From e7a60f1ea1aacfb7af0243ae961d3df542bf1cec Mon Sep 17 00:00:00 2001 From: "Doink (OpenClaw)" Date: Mon, 9 Mar 2026 13:09:58 -0700 Subject: [PATCH] fix: gate codex-acp until it is actually shippable --- README.md | 3 +++ docs/adr/adr-001-agentctl-adopts-acp.md | 10 ++++++++++ src/cli.test.ts | 12 ++++++++++++ src/cli.ts | 10 ++++++++-- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6471e37..cca4c5c 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,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 3f18653..2780b75 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 a94e583..6614abd 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"; @@ -42,7 +41,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(), @@ -95,6 +93,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}`);