Docs

CLI

Command-line interface for GridWonk API operations, built for humans and AI agents.

last-updated: "2026-10-27"

Project capacity remains megawatts for --capacity-mw; the console's new kW/MW selector does not change CLI units. Partial document reports and direct site-plan Attach DWG are console views, not new CLI operations.

Prompt inspection is read-only: prompts list and prompts diff remain; snapshot, activate and rollback commands are removed. Prompt changes require reviewed Git changes and separately authorized database activation. Repository eval:check, eval:compare and eval:verify scripts are not packaged CLI commands and do not authorize paid execution or release acceptance.

Overview

The Salesforce installed application's Layer 2 packet-submission source adds no GridWonk CLI command. Salesforce will initiate its runtime requests over a separate signed API; the Salesforce CLI used by engineers for development and testing is not a runtime transport. The installed-app endpoint and processing remain disabled.

AX optimization commands are removed

The optimize command and opt alias, including status and list, are no longer available. Prompt history and evaluation commands remain.

The @gridwonk/cli package provides the GridWonk command-line interface (CLI). The package scope is canonical; the executable command remains gridwonk during the binary naming transition. It is the command-line projection of the Canonical Capability Manifest, which is the source of truth for capability IDs, auth lanes, lifecycle, risk metadata, and surface identifiers. A projection is a surface-specific catalog of the same capability contract, not a separate source of truth. The manifest's operation-level bindings distinguish reads, writes, confirmation requirements, and optional OAuth scopes so a CLI command cannot imply broader authority than its shared capability operation. Guarded Codex-only administration is recorded separately from CLI authority: adding a read to the protected admin MCP catalog does not silently create a CLI command or grant impersonation, billing, or model-catalog write access.

Protected document recovery follows the same boundary: admin-document-recovery adds no CLI or customer SDK command. Its human-operator preview/apply/status flow does not change the existing packet upload-retry commands or authorize paid recovery through a stored CLI key.

The review-application capability's forced fresh-perception option is likewise console-only, limited to platform administrators on demo packets. It does not add a CLI command or broaden the partner packet review command.

Packet Owner Evidence keeps the stable capability ID packet-applicant-evidence. Its human confirmations—including utility staff confirmations on their own editable packets—remain in the console, not CLI commands, SDK methods, REST writes, or MCP calls. The utility-owner repair does not broaden packet write credentials or introduce a developer invitation command.

The CLI provides terminal access to the GridWonk API v1, session-backed admin workflows, and Model Context Protocol (MCP) gateway operations. It supports two output modes: an interactive Ink terminal UI for human operators, and a --json flag for machine-readable output consumed by AI coding agents (Claude Code, Codex) and CI/CD pipelines.

Most runtime commands use @gridwonk/sdk; browser login, bootstrap, and session-only helper commands call the matching GridWonk route APIs directly. SDK-backed commands inherit SDK retry logic, rate limiting, and error mapping.

Canonical GridWonk host

The CLI defaults to the canonical https://gridwonk.com API origin. An authenticated request therefore needs no base URL or trust override:

gridwonk utilities list --state CA --json

Use --base-url only for an approved alternate environment. Custom origins also require --allow-untrusted-base-url. Exact legacy production hosts are accepted for compatibility and normalized to https://gridwonk.com before an authenticated request is sent.

Quick Start

# Install the CLI (requires GitHub Packages ~/.npmrc setup — see below)
npm install -g @gridwonk/cli

# Store your API key
gridwonk auth login --api-key gw_live_YOUR_KEY

# Inspect the locally configured credential source and effective host
gridwonk whoami

# Verify the credential with a real API read against the canonical GridWonk host
gridwonk utilities list --state CA --json

The package installs two commands: gridwonk, the canonical one, and gridboost, the pre-rebrand name kept so existing scripts and aliases keep running. Both are the same launcher, so they behave identically — but help, usage, examples, and shell completions all speak gridwonk, and completions are registered for that name.

# Legacy gb_live_/gb_test_ keys are no longer accepted; use gw_live_ or gw_test_ keys.

# Query customer-released requirements against the canonical GridWonk host
gridwonk requirements published --utility "nashville-electric-service" --json

GitHub Packages setup: The @gridwonk/cli package is hosted on GitHub Packages. Add the following to your ~/.npmrc (one-time setup):

@gridwonk:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=ghp_YOUR_TOKEN

Local installs require a GitHub personal access token (classic) with read:packages scope and access to the package. See GitHub's registry authentication guidance for local installation and GitHub Actions credential options.

For human session-backed CLI access, use browser login:

gridwonk auth login --browser
gridwonk auth status --json
gridwonk orgs list --json
gridwonk orgs switch <org-id>
gridwonk auth connect --client codex --org <org-id>

Browser-backed login is the baseline path for session-only mutations. Once you have a stored session and active org, the same terminal can execute high-risk writes that are intentionally blocked for API keys.

The CLI acts as you, so browser login first asks you to accept any updated legal terms, then finishes the login. The CLI waits two minutes for the browser; if it times out while you review the terms, run gridwonk auth login --browser again and it finishes right away. If the terms change while you hold a session, auth bootstrap-status and auth bootstrap-key answer 403 FORBIDDEN with reason legal_acceptance_required and a link to accept; other session commands are refused until you accept in the browser.

For direct session-token fallback or agent handoff, the CLI still accepts an explicit session token:

export GRIDWONK_SESSION_TOKEN=sb_...
gridwonk auth connect --client codex
gridwonk capabilities --json
gridwonk orgs switch <org-id>
gridwonk admin models list --json

Authentication

API keys are resolved in order of precedence:

  1. --api-key <key> flag (highest priority)
  2. GRIDWONK_API_KEY shell environment variable
  3. Opted-in project .env.local (allowlisted keys only)
  4. ~/.gridwonk/config.json (stored via gridwonk auth login)

Project .env.local loading is opt-in only. Supported keys:

  • GRIDWONK_API_KEY
  • GRIDWONK_BASE_URL

The pre-rebrand GRIDBOOST_* variables and ~/.gridboost/config.json are still read when their GRIDWONK_* / ~/.gridwonk counterparts are absent, so an existing shell or CI job keeps working. The CLI prints a one-time deprecation warning; rename them when convenient. Setting a GRIDWONK_* variable to an empty string means "cleared" and does not fall back to the legacy name, project file, or stored config. Config writes always target ~/.gridwonk/config.json; the first write carries forward fields read from a legacy-only config. A failed first write leaves the legacy config active, and gridwonk config show reports the file actually being read. gridwonk auth logout removes stored credentials from both locations.

# CI/CD: use environment variable
export GRIDWONK_API_KEY=gw_live_...
gridwonk jobs list --json

# Interactive: store API key locally
gridwonk auth login

# Opt-in project .env.local for one command
gridwonk --project-env auth status

# Opt-in project .env.local in automation
GRIDWONK_ENABLE_PROJECT_ENV=1 gridwonk usage --json

The config directory is created with 0o700 permissions and the config file with 0o600 to protect stored credentials.

Session-backed commands resolve auth in this order:

  1. --session-token <token> flag
  2. GRIDWONK_SESSION_TOKEN shell environment variable
  3. ~/.gridwonk/config.json (stored via gridwonk auth login --browser or gridwonk auth login --session-token ...)

Session-only mutation commands reject API keys and point operators back to:

gridwonk auth login --browser
gridwonk auth connect --client codex
gridwonk orgs switch <org-id>

Global Options

FlagDescription
--jsonMachine-readable JSON output (NDJSON for streams)
--api-key <key>Override stored/env API key
--session-token <token>Override stored/env session token
--base-url <url>Override the API base URL; the default is https://gridwonk.com
--org <id>Override active organization for operator or session-backed commands
--project-envOpt-in loading allowlisted CLI environment variables from .env.local
--show-secretDisplay raw secrets in human output when explicitly requested
--allow-untrusted-base-urlPermit an approved custom origin outside the GridWonk, legacy compatibility, localhost, and project-owned Vercel allowlist
--dry-runPreview supported destructive actions without executing; support is command-specific
--yesSkip confirmation prompts for destructive operations
--no-colorDisable ANSI colors
-v, --verboseShow request/response details
-q, --quietSuppress non-essential output

Command Reference

Every command listed here is covered by npm run capabilities:contracts: a capability whose cli binding is marked available must resolve to a registered command path, so this reference cannot silently drift from what the CLI actually ships.

The active packet-combined-split capability remains console-only behind a server-side per-organization setting (the COMBINED_SPLIT dial merged with database rows that organization admins and platform admins manage). The manifest deliberately has no CLI binding for proposing, confirming, retrying, discarding, or materializing a split. Developers use More actions → Split PDF in the console for eligible PDFs, including those already assigned a document type or reviewed.

The mixed-upload coordinator now binds through packets intake-batches (manifest operation family utility-packet-intake.upload-batch). It reserves, reads, heartbeats, pairs, cancels unstarted items, and abandons selections while preserving the existing intake identities. ZIP creation and recovery use packets archive-intake; standalone CAD upload still has no CLI create command. Applicant-owned inspected CAD items or archive children can be paired with intake-batches pair.

The standalone native-CAD intake, visualization, and preflight capabilities have no CLI binding. The intake contract provides a partner REST route, while this layer has no command for uploading, downloading, viewing, or inspecting a DWG. Optional DWG companions are available for any utility through the existing console and partner REST intake; see Upload.

The high-risk admin-purge-empty-synthetic-projects capability also has no CLI binding. It is limited to the protected GridWonk admin MCP preview/apply flow so it cannot become a general-purpose project deletion command.

projects — Manage Developer Projects

gridwonk projects list [--utility <name>] [--state <state>] [--limit <n>] [--offset <n>]
gridwonk projects get <project-id>
gridwonk projects create --utility <name> --name <name> --capacity-mw <mw> \
  --interconnection-level <distribution|transmission> [--state <state>] \
  [--declared-tier-slug <slug>] --yes
gridwonk projects update <project-id> [--name <name>] [--capacity-mw <mw>] \
  [--state <state>] [--interconnection-level <distribution|transmission>] --yes

Create and update support --dry-run and explicit --yes confirmation. These commands manage real developer projects only; synthetic demo creation and project deletion are not customer CLI capabilities.

--declared-tier-slug <slug> declares the interconnection program (the API's declaredTierSlug) and is required when the utility publishes two or more programs for the chosen level (and refused otherwise). The API's refusal message lists the valid slugs, and --json output carries them under error.details.programs together with error.reason on 503 responses.

projects update cannot change the declared program, and --interconnection-level is refused when the change would leave the project in a state creation would not have accepted: a project that declared a program is bound to its track, and an undeclared project cannot move onto a track where the utility publishes two or more programs. Create a new project with --declared-tier-slug instead.

auth — Manage Authentication

gridwonk auth login [--api-key <key>]      # Store API key
gridwonk auth login --browser              # Browser-assisted session login
gridwonk auth login --session-token <tok>  # Store session token directly
gridwonk auth connect --client codex       # Validate key or session + show onboarding
gridwonk auth logout                        # Remove stored credentials
gridwonk auth status                        # Show current auth context
gridwonk auth token [--expires-in <sec>]    # Exchange API key for JWT
gridwonk auth bootstrap-status --org <id>   # Check first-key bootstrap eligibility
gridwonk auth bootstrap-key --org <id> --name "Initial Management Key"

bootstrap-key requires an explicit, nonblank --org <id> flag, either before or after the subcommand. It does not choose the target from stored configuration or environment variables. Use --dry-run to preview the target without making a network request.

bootstrap-status and bootstrap-key return 403 FORBIDDEN with reason legal_acceptance_required while your account has updated legal terms to accept; the error message includes the accept link. bootstrap-status reports not_allowlisted with the reason API access is suspended for this organization or This organization is suspended when a platform admin has suspended the organization's API and MCP access or the account is suspended; bootstrap-key is refused in the same state. Contact support to restore access.

Utility and consultant organizations are allowlisted by default, so an owner or admin of either can bootstrap a first management key without a platform-admin step; developer organizations still report not_allowlisted until a platform admin enables their API profile. Utility owners and admins can also mint keys in the browser at /utility/api-keys.

auth status --json response:

{
  "data": {
    "authenticated": true,
    "apiKeyAuthenticated": true,
    "sessionAuthenticated": true,
    "source": "config",
    "sessionSource": "env",
    "keyPrefix": "gw_live_ab...",
    "sessionPrefix": "sb_ab...",
    "baseUrl": "https://gridwonk.com",
    "organizationId": "org_123"
  }
}

capabilities — Agent Discovery

gridwonk capabilities --json                # Machine-readable CLI catalog

gridwonk capabilities --json returns the CLI-specific agent discovery catalog from packages/cli/src/capabilities.ts. That catalog tells agents which CLI commands are useful, which auth lane they need, and whether JSON output is supported. It is a CLI projection of the Canonical Capability Manifest, not the canonical manifest itself. The manifest declares CLI bindings today; npm run capabilities:contracts verifies available manifest bindings against registered CLI command paths, while npm run capabilities:surface-report highlights broader CLI-only commands that may need manifest bindings or reduction decisions.

orgs — Session Organization Context

gridwonk orgs list                          # List accessible orgs
gridwonk orgs get <org-id>                  # Get org detail
gridwonk orgs switch <org-id>               # Persist active org for session commands

notifications — User Inbox

gridwonk notifications list
gridwonk notifications read <notification-id>
gridwonk notifications read-all
gridwonk notifications dismiss <notification-id>

feedback — Discovery Feedback

gridwonk feedback list
gridwonk feedback summary
gridwonk feedback submit-document --document-id <id> --type document_incorrect

remediation — Working Copies And Export Bundles

gridwonk remediation draft get --document-id <id>
gridwonk remediation draft patch --document-id <id> --span-id <span> --text "Updated language"
gridwonk remediation export create --document-id <id>
gridwonk remediation export get --export-id <id> --json

The remediation commands read working-copy spans, patch an edited span after mutation confirmation, create clean/redline/evidence export bundles, and fetch export status plus artifact URLs.

admin models — Platform Model Management

gridwonk admin models list
gridwonk admin models assign --agent-id <id> --task-category <cat> --model provider:model
gridwonk admin models catalog
gridwonk admin models lifecycle

admin utilities — Internal Review Queues

gridwonk admin utilities list
gridwonk admin utilities get <utility-id>
gridwonk admin utilities url-reviews list
gridwonk --org <org-id> admin utilities url-reviews approve --utility-id <utility-id>
gridwonk --org <org-id> admin utilities url-reviews reject --utility-id <utility-id>
gridwonk admin utilities delete <utility-id>
gridwonk admin utilities url-reviews stats
gridwonk admin utilities discovery-reviews list
gridwonk admin utilities discovery-reviews get <document-id>
gridwonk admin utilities digitization-reviews list
gridwonk admin utilities digitization-reviews get <document-id>
gridwonk admin utilities published-requirement-reviews list
gridwonk admin utilities published-requirement-reviews list --review-status needs-review
gridwonk admin utilities published-requirement-reviews stats

These commands summarize the published Packet Intake review catalog. Open /admin/requirements-review to approve, reject, or refine an individual requirement.

--review-status accepts ready, needs-review, changed, blocked, or evidence-only, and filters server-side. Omit it to list every requirement set in scope. Both commands are scoped by --org the same way the other operator review commands are.

admin utilities delete refuses roster-managed utilities (rows the utility roster catalog matches) with HTTP 409 — remove them via the domains/utilities publish flow instead (ADR-068).

Session-Only Mutation Examples

Workspace appearance is selected in Team and logo > Workspace appearance using the local preview and Save appearance. The session-authorized browser route does not create a CLI or SDK appearance command; existing organization branding administration remains separately scoped.

gridwonk --org <org-id> changes subscriptions create --utility pge --state CA --json
gridwonk --org <org-id> changes subscriptions delete <subscription-id> --json

gridwonk admin users update <profile-id> --role admin --json
gridwonk admin users bulk-reject --ids <id-1>,<id-2> --reason "Missing verification" --json

gridwonk admin orgs impersonate start <org-id> --reason "Support escalation follow-up" --json
gridwonk admin orgs billing-override set <org-id> --reason "Contract grace period" --json

gridwonk admin chatbot presets apply --preset-id <preset-id> --json
gridwonk admin chatbot capabilities update --payload '{"capabilities":[{"id":"cap-id","enabled":false}]}' --json
gridwonk admin chatbot mcp-servers update <server-id> --payload '{"enabled":false}' --json

admin users — Platform User Operations

gridwonk admin users list
gridwonk admin users get <profile-id>
gridwonk admin users update <profile-id> [--action approve|reject] [--rejection-reason <text>] [--role user|admin]
gridwonk admin users deactivate <profile-id>
gridwonk admin users reinvite <profile-id>
gridwonk admin users reset-password <profile-id>
gridwonk admin users bulk-approve --ids <id-1>,<id-2>
gridwonk admin users bulk-reject --ids <id-1>,<id-2> --reason "<text>"

admin orgs — Organization Admin Operations

gridwonk admin orgs list
gridwonk admin orgs get <org-id>
gridwonk admin orgs members list <org-id>
gridwonk admin orgs grants list <org-id>
gridwonk admin orgs impersonation-audit [--organization-id <org-id>]
gridwonk admin orgs impersonate start <org-id> --reason "<text>"
gridwonk admin orgs impersonate stop [--organization-id <org-id>]
gridwonk admin orgs billing-override set <org-id> --reason "<text>" [--expires-at <iso-date>]
gridwonk admin orgs billing-override clear <org-id>

admin monitoring — Benchmark And Session Ops

gridwonk admin monitoring performance trends --agent-id <agent-id>
gridwonk admin monitoring performance agent <agent-id>
gridwonk admin monitoring sessions list [--utility <name>] [--status <status>]
gridwonk admin monitoring diagnosis-check [--yes] [--dry-run] [--json]

The diagnosis check requires platform-admin authority and explicit approval to send a synthetic system incident to the configured operational Slack channel and reserve at most $0.10 for its private-queue AI assessment. Without --yes, the command asks for confirmation; --dry-run sends nothing. Only one attempt is allowed per 24 hours across operators and deployments. No customer data or prompt is accepted. A queued result does not prove inference or Slack delivery; verify the matching incident ID and completion log. With the operational Slack bot configured, the assessment is a reply beneath the original synthetic alert; it does not request Claude triage. Native Vercel Agent billing is separate.

admin chatbot — Chatbot Runtime Administration

gridwonk admin chatbot access-rules list
gridwonk admin chatbot access-rules create --payload '<json>'
gridwonk admin chatbot access-rules update --payload '<json>'
gridwonk admin chatbot access-rules delete --ids <id-1>,<id-2>

gridwonk admin chatbot tools list
gridwonk admin chatbot tools create --payload '<json>'
gridwonk admin chatbot tools update --payload '<json>'

gridwonk admin chatbot mcp-servers list
gridwonk admin chatbot mcp-servers get <server-id>
gridwonk admin chatbot mcp-servers update <server-id> --payload '<json>'

gridwonk admin chatbot presets list
gridwonk admin chatbot presets create --payload '<json>'
gridwonk admin chatbot presets update --payload '<json>'
gridwonk admin chatbot presets delete --ids <id-1>,<id-2>
gridwonk admin chatbot presets apply --preset-id <preset-id>

gridwonk admin chatbot capabilities get [--category <name>]
gridwonk admin chatbot capabilities update --payload '<json>'
gridwonk admin chatbot ai-elements get
gridwonk admin chatbot ai-elements update --payload '<json>'
gridwonk admin chatbot prompt-preview --utility <name>

changes — Change Monitoring

gridwonk --org <org-id> changes subscriptions list
gridwonk --org <org-id> changes subscriptions create --utility <utility-key> [--state <ST>]
gridwonk --org <org-id> changes subscriptions delete <subscription-id>
gridwonk --org <org-id> changes status --utility <utility-key> [--state <ST>]
gridwonk --org <org-id> changes events list [--utility <utility-key>] [--state <ST>]

sessions — Org Session Visibility

gridwonk --org <org-id> sessions list [--utility <name>] [--agent <type>] [--status <status>]

utilities — Utility Catalog

gridwonk utilities match --name "Duke Energy" --state NC
gridwonk utilities list --state CA --type iou
gridwonk utilities search --query "municipal electric"

docs — Document Operations

gridwonk docs classify --text "$(cat extracted-document.md)"
gridwonk docs classify --file ./extracted-document.md
gridwonk docs digitize --document-id <uuid> [--table <name>] [--utility <name>]

docs classify accepts text or extracted markdown. It rejects PDFs directly; upload PDFs through packet intake (the packets commands), then classify the extracted text. The former docs upload command was removed with the legacy 3 MiB upload on 2026-09-30.

Both docs commands are deprecated pre-packet compatibility adapters. They still work unchanged and are not scheduled for removal, but packet workflows use Storage-native intake and the pinned, authoritative role-decision flow instead. New integrations should target those rather than building on docs classify / docs digitize.

assist — Low-Cost CLI Assistant

gridwonk assist --prompt "Summarize Duke Energy NC site-control requirements"
gridwonk assist --prompt "Answer from this context" --context ./requirements.md --stream

ferc — Utility Analytics Exports

gridwonk --org <org-id> ferc analytics [--start-date <date>] [--end-date <date>]
gridwonk --org <org-id> ferc export [--start-date <date>] [--end-date <date>]

agents — AI Agent Operations

gridwonk agents list                        # List available agent IDs
gridwonk agents chat --utility <name> \
  [--state <ST>] [--message <text>] \
  [--session-id <id>]                        # Chat with an agent
gridwonk agents execute --agent-id <id> \
  --utility <name> --query <text> \
  [--state <ST>] [--watch]                   # Execute a named agent

Single-message mode (non-interactive):

gridwonk agents chat --utility "PG&E" \
  --message "What docs do I need for 5MW solar?" --json

Human-readable responses append a de-duplicated Sources list when the answer has citations. With --json, the response is NDJSON — one JSON event per line from the SSE stream, including structured source events.

Interactive mode (no --message flag) opens a full-screen Ink chat TUI with keyboard input and streaming responses.

Agent execution with --watch streams job progress via SSE:

gridwonk agents execute --agent-id procedures-discovery-agent \
  --utility "Duke Energy" --query "Refresh procedure documents" --watch

jobs — Async Job Management

gridwonk jobs list [--status <s>] \
  [--type <t>] [--limit <n>]                 # List jobs (table UI)
gridwonk jobs get <job-id>                   # Job details
gridwonk jobs cancel <job-id>                # Cancel a running job
gridwonk jobs watch <job-id>                 # Live SSE progress bar

Cancelling an authorized packet-review job also settles its linked active review and prevents late packet results without deleting completed document findings. It does not broaden the key's job-organization scope. A successful CLI cancellation is not proof that an already-running provider request stopped. Use the project's Review Actions → Cancel Packet Review control or ask support to confirm runtime-stop warnings before retrying a stuck packet.

Illustrative jobs list output: Ink renders an auto-formatted table:

┌──────────┬─────────────┬──────────┬──────────┐
│ ID       │ Type        │ Status   │ Progress │
├──────────┼─────────────┼──────────┼──────────┤
│ abc12345 │ compliance  │ complete │ 100%     │
│ def67890 │ discovery   │ running  │ 42%      │
└──────────┴─────────────┴──────────┴──────────┘

jobs watch provides a live progress bar and status updates powered by Server-Sent Events:

gridwonk jobs watch abc12345

With --json, the stream is output as NDJSON:

gridwonk jobs watch abc12345 --json
# {"type":"job.update","data":{"status":"running","progress":42}}
# {"type":"job.update","data":{"status":"running","progress":85}}
# {"type":"job.complete","data":{"status":"complete","progress":100}}

webhooks — Webhook Subscriptions

gridwonk webhooks list                       # List subscriptions
gridwonk webhooks get <id>                   # Details + delivery attempts
gridwonk webhooks create --url <url> \
  [--events <e...>] [--secret <s>]           # Create subscription
gridwonk webhooks update <id> \
  [--url <url>] [--events <e...>] \
  [--active <bool>]                          # Update subscription
gridwonk webhooks delete <id>                # Delete subscription

Webhook secrets are masked in terminal output (only last 4 characters shown).

The existing --events option also accepts the five utility.* families documented in Webhooks. Their schema activation and production release remain separately held. Subscription management still requires the existing management-key authority, and utility events are scoped to the receiving utility organization. Subscribing does not grant notice-sending or human-decision permission. There is no new CLI command for provider receipts or resetting an exhausted utility-event delivery.

keys — API Key Management

gridwonk keys list [--status <s>]                   # List org API keys
gridwonk keys create --name <name> \
  [--env <live|test>] [--rpm <number>]               # Create a new key
gridwonk keys get <id>                               # Key details
gridwonk keys update <id> \
  [--name <name>] [--status <s>] [--rpm <number>]   # Update key
gridwonk keys revoke <id>                            # Permanently revoke key
SubcommandDescription
listList API keys for the authenticated organization. Filter by --status (active, suspended, revoked).
createCreate a new API key. The plaintext key is shown once — store it securely.
getShow key details including usage stats and rate limits.
updateUpdate key name, status (active/suspended), or rate limit.
revokePermanently revoke a key. Cannot be undone. Self-revoke is blocked.

keys update --allowed-endpoints <csv> accepts a comma-separated list. It trims entries, removes empty entries between commas, and preserves order and duplicates. Omitting the option or passing --allowed-endpoints "" leaves allowedEndpoints out of the request. Whitespace-only or comma-only input sends an explicit empty list (allowedEndpoints: []); it is not equivalent to omission. Use keys update --dry-run --json with the key ID and proposed options to inspect the parsed settings before confirming a change. Existing access requirements are unchanged.

Example — create and list keys:

$ gridwonk keys create --name "CI Pipeline" --env test --rpm 120
Key created: gw_test_...
WARNING: Store this key securely. It will not be shown again.

$ gridwonk keys list --status active --json
{"data":{"keys":[...],"total":3}}

apps — Application Queries

gridwonk apps query [--utility <name>] \
  [--status <s>] [--limit <n>] \
  [--include-reports]                        # Query applications

requirements — Utility Requirements

gridwonk requirements published --utility <name> \
  [--state <ST>] \
  [--category <cat>] \
  [--ix-type <T|D>] \
  [--limit <n>] [--offset <n>]                # Query published requirements

Categories: site_control, technical_specs, forms, fees

requirements published

The current command. It wraps the SDK queryPublishedRequirements() method, which calls GET /api/v1/published-requirements, and prints the response summary followed by each requirement with its cited sources. --limit accepts 1-200 (default 50); when more rows remain, the renderer tells you to page with --offset.

The capability manifest assigns both this replacement command and the console Requirements view to published-requirements; the legacy capability no longer claims the UI destination.

Coverage is everything published except utility-rejected rows, with honest gaps:

  • The utility name is not fuzzy-resolved. This command sends your input straight through and lets the server resolve it exactly (name, then canonical slug). An unknown utility returns an honest empty result rather than a guessed neighbour.
  • Only utility-rejected rows are omitted. Every other published row is returned. With --json, each row carries reviewStatus: approved (utility reviewers signed off) or pending (awaiting a current utility decision). In the human-readable output, pending rows are marked [pending utility review]. A decision made stale by a later change reverts that row to pending; it is never dropped.
  • With --json, data.releaseStatus (released, partially_released, review_incomplete, or not_published) reports the utility's review progress. It does not gate what comes back — a review_incomplete scope still returns its rows.
  • --category fees always returns an empty set — the published store has no fee role.
  • Rows whose published wording is still under review are withheld and reported in the summary. That is a separate mechanism from reviewStatus.
gridwonk requirements published --utility "nashville-electric-service" --state TN --category forms --json

The old requirements query and requirements list aliases have been removed. Existing scripts must migrate to requirements published.

deficiencies — Deficiency Reports

gridwonk deficiencies query \
  [--utility <name>] [--severity <level>] \
  [--status <state>] [--location-status <state>] \
  [--finding-state <state>] [--remediation-status <state>] [--include-anchors] \
  [--limit <n>]                              # Query deficiency reports

Severity levels: critical, high, medium, low

--status is a backward-compatible alias that accepts either location states (exact, approximate, unresolved, pending) or remediation states (open, in_progress, pending_revalidation, resolved, wont_fix). Use --include-anchors when you need source and working-copy anchor details.

usage — API Usage Statistics

gridwonk usage [--days <n>]                  # Default: 30 days

mcp — MCP Protocol Operations

gridwonk mcp tools                           # List available MCP tools
gridwonk mcp call --method <method> \
  [--params <json>]                          # Call MCP JSON-RPC method

Example — query published requirements via MCP:

gridwonk mcp call --method tools/call \
  --params '{"name":"query_published_requirements","arguments":{"utility":"nashville-electric-service","state":"TN"}}'

The MCP commands reach the same public MCP gateway described in MCP Servers. The CLI does not own MCP tool definitions; it lists and calls the current gateway projection, which is backed by lib/mcp/public-tool-definitions.ts and checked against the Canonical Capability Manifest. query_published_requirements therefore behaves exactly like gridwonk requirements published, including the all-except-rejected rule and per-row reviewStatus. The old public MCP query_requirements tool has been removed. The internal chat-runtime tool that shares its short name is separate and always reads published Packet Intake requirements — see Requirement Lookups.

prompts — Prompt Inspection and History

gridwonk prompts list [--agent <id>] \
  [--status <status>]                        # List prompt versions
gridwonk prompts diff <v1> <v2>             # Show diff between versions

The former write commands are not registered and make no API request. Read authentication and historical source labels remain unchanged.

evals — Evaluation Runs

Run dispatch currently accepts only the checked-in deterministic location and digitizer Markdown datasets. An optional path must equal that agent's registered path; arbitrary paths are rejected. Paid chatbot runs are unavailable until immutable target reconstruction and server-owned spending approval exist. Stored or copied approval fields do not authorize a run. History/report remain readable.

gridwonk evals list [--agent <id>] \
  [--status <status>]                        # List eval runs
gridwonk evals run --agent <id> \
  [--dataset <path>]                         # Trigger an eval run
gridwonk evals report <run-id>              # Show eval run details

config — CLI Configuration

gridwonk config show                         # Display config (keys masked)
gridwonk config set <key> <value>            # Set apiKey or baseUrl
gridwonk config unset <key>                  # Remove a config value
gridwonk config path                         # Show config file location

whoami — Authentication Context

gridwonk whoami                              # Inspect local auth state + key source; no API request

Illustrative output: The base URL is the effective locally configured API origin. Run a read command such as utilities list --state CA --json to verify the credential with the server.

Authenticated
  Key:      gw_...cdef
  Source:   config
  Base URL: <configured API origin>

completion — Shell Completions

# Bash
eval "$(gridwonk completion bash)"

# Zsh (add to .zshrc)
eval "$(gridwonk completion zsh)"

# Fish
gridwonk completion fish | source

Command Aliases

Full CommandAlias
requirementsreq
deficienciesdef
utilitiesutil
remediationrem
webhookswh

Aliases can be used anywhere the full command name is accepted:

gridwonk req published --utility "nashville-electric-service" # same as: gridwonk requirements published
gridwonk def query --severity high     # same as: gridwonk deficiencies query
gridwonk rem export create             # same as: gridwonk remediation export create

Exit Codes

CodeMeaningSDK Error Class
0Success—
1General errorError
2Authentication errorAuthenticationError
3Not foundNotFoundError
4Rate limitedRateLimitError
5Server errorGridWonkError (status >= 500)

AI Agent Integration

The --json flag makes every command consumable by AI coding agents. Combined with exit codes, the CLI becomes structured tooling for automated pipelines.

This runnable document pipeline requires an authenticated CLI, jq, and the id of a document that already exists in a packet (upload it through packet intake first):

GRIDWONK_CLI=(gridwonk)

DIGITIZE_JSON="$("${GRIDWONK_CLI[@]}" docs digitize \
  --document-id "$DOCUMENT_ID" \
  --json)"

printf '%s' "$DIGITIZE_JSON" | jq -er '.data | {success, alreadyDigitized}'

Application session IDs are not document IDs. Query applications as a separate read-only pipeline, using a supported status such as active:

gridwonk apps query --utility "PJM" --status active --json | \
  jq -r '.data.applications[].id'

Streaming commands (agents chat, jobs watch) output NDJSON when --json is set — one JSON object per line, suitable for incremental parsing.

Binary Distribution

The CLI can also be installed as a standalone binary (no Node.js required). The bun compile build produces a single-file gridwonk executable for each platform.

GitHub Releases: Automated via .github/workflows/cli-release.yml. Each release publishes binaries for macOS (arm64, x64) and Linux (x64).

# Download and install (macOS arm64 example)
curl -L https://github.com/GridWonk/gridwonk/releases/latest/download/gridwonk-darwin-arm64 -o gridwonk
chmod +x gridwonk
sudo mv gridwonk /usr/local/bin/

The binary bundles all dependencies — the SDK, Ink UI, and Commander CLI framework — into a single executable. No npm install or GitHub Packages token is required.

gridwonk packets (partner lane)

Partner packet intake and review. Every command requires a partner-scoped access token (POST /api/v1/oauth/token with scope=partner.read partner.write) passed as the API key — raw operator keys are refused on these endpoints.

CommandDescription
packets intake createCreate a Storage-native intake and receive upload authorization (--submission, --idempotency-key, --file-name, --mime-type, --size-bytes; optional --replace-document, or both --batch and --batch-item)
packets intake finalize <intakeId>Prove the uploaded object and start processing
packets intake status <intakeId>Safe processing status projection
packets intake-batches reserve --submission <id> --idempotency-key <key> --source-kind <loose|archive> --items <json>Reserve an immutable 1–12 item upload manifest; identical retries return the original batch
packets intake-batches status <batchId> --submission <id>Read batch and item status
packets intake-batches heartbeat <batchId> --submission <id>Extend an active batch's idle deadline
packets intake-batches pair <batchId> --submission <id> (--batch-item <id>|--archive-entry <id>) [--target-version <id>]Pair an inspected DWG item to a current site plan
packets intake-batches cancel-item <batchId> --submission <id> --item <id>Cancel one unfinished item
packets intake-batches abandon <batchId> --submission <id>Abandon an unfinished batch
packets archive-intake create --submission <id> --file-name packet.zip --size-bytes <n> [--idempotency-key <key>] [--batch <id> --batch-item <id>]Reserve a ZIP; a retry key is required without both batch identifiers
packets archive-intake status <archiveId> --submission <id>Read safe archive and entry progress
packets archive-intake finalize <archiveId> --submission <id>Finalize or resume processing using the same archive identity
packets archive-intake abandon <archiveId> --submission <id>Retire an archive still uploading
packets intake cancel <intakeId>Cancel an unaccepted document upload
packets intake reauthorize <intakeId>Create a new byte-zero upload attempt, keeping the intake ID
packets intake retry-processing <intakeId>Retry accepted internal processing failures, up to three user cycles
packets documents list --submission <id>Documents with current roles and preserved classifier lineage
packets documents attach <assetId> --submission <id>Attach an owner-organization File Library asset to an editable packet
packets documents delete <documentId> --submission <id>Permanently delete a document from a draft or resubmission working set after confirmation
packets documents review <documentId> --submission <id> [--retry-failed]Start or reuse one exact document review (120/hour per user+org, plus the organization review budget)
packets documents text <documentId> --submission <id> --version-id <id>Sanitized OCR text + coordinates
packets documents set-role <documentId> --role <role>Correct or explicitly confirm a content role; a correction re-runs the analysis applicable to that role
packets review start --submission <id>Start an applicant or eligible utility packet review through the shared review budget (50/hour per user+org); active, unexpired upload batches return HTTP 409 until settled, abandoned, or expired
packets review get <runId> --submission <id>Review run with the cited deficiency report, coverage, and recorded per-check outcomes
packets status --submission <id>Canonical workflow status + immutable packages
packets screening --submission <id>Utility-only package-bound screening status
packets documents pdf <documentId> --submission <id> --version-id <id> [--package <id>]Short-lived signed URL for the accepted sanitized rendition (never the original upload); prints the typed preparing/unavailable status while the rendition is cold

All three document mutations use the standard confirmation prompt and accept --yes or --dry-run. Dry-run prints the planned request without contacting the server, so it does not prove authorization. Use --retry-failed only with packets documents review; the MCP review tool does not expose that option.

gridwonk utility (utility partner lane)

Utility draft creation and shape changes validate capacity before sending it: invalid numbers are refused by both direct commands and the interactive navigator. The API accepts capacities from 0.000001 through 99999999.999999 MW in whole-watt increments and returns 409 when an application number already belongs to the utility organization.

A utility organization's partner-scoped token (partner.read) reads its own Applications workspace. The organization comes from the token; no flag selects another organization.

Utility screening uses the existing packets review start --submission <id> command with partner.write; the server selects utility authority. It requires the utility cohort, matching utility identity, an eligible application stage, and current write membership. It cannot screen a developer draft or use a utility-issued consultant grant to enter the utility lane.

For a formal application in pending, queued, or resubmitted, the command records screening together with the queued review before work is dispatched. Completion moves it to screened; a failed start or run restores the prior status when no other utility review is active. Console, REST, SDK, and MCP starts use these same transitions. Re-screening preserves existing decisions and notice states, and utility-owned drafts keep their package-freeze path.

CommandPurpose
utility applications list [--query] [--screening-status] [--generation-type] [--min-capacity-mw] [--max-capacity-mw] [--sort-by] [--sort-order] [--limit] [--offset] [--include-drafts]The Applications queue with canonical workflow statuses
utility applications get --submission <id> [--package <id>]One application with its package-bound detail (summary only, package: null, for a utility-owned draft)
utility applications packages --submission <id>Every immutable submitted package, newest first
utility applications findings --submission <id> --package <id>The pinned review, report snapshot, adjudication ledger, and screening decision of one package
utility applications history --submission <id>The immutable application history
utility applications create [--application-number] [--project-name] [--capacity-mw] [--interconnection-level] [--program] [--request-key]Create one utility-owned draft (partner.write); a blank number is generated
utility applications batch-create --manifest <file.json> [--request-key]Create a manifest of drafts in one retry-safe call (partner.write). Rows take the same fields as create; a row with an unknown or misspelled field, or without an applicationNumber, is refused before anything is sent
utility applications shape --submission <id> [--capacity-mw] [--interconnection-level] [--declared-tier-slug | --clear-declared-tier-slug]Set a utility-owned draft's capacity, level, and program (partner.write)
utility applications freeze --submission <id>Manually freeze an eligible utility-owned draft; returns the immutable package identity (partner.write)
utility adjudicate --submission <id> --package <id> --run <id> --finding <id> --decision <decision> --expected-version <n> [--rationale <text>]Record accept, dismiss, defer, or edit against the exact latest package/run/finding; use version 0 for the first decision
utility screening complete --submission <id> --package <id>Complete the exact latest package's screening; a repeat reports already complete, not project approval
utility study-requirement set --submission <id> --scope-description <text> --requirement-text <text> [--case-reference <text>]Record a requirement for the next submission while the current screened round remains open
utility notices list --submission <id>Read notice summaries for the application (partner.read)
utility notices get --submission <id> --notice <id>Read exact application-bound notice content and delivery progress (partner.read)
utility notices create --submission <id> --package <id>Create a package-bound draft from current finding decisions (partner.write)
utility notices edit --submission <id> --notice <id>Edit permitted draft/review content; finding provenance is server-owned (partner.write)
utility notices submit/approve/return/revoke/acknowledge --submission <id> --notice <id>Perform the named lifecycle edge, never an arbitrary status assignment (partner.write)
utility notices send --submission <id> --notice <id> --recipient-email <address>Commit a send request using an eligible address on file (partner.write)

Mutations honor the global --dry-run and --yes flags.

The notice commands are implemented in the dependent utility-notice stack; deployment and schema activation remain separate approvals. They require current direct utility membership, and writes require a writer role. A notice from a different application is refused even within the same organization. API send recipients must be the recorded applicant address or an active, unexpired owner/admin/member address in the applicant organization. No command lists contact addresses. Pending, held and provider-accepted delivery are reported separately from canonical notice status; none proves inbox delivery. A repeated finalized send or acknowledgment reports no change. See notice contracts before retrying.

All four manual-decision commands require partner.write and a current utility writer role. They use the console's shared cores and are excluded from MCP. --dry-run makes no HTTP request and does not prove server authorization. Dismiss, defer, and edit require --rationale; an edit also requires one or more of --edit-title, --edit-description, --edit-recommendation, and --edit-severity. Refresh the package findings after a version conflict. Study requirements leave the existing frozen package and report unchanged. See the utility lane guide for lifecycle constraints and receipts.

Salesforce has no dedicated CLI binding. The connector is implemented but disabled, and ordinary packet commands cannot recapture or edit source-owned evidence. Reads of those copies require the effective human viewer's current Salesforce permissions. If a utility queue query matches more than 200 Salesforce-owned applications, narrow its filters; lowering --limit alone does not reduce the permission-check candidate set.

During a temporary Salesforce permission-check outage, utility applications list keeps ordinary and successfully authorized applications available and prints a partial-list/count warning. JSON output includes salesforceReadUnavailable: true; rows and total exclude unverified source applications. Retry the command to recheck live permissions. No old permission result is reused.

The partner CLI can confirm or correct a role, but it does not expose the platform-admin aggregate that counts later human changes to automatic assignments. That measurement remains read-only and internal; it does not add a CLI activation switch.

Combined-PDF splitting remains console-only. ZIP expansion uses packets archive-intake and the same owner checks and file limits as the packet API. Create prints short-lived upload authorization: keep that output private. Upload the bytes, then finalize. Retry a 503 WORKFLOW_START_FAILED using the same archive or intake ID. Utility ZIP uploads accept PDF, PNG and JPEG; native CAD remains excluded. Mutations support --dry-run and require the normal confirmation or --yes.

Native-CAD companion intake has no CLI binding. Use the console or partner REST routes so the exact site-plan version and direct binary upload authorization remain explicit. Interactive CAD visualization and preflight also remain console-only; the CLI receives neither native DWG bytes nor Autodesk viewer tokens.

On this page