Context
Claude Code CLI has shipped significant updates from v2.1.60 through v2.1.76. A cross-reference of the changelog against agentrun's current backend support identified 4 actionable gaps. Codex and OpenCode were also audited — no meaningful gaps found (their recent changes are UI/plugin/config-level with no wire format impact).
All actionable items are Claude-side. The existing option plumbing works end-to-end: callers like crucible-pro set StationConfig.Options → flows into Session.Options → Claude backend reads in appendSessionArgs(). The only missing piece is the constant definitions and flag mappings in agentrun.
Items
1. OptionSessionName — root option → Claude --name
What: New -n/--name <name> flag sets a display name for the session. Cross-cutting concept (session naming is universal), so the option constant belongs in the root package.
Where:
session.go: Add OptionSessionName = "session_name" constant
engine/cli/claude/claude.go:appendSessionArgs(): Map to --name <value> with null-byte guard + leading-dash guard
- Codex/OpenCode: silently ignore (no equivalent flag)
Caller usage (e.g., crucible-pro config):
stations:
inspector:
options:
session_name: "Inspector Station"
Effort: ~20 lines
2. OptionRemoteControl — Claude-specific option → --remote-control
What: Enables Remote Control on spawned sessions. This bridges the local subprocess to claude.ai/code and the Claude mobile app, letting users monitor/interact with agent sessions from any device.
Where:
engine/cli/claude/claude.go: Add OptionRemoteControl = "claude.remote_control" constant
engine/cli/claude/claude.go:appendSessionArgs(): ParseBoolOption → append --remote-control when true
- Only Claude backend — Codex/OpenCode have no equivalent
Important caveats (document in godoc):
- Requires claude.ai OAuth authentication (won't work with API keys, Bedrock, Vertex)
- Session URL appears in stderr (consumers can capture via
cli.WithStderrWriter)
- Untested: verify
-p --output-format stream-json --remote-control works together before merging. The docs show interactive use; programmatic + RC may need validation.
Caller usage:
stations:
inspector:
backend: claude
options:
claude.remote_control: "true"
session_name: "Inspector Station"
Effort: ~15 lines + manual smoke test
3. Deprecate EffortMax
What: Claude Code removed "max" from effort levels (now low/medium/high only, changelog). Our root package still defines EffortMax Effort = "max" and Valid() returns true for it. The Claude backend silently skips it (claude.go:254: e != agentrun.EffortMax). Codex maps it to "xhigh", OpenCode passes it through.
Decision needed: Since agentrun is greenfield with no backwards-compat concerns (per CLAUDE.md), consider removing EffortMax entirely rather than just deprecating:
- Remove from
session.go (constant + Valid() check)
- Remove from
engine/cli/claude/claude.go skip guard (becomes unnecessary)
- Remove mapping from
engine/cli/codex/codex.go and engine/cli/opencode/opencode.go
- Update tests that reference
EffortMax
Alternative: Keep for Codex/OpenCode which do support a "max" equivalent, and only document it as unsupported on Claude. This is the safer choice if Codex xhigh or OpenCode max variant are valuable to consumers.
Effort: ~5 lines (deprecate) or ~30 lines (remove + test updates)
4. Parse rate_limit_event (optional, lower priority)
What: Claude CLI now emits rate_limit_event in the JSONL stream with quota status and reset times. Currently falls through to MessageSystem in the parser. Example from live output:
{"type":"rate_limit_event","rate_limit_info":{"status":"allowed","resetsAt":1773360000,"rateLimitType":"five_hour","overageStatus":"rejected"}}
Options:
- A) New
MessageRateLimit type in root — structured rate limit data
- B) Keep as
MessageSystem — raw data accessible via msg.Raw
- C) Skip entirely — consumers who need this can check
msg.Raw
Recommendation: Option B (no code change) or C. Rate limit data is observability, not control flow. Consumers can already access it via msg.Raw on system messages. Adding a new MessageType for a single backend's event may not meet the "2+ backends" bar from DESIGN.md.
Effort: 0 (skip) to ~30 lines (new type)
What Was Audited and Found Not Actionable
| Feature |
Why Skip |
Remote Control server mode (claude remote-control --spawn) |
Different execution model (multi-session server), not subprocess spawning |
Channels (--channels) |
Plugin/interactive feature; channel messages appear as standard MessageToolUse/MessageToolResult — already parsed |
| Elicitation messages |
MCP interactive input; requires bidirectional user flow not modeled by Process.Send() |
| HTTP hooks |
Config-level hook transport, not wire format |
| Worktree sparse paths |
Config-level git setting |
Codex exec_wait → wait rename |
Tool name passthrough, no parser impact |
| Codex hooks engine |
Hook system, not wire format |
| OpenCode workspace ID |
Already handled via Session.CWD |
| OpenCode auth flags |
User concern, not library concern |
Implementation Notes
- Items 1-2 follow the exact pattern of existing options in
appendSessionArgs() — see OptionEffort, OptionAddDirs, OptionAllowedTools for reference
- Item 2 needs a manual smoke test: spawn a Claude session with
-p --output-format stream-json --remote-control and verify the JSONL stream works + remote URL appears in stderr
- Item 3 decision (deprecate vs remove) should be made during planning based on whether any consumer uses Codex
xhigh effort
- All items are additive — no breaking changes to existing API
References
Context
Claude Code CLI has shipped significant updates from v2.1.60 through v2.1.76. A cross-reference of the changelog against agentrun's current backend support identified 4 actionable gaps. Codex and OpenCode were also audited — no meaningful gaps found (their recent changes are UI/plugin/config-level with no wire format impact).
All actionable items are Claude-side. The existing option plumbing works end-to-end: callers like crucible-pro set
StationConfig.Options→ flows intoSession.Options→ Claude backend reads inappendSessionArgs(). The only missing piece is the constant definitions and flag mappings in agentrun.Items
1.
OptionSessionName— root option → Claude--nameWhat: New
-n/--name <name>flag sets a display name for the session. Cross-cutting concept (session naming is universal), so the option constant belongs in the root package.Where:
session.go: AddOptionSessionName = "session_name"constantengine/cli/claude/claude.go:appendSessionArgs(): Map to--name <value>with null-byte guard + leading-dash guardCaller usage (e.g., crucible-pro config):
Effort: ~20 lines
2.
OptionRemoteControl— Claude-specific option →--remote-controlWhat: Enables Remote Control on spawned sessions. This bridges the local subprocess to claude.ai/code and the Claude mobile app, letting users monitor/interact with agent sessions from any device.
Where:
engine/cli/claude/claude.go: AddOptionRemoteControl = "claude.remote_control"constantengine/cli/claude/claude.go:appendSessionArgs():ParseBoolOption→ append--remote-controlwhen trueImportant caveats (document in godoc):
cli.WithStderrWriter)-p --output-format stream-json --remote-controlworks together before merging. The docs show interactive use; programmatic + RC may need validation.Caller usage:
Effort: ~15 lines + manual smoke test
3. Deprecate
EffortMaxWhat: Claude Code removed "max" from effort levels (now low/medium/high only, changelog). Our root package still defines
EffortMax Effort = "max"andValid()returns true for it. The Claude backend silently skips it (claude.go:254:e != agentrun.EffortMax). Codex maps it to"xhigh", OpenCode passes it through.Decision needed: Since agentrun is greenfield with no backwards-compat concerns (per CLAUDE.md), consider removing
EffortMaxentirely rather than just deprecating:session.go(constant +Valid()check)engine/cli/claude/claude.goskip guard (becomes unnecessary)engine/cli/codex/codex.goandengine/cli/opencode/opencode.goEffortMaxAlternative: Keep for Codex/OpenCode which do support a "max" equivalent, and only document it as unsupported on Claude. This is the safer choice if Codex
xhighor OpenCodemaxvariant are valuable to consumers.Effort: ~5 lines (deprecate) or ~30 lines (remove + test updates)
4. Parse
rate_limit_event(optional, lower priority)What: Claude CLI now emits
rate_limit_eventin the JSONL stream with quota status and reset times. Currently falls through toMessageSystemin the parser. Example from live output:{"type":"rate_limit_event","rate_limit_info":{"status":"allowed","resetsAt":1773360000,"rateLimitType":"five_hour","overageStatus":"rejected"}}Options:
MessageRateLimittype in root — structured rate limit dataMessageSystem— raw data accessible viamsg.Rawmsg.RawRecommendation: Option B (no code change) or C. Rate limit data is observability, not control flow. Consumers can already access it via
msg.Rawon system messages. Adding a new MessageType for a single backend's event may not meet the "2+ backends" bar from DESIGN.md.Effort: 0 (skip) to ~30 lines (new type)
What Was Audited and Found Not Actionable
claude remote-control --spawn)--channels)MessageToolUse/MessageToolResult— already parsedProcess.Send()exec_wait→waitrenameSession.CWDImplementation Notes
appendSessionArgs()— seeOptionEffort,OptionAddDirs,OptionAllowedToolsfor reference-p --output-format stream-json --remote-controland verify the JSONL stream works + remote URL appears in stderrxhigheffortReferences