# Contractor Agents CLI Design ## Purpose Define the plugin-owned CLI surface for managing contractor-backed OpenClaw agents. Phase 1 supports Claude only. Gemini remains reserved in the command shape but is not implemented yet. ## Command root ```bash openclaw contractor-agents ``` This should be implemented as a plugin-owned CLI root, not as a patch to `openclaw agents add`. ## Why a separate command root Current OpenClaw plugin docs show support for plugin CLI registration, but do not document support for extending existing core commands with new flags. Relevant doc statements: > "Common registration methods: ... `registerCommand` / `registerCli` | CLI commands" > "For plugin-owned root CLI commands, prefer `api.registerCli(..., { descriptors: [...] })` ..." This suggests the supported extension seam is plugin-owned CLI trees. Sources: - https://docs.openclaw.ai/tools/plugin - https://docs.openclaw.ai/plugins/sdk-entrypoints ## Phase 1 command ```bash openclaw contractor-agents add --agent-id --workspace --contractor ``` Phase 1 restrictions: - `--contractor` must currently be `claude` - `gemini` is accepted only as a reserved future value if desired, but should currently fail with a clear not-yet-implemented message unless you intentionally decide to reject it at parsing time ## Arguments ### Required - `--agent-id ` - `--workspace ` - `--contractor ` ### Optional, possible later Not required for first implementation, but likely useful later: - `--bridge-model ` - `--backend ` - `--mode ` - `--json` - `--non-interactive` For now, phase 1 can hardcode the bridge model and runtime defaults. ## Behavior of `add` For: ```bash openclaw contractor-agents add --agent-id my-agent --workspace /path/to/ws --contractor claude ``` The CLI should do the following. ### Step 1, validate inputs - ensure `agent-id` is provided - ensure workspace exists or is creatable, based on your desired policy - ensure contractor kind is supported - ensure target agent does not already exist unless overwrite behavior is explicitly added later ### Step 2, create the base OpenClaw agent Run the equivalent of: ```bash openclaw agents add --workspace --model contractor-claude-bridge --non-interactive ``` Important note: Earlier review of `openclaw agents add` docs showed these supported options: > `--workspace ` > `--model ` > `--agent-dir ` > `--bind ` > `--non-interactive` > `--json` Source: - https://docs.openclaw.ai/cli/agents This means the contractor CLI can compose the existing agent creation flow rather than replacing it. ### Step 3, mark the agent as a contractor-backed agent After agent creation, write contractor metadata so runtime selection and session bridging can identify this agent as contractor-managed. Proposed config direction: ```json5 { agents: { list: [ { id: "my-agent", model: "contractor-claude-bridge", runtime: { type: "contractor", contractor: { kind: "claude", backend: "acp", mode: "persistent" } } } ] } } ``` Exact schema is still TBD, but the CLI should be the mechanism that writes this state. ### Step 4, initialize contractor runtime state Prepare runtime state for the agent, including a place to store session mappings. Suggested path: ```text /.openclaw/contractor-agent/ ``` Suggested initial files: ```text session-map.json runtime.json ``` ## Session mapping responsibility The CLI does not create Claude sessions immediately unless you explicitly want eager setup. Recommended phase 1 behavior: - create agent metadata - create runtime state directory - initialize empty mapping file - defer real Claude session creation to first actual agent turn This keeps `add` lightweight and avoids unused contractor sessions. ## Suggested future commands These are not required immediately, but the command tree should reserve room for them. ### Status ```bash openclaw contractor-agents status --agent-id ``` Show: - contractor kind - bridge model id - runtime backend - session mapping count - recent activity ### List sessions ```bash openclaw contractor-agents sessions --agent-id ``` Show session mappings for the given contractor-backed agent. ### Reset mapping ```bash openclaw contractor-agents reset-session --agent-id --openclaw-session ``` Drop a specific OpenClaw-to-Claude mapping so the next message recreates the Claude session. ### Disable ```bash openclaw contractor-agents disable --agent-id ``` Either: - remove contractor metadata but keep agent - or mark the contractor runtime disabled Semantics TBD. ## JSON output I recommend all subcommands eventually support `--json` so this can be scripted. Example success response shape: ```json { "ok": true, "agentId": "my-agent", "workspace": "/path/to/ws", "contractor": "claude", "model": "contractor-claude-bridge", "runtimeStateDir": "/path/to/ws/.openclaw/contractor-agent" } ``` ## Failure cases The CLI should fail clearly for: - unsupported contractor kind - agent already exists - workspace invalid or inaccessible - bridge model plugin not available - failure in underlying `openclaw agents add` - failure writing contractor metadata If the agent is created successfully but metadata writing fails, the CLI should either: - roll back the created agent if safe and simple - or return a partial-failure error with explicit cleanup instructions Phase 1 recommendation: prefer explicit rollback if implementation is reliable. ## Interaction with the bridge model The CLI should not directly run Claude Code or create a Claude contractor session by default. Its main job is to provision an agent whose primary model is the contractor bridge model: - `contractor-claude-bridge` That model then handles runtime dispatch during actual conversation turns. ## Implementation notes The plugin should register a root command owned by the plugin. Relevant doc statements: > "For plugin-owned root CLI commands, prefer `api.registerCli(..., { descriptors: [...] })` when you want the command to stay lazy-loaded without disappearing from the root CLI parse tree." Source: - https://docs.openclaw.ai/plugins/sdk-entrypoints So the intended shape is: - plugin registers `contractor-agents` - plugin owns parsing and handling of its subcommands - plugin composes `openclaw agents add` behavior internally or via shared config/runtime helpers ## Open questions 1. Should the CLI shell out to `openclaw agents add` or use a lower-level config/runtime helper directly? 2. Where should contractor metadata live, `agents.list[].runtime`, plugin config, or both? 3. Should `gemini` be rejected now or accepted with a not implemented error? 4. Should add create the workspace if it does not exist? 5. Should agent creation be rolled back if contractor metadata writing fails? ## References ### Plugin CLI support > "Common registration methods: ... `registerCommand` / `registerCli` | CLI commands" Source: - https://docs.openclaw.ai/tools/plugin ### Plugin-owned CLI descriptors > "For plugin-owned root CLI commands, prefer `api.registerCli(..., { descriptors: [...] })` ..." Source: - https://docs.openclaw.ai/plugins/sdk-entrypoints ### Existing agent creation command > `agents add [name]` > `--workspace ` > `--model ` > `--agent-dir ` > `--bind ` > `--non-interactive` > `--json` Source: - https://docs.openclaw.ai/cli/agents