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/run-persistence.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { RUNTIME_ROOT } from "./constants.js";
|
|
4
|
-
import { canTransition, createInitialCloseoutState, createInitialFlowState, isFlowTrack, skippedStagesForTrack, SHIP_SUBSTATES } from "./flow-state.js";
|
|
5
|
-
import { ensureFeatureSystem, syncActiveFeatureSnapshot } from "./feature-system.js";
|
|
4
|
+
import { canTransition, createInitialCloseoutState, createInitialFlowState, FLOW_STATE_SCHEMA_VERSION, isFlowTrack, skippedStagesForTrack, SHIP_SUBSTATES } from "./flow-state.js";
|
|
6
5
|
import { ensureDir, exists, withDirectoryLock, writeFileSafe } from "./fs-utils.js";
|
|
7
6
|
import { FLOW_STAGES } from "./types.js";
|
|
8
7
|
export class InvalidStageTransitionError extends Error {
|
|
@@ -283,6 +282,7 @@ function coerceFlowState(parsed) {
|
|
|
283
282
|
? activeRunIdRaw.trim()
|
|
284
283
|
: next.activeRunId;
|
|
285
284
|
return {
|
|
285
|
+
schemaVersion: FLOW_STATE_SCHEMA_VERSION,
|
|
286
286
|
activeRunId,
|
|
287
287
|
currentStage: isFlowStage(parsed.currentStage) ? parsed.currentStage : next.currentStage,
|
|
288
288
|
completedStages: sanitizeCompletedStages(parsed.completedStages),
|
|
@@ -334,9 +334,7 @@ async function quarantineCorruptState(statePath, cause) {
|
|
|
334
334
|
throw new CorruptFlowStateError(statePath, quarantinedPath, cause);
|
|
335
335
|
}
|
|
336
336
|
export async function readFlowState(projectRoot, options = {}) {
|
|
337
|
-
|
|
338
|
-
await ensureFeatureSystem(projectRoot);
|
|
339
|
-
}
|
|
337
|
+
void options;
|
|
340
338
|
const statePath = flowStatePath(projectRoot);
|
|
341
339
|
if (!(await exists(statePath))) {
|
|
342
340
|
return createInitialFlowState();
|
|
@@ -361,7 +359,6 @@ export async function readFlowState(projectRoot, options = {}) {
|
|
|
361
359
|
return coerceFlowState(parsed);
|
|
362
360
|
}
|
|
363
361
|
export async function writeFlowState(projectRoot, state, options = {}) {
|
|
364
|
-
await ensureFeatureSystem(projectRoot);
|
|
365
362
|
const doWrite = async () => {
|
|
366
363
|
const statePath = flowStatePath(projectRoot);
|
|
367
364
|
if (!options.allowReset && (await exists(statePath))) {
|
|
@@ -389,7 +386,6 @@ export async function writeFlowState(projectRoot, state, options = {}) {
|
|
|
389
386
|
else {
|
|
390
387
|
await withDirectoryLock(flowStateLockPath(projectRoot), doWrite);
|
|
391
388
|
}
|
|
392
|
-
await syncActiveFeatureSnapshot(projectRoot);
|
|
393
389
|
}
|
|
394
390
|
/**
|
|
395
391
|
* Exposed path helper so callers that need to serialize a multi-step
|
|
@@ -400,7 +396,6 @@ export function flowStateLockPathFor(projectRoot) {
|
|
|
400
396
|
return flowStateLockPath(projectRoot);
|
|
401
397
|
}
|
|
402
398
|
export async function ensureRunSystem(projectRoot, _options = {}) {
|
|
403
|
-
await ensureFeatureSystem(projectRoot);
|
|
404
399
|
await ensureDir(runsRoot(projectRoot));
|
|
405
400
|
await ensureDir(activeArtifactsPath(projectRoot));
|
|
406
401
|
const statePath = flowStatePath(projectRoot);
|
|
@@ -408,6 +403,5 @@ export async function ensureRunSystem(projectRoot, _options = {}) {
|
|
|
408
403
|
if (!(await exists(statePath))) {
|
|
409
404
|
await writeFlowState(projectRoot, state, { allowReset: true });
|
|
410
405
|
}
|
|
411
|
-
await syncActiveFeatureSnapshot(projectRoot);
|
|
412
406
|
return state;
|
|
413
407
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cclaw-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.51.0",
|
|
4
4
|
"description": "Installer-first flow toolkit for coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -40,7 +40,6 @@
|
|
|
40
40
|
"node": ">=20.0.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"openai": "^4.104.0",
|
|
44
43
|
"yaml": "^2.8.1"
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { RUNTIME_ROOT } from "../constants.js";
|
|
2
|
-
const ARCHIVE_SKILL_FOLDER = "flow-archive";
|
|
3
|
-
const ARCHIVE_SKILL_NAME = "flow-archive";
|
|
4
|
-
function flowStatePath() {
|
|
5
|
-
return `${RUNTIME_ROOT}/state/flow-state.json`;
|
|
6
|
-
}
|
|
7
|
-
function runsPath() {
|
|
8
|
-
return `${RUNTIME_ROOT}/runs`;
|
|
9
|
-
}
|
|
10
|
-
function activeArtifactsPath() {
|
|
11
|
-
return `${RUNTIME_ROOT}/artifacts`;
|
|
12
|
-
}
|
|
13
|
-
export function archiveCommandContract() {
|
|
14
|
-
return `# /cc-ops archive
|
|
15
|
-
|
|
16
|
-
## Purpose
|
|
17
|
-
|
|
18
|
-
Finalize the active cclaw run: move artifacts to \`${runsPath()}/<archive-id>\`,
|
|
19
|
-
snapshot state, write a manifest, and reset runtime for the next run.
|
|
20
|
-
|
|
21
|
-
Auto-triggered by \`/cc-next\` when \`closeout.shipSubstate === "ready_to_archive"\`.
|
|
22
|
-
Direct invocation from a harness command is supported but rarely needed.
|
|
23
|
-
|
|
24
|
-
## HARD-GATE
|
|
25
|
-
|
|
26
|
-
- Do not archive with \`closeout.shipSubstate !== "ready_to_archive"\`.
|
|
27
|
-
- Do not archive a shipped run when \`retro.completedAt\` is missing and
|
|
28
|
-
\`closeout.retroSkipped !== true\`.
|
|
29
|
-
- Never hand-move files between \`${activeArtifactsPath()}\` and \`${runsPath()}\`.
|
|
30
|
-
Always run the archive runtime command so the snapshot+manifest stay
|
|
31
|
-
atomic.
|
|
32
|
-
|
|
33
|
-
## Inputs
|
|
34
|
-
|
|
35
|
-
\`/cc-ops archive [--name=<slug>]\`
|
|
36
|
-
|
|
37
|
-
(Legacy flags \`--skip-retro --retro-reason=<text>\` still exist for CLI
|
|
38
|
-
invocations; in-harness the skip path is driven by \`closeout.retroSkipped\`
|
|
39
|
-
set during retro.)
|
|
40
|
-
|
|
41
|
-
## Algorithm
|
|
42
|
-
|
|
43
|
-
1. Read \`${flowStatePath()}\`.
|
|
44
|
-
2. Verify \`closeout.shipSubstate === "ready_to_archive"\`. If not, report
|
|
45
|
-
\`closeout not ready (state=<substate>) | run: /cc-next\` and stop.
|
|
46
|
-
3. Build archive command:
|
|
47
|
-
- base: \`npx cclaw archive\`,
|
|
48
|
-
- optional: \`--name=<slug>\`,
|
|
49
|
-
- legacy override: \`--skip-retro --retro-reason=<text>\` (only when user
|
|
50
|
-
explicitly wants the CLI skip path).
|
|
51
|
-
4. Execute the archive command in project root.
|
|
52
|
-
5. On success, flow-state is reset to the initial stage for the default
|
|
53
|
-
track; \`closeout.shipSubstate\` returns to \`"idle"\` on reset.
|
|
54
|
-
6. Surface:
|
|
55
|
-
- archive id/path,
|
|
56
|
-
- reset stage,
|
|
57
|
-
- knowledge curation hint when \`activeEntryCount >= softThreshold\`.
|
|
58
|
-
|
|
59
|
-
## Output format
|
|
60
|
-
|
|
61
|
-
\`\`\`
|
|
62
|
-
cclaw archive
|
|
63
|
-
status: archived
|
|
64
|
-
run: <archive-id>
|
|
65
|
-
path: .cclaw/runs/<archive-id>
|
|
66
|
-
next: /cc <new-idea>
|
|
67
|
-
\`\`\`
|
|
68
|
-
|
|
69
|
-
## Primary skill
|
|
70
|
-
|
|
71
|
-
**${RUNTIME_ROOT}/skills/${ARCHIVE_SKILL_FOLDER}/SKILL.md**
|
|
72
|
-
`;
|
|
73
|
-
}
|
|
74
|
-
export function archiveCommandSkillMarkdown() {
|
|
75
|
-
return `---
|
|
76
|
-
name: ${ARCHIVE_SKILL_NAME}
|
|
77
|
-
description: "Finalize the active cclaw run. Auto-triggered by /cc-next when shipSubstate=ready_to_archive."
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
# /cc-ops archive
|
|
81
|
-
|
|
82
|
-
## HARD-GATE
|
|
83
|
-
|
|
84
|
-
Never simulate archive by hand-editing runtime files. Always execute the
|
|
85
|
-
archive runtime command so state snapshots and manifest generation stay
|
|
86
|
-
atomic. Never bypass the substate check — if retro/compound haven't
|
|
87
|
-
advanced the substate to \`ready_to_archive\`, stop and surface the
|
|
88
|
-
mismatch.
|
|
89
|
-
|
|
90
|
-
## Protocol
|
|
91
|
-
|
|
92
|
-
1. Read \`${flowStatePath()}\`:
|
|
93
|
-
- if \`closeout.shipSubstate !== "ready_to_archive"\`, stop and route
|
|
94
|
-
the user back to \`/cc-next\` (it will resume at the correct step),
|
|
95
|
-
- sanity-check: \`completedStages\` must include \`"ship"\`,
|
|
96
|
-
- sanity-check: \`retro.completedAt\` is set **or**
|
|
97
|
-
\`closeout.retroSkipped === true\` with a reason.
|
|
98
|
-
2. Build shell command:
|
|
99
|
-
- \`npx cclaw archive\`,
|
|
100
|
-
- append \`--name=<slug>\` when provided,
|
|
101
|
-
- append legacy \`--skip-retro --retro-reason=<text>\` only when the user
|
|
102
|
-
explicitly requests the CLI skip path (normally not needed — skip is
|
|
103
|
-
captured in \`closeout\` during retro).
|
|
104
|
-
3. Run command from repo root.
|
|
105
|
-
4. Relay key lines from output:
|
|
106
|
-
- archive destination under \`${runsPath()}\`,
|
|
107
|
-
- flow reset confirmation,
|
|
108
|
-
- knowledge curation recommendation if \`activeEntryCount >= 50\`.
|
|
109
|
-
|
|
110
|
-
## Resume semantics
|
|
111
|
-
|
|
112
|
-
Archive is idempotent on a per-run basis. If a previous session ran
|
|
113
|
-
archive successfully, the active artifacts directory is empty and
|
|
114
|
-
\`closeout.shipSubstate\` is \`"idle"\`; \`/cc-next\` will simply report
|
|
115
|
-
"Flow complete" or prompt for a new \`/cc\` input.
|
|
116
|
-
|
|
117
|
-
## Validation
|
|
118
|
-
|
|
119
|
-
- \`${runsPath()}\` contains a new archive folder for this run.
|
|
120
|
-
- \`${activeArtifactsPath()}\` is reset for the next run.
|
|
121
|
-
- \`${flowStatePath()}\` is valid JSON and points to the initial stage.
|
|
122
|
-
- \`closeout.shipSubstate === "idle"\` after reset.
|
|
123
|
-
`;
|
|
124
|
-
}
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import { RUNTIME_ROOT } from "../constants.js";
|
|
2
|
-
const COMPOUND_SKILL_FOLDER = "flow-compound";
|
|
3
|
-
const COMPOUND_SKILL_NAME = "flow-compound";
|
|
4
|
-
const DEFAULT_RECURRENCE_THRESHOLD = 3;
|
|
5
|
-
const SMALL_PROJECT_ARCHIVE_RUNS_THRESHOLD = 5;
|
|
6
|
-
const SMALL_PROJECT_RECURRENCE_THRESHOLD = 2;
|
|
7
|
-
function resolveRecurrenceThreshold(options) {
|
|
8
|
-
const threshold = options.recurrenceThreshold;
|
|
9
|
-
if (typeof threshold === "number" && Number.isInteger(threshold) && threshold >= 1) {
|
|
10
|
-
return threshold;
|
|
11
|
-
}
|
|
12
|
-
return DEFAULT_RECURRENCE_THRESHOLD;
|
|
13
|
-
}
|
|
14
|
-
export function compoundCommandContract(options = {}) {
|
|
15
|
-
const recurrenceThreshold = resolveRecurrenceThreshold(options);
|
|
16
|
-
return `# /cc-ops compound
|
|
17
|
-
|
|
18
|
-
## Purpose
|
|
19
|
-
|
|
20
|
-
Lift repeated lessons from \`${RUNTIME_ROOT}/knowledge.jsonl\` into durable
|
|
21
|
-
project assets (rules, protocols, skills) so the next run is easier and safer.
|
|
22
|
-
|
|
23
|
-
Auto-triggered by \`/cc-next\` when \`closeout.shipSubstate === "compound_review"\`.
|
|
24
|
-
Direct invocation is supported but rarely needed.
|
|
25
|
-
|
|
26
|
-
## HARD-GATE
|
|
27
|
-
|
|
28
|
-
- Do not mutate rules/skills/protocols without explicit user approval.
|
|
29
|
-
- Every proposal must cite concrete knowledge evidence (line refs or IDs).
|
|
30
|
-
- Keep scope focused: one compound change set per run.
|
|
31
|
-
- Do not block the archive step if no clusters qualify — record an empty
|
|
32
|
-
compound pass and advance.
|
|
33
|
-
|
|
34
|
-
## Inputs
|
|
35
|
-
|
|
36
|
-
\`/cc-ops compound\` (no flags). The structured ask presents candidates;
|
|
37
|
-
the user can approve individual lifts, accept-all, or skip.
|
|
38
|
-
|
|
39
|
-
## Algorithm
|
|
40
|
-
|
|
41
|
-
1. Read \`${RUNTIME_ROOT}/knowledge.jsonl\` (strict JSONL, one entry per line).
|
|
42
|
-
2. Cluster entries by \`trigger\` + \`action\` similarity.
|
|
43
|
-
3. Resolve recurrence policy:
|
|
44
|
-
- base threshold = \`${recurrenceThreshold}\` (from \`config.compound.recurrenceThreshold\`),
|
|
45
|
-
- count archived runs under \`${RUNTIME_ROOT}/runs/\`,
|
|
46
|
-
- if archived run count is < ${SMALL_PROJECT_ARCHIVE_RUNS_THRESHOLD}, use
|
|
47
|
-
effective threshold = \`min(base threshold, ${SMALL_PROJECT_RECURRENCE_THRESHOLD})\` for this pass.
|
|
48
|
-
4. Filter candidates that satisfy at least one trigger:
|
|
49
|
-
- recurrence count >= effective threshold, or
|
|
50
|
-
- any knowledge entry in the cluster has \`severity: "critical"\`
|
|
51
|
-
(critical override, recurrence can be 1).
|
|
52
|
-
5. If **no candidates** exist:
|
|
53
|
-
- set \`closeout.compoundCompletedAt = <ISO>\`,
|
|
54
|
-
- set \`closeout.compoundPromoted = 0\`,
|
|
55
|
-
- set \`closeout.shipSubstate = "ready_to_archive"\`,
|
|
56
|
-
- emit \`compound: no candidates | next: /cc-next\` and stop.
|
|
57
|
-
6. **Drift check** each surviving candidate before presenting it (see
|
|
58
|
-
"Drift check" section in the skill): confirm the lift target file is
|
|
59
|
-
current, spot-check the repo for contradictions, demote stale clusters
|
|
60
|
-
into a new superseding entry instead of a lift.
|
|
61
|
-
7. Otherwise, present **one** structured ask via the harness's native ask
|
|
62
|
-
tool (\`AskUserQuestion\` / \`AskQuestion\` / \`question\` /
|
|
63
|
-
\`request_user_input\`; plain-text lettered list as fallback) summarising
|
|
64
|
-
all candidates at once:
|
|
65
|
-
- \`apply-all\` (default) — apply every listed lift,
|
|
66
|
-
- \`apply-selected\` — prompt per-candidate,
|
|
67
|
-
- \`skip\` — record a skip reason and advance without changes.
|
|
68
|
-
8. Apply approved lifts to the target file(s). Each lift also appends a
|
|
69
|
-
\`type: "compound"\` entry back to \`${RUNTIME_ROOT}/knowledge.jsonl\`
|
|
70
|
-
summarising what was lifted.
|
|
71
|
-
9. Update flow-state:
|
|
72
|
-
- \`closeout.compoundCompletedAt = <ISO>\`,
|
|
73
|
-
- \`closeout.compoundPromoted = <count>\`,
|
|
74
|
-
- \`closeout.compoundSkipped = true\` if user picked skip,
|
|
75
|
-
- \`closeout.shipSubstate = "ready_to_archive"\`.
|
|
76
|
-
10. Emit one-line summary: \`compound: promoted=<N> skipped=<bool> | next: /cc-next\`.
|
|
77
|
-
|
|
78
|
-
## Primary skill
|
|
79
|
-
|
|
80
|
-
**${RUNTIME_ROOT}/skills/${COMPOUND_SKILL_FOLDER}/SKILL.md**
|
|
81
|
-
`;
|
|
82
|
-
}
|
|
83
|
-
export function compoundCommandSkillMarkdown(options = {}) {
|
|
84
|
-
const recurrenceThreshold = resolveRecurrenceThreshold(options);
|
|
85
|
-
return `---
|
|
86
|
-
name: ${COMPOUND_SKILL_NAME}
|
|
87
|
-
description: "Lift repeated learnings into durable rules/protocols/skills. Auto-triggered after retro accept."
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
# /cc-ops compound
|
|
91
|
-
|
|
92
|
-
## Announce at start
|
|
93
|
-
|
|
94
|
-
"Using flow-compound to lift repeated learnings into durable workflow assets."
|
|
95
|
-
|
|
96
|
-
## HARD-GATE
|
|
97
|
-
|
|
98
|
-
No silent codification. Every lift requires explicit user approval. An
|
|
99
|
-
empty pass is allowed and must advance \`closeout.shipSubstate\` to
|
|
100
|
-
\`"ready_to_archive"\`.
|
|
101
|
-
|
|
102
|
-
## Protocol
|
|
103
|
-
|
|
104
|
-
1. Parse \`.cclaw/knowledge.jsonl\` and group repeated lessons by
|
|
105
|
-
trigger+action similarity.
|
|
106
|
-
2. Resolve recurrence policy:
|
|
107
|
-
- base threshold = \`${recurrenceThreshold}\` from \`config.compound.recurrenceThreshold\`,
|
|
108
|
-
- count archived runs under \`.cclaw/runs/\`,
|
|
109
|
-
- if archived run count is < ${SMALL_PROJECT_ARCHIVE_RUNS_THRESHOLD}, use
|
|
110
|
-
effective threshold = \`min(base threshold, ${SMALL_PROJECT_RECURRENCE_THRESHOLD})\` for this pass.
|
|
111
|
-
3. Keep only candidates that meet at least one trigger:
|
|
112
|
-
- recurrence >= effective threshold and actionable lift path, or
|
|
113
|
-
- a cluster entry with \`severity: critical\` (critical override, recurrence can be 1).
|
|
114
|
-
4. If none qualify, record an empty pass:
|
|
115
|
-
- \`closeout.compoundCompletedAt = <ISO>\`,
|
|
116
|
-
- \`closeout.compoundPromoted = 0\`,
|
|
117
|
-
- \`closeout.shipSubstate = "ready_to_archive"\`,
|
|
118
|
-
- announce \`compound: no candidates\` and stop.
|
|
119
|
-
5. **Drift check — run before presenting any candidate.** Knowledge lines
|
|
120
|
-
are append-only, so textual repetition alone does not prove the rule is
|
|
121
|
-
still true. For every cluster that survives the recurrence filter:
|
|
122
|
-
|
|
123
|
-
- **Read the lift target.** Open the rule/protocol/skill file you would
|
|
124
|
-
edit. If the current contents already encode a stronger version of
|
|
125
|
-
the cluster's \`action\`, drop the candidate (nothing to lift).
|
|
126
|
-
- **Grep for contradictions.** Run a quick repo search on the cluster's
|
|
127
|
-
\`trigger\` keywords. If recent code or docs contradict the cluster,
|
|
128
|
-
treat the cluster as stale.
|
|
129
|
-
- **Check age.** Inspect \`last_seen_ts\` across the cluster's lines. If
|
|
130
|
-
every contributing line is older than ~90 days with no fresh
|
|
131
|
-
observation, treat the cluster as stale.
|
|
132
|
-
- **Handle stale clusters correctly.** Do **not** silently skip them.
|
|
133
|
-
Append a new superseding \`type: "lesson"\` line to
|
|
134
|
-
\`.cclaw/knowledge.jsonl\` whose \`trigger\` explicitly references the
|
|
135
|
-
old pattern (e.g. \`"when previous rule about X no longer holds: ..."\`)
|
|
136
|
-
and whose \`action\` documents the replacement or archive reason.
|
|
137
|
-
Then drop the candidate from the lift list.
|
|
138
|
-
- **Cite line IDs.** Every surviving candidate must list the concrete
|
|
139
|
-
knowledge line indices (1-based) that back it, not just a
|
|
140
|
-
summary string. This is what makes the lift auditable.
|
|
141
|
-
- **Include qualification reason.** Mark each candidate as
|
|
142
|
-
\`recurrence\` or \`critical_override\` so reviewers can see why it passed
|
|
143
|
-
the filter.
|
|
144
|
-
- Optionally invoke the \`knowledge-curation\` utility skill's
|
|
145
|
-
stale/duplicate/supersede heuristics if you want a second pass.
|
|
146
|
-
|
|
147
|
-
6. Otherwise, render each candidate as:
|
|
148
|
-
|
|
149
|
-
\`\`\`
|
|
150
|
-
Candidate: <short title>
|
|
151
|
-
Qualification: <recurrence|critical_override>
|
|
152
|
-
Evidence: <knowledge line-ids>
|
|
153
|
-
Freshness: <newest last_seen_ts among evidence lines>
|
|
154
|
-
Lift target: <rule/protocol/skill file>
|
|
155
|
-
Change type: <add/update/remove>
|
|
156
|
-
Expected benefit: <what regressions this prevents>
|
|
157
|
-
\`\`\`
|
|
158
|
-
|
|
159
|
-
7. Present **one** structured question with three options:
|
|
160
|
-
- \`apply-all\` (default) — apply every candidate,
|
|
161
|
-
- \`apply-selected\` — prompt per-candidate approval next,
|
|
162
|
-
- \`skip\` — record a skip reason and advance.
|
|
163
|
-
|
|
164
|
-
8. For approved candidates:
|
|
165
|
-
- edit the target file(s) with the lift,
|
|
166
|
-
- append a \`type: "compound"\` entry to \`.cclaw/knowledge.jsonl\`
|
|
167
|
-
describing what was promoted, including the source line IDs.
|
|
168
|
-
|
|
169
|
-
9. Update flow-state \`closeout\`:
|
|
170
|
-
- \`compoundCompletedAt\`,
|
|
171
|
-
- \`compoundPromoted\` (count),
|
|
172
|
-
- \`compoundSkipped\` (boolean) + \`compoundSkipReason\` when applicable,
|
|
173
|
-
- \`shipSubstate = "ready_to_archive"\`.
|
|
174
|
-
|
|
175
|
-
## Resume semantics
|
|
176
|
-
|
|
177
|
-
A new session with \`shipSubstate === "compound_review"\` re-runs the scan
|
|
178
|
-
and re-asks the structured question. If the user already applied lifts in
|
|
179
|
-
a previous session but the state file was not updated, they should pick
|
|
180
|
-
\`skip\` with reason \`already-applied\` — compound is idempotent from the
|
|
181
|
-
closeout chain's perspective.
|
|
182
|
-
|
|
183
|
-
## Validation
|
|
184
|
-
|
|
185
|
-
- \`closeout.compoundCompletedAt\` is set.
|
|
186
|
-
- \`closeout.shipSubstate === "ready_to_archive"\`.
|
|
187
|
-
- If lifts were applied, the target files show the edit and at least one
|
|
188
|
-
new \`compound\` line exists in \`.cclaw/knowledge.jsonl\`, and the new
|
|
189
|
-
line references the source knowledge line IDs.
|
|
190
|
-
- If drift check demoted any cluster, a new superseding \`lesson\` line
|
|
191
|
-
exists on the same run documenting the replacement.
|
|
192
|
-
`;
|
|
193
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export declare const DEFAULT_CONTEXT_MODE = "default";
|
|
2
|
-
/**
|
|
3
|
-
* Valid context mode identifiers used by the session hooks and the
|
|
4
|
-
* `context-engineering` skill. Mode bodies no longer live as separate
|
|
5
|
-
* `.cclaw/contexts/<mode>.md` files — the guidance was merged into the
|
|
6
|
-
* `context-engineering` skill. This list only exists so `doctor` can
|
|
7
|
-
* validate that `state/context-mode.json#activeMode` references a known
|
|
8
|
-
* mode name.
|
|
9
|
-
*/
|
|
10
|
-
export declare const AVAILABLE_CONTEXT_MODES: readonly ["default", "execution", "review", "incident"];
|
|
11
|
-
/** Legacy alias: kept so existing imports keep typechecking. */
|
|
12
|
-
export declare const CONTEXT_MODES: Record<string, true>;
|
|
13
|
-
export interface ContextModeState {
|
|
14
|
-
activeMode: string;
|
|
15
|
-
updatedAt: string;
|
|
16
|
-
availableModes: string[];
|
|
17
|
-
}
|
|
18
|
-
export declare function createInitialContextModeState(nowIso?: string): ContextModeState;
|
package/dist/content/contexts.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_CONTEXT_MODE = "default";
|
|
2
|
-
/**
|
|
3
|
-
* Valid context mode identifiers used by the session hooks and the
|
|
4
|
-
* `context-engineering` skill. Mode bodies no longer live as separate
|
|
5
|
-
* `.cclaw/contexts/<mode>.md` files — the guidance was merged into the
|
|
6
|
-
* `context-engineering` skill. This list only exists so `doctor` can
|
|
7
|
-
* validate that `state/context-mode.json#activeMode` references a known
|
|
8
|
-
* mode name.
|
|
9
|
-
*/
|
|
10
|
-
export const AVAILABLE_CONTEXT_MODES = [
|
|
11
|
-
"default",
|
|
12
|
-
"execution",
|
|
13
|
-
"review",
|
|
14
|
-
"incident"
|
|
15
|
-
];
|
|
16
|
-
/** Legacy alias: kept so existing imports keep typechecking. */
|
|
17
|
-
export const CONTEXT_MODES = Object.fromEntries(AVAILABLE_CONTEXT_MODES.map((mode) => [mode, true]));
|
|
18
|
-
export function createInitialContextModeState(nowIso = new Date().toISOString()) {
|
|
19
|
-
return {
|
|
20
|
-
activeMode: DEFAULT_CONTEXT_MODE,
|
|
21
|
-
updatedAt: nowIso,
|
|
22
|
-
availableModes: [...AVAILABLE_CONTEXT_MODES]
|
|
23
|
-
};
|
|
24
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { stagePolicyNeedles, stageSchema } from "./stage-schema.js";
|
|
2
|
-
import { stageSkillFolder } from "./skills.js";
|
|
3
|
-
export function stageCommandContract(stage, track = "standard") {
|
|
4
|
-
const schema = stageSchema(stage, track);
|
|
5
|
-
const skillPath = `.cclaw/skills/${stageSkillFolder(stage)}/SKILL.md`;
|
|
6
|
-
const reads = schema.crossStageTrace.readsFrom;
|
|
7
|
-
const readsLine = reads.length > 0 ? reads.join(", ") : "(first stage)";
|
|
8
|
-
const hydrationLines = reads.length > 0
|
|
9
|
-
? reads.map((readPath) => `- \`${readPath}\``).join("\n")
|
|
10
|
-
: "- (first stage — no upstream artifacts)";
|
|
11
|
-
const gateIds = schema.requiredGates
|
|
12
|
-
.map((g) => `\`${g.id}\``)
|
|
13
|
-
.join(", ");
|
|
14
|
-
const writes = schema.crossStageTrace.writesTo;
|
|
15
|
-
const writesLine = writes.map((w) => `\`${w}\``).join(", ");
|
|
16
|
-
const primaryArtifact = `.cclaw/artifacts/${schema.artifactFile}`;
|
|
17
|
-
const writeStepPaths = writes.length > 1
|
|
18
|
-
? writes.map((w) => `\`${w}\``).join(" and ")
|
|
19
|
-
: `\`${primaryArtifact}\``;
|
|
20
|
-
const policyNeedles = stagePolicyNeedles(stage, track);
|
|
21
|
-
return `# /cc-${stage}
|
|
22
|
-
|
|
23
|
-
Load and follow **${skillPath}** — it contains the full checklist, examples, interaction protocol, and verification discipline.
|
|
24
|
-
|
|
25
|
-
## HARD-GATE
|
|
26
|
-
${schema.hardGate}
|
|
27
|
-
|
|
28
|
-
## In / Out
|
|
29
|
-
- **Reads:** ${readsLine}
|
|
30
|
-
- **Writes:** ${writesLine}
|
|
31
|
-
- **Next:** \`/cc-next\` (updates flow-state and loads the next stage)
|
|
32
|
-
|
|
33
|
-
## Context Hydration (mandatory before stage work)
|
|
34
|
-
1. Read \`.cclaw/state/flow-state.json\`.
|
|
35
|
-
2. Resolve active artifact root: \`.cclaw/artifacts/\`.
|
|
36
|
-
3. Load required upstream artifacts for this stage:
|
|
37
|
-
${hydrationLines}
|
|
38
|
-
4. Stream \`.cclaw/knowledge.jsonl\` and apply relevant JSON-line entries (strict schema: type, trigger, action, confidence, domain, stage, origin_stage, origin_feature, frequency, universality, maturity, created, first_seen_ts, last_seen_ts, project; optional: source, severity).
|
|
39
|
-
5. Write stage output to ${writeStepPaths}.
|
|
40
|
-
6. Do NOT copy artifacts into \`.cclaw/runs/\`; archival is handled by \`/cc-ops archive\` (agent-facing wrapper over archive runtime).
|
|
41
|
-
|
|
42
|
-
## Gates
|
|
43
|
-
${gateIds}
|
|
44
|
-
|
|
45
|
-
## Exit
|
|
46
|
-
${schema.exitCriteria.map((v) => `- ${v}`).join("\n")}
|
|
47
|
-
|
|
48
|
-
## Anchors
|
|
49
|
-
${policyNeedles.map((v) => `- ${v}`).join("\n")}
|
|
50
|
-
`;
|
|
51
|
-
}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { RUNTIME_ROOT } from "../constants.js";
|
|
2
|
-
export const DOCTOR_REFERENCE_DIR = `${RUNTIME_ROOT}/references/doctor`;
|
|
3
|
-
export const DOCTOR_REFERENCE_MARKDOWN = {
|
|
4
|
-
"README.md": `# Doctor Reference Index
|
|
5
|
-
|
|
6
|
-
Reference docs for \`cclaw doctor\` checks.
|
|
7
|
-
|
|
8
|
-
## Categories
|
|
9
|
-
|
|
10
|
-
- \`runtime-layout.md\` - runtime directories, generated commands, and skill files
|
|
11
|
-
- \`hooks-and-lifecycle.md\` - hook wiring and harness lifecycle integration
|
|
12
|
-
- \`harness-and-routing.md\` - harness shims, AGENTS/CLAUDE routing blocks, cursor rule
|
|
13
|
-
- \`state-and-gates.md\` - flow-state integrity and gate evidence contracts
|
|
14
|
-
- \`delegation-and-preamble.md\` - mandatory delegations and lightweight announce discipline
|
|
15
|
-
- \`traceability.md\` - spec/plan/tdd trace matrix expectations
|
|
16
|
-
- \`tooling-capabilities.md\` - local runtime prerequisites (node only)
|
|
17
|
-
- \`config-and-policy.md\` - config schema, rules policy, and validation references
|
|
18
|
-
`,
|
|
19
|
-
"runtime-layout.md": `# Runtime Layout
|
|
20
|
-
|
|
21
|
-
## Expected surfaces
|
|
22
|
-
|
|
23
|
-
- \`.cclaw/\` root and generated subdirectories
|
|
24
|
-
- stage command contracts under \`.cclaw/commands/\`
|
|
25
|
-
- stage skills under \`.cclaw/skills/\`
|
|
26
|
-
- utility command contracts (\`start\`, \`next\`, \`learn\`, \`status\`)
|
|
27
|
-
- state files under \`.cclaw/state/\`
|
|
28
|
-
|
|
29
|
-
## Typical fixes
|
|
30
|
-
|
|
31
|
-
1. Run \`cclaw sync\` to re-materialize generated assets.
|
|
32
|
-
2. If runtime is severely drifted, run \`cclaw upgrade\`.
|
|
33
|
-
3. Avoid manual edits under generated runtime paths unless explicitly supported.
|
|
34
|
-
`,
|
|
35
|
-
"hooks-and-lifecycle.md": `# Hooks And Lifecycle
|
|
36
|
-
|
|
37
|
-
## Expected behavior
|
|
38
|
-
|
|
39
|
-
- session start rehydrates flow + knowledge digest
|
|
40
|
-
- pre-tool hooks run prompt/workflow guards
|
|
41
|
-
- post-tool hooks run context monitor
|
|
42
|
-
- stop hooks checkpoint progress
|
|
43
|
-
- OpenCode uses plugin-based lifecycle integration
|
|
44
|
-
|
|
45
|
-
## Typical fixes
|
|
46
|
-
|
|
47
|
-
1. Re-run \`cclaw sync\` after harness config changes.
|
|
48
|
-
2. Ensure harness is enabled in \`.cclaw/config.yaml\`.
|
|
49
|
-
3. Validate hook JSON shape and remove malformed manual edits.
|
|
50
|
-
`,
|
|
51
|
-
"harness-and-routing.md": `# Harness And Routing
|
|
52
|
-
|
|
53
|
-
## Expected behavior
|
|
54
|
-
|
|
55
|
-
- command shims exist for every enabled harness
|
|
56
|
-
- managed routing block is present in \`AGENTS.md\` (and \`CLAUDE.md\` when applicable)
|
|
57
|
-
- cursor rule mirrors workflow activation guidance
|
|
58
|
-
- opencode plugin path is registered in opencode config
|
|
59
|
-
|
|
60
|
-
## Typical fixes
|
|
61
|
-
|
|
62
|
-
1. Confirm \`harnesses\` list in \`.cclaw/config.yaml\`.
|
|
63
|
-
2. Run \`cclaw sync\` to re-generate shims/routing files.
|
|
64
|
-
3. Remove stale harness artifacts for disabled harnesses via \`cclaw sync\`.
|
|
65
|
-
`,
|
|
66
|
-
"state-and-gates.md": `# State And Gates
|
|
67
|
-
|
|
68
|
-
## Expected behavior
|
|
69
|
-
|
|
70
|
-
- \`flow-state.json\` has activeRunId, current stage, and consistent track/skippedStages
|
|
71
|
-
- current-stage gate evidence is internally consistent
|
|
72
|
-
- completed stages only include passed required gates
|
|
73
|
-
|
|
74
|
-
## Typical fixes
|
|
75
|
-
|
|
76
|
-
1. Run \`cclaw doctor --reconcile-gates\` to refresh current-stage gate catalog.
|
|
77
|
-
2. Repair inconsistent stage artifacts, then re-run doctor.
|
|
78
|
-
3. Do not manually mutate gate arrays without matching artifact evidence.
|
|
79
|
-
`,
|
|
80
|
-
"delegation-and-preamble.md": `# Delegation And Preamble
|
|
81
|
-
|
|
82
|
-
## Delegation contract
|
|
83
|
-
|
|
84
|
-
- mandatory delegations for the current stage must be completed or waived
|
|
85
|
-
- waivers should include an explicit reason
|
|
86
|
-
- stale entries from previous runs are ignored by current-run checks
|
|
87
|
-
- delegation entries use span-compatible fields (\`spanId\`, \`startTs\`, \`endTs\`, \`retryCount\`, \`evidenceRefs\`)
|
|
88
|
-
|
|
89
|
-
## Announce discipline contract
|
|
90
|
-
|
|
91
|
-
- no dedicated preamble runtime log is required
|
|
92
|
-
- substantial turns should still start with a concise announce (stage + goal + next action)
|
|
93
|
-
- do not spam repeated announces when intent did not change
|
|
94
|
-
|
|
95
|
-
## Typical fixes
|
|
96
|
-
|
|
97
|
-
1. Append missing delegation records with \`completed\` or \`waived\` status.
|
|
98
|
-
2. Record harness-limitation waivers when native delegation is unavailable.
|
|
99
|
-
3. Keep announces concise and only refresh when plan/risk materially changes.
|
|
100
|
-
`,
|
|
101
|
-
"traceability.md": `# Traceability
|
|
102
|
-
|
|
103
|
-
## Expected behavior
|
|
104
|
-
|
|
105
|
-
- spec criteria map to plan tasks
|
|
106
|
-
- plan tasks map to tdd slices/tests
|
|
107
|
-
- no orphaned criteria/tasks/tests when downstream artifacts exist
|
|
108
|
-
|
|
109
|
-
## Typical fixes
|
|
110
|
-
|
|
111
|
-
1. Add stable IDs to spec/plan/tdd sections.
|
|
112
|
-
2. Ensure mapping tables include every active criterion/task/slice.
|
|
113
|
-
3. Re-run \`cclaw doctor\` after artifact updates.
|
|
114
|
-
`,
|
|
115
|
-
"tooling-capabilities.md": `# Tooling Capabilities
|
|
116
|
-
|
|
117
|
-
## Required
|
|
118
|
-
|
|
119
|
-
- \`node\` (>=20) — the only runtime dependency. All hooks, git-hook relays, and the
|
|
120
|
-
\`cclaw\` CLI itself run on Node.js. No \`bash\`, \`python3\`, or \`jq\` required.
|
|
121
|
-
- \`git\` — needed for worktree and pre-commit/pre-push relays.
|
|
122
|
-
|
|
123
|
-
## Not required (removed)
|
|
124
|
-
|
|
125
|
-
Earlier releases relied on \`bash\` to execute generated shell hooks and on
|
|
126
|
-
\`python3\`/\`jq\` as JSON fallback parsers. Node-only mode removes both: hooks
|
|
127
|
-
dispatch through \`.cclaw/hooks/run-hook.cmd <hook-name>\` (which forwards to
|
|
128
|
-
Node), so these tools
|
|
129
|
-
are no longer part of the supported runtime contract.
|
|
130
|
-
|
|
131
|
-
## Typical fixes
|
|
132
|
-
|
|
133
|
-
1. Install Node.js 20 or newer (matches \`package.json\` \`engines\`) and ensure \`node\` is on \`PATH\`.
|
|
134
|
-
2. Re-run \`cclaw sync\` to regenerate hook configs after upgrading Node.
|
|
135
|
-
`,
|
|
136
|
-
"config-and-policy.md": `# Config And Policy
|
|
137
|
-
|
|
138
|
-
## Expected behavior
|
|
139
|
-
|
|
140
|
-
- \`.cclaw/config.yaml\` parses and uses supported keys/values
|
|
141
|
-
- \`.cclaw/rules/rules.json\` matches generated policy schema
|
|
142
|
-
- policy needles and required sections remain present in generated contracts
|
|
143
|
-
|
|
144
|
-
## Typical fixes
|
|
145
|
-
|
|
146
|
-
1. Repair invalid config values and run \`cclaw sync\`.
|
|
147
|
-
2. Re-generate policy files via \`cclaw sync\` if drift is detected.
|
|
148
|
-
3. Keep generated contracts aligned with stage schemas and policy needles.
|
|
149
|
-
`
|
|
150
|
-
};
|