cclaw-cli 0.39.1 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -134,7 +134,7 @@ Cursor dispatch is real isolation.
134
134
  const OPENCODE_PLAYBOOK = `---
135
135
  harness: opencode
136
136
  fallback: role-switch
137
- description: "OpenCode has plugin-based dispatch hooks but no isolated subagent worker primitive. cclaw uses an in-session role-switch with a delegation-log entry + evidenceRefs."
137
+ description: "OpenCode has plugin-based dispatch hooks and a native structured-ask tool (question) but no isolated subagent worker primitive. cclaw uses an in-session role-switch with a delegation-log entry + evidenceRefs, and emits Decision Protocol calls through the question tool when it is permitted."
138
138
  ---
139
139
 
140
140
  # OpenCode — Parity Playbook
@@ -145,6 +145,22 @@ delegation gate by role-switching inside the same session: the agent
145
145
  announces the role, performs the work against the contract, and records
146
146
  evidence.
147
147
 
148
+ **Structured ask: native \`question\` tool.** OpenCode ships a first-class
149
+ \`question\` primitive (header + question text + options, plus a
150
+ "type custom" fallback; supports multi-question navigation). It is
151
+ permission-gated:
152
+
153
+ - \`opencode.json\` must grant \`permission.question: "allow"\` (or be
154
+ covered by a \`"*": "allow"\` default).
155
+ - ACP clients additionally need \`OPENCODE_ENABLE_QUESTION_TOOL=1\` set
156
+ on the \`opencode acp\` process.
157
+
158
+ When the tool is permitted, every Decision Protocol call maps to a single
159
+ \`question\` invocation. When it is denied or the host doesn't expose it,
160
+ fall back to the shared plain-text lettered list — same skeleton, same
161
+ artifact decision log. Full mapping:
162
+ \`.cclaw/references/harness-tools/opencode.md\`.
163
+
148
164
  ## Role-switch protocol
149
165
 
150
166
  1. Announce the role explicitly in a single message:
@@ -192,28 +208,55 @@ has either a \`completed\` row with evidenceRefs (role-switch) or a
192
208
  const CODEX_PLAYBOOK = `---
193
209
  harness: codex
194
210
  fallback: role-switch
195
- description: "OpenAI Codex has no subagent dispatch and no hooks. cclaw ships entry points as skills under .agents/skills/; mandatory delegations fall back to role-switch with evidenceRefs."
211
+ description: "OpenAI Codex exposes lifecycle hooks (v0.114+, gated by the codex_hooks feature flag) but no subagent dispatch and no custom slash commands. cclaw ships entry points as skills under .agents/skills/cc*/ and wires .codex/hooks.json; mandatory delegations fall back to role-switch with evidenceRefs."
196
212
  ---
197
213
 
198
214
  # OpenAI Codex — Parity Playbook
199
215
 
200
- Codex CLI exposes **neither a custom slash-command system nor a hooks
201
- API**. cclaw v0.39.0 acknowledged this and rewired the codex harness:
216
+ Codex CLI has a different shape from Claude/Cursor:
202
217
 
203
218
  - **Entry points are skills.** \`/cc\`, \`/cc-next\`, \`/cc-ideate\`,
204
219
  \`/cc-view\`, \`/cc-ops\` are generated as skills at
205
- \`.agents/skills/cclaw-cc/SKILL.md\` (and \`cclaw-cc-next/\`, etc.). They
206
- activate via Codex's native \`/use <skillName>\` command or
207
- automatically when the user's prompt mentions any of the
208
- \`/cc\`-style tokens (skill descriptions include them verbatim).
209
- - **No hooks.** Everything that Claude/Cursor get from
210
- \`SessionStart\` / \`PreToolUse\` / \`PostToolUse\` / \`Stop\` /
211
- \`PreCompact\` must run as explicit agent steps. The session rehydration,
212
- prompt-guard, workflow-guard, context-monitor, and stop-checkpoint
213
- behaviors are documented in \`.cclaw/skills/using-cclaw/SKILL.md\`.
214
- - **Legacy paths are dead.** \`.codex/commands/*\` and \`.codex/hooks.json\`
215
- are removed on every \`cclaw sync\`. Do not restore them by hand —
216
- Codex CLI never read either path.
220
+ \`.agents/skills/cc/SKILL.md\` (and \`cc-next/\`, \`cc-view/\`,
221
+ \`cc-ideate/\`, \`cc-ops/\`). They activate via Codex's native
222
+ \`/use <skillName>\` command or automatically when the user's prompt
223
+ mentions any of the \`/cc\`-style tokens (skill descriptions include
224
+ them verbatim). Codex CLI removed custom prompts in v0.89 (Jan 2026);
225
+ there is no way to register a true custom slash command.
226
+ - **Lifecycle hooks.** Codex CLI v0.114 (Mar 2026) exposes lifecycle
227
+ hooks at \`.codex/hooks.json\`, gated behind the experimental
228
+ \`[features] codex_hooks = true\` flag in \`~/.codex/config.toml\`.
229
+ cclaw writes \`.codex/hooks.json\` on sync; if the flag is off, the
230
+ file is simply inert and \`cclaw doctor\` emits a warning. \`cclaw init\`
231
+ offers to patch the flag with explicit user consent.
232
+ - **Tool interception is Bash-only.** Codex's \`PreToolUse\` and
233
+ \`PostToolUse\` events only fire for the \`Bash\` tool. \`Write\`,
234
+ \`Edit\`, \`WebSearch\`, and MCP tool calls are **not** gated by hooks.
235
+ cclaw partially compensates by also wiring \`UserPromptSubmit\` to
236
+ \`prompt-guard.sh\` so the stage routing check fires before the turn
237
+ executes, but workflow-guard (TDD red-first, artifact presence) only
238
+ fires on Bash turns. See the hook coverage matrix below.
239
+ - **Legacy paths.** \`.codex/commands/*\` was never consumed by Codex and
240
+ is removed on every \`cclaw sync\`. The v0.39.x \`.agents/skills/cclaw-cc*/\`
241
+ layout is replaced by \`.agents/skills/cc*/\` and the old folders are
242
+ auto-removed on sync. Do not restore either by hand.
243
+
244
+ ## Structured ask: native \`request_user_input\` tool
245
+
246
+ Codex exposes \`request_user_input\` — an experimental tool that accepts
247
+ 1-3 short questions and returns the user's answers in the same order.
248
+ It is the primitive the built-in Plan / Collaboration mode templates use
249
+ (see \`codex-rs/collaboration-mode-templates/templates/plan.md\`), and
250
+ agents running inside Codex can call it directly. Answers come back as
251
+ free-form strings, not option IDs — keep lettered options inline in the
252
+ question text so the user's reply maps cleanly to the artifact
253
+ decision log.
254
+
255
+ cclaw stage skills invoke \`request_user_input\` for every Decision
256
+ Protocol call when the tool is available, and fall back to the shared
257
+ plain-text lettered list when Codex returns a schema error or when the
258
+ current host hides the tool (older builds, non-collaboration mode). Full
259
+ mapping: \`.cclaw/references/harness-tools/codex.md\`.
217
260
 
218
261
  ## Fallback: role-switch
219
262
 
@@ -243,33 +286,57 @@ disabled in v0.33 and remains off.
243
286
 
244
287
  ## Invocation cheatsheet
245
288
 
246
- - \`/use cclaw-cc\` — open the \`/cc\` skill and pick a track.
247
- - \`/use cclaw-cc-next\` — advance the flow one stage.
248
- - \`/use cclaw-cc-ops\` — compound / archive / rewind.
289
+ - \`/use cc\` — open the \`/cc\` skill and pick a track.
290
+ - \`/use cc-next\` — advance the flow one stage.
291
+ - \`/use cc-ops\` — compound / archive / rewind.
249
292
  - Typing \`/cc …\` or \`/cc-next …\` in plain text also works: Codex
250
293
  matches the skill descriptions (which spell out these tokens) and
251
294
  auto-loads the right skill body.
252
295
  - Use Codex's built-in \`/skill\` UI to enable or disable
253
296
  cclaw skills per session.
254
297
 
255
- ## Hook substitution matrix
298
+ ## Feature flag — how to enable hooks
299
+
300
+ Codex CLI ignores \`.codex/hooks.json\` unless \`codex_hooks = true\`
301
+ appears under \`[features]\` in \`~/.codex/config.toml\`:
302
+
303
+ \`\`\`toml
304
+ [features]
305
+ codex_hooks = true
306
+ \`\`\`
307
+
308
+ \`cclaw init --codex\` prompts to write this automatically (one-line
309
+ diff, preserving the rest of \`config.toml\` untouched). Decline the
310
+ prompt to leave the file alone; the skill-level \`/use cc\` entry points
311
+ continue to work regardless.
312
+
313
+ ## Hook coverage matrix
256
314
 
257
- | Hook intent | Codex substitute |
258
- |-------------|------------------|
259
- | SessionStart rehydration | On first turn, the agent reads \`.cclaw/state/flow-state.json\` and \`.cclaw/knowledge.jsonl\` explicitly before acting. |
260
- | PreToolUse prompt-guard | The \`/cc\` skill body enforces task classification before writes. |
261
- | PreToolUse workflow-guard | The active stage skill enforces TDD / artifact gates before writes. |
262
- | PostToolUse context-monitor | End-of-turn budget check lives in \`.cclaw/references/protocols/ethos.md\`. |
263
- | Stop checkpoint | Stage-completion protocol updates \`.cclaw/state/flow-state.json\` in the same turn. |
264
- | PreCompact digest | Manual \`/cc-view status\` before \`/compact\`; the user triggers this. |
315
+ | Hook intent | Codex mapping | Coverage |
316
+ |-------------|---------------|----------|
317
+ | SessionStart rehydration | \`SessionStart\` matcher \`startup|resume\` \`session-start.sh\` | Full. |
318
+ | PreToolUse prompt-guard | \`PreToolUse\` matcher \`Bash\` + \`UserPromptSubmit\` \`prompt-guard.sh\` | Bash tool calls are gated inline; \`UserPromptSubmit\` catches prompts before any tool fires, so non-Bash writes (\`Write\`/\`Edit\`) are still prompt-guarded at the turn boundary. |
319
+ | PreToolUse workflow-guard | \`PreToolUse\` matcher \`Bash\` \`workflow-guard.sh\` | Bash-only. For \`Write\`/\`Edit\` calls the agent performs the TDD-order / artifact check in-turn (see the stage skill). |
320
+ | PostToolUse context-monitor | \`PostToolUse\` matcher \`Bash\` → \`context-monitor.sh\` | Bash-only. Other tool calls get context-monitored at end-of-turn via \`.cclaw/references/protocols/ethos.md\`. |
321
+ | Stop checkpoint | \`Stop\` \`stop-checkpoint.sh\` | Full. |
322
+ | PreCompact digest | Not supported — Codex has no \`PreCompact\` event. | Covered by \`/cc-ops retro\` and the user running \`/cc-view status\` before Codex's \`/compact\` command. |
265
323
 
266
324
  ## Verification
267
325
 
268
326
  \`cclaw doctor\` on a codex-enabled install checks:
269
327
 
270
- - \`shim:codex:cclaw-cc:present\` and \`frontmatter\` (plus the four
271
- utility skills).
272
- - No legacy \`.codex/commands/\` or \`.codex/hooks.json\` lingering.
328
+ - \`shim:codex:cc:present\` and \`frontmatter\` (plus the four utility
329
+ skills \`cc-next\`, \`cc-view\`, \`cc-ops\`, \`cc-ideate\`).
330
+ - \`hook:schema:codex\` validates \`.codex/hooks.json\` shape.
331
+ - \`hook:wiring:codex\` verifies the generated hooks reference every
332
+ runtime script cclaw needs (session-start, prompt-guard, workflow-guard,
333
+ context-monitor, stop-checkpoint).
334
+ - \`warning:codex:feature_flag\` is emitted as a warning (not an error)
335
+ when \`~/.codex/config.toml\` is missing the \`codex_hooks\` feature
336
+ flag — hooks silently do nothing in that state.
337
+ - \`warning:codex:legacy_commands_dir\` and
338
+ \`warning:codex:legacy_cclaw_cc_skills\` catch leftovers from older
339
+ cclaw versions.
273
340
  - Every mandatory agent for the active stage has a \`completed\` row
274
341
  with \`fulfillmentMode: "role-switch"\` and at least one \`evidenceRef\`.
275
342
  `;
@@ -17,4 +17,4 @@
17
17
  import type { HarnessId } from "../types.js";
18
18
  export declare const HARNESS_TOOL_REFS_DIR = "references/harness-tools";
19
19
  export declare function harnessToolRefMarkdown(harness: HarnessId): string;
20
- export declare const HARNESS_TOOL_REFS_INDEX_MD = "---\nname: Harness tool maps\ndescription: \"Index file. One reference per supported harness \u2014 cite the per-harness file instead of hardcoding tool names in stage skills.\"\n---\n\n# Harness Tool Maps\n\ncclaw supports four harnesses; each exposes different primitive names for the same capabilities. Stage skills and utility skills cite the file matching the currently active harness and fall back to plain-text equivalents for capabilities that the harness lacks.\n\n| Harness | File | Notes |\n|---|---|---|\n| Claude Code | `.cclaw/references/harness-tools/claude.md` | Richest tool surface (AskUserQuestion, Task, WebFetch, WebSearch, MCP, \u2026). |\n| Cursor | `.cclaw/references/harness-tools/cursor.md` | Near-parity with Claude; uses `AskQuestion` instead of `AskUserQuestion`. |\n| OpenCode | `.cclaw/references/harness-tools/opencode.md` | No native ask-user / dispatch; more plain-text fallbacks. |\n| Codex | `.cclaw/references/harness-tools/codex.md` | No native ask-user / dispatch; shell + file I/O only by default. |\n\nWhen a new harness is added or an existing one renames a tool, update the corresponding file (and this index) \u2014 do NOT scatter tool names across skill text.\n";
20
+ export declare const HARNESS_TOOL_REFS_INDEX_MD = "---\nname: Harness tool maps\ndescription: \"Index file. One reference per supported harness \u2014 cite the per-harness file instead of hardcoding tool names in stage skills.\"\n---\n\n# Harness Tool Maps\n\ncclaw supports four harnesses; each exposes different primitive names for the same capabilities. Stage skills and utility skills cite the file matching the currently active harness and fall back to plain-text equivalents for capabilities that the harness lacks.\n\n| Harness | File | Notes |\n|---|---|---|\n| Claude Code | `.cclaw/references/harness-tools/claude.md` | Richest tool surface (AskUserQuestion, Task, WebFetch, WebSearch, MCP, \u2026). |\n| Cursor | `.cclaw/references/harness-tools/cursor.md` | Near-parity with Claude; uses `AskQuestion` instead of `AskUserQuestion`. |\n| OpenCode | `.cclaw/references/harness-tools/opencode.md` | Native `question` tool (permission-gated) for structured asks; no isolated subagent dispatch. |\n| Codex | `.cclaw/references/harness-tools/codex.md` | Native `request_user_input` tool (experimental, Plan / Collaboration mode) for structured asks; no subagent dispatch. |\n\nWhen a new harness is added or an existing one renames a tool, update the corresponding file (and this index) \u2014 do NOT scatter tool names across skill text.\n";
@@ -133,13 +133,13 @@ description: "Canonical mapping of cclaw capability names → OpenCode primitive
133
133
 
134
134
  # OpenCode — Tool Map
135
135
 
136
- OpenCode exposes a leaner tool surface than Claude Code / Cursor. When a cclaw skill describes a capability that OpenCode lacks, fall back to the plain-text equivalent listed below.
136
+ OpenCode exposes a leaner tool surface than Claude Code / Cursor, but it DOES have a native structured-ask primitive (\`question\`) — you just have to opt into it. When a cclaw skill describes a capability that OpenCode lacks entirely, fall back to the plain-text equivalent listed below.
137
137
 
138
138
  ## Core capabilities
139
139
 
140
140
  | cclaw capability | OpenCode primitive | Notes |
141
141
  |---|---|---|
142
- | Ask user a structured question | **Not available as a tool.** | Emit a plain-text numbered list: \`A) ... B) ... C) (recommended) ...\`. Wait for the user's letter. |
142
+ | Ask user a structured question | \`question\` tool | Each call has a header, question text, and a list of options; users can pick an option or type a custom answer. Supports multiple questions with navigation. **Gated:** \`opencode.json\` must set \`permission.question: "allow"\`; ACP clients additionally need the \`OPENCODE_ENABLE_QUESTION_TOOL=1\` env var. If the tool is denied or unavailable, fall back to a plain-text lettered list (\`A) ... B) ... C) (recommended) ...\`). |
143
143
  | Dispatch a subagent | **Not available as a tool.** | Inline the work in the current turn, or split across multiple turns with the user driving. |
144
144
  | Read file | file-read primitive | Same role as \`Read\`. |
145
145
  | Edit file | file-edit primitive | Same role as \`StrReplace\`; confirm diff before writing. |
@@ -154,6 +154,22 @@ OpenCode exposes a leaner tool surface than Claude Code / Cursor. When a cclaw s
154
154
 
155
155
  ## Decision-protocol mapping
156
156
 
157
+ When the \`question\` tool is enabled, issue one call per decision:
158
+
159
+ \`\`\`
160
+ question({
161
+ header: "<stage> decision",
162
+ question: "<one-sentence decision>",
163
+ options: [
164
+ "A) <label> — <trade-off>",
165
+ "B) <label> — <trade-off>",
166
+ "C) <label> — <trade-off> (recommended, because <reason>)"
167
+ ]
168
+ })
169
+ \`\`\`
170
+
171
+ If the tool is denied or the host doesn't expose it, fall back to plain text using the same skeleton:
172
+
157
173
  \`\`\`
158
174
  Decision: <one sentence>.
159
175
 
@@ -166,7 +182,7 @@ Please reply with the letter.
166
182
 
167
183
  ## Escalation / fall-back
168
184
 
169
- Because OpenCode lacks native ask-user and dispatch tools, more of cclaw's protocols degrade to plain text. This is expected the flow gates and artifacts are identical; only the delivery channel changes.
185
+ OpenCode has the structured-ask primitive (\`question\`) but no isolated subagent dispatch, so delegation falls back to the role-switch playbook. Flow gates and artifacts are identical; only the delivery channel changes.
170
186
  `;
171
187
  const CODEX_TOOLS_MD = `---
172
188
  harness: codex
@@ -176,14 +192,14 @@ description: "Canonical mapping of cclaw capability names → Codex CLI primitiv
176
192
 
177
193
  # Codex — Tool Map
178
194
 
179
- Codex (OpenAI Codex CLI) exposes roughly the same core surface as OpenCode: file I/O, shell, no native ask-user, no dispatch. Fall back to plain text for anything else.
195
+ Codex (OpenAI Codex CLI) exposes file I/O, shell, skills, and lifecycle hooks (≥ v0.114, gated by the \`codex_hooks\` feature flag). It does NOT have isolated subagent dispatch, but it DOES expose a native structured-ask tool (\`request_user_input\`) on builds with the Plan / Collaboration mode templates. Fall back to plain text only when that tool is denied or hidden.
180
196
 
181
197
  ## Core capabilities
182
198
 
183
199
  | cclaw capability | Codex primitive | Notes |
184
200
  |---|---|---|
185
- | Ask user a structured question | **Not available as a tool.** | Emit a plain-text lettered list; wait for the user's reply. |
186
- | Dispatch a subagent | **Not available as a tool.** | Inline the work; split turns if needed. |
201
+ | Ask user a structured question | \`request_user_input\` tool | Accepts 1-3 short questions and returns the user's answers in the same order. Experimental; used by Codex's built-in Plan / Collaboration mode (see \`codex-rs/collaboration-mode-templates/templates/plan.md\`). Offer only meaningful options — filler choices are explicitly discouraged. Free-form answer strings are returned; keep the lettered options inline in the question text. Fall back to a plain-text lettered list if the tool is hidden or errors. |
202
+ | Dispatch a subagent | **Not available as a tool.** | Codex has no named or generic subagent dispatch. cclaw closes the mandatory-delegation gate with the role-switch playbook (\`.cclaw/references/harnesses/codex-playbook.md\`). |
187
203
  | Read file | \`read\` / \`open\` primitive | Same role as \`Read\`. |
188
204
  | Edit file | \`edit\` / \`patch\` primitive | Same role as \`StrReplace\`. |
189
205
  | Create file | \`write\` primitive | Prefer editing existing files. |
@@ -192,11 +208,23 @@ Codex (OpenAI Codex CLI) exposes roughly the same core surface as OpenCode: file
192
208
  | Shell command | shell primitive | Codex CLI may restrict some binaries by default — check the effective permissions. |
193
209
  | Fetch URL | \`curl\` via shell | Extract markdown manually. |
194
210
  | Web search | **Not available.** | Ask user for docs / URL. |
195
- | Todo tracking | **Not available as a tool.** | Keep an inline \`### TODO\` section; update it as you progress. |
211
+ | Todo tracking | \`update_plan\` tool (Codex-native checklist) | \`update_plan\` is Codex's built-in progress / checklist surface and is **separate** from Plan / Collaboration mode do not conflate them. cclaw also keeps an inline \`### TODO\` block in-turn as an audit mirror. |
196
212
  | MCP tool call | Depends on runtime config. | If MCP is wired, cite the descriptor; otherwise treat as unavailable. |
197
213
 
198
214
  ## Decision-protocol mapping
199
215
 
216
+ When \`request_user_input\` is available, issue a single call with 1-3 questions:
217
+
218
+ \`\`\`
219
+ request_user_input({
220
+ questions: [
221
+ "<stage> — <one-sentence decision>. Reply A/B/C. A) <label> — <trade-off>. B) <label> — <trade-off>. C) <label> — <trade-off> (recommended, <reason>)."
222
+ ]
223
+ })
224
+ \`\`\`
225
+
226
+ Answers come back as free-form strings, not option IDs — keep the lettered options inline so the user's reply maps cleanly to the artifact decision log. When the tool is hidden (older build, non-collaboration mode), fall back to plain text with the same skeleton:
227
+
200
228
  \`\`\`
201
229
  Decision: <one sentence>.
202
230
 
@@ -209,7 +237,7 @@ Please reply with the letter.
209
237
 
210
238
  ## Escalation / fall-back
211
239
 
212
- Treat missing tools as "plain-text required", not "skip the step". The gate still has to pass; only the channel changes.
240
+ \`request_user_input\` is the only structured-ask primitive Codex ships; dispatch still requires the role-switch playbook. Treat missing tools as "plain-text required", not "skip the step". The gate still has to pass; only the channel changes.
213
241
  `;
214
242
  const HARNESS_TOOL_REFS = {
215
243
  claude: CLAUDE_TOOLS_MD,
@@ -233,8 +261,8 @@ cclaw supports four harnesses; each exposes different primitive names for the sa
233
261
  |---|---|---|
234
262
  | Claude Code | \`.cclaw/${HARNESS_TOOL_REFS_DIR}/claude.md\` | Richest tool surface (AskUserQuestion, Task, WebFetch, WebSearch, MCP, …). |
235
263
  | Cursor | \`.cclaw/${HARNESS_TOOL_REFS_DIR}/cursor.md\` | Near-parity with Claude; uses \`AskQuestion\` instead of \`AskUserQuestion\`. |
236
- | OpenCode | \`.cclaw/${HARNESS_TOOL_REFS_DIR}/opencode.md\` | No native ask-user / dispatch; more plain-text fallbacks. |
237
- | Codex | \`.cclaw/${HARNESS_TOOL_REFS_DIR}/codex.md\` | No native ask-user / dispatch; shell + file I/O only by default. |
264
+ | OpenCode | \`.cclaw/${HARNESS_TOOL_REFS_DIR}/opencode.md\` | Native \`question\` tool (permission-gated) for structured asks; no isolated subagent dispatch. |
265
+ | Codex | \`.cclaw/${HARNESS_TOOL_REFS_DIR}/codex.md\` | Native \`request_user_input\` tool (experimental, Plan / Collaboration mode) for structured asks; no subagent dispatch. |
238
266
 
239
267
  When a new harness is added or an existing one renames a tool, update the corresponding file (and this index) — do NOT scatter tool names across skill text.
240
268
  `;
@@ -112,7 +112,7 @@ Harness-specific additions:
112
112
  - \`claude\`: \`.claude/commands/cc*.md\`, \`.claude/hooks/hooks.json\`
113
113
  - \`cursor\`: \`.cursor/commands/cc*.md\`, \`.cursor/hooks.json\`, \`.cursor/rules/cclaw-workflow.mdc\`
114
114
  - \`opencode\`: \`.opencode/commands/cc*.md\`, \`.opencode/plugins/cclaw-plugin.mjs\`, opencode plugin registration
115
- - \`codex\`: \`.agents/skills/cclaw-cc/SKILL.md\`, \`.agents/skills/cclaw-cc-next/SKILL.md\`, \`.agents/skills/cclaw-cc-ideate/SKILL.md\`, \`.agents/skills/cclaw-cc-view/SKILL.md\`, \`.agents/skills/cclaw-cc-ops/SKILL.md\` (Codex CLI reads \`.agents/skills/\` on startup; \`.codex/*\` was never consumed by the CLI and is auto-cleaned on sync)
115
+ - \`codex\`: \`.agents/skills/cc/SKILL.md\`, \`.agents/skills/cc-next/SKILL.md\`, \`.agents/skills/cc-ideate/SKILL.md\`, \`.agents/skills/cc-view/SKILL.md\`, \`.agents/skills/cc-ops/SKILL.md\`, \`.codex/hooks.json\` (Codex CLI reads \`.agents/skills/\` for custom skills and consumes \`.codex/hooks.json\` on v0.114+ when \`[features] codex_hooks = true\` is set in \`~/.codex/config.toml\`. \`.codex/commands/\` and the legacy \`.agents/skills/cclaw-cc*/\` layout from v0.39.x are auto-cleaned on sync.)
116
116
 
117
117
  ## Runtime observability
118
118
 
@@ -32,10 +32,16 @@ export const HOOK_EVENTS_BY_HARNESS = {
32
32
  precompact_digest: "plugin session.cleared/session.resumed hooks"
33
33
  },
34
34
  codex: {
35
- // Codex CLI has no hooks primitive. cclaw substitutes via skills
36
- // under `.agents/skills/cclaw-cc*/SKILL.md` plus explicit in-turn
37
- // agent steps (see codex playbook). All semantic events are
38
- // intentionally unmapped here so `harness-gaps.json` exposes them
39
- // honestly.
35
+ // Codex CLI v0.114+ exposes lifecycle hooks via `.codex/hooks.json`,
36
+ // gated by `[features] codex_hooks = true` in `~/.codex/config.toml`.
37
+ // SessionStart, Stop, and UserPromptSubmit fire for every turn;
38
+ // PreToolUse/PostToolUse are **Bash-only** (Write/Edit/WebSearch/MCP
39
+ // calls do not trigger them). `precompact_digest` is unmapped —
40
+ // Codex has no PreCompact event; cclaw covers it via `/cc-ops retro`.
41
+ session_rehydrate: "SessionStart matcher startup|resume",
42
+ pre_tool_prompt_guard: "PreToolUse matcher Bash -> prompt-guard.sh (plus UserPromptSubmit for non-Bash prompts)",
43
+ pre_tool_workflow_guard: "PreToolUse matcher Bash -> workflow-guard.sh (Bash-only)",
44
+ post_tool_context_monitor: "PostToolUse matcher Bash -> context-monitor.sh (Bash-only)",
45
+ stop_checkpoint: "Stop -> stop-checkpoint.sh"
40
46
  }
41
47
  };
@@ -1209,14 +1209,14 @@ Cclaw generates real hook integrations for every harness that exposes a
1209
1209
  hook primitive:
1210
1210
  - **Claude/Cursor:** lifecycle rehydration + PreToolUse/PostToolUse + Stop
1211
1211
  - **OpenCode:** session lifecycle + system transform rehydration + bootstrap parity (digest/warnings/knowledge snapshot)
1212
- - **Codex:** *no hooks API exists in Codex CLI* substitution happens via skills (\`.agents/skills/cclaw-cc*/SKILL.md\`) and explicit in-turn agent steps. See \`.cclaw/references/harnesses/codex-playbook.md\`.
1212
+ - **Codex:** Codex CLI ≥ v0.114 exposes lifecycle hooks at \`.codex/hooks.json\`, gated behind \`[features] codex_hooks = true\` in \`~/.codex/config.toml\`. \`PreToolUse\`/\`PostToolUse\` intercept **only the \`Bash\` tool** in Codex; \`Write\`/\`Edit\`/\`WebSearch\`/MCP calls are substituted via the \`/cc\` skill bodies under \`.agents/skills/cc*/SKILL.md\` and explicit in-turn agent steps. See \`.cclaw/references/harnesses/codex-playbook.md\` for the coverage matrix.
1213
1213
 
1214
1214
  | Harness | Hook file | Events |
1215
1215
  |---------|-----------|--------|
1216
1216
  | Claude Code | \`.claude/hooks/hooks.json\` | SessionStart(startup/resume/clear/compact), PreToolUse, PostToolUse, Stop |
1217
1217
  | Cursor | \`.cursor/hooks.json\` | sessionStart/sessionResume/sessionClear/sessionCompact, preToolUse, postToolUse, stop |
1218
1218
  | OpenCode | \`${RUNTIME_ROOT}/hooks/opencode-plugin.mjs\` | session.created/updated/resumed/cleared/compacted/idle, tool.execute.before/after, system transform |
1219
- | Codex | *none* | skill-description matching + in-turn agent steps (no hooks API) |
1219
+ | Codex | \`.codex/hooks.json\` | SessionStart(startup/resume), UserPromptSubmit, PreToolUse(Bash), PostToolUse(Bash), Stop (feature-gated by \`codex_hooks = true\`) |
1220
1220
 
1221
1221
  Hook state files:
1222
1222
  - \`${RUNTIME_ROOT}/state/stage-activity.jsonl\`
@@ -23,4 +23,23 @@ export declare function summarizeObservationsScript(): string;
23
23
  */
24
24
  export declare function claudeHooksJsonWithObservation(): string;
25
25
  export declare function cursorHooksJsonWithObservation(): string;
26
+ /**
27
+ * Codex CLI ≥ v0.114 hooks. Differences vs. the Claude shape:
28
+ *
29
+ * - `SessionStart` matcher is limited to `startup|resume` — Codex does
30
+ * not emit `clear` or `compact` lifecycle phases.
31
+ * - `PreToolUse` / `PostToolUse` fire **only for the `Bash` tool**
32
+ * (documented Codex limitation, v0.114/v0.115). We use the `Bash`
33
+ * matcher verbatim so Codex doesn't silently swallow our commands.
34
+ * - `UserPromptSubmit` is supported and is the closest analogue to
35
+ * Cursor's `preToolUse` for non-Bash tooling — we run prompt-guard
36
+ * there so workflow/prompt checks still fire when the tool being
37
+ * used is `Write` or `Edit` rather than `Bash`.
38
+ * - There is no `PreCompact` event in Codex CLI — pre-compact
39
+ * semantics are carried by the agent itself inside `/cc-ops retro`.
40
+ *
41
+ * The entire file is inert unless the user opts into
42
+ * `[features] codex_hooks = true` in `~/.codex/config.toml`; cclaw
43
+ * doctor and the init prompt handle that flag.
44
+ */
26
45
  export declare function codexHooksJsonWithObservation(): string;
@@ -1792,20 +1792,44 @@ export function cursorHooksJsonWithObservation() {
1792
1792
  }
1793
1793
  }, null, 2);
1794
1794
  }
1795
+ /**
1796
+ * Codex CLI ≥ v0.114 hooks. Differences vs. the Claude shape:
1797
+ *
1798
+ * - `SessionStart` matcher is limited to `startup|resume` — Codex does
1799
+ * not emit `clear` or `compact` lifecycle phases.
1800
+ * - `PreToolUse` / `PostToolUse` fire **only for the `Bash` tool**
1801
+ * (documented Codex limitation, v0.114/v0.115). We use the `Bash`
1802
+ * matcher verbatim so Codex doesn't silently swallow our commands.
1803
+ * - `UserPromptSubmit` is supported and is the closest analogue to
1804
+ * Cursor's `preToolUse` for non-Bash tooling — we run prompt-guard
1805
+ * there so workflow/prompt checks still fire when the tool being
1806
+ * used is `Write` or `Edit` rather than `Bash`.
1807
+ * - There is no `PreCompact` event in Codex CLI — pre-compact
1808
+ * semantics are carried by the agent itself inside `/cc-ops retro`.
1809
+ *
1810
+ * The entire file is inert unless the user opts into
1811
+ * `[features] codex_hooks = true` in `~/.codex/config.toml`; cclaw
1812
+ * doctor and the init prompt handle that flag.
1813
+ */
1795
1814
  export function codexHooksJsonWithObservation() {
1796
1815
  return JSON.stringify({
1797
1816
  cclawHookSchemaVersion: 1,
1798
1817
  hooks: {
1799
1818
  SessionStart: [{
1800
- matcher: "startup|resume|clear|compact",
1819
+ matcher: "startup|resume",
1801
1820
  hooks: [{
1802
1821
  type: "command",
1803
- command: `bash ${RUNTIME_ROOT}/hooks/session-start.sh`,
1804
- statusMessage: "Loading cclaw flow state"
1822
+ command: `bash ${RUNTIME_ROOT}/hooks/session-start.sh`
1823
+ }]
1824
+ }],
1825
+ UserPromptSubmit: [{
1826
+ hooks: [{
1827
+ type: "command",
1828
+ command: `bash ${RUNTIME_ROOT}/hooks/prompt-guard.sh`
1805
1829
  }]
1806
1830
  }],
1807
1831
  PreToolUse: [{
1808
- matcher: "*",
1832
+ matcher: "Bash",
1809
1833
  hooks: [{
1810
1834
  type: "command",
1811
1835
  command: `bash ${RUNTIME_ROOT}/hooks/prompt-guard.sh`
@@ -1815,7 +1839,7 @@ export function codexHooksJsonWithObservation() {
1815
1839
  }]
1816
1840
  }],
1817
1841
  PostToolUse: [{
1818
- matcher: "*",
1842
+ matcher: "Bash",
1819
1843
  hooks: [{
1820
1844
  type: "command",
1821
1845
  command: `bash ${RUNTIME_ROOT}/hooks/context-monitor.sh`
@@ -1827,14 +1851,6 @@ export function codexHooksJsonWithObservation() {
1827
1851
  command: `bash ${RUNTIME_ROOT}/hooks/stop-checkpoint.sh`,
1828
1852
  timeout: 10
1829
1853
  }]
1830
- }],
1831
- PreCompact: [{
1832
- matcher: "manual|auto",
1833
- hooks: [{
1834
- type: "command",
1835
- command: `bash ${RUNTIME_ROOT}/hooks/pre-compact.sh`,
1836
- timeout: 10
1837
- }]
1838
1854
  }]
1839
1855
  }
1840
1856
  }, null, 2);
@@ -13,10 +13,18 @@ Shared format for decisions that require user confirmation.
13
13
  1. State the decision in one sentence.
14
14
  2. Provide 2-4 labeled options (A, B, C...).
15
15
  3. Mark one option as **recommended** with a short rationale.
16
- 4. Use harness question tools when available:
17
- - Claude: \`AskUserQuestion\`
18
- - Cursor: \`AskQuestion\`
19
- - OpenCode/Codex: plain text options
16
+ 4. Use the harness's structured-ask tool when available:
17
+ - Claude: \`AskUserQuestion\` (up to ~4 options × multi-question).
18
+ - Cursor: \`AskQuestion\` (≥2 options, multi-question, optional \`allow_multiple\`).
19
+ - OpenCode: \`question\` tool (options + "type custom" fallback).
20
+ Requires \`permission.question: "allow"\` in \`opencode.json\`; ACP
21
+ clients additionally need \`OPENCODE_ENABLE_QUESTION_TOOL=1\`.
22
+ - Codex: \`request_user_input\` (1-3 short questions; experimental,
23
+ surfaced in Plan / Collaboration mode).
24
+ - Fallback (any harness where the native tool is hidden, denied, or
25
+ returns a schema error): a numbered / lettered plain-text list
26
+ keeping the same Re-ground / Simplify / RECOMMENDATION / Options
27
+ skeleton described below.
20
28
  5. Wait for user choice before proceeding.
21
29
 
22
30
  ## Decision skeleton
@@ -48,8 +48,11 @@ in the structured ask; there is no \`--skip\` flag.
48
48
  - scan \`${knowledgePath()}\` for entries recorded during this run,
49
49
  - structure the draft as: Outcomes / Slowed / Accelerated / Repeatable rule.
50
50
  4. Update \`closeout.retroDraftedAt = <ISO>\` in flow-state.
51
- 5. Present **one** structured ask (AskUserQuestion on Claude, AskQuestion on
52
- Cursor, plain-text options elsewhere):
51
+ 5. Present **one** structured ask using the harness's native tool
52
+ (\`AskUserQuestion\` on Claude, \`AskQuestion\` on Cursor, \`question\` on
53
+ OpenCode when \`permission.question: "allow"\` is set,
54
+ \`request_user_input\` on Codex in Plan / Collaboration mode; fall back
55
+ to a plain-text lettered list when the tool is hidden or errors):
53
56
  - \`accept\` (default) — keep the draft as-is,
54
57
  - \`edit\` — user edits \`${retroArtifactPath()}\` in-place, then re-runs \`/cc-next\`,
55
58
  - \`skip\` — record \`retroSkipped: true\` + one-line reason, no compound entry required.
@@ -106,8 +109,9 @@ Do not silently skip. Do not finalize without updating \`flow-state.json\`.
106
109
  - **Accelerated** — patterns/decisions that worked and are worth keeping.
107
110
  - **Repeatable rule** — one candidate rule/pattern for next run.
108
111
  Record \`closeout.retroDraftedAt\`.
109
- 3. Ask the user **one** structured question via the harness question tool
110
- (AskUserQuestion / AskQuestion / plain text fallback):
112
+ 3. Ask the user **one** structured question via the harness's native
113
+ ask tool (\`AskUserQuestion\` / \`AskQuestion\` / \`question\` /
114
+ \`request_user_input\`; plain-text lettered list as fallback):
111
115
 
112
116
  > Retro draft ready at \`${retroArtifactPath()}\`. How do you want to
113
117
  > proceed? (default: accept)
@@ -37,7 +37,7 @@ export const DESIGN = {
37
37
  interactionProtocol: [
38
38
  "Review architecture decisions section-by-section.",
39
39
  "For EACH issue found in a review section, present it ONE AT A TIME. Do NOT batch multiple issues.",
40
- "For each issue: use the Decision Protocol — describe concretely with file/line references, present labeled options (A/B/C) with trade-offs, effort estimate (S/M/L/XL), risk level (Low/Med/High), and mark one as (recommended). Do NOT use a numeric Completeness rubric; recommend the option that best covers architecture, data-flow, failure-modes, test, and perf review concerns for the issue with the lowest risk. If AskQuestion/AskUserQuestion is available, send exactly ONE question per call, validate fields against runtime schema, and on schema error immediately fall back to plain-text question instead of retrying guessed payloads.",
40
+ "For each issue: use the Decision Protocol — describe concretely with file/line references, present labeled options (A/B/C) with trade-offs, effort estimate (S/M/L/XL), risk level (Low/Med/High), and mark one as (recommended). Do NOT use a numeric Completeness rubric; recommend the option that best covers architecture, data-flow, failure-modes, test, and perf review concerns for the issue with the lowest risk. If the harness's native structured-ask tool is available (`AskUserQuestion` / `AskQuestion` / `question` / `request_user_input`), send exactly ONE question per call, validate fields against the runtime schema, and on schema error immediately fall back to a plain-text lettered list instead of retrying guessed payloads.",
41
41
  "Only proceed to the next review section after ALL issues in the current section are resolved.",
42
42
  "If a section has no issues, say 'No issues found' and move on.",
43
43
  "Do not skip failure-mode mapping.",
@@ -39,9 +39,9 @@ export const REVIEW = {
39
39
  "Run Layer 1 (spec compliance) completely before starting Layer 2.",
40
40
  "In each review section, present findings ONE AT A TIME. Do NOT batch.",
41
41
  "Classify every finding as Critical, Important, or Suggestion.",
42
- "For each Critical finding: use the Decision Protocol — present resolution options (A/B/C) with trade-offs, and mark one as (recommended). Do NOT use a numeric Completeness rubric; recommend the option that fully closes the finding with no carry-over risk and the smallest blast radius. If AskQuestion/AskUserQuestion is available, send exactly ONE question per call, validate fields against runtime schema, and on schema error immediately fall back to plain-text question instead of retrying guessed payloads.",
42
+ "For each Critical finding: use the Decision Protocol — present resolution options (A/B/C) with trade-offs, and mark one as (recommended). Do NOT use a numeric Completeness rubric; recommend the option that fully closes the finding with no carry-over risk and the smallest blast radius. If the harness's native structured-ask tool is available (`AskUserQuestion` on Claude, `AskQuestion` on Cursor, `question` on OpenCode with `permission.question: \"allow\"`, `request_user_input` on Codex in Plan/Collaboration mode), send exactly ONE question per call, validate fields against the runtime schema, and on schema error immediately fall back to a plain-text lettered list instead of retrying guessed payloads.",
43
43
  "Resolve all critical blockers before ship.",
44
- "For final verdict: use AskQuestion/AskUserQuestion only if runtime schema is confirmed; otherwise collect verdict with a plain-text single-choice prompt (APPROVED / APPROVED_WITH_CONCERNS / BLOCKED).",
44
+ "For final verdict: use the native structured-ask tool (`AskUserQuestion` / `AskQuestion` / `question` / `request_user_input`) only if runtime schema is confirmed; otherwise collect verdict with a plain-text single-choice prompt (APPROVED / APPROVED_WITH_CONCERNS / BLOCKED).",
45
45
  "**STOP.** Do NOT proceed to ship until the user provides an explicit verdict."
46
46
  ],
47
47
  process: [
@@ -32,7 +32,7 @@ export const SCOPE = {
32
32
  "**Error and Rescue Registry** — For each capability: what breaks, how detected, what fallback."
33
33
  ],
34
34
  interactionProtocol: [
35
- "For scope mode selection: use the Decision Protocol — present expand/selective/hold/reduce as labeled options with trade-offs and mark one as (recommended). Do NOT use a numeric Completeness rubric; recommend the option that best covers the prime-directive failure modes, four data-flow paths, observability, and deferred handling for the in-scope set with the smallest blast radius. Base your recommendation on default heuristics: greenfield -> expand, enhancement -> selective, bugfix/hotfix/refactor -> hold, broad blast radius -> reduce. If AskQuestion/AskUserQuestion is available, send exactly ONE question per call, validate fields against runtime schema, and on schema error immediately fall back to plain-text question instead of retrying guessed payloads.",
35
+ "For scope mode selection: use the Decision Protocol — present expand/selective/hold/reduce as labeled options with trade-offs and mark one as (recommended). Do NOT use a numeric Completeness rubric; recommend the option that best covers the prime-directive failure modes, four data-flow paths, observability, and deferred handling for the in-scope set with the smallest blast radius. Base your recommendation on default heuristics: greenfield -> expand, enhancement -> selective, bugfix/hotfix/refactor -> hold, broad blast radius -> reduce. If the harness's native structured-ask tool is available (`AskUserQuestion` / `AskQuestion` / `question` / `request_user_input`), send exactly ONE question per call, validate fields against the runtime schema, and on schema error immediately fall back to a plain-text lettered list instead of retrying guessed payloads.",
36
36
  "Walk through the scope checklist interactively. Each checklist item that surfaces a decision should be presented to the user as a question, not as a monologue. Do not dump all items at once.",
37
37
  "Challenge premise and verify the problem framing before anything else.",
38
38
  "Take a position on every scope decision. Avoid hedging phrases like 'this could work' or 'there are many ways'; state your recommendation and one concrete condition that would change it.",
@@ -35,7 +35,7 @@ export const SHIP = {
35
35
  interactionProtocol: [
36
36
  "Run preflight checks before any release action.",
37
37
  "Document release notes and rollback plan explicitly.",
38
- "For finalization mode: use the Decision Protocol — present modes as labeled options (A/B/C/D) with consequences, and mark one as (recommended). Do NOT use a numeric Completeness rubric; recommend the mode that best addresses release blast-radius, rollback readiness, observability, and stakeholder communication — ties go to the most reversible option. If AskQuestion/AskUserQuestion is available, send exactly ONE question per call, validate fields against runtime schema, and on schema error immediately fall back to plain-text question instead of retrying guessed payloads.",
38
+ "For finalization mode: use the Decision Protocol — present modes as labeled options (A/B/C/D) with consequences, and mark one as (recommended). Do NOT use a numeric Completeness rubric; recommend the mode that best addresses release blast-radius, rollback readiness, observability, and stakeholder communication — ties go to the most reversible option. If the harness's native structured-ask tool is available (`AskUserQuestion` / `AskQuestion` / `question` / `request_user_input`), send exactly ONE question per call, validate fields against the runtime schema, and on schema error immediately fall back to a plain-text lettered list instead of retrying guessed payloads.",
39
39
  "Do not proceed if critical blockers remain from review.",
40
40
  "**STOP.** Present finalization options and wait for user selection before executing any finalization action."
41
41
  ],
@@ -76,7 +76,7 @@ This is the **recommended way to start** working with cclaw. Use \`/cc-next\` fo
76
76
  7. Present the recommendation as a single decision with explicit options:
77
77
  > \`Recommended track: <quick|medium|standard>\` because \`<one-line reason citing matched triggers>\`.
78
78
  > Override? (A) keep \`<recommended>\` (B) switch track (C) cancel.
79
- If \`AskQuestion\`/\`AskUserQuestion\` is available, send exactly ONE question; on schema error, fall back to plain text.
79
+ If the harness's native ask tool is available (\`AskUserQuestion\` / \`AskQuestion\` / \`question\` / \`request_user_input\`), send exactly ONE question; on schema error, fall back to a plain-text lettered list.
80
80
  8. Persist the chosen track to \`${flowPath}\` (\`track\` field). Compute \`skippedStages\` from the track and write that too. Use the **first stage of the chosen track** as \`currentStage\` (quick → \`spec\`, medium/standard → \`brainstorm\`, trivial fast-path → \`design\` or \`spec\` per Phase 0).
81
81
  9. Write the prompt to \`.cclaw/artifacts/00-idea.md\` with the following header lines: \`Class:\` (from Phase 0), \`Track:\` (chosen track + matched heuristic), \`Stack:\` (from Phase 2 detection, or \`unknown\`), and a \`Discovered context\` section if Phase 1 found origin docs.
82
82
  10. Load the **first-stage skill for the chosen track** and its command file:
@@ -47,8 +47,8 @@ Human input remains mandatory only at explicit approval gates (plan approval, us
47
47
  |---|---|---|---|---|
48
48
  | Claude | \`native\` | Task (named subagent_type) | AskUserQuestion | \`.cclaw/references/harnesses/claude-playbook.md\` |
49
49
  | Cursor | \`generic-dispatch\` | Task (generic subagent_type: explore/generalPurpose/…) | AskQuestion | \`.cclaw/references/harnesses/cursor-playbook.md\` |
50
- | OpenCode | \`role-switch\` | plugin dispatch _or_ in-session role-switch | plain-text options | \`.cclaw/references/harnesses/opencode-playbook.md\` |
51
- | Codex | \`role-switch\` | in-session role-switch (mandatory evidenceRefs) | plain-text options | \`.cclaw/references/harnesses/codex-playbook.md\` |
50
+ | OpenCode | \`role-switch\` | plugin dispatch _or_ in-session role-switch | \`question\` (permission-gated; \`permission.question: "allow"\`) | \`.cclaw/references/harnesses/opencode-playbook.md\` |
51
+ | Codex | \`role-switch\` | in-session role-switch (mandatory evidenceRefs) | \`request_user_input\` (experimental; Plan / Collaboration mode) | \`.cclaw/references/harnesses/codex-playbook.md\` |
52
52
 
53
53
  **Dispatch rules driven by \`subagentFallback\`:**
54
54