OpenWOP openwop.dev

The OpenWOP CLI @openwop/cli · zero runtime dependencies

The protocol, from your terminal.

@openwop/cli is the host-agnostic control plane for any OpenWOP-compatible host — a single openwop command that drives the protocol from your terminal. It is a reference client, not an engine: every command surfaces a capability the host advertises at /.well-known/openwop, sends the wire shape the host expects, and renders the host's resolved view. It bundles to a single file with zero runtime dependencies and ships independently of the spec corpus.

# install
npm install -g @openwop/cli
openwop --version

# point it at a host
export OPENWOP_BASE_URL=https://app.openwop.dev/api
openwop capabilities      # read /.well-known/openwop
openwop doctor            # connectivity + advertised-capability check
A 74-second narrated film, with English captions. An agent says a job is done; how do you know it is? The film shows the idea in pictures: a tool that first asks a system what it can do, tells you when work has really finished, says when it is waiting for a person, and says so plainly when something is not available. The small command cards show real output from the openwop CLI. A scripted illustration.

Safe to script against a shared host

Three properties hold for every command, so the CLI is safe to script against a shared host. Meaningful exit codes make commands scriptable: 0 ok, 3 escalated / pending, 1 failed (with per-group nuances documented in --help).

  1. 1Capability-honest, fail closedA command drives a surface only when the host advertises it. When the host doesn't, the command fails closed with a legible message and a non-zero exit — never a stack trace, never a fabricated success.
  2. 2The host is the authorityPolicy, RBAC, toggle/variant resolution, consent, approvals, and goal/proposal completion are all decided host-side. The CLI renders the host's decision; it never computes or asserts one locally.
  3. 3Secrets are refs, never valuesBYOK keys, OAuth client secrets, SAML certs, and SCIM tokens stay host-side. The CLI handles refs and status only, and runs every response through a redactor before output — nothing secret is printed, logged, or written to local config.

Command groups

Point at a host and run openwop --help for the live list. The groups cluster by area:

Setup & health
onboarddoctorcapabilitiesconfig
Run lifecycle
runschatinterruptsworkflowscatalogmedia
Agents & orchestration
agentsrosterworkforces (fleet)a2a
Governance & safety
approvalsgovernance (policy)consenttoggles
Identity & access
usersprofilesauth (sso)
Extensibility & connections
packsmcpconnections (conn)providersbyok
Memory & workspace
memoryworkspaceprompts
Automation & messaging
cronwebhookstriggersmessagingrelaynotifications
Observability
analytics (usage)

Agent-platform capabilities

Three higher-level capabilities for driving an agent platform — each capability-gated, so the group activates only when the host advertises it.

  • proposals

    Reviewable learning

    An agent's learned change is stored as an inert proposal.

  • goals

    Standing goals

    A durable objective the host pursues across runs until a judge verdicts it satisfied or a bound stops it.

  • export / import

    Portability

    Move reusable estate — agents, packs, schedules, rosters, templates — between hosts as a refs-only bundle.

  • triggers

    Trigger bridge

    Bind an external webhook / email / form source to a workflow, then let a verified inbound event start a run with the payload as ctx.triggerData.

  • a2a

    Durable A2A tasks

    When a host advertises a2a.durableTasks, every backing run carries a persisted A2ATaskState (taskId === runId) that survives caller disconnect, host restart, and HITL pauses.

The full reference

Install, hosts, the contract, every command group, the agent-platform capabilities and the channel relay.

Install

npm install -g @openwop/cli
openwop --version

One-off, no install (handy in CI or a scratch shell):

npx -y @openwop/cli@latest --help

Requires Node 22+ to install (the one-line installer ensures it; the package's engines floor is ≥ 20). Channel adapters for Discord and WhatsApp are optional peer dependencies — install them only if you use those channels.

Point it at a host

The CLI reads OPENWOP_BASE_URL (or --base-url) and OPENWOP_API_KEY (or --api-key). Discovery needs no credential, so against the reference deployment these work straight away:

export OPENWOP_BASE_URL=https://app.openwop.dev/api
openwop capabilities      # read /.well-known/openwop
openwop doctor            # connectivity + advertised-capability check

Protocol calls — creating a run, listing runs — need an API key; without one the host answers 401. To get a key for the reference deployment, sign in at app.openwop.dev, open Access → API keys, and create a key with the CLI — act as me preset. It covers the protocol surface and workspace commands such as openwop agents list and openwop workflows register. Run workflows is for scripts that only start and read runs: the host answers 403 when such a key reaches a workspace command. Read only cannot start a run. The key is shown once, with the two lines the CLI reads:

export OPENWOP_BASE_URL=https://app.openwop.dev/api
export OPENWOP_API_KEY=owk_…

The key is read from --api-key, then OPENWOP_API_KEY, then openwop config set host.apiKey. The CLI sends it in the Authorization header. A key acts as the account that created it, expires after 90 days by default, and can be revoked on the same screen.

From CLI 1.4.0 you can skip copying a key. openwop login shows a short code; type it on the same Access → API keys page under "Sign in the OpenWOP CLI" and approve it. The host issues the CLI a 30-day key, saved to your config and listed in the app as CLI: <label>; openwop logout revokes it. Approve a code only if you just ran openwop login yourself.

export OPENWOP_BASE_URL=https://app.openwop.dev/api
openwop login

A new account starts with no workflows, so register one before you create a run:

cat > hello.json <<'JSON'
{"workflowId":"walk-hello","name":"Walk hello","nodes":[{"nodeId":"done","typeId":"core.noop","config":{}}],"edges":[]}
JSON
openwop workflows register hello.json
openwop runs create walk-hello --wait

To run against a host of your own instead, the quickstart starts one locally with a development key, and the install page covers a full deployment.

openwop onboard saves your host URL and stores your own model-provider key (BYOK) on the host. It does not sign you in or issue an OpenWOP API key.

The in-app command reference — with one-click copyable snippets, rendered against whatever host you're pointed at — lives at app.openwop.dev/cli.

How it behaves — the contract

Three properties hold for every command, so the CLI is safe to script against a shared host:

  • Capability-honest, fail closed. A command drives a surface only when the host advertises it. When the host doesn't, the command fails closed with a legible message and a non-zero exit — never a stack trace, never a fabricated success.
  • The host is the authority. Policy, RBAC, toggle/variant resolution, consent, approvals, and goal/proposal completion are all decided host-side. The CLI renders the host's decision; it never computes or asserts one locally.
  • Secrets are refs, never values. BYOK keys, OAuth client secrets, SAML certs, and SCIM tokens stay host-side. The CLI handles refs and status only, and runs every response through a redactor before output — nothing secret is printed, logged, or written to local config.

Meaningful exit codes make commands scriptable: 0 ok, 3 escalated / pending, 1 failed (with per-group nuances documented in --help).

Command groups

Point at a host and run openwop --help for the live list. The groups cluster by area:

AreaGroups
Setup & healthonboard · doctor · capabilities · config
Run lifecycleruns · chat · interrupts · workflows · catalog · media
Agents & orchestrationagents · roster · workforces (fleet) · a2a
Governance & safetyapprovals · governance (policy) · consent · toggles
Identity & accessusers · profiles · auth (sso)
Extensibility & connectionspacks · mcp · connections (conn) · providers · byok
Memory & workspacememory · workspace · prompts
Automation & messagingcron · webhooks · triggers · messaging · relay · notifications
Observabilityanalytics (usage)

Agent-platform capabilities

Three higher-level capabilities for driving an agent platform — each capability-gated, so the group activates only when the host advertises it.

Reviewable learning — proposals

An agent's learned change is stored as an inert proposal. It does nothing until a human reviews it and applies it through the host's activation gate (which may route through an approval). The CLI renders the host's verdict and never activates locally.

openwop proposals list --state pending
openwop proposals revise prop_123 --artifact-json '{"systemPrompt":"…"}'
openwop proposals apply prop_123          # host materializes + routes through its activation mode

Standing goals — goals

A durable objective the host pursues across runs until a judge verdicts it satisfied or a bound stops it. Completion is the judge's verdict — there is no satisfy verb, and the CLI never declares victory from the client. A bounds-less goal is refused when the host requires bounds, so unattended continuation always terminates.

openwop goals create --objective "Keep the triage backlog under 20" \
  --judge verifier --continuation schedule --max-iterations 50
openwop goals pause goal_123

Portability — export / import

Move reusable estate — agents, packs, schedules, rosters, templates — between hosts as a refs-only bundle. Secrets never travel as values; the bundle reports secretsToRebind references you bind at the destination. Always dry-run first; apply is idempotent and re-owns every entity to you.

openwop export --kinds agent --kinds schedule --out estate.json
openwop import estate.json --dry-run      # preview creates/updates/skips/conflicts (no writes)
openwop import estate.json                 # apply

Trigger bridge — triggers

Bind an external webhook / email / form source to a workflow, then let a verified inbound event start a run with the payload as ctx.triggerData. The host verifies the source, drops duplicates, and tracks each binding's state (active, paused, failed, dead-lettered). The CLI registers the subscription and shows that state.

A webhook binding secret is returned once at creation; the CLI prints the fingerprint and never persists the value.

openwop triggers register --source webhook --workflow wf_intake --dedup --verification required
openwop triggers list --state active
openwop triggers get tgsub_123            # exit code reflects state: 0 active · 3 paused · 1 failed

Durable A2A tasks — a2a

When a host advertises a2a.durableTasks, every backing run carries a persisted A2ATaskState (taskId === runId) that survives caller disconnect, host restart, and HITL pauses. status shows what the host advertises; task reads one durable task's live state. The record is content-free — no run inputs, outputs, artifacts, or credentials — and the CLI renders the host's projection rather than deriving a state locally.

openwop a2a status
openwop a2a task <taskId>                  # exit: 0 completed · 3 in-progress/needs-input · 1 failed

Channel relay (optional)

The messaging and relay commands are a non-normative host extension: the CLI can run a local adapter that bridges a chat channel (Signal, iMessage, WhatsApp, Discord) into a workflow or agent on the host. The CLI pairs with the host over an authenticated session via a short code; channel-side auth lives only in the local adapter process and never reaches the host as a primary credential.

Source

@openwop/cli is on npm; source, docs, and the issue tracker are at github.com/openwop/openwop-cli. The CLI evolves additively within the current major.

Drive any host.

@openwop/cli is on npm; source, docs, and the issue tracker are at github.com/openwop/openwop-cli. The CLI evolves additively within the current major.