Imported from amittell/agentcli (
AGENTS.md). Install upstream withnpx skills add amittell/agentcli. Copyright stays with the author.
AGENTS
Purpose
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.
Working Rules
- 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.
Error Handling
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.
Discovery Flow
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.
Useful Commands
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
Coordination protocol (mandatory)
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.
Repo-scoped tokens (v0.42+)
On a shared coord service that fronts several repos, use a repo-scoped token so you only ever see and touch your own repo's claims. The server enforces the scope from the token, so list_claims / check_conflicts return just your repo no matter what the client sends.
If a tool result carries a coord_notice -- or coord status prints a Token warning: line -- your token is unscoped and deprecated: on a shared service it sees and can affect every repo's claims. It is still honored for now, but switch. Ask an operator for a scoped token and drop it in .coordination/local.env:
coord tokens create <engineer> --repo <owner/name>
Operator-wide reads are opt-in with all_repos=True (a scoped token gets a 403, not a silent all-repo view). Rollout detail: docs/deployment.md.
Sub-file (symbol-level) claims (v0.14+)
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.
Queueing instead of bouncing (v0.21+)
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).
Asking the holder directly (v0.6+ / v0.11+ decisions)
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.
Operator visibility
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.