From cbd4abfa953b793ad16e50c7376f5dda34421d6e Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Sun, 6 Sep 2026 14:01:15 +0000 Subject: [PATCH] feat(codex): open native agents overview with managed runtime --- README.md | 23 +++++++++++++++++++++-- package.json | 2 +- src/cli-schema.mjs | 5 +++-- src/commands.mjs | 2 +- src/engines.mjs | 15 ++++++++++++--- test/engines.test.mjs | 27 ++++++++++++++++++++++++++- 6 files changed, 64 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 00c20964..5fc1cfc8 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ or miss one that does. A test fails the build when it drifts. | command | group | what it does | |---|---|---| -| `moshcode agents` | engines | list engines or launch one autonomously | +| `moshcode agents` | engines | list engines, open their agent view, or launch autonomously | | `moshcode start` | engines | launch an engine with its native defaults | | `moshcode herd` | runtime | run agent sessions that outlive this terminal | | `moshcode ps` | runtime | list herd sessions and what each one is doing | @@ -107,7 +107,7 @@ use this only in an isolated container, VM, or workspace you trust: moshcode agents claude # claude agents --dangerously-skip-permissions (agent view) moshcode agents opencode # opencode --auto (autonomous) moshcode agents privacycode # privacycode --auto (autonomous) -moshcode agents codex # codex --dangerously-bypass-approvals-and-sandbox (autonomous) +moshcode agents codex # codex --dangerously-bypass-approvals-and-sandbox agents (agent view) moshcode agents gemini # gemini --approval-mode=yolo (autonomous) moshcode agents kimi # kimi --yolo (autonomous) moshcode agents qwen # qwen --approval-mode=yolo (autonomous) @@ -116,6 +116,25 @@ moshcode agents aider # aider --yes-always moshcode agents openagents # openagents (dashboard) ``` +Codex's native agents overview requires a CLI with `codex agents` support +(verified with 0.151.0) and, for the local daemon, the managed standalone +installation. `moshcode install codex` / `moshcode upgrade codex` use Codex's +official standalone installer on macOS/Linux; an npm-only install is not enough. +Existing npm installations are preserved. Windows retains npm and requires +`--remote ` for the agents overview. +`/agents codex` opens the same live overview of sessions on Codex's shared local +app-server daemon. The approval/sandbox bypass is passed for this invocation; +moshcode does not rewrite your global Codex settings or stop existing sessions. +Additional arguments are forwarded to the native `agents` subcommand, for example +`moshcode agents codex --no-alt-screen`. + +For separate conversations, Codex's `/new` starts a fresh chat in the same CLI, +`/resume` reopens a saved chat, and `/fork` branches a conversation while preserving +the original. These commands are distinct from launching parallel subagents: +ask Codex to delegate work, then use its `/agent` or `/subagents` picker to switch +threads. See the [Codex command reference](https://learn.chatgpt.com/docs/developer-commands?surface=cli) +and [subagent guide](https://learn.chatgpt.com/docs/agent-configuration/subagents). + `start` is the explicit raw path. It injects nothing, so the native engine keeps its normal permission model and receives only your arguments: diff --git a/package.json b/package.json index 1a27ce36..478292c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "moshcode", - "version": "0.93.0", + "version": "0.94.0", "type": "module", "description": "moshcode \u2014 a metal wrapper for coding engines and native UGig/CoinPay workflow CLIs, with OpenPRD and moshscript", "repository": { diff --git a/src/cli-schema.mjs b/src/cli-schema.mjs index e05c31e9..c5709202 100644 --- a/src/cli-schema.mjs +++ b/src/cli-schema.mjs @@ -35,7 +35,7 @@ export const CORE_CLI_COMMANDS = [ { name: "agents", group: "engines", - description: "list engines or launch one autonomously", + description: "list engines, open their agent view, or launch autonomously", synopsis: [ ["moshcode agents", "list engines and their install status"], ["moshcode agents --json", "list engine status as machine-readable JSON"], @@ -48,6 +48,7 @@ export const CORE_CLI_COMMANDS = [ ["moshcode agents", "which engines are here"], ["moshcode agents --json", "pipe engine status into a script"], ["moshcode agents claude", "claude's agent list"], + ["moshcode agents codex", "Codex's shared-daemon agents overview (CLI 0.151.0+)"], ], seeAlso: ["start", "engines", "install"], note: "autonomous modes bypass approval prompts — use them in a container or a workspace you trust.", @@ -1518,7 +1519,7 @@ export const PIT_COMMANDS = [ { name: "new", pitOnly: true, description: "open and switch to another moshcode tab" }, { name: "agents", aliases: ["agent", "engines"], args: "[name]", cli: "agents", - description: "list engines, or launch one autonomously" }, + description: "list engines, open their agent view, or launch autonomously" }, { name: "start", args: " [args…]", cli: "start", description: "raw launch; inject no engine arguments" }, { name: "herd", args: "[verb] [args…]", cli: "herd", diff --git a/src/commands.mjs b/src/commands.mjs index 12779cf8..026762f6 100644 --- a/src/commands.mjs +++ b/src/commands.mjs @@ -826,7 +826,7 @@ const COMMANDS = [ cliVerb("run", "run another .mosh file (include)"), // shortcut: ai() runs an engine headlessly and RETURNS its output (see PRD R17) aiVerb, - cliVerb("agents", "launch an autonomous agent session (moshcode agents )"), + cliVerb("agents", "open the native agent view or launch autonomously (moshcode agents )"), cliVerb("herd", "drive the herd (moshcode herd ) — see herdStart/herdWait for values"), cliVerb("ps", "print the herd roster"), cliVerb("cost", "print what the herd is spending (moshcode cost [name] [--all])"), diff --git a/src/engines.mjs b/src/engines.mjs index 26650387..1d03ec6e 100644 --- a/src/engines.mjs +++ b/src/engines.mjs @@ -5,8 +5,8 @@ // // `agentsView` (optional) is the exact argv that opens the engine's native // agent list/view — used by `/agents ` when the engine actually has one -// (currently claude). It's the FULL leading args (subcommand + any flags that -// subcommand accepts). Engines without an `agentsView` fall back to +// (currently Claude and Codex). It's the FULL leading args, including root +// flags before the subcommand when required. Engines without an `agentsView` fall back to // `agentArgs` — an autonomous session with native approvals // bypassed/auto-approved. Do not use a machine-readable, one-shot list command // as an agents view: `/agents` promises to hand the terminal to a live session. @@ -131,7 +131,16 @@ export const ENGINES = { desc: "Codex — OpenAI's coding CLI", bin: "codex", agentArgs: ["--dangerously-bypass-approvals-and-sandbox"], - install: { cmd: "npm", args: ["install", "-g", "@openai/codex"] }, + // Codex 0.151.0+: live shared-daemon session overview. The bypass option + // belongs to the root command, not the `agents` subcommand. + agentsView: ["--dangerously-bypass-approvals-and-sandbox", "agents"], + // The local agents daemon requires the installer-managed standalone + // package; npm alone can launch chats but cannot bootstrap that daemon. + // Windows uses a remote agents server and retains its npm installation. + install: process.platform === "win32" + ? { cmd: "npm", args: ["install", "-g", "@openai/codex"] } + : { cmd: "bash", args: ["-o", "pipefail", "-c", "curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh"] }, + binDirs: [path.join(homedir(), ".local", "bin")], resume: ["resume", "--last"], state: { blocked: [/\ballow (?:this )?command\b/i, /\bapprove this (?:command|edit|change)\b/i], diff --git a/test/engines.test.mjs b/test/engines.test.mjs index b99084fc..ee51b842 100644 --- a/test/engines.test.mjs +++ b/test/engines.test.mjs @@ -39,7 +39,7 @@ const EXPECTED_LAUNCH_ARGS = { opencode: ["--auto"], privacycode: ["--auto"], claude: ["agents", "--dangerously-skip-permissions"], - codex: ["--dangerously-bypass-approvals-and-sandbox"], + codex: ["--dangerously-bypass-approvals-and-sandbox", "agents"], gemini: ["--approval-mode=yolo"], kimi: ["--yolo"], // no agents view — kimi has no agent list to land on qwen: ["--approval-mode=yolo"], @@ -136,6 +136,31 @@ for (const [key, expected] of Object.entries(EXPECTED_LAUNCH_ARGS)) { }); } +test("Codex installs the managed runtime needed by its local agents daemon", () => { + if (process.platform === "win32") { + assert.deepEqual(ENGINES.codex.install, { cmd: "npm", args: ["install", "-g", "@openai/codex"] }); + } else { + assert.equal(ENGINES.codex.install.cmd, "bash"); + assert.deepEqual(ENGINES.codex.install.args.slice(0, 3), ["-o", "pipefail", "-c"]); + assert.match(ENGINES.codex.install.args[3], /https:\/\/chatgpt\.com\/codex\/install\.sh/); + assert.match(ENGINES.codex.install.args[3], /CODEX_NON_INTERACTIVE=1 sh$/); + } + assert.ok(ENGINES.codex.binDirs.includes(path.join(homedir(), ".local", "bin"))); +}); + +test("Codex overview keeps the root bypass before agents and preserves native view options", async () => { + const nativeBin = tempDir(); + writeEngine(nativeBin, "codex"); + const extra = ["--no-alt-screen", "-C", "/tmp/project with spaces", "-c", 'model="gpt-6-astra"']; + const result = await run(["agents", "codex", ...extra], nativeBin); + assert.equal(result.status, 0); + assert.deepEqual(JSON.parse(result.stdout), [ + "--dangerously-bypass-approvals-and-sandbox", "agents", ...extra, + ]); + assert.deepEqual(ENGINES.codex.agentArgs, ["--dangerously-bypass-approvals-and-sandbox"]); + assert.deepEqual(ENGINES.codex.resume, ["resume", "--last"]); +}); + test("bare engine launch remains a raw passthrough", async () => { const nativeBin = tempDir(); mkdirSync(nativeBin, { recursive: true });