@usenaive-sdk/cli
v0.15.1
Published
Naïve CLI — provision and govern a real-world agent profile per agent (identity, card, comms, runtime). Formerly @usenaive/cli.
Downloads
1,391
Readme
@usenaive-sdk/cli
Command-line interface for the Naive API v2. Register, manage identity, and use all primitives directly from the terminal.
What It Provides
- Auth & Onboarding — Register new accounts, login, link existing ones, manage API keys
- Identity — View agent profile, company, email inboxes, resources
- Domains — List domains, connect custom domains (BYOD), view DNS records, verify, search, purchase
- Billing — Plans, subscribe, upgrade, credit top-ups, billing portal
- Email — Create/delete inboxes, send emails, read inboxes
- Search — Web search, URL extraction, deep research
- Images — Generate via fal.ai, search stock photos (dynamic pricing)
- Video — Generate via fal.ai (dynamic pricing)
- Social — Connect accounts, create posts, schedule, analytics (via bundle.social)
- Verification — Identity verification (KYC) for company founders/members via Footprint
- Formation — Company formation (LLC incorporation) via Doola ($349 fee via Stripe Checkout)
- Cards — Virtual cards — create, fund, assign agents, track transactions (Stripe Issuing + Reloadly)
- Jobs — List, inspect, and cancel async jobs
- Status — Credit balance and usage history
Local Development
Prerequisites
- Node.js 20+
- pnpm 9+
Setup
# From monorepo root
pnpm installRun (development)
# Run any command directly with tsx
pnpm --filter @usenaive-sdk/cli dev -- register --name "Test" --email [email protected]
# Or from packages/cli
cd packages/cli
pnpm dev -- search "AI frameworks"Build
pnpm --filter @usenaive-sdk/cli buildLink locally (test as global binary)
cd packages/cli
pnpm link --global
naive --helpUsage
Configuration
The CLI stores config at ~/.naive/config.json:
{
"api_key": "nv_sk_live_...",
"base_url": "https://api.usenaive.ai"
}Set via registration or environment:
# Auto-saved on register/login/browser auth
naive register --name "My Agent" --email [email protected] --password yourpassword
# Or set manually
export NAIVE_API_KEY=nv_sk_live_...
export NAIVE_BASE_URL=http://localhost:3100 # for local devThe durable runtime — naive teams
The addressing tuple is (company, tenant, team) and it is in the path, not
inferred, so --tenant is required on every subcommand except list. There is
no default: --tenant @self is the only shorthand.
naive teams list
naive teams show support --tenant tu_8f21
naive teams submit support "refund the duplicate charge" --tenant tu_8f21
naive teams board support --tenant tu_8f21
naive teams watch support --tenant tu_8f21 --run run_01J8 --follow # NDJSON
naive teams approvals support --tenant tu_8f21
naive teams decide support apr_01J --allow --because "verified with the customer"All 27 subcommands, their flags, their REST paths and their ActionIds are
declared once in src/lib/teams-catalog.ts; src/commands/teams.ts builds the
commander tree by walking it and declares no subcommand of its own.
--because is a required flag (never a positional) on every op that widens
authority or destroys state: unblock decide settle model stop migrate rollback.
Exit codes it uses: 0 success · 1 error · 2 success with a diff
(plan --detailed-exitcode) · 3 success where the terminal state is not
success (tasks|task --fail-on-unverified, watch --fail-on-terminal).
unverified is a third terminal state, and a CI script that reads 0 as "the
work is done" would otherwise count an unattested task as a pass. The full
CLI-wide ladder, including 4, is under Exit codes.
Not yet served. There is no /v1/teams mount on packages/api in this
repository. Every naive teams subcommand therefore reaches the API's catch-all
today, and the CLI says exactly that — it reports the missing route, not a
missing team.
Deprecation
ceo · tasks · objectives · employees · cron · loops · memory drive the legacy
orchestration runtime, which is frozen. They all keep working, unchanged.
Each prints a one-line banner on stderr carrying a greppable [dep.<group>] id
and its replacement, and attaches a deprecation object to the JSON envelope on
stdout, so stdout stays JSON.parse-able. Nothing is disabled and no route is
removed.
Where a capability genuinely has no successor (tasks complete, cron pause,
the provisioning verbs) the notice says so and gives the reason, rather than
inventing a replacement — the record's replacement is a closed union, so a
missing one cannot render as an empty string.
Commands
# Auth
naive register --name "Agent" --email [email protected] --password mypassword --company "Acme"
naive login --email [email protected] --password mypassword
naive auth email [email protected]
naive whoami
naive companies
naive keys list
naive keys create "Production"
naive keys revoke <key-id>
# Identity
naive identity
naive identity emails
naive identity resources
# CEO (orchestration)
naive ceo run "Launch my product"
naive ceo stream <runId>
naive ceo message "Approved, hire the team"
naive ceo status
naive ceo sessions
# Tasks (kanban)
naive tasks list
naive tasks list --status running --assignee "Jordan Kim"
naive tasks create "Build landing page" --description "Responsive hero section" --assignee "Jordan Kim" --priority high
naive tasks show <id> # Accepts UUID or hermes task ID (t_*)
naive tasks complete <id> --summary "Deployed to prod"
naive tasks block <id> --reason "Waiting for DNS"
naive tasks unblock <id>
naive tasks comment <id> "Added SEO meta tags"
naive tasks dispatch
naive tasks stats
# Employees
naive employees list
naive employees hire --name "Jordan Kim" --role engineer --skills "typescript,react"
naive employees fire <id>
naive employees configure <id> --model gpt-4o
# Objectives
naive objectives list
naive objectives create "Launch product" --criteria "100 signups"
naive objectives update <id> --status completed
naive objectives show <id>
# Cron Jobs
naive cron create "0 9 * * *" "Check email and summarize"
naive cron list
naive cron trigger <id>
naive cron pause <id>
# Memory
naive memory add --target memory "Brand color is #FF6B00"
naive memory list
naive memory remove <id>
# Domains
naive domains # List all domains
naive domains connect example.com # Connect a custom domain (BYOD)
naive domains dns-records <domain-id> # Show required DNS records
naive domains verify <domain-id> # Trigger domain verification
naive domains search example.com # Check domain availability + price
naive domains purchase example.com # Purchase a domain via Stripe
# Billing
naive billing plans # List plans with pricing
naive billing subscribe --plan pro # Subscribe to a plan
naive billing upgrade --plan pro # Upgrade existing subscription
naive billing status # Check subscription + credits
naive billing portal # Stripe billing management
naive billing packs # List credit top-up packs
naive billing topup --pack medium # Buy credits
# LLM router — REQUIRES A PAID ACCOUNT (a pack or a plan; free credit is refused)
naive llm models claude # Free, no payment needed
naive llm chat -m openai/gpt-5.2 "hi" # exit 4 + decision_required until paid
# Email
naive email inboxes
naive email create --local-part hello # Create new inbox on active domain
naive email delete <inbox-id> # Delete an inbox
naive email send --from-inbox <uuid> --to [email protected] --subject "Hi" --body "Hello"
naive email inbox --inbox <uuid> --limit 20
naive email sent --limit 20
naive email read <email-id>
# Search
naive search "AI agent frameworks"
naive search url https://example.com --extract "Main points?"
naive search research "Compare React vs Astro" --depth thorough --wait
# Images
naive images generate "A tech logo" --model "fal-ai/flux-pro/v1.1" --wait
naive images generate --input '{"prompt":"...","num_images":2}' --wait
naive images status <job-id>
naive images stock "office workspace" --count 5
naive images models
# Video
naive video generate "Dog on beach" --model "fal-ai/kling-video/v3/pro/text-to-video" --duration 5 --wait
naive video status <job-id>
naive video models
# Social
naive social status # Check activation + accounts
naive social activate # Activate social media
naive social connect --platform twitter --redirect-url https://example.com # OAuth URL
naive social portal --redirect-url https://example.com # Multi-platform portal
naive social accounts # List connected accounts
naive social label <account-id> --label "Main" # Label an account
naive social disconnect <account-id> # Disconnect account
naive social sync # Sync from bundle.social
naive social upload --url https://example.com/video.mp4 # Upload media
naive social posts # List posts
naive social posts --status draft # Filter by status
naive social post "Hello world!" --platforms twitter,linkedin --publish # Create + publish (2.5 credits; 3 for X)
naive social post "Draft" --platforms twitter # Create draft (free)
naive social post "Demo" --platforms youtube --media-url https://example.com/video.mp4 --youtube-type SHORT --publish
naive social get <post-id> # Get post details
naive social edit <post-id> --content "Updated" # Edit draft
naive social delete <post-id> # Delete post
naive social publish <post-id> # Publish draft (2.5 credits; 3 for X)
naive social analytics <post-id> # Post analytics
naive social comments <post-id> # Post comments
naive social account-analytics <account-id> # Account analytics
# Cards
naive cards # List all cards
naive cards cardholder # View cardholder
naive cards create-cardholder --first-name John --last-name Doe --billing-line1 "123 Main St" --billing-city "SF" --billing-state CA --billing-postal-code 94105 --dob-day 15 --dob-month 6 --dob-year 1990
naive cards create --name "Marketing" --spending-limit 10000 # Returns checkout URL
naive cards check-payment <card-id> # Issue card after payment
naive cards details <card-id> # Get PAN/CVC or redeem code
naive cards top-up <card-id> --amount 5000 # Returns checkout URL
naive cards cancel <card-id> # Cancel a card
naive cards assign <card-id> --agent-id <uuid> # Assign agent
naive cards unassign <card-id> <agent-id> # Remove assignment
naive cards log-transaction <card-id> --amount 2500 --description "Purchase"
naive cards transactions --card-id <uuid> # List transactions
# Jobs
naive jobs
naive jobs --status processing
naive jobs get <job-id>
naive jobs cancel <job-id>
# Status
naive status
naive usage --days 7Global Options
--api-key <key> Override API key (env: NAIVE_API_KEY)
--base-url <url> Override base URL (env: NAIVE_BASE_URL)
--help Show help
--version Show versionWhich stream the envelope is on
stdout is the machine document on every outcome. The success envelope
({success:true, action, result, next_steps, …}) and the failure envelope
({success:false, action, error, recovery_steps}) both go to stdout, so
naive <anything> | jq and any agent reading stdout gets an answer whether the
command worked or not — including the recovery_steps that are its route out.
Exit code is still 1 on failure.
stderr carries only human-facing noise: the deprecation banner, the
update-available box, the "try human mode" tip, and — in --human mode only —
the red ✗ … failed diagnostic. Nothing on stderr is required to understand
what happened; stdout stays JSON.parse-able whole.
Exit codes
| code | meaning |
|---|---|
| 0 | success |
| 1 | error |
| 2 | success, and a diff exists (teams plan --detailed-exitcode) |
| 3 | success, and the terminal state is not success (--fail-on-unverified, --fail-on-terminal) |
| 4 | a human has to decide this, and nothing was done |
4 exists because 1 is the code every caller retries. It means the command
did not fail in any way that re-running can fix — the way forward is known,
there is more than one of them, and picking between them is not the CLI's to do.
The envelope carries a decision_required object alongside the usual error:
{
"success": false,
"action": "llm.chat",
"error": { "code": "llm_routing_requires_payment", "retryable": false, "balance": 20, … },
"decision_required": {
"question": "The LLM router needs paid credit on this account. Add a subscription, buy credits, or stop here?",
"because": "Both ways out spend real money, and they are not the same deal…",
"options": [ { "id": "topup", "label": …, "command": "naive billing topup --pack medium" }, … ],
"chosen": null // null ⇒ NOTHING was decided on your behalf
},
"recovery_steps": [ … ] // reads only — never a purchase
}An agent relays decision_required to its operator and stops. It does not pick.
The purchases appear only under options, never in recovery_steps, because
recovery_steps is the array every other error on this surface teaches an agent
to just run.
Today the only source is the LLM router. naive llm chat (and /v1/llm/*,
and the provider proxies) require a paid account: free and comped credit do
not buy model routing, at any balance. Any credit pack or any subscription
unlocks it permanently. At a real interactive terminal (--human + a TTY) the
CLI asks the question instead of only printing it — and still only echoes the
chosen command, never runs it, since a keystroke at an unbidden prompt is not
consent to open a Stripe checkout.
Production / Publishing
Publish to npm
cd packages/cli
pnpm build
npm publish --access publicUsers install with:
npm install -g @usenaive-sdk/cli
naive --helpUse without installing
npx @usenaive-sdk/cli register --name "My Agent" --email [email protected]
npx @usenaive-sdk/cli search "AI frameworks"Architecture
src/
├── index.ts # Entry point, commander program setup
├── config.ts # ~/.naive/config.json read/write
├── client.ts # HTTP client (fetch wrapper with auth + error handling)
├── output.ts # Structured agent-native JSON output (agentOutput/agentError)
└── commands/
├── ceo.ts # naive ceo (run/message/status/sessions/stream)
├── tasks.ts # naive tasks (list/create/show/complete/block/unblock/comment/dispatch/stats)
├── employees.ts # naive employees (list/hire/fire/configure)
├── objectives.ts # naive objectives (list/create/update/show)
├── memory.ts # naive memory (add/list/remove)
├── cron-jobs.ts # naive cron (create/list/trigger/pause/resume/delete)
├── register.ts # naive register
├── login.ts # naive login
├── link.ts # naive link
├── whoami.ts # naive whoami
├── companies.ts # naive companies
├── keys.ts # naive keys
├── identity.ts # naive identity
├── status.ts # naive status
├── usage.ts # naive usage
├── domains.ts # naive domains (list/connect/dns-records/verify/search/purchase)
├── billing.ts # naive billing (plans/subscribe/upgrade/status/portal/packs/topup)
├── email.ts # naive email (inboxes/create/delete/send/inbox/read)
├── search.ts # naive search (web/url/research)
├── images.ts # naive images (generate/stock/models)
├── video.ts # naive video (generate/models)
├── social.ts # naive social (status/activate/connect/portal/accounts/label/disconnect/sync/upload/posts/post/get/edit/delete/publish/analytics/comments/account-analytics)
├── verification.ts # naive verification (start/list/status/complete/resend)
├── formation.ts # naive formation (naics-codes/submit/retry-payment/execute/list/status/documents/download)
├── cards.ts # naive cards (list/cardholder/create-cardholder/create/details/check-payment/retry-issue/top-up/refund/cancel/assignments/assign/unassign/log-transaction/transactions)
└── jobs.ts # naive jobs (list/get/cancel)Purpose
Naïve CLI — provision and govern a real-world agent profile per agent (identity, card, comms, runtime). Formerly @usenaive/cli.
Consumers
Part of the Naive monorepo. See the root README for how components fit together and which packages depend on this one.
Run standalone
pnpm --filter @usenaive-sdk/cli dev
pnpm --filter @usenaive-sdk/cli build
pnpm --filter @usenaive-sdk/cli test
pnpm --filter @usenaive-sdk/cli typecheckPlace in the topology
One node in the Naive monorepo (open plumbing). The root README has the full architecture diagram.
