Files
ContractorAgent/docs/claude/CLI.md

308 lines
7.6 KiB
Markdown

# 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 <agent-id> --workspace <workspace> --contractor <claude|gemini>
```
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 <agent-id>`
- `--workspace <workspace>`
- `--contractor <claude|gemini>`
### Optional, possible later
Not required for first implementation, but likely useful later:
- `--bridge-model <model-id>`
- `--backend <acp-backend>`
- `--mode <persistent|oneshot>`
- `--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 <agent-id> --workspace <workspace> --model contractor-claude-bridge --non-interactive
```
Important note:
Earlier review of `openclaw agents add` docs showed these supported options:
> `--workspace <dir>`
> `--model <id>`
> `--agent-dir <dir>`
> `--bind <channel[:accountId]>`
> `--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
<workspace>/.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 <agent-id>
```
Show:
- contractor kind
- bridge model id
- runtime backend
- session mapping count
- recent activity
### List sessions
```bash
openclaw contractor-agents sessions --agent-id <agent-id>
```
Show session mappings for the given contractor-backed agent.
### Reset mapping
```bash
openclaw contractor-agents reset-session --agent-id <agent-id> --openclaw-session <session-key>
```
Drop a specific OpenClaw-to-Claude mapping so the next message recreates the Claude session.
### Disable
```bash
openclaw contractor-agents disable --agent-id <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 <dir>`
> `--model <id>`
> `--agent-dir <dir>`
> `--bind <channel[:accountId]>`
> `--non-interactive`
> `--json`
Source:
- https://docs.openclaw.ai/cli/agents