agentcli is the agent-native control plane for workflow manifests. It is not the durable runtime.
Use this repo when the task is about:
- manifest authoring
- validation
- compile target behavior
- scheduler inspection surfaces
- JSON-RPC / MCP style integration
Do not reimplement scheduler durability here. Runtime concerns belong in openclaw-scheduler.
- Prefer machine-readable output and raw JSON payloads.
- Pass
--jsonto force structured JSON output from any command (includinghelp), exceptservewhich runs the JSON-RPC server on stdio. - Keep manifests backend-portable unless the task explicitly targets
openclaw-scheduler. - Default compile target is
standalone. - Treat
openclaw-scheduleras an adapter/backend, not as the core abstraction. - Preserve agent-safe behavior: safe output paths, strict validation, field masks, and sanitization.
All CLI errors are written to stderr as JSON with the following shape:
{
"ok": false,
"error": "Human-readable error message",
"error_type": "validation_error | unknown_command | invalid_argument | parse_error | internal_error"
}Use error_type for structured dispatch rather than parsing the error string. Validation errors include an additional validation field with the full error and warning arrays.
When first interacting with agentcli, use this sequence:
agentcli version-- confirm the package and manifest spec versionagentcli describe commands-- enumerate all available CLI commandsagentcli describe rpc-- enumerate JSON-RPC methods and notificationsagentcli targets-- list available compile targets with capabilitiesagentcli schema manifest-- get the machine-readable manifest schema
For JSON-RPC integrations, use agentcli.version and agentcli.describe with target: "rpc" to discover the method surface programmatically.
agentcli version-- show package and manifest spec versionagentcli init-- bootstrap a local home directory with a starter manifestagentcli targets-- list available compilation targetsagentcli paths-- show resolved home directory layoutagentcli schema manifest-- emit machine-readable schema for the manifest formatagentcli describe commands-- list all CLI commands with summariesagentcli validate examples/hello-world.jsonagentcli compile examples/hello-world.json --target standalone --explainagentcli compile examples/hello-world.json --target openclaw-scheduleragentcli apply <manifest> --adopt-by name --dry-run-- preview migration of existing scheduler jobsagentcli inspect jobs --db /path/to/scheduler.sqlite --fields id,statusagentcli approve <manifest> <task-id> --by <principal> --reason <text>-- grant a local single-use approval for a gated taskagentcli approvals list [--status pending|consumed|expired|revoked|all]-- list approval recordsagentcli approvals revoke <approval-id> --by <principal> --reason <text>-- revoke a pending approvalagentcli exec <manifest> <task-id> --approval-id <id>-- target a specific pending grantagentcli serve
Multi-agent file coordination via the coord MCP server. Required calls every session:
list_claimsat task start.claim_filesbefore editing.release_claims(orrelease_sessionto drop everything this MCP session holds, v0.6+) when done.
If claim_files returns conflicts, stop and ask the user. No edits outside claimed scope; no opportunistic refactors; shared config edits only with explicit user approval.
When two agents need different parts of the same file, claim symbols instead of whole files. Pass symbols={"src/auth/login.ts": ["handleLogin"]} to claim_files so the claim scopes to just that function. Two agents on disjoint symbols of the same file auto-coexist with no 409.
Foo::handleA(v0.16): method-level notation. Sibling methods of the same class auto-coexist; the bare class blocks all of its methods.Outer::Inner::method(v0.17): recursive nesting works to any depth.- Server-side validation (v0.17): when
COORD_REPO_ROOTis set, the server rejects symbols that do not exist in the file with a hint listing what is parseable. The MCP wrapper pre-validates locally before POST so typos fail fast; disable withCOORD_DISABLE_CLIENT_VALIDATION=1.
When a hot file is contested and your work is blocking the team, pass wait_seconds=60 to claim_files. The request joins a FIFO queue behind the blocking holder; on release the next queued requester is auto-granted. Pair with urgency='low' | 'normal' | 'high' | 'blocking' (v0.25) to jump ahead of lower-priority waiters; long-waiting entries age-boost one level after COORD_QUEUE_AGE_BOOST_SECONDS (v0.26). Abandon a wait early via cancel_queue_request(queue_id, engineer=...) (v0.26). Inspect your own queue rows via my_requests(queued=True) (v0.22).
If queueing will not work either:
request_releasefiles an explicit ask against the holder's claim. The holder's TTL shortens; their decision lands back in yourmy_requestsview.respond_to_requestdecisions (v0.11+):approved(release whole claim),denied(keep it),narrowed(close the claim, open a tighter one -- passnarrowed_pattern),coexist(let the requester have a sibling claim on the same scope -- passcoexist_pattern).coexistis cooperative not enforced; agents on the same file still handle imports and module-level state themselves.
Poll pending_requests between operations to see who is blocked on your scope and respond via respond_to_request. The dashboard surfaces hotspot files, an auto-resolution heatmap, and a pending-queue panel for ambient awareness.