diff --git a/README.md b/README.md index adc318c..fbd8064 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,9 @@ npm install -g @orgloop/agentctl Requires Node.js >= 20. +Public adapters currently shipped in the CLI: `claude-code`, `codex`, `opencode`, `pi`, `pi-rust`, and `openclaw`. +ACP-backed adapter work is in progress internally, but adapters such as `codex-acp` are not user-visible until packaging and discover-first session reattachment are ready. + ## Quick Start ```bash diff --git a/docs/adr/adr-001-agentctl-adopts-acp.md b/docs/adr/adr-001-agentctl-adopts-acp.md index e07089b..e33009e 100644 --- a/docs/adr/adr-001-agentctl-adopts-acp.md +++ b/docs/adr/adr-001-agentctl-adopts-acp.md @@ -26,6 +26,16 @@ Research ([acpx-vs-agentctl analysis](obsidian://open?vault=My%20Notes&file=Proj **agentctl will adopt ACP as its primary agent interface strategy.** +### Rollout boundary + +This ADR describes the architectural direction, not a claim that ACP-backed adapters are already production-ready in the public CLI. + +Until an ACP adapter has: +- a packaged/distributed bridge story (or explicit documented prerequisite), and +- discover-first rediscovery / reattach semantics that survive a fresh CLI process or daemon restart, + +it should remain experimental and not be registered as a public adapter. + ### Principles 1. **Ride on ACP, don't fight it.** agentctl's CLI and internal APIs should align with ACP primitives (sessions, prompts, cancel, permissions). Where ACP provides a clean abstraction, use it rather than reinventing. diff --git a/src/cli.test.ts b/src/cli.test.ts index 9eadf03..00a4457 100644 --- a/src/cli.test.ts +++ b/src/cli.test.ts @@ -85,6 +85,18 @@ describe("launch --adapter flag (#74)", () => { // Should reference the requested adapter in the error, not silently use claude-code expect(stderr).not.toContain("Launched session"); }); + + it("rejects codex-acp with a targeted experimental message", async () => { + const { stderr } = await run([ + "launch", + "--adapter", + "codex-acp", + "-p", + "test", + ]); + expect(stderr).toContain("not publicly shipped yet"); + expect(stderr).toContain("use 'codex' for now"); + }); }); describe("shortId (#71)", () => { diff --git a/src/cli.ts b/src/cli.ts index 3a2df65..42af17a 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -13,7 +13,6 @@ import { fileURLToPath } from "node:url"; import { Command } from "commander"; import { ClaudeCodeAdapter } from "./adapters/claude-code.js"; import { CodexAdapter } from "./adapters/codex.js"; -import { createCodexAcpAdapter } from "./adapters/codex-acp.js"; import { OpenClawAdapter } from "./adapters/openclaw.js"; import { OpenCodeAdapter } from "./adapters/opencode.js"; import { PiAdapter } from "./adapters/pi.js"; @@ -47,7 +46,6 @@ import { createWorktree, type WorktreeInfo } from "./worktree.js"; const adapters: Record = { "claude-code": new ClaudeCodeAdapter(), codex: new CodexAdapter(), - "codex-acp": createCodexAcpAdapter(), openclaw: new OpenClawAdapter(), opencode: new OpenCodeAdapter(), pi: new PiAdapter(), @@ -101,6 +99,14 @@ function getAdapter(name?: string): AgentAdapter { if (!name) { return adapters["claude-code"]; } + + if (name === "codex-acp") { + console.error( + "Adapter 'codex-acp' is not publicly shipped yet. The ACP bridge packaging and discover-first rediscovery story are still incomplete, so use 'codex' for now.", + ); + process.exit(1); + } + const adapter = adapters[name]; if (!adapter) { console.error(`Unknown adapter: ${name}`);