@sage-protocol/cli
v0.5.7
Published
Sage Protocol CLI for managing AI prompt libraries
Downloads
2,140
Readme
Sage CLI
Fast, scriptable tooling for the Sage Protocol. The CLI wraps the Sage SDK so you can:
- Connect wallets (Cast, Privy, injected) and manage DAO context
- Propose, queue, and execute governance actions
- Inspect treasury and bond positions
- Upload, pin, and verify library prompts on Sage’s IPFS worker
- Run deterministic test-mode flows for local development
Full guides live at https://docs.sageprotocol.io.
Install & Run
Global install
npm i -g @sage-protocol/cli
# or on demand
npx @sage-protocol/cli --helpThe binary is published as sage. Update notifications appear once per day unless you set SAGE_NO_UPDATE_CHECK=1 (e.g., in CI).
Workspace development
Requirements: Node 18+ with Corepack enabled (corepack enable). From the repo root:
corepack yarn plugin import workspace-tools
corepack yarn workspaces focus -A @sage-protocol/cli
corepack yarn workspace @sage-protocol/cli build
corepack yarn workspace @sage-protocol/cli dev # runs src/index.js with ts-node/register
corepack yarn workspace @sage-protocol/cli test # unit suiteWhile iterating, rerun build to refresh dist/ (used by bin/sage.js).
CI or release automation should execute:
corepack enable
corepack yarn install --mode=update-lockfile
corepack yarn workspace @sage-protocol/cli buildGuided Onboarding
sage wizard (alias: sage tutorial) walks new users through the full workflow:
- Detect or create a wallet (
sage wallet connectunder the hood) with clear guidance when keystore directories are missing. - Configure worker credentials and gateways, reusing the
sage config ipfsonboarding flow. - Upload a prompt, warm the Sage gateway (
https://ipfs.dev.sageprotocol.io/ipfs), and record the manifest pointer. - Review governance requirements, stake thresholds, and (optionally) create a SubDAO using the selected template.
Run with --yes to accept defaults; interactive prompts appear when a safe default does not exist (for example, selecting a local file to upload).
Configuration
The CLI now treats .sage/config.json (project or XDG) as the primary source of truth; .env is still loaded for backward compatibility and for secrets, but most workflow settings live in the profile. sage init writes the active profile automatically, and you can tweak values with the config commands below. In CI, set env vars only for tokens or temporary overrides.
Configuration prefers environment variables, then project profiles (.sage/ in the repo), then XDG base directories (e.g., ~/.config/sage). Key commands:
sage config profile list– discover active profilessage config ipfs onboard/sage ipfs setup– worker & gateway wizardsage config set-rpc <rpcUrl> [--chain-id <id>]– persist network endpoints per profilesage config addresses set <KEY>=<0x...>– store contract addresses without touching.envsage config show --all– inspect the merged view
Override the keystore directory with SAGE_CAST_KEYSTORE_DIR or use the defaults (~/.foundry/keystores, project .cast-keystore).
Secrets
By default the CLI stores sensitive values (e.g., PINATA_JWT, worker tokens) in your OS keychain using keytar and writes only references into .sage/config.json.
- Set:
sage secret set pinata.jwt(prompts) orsage config ipfs set-pinata --jwt <token> - Get (masked):
sage secret get pinata.jwt - Delete/list:
sage secret delete <name>,sage secret list
In CI set SAGE_SECRETS_BACKEND=env and provide env vars like SAGE_SECRET_PINATA_JWT or the original provider variables; the CLI will resolve them without touching the keychain. Use --allow-plain-secret on config ipfs set-* only if you truly need to persist secrets in plaintext.
IPFS & Pinning
Uploading defaults to the Sage worker provider with the hosted gateway:
- Provider:
worker - Gateway:
https://ipfs.dev.sageprotocol.io/ipfs - Worker base:
https://api.sageprotocol.io
Pinata is now opt-in. Use --use-pinata (or set SAGE_IPFS_PROVIDER=pinata) when you want to supply Pinata credentials; otherwise the worker handles warming and pinning. Additional options:
--warmorSAGE_IPFS_WARM=trueto prefetch via the gateway--provider <worker|pinata|w3s>to switch providers per commandsage ipfs pin <cid>to ensure content stays replicated after upload
The CLI signs worker challenges with your connected wallet, so make sure your signer has the proper on-chain roles. Configure timeouts with SAGE_IPFS_TIMEOUT_MS and retry behaviour with SAGE_IPFS_RETRIES.
Off‑chain credits (Phase A)
- Enable
SAGE_PAY_TO_PIN: truein your profile flags to surface credits UX. - Show credits:
sage ipfs credits --worker-url https://ipfs.dev.sageprotocol.io - Buy credits:
sage ipfs buy-credits --worker-url …(prints checkout URL) - Pin with credits:
sage ipfs pin <cid> --worker-url …(prints 402 guidance when needed). You can always use your own provider withsage ipfs upload --provider pinataif you prefer BYO model.
Prepare‑only auctions (LaunchGate + Safe)
- We do not broadcast Doppler auction creation from local EOAs. Instead:
- Set profile flags:
SAGE_DOPPLER_PERMITTED: trueand optionallySAGE_DOPPLER_ALPHA: true(unified SDK). - Run:
sage doppler create --prepare-only --variant dynamic [--via-wrapper] --output safe-payload.json. - To forbid direct deploy/migrate, set
SAGE_REQUIRE_LAUNCHGATE: true.
- Set profile flags:
On‑chain pin and credits (Phase B)
- Pin burn (prepare-only vs send):
- Prepare:
SAGE_PAY_TO_PIN=1 SAGE_PAY_TO_PIN_MODE=onchain sage ipfs pin <cid> - Send:
… sage ipfs pin <cid> --send(requires wallet configured)
- Prepare:
- Buy credits on-chain:
- Prepare (simple allowance):
sage ipfs buy-credits-onchain --token <USDC> --amount <baseUnits> --credits <n> - Prepare (Permit2):
sage ipfs buy-credits-onchain --permit2 <addr> --token <USDC> --amount <baseUnits> --credits <n> - Append
--sendto submit the transaction directly.
- Prepare (simple allowance):
Signed Addresses Payload (Worker Implementers)
- Schema: the Worker should serve a JSON with this shape under
/addresses:{ "payload": { "chainId": 84532, "signer": "0xTreasurySafeOrSigner", "registry": "0xAddressRegistryOrNull", "addresses": { "PAYMENT_ROUTER_ADDRESS": "0x...", "CREDIT_TOKEN_ADDRESS": "0x..." }, "expected": { "PAYMENT_ROUTER_ADDRESS": "0xcodehash", "CREDIT_TOKEN_ADDRESS": "0xcodehash" }, "effectiveFromBlock": 1234567, "timestamp": 1730000000, "expiresAt": 1730864000 }, "signature": "0x…" } - The signature must be produced by the allowed signer:
- EOA:
ethers.signMessage(stableStringify(payload))and publish the signer inSAGE_TRUSTED_SIGNER(CLI env or profile flag), or - Safe (contract): sign via a Safe module; the CLI can verify using EIP‑1271
isValidSignatureagainstpayload.signer.
- EOA:
- Validation in CLI:
sage config addresses verify --worker https://worker/addresses(reads payload, verifies signature, checks codehashes on-chain).sage config addresses fetch --worker … --write(same as verify, then writes addresses to profile).
Testing
Unit suites live under packages/cli/tests. Run corepack yarn workspace @sage-protocol/cli test:unit for fast feedback or test:ci for coverage reports. Some wallet tests mock Foundry; ensure cast is available on your PATH when running the full suite.
Contributing
- Fork, branch, and focus-install dependencies (
yarn workspaces focus -A @sage-protocol/cli). - Add or update tests alongside code changes.
- Keep UX messages explicit—surface actionable guidance when commands fail.
- Submit a PR with context, testing performed, and any follow-up work required.
See CONTRIBUTING.md for full guidelines.
License
Apache 2.0 — see LICENSE in this directory.
Feature flags and environment gating
- Production defaults avoid environment variables. Use profile-based flags in
.sage/config.jsonunder the active profile. - Supported flags (profile
profiles.<name>.flags):SAGE_CLI_TEST_MODE: enables test-mode helpers and allows environment overrides for rapid iteration.SAGE_FLAGS_ALLOW_ENV: allows reading feature flags and network settings fromprocess.env.SAGE_LEGACY_ENV_MIRROR: mirrors profile settings intoprocess.env(legacy behavior). Disabled by default.
Notes
resolveFlag(name)now consults profile flags first; env is only used in test mode or whenSAGE_FLAGS_ALLOW_ENV=1.resolveRpcUrl()andresolveChainId()prefer profile values; env is only used whenSAGE_FLAGS_ALLOW_ENVor test mode is enabled.- Profile presets
- Seed example presets for Base or Mainnet using the helper script:
node packages/cli/scripts/presets/seed-profiles.js --address_registry_address 0x... --payment_router_address 0x... --credit_token_address 0x...- Outputs JSON under
packages/cli/assets/presets/<name>.json(setPRESET_NAME=baseorPRESET_NAME=mainnet).
- Import into the active profile:
sage config addresses import --file packages/cli/assets/presets/base.json
- Seed example presets for Base or Mainnet using the helper script:
