cclaw-cli 0.51.29 → 0.55.2

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.
Files changed (151) hide show
  1. package/README.md +22 -16
  2. package/dist/artifact-linter/brainstorm.d.ts +2 -0
  3. package/dist/artifact-linter/brainstorm.js +245 -0
  4. package/dist/artifact-linter/design.d.ts +2 -0
  5. package/dist/artifact-linter/design.js +323 -0
  6. package/dist/artifact-linter/plan.d.ts +2 -0
  7. package/dist/artifact-linter/plan.js +162 -0
  8. package/dist/artifact-linter/review-army.d.ts +24 -0
  9. package/dist/artifact-linter/review-army.js +365 -0
  10. package/dist/artifact-linter/review.d.ts +2 -0
  11. package/dist/artifact-linter/review.js +65 -0
  12. package/dist/artifact-linter/scope.d.ts +2 -0
  13. package/dist/artifact-linter/scope.js +115 -0
  14. package/dist/artifact-linter/shared.d.ts +246 -0
  15. package/dist/artifact-linter/shared.js +1488 -0
  16. package/dist/artifact-linter/ship.d.ts +2 -0
  17. package/dist/artifact-linter/ship.js +46 -0
  18. package/dist/artifact-linter/spec.d.ts +2 -0
  19. package/dist/artifact-linter/spec.js +108 -0
  20. package/dist/artifact-linter/tdd.d.ts +2 -0
  21. package/dist/artifact-linter/tdd.js +124 -0
  22. package/dist/artifact-linter.d.ts +4 -76
  23. package/dist/artifact-linter.js +56 -2949
  24. package/dist/cli.d.ts +2 -18
  25. package/dist/cli.js +8 -246
  26. package/dist/codex-feature-flag.d.ts +1 -1
  27. package/dist/codex-feature-flag.js +1 -1
  28. package/dist/config.d.ts +3 -2
  29. package/dist/config.js +67 -3
  30. package/dist/constants.d.ts +1 -7
  31. package/dist/constants.js +9 -15
  32. package/dist/content/cancel-command.js +2 -2
  33. package/dist/content/closeout-guidance.js +13 -10
  34. package/dist/content/core-agents.d.ts +18 -0
  35. package/dist/content/core-agents.js +51 -7
  36. package/dist/content/decision-protocol.d.ts +1 -1
  37. package/dist/content/decision-protocol.js +1 -1
  38. package/dist/content/examples.js +6 -6
  39. package/dist/content/harness-doc.js +20 -2
  40. package/dist/content/hook-inline-snippets.d.ts +17 -4
  41. package/dist/content/hook-inline-snippets.js +218 -5
  42. package/dist/content/hook-manifest.d.ts +2 -2
  43. package/dist/content/hook-manifest.js +2 -2
  44. package/dist/content/hooks.d.ts +1 -0
  45. package/dist/content/hooks.js +32 -137
  46. package/dist/content/idea-command.d.ts +8 -0
  47. package/dist/content/{ideate-command.js → idea-command.js} +57 -50
  48. package/dist/content/idea-frames.d.ts +31 -0
  49. package/dist/content/{ideate-frames.js → idea-frames.js} +9 -9
  50. package/dist/content/idea-ranking.d.ts +25 -0
  51. package/dist/content/{ideate-ranking.js → idea-ranking.js} +5 -5
  52. package/dist/content/iron-laws.d.ts +0 -1
  53. package/dist/content/iron-laws.js +31 -16
  54. package/dist/content/learnings.js +1 -1
  55. package/dist/content/meta-skill.js +11 -13
  56. package/dist/content/node-hooks.d.ts +10 -0
  57. package/dist/content/node-hooks.js +45 -11
  58. package/dist/content/opencode-plugin.js +3 -3
  59. package/dist/content/session-hooks.js +1 -1
  60. package/dist/content/skills.js +19 -7
  61. package/dist/content/stage-command.js +1 -1
  62. package/dist/content/stage-schema.js +44 -2
  63. package/dist/content/stages/_lint-metadata/index.js +26 -2
  64. package/dist/content/stages/brainstorm.js +13 -7
  65. package/dist/content/stages/design.js +16 -11
  66. package/dist/content/stages/plan.js +9 -6
  67. package/dist/content/stages/review.js +4 -4
  68. package/dist/content/stages/schema-types.d.ts +1 -1
  69. package/dist/content/stages/scope.js +15 -12
  70. package/dist/content/stages/ship.js +2 -2
  71. package/dist/content/stages/spec.js +9 -3
  72. package/dist/content/stages/tdd.js +14 -4
  73. package/dist/content/start-command.d.ts +2 -2
  74. package/dist/content/start-command.js +24 -21
  75. package/dist/content/status-command.js +8 -8
  76. package/dist/content/subagents.js +61 -7
  77. package/dist/content/templates.d.ts +1 -1
  78. package/dist/content/templates.js +104 -152
  79. package/dist/content/tree-command.js +2 -2
  80. package/dist/content/utility-skills.d.ts +2 -2
  81. package/dist/content/utility-skills.js +2 -2
  82. package/dist/content/view-command.js +4 -2
  83. package/dist/delegation.d.ts +2 -0
  84. package/dist/delegation.js +2 -1
  85. package/dist/early-loop.d.ts +66 -0
  86. package/dist/early-loop.js +275 -0
  87. package/dist/flow-state.d.ts +1 -1
  88. package/dist/flow-state.js +1 -1
  89. package/dist/gate-evidence.d.ts +8 -0
  90. package/dist/gate-evidence.js +141 -5
  91. package/dist/harness-adapters.d.ts +2 -2
  92. package/dist/harness-adapters.js +54 -122
  93. package/dist/harness-selection.d.ts +31 -0
  94. package/dist/harness-selection.js +214 -0
  95. package/dist/install.js +166 -38
  96. package/dist/internal/advance-stage/advance.d.ts +50 -0
  97. package/dist/internal/advance-stage/advance.js +480 -0
  98. package/dist/internal/advance-stage/cancel-run.d.ts +8 -0
  99. package/dist/internal/advance-stage/cancel-run.js +19 -0
  100. package/dist/internal/advance-stage/flow-state-coercion.d.ts +3 -0
  101. package/dist/internal/advance-stage/flow-state-coercion.js +81 -0
  102. package/dist/internal/advance-stage/helpers.d.ts +14 -0
  103. package/dist/internal/advance-stage/helpers.js +145 -0
  104. package/dist/internal/advance-stage/hook.d.ts +8 -0
  105. package/dist/internal/advance-stage/hook.js +40 -0
  106. package/dist/internal/advance-stage/parsers.d.ts +54 -0
  107. package/dist/internal/advance-stage/parsers.js +307 -0
  108. package/dist/internal/advance-stage/review-loop.d.ts +7 -0
  109. package/dist/internal/advance-stage/review-loop.js +170 -0
  110. package/dist/internal/advance-stage/rewind.d.ts +14 -0
  111. package/dist/internal/advance-stage/rewind.js +108 -0
  112. package/dist/internal/advance-stage/start-flow.d.ts +11 -0
  113. package/dist/internal/advance-stage/start-flow.js +136 -0
  114. package/dist/internal/advance-stage/verify.d.ts +29 -0
  115. package/dist/internal/advance-stage/verify.js +225 -0
  116. package/dist/internal/advance-stage.js +21 -1470
  117. package/dist/internal/compound-readiness.d.ts +1 -1
  118. package/dist/internal/compound-readiness.js +2 -2
  119. package/dist/internal/early-loop-status.d.ts +7 -0
  120. package/dist/internal/early-loop-status.js +90 -0
  121. package/dist/internal/runtime-integrity.d.ts +7 -0
  122. package/dist/internal/runtime-integrity.js +288 -0
  123. package/dist/internal/tdd-red-evidence.js +1 -1
  124. package/dist/knowledge-store.d.ts +3 -8
  125. package/dist/knowledge-store.js +16 -29
  126. package/dist/managed-resources.js +24 -2
  127. package/dist/policy.js +5 -7
  128. package/dist/run-archive.d.ts +1 -1
  129. package/dist/run-archive.js +16 -16
  130. package/dist/run-persistence.js +112 -12
  131. package/dist/tdd-cycle.d.ts +3 -3
  132. package/dist/tdd-cycle.js +1 -1
  133. package/dist/types.d.ts +18 -10
  134. package/package.json +1 -1
  135. package/dist/content/finish-command.d.ts +0 -2
  136. package/dist/content/finish-command.js +0 -26
  137. package/dist/content/ideate-command.d.ts +0 -8
  138. package/dist/content/ideate-frames.d.ts +0 -31
  139. package/dist/content/ideate-ranking.d.ts +0 -25
  140. package/dist/content/next-command.d.ts +0 -20
  141. package/dist/content/next-command.js +0 -298
  142. package/dist/content/seed-shelf.d.ts +0 -36
  143. package/dist/content/seed-shelf.js +0 -301
  144. package/dist/content/stage-common-guidance.d.ts +0 -1
  145. package/dist/content/stage-common-guidance.js +0 -106
  146. package/dist/doctor-registry.d.ts +0 -10
  147. package/dist/doctor-registry.js +0 -186
  148. package/dist/doctor.d.ts +0 -17
  149. package/dist/doctor.js +0 -2206
  150. package/dist/internal/hook-manifest.d.ts +0 -16
  151. package/dist/internal/hook-manifest.js +0 -77
@@ -1,43 +1,43 @@
1
1
  import { RUNTIME_ROOT } from "../constants.js";
2
- import { resolveIdeateFrames } from "./ideate-frames.js";
3
- import { ideateStructuredAskToolsWithFallback } from "./decision-protocol.js";
2
+ import { resolveIdeaFrames } from "./idea-frames.js";
3
+ import { ideaStructuredAskToolsWithFallback } from "./decision-protocol.js";
4
4
  import { conversationLanguagePolicyMarkdown } from "./language-policy.js";
5
- const IDEATE_SKILL_FOLDER = "flow-ideate";
6
- const IDEATE_SKILL_NAME = "flow-ideate";
5
+ const IDEA_SKILL_FOLDER = "flow-idea";
6
+ const IDEA_SKILL_NAME = "flow-idea";
7
7
  /**
8
- * Directory + filename convention for ideate artifacts. These are separate
9
- * from stage artifacts (00-..08-*.md) because `/cc-ideate` runs outside the
8
+ * Directory + filename convention for idea artifacts. These are separate
9
+ * from stage artifacts (00-..08-*.md) because `/cc-idea` runs outside the
10
10
  * critical-path flow state machine and must not collide with stage numbering.
11
11
  */
12
- const IDEATE_ARTIFACT_GLOB = ".cclaw/artifacts/ideate-*.md";
13
- const IDEATE_ARTIFACT_PATTERN = ".cclaw/artifacts/ideate-<YYYY-MM-DD-slug>.md";
14
- const IDEATE_RESUME_WINDOW_DAYS = 30;
15
- const STRUCTURED_ASK_TOOLS = ideateStructuredAskToolsWithFallback();
16
- export function minimumDistinctIdeateFrames(frameCount, mode = "repo-grounded") {
12
+ const IDEA_ARTIFACT_GLOB = ".cclaw/artifacts/idea-*.md";
13
+ const IDEA_ARTIFACT_PATTERN = ".cclaw/artifacts/idea-<YYYY-MM-DD-slug>.md";
14
+ const IDEA_RESUME_WINDOW_DAYS = 30;
15
+ const STRUCTURED_ASK_TOOLS = ideaStructuredAskToolsWithFallback();
16
+ export function minimumDistinctIdeaFrames(frameCount, mode = "repo-grounded") {
17
17
  if (frameCount <= 0)
18
18
  return 0;
19
19
  const cap = mode === "repo-grounded" ? 4 : 2;
20
20
  return Math.min(cap, frameCount);
21
21
  }
22
22
  function renderFrameBullets(frameIds) {
23
- return resolveIdeateFrames(frameIds)
23
+ return resolveIdeaFrames(frameIds)
24
24
  .map((frame) => ` - ${frame.label} (\`${frame.id}\`)`)
25
25
  .join("\n");
26
26
  }
27
27
  function renderFrameNames(frameIds) {
28
- return resolveIdeateFrames(frameIds)
28
+ return resolveIdeaFrames(frameIds)
29
29
  .map((frame) => frame.label)
30
30
  .join(", ");
31
31
  }
32
- export function ideateCommandContract(options = {}) {
33
- const frames = resolveIdeateFrames(options.frameIds);
32
+ export function ideaCommandContract(options = {}) {
33
+ const frames = resolveIdeaFrames(options.frameIds);
34
34
  const frameBullets = renderFrameBullets(options.frameIds);
35
- const minimumDistinctFrames = minimumDistinctIdeateFrames(frames.length, options.mode);
36
- return `# /cc-ideate
35
+ const minimumDistinctFrames = minimumDistinctIdeaFrames(frames.length, options.mode);
36
+ return `# /cc-idea
37
37
 
38
38
  ## Purpose
39
39
 
40
- Repository-improvement ideate mode. Generate a ranked backlog of
40
+ Repository-improvement idea mode. Generate a ranked backlog of
41
41
  high-value improvements, persist it as an artifact on disk, and end with
42
42
  an explicit handoff — either launch \`/cc\` on a chosen candidate in the
43
43
  same session, or save/discard the backlog.
@@ -45,18 +45,20 @@ same session, or save/discard the backlog.
45
45
  ## HARD-GATE
46
46
 
47
47
  ${conversationLanguagePolicyMarkdown()}
48
- - Ideate mode only. Never mutate \`.cclaw/state/flow-state.json\`.
48
+ - Idea mode only. Never mutate \`.cclaw/state/flow-state.json\`.
49
49
  - Every recommendation cites evidence from the current repository
50
50
  (file path, command output, or knowledge-store entry id).
51
- - Always write a persisted artifact to
52
- \`${IDEATE_ARTIFACT_PATTERN}\`. Chat-only output is not acceptable
53
- the next session must be able to resume.
54
- - Always end with a structured handoff prompt, not an open question.
51
+ - Whenever you produce ideation output, persist it to
52
+ \`${IDEA_ARTIFACT_PATTERN}\`. Chat-only output is not acceptable.
53
+ The only exception is an explicit user-cancel from the resume prompt —
54
+ in that case, write nothing and exit silently.
55
+ - Always end with a structured handoff prompt, not an open question
56
+ (skipped on explicit cancel).
55
57
 
56
58
  ## Algorithm
57
59
 
58
- 1. **Resume check.** Glob \`${IDEATE_ARTIFACT_GLOB}\`. If any artifact
59
- has been modified within the last ${IDEATE_RESUME_WINDOW_DAYS} days,
60
+ 1. **Resume check.** Glob \`${IDEA_ARTIFACT_GLOB}\`. If any artifact
61
+ has been modified within the last ${IDEA_RESUME_WINDOW_DAYS} days,
60
62
  offer the user: continue that backlog, start fresh, or cancel.
61
63
  2. **Mode classification.** Explicitly classify subject:
62
64
  \`repo-grounded\` / \`elsewhere-software\` / \`elsewhere-non-software\` / \`narrow\`.
@@ -83,7 +85,7 @@ ${frameBullets}
83
85
  \`(impact points / effort cost) * confidence multiplier\` and recommend
84
86
  the top survivor.
85
87
  8. **Write the artifact** at
86
- \`${IDEATE_ARTIFACT_PATTERN}\` using the schema in the skill.
88
+ \`${IDEA_ARTIFACT_PATTERN}\` using the schema in the skill.
87
89
  8.5 **Seed shelf (optional).** For critiqued-out or deferred ideas that still
88
90
  show upside, write seed notes to
89
91
  \`${RUNTIME_ROOT}/seeds/SEED-<YYYY-MM-DD>-<slug>.md\` with
@@ -91,61 +93,66 @@ ${frameBullets}
91
93
  9. **Present the handoff prompt** with four concrete options — not A/B/C
92
94
  letters. Default = "Start /cc on the top recommendation".
93
95
 
94
- ## Headless mode
96
+ ## Headless mode (CI/automation only)
95
97
 
98
+ Headless envelopes are a machine-mode exception for CI/automation orchestration.
99
+ In normal interactive ideation, respond with natural language plus the artifact path.
96
100
  For skill-to-skill invocation, emit exactly one JSON envelope:
97
101
 
98
102
  \`\`\`json
99
- {"version":"1","kind":"stage-output","stage":"non-flow","payload":{"command":"/cc-ideate","artifact":".cclaw/artifacts/ideate-<date>-<slug>.md","recommendation":"I-1"},"emittedAt":"<ISO-8601>"}
103
+ {"version":"1","kind":"stage-output","stage":"non-flow","payload":{"command":"/cc-idea","artifact":".cclaw/artifacts/idea-<date>-<slug>.md","recommendation":"I-1"},"emittedAt":"<ISO-8601>"}
100
104
  \`\`\`
101
105
 
102
106
  Validate envelopes with:
103
- \`cclaw internal envelope-validate --stdin\`
107
+ \`npx cclaw-cli internal envelope-validate --stdin\`
104
108
 
105
109
  ## Primary skill
106
110
 
107
- **${RUNTIME_ROOT}/skills/${IDEATE_SKILL_FOLDER}/SKILL.md**
111
+ **${RUNTIME_ROOT}/skills/${IDEA_SKILL_FOLDER}/SKILL.md**
108
112
  `;
109
113
  }
110
- export function ideateCommandSkillMarkdown(options = {}) {
111
- const frames = resolveIdeateFrames(options.frameIds);
114
+ export function ideaCommandSkillMarkdown(options = {}) {
115
+ const frames = resolveIdeaFrames(options.frameIds);
112
116
  const frameBullets = renderFrameBullets(options.frameIds);
113
- const minimumDistinctFrames = minimumDistinctIdeateFrames(frames.length, options.mode);
117
+ const minimumDistinctFrames = minimumDistinctIdeaFrames(frames.length, options.mode);
114
118
  const frameNames = renderFrameNames(options.frameIds);
115
119
  return `---
116
- name: ${IDEATE_SKILL_NAME}
117
- description: "Repository ideate mode: detect and rank high-leverage improvements, persist a backlog artifact, and hand off to /cc or save/discard."
120
+ name: ${IDEA_SKILL_NAME}
121
+ description: "Repository idea mode: detect and rank high-leverage improvements, persist a backlog artifact, and hand off to /cc or save/discard."
118
122
  ---
119
123
 
120
- # /cc-ideate
124
+ # /cc-idea
121
125
 
122
126
  ## Announce at start
123
127
 
124
- "Using flow-ideate to identify highest-leverage improvements in this
128
+ "Using flow-idea to identify highest-leverage improvements in this
125
129
  repository. Will persist a ranked backlog to
126
- \`${IDEATE_ARTIFACT_PATTERN}\` and end with an explicit handoff."
130
+ \`${IDEA_ARTIFACT_PATTERN}\` and end with an explicit handoff."
127
131
 
128
132
  ## HARD-GATE
129
133
 
130
134
  ${conversationLanguagePolicyMarkdown()}
131
- - Do not start coding in ideate mode.
132
- - Do not mutate \`.cclaw/state/flow-state.json\` — ideate mode sits outside
135
+ - Do not start coding in idea mode.
136
+ - Do not mutate \`.cclaw/state/flow-state.json\` — idea mode sits outside
133
137
  the critical-path flow.
134
- - Always produce the artifact file on disk before presenting the handoff.
138
+ - Whenever ideation output is produced, persist the artifact file on disk
139
+ before presenting the handoff. The only exception is an explicit user-cancel
140
+ from the resume prompt — in that case, write nothing and exit silently.
135
141
  - Always end with a structured handoff that names the concrete follow-up
136
- command for each option. No A/B/C letters without command context.
142
+ command for each option (skipped on explicit cancel). No A/B/C letters
143
+ without command context.
137
144
 
138
145
  ## Protocol
139
146
 
140
147
  ### Phase 0 — Resume and classify
141
148
 
142
149
  1. Use the harness's file-glob tool (\`Glob\` pattern
143
- \`${IDEATE_ARTIFACT_GLOB}\` or equivalent \`ls\`/\`find\`).
144
- 2. Filter to files modified within the last ${IDEATE_RESUME_WINDOW_DAYS} days.
150
+ \`${IDEA_ARTIFACT_GLOB}\` or equivalent \`ls\`/\`find\`).
151
+ 2. Filter to files modified within the last ${IDEA_RESUME_WINDOW_DAYS} days.
145
152
  3. If one or more match, present **one** structured ask using the
146
153
  harness's native tool (${STRUCTURED_ASK_TOOLS}) with options:
147
154
  - **Continue the existing backlog** — read the most-recent
148
- ideate-*.md and work from its candidate list; skip re-scanning.
155
+ idea-*.md and work from its candidate list; skip re-scanning.
149
156
  - **Start a fresh scan** — proceed to Phase 1; the old artifact stays
150
157
  on disk for history.
151
158
  - **Cancel** — stop; do not scan or write anything.
@@ -218,10 +225,10 @@ Only survivors advance to ranking.
218
225
  and break ties with rationale strength.
219
226
  4. Compute the artifact filename:
220
227
  - \`slug\` = first 3–5 words of the top recommendation, lowercase,
221
- non-alphanumeric collapsed to \`-\`, trimmed. When ideate mode is
228
+ non-alphanumeric collapsed to \`-\`, trimmed. When idea mode is
222
229
  focus-hinted (user passed an argument), use the focus hint instead.
223
230
  - \`date\` = today in \`YYYY-MM-DD\` (local time).
224
- - Path = \`.cclaw/artifacts/ideate-<date>-<slug>.md\`.
231
+ - Path = \`.cclaw/artifacts/idea-<date>-<slug>.md\`.
225
232
  5. Use the harness's write-file tool (\`Write\`, \`apply_patch\`, or shell
226
233
  \`cat <<EOF > path\`) to create the artifact with this schema:
227
234
 
@@ -269,7 +276,7 @@ Only survivors advance to ranking.
269
276
  6. Optional: for promising non-selected ideas, write
270
277
  \`${RUNTIME_ROOT}/seeds/SEED-<YYYY-MM-DD>-<slug>.md\` entries with:
271
278
  \`title\`, \`trigger_when\`, \`hypothesis\`, \`action\`, and
272
- \`source_artifact\` = ideate artifact path.
279
+ \`source_artifact\` = idea artifact path.
273
280
  7. Confirm in chat: "Wrote <path>."
274
281
 
275
282
  ### Phase 5 — Handoff prompt
@@ -286,7 +293,7 @@ Required options, in this order:
286
293
  2. **Pick a different candidate** — the agent asks which ID (I-2, I-3, …)
287
294
  and then invokes \`/cc <that candidate's handoff phrase>\`.
288
295
  3. **Save and close** — leave the artifact on disk, do nothing else.
289
- Next session: \`/cc-ideate\` will offer to resume it.
296
+ Next session: \`/cc-idea\` will offer to resume it.
290
297
  4. **Discard** — delete the just-written artifact. Use only when the
291
298
  scan produced nothing actionable.
292
299
 
@@ -298,7 +305,7 @@ lettered list with the same four labels. Do not invent extra options.
298
305
  - **Start /cc on I-1** or **different candidate:** announce
299
306
  "Handing off to /cc <phrase>" and load the \`using-cclaw\` router
300
307
  skill. From there, the normal \`/cc\` classification and stage flow
301
- takes over. Do not produce a second artifact; the ideate file is
308
+ takes over. Do not produce a second artifact; the idea file is
302
309
  preserved as the origin document for this run.
303
310
  - **Save and close:** reply with the artifact path and stop.
304
311
  - **Discard:** delete the artifact file, confirm deletion, stop.
@@ -0,0 +1,31 @@
1
+ export type IdeaFrameId = "pain-friction" | "inversion" | "assumption-break" | "leverage" | "cross-domain-analogy" | "constraint-flip";
2
+ export interface IdeaFrame {
3
+ id: IdeaFrameId;
4
+ label: string;
5
+ prompt: string;
6
+ examplePatterns: string[];
7
+ }
8
+ export interface IdeaFrameDispatchInput {
9
+ focus: string;
10
+ mode: "repo-grounded" | "elsewhere-software" | "elsewhere-non-software";
11
+ signalSummary: string[];
12
+ }
13
+ export interface IdeaFrameDispatchPlanEntry {
14
+ frameId: IdeaFrameId;
15
+ label: string;
16
+ prompt: string;
17
+ }
18
+ export interface IdeaCandidateDraft {
19
+ title: string;
20
+ evidencePath: string;
21
+ summary: string;
22
+ frameId: IdeaFrameId;
23
+ }
24
+ export interface IdeaCandidateMerged extends Omit<IdeaCandidateDraft, "frameId"> {
25
+ frameIds: IdeaFrameId[];
26
+ }
27
+ export declare const DEFAULT_IDEA_FRAME_IDS: readonly IdeaFrameId[];
28
+ export declare const IDEA_FRAMES: readonly IdeaFrame[];
29
+ export declare function resolveIdeaFrames(frameIds?: readonly IdeaFrameId[]): IdeaFrame[];
30
+ export declare function buildIdeaFrameDispatchPlan(input: IdeaFrameDispatchInput, frameIds?: readonly IdeaFrameId[]): IdeaFrameDispatchPlanEntry[];
31
+ export declare function dedupeIdeaCandidates(drafts: readonly IdeaCandidateDraft[]): IdeaCandidateMerged[];
@@ -60,7 +60,7 @@ const FRAME_REGISTRY = {
60
60
  ]
61
61
  }
62
62
  };
63
- export const DEFAULT_IDEATE_FRAME_IDS = Object.freeze([
63
+ export const DEFAULT_IDEA_FRAME_IDS = Object.freeze([
64
64
  "pain-friction",
65
65
  "inversion",
66
66
  "assumption-break",
@@ -68,16 +68,16 @@ export const DEFAULT_IDEATE_FRAME_IDS = Object.freeze([
68
68
  "cross-domain-analogy",
69
69
  "constraint-flip"
70
70
  ]);
71
- export const IDEATE_FRAMES = Object.freeze(DEFAULT_IDEATE_FRAME_IDS.map((id) => FRAME_REGISTRY[id]));
72
- export function resolveIdeateFrames(frameIds) {
71
+ export const IDEA_FRAMES = Object.freeze(DEFAULT_IDEA_FRAME_IDS.map((id) => FRAME_REGISTRY[id]));
72
+ export function resolveIdeaFrames(frameIds) {
73
73
  if (!frameIds || frameIds.length === 0) {
74
- return [...IDEATE_FRAMES];
74
+ return [...IDEA_FRAMES];
75
75
  }
76
76
  const seen = new Set();
77
77
  const resolved = [];
78
78
  for (const rawId of frameIds) {
79
- if (!DEFAULT_IDEATE_FRAME_IDS.includes(rawId)) {
80
- throw new Error(`Unknown ideate frame id: ${rawId}`);
79
+ if (!DEFAULT_IDEA_FRAME_IDS.includes(rawId)) {
80
+ throw new Error(`Unknown idea frame id: ${rawId}`);
81
81
  }
82
82
  if (seen.has(rawId))
83
83
  continue;
@@ -86,11 +86,11 @@ export function resolveIdeateFrames(frameIds) {
86
86
  }
87
87
  return resolved;
88
88
  }
89
- export function buildIdeateFrameDispatchPlan(input, frameIds) {
89
+ export function buildIdeaFrameDispatchPlan(input, frameIds) {
90
90
  const signalBlock = input.signalSummary.length > 0
91
91
  ? input.signalSummary.map((line) => `- ${line}`).join("\n")
92
92
  : "- no pre-scan signals captured yet";
93
- return resolveIdeateFrames(frameIds).map((frame) => ({
93
+ return resolveIdeaFrames(frameIds).map((frame) => ({
94
94
  frameId: frame.id,
95
95
  label: frame.label,
96
96
  prompt: [
@@ -115,7 +115,7 @@ function normalizeCandidateKey(title, evidencePath) {
115
115
  .replace(/\\/gu, "/");
116
116
  return `${normalizedTitle}::${normalizedEvidence}`;
117
117
  }
118
- export function dedupeIdeateCandidates(drafts) {
118
+ export function dedupeIdeaCandidates(drafts) {
119
119
  const merged = new Map();
120
120
  for (const draft of drafts) {
121
121
  const key = normalizeCandidateKey(draft.title, draft.evidencePath);
@@ -0,0 +1,25 @@
1
+ export type IdeaImpact = "high" | "medium" | "low";
2
+ export type IdeaEffort = "s" | "m" | "l";
3
+ export type IdeaConfidence = "high" | "medium" | "low";
4
+ export interface IdeaCandidateEvaluationInput {
5
+ id: string;
6
+ title: string;
7
+ impact: IdeaImpact;
8
+ effort: IdeaEffort;
9
+ confidence: IdeaConfidence;
10
+ rationaleStrength: number;
11
+ counterArgumentStrength: number;
12
+ }
13
+ export interface IdeaCandidateEvaluation extends IdeaCandidateEvaluationInput {
14
+ disposition: "survivor" | "critiqued-out";
15
+ rankingScore: number;
16
+ }
17
+ export interface IdeaRankingResult {
18
+ survivors: IdeaCandidateEvaluation[];
19
+ critiquedOut: IdeaCandidateEvaluation[];
20
+ recommendationId: string | null;
21
+ }
22
+ export declare function isCritiquedOut(rationaleStrength: number, counterArgumentStrength: number): boolean;
23
+ export declare function scoreIdeaCandidate(impact: IdeaImpact, effort: IdeaEffort, confidence: IdeaConfidence): number;
24
+ export declare function evaluateIdeaCandidate(input: IdeaCandidateEvaluationInput): IdeaCandidateEvaluation;
25
+ export declare function rankIdeaCandidates(inputs: readonly IdeaCandidateEvaluationInput[], maxSurvivors?: number): IdeaRankingResult;
@@ -25,22 +25,22 @@ function clampStrength(value) {
25
25
  export function isCritiquedOut(rationaleStrength, counterArgumentStrength) {
26
26
  return clampStrength(counterArgumentStrength) > clampStrength(rationaleStrength);
27
27
  }
28
- export function scoreIdeateCandidate(impact, effort, confidence) {
28
+ export function scoreIdeaCandidate(impact, effort, confidence) {
29
29
  const raw = (IMPACT_POINTS[impact] / EFFORT_COST[effort]) * CONFIDENCE_MULTIPLIER[confidence];
30
30
  return Number(raw.toFixed(3));
31
31
  }
32
- export function evaluateIdeateCandidate(input) {
32
+ export function evaluateIdeaCandidate(input) {
33
33
  const disposition = isCritiquedOut(input.rationaleStrength, input.counterArgumentStrength)
34
34
  ? "critiqued-out"
35
35
  : "survivor";
36
36
  return {
37
37
  ...input,
38
38
  disposition,
39
- rankingScore: scoreIdeateCandidate(input.impact, input.effort, input.confidence)
39
+ rankingScore: scoreIdeaCandidate(input.impact, input.effort, input.confidence)
40
40
  };
41
41
  }
42
- export function rankIdeateCandidates(inputs, maxSurvivors = 10) {
43
- const evaluated = inputs.map(evaluateIdeateCandidate);
42
+ export function rankIdeaCandidates(inputs, maxSurvivors = 10) {
43
+ const evaluated = inputs.map(evaluateIdeaCandidate);
44
44
  const survivors = evaluated
45
45
  .filter((candidate) => candidate.disposition === "survivor")
46
46
  .sort((left, right) => {
@@ -138,5 +138,4 @@ export declare function ironLawRuntimeDocument(options?: {
138
138
  strictLaws?: string[];
139
139
  nowIso?: string;
140
140
  }): IronLawRuntimeDocument;
141
- export declare function ironLawsAgentsMdBlock(): string;
142
141
  export declare function ironLawsSkillMarkdown(): string;
@@ -146,31 +146,37 @@ export function ironLawRuntimeDocument(options = {}) {
146
146
  laws
147
147
  };
148
148
  }
149
- export function ironLawsAgentsMdBlock() {
150
- const rows = IRON_LAWS.map((law) => {
151
- return `| \`${law.id}\` | ${law.rule} | ${law.enforcement} | ${law.severity} |`;
152
- }).join("\n");
153
- return `### Iron Laws
154
-
155
- These rules are always-on. Hook-enforced laws can block actions in strict mode.
156
-
157
- | ID | Rule | Enforced by | Level |
158
- |---|---|---|---|
159
- ${rows}
160
- `;
149
+ function appliesToLabel(law) {
150
+ return law.appliesTo === "all" ? "all stages" : law.appliesTo.join(", ");
151
+ }
152
+ function hardGateReference(law) {
153
+ if (law.appliesTo === "all") {
154
+ return "the active stage `HARD-GATE` block in `.cclaw/skills/<stage>/SKILL.md`";
155
+ }
156
+ return law.appliesTo
157
+ .map((stage) => `\`${RUNTIME_ROOT}/skills/${stage}/SKILL.md\` (${stage} HARD-GATE)`)
158
+ .join(", ");
161
159
  }
162
160
  export function ironLawsSkillMarkdown() {
163
- const list = IRON_LAWS.map((law, index) => {
164
- const applies = law.appliesTo === "all" ? "all stages" : law.appliesTo.join(", ");
161
+ const enforcedLawIds = new Set([
162
+ "stop-clean-or-handoff",
163
+ "review-coverage-complete-before-ship"
164
+ ]);
165
+ const enforced = IRON_LAWS.filter((law) => enforcedLawIds.has(law.id));
166
+ const advisory = IRON_LAWS.filter((law) => !enforcedLawIds.has(law.id));
167
+ const enforcedSections = enforced.map((law, index) => {
165
168
  return `### ${index + 1}. ${law.title}
166
169
 
167
170
  - **ID:** \`${law.id}\`
168
171
  - **Rule:** ${law.rule}
169
172
  - **Why:** ${law.rationale}
170
- - **Applies to:** ${applies}
173
+ - **Applies to:** ${appliesToLabel(law)}
171
174
  - **Enforced by:** ${law.enforcement} (${law.severity})
172
175
  `;
173
176
  }).join("\n");
177
+ const advisoryList = advisory
178
+ .map((law) => `- \`${law.id}\` — applies to ${appliesToLabel(law)}; see ${hardGateReference(law)}.`)
179
+ .join("\n");
174
180
  return `---
175
181
  name: iron-laws
176
182
  description: "Non-negotiable workflow constraints enforced by cclaw hooks and routing."
@@ -181,7 +187,16 @@ description: "Non-negotiable workflow constraints enforced by cclaw hooks and ro
181
187
  These are cclaw's non-negotiable constraints for harness sessions.
182
188
  Use them as the final arbitration layer when local instructions conflict.
183
189
 
184
- ${list}
190
+ ## Hook-Enforced Runtime Laws
191
+
192
+ ${enforcedSections}
193
+
194
+ ## Advisory Laws (Stage-Owned)
195
+
196
+ The following laws remain active guidance, but their canonical enforcement surface
197
+ is each stage's \`HARD-GATE\` contract:
198
+
199
+ ${advisoryList}
185
200
 
186
201
  ## Practical rule
187
202
 
@@ -101,7 +101,7 @@ Optional fields \`source\`, \`severity\`, \`supersedes\`, and \`superseded_by\`
101
101
  | \`first_seen_ts\` | ISO 8601 UTC string | yes | First observed timestamp (usually equals \`created\`). |
102
102
  | \`last_seen_ts\` | ISO 8601 UTC string | yes | Last re-confirmed timestamp. |
103
103
  | \`project\` | string \\| null | yes | Repo or scope name. Use \`null\` when the entry crosses projects. |
104
- | \`source\` | \`"stage" \\| "retro" \\| "compound" \\| "ideate" \\| "manual" \\| null\` | no | Origin channel for the entry when known. |
104
+ | \`source\` | \`"stage" \\| "retro" \\| "compound" \\| "idea" \\| "manual" \\| null\` | no | Origin channel for the entry when known. |
105
105
  | \`severity\` | \`"critical" \\| "important" \\| "suggestion"\` | no | Priority signal for compound lifts; \`critical\` enables single-hit override in compound readiness analysis. |
106
106
  | \`supersedes\` | string[] | no | Non-empty IDs/slugs of older entries this entry refreshes. Use only for clear replacements discovered during compound closeout or curation. |
107
107
  | \`superseded_by\` | string | no | Non-empty ID/slug of the newer entry that refreshes this one. Use only when marking stale guidance as replaced. |
@@ -13,7 +13,7 @@ function generatedHelperSkillList() {
13
13
  export function usingCclawSkillMarkdown() {
14
14
  return `---
15
15
  name: using-cclaw
16
- description: "Routing brain for cclaw. Decide whether to start/resume a stage, answer directly, or use visible commands like /cc, /cc-next, /cc-ideate, and /cc-view."
16
+ description: "Routing brain for cclaw. Decide whether to start/resume a stage, answer directly, or use visible commands like /cc, /cc-idea, and /cc-cancel."
17
17
  ---
18
18
 
19
19
  # Using Cclaw
@@ -64,12 +64,11 @@ Task arrives
64
64
  ├─ Running as spawned subagent? -> obey parent prompt only; do not run cclaw routing
65
65
  ├─ Pure question / non-software ask? -> answer directly (no stage)
66
66
  ├─ New software work? -> /cc <idea>
67
- ├─ Repo-improvement discovery? -> /cc-ideate
68
- ├─ Resume existing flow? -> /cc or /cc-next
67
+ ├─ Repo-improvement discovery? -> /cc-idea
68
+ ├─ Resume existing flow? -> /cc
69
69
  ├─ Knowledge operation? -> load the learnings skill
70
- ├─ Read-only workspace view? -> /cc-view [status|tree|diff]
71
- ├─ Normal post-ship closeout? -> /cc-next drives ${closeoutChainInline()}
72
- └─ Explicit early archival/reset? -> npx cclaw-cli archive [--name=<slug>]
70
+ ├─ Normal post-ship closeout? -> /cc drives ${closeoutChainInline()}
71
+ └─ Explicit early cancellation/abandonment? -> /cc-cancel
73
72
  \`\`\`
74
73
 
75
74
  ## Task classification
@@ -87,25 +86,24 @@ Task arrives
87
86
  Before stage work:
88
87
 
89
88
  1. Read \`.cclaw/state/flow-state.json\`.
90
- 2. If active stage exists, continue with \`/cc\` or \`/cc-next\`.
89
+ 2. If active stage exists, continue with \`/cc\`.
91
90
  3. Do not jump directly to stage-specific commands.
92
91
 
93
92
  ## Platform reliability notes
94
93
 
95
94
  - Managed hook dispatch uses \`.cclaw/hooks/run-hook.cmd\` (cross-platform wrapper).
96
- - If hooks fail due missing runtime deps (for example \`node\` not on \`PATH\`), run \`npx cclaw-cli doctor\` before continuing.
95
+ - If hooks fail due missing runtime deps (for example \`node\` not on \`PATH\`), run \`npx cclaw-cli sync\` before continuing.
97
96
  - Prefer cross-platform commands in artifacts/examples (\`npm test\`, \`pnpm test\`, \`python -m pytest\`, etc.) over shell-specific aliases whenever possible.
98
97
 
99
98
  ## Stage quick map
100
99
 
101
- Use \`/cc <idea>\` for new work, \`/cc-next\` for progression and closeout, \`/cc-view\` for read-only state, and \`/cc-ideate\` for backlog discovery.
100
+ Use \`/cc <idea>\` for new work, \`/cc\` for progression and closeout, \`/cc-idea\` for backlog discovery, and \`/cc-cancel\` for cancellation/abandonment.
102
101
 
103
102
  ## Main vs Operator Surfaces
104
103
 
105
- - **Main workflow:** \`/cc\`, \`/cc-next\`, \`/cc-ideate\`, \`/cc-view status\`, and \`node .cclaw/hooks/stage-complete.mjs <stage>\` inside the installed harness runtime.
106
- - **Installer/support surface:** \`npx cclaw-cli init\`, \`npx cclaw-cli sync\`, \`npx cclaw-cli upgrade\`, \`npx cclaw-cli doctor\`, and explicit support/archive actions. Do not ask users to install or run a \`cclaw\` binary during normal stage flow.
107
- - **Read-only support:** \`/cc-view tree\` and \`/cc-view diff\`.
108
- - Use operator/support surfaces only for install/runtime diagnosis, explicit archival, or deeper inspection. Do not make them part of the happy path.
104
+ - **Main workflow:** \`/cc\`, \`/cc-idea\`, and \`/cc-cancel\` inside the installed harness runtime.
105
+ - **Installer/support surface:** \`npx cclaw-cli init\`, \`npx cclaw-cli sync\`, \`npx cclaw-cli upgrade\`, \`npx cclaw-cli sync\`, and \`npx cclaw-cli uninstall\`.
106
+ - Use operator/support surfaces only for install/runtime diagnosis or lifecycle maintenance. Do not make them part of the happy path.
109
107
 
110
108
  ## Whole flow map
111
109
 
@@ -15,6 +15,16 @@ export interface NodeHookRuntimeOptions {
15
15
  * `cclaw sync` after changing the config value so hook and CLI agree.
16
16
  */
17
17
  compoundRecurrenceThreshold?: number;
18
+ /**
19
+ * Enables early-stage producer/critic loop diagnostics in session-start.
20
+ * Defaults to true.
21
+ */
22
+ earlyLoopEnabled?: boolean;
23
+ /**
24
+ * Baked-in max iterations for brainstorm/scope/design early-loop status.
25
+ * Derived from `config.earlyLoop.maxIterations`.
26
+ */
27
+ earlyLoopMaxIterations?: number;
18
28
  }
19
29
  /**
20
30
  * Node-only hook runtime (single entrypoint).