cclaw-cli 0.48.35 → 0.51.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.
Files changed (181) hide show
  1. package/README.md +54 -82
  2. package/dist/artifact-linter.d.ts +4 -0
  3. package/dist/artifact-linter.js +24 -3
  4. package/dist/cli.d.ts +1 -19
  5. package/dist/cli.js +49 -495
  6. package/dist/constants.d.ts +2 -13
  7. package/dist/constants.js +1 -46
  8. package/dist/content/closeout-guidance.d.ts +14 -0
  9. package/dist/content/closeout-guidance.js +42 -0
  10. package/dist/content/core-agents.js +51 -9
  11. package/dist/content/decision-protocol.d.ts +12 -0
  12. package/dist/content/decision-protocol.js +20 -0
  13. package/dist/content/diff-command.d.ts +1 -2
  14. package/dist/content/diff-command.js +8 -94
  15. package/dist/content/examples.d.ts +4 -10
  16. package/dist/content/examples.js +10 -20
  17. package/dist/content/hook-events.js +2 -2
  18. package/dist/content/hook-inline-snippets.d.ts +5 -2
  19. package/dist/content/hook-inline-snippets.js +33 -1
  20. package/dist/content/hook-manifest.d.ts +3 -4
  21. package/dist/content/hook-manifest.js +11 -12
  22. package/dist/content/hooks.js +2 -0
  23. package/dist/content/ideate-command.d.ts +2 -0
  24. package/dist/content/ideate-command.js +31 -25
  25. package/dist/content/iron-laws.d.ts +5 -5
  26. package/dist/content/iron-laws.js +5 -5
  27. package/dist/content/learnings.d.ts +3 -4
  28. package/dist/content/learnings.js +24 -50
  29. package/dist/content/meta-skill.js +31 -24
  30. package/dist/content/next-command.js +38 -38
  31. package/dist/content/node-hooks.js +17 -343
  32. package/dist/content/opencode-plugin.js +2 -100
  33. package/dist/content/research-playbooks.js +14 -14
  34. package/dist/content/review-loop.d.ts +2 -0
  35. package/dist/content/review-loop.js +8 -0
  36. package/dist/content/session-hooks.js +14 -46
  37. package/dist/content/skills.d.ts +0 -5
  38. package/dist/content/skills.js +53 -128
  39. package/dist/content/stage-common-guidance.d.ts +0 -1
  40. package/dist/content/stage-common-guidance.js +15 -14
  41. package/dist/content/stage-schema.d.ts +26 -1
  42. package/dist/content/stage-schema.js +121 -40
  43. package/dist/content/stages/_lint-metadata/index.js +9 -15
  44. package/dist/content/stages/brainstorm.js +22 -43
  45. package/dist/content/stages/design.js +37 -57
  46. package/dist/content/stages/plan.js +22 -13
  47. package/dist/content/stages/review.js +24 -27
  48. package/dist/content/stages/scope.js +34 -46
  49. package/dist/content/stages/ship.js +7 -4
  50. package/dist/content/stages/spec.js +20 -9
  51. package/dist/content/stages/tdd.js +64 -44
  52. package/dist/content/start-command.js +10 -12
  53. package/dist/content/status-command.d.ts +2 -7
  54. package/dist/content/status-command.js +19 -146
  55. package/dist/content/subagents.d.ts +0 -5
  56. package/dist/content/subagents.js +47 -28
  57. package/dist/content/templates.d.ts +1 -1
  58. package/dist/content/templates.js +126 -135
  59. package/dist/content/track-render-context.d.ts +17 -0
  60. package/dist/content/track-render-context.js +44 -0
  61. package/dist/content/tree-command.d.ts +1 -2
  62. package/dist/content/tree-command.js +4 -87
  63. package/dist/content/utility-skills.d.ts +2 -29
  64. package/dist/content/utility-skills.js +2 -1533
  65. package/dist/content/view-command.js +29 -11
  66. package/dist/delegation.d.ts +1 -1
  67. package/dist/delegation.js +5 -15
  68. package/dist/doctor-registry.js +20 -21
  69. package/dist/doctor.js +88 -408
  70. package/dist/flow-state.d.ts +3 -0
  71. package/dist/flow-state.js +2 -0
  72. package/dist/harness-adapters.d.ts +1 -1
  73. package/dist/harness-adapters.js +48 -57
  74. package/dist/install.js +128 -520
  75. package/dist/internal/advance-stage.js +3 -9
  76. package/dist/internal/compound-readiness.d.ts +1 -1
  77. package/dist/internal/compound-readiness.js +1 -1
  78. package/dist/internal/tdd-loop-status.d.ts +1 -1
  79. package/dist/internal/tdd-loop-status.js +1 -1
  80. package/dist/knowledge-store.d.ts +16 -10
  81. package/dist/knowledge-store.js +51 -15
  82. package/dist/policy.js +16 -109
  83. package/dist/run-archive.d.ts +4 -6
  84. package/dist/run-archive.js +15 -20
  85. package/dist/run-persistence.d.ts +2 -2
  86. package/dist/run-persistence.js +3 -9
  87. package/package.json +1 -2
  88. package/dist/content/archive-command.d.ts +0 -2
  89. package/dist/content/archive-command.js +0 -124
  90. package/dist/content/compound-command.d.ts +0 -5
  91. package/dist/content/compound-command.js +0 -193
  92. package/dist/content/contexts.d.ts +0 -9
  93. package/dist/content/contexts.js +0 -65
  94. package/dist/content/contracts.d.ts +0 -2
  95. package/dist/content/contracts.js +0 -51
  96. package/dist/content/doctor-references.d.ts +0 -2
  97. package/dist/content/doctor-references.js +0 -150
  98. package/dist/content/eval-scaffold.d.ts +0 -15
  99. package/dist/content/eval-scaffold.js +0 -370
  100. package/dist/content/feature-command.d.ts +0 -2
  101. package/dist/content/feature-command.js +0 -123
  102. package/dist/content/flow-map.d.ts +0 -23
  103. package/dist/content/flow-map.js +0 -134
  104. package/dist/content/harness-doc.d.ts +0 -2
  105. package/dist/content/harness-doc.js +0 -202
  106. package/dist/content/harness-playbooks.d.ts +0 -24
  107. package/dist/content/harness-playbooks.js +0 -393
  108. package/dist/content/harness-tool-refs.d.ts +0 -20
  109. package/dist/content/harness-tool-refs.js +0 -268
  110. package/dist/content/ops-command.d.ts +0 -2
  111. package/dist/content/ops-command.js +0 -71
  112. package/dist/content/protocols.d.ts +0 -7
  113. package/dist/content/protocols.js +0 -215
  114. package/dist/content/retro-command.d.ts +0 -2
  115. package/dist/content/retro-command.js +0 -165
  116. package/dist/content/rewind-command.d.ts +0 -2
  117. package/dist/content/rewind-command.js +0 -106
  118. package/dist/content/tdd-log-command.d.ts +0 -2
  119. package/dist/content/tdd-log-command.js +0 -85
  120. package/dist/eval/agents/single-shot.d.ts +0 -27
  121. package/dist/eval/agents/single-shot.js +0 -79
  122. package/dist/eval/agents/with-tools.d.ts +0 -44
  123. package/dist/eval/agents/with-tools.js +0 -261
  124. package/dist/eval/agents/workflow.d.ts +0 -31
  125. package/dist/eval/agents/workflow.js +0 -155
  126. package/dist/eval/baseline.d.ts +0 -38
  127. package/dist/eval/baseline.js +0 -282
  128. package/dist/eval/config-loader.d.ts +0 -14
  129. package/dist/eval/config-loader.js +0 -395
  130. package/dist/eval/corpus.d.ts +0 -30
  131. package/dist/eval/corpus.js +0 -330
  132. package/dist/eval/cost-guard.d.ts +0 -102
  133. package/dist/eval/cost-guard.js +0 -190
  134. package/dist/eval/diff.d.ts +0 -64
  135. package/dist/eval/diff.js +0 -323
  136. package/dist/eval/llm-client.d.ts +0 -176
  137. package/dist/eval/llm-client.js +0 -267
  138. package/dist/eval/mode.d.ts +0 -28
  139. package/dist/eval/mode.js +0 -61
  140. package/dist/eval/progress.d.ts +0 -83
  141. package/dist/eval/progress.js +0 -59
  142. package/dist/eval/report.d.ts +0 -11
  143. package/dist/eval/report.js +0 -181
  144. package/dist/eval/rubric-loader.d.ts +0 -20
  145. package/dist/eval/rubric-loader.js +0 -143
  146. package/dist/eval/runner.d.ts +0 -81
  147. package/dist/eval/runner.js +0 -746
  148. package/dist/eval/runs.d.ts +0 -41
  149. package/dist/eval/runs.js +0 -114
  150. package/dist/eval/sandbox.d.ts +0 -38
  151. package/dist/eval/sandbox.js +0 -137
  152. package/dist/eval/tools/glob.d.ts +0 -2
  153. package/dist/eval/tools/glob.js +0 -163
  154. package/dist/eval/tools/grep.d.ts +0 -2
  155. package/dist/eval/tools/grep.js +0 -152
  156. package/dist/eval/tools/index.d.ts +0 -7
  157. package/dist/eval/tools/index.js +0 -35
  158. package/dist/eval/tools/read.d.ts +0 -2
  159. package/dist/eval/tools/read.js +0 -122
  160. package/dist/eval/tools/types.d.ts +0 -49
  161. package/dist/eval/tools/types.js +0 -41
  162. package/dist/eval/tools/write.d.ts +0 -2
  163. package/dist/eval/tools/write.js +0 -92
  164. package/dist/eval/types.d.ts +0 -561
  165. package/dist/eval/types.js +0 -47
  166. package/dist/eval/verifiers/judge.d.ts +0 -40
  167. package/dist/eval/verifiers/judge.js +0 -256
  168. package/dist/eval/verifiers/rules.d.ts +0 -24
  169. package/dist/eval/verifiers/rules.js +0 -218
  170. package/dist/eval/verifiers/structural.d.ts +0 -14
  171. package/dist/eval/verifiers/structural.js +0 -171
  172. package/dist/eval/verifiers/traceability.d.ts +0 -23
  173. package/dist/eval/verifiers/traceability.js +0 -84
  174. package/dist/eval/verifiers/workflow-consistency.d.ts +0 -21
  175. package/dist/eval/verifiers/workflow-consistency.js +0 -225
  176. package/dist/eval/workflow-corpus.d.ts +0 -7
  177. package/dist/eval/workflow-corpus.js +0 -207
  178. package/dist/feature-system.d.ts +0 -42
  179. package/dist/feature-system.js +0 -432
  180. package/dist/internal/knowledge-digest.d.ts +0 -7
  181. package/dist/internal/knowledge-digest.js +0 -93
@@ -10,17 +10,8 @@ export declare const FLOW_VERSION = "1.0.0";
10
10
  export declare const SHIP_FINALIZATION_MODES: readonly ["FINALIZE_MERGE_LOCAL", "FINALIZE_OPEN_PR", "FINALIZE_KEEP_BRANCH", "FINALIZE_DISCARD_BRANCH", "FINALIZE_NO_VCS"];
11
11
  export type ShipFinalizationMode = (typeof SHIP_FINALIZATION_MODES)[number];
12
12
  export declare const DEFAULT_HARNESSES: HarnessId[];
13
- /**
14
- * Evals subtree. Scaffolds the directory layout and a default config.yaml; the
15
- * structural verifier, rule verifiers, and LLM wiring layer on incrementally.
16
- * Keeping this separate from the main REQUIRED_DIRS list makes it explicit that
17
- * the evals runtime is additive and does not affect non-eval cclaw behavior.
18
- */
19
- export declare const EVALS_ROOT = ".cclaw/evals";
20
- export declare const EVALS_CONFIG_PATH = ".cclaw/evals/config.yaml";
21
- export declare const EVALS_DIRS: readonly [".cclaw/evals", ".cclaw/evals/corpus", ".cclaw/evals/rubrics", ".cclaw/evals/baselines", ".cclaw/evals/reports"];
22
- export declare const REQUIRED_DIRS: readonly [".cclaw", ".cclaw/commands", ".cclaw/skills", ".cclaw/contexts", ".cclaw/templates", ".cclaw/artifacts", ".cclaw/worktrees", ".cclaw/state", ".cclaw/runs", ".cclaw/rules", ".cclaw/adapters", ".cclaw/agents", ".cclaw/hooks", ".cclaw/custom-skills", ".cclaw/evals", ".cclaw/evals/corpus", ".cclaw/evals/rubrics", ".cclaw/evals/baselines", ".cclaw/evals/reports"];
23
- export declare const REQUIRED_GITIGNORE_PATTERNS: readonly ["# cclaw generated artifacts", ".cclaw/", "# cclaw evals: user-owned, track in git", "!.cclaw/evals/", "!.cclaw/evals/config.yaml", "!.cclaw/evals/corpus/", "!.cclaw/evals/corpus/**", "!.cclaw/evals/rubrics/", "!.cclaw/evals/rubrics/**", "!.cclaw/evals/baselines/", "!.cclaw/evals/baselines/**", ".claude/commands/cc-*.md", ".claude/commands/cc.md", ".cursor/commands/cc-*.md", ".cursor/commands/cc.md", ".opencode/commands/cc-*.md", ".opencode/commands/cc.md", ".agents/skills/cc/SKILL.md", ".agents/skills/cc-*/SKILL.md", ".claude/hooks/hooks.json", ".cursor/hooks.json", ".codex/hooks.json", ".opencode/plugins/cclaw-plugin.mjs", ".cursor/rules/cclaw-workflow.mdc"];
13
+ export declare const REQUIRED_DIRS: readonly [".cclaw", ".cclaw/commands", ".cclaw/skills", ".cclaw/templates", ".cclaw/artifacts", ".cclaw/state", ".cclaw/runs", ".cclaw/rules", ".cclaw/agents", ".cclaw/hooks"];
14
+ export declare const REQUIRED_GITIGNORE_PATTERNS: readonly ["# cclaw generated artifacts", ".cclaw/", ".claude/commands/cc-*.md", ".claude/commands/cc.md", ".cursor/commands/cc-*.md", ".cursor/commands/cc.md", ".opencode/commands/cc-*.md", ".opencode/commands/cc.md", ".agents/skills/cc/SKILL.md", ".agents/skills/cc-*/SKILL.md", ".claude/hooks/hooks.json", ".cursor/hooks.json", ".codex/hooks.json", ".opencode/plugins/cclaw-plugin.mjs", ".cursor/rules/cclaw-workflow.mdc"];
24
15
  /**
25
16
  * Canonical stage -> skill folder mapping.
26
17
  *
@@ -31,6 +22,4 @@ export declare const REQUIRED_GITIGNORE_PATTERNS: readonly ["# cclaw generated a
31
22
  * Keep this map as the single source of truth for generated skill paths.
32
23
  */
33
24
  export declare const STAGE_TO_SKILL_FOLDER: Record<FlowStage, string>;
34
- export declare const UTILITY_COMMANDS: readonly ["learn", "next", "ideate", "view", "status", "tree", "diff", "ops", "feature", "tdd-log", "retro", "compound", "archive", "rewind"];
35
25
  export declare const SUBAGENT_SKILL_FOLDERS: readonly ["subagent-dev", "parallel-dispatch"];
36
- export type UtilityCommand = (typeof UTILITY_COMMANDS)[number];
package/dist/constants.js CHANGED
@@ -52,50 +52,21 @@ export const DEFAULT_HARNESSES = [
52
52
  "opencode",
53
53
  "codex"
54
54
  ];
55
- /**
56
- * Evals subtree. Scaffolds the directory layout and a default config.yaml; the
57
- * structural verifier, rule verifiers, and LLM wiring layer on incrementally.
58
- * Keeping this separate from the main REQUIRED_DIRS list makes it explicit that
59
- * the evals runtime is additive and does not affect non-eval cclaw behavior.
60
- */
61
- export const EVALS_ROOT = `${RUNTIME_ROOT}/evals`;
62
- export const EVALS_CONFIG_PATH = `${EVALS_ROOT}/config.yaml`;
63
- export const EVALS_DIRS = [
64
- EVALS_ROOT,
65
- `${EVALS_ROOT}/corpus`,
66
- `${EVALS_ROOT}/rubrics`,
67
- `${EVALS_ROOT}/baselines`,
68
- `${EVALS_ROOT}/reports`
69
- ];
70
55
  export const REQUIRED_DIRS = [
71
56
  RUNTIME_ROOT,
72
57
  `${RUNTIME_ROOT}/commands`,
73
58
  `${RUNTIME_ROOT}/skills`,
74
- `${RUNTIME_ROOT}/contexts`,
75
59
  `${RUNTIME_ROOT}/templates`,
76
60
  `${RUNTIME_ROOT}/artifacts`,
77
- `${RUNTIME_ROOT}/worktrees`,
78
61
  `${RUNTIME_ROOT}/state`,
79
62
  `${RUNTIME_ROOT}/runs`,
80
63
  `${RUNTIME_ROOT}/rules`,
81
- `${RUNTIME_ROOT}/adapters`,
82
64
  `${RUNTIME_ROOT}/agents`,
83
- `${RUNTIME_ROOT}/hooks`,
84
- `${RUNTIME_ROOT}/custom-skills`,
85
- ...EVALS_DIRS
65
+ `${RUNTIME_ROOT}/hooks`
86
66
  ];
87
67
  export const REQUIRED_GITIGNORE_PATTERNS = [
88
68
  "# cclaw generated artifacts",
89
69
  `${RUNTIME_ROOT}/`,
90
- "# cclaw evals: user-owned, track in git",
91
- `!${EVALS_ROOT}/`,
92
- `!${EVALS_ROOT}/config.yaml`,
93
- `!${EVALS_ROOT}/corpus/`,
94
- `!${EVALS_ROOT}/corpus/**`,
95
- `!${EVALS_ROOT}/rubrics/`,
96
- `!${EVALS_ROOT}/rubrics/**`,
97
- `!${EVALS_ROOT}/baselines/`,
98
- `!${EVALS_ROOT}/baselines/**`,
99
70
  ".claude/commands/cc-*.md",
100
71
  ".claude/commands/cc.md",
101
72
  ".cursor/commands/cc-*.md",
@@ -133,22 +104,6 @@ export const STAGE_TO_SKILL_FOLDER = {
133
104
  review: "two-layer-review",
134
105
  ship: "shipping-and-handoff"
135
106
  };
136
- export const UTILITY_COMMANDS = [
137
- "learn",
138
- "next",
139
- "ideate",
140
- "view",
141
- "status",
142
- "tree",
143
- "diff",
144
- "ops",
145
- "feature",
146
- "tdd-log",
147
- "retro",
148
- "compound",
149
- "archive",
150
- "rewind"
151
- ];
152
107
  export const SUBAGENT_SKILL_FOLDERS = [
153
108
  "subagent-dev",
154
109
  "parallel-dispatch"
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared post-ship closeout wording.
3
+ *
4
+ * Keep closeout chain and ship substate language in one place across command
5
+ * contracts, skills, and stage/docs surfaces.
6
+ */
7
+ export declare const CLOSEOUT_CHAIN = "retro -> compound -> archive";
8
+ export declare const CLOSEOUT_SUBSTATE_KEY = "closeout.shipSubstate";
9
+ export declare function closeoutChainInline(): string;
10
+ export declare function closeoutSubstateInline(): string;
11
+ export declare function closeoutNextCommandGuidance(): string;
12
+ export declare function closeoutSubstateProtocolBullets(): string;
13
+ export declare function closeoutFlowMapSentence(): string;
14
+ export declare function closeoutProtocolBehaviorSentence(): string;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Shared post-ship closeout wording.
3
+ *
4
+ * Keep closeout chain and ship substate language in one place across command
5
+ * contracts, skills, and stage/docs surfaces.
6
+ */
7
+ export const CLOSEOUT_CHAIN = "retro -> compound -> archive";
8
+ export const CLOSEOUT_SUBSTATE_KEY = "closeout.shipSubstate";
9
+ export function closeoutChainInline() {
10
+ return `\`${CLOSEOUT_CHAIN}\``;
11
+ }
12
+ export function closeoutSubstateInline() {
13
+ return `\`${CLOSEOUT_SUBSTATE_KEY}\``;
14
+ }
15
+ export function closeoutNextCommandGuidance() {
16
+ return `After ship completes, the closeout chain ${closeoutChainInline()} runs automatically, driven by ${closeoutSubstateInline()}. Continue through \`/cc-next\`; do not branch into \`ce:compound\`, a separate operations router, or a one-off closeout command. Ralph Loop may be mentioned only as tdd carry-forward context when it explains the next \`/cc-next\` move; it is not part of compound/archive routing.`;
17
+ }
18
+ export function closeoutSubstateProtocolBullets() {
19
+ return `When \`currentStage === "ship"\`, route by **${closeoutSubstateInline()}**:
20
+ - \`"idle"\` or missing -> set ${closeoutSubstateInline()} = \`"retro_review"\`, then
21
+ execute the in-stage retro protocol (draft + one structured accept/edit/skip ask).
22
+ - \`"retro_review"\` -> continue the retro protocol (re-ask the structured
23
+ question; the draft already exists — do not regenerate it).
24
+ - \`"compound_review"\` -> execute the in-stage compound closeout scan (not \`ce:compound\`):
25
+ read \`.cclaw/state/compound-readiness.json\` plus the relevant tail of
26
+ \`.cclaw/knowledge.jsonl\`, assess overlap before adding duplicate knowledge,
27
+ separate bug-track learnings (turn into rules/tests/remediation) from
28
+ knowledge-track learnings (durable project/process guidance), and use
29
+ lightweight \`supersedes\` / \`superseded_by\` fields when refreshing stale or
30
+ partially replaced entries. Optionally ask whether to scan Cursor/Claude/Codex
31
+ session transcripts for matching historical learnings; only do it after opt-in.
32
+ Ask **one** structured question (apply / skip) per candidate cluster or a
33
+ single accept-all / skip choice, then advance substate.
34
+ - \`"ready_to_archive"\` -> run \`cclaw archive\` (or \`cclaw archive --name=<slug>\`) and reset state.
35
+ - \`"archived"\` (transient) -> report "run archived" and stop.`;
36
+ }
37
+ export function closeoutFlowMapSentence() {
38
+ return `The first stage names are the critical path. \`retro\`, \`compound\`, and \`archive\` are post-ship closeout substates under ${closeoutSubstateInline()}, not separate stage schemas or commands. Continue them with \`/cc-next\`; do not route compound closeout through \`ce:compound\`.`;
39
+ }
40
+ export function closeoutProtocolBehaviorSentence() {
41
+ return `Keep decision, completion, and preamble discipline inline: ask only decision-changing questions, verify gates before advancing, and keep context compact. After \`ship\`, keep using \`/cc-next\` through ${closeoutChainInline()}; do not route normal closeout through \`ce:compound\` or a separate operations command. In compound closeout, assess overlap before appending knowledge: refresh recurring bug-track learnings as actionable rules/tests, keep knowledge-track learnings as durable process/project guidance, and mark outdated entries with lightweight \`supersedes\` / \`superseded_by\` fields instead of building a new doc system.`;
42
+ }
@@ -13,6 +13,38 @@ function yamlScalarString(value) {
13
13
  function yamlFlowSequence(values) {
14
14
  return JSON.stringify(values);
15
15
  }
16
+ function formattedAgentsForStages(stages) {
17
+ const summary = stageDelegationSummary("standard");
18
+ const merged = [];
19
+ for (const stage of stages) {
20
+ const row = summary.find((item) => item.stage === stage);
21
+ if (!row)
22
+ continue;
23
+ for (const agent of row.primaryAgents) {
24
+ if (!merged.includes(agent)) {
25
+ merged.push(agent);
26
+ }
27
+ }
28
+ }
29
+ return merged.length > 0 ? merged.join(", ") : "none";
30
+ }
31
+ function activationModeSummary() {
32
+ const summary = stageDelegationSummary("standard");
33
+ const mandatory = new Set();
34
+ const proactive = new Set();
35
+ for (const row of summary) {
36
+ for (const agent of row.mandatoryAgents) {
37
+ mandatory.add(agent);
38
+ }
39
+ for (const agent of row.proactiveAgents) {
40
+ proactive.add(agent);
41
+ }
42
+ }
43
+ return {
44
+ mandatory: [...mandatory].join(", "),
45
+ proactive: [...proactive].join(", ")
46
+ };
47
+ }
16
48
  /**
17
49
  * Canonical specialist roster (core-5) materialized under `.cclaw/agents/`.
18
50
  *
@@ -135,6 +167,7 @@ export const CCLAW_AGENTS = [
135
167
  ].join("\n")
136
168
  }
137
169
  ];
170
+ import { stageDelegationSummary } from "./stage-schema.js";
138
171
  import { enhancedAgentBody } from "./subagents.js";
139
172
  /**
140
173
  * Render a complete cclaw agent markdown file (YAML frontmatter + body).
@@ -175,14 +208,20 @@ ${taskDelegation}
175
208
  * Markdown table mapping cclaw stage entry points to specialist agents.
176
209
  */
177
210
  export function agentRoutingTable() {
211
+ const brainstormPrimary = formattedAgentsForStages(["brainstorm"]);
212
+ const scopeDesignPlanPrimary = formattedAgentsForStages(["scope", "design", "plan"]);
213
+ const specPrimary = formattedAgentsForStages(["spec"]);
214
+ const tddPrimary = formattedAgentsForStages(["tdd"]);
215
+ const reviewPrimary = formattedAgentsForStages(["review"]);
216
+ const shipPrimary = formattedAgentsForStages(["ship"]);
178
217
  return `| Stage Entry | Primary Agent(s) | Supporting guidance |
179
218
  |---|---|---|
180
- | Brainstorm (start with \`/cc <idea>\`) | planner | Run in-thread research playbooks: \`research/repo-scan.md\`, \`research/learnings-lookup.md\` |
181
- | Scope / Design / Plan (via \`/cc-next\`) | planner | Use \`research/git-history.md\` (scope) and \`research/framework-docs-lookup.md\` + \`research/best-practices-lookup.md\` (design) as needed |
182
- | Spec (via \`/cc-next\`) | reviewer | planner (if ambiguity or conflicts remain) |
183
- | TDD (via \`/cc-next\`) | test-author | doc-updater on public behavior/config changes |
184
- | Review (via \`/cc-next\`) | reviewer, security-reviewer | conditional second reviewer for high blast-radius diffs |
185
- | Ship (via \`/cc-next\`) | doc-updater | security-reviewer when release risk is elevated |
219
+ | Brainstorm (start with \`/cc <idea>\`) | ${brainstormPrimary} | Run in-thread research playbooks: \`research/repo-scan.md\`, \`research/learnings-lookup.md\` |
220
+ | Scope / Design / Plan (via \`/cc-next\`) | ${scopeDesignPlanPrimary} | Use \`research/git-history.md\` (scope) and \`research/framework-docs-lookup.md\` + \`research/best-practices-lookup.md\` (design) as needed |
221
+ | Spec (via \`/cc-next\`) | ${specPrimary} | planner (if ambiguity or conflicts remain) |
222
+ | TDD (via \`/cc-next\`) | ${tddPrimary} | doc-updater on public behavior/config changes |
223
+ | Review (via \`/cc-next\`) | ${reviewPrimary} | conditional second reviewer for high blast-radius diffs |
224
+ | Ship (via \`/cc-next\`) | ${shipPrimary} | security-reviewer when release risk is elevated |
186
225
  `;
187
226
  }
188
227
  /**
@@ -218,9 +257,12 @@ Research work is no longer modeled as standalone personas. Use in-thread playboo
218
257
 
219
258
  ### Activation modes
220
259
 
221
- - **Mandatory:** planner (scope/design/plan), reviewer + security-reviewer (review), test-author (tdd), doc-updater (ship).
222
- - **Proactive:** planner on ambiguity, security-reviewer on trust-boundary movement outside review, doc-updater on behavior/config drift.
223
- - **On-demand:** none in the core-5 roster; research playbooks are in-thread procedures.
260
+ ${(() => {
261
+ const mode = activationModeSummary();
262
+ return `- **Mandatory:** ${mode.mandatory}.
263
+ - **Proactive:** ${mode.proactive}.
264
+ - **On-demand:** none in the core-5 roster; research playbooks are in-thread procedures.`;
265
+ })()}
224
266
 
225
267
  ### Cost-aware routing
226
268
 
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shared wording blocks for Decision Protocol + structured ask fallback.
3
+ *
4
+ * Keep stage/utility prompt surfaces consistent and reduce wording drift.
5
+ */
6
+ export declare const STRUCTURED_ASK_TOOL_LIST_GENERIC = "`AskUserQuestion` / `AskQuestion` / `question` / `request_user_input`";
7
+ export declare const STRUCTURED_ASK_TOOL_LIST_REVIEW = "`AskUserQuestion` on Claude, `AskQuestion` on Cursor, `question` on OpenCode with `permission.question: \"allow\"`, `request_user_input` on Codex in Plan/Collaboration mode";
8
+ export declare const STRUCTURED_ASK_TOOL_LIST_IDEATE = "`AskUserQuestion` on Claude, `AskQuestion` on Cursor, `question` on OpenCode when `permission.question: \"allow\"` is set, `request_user_input` on Codex in Plan / Collaboration mode";
9
+ export declare function structuredAskFallbackSentence(toolList?: string): string;
10
+ export declare function decisionProtocolInstruction(subject: string, optionsClause: string, recommendationClause: string, toolList?: string): string;
11
+ export declare function structuredAskSingleChoiceInstruction(subject: string, choicesClause: string, toolList?: string): string;
12
+ export declare function ideateStructuredAskToolsWithFallback(): string;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shared wording blocks for Decision Protocol + structured ask fallback.
3
+ *
4
+ * Keep stage/utility prompt surfaces consistent and reduce wording drift.
5
+ */
6
+ export const STRUCTURED_ASK_TOOL_LIST_GENERIC = "\`AskUserQuestion\` / \`AskQuestion\` / \`question\` / \`request_user_input\`";
7
+ export const STRUCTURED_ASK_TOOL_LIST_REVIEW = "\`AskUserQuestion\` on Claude, \`AskQuestion\` on Cursor, \`question\` on OpenCode with \`permission.question: \"allow\"\`, \`request_user_input\` on Codex in Plan/Collaboration mode";
8
+ export const STRUCTURED_ASK_TOOL_LIST_IDEATE = "\`AskUserQuestion\` on Claude, \`AskQuestion\` on Cursor, \`question\` on OpenCode when \`permission.question: \"allow\"\` is set, \`request_user_input\` on Codex in Plan / Collaboration mode";
9
+ export function structuredAskFallbackSentence(toolList = STRUCTURED_ASK_TOOL_LIST_GENERIC) {
10
+ return `If the harness's native structured-ask tool is available (${toolList}), 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.`;
11
+ }
12
+ export function decisionProtocolInstruction(subject, optionsClause, recommendationClause, toolList = STRUCTURED_ASK_TOOL_LIST_GENERIC) {
13
+ return `For ${subject}: use the Decision Protocol — ${optionsClause}. Do NOT use a numeric Completeness rubric; ${recommendationClause}. ${structuredAskFallbackSentence(toolList)}`;
14
+ }
15
+ export function structuredAskSingleChoiceInstruction(subject, choicesClause, toolList = STRUCTURED_ASK_TOOL_LIST_GENERIC) {
16
+ return `For ${subject}: use the native structured-ask tool (${toolList}) only if runtime schema is confirmed; otherwise collect ${choicesClause} with a plain-text single-choice prompt.`;
17
+ }
18
+ export function ideateStructuredAskToolsWithFallback() {
19
+ return `${STRUCTURED_ASK_TOOL_LIST_IDEATE}; fall back to a plain-text lettered list when the tool is hidden or errors`;
20
+ }
@@ -1,2 +1 @@
1
- export declare function diffCommandContract(): string;
2
- export declare function diffCommandSkillMarkdown(): string;
1
+ export declare function diffSubcommandMarkdown(): string;
@@ -1,126 +1,40 @@
1
1
  import { RUNTIME_ROOT } from "../constants.js";
2
- const DIFF_SKILL_FOLDER = "flow-diff";
3
- const DIFF_SKILL_NAME = "flow-diff";
4
2
  function flowStatePath() {
5
3
  return `${RUNTIME_ROOT}/state/flow-state.json`;
6
4
  }
7
- function snapshotPath() {
8
- return `${RUNTIME_ROOT}/state/flow-state.snapshot.json`;
9
- }
10
5
  function delegationLogPath() {
11
6
  return `${RUNTIME_ROOT}/state/delegation-log.json`;
12
7
  }
13
8
  function retroArtifactPath() {
14
9
  return `${RUNTIME_ROOT}/artifacts/09-retro.md`;
15
10
  }
16
- export function diffCommandContract() {
11
+ export function diffSubcommandMarkdown() {
17
12
  return `# /cc-view diff
18
13
 
19
- ## Purpose
20
-
21
- Show a visual before/after diff map for flow-state progression. Covers the core
22
- stage/gate transitions plus:
23
-
24
- - ship **closeout substate** transitions (\`retro_review\` → \`compound_review\` → \`ready_to_archive\`),
25
- - delegation **fulfillmentMode** transitions per mandatory agent,
26
- - appearance or removal of the retro artifact \`09-retro.md\`.
27
-
28
- ## HARD-GATE
29
-
30
- - Compare against \`${snapshotPath()}\` first; do not overwrite baseline before rendering.
31
- - If no snapshot exists, initialize baseline and report "baseline created" explicitly.
32
-
33
- ## Algorithm
34
-
35
- 1. Read current state from \`${flowStatePath()}\` (including \`closeout\`).
36
- 2. Read current delegation log from \`${delegationLogPath()}\` (if missing treat as empty).
37
- 3. Read baseline from \`${snapshotPath()}\` (if missing -> create baseline from
38
- current state **plus** a copy of the current delegation log; report
39
- \`flow diff baseline created\` and stop).
40
- 4. Compute deltas:
41
- - stage transition (\`from -> to\`),
42
- - completed stage additions/removals,
43
- - skipped stage additions/removals,
44
- - stale stage additions/removals,
45
- - current-stage gate \`passed\` and \`blocked\` changes,
46
- - \`closeout.shipSubstate\` transition (\`from -> to\`),
47
- - \`closeout.retroDraftedAt\` / \`retroAcceptedAt\` / \`retroSkipped\` flips,
48
- - \`closeout.compoundPromoted\` / \`compoundSkipped\` flips,
49
- - per-agent \`fulfillmentMode\` transitions from the baseline delegation log,
50
- - appearance (\`+\`) or disappearance (\`-\`) of \`${retroArtifactPath()}\`.
51
- 5. Render a compact diff map (added \`+\`, removed \`-\`, changed \`->\`).
52
- 6. Persist current state back to \`${snapshotPath()}\` as new baseline with
53
- \`capturedAt\` and an embedded \`delegations\` projection
54
- (\`{ agent, status, fulfillmentMode }[]\`) so fulfillmentMode transitions are
55
- computable on the next run.
56
-
57
- ## Diff Map Format
58
-
59
- \`\`\`
60
- cclaw flow diff
61
- stage: design -> spec
62
- completed: +design
63
- stale: -design
64
- gates(spec): +spec_contract_complete -spec_open_questions_closed
65
- blocked(spec): +spec_trace_matrix_missing
66
- closeout: idle -> retro_review
67
- retro: +drafted (09-retro.md appeared)
68
- delegations:
69
- - reviewer: scheduled -> completed (mode=generic-dispatch)
70
- - test-author: mode=? -> role-switch (evidenceRefs=2)
71
- \`\`\`
72
-
73
- - The \`closeout:\` line is omitted when \`shipSubstate\` is unchanged.
74
- - The \`delegations:\` block is omitted when no agent changed status or mode.
75
- - The \`retro:\` line is emitted only on artifact appearance/removal or on a
76
- \`retroAcceptedAt\` / \`retroSkipped\` flip.
77
-
78
- ## Primary skill
79
-
80
- **${RUNTIME_ROOT}/skills/${DIFF_SKILL_FOLDER}/SKILL.md**
81
- `;
82
- }
83
- export function diffCommandSkillMarkdown() {
84
- return `---
85
- name: ${DIFF_SKILL_NAME}
86
- description: "Compare current flow-state against saved snapshot and render gate/stage/closeout/delegation deltas."
87
- ---
88
-
89
- # /cc-view diff
90
-
91
14
  ## HARD-GATE
92
15
 
93
- Never lose baseline visibility: render deltas before writing a new snapshot.
16
+ Never mutate state from \`/cc-view diff\`. It is a read-only inspection command.
94
17
 
95
18
  ## Protocol
96
19
 
97
20
  1. Read \`${flowStatePath()}\`.
98
21
  2. Read \`${delegationLogPath()}\` (missing → treat as empty list).
99
- 3. Read \`${snapshotPath()}\`.
100
- 4. If snapshot missing:
101
- - write baseline snapshot from current state **plus** a
102
- \`delegations\` projection (\`{ agent, status, fulfillmentMode }[]\`),
103
- - print \`flow diff baseline created\`,
104
- - stop.
105
- 5. Build deltas for:
22
+ 3. Inspect git diff for \`${flowStatePath()}\`, \`${delegationLogPath()}\`, and \`${retroArtifactPath()}\`.
23
+ 4. Build deltas for:
106
24
  - stage, completed/skipped/stale sets,
107
25
  - current-stage gate arrays (\`passed\`, \`blocked\`),
108
26
  - \`closeout.shipSubstate\` transitions (\`from -> to\`),
109
27
  - \`closeout.retroDraftedAt\` / \`retroAcceptedAt\` / \`retroSkipped\` flips,
110
28
  - \`closeout.compoundPromoted\` / \`compoundSkipped\` / \`compoundCompletedAt\` flips,
111
- - per-agent \`fulfillmentMode\` transitions by matching baseline delegations
112
- against current delegations on \`agent\` + latest entry,
29
+ - per-agent \`fulfillmentMode\` changes visible in delegation diffs,
113
30
  - appearance or removal of \`${retroArtifactPath()}\` on disk.
31
+ 5. If git has no baseline for these files, print \`baseline: unavailable (read-only mode)\`.
114
32
  6. Print a compact diff map with explicit \`+\`, \`-\`, and \`->\` markers.
115
- 7. Write updated snapshot with:
116
- - \`capturedAt\` (ISO),
117
- - \`state\` (full current flow-state object),
118
- - \`delegations\` projection from the current log.
119
33
 
120
34
  ## Validation
121
35
 
122
- - Diff output must be deterministic for identical states ("no changes").
123
- - Snapshot file stays valid JSON after every run.
36
+ - Diff output must be deterministic for identical states ("no visible changes").
37
+ - The command must not create or update any \`.cclaw/state/*.snapshot*\` file.
124
38
  - Do not suppress removed values; removals are first-class evidence.
125
39
  - Closeout diff lines must use the same \`shipSubstate\` vocabulary as the
126
40
  state machine (\`idle\` / \`retro_review\` / \`compound_review\` /
@@ -1,18 +1,12 @@
1
1
  import type { FlowStage } from "../types.js";
2
2
  export declare function stageGoodBadExamples(stage: FlowStage): string;
3
- export declare const STAGE_EXAMPLES_REFERENCE_DIR = "references/stages";
4
- export declare function stageExamplesReferencePath(stage: FlowStage): string;
5
3
  /**
6
- * Returns the full example artifact body as a standalone reference markdown
7
- * file. Materialized under .cclaw/references/stages/<stage>-examples.md so
8
- * the always-rendered skill body can link instead of inlining.
4
+ * Returns the full example artifact body for tests and internal quality checks.
5
+ * Generated user projects keep only short inline shape cues.
9
6
  */
10
- export declare function stageExamplesReferenceMarkdown(stage: FlowStage): string | null;
7
+ export declare function stageFullArtifactExampleMarkdown(stage: FlowStage): string | null;
11
8
  /**
12
- * Returns the short inline pointer rendered directly inside the stage skill.
13
- * Replaces the previous always-inline ~50-100 line fenced block and
14
- * delivers true progressive disclosure: the full example lives in a
15
- * reference file loaded on demand.
9
+ * Returns short inline shape cues rendered directly inside the stage skill.
16
10
  */
17
11
  export declare function stageExamples(stage: FlowStage): string;
18
12
  export type ExampleDomain = "web" | "cli" | "library" | "data-pipeline";
@@ -393,16 +393,16 @@ Execution rule: complete and verify each batch before starting the next batch.
393
393
  | R-2 | Important | performance | \`feedStore.merge()\` does full-array scan on every SSE event; O(n) per event where n is feed length. | open |
394
394
  | R-3 | Suggestion | architecture | SSE reconnect logic duplicated across \`useNotifications\` and \`usePresence\`; extract shared hook. | open |
395
395
 
396
- ## Review Army Contract
396
+ ## Review Findings Contract
397
397
 
398
398
  - See \`07-review-army.json\`
399
399
  - Reconciliation summary: 1 duplicate collapsed (R-1 reported by reviewer and security-reviewer), 0 conflicts
400
400
 
401
- ## Review Readiness Dashboard
401
+ ## Review Readiness Snapshot
402
402
 
403
403
  - Layer 1 complete: yes (3/3 criteria)
404
404
  - Layer 2 complete: yes (5 sections reviewed)
405
- - Review army schema valid: yes
405
+ - Review findings schema valid: yes
406
406
  - Open critical blockers: 1 (R-1)
407
407
  - Ship recommendation: BLOCKED until R-1 resolved
408
408
 
@@ -613,16 +613,11 @@ export function stageGoodBadExamples(stage) {
613
613
  });
614
614
  return blocks.join("\n");
615
615
  }
616
- export const STAGE_EXAMPLES_REFERENCE_DIR = "references/stages";
617
- export function stageExamplesReferencePath(stage) {
618
- return `.cclaw/${STAGE_EXAMPLES_REFERENCE_DIR}/${stage}-examples.md`;
619
- }
620
616
  /**
621
- * Returns the full example artifact body as a standalone reference markdown
622
- * file. Materialized under .cclaw/references/stages/<stage>-examples.md so
623
- * the always-rendered skill body can link instead of inlining.
617
+ * Returns the full example artifact body for tests and internal quality checks.
618
+ * Generated user projects keep only short inline shape cues.
624
619
  */
625
- export function stageExamplesReferenceMarkdown(stage) {
620
+ export function stageFullArtifactExampleMarkdown(stage) {
626
621
  const examples = STAGE_EXAMPLES[stage];
627
622
  if (!examples)
628
623
  return null;
@@ -630,12 +625,12 @@ export function stageExamplesReferenceMarkdown(stage) {
630
625
  `---`,
631
626
  `stage: ${stage}`,
632
627
  `name: ${stage}-stage-examples`,
633
- `description: "Full sample artifact for the ${stage} stage. Loaded only when an agent explicitly needs a complete example; the stage skill links here rather than inlining."`,
628
+ `description: "Full sample artifact for the ${stage} stage."`,
634
629
  `---`,
635
630
  "",
636
631
  `# ${stage} stage — full artifact sample`,
637
632
  "",
638
- `This file is linked from \`.cclaw/skills/<${stage}-stage>/SKILL.md\` under **Examples → See also**. The sample uses H2 headings that mirror the artifact a cclaw session must produce, so the markdown is wrapped in a fence to avoid collapsing into the outline.`,
633
+ `The sample uses H2 headings that mirror the artifact a cclaw session must produce, so the markdown is wrapped in a fence to avoid collapsing into the outline.`,
639
634
  "",
640
635
  "```markdown",
641
636
  examples,
@@ -644,10 +639,7 @@ export function stageExamplesReferenceMarkdown(stage) {
644
639
  ].join("\n");
645
640
  }
646
641
  /**
647
- * Returns the short inline pointer rendered directly inside the stage skill.
648
- * Replaces the previous always-inline ~50-100 line fenced block and
649
- * delivers true progressive disclosure: the full example lives in a
650
- * reference file loaded on demand.
642
+ * Returns short inline shape cues rendered directly inside the stage skill.
651
643
  */
652
644
  export function stageExamples(stage) {
653
645
  const examples = STAGE_EXAMPLES[stage];
@@ -656,9 +648,7 @@ export function stageExamples(stage) {
656
648
  return [
657
649
  "## Examples",
658
650
  "",
659
- `Full artifact sample for this stage lives at \`${stageExamplesReferencePath(stage)}\`. Open it when you need a complete reference; do NOT paste the example into the artifact verbatim it is a shape guide, not a template.`,
660
- "",
661
- "Summary of what the reference covers:",
651
+ "Shape cues to follow; do not paste these headings verbatim unless they match the work:",
662
652
  ...exampleSummaryBullets(stage),
663
653
  ""
664
654
  ].join("\n");
@@ -14,8 +14,8 @@ const OPENCODE_SEMANTIC_COVERAGE = {
14
14
  pre_tool_prompt_guard: "plugin tool.execute.before -> prompt-guard",
15
15
  pre_tool_workflow_guard: "plugin tool.execute.before -> workflow-guard",
16
16
  post_tool_context_monitor: "plugin tool.execute.after -> context-monitor",
17
- stop_checkpoint: "plugin session.idle -> stop-checkpoint",
18
- precompact_digest: "plugin session.compacted -> pre-compact"
17
+ stop_handoff: "plugin session.idle -> stop-handoff",
18
+ precompact_compat: "plugin session.compacted -> pre-compact"
19
19
  };
20
20
  /**
21
21
  * Public semantic coverage map derived from `HOOK_MANIFEST` for
@@ -45,8 +45,11 @@
45
45
  * - `countArchivedRunsInline` counts immediate subdirectories of
46
46
  * `<root>/.cclaw/runs/` so both the hook and the CLI see the same
47
47
  * `archivedRunsCount` for the small-project relaxation.
48
+ * - `formatCompoundReadinessLineInline` mirrors the one-line summary shape
49
+ * used by `src/internal/compound-readiness.ts::formatCompoundReadinessLine`
50
+ * so session-start and internal CLI command stay wording-compatible.
48
51
  */
49
- export declare const HOOK_INLINE_SHARED_HELPERS = "\nfunction normalizeCompoundLastUpdatedAt(date) {\n return date.toISOString().replace(/\\.\\d{3}Z$/u, \"Z\");\n}\n\n// Count archived runs as sub-directories under `.cclaw/runs/`. Missing\n// dir returns 0; unexpected errors return undefined so the caller can\n// skip the small-project relaxation rather than guess.\nasync function countArchivedRunsInline(root) {\n const dir = path.join(root, RUNTIME_ROOT, \"runs\");\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n return entries.filter((entry) => entry.isDirectory()).length;\n } catch (error) {\n const code = error && typeof error === \"object\" && \"code\" in error ? error.code : null;\n if (code === \"ENOENT\") return 0;\n return undefined;\n }\n}\n";
52
+ export declare const HOOK_INLINE_SHARED_HELPERS = "\nfunction normalizeCompoundLastUpdatedAt(date) {\n return date.toISOString().replace(/\\.\\d{3}Z$/u, \"Z\");\n}\n\n// Count archived runs as sub-directories under `.cclaw/runs/`. Missing\n// dir returns 0; unexpected errors return undefined so the caller can\n// skip the small-project relaxation rather than guess.\nasync function countArchivedRunsInline(root) {\n const dir = path.join(root, RUNTIME_ROOT, \"runs\");\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n return entries.filter((entry) => entry.isDirectory()).length;\n } catch (error) {\n const code = error && typeof error === \"object\" && \"code\" in error ? error.code : null;\n if (code === \"ENOENT\") return 0;\n return undefined;\n }\n}\n\nfunction formatCompoundReadinessLineInline(readiness) {\n if (!readiness || typeof readiness !== \"object\") {\n return \"\";\n }\n const ready = Array.isArray(readiness.ready) ? readiness.ready : [];\n const readyCount =\n typeof readiness.readyCount === \"number\" && Number.isFinite(readiness.readyCount)\n ? Math.trunc(readiness.readyCount)\n : ready.length;\n const clusterCount =\n typeof readiness.clusterCount === \"number\" && Number.isFinite(readiness.clusterCount)\n ? Math.trunc(readiness.clusterCount)\n : 0;\n const threshold =\n typeof readiness.threshold === \"number\" && Number.isFinite(readiness.threshold)\n ? Math.trunc(readiness.threshold)\n : COMPOUND_RECURRENCE_THRESHOLD;\n if (readyCount === 0) {\n return \"Compound readiness: no candidates (clusters=\" +\n String(clusterCount) + \", threshold=\" + String(threshold) + \")\";\n }\n const critical = ready.filter(\n (entry) => entry && typeof entry === \"object\" && entry.severity === \"critical\"\n ).length;\n const criticalSuffix = critical > 0 ? \" (critical=\" + String(critical) + \")\" : \"\";\n return \"Compound readiness: clusters=\" + String(clusterCount) +\n \", ready=\" + String(readyCount) + criticalSuffix;\n}\n";
50
53
  /**
51
54
  * Inline mirror of `src/knowledge-store.ts::computeCompoundReadiness`.
52
55
  *
@@ -67,7 +70,7 @@ export declare const HOOK_INLINE_SHARED_HELPERS = "\nfunction normalizeCompoundL
67
70
  * `SMALL_PROJECT_RECURRENCE_THRESHOLD`, `COMPOUND_RECURRENCE_THRESHOLD`,
68
71
  * and `HOOK_INLINE_SHARED_HELPERS` being in the same runtime scope.
69
72
  */
70
- export declare const COMPOUND_READINESS_INLINE_SOURCE = "\nasync function computeCompoundReadinessInline(root, options) {\n const filePath = path.join(root, RUNTIME_ROOT, \"knowledge.jsonl\");\n // Caller may supply pre-read raw to avoid double-reading knowledge.jsonl.\n const raw = typeof (options && options.prereadRaw) === \"string\"\n ? options.prereadRaw\n : await readTextFile(filePath, \"\");\n const baseThresholdRaw = options && options.threshold;\n const baseThreshold = Number.isInteger(baseThresholdRaw) && baseThresholdRaw >= 1\n ? baseThresholdRaw\n : COMPOUND_RECURRENCE_THRESHOLD;\n const archivedRunsCount =\n typeof (options && options.archivedRunsCount) === \"number\" &&\n Number.isFinite(options.archivedRunsCount) &&\n options.archivedRunsCount >= 0\n ? Math.floor(options.archivedRunsCount)\n : undefined;\n const smallProjectRelaxationApplied =\n archivedRunsCount !== undefined &&\n archivedRunsCount < SMALL_PROJECT_ARCHIVE_RUNS_THRESHOLD &&\n baseThreshold > SMALL_PROJECT_RECURRENCE_THRESHOLD;\n const threshold = smallProjectRelaxationApplied\n ? SMALL_PROJECT_RECURRENCE_THRESHOLD\n : baseThreshold;\n const maxReady = Number.isInteger(options && options.maxReady) && options.maxReady >= 1\n ? options.maxReady\n : 10;\n const normalize = (value) => String(value == null ? \"\" : value).trim().replace(/\\s+/gu, \" \").toLowerCase();\n const severityWeight = (sev) => {\n if (sev === \"critical\") return 3;\n if (sev === \"important\") return 2;\n if (sev === \"suggestion\") return 1;\n return 0;\n };\n const buckets = new Map();\n for (const rawLine of raw.split(/\\r?\\n/gu)) {\n const line = rawLine.trim();\n if (line.length === 0) continue;\n let row;\n try { row = JSON.parse(line); } catch { continue; }\n if (!row || typeof row !== \"object\" || Array.isArray(row)) continue;\n if (row.maturity === \"lifted-to-enforcement\") continue;\n const type = typeof row.type === \"string\" ? row.type : \"\";\n const trigger = typeof row.trigger === \"string\" ? row.trigger : \"\";\n const action = typeof row.action === \"string\" ? row.action : \"\";\n if (type.length === 0 || trigger.length === 0 || action.length === 0) continue;\n const key = type + \"||\" + normalize(trigger) + \"||\" + normalize(action);\n const frequency = Number.isInteger(row.frequency) && row.frequency > 0 ? Math.floor(row.frequency) : 1;\n const lastSeen = typeof row.last_seen_ts === \"string\" ? row.last_seen_ts : \"\";\n let bucket = buckets.get(key);\n if (!bucket) {\n bucket = {\n trigger,\n action,\n recurrence: frequency,\n entryCount: 1,\n severity: typeof row.severity === \"string\" ? row.severity : undefined,\n lastSeenTs: lastSeen,\n types: new Set([type]),\n maturity: new Set([typeof row.maturity === \"string\" ? row.maturity : \"raw\"])\n };\n buckets.set(key, bucket);\n continue;\n }\n bucket.recurrence += frequency;\n bucket.entryCount += 1;\n bucket.types.add(type);\n bucket.maturity.add(typeof row.maturity === \"string\" ? row.maturity : \"raw\");\n if (row.severity === \"critical\") {\n bucket.severity = \"critical\";\n } else if (row.severity === \"important\" && bucket.severity !== \"critical\") {\n bucket.severity = \"important\";\n }\n if (lastSeen && Date.parse(lastSeen) > Date.parse(bucket.lastSeenTs || \"0\")) {\n bucket.lastSeenTs = lastSeen;\n }\n }\n const ready = [];\n for (const bucket of buckets.values()) {\n const criticalOverride = bucket.severity === \"critical\";\n const meetsRecurrence = bucket.recurrence >= threshold;\n if (!criticalOverride && !meetsRecurrence) continue;\n ready.push({\n trigger: bucket.trigger,\n action: bucket.action,\n recurrence: bucket.recurrence,\n entryCount: bucket.entryCount,\n qualification: criticalOverride && !meetsRecurrence ? \"critical_override\" : \"recurrence\",\n ...(bucket.severity ? { severity: bucket.severity } : {}),\n lastSeenTs: bucket.lastSeenTs,\n types: Array.from(bucket.types).sort(),\n maturity: Array.from(bucket.maturity).sort()\n });\n }\n ready.sort((a, b) => {\n const sevDiff = severityWeight(b.severity) - severityWeight(a.severity);\n if (sevDiff !== 0) return sevDiff;\n if (b.recurrence !== a.recurrence) return b.recurrence - a.recurrence;\n const recencyDiff = Date.parse(b.lastSeenTs || \"0\") - Date.parse(a.lastSeenTs || \"0\");\n if (!Number.isNaN(recencyDiff) && recencyDiff !== 0) return recencyDiff;\n return String(a.trigger).localeCompare(String(b.trigger));\n });\n return {\n schemaVersion: 2,\n threshold,\n baseThreshold,\n ...(archivedRunsCount !== undefined ? { archivedRunsCount } : {}),\n smallProjectRelaxationApplied,\n clusterCount: buckets.size,\n readyCount: ready.length,\n ready: ready.slice(0, maxReady),\n lastUpdatedAt: normalizeCompoundLastUpdatedAt(new Date())\n };\n}\n";
73
+ export declare const COMPOUND_READINESS_INLINE_SOURCE = "\nasync function computeCompoundReadinessInline(root, options) {\n const filePath = path.join(root, RUNTIME_ROOT, \"knowledge.jsonl\");\n // Caller may supply pre-read raw to avoid double-reading knowledge.jsonl.\n const raw = typeof (options && options.prereadRaw) === \"string\"\n ? options.prereadRaw\n : await readTextFile(filePath, \"\");\n const baseThresholdRaw = options && options.threshold;\n const baseThreshold = Number.isInteger(baseThresholdRaw) && baseThresholdRaw >= 1\n ? baseThresholdRaw\n : COMPOUND_RECURRENCE_THRESHOLD;\n const archivedRunsCount =\n typeof (options && options.archivedRunsCount) === \"number\" &&\n Number.isFinite(options.archivedRunsCount) &&\n options.archivedRunsCount >= 0\n ? Math.floor(options.archivedRunsCount)\n : undefined;\n const smallProjectRelaxationApplied =\n archivedRunsCount !== undefined &&\n archivedRunsCount < SMALL_PROJECT_ARCHIVE_RUNS_THRESHOLD &&\n baseThreshold > SMALL_PROJECT_RECURRENCE_THRESHOLD;\n const threshold = smallProjectRelaxationApplied\n ? SMALL_PROJECT_RECURRENCE_THRESHOLD\n : baseThreshold;\n const maxReady = Number.isInteger(options && options.maxReady) && options.maxReady >= 1\n ? options.maxReady\n : 10;\n const normalize = (value) => String(value == null ? \"\" : value).trim().replace(/\\s+/gu, \" \").toLowerCase();\n const severityWeight = (sev) => {\n if (sev === \"critical\") return 3;\n if (sev === \"important\") return 2;\n if (sev === \"suggestion\") return 1;\n return 0;\n };\n const buckets = new Map();\n for (const rawLine of raw.split(/\\r?\\n/gu)) {\n const line = rawLine.trim();\n if (line.length === 0) continue;\n let row;\n try { row = JSON.parse(line); } catch { continue; }\n if (!row || typeof row !== \"object\" || Array.isArray(row)) continue;\n if (row.maturity === \"lifted-to-enforcement\" || typeof row.superseded_by === \"string\") continue;\n const type = typeof row.type === \"string\" ? row.type : \"\";\n const trigger = typeof row.trigger === \"string\" ? row.trigger : \"\";\n const action = typeof row.action === \"string\" ? row.action : \"\";\n if (type.length === 0 || trigger.length === 0 || action.length === 0) continue;\n const key = type + \"||\" + normalize(trigger) + \"||\" + normalize(action);\n const frequency = Number.isInteger(row.frequency) && row.frequency > 0 ? Math.floor(row.frequency) : 1;\n const lastSeen = typeof row.last_seen_ts === \"string\" ? row.last_seen_ts : \"\";\n let bucket = buckets.get(key);\n if (!bucket) {\n bucket = {\n trigger,\n action,\n recurrence: frequency,\n entryCount: 1,\n severity: typeof row.severity === \"string\" ? row.severity : undefined,\n lastSeenTs: lastSeen,\n types: new Set([type]),\n maturity: new Set([typeof row.maturity === \"string\" ? row.maturity : \"raw\"])\n };\n buckets.set(key, bucket);\n continue;\n }\n bucket.recurrence += frequency;\n bucket.entryCount += 1;\n bucket.types.add(type);\n bucket.maturity.add(typeof row.maturity === \"string\" ? row.maturity : \"raw\");\n if (row.severity === \"critical\") {\n bucket.severity = \"critical\";\n } else if (row.severity === \"important\" && bucket.severity !== \"critical\") {\n bucket.severity = \"important\";\n }\n if (lastSeen && Date.parse(lastSeen) > Date.parse(bucket.lastSeenTs || \"0\")) {\n bucket.lastSeenTs = lastSeen;\n }\n }\n const ready = [];\n for (const bucket of buckets.values()) {\n const criticalOverride = bucket.severity === \"critical\";\n const meetsRecurrence = bucket.recurrence >= threshold;\n if (!criticalOverride && !meetsRecurrence) continue;\n ready.push({\n trigger: bucket.trigger,\n action: bucket.action,\n recurrence: bucket.recurrence,\n entryCount: bucket.entryCount,\n qualification: criticalOverride && !meetsRecurrence ? \"critical_override\" : \"recurrence\",\n ...(bucket.severity ? { severity: bucket.severity } : {}),\n lastSeenTs: bucket.lastSeenTs,\n types: Array.from(bucket.types).sort(),\n maturity: Array.from(bucket.maturity).sort()\n });\n }\n ready.sort((a, b) => {\n const sevDiff = severityWeight(b.severity) - severityWeight(a.severity);\n if (sevDiff !== 0) return sevDiff;\n if (b.recurrence !== a.recurrence) return b.recurrence - a.recurrence;\n const recencyDiff = Date.parse(b.lastSeenTs || \"0\") - Date.parse(a.lastSeenTs || \"0\");\n if (!Number.isNaN(recencyDiff) && recencyDiff !== 0) return recencyDiff;\n return String(a.trigger).localeCompare(String(b.trigger));\n });\n return {\n schemaVersion: 2,\n threshold,\n baseThreshold,\n ...(archivedRunsCount !== undefined ? { archivedRunsCount } : {}),\n smallProjectRelaxationApplied,\n clusterCount: buckets.size,\n readyCount: ready.length,\n ready: ready.slice(0, maxReady),\n lastUpdatedAt: normalizeCompoundLastUpdatedAt(new Date())\n };\n}\n";
71
74
  /**
72
75
  * Inline mirror of `src/tdd-cycle.ts::computeRalphLoopStatus`.
73
76
  *