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