cclaw-cli 0.49.0 → 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.
- package/README.md +54 -82
- package/dist/artifact-linter.d.ts +4 -0
- package/dist/artifact-linter.js +24 -3
- package/dist/cli.d.ts +1 -19
- package/dist/cli.js +49 -491
- package/dist/constants.d.ts +2 -13
- package/dist/constants.js +1 -43
- package/dist/content/closeout-guidance.d.ts +14 -0
- package/dist/content/closeout-guidance.js +42 -0
- package/dist/content/core-agents.js +51 -9
- package/dist/content/decision-protocol.d.ts +12 -0
- package/dist/content/decision-protocol.js +20 -0
- package/dist/content/diff-command.d.ts +1 -2
- package/dist/content/diff-command.js +8 -94
- package/dist/content/examples.d.ts +4 -10
- package/dist/content/examples.js +10 -20
- package/dist/content/hook-events.js +2 -2
- package/dist/content/hook-inline-snippets.d.ts +5 -2
- package/dist/content/hook-inline-snippets.js +33 -1
- package/dist/content/hook-manifest.d.ts +3 -4
- package/dist/content/hook-manifest.js +11 -12
- package/dist/content/hooks.js +2 -0
- package/dist/content/ideate-command.d.ts +2 -0
- package/dist/content/ideate-command.js +31 -25
- package/dist/content/iron-laws.d.ts +5 -5
- package/dist/content/iron-laws.js +5 -5
- package/dist/content/learnings.d.ts +3 -4
- package/dist/content/learnings.js +24 -50
- package/dist/content/meta-skill.js +31 -21
- package/dist/content/next-command.js +38 -38
- package/dist/content/node-hooks.js +17 -343
- package/dist/content/opencode-plugin.js +2 -100
- package/dist/content/research-playbooks.js +14 -14
- package/dist/content/review-loop.d.ts +2 -0
- package/dist/content/review-loop.js +8 -0
- package/dist/content/session-hooks.js +14 -46
- package/dist/content/skills.d.ts +0 -5
- package/dist/content/skills.js +53 -128
- package/dist/content/stage-common-guidance.d.ts +0 -1
- package/dist/content/stage-common-guidance.js +15 -14
- package/dist/content/stage-schema.d.ts +26 -1
- package/dist/content/stage-schema.js +121 -40
- package/dist/content/stages/_lint-metadata/index.js +9 -15
- package/dist/content/stages/brainstorm.js +22 -43
- package/dist/content/stages/design.js +37 -57
- package/dist/content/stages/plan.js +22 -13
- package/dist/content/stages/review.js +24 -27
- package/dist/content/stages/scope.js +34 -46
- package/dist/content/stages/ship.js +7 -4
- package/dist/content/stages/spec.js +20 -9
- package/dist/content/stages/tdd.js +64 -44
- package/dist/content/start-command.js +10 -12
- package/dist/content/status-command.d.ts +2 -7
- package/dist/content/status-command.js +19 -146
- package/dist/content/subagents.d.ts +0 -5
- package/dist/content/subagents.js +47 -28
- package/dist/content/templates.d.ts +1 -1
- package/dist/content/templates.js +126 -135
- package/dist/content/track-render-context.d.ts +17 -0
- package/dist/content/track-render-context.js +44 -0
- package/dist/content/tree-command.d.ts +1 -2
- package/dist/content/tree-command.js +4 -87
- package/dist/content/utility-skills.d.ts +2 -29
- package/dist/content/utility-skills.js +2 -1534
- package/dist/content/view-command.js +29 -11
- package/dist/delegation.d.ts +1 -1
- package/dist/delegation.js +5 -15
- package/dist/doctor-registry.js +20 -21
- package/dist/doctor.js +88 -344
- package/dist/flow-state.d.ts +3 -0
- package/dist/flow-state.js +2 -0
- package/dist/harness-adapters.d.ts +1 -1
- package/dist/harness-adapters.js +48 -57
- package/dist/install.js +128 -358
- package/dist/internal/advance-stage.js +3 -9
- package/dist/internal/compound-readiness.d.ts +1 -1
- package/dist/internal/compound-readiness.js +1 -1
- package/dist/internal/tdd-loop-status.d.ts +1 -1
- package/dist/internal/tdd-loop-status.js +1 -1
- package/dist/knowledge-store.d.ts +16 -10
- package/dist/knowledge-store.js +51 -15
- package/dist/policy.js +16 -105
- package/dist/run-archive.d.ts +4 -6
- package/dist/run-archive.js +15 -20
- package/dist/run-persistence.d.ts +2 -2
- package/dist/run-persistence.js +3 -9
- package/package.json +1 -2
- package/dist/content/archive-command.d.ts +0 -2
- package/dist/content/archive-command.js +0 -124
- package/dist/content/compound-command.d.ts +0 -5
- package/dist/content/compound-command.js +0 -193
- package/dist/content/contexts.d.ts +0 -18
- package/dist/content/contexts.js +0 -24
- package/dist/content/contracts.d.ts +0 -2
- package/dist/content/contracts.js +0 -51
- package/dist/content/doctor-references.d.ts +0 -2
- package/dist/content/doctor-references.js +0 -150
- package/dist/content/eval-scaffold.d.ts +0 -15
- package/dist/content/eval-scaffold.js +0 -370
- package/dist/content/feature-command.d.ts +0 -2
- package/dist/content/feature-command.js +0 -123
- package/dist/content/flow-map.d.ts +0 -23
- package/dist/content/flow-map.js +0 -134
- package/dist/content/harness-doc.d.ts +0 -2
- package/dist/content/harness-doc.js +0 -202
- package/dist/content/harness-playbooks.d.ts +0 -24
- package/dist/content/harness-playbooks.js +0 -393
- package/dist/content/harness-tool-refs.d.ts +0 -20
- package/dist/content/harness-tool-refs.js +0 -268
- package/dist/content/ops-command.d.ts +0 -2
- package/dist/content/ops-command.js +0 -71
- package/dist/content/protocols.d.ts +0 -7
- package/dist/content/protocols.js +0 -215
- package/dist/content/retro-command.d.ts +0 -2
- package/dist/content/retro-command.js +0 -165
- package/dist/content/rewind-command.d.ts +0 -2
- package/dist/content/rewind-command.js +0 -106
- package/dist/content/tdd-log-command.d.ts +0 -2
- package/dist/content/tdd-log-command.js +0 -85
- package/dist/eval/agents/single-shot.d.ts +0 -27
- package/dist/eval/agents/single-shot.js +0 -79
- package/dist/eval/agents/with-tools.d.ts +0 -44
- package/dist/eval/agents/with-tools.js +0 -261
- package/dist/eval/agents/workflow.d.ts +0 -31
- package/dist/eval/agents/workflow.js +0 -155
- package/dist/eval/baseline.d.ts +0 -38
- package/dist/eval/baseline.js +0 -282
- package/dist/eval/config-loader.d.ts +0 -14
- package/dist/eval/config-loader.js +0 -395
- package/dist/eval/corpus.d.ts +0 -30
- package/dist/eval/corpus.js +0 -330
- package/dist/eval/cost-guard.d.ts +0 -102
- package/dist/eval/cost-guard.js +0 -190
- package/dist/eval/diff.d.ts +0 -64
- package/dist/eval/diff.js +0 -323
- package/dist/eval/llm-client.d.ts +0 -176
- package/dist/eval/llm-client.js +0 -267
- package/dist/eval/mode.d.ts +0 -28
- package/dist/eval/mode.js +0 -61
- package/dist/eval/progress.d.ts +0 -83
- package/dist/eval/progress.js +0 -59
- package/dist/eval/report.d.ts +0 -11
- package/dist/eval/report.js +0 -181
- package/dist/eval/rubric-loader.d.ts +0 -20
- package/dist/eval/rubric-loader.js +0 -143
- package/dist/eval/runner.d.ts +0 -81
- package/dist/eval/runner.js +0 -746
- package/dist/eval/runs.d.ts +0 -41
- package/dist/eval/runs.js +0 -114
- package/dist/eval/sandbox.d.ts +0 -38
- package/dist/eval/sandbox.js +0 -137
- package/dist/eval/tools/glob.d.ts +0 -2
- package/dist/eval/tools/glob.js +0 -163
- package/dist/eval/tools/grep.d.ts +0 -2
- package/dist/eval/tools/grep.js +0 -152
- package/dist/eval/tools/index.d.ts +0 -7
- package/dist/eval/tools/index.js +0 -35
- package/dist/eval/tools/read.d.ts +0 -2
- package/dist/eval/tools/read.js +0 -122
- package/dist/eval/tools/types.d.ts +0 -49
- package/dist/eval/tools/types.js +0 -41
- package/dist/eval/tools/write.d.ts +0 -2
- package/dist/eval/tools/write.js +0 -92
- package/dist/eval/types.d.ts +0 -561
- package/dist/eval/types.js +0 -47
- package/dist/eval/verifiers/judge.d.ts +0 -40
- package/dist/eval/verifiers/judge.js +0 -256
- package/dist/eval/verifiers/rules.d.ts +0 -24
- package/dist/eval/verifiers/rules.js +0 -218
- package/dist/eval/verifiers/structural.d.ts +0 -14
- package/dist/eval/verifiers/structural.js +0 -171
- package/dist/eval/verifiers/traceability.d.ts +0 -23
- package/dist/eval/verifiers/traceability.js +0 -84
- package/dist/eval/verifiers/workflow-consistency.d.ts +0 -21
- package/dist/eval/verifiers/workflow-consistency.js +0 -225
- package/dist/eval/workflow-corpus.d.ts +0 -7
- package/dist/eval/workflow-corpus.js +0 -207
- package/dist/feature-system.d.ts +0 -42
- package/dist/feature-system.js +0 -432
- package/dist/internal/knowledge-digest.d.ts +0 -7
- package/dist/internal/knowledge-digest.js +0 -93
package/dist/constants.d.ts
CHANGED
|
@@ -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
|
-
|
|
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/state", ".cclaw/runs", ".cclaw/rules", ".cclaw/agents", ".cclaw/hooks", ".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,47 +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
61
|
`${RUNTIME_ROOT}/state`,
|
|
78
62
|
`${RUNTIME_ROOT}/runs`,
|
|
79
63
|
`${RUNTIME_ROOT}/rules`,
|
|
80
64
|
`${RUNTIME_ROOT}/agents`,
|
|
81
|
-
`${RUNTIME_ROOT}/hooks
|
|
82
|
-
...EVALS_DIRS
|
|
65
|
+
`${RUNTIME_ROOT}/hooks`
|
|
83
66
|
];
|
|
84
67
|
export const REQUIRED_GITIGNORE_PATTERNS = [
|
|
85
68
|
"# cclaw generated artifacts",
|
|
86
69
|
`${RUNTIME_ROOT}/`,
|
|
87
|
-
"# cclaw evals: user-owned, track in git",
|
|
88
|
-
`!${EVALS_ROOT}/`,
|
|
89
|
-
`!${EVALS_ROOT}/config.yaml`,
|
|
90
|
-
`!${EVALS_ROOT}/corpus/`,
|
|
91
|
-
`!${EVALS_ROOT}/corpus/**`,
|
|
92
|
-
`!${EVALS_ROOT}/rubrics/`,
|
|
93
|
-
`!${EVALS_ROOT}/rubrics/**`,
|
|
94
|
-
`!${EVALS_ROOT}/baselines/`,
|
|
95
|
-
`!${EVALS_ROOT}/baselines/**`,
|
|
96
70
|
".claude/commands/cc-*.md",
|
|
97
71
|
".claude/commands/cc.md",
|
|
98
72
|
".cursor/commands/cc-*.md",
|
|
@@ -130,22 +104,6 @@ export const STAGE_TO_SKILL_FOLDER = {
|
|
|
130
104
|
review: "two-layer-review",
|
|
131
105
|
ship: "shipping-and-handoff"
|
|
132
106
|
};
|
|
133
|
-
export const UTILITY_COMMANDS = [
|
|
134
|
-
"learn",
|
|
135
|
-
"next",
|
|
136
|
-
"ideate",
|
|
137
|
-
"view",
|
|
138
|
-
"status",
|
|
139
|
-
"tree",
|
|
140
|
-
"diff",
|
|
141
|
-
"ops",
|
|
142
|
-
"feature",
|
|
143
|
-
"tdd-log",
|
|
144
|
-
"retro",
|
|
145
|
-
"compound",
|
|
146
|
-
"archive",
|
|
147
|
-
"rewind"
|
|
148
|
-
];
|
|
149
107
|
export const SUBAGENT_SKILL_FOLDERS = [
|
|
150
108
|
"subagent-dev",
|
|
151
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>\`) |
|
|
181
|
-
| Scope / Design / Plan (via \`/cc-next\`) |
|
|
182
|
-
| Spec (via \`/cc-next\`) |
|
|
183
|
-
| TDD (via \`/cc-next\`) |
|
|
184
|
-
| Review (via \`/cc-next\`) |
|
|
185
|
-
| Ship (via \`/cc-next\`) |
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
100
|
-
4.
|
|
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\`
|
|
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
|
-
-
|
|
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
|
|
7
|
-
*
|
|
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
|
|
7
|
+
export declare function stageFullArtifactExampleMarkdown(stage: FlowStage): string | null;
|
|
11
8
|
/**
|
|
12
|
-
* Returns
|
|
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";
|
package/dist/content/examples.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
622
|
-
*
|
|
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
|
|
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.
|
|
628
|
+
`description: "Full sample artifact for the ${stage} stage."`,
|
|
634
629
|
`---`,
|
|
635
630
|
"",
|
|
636
631
|
`# ${stage} stage — full artifact sample`,
|
|
637
632
|
"",
|
|
638
|
-
`
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
18
|
-
|
|
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
|
*
|