cclaw-cli 0.48.35 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 -495
- package/dist/constants.d.ts +2 -13
- package/dist/constants.js +1 -46
- 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 -24
- 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 -1533
- 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 -408
- 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 -520
- 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 -109
- 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 -9
- package/dist/content/contexts.js +0 -65
- 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-archive.js
CHANGED
|
@@ -2,7 +2,6 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { RUNTIME_ROOT } from "./constants.js";
|
|
4
4
|
import { createInitialFlowState } from "./flow-state.js";
|
|
5
|
-
import { readActiveFeature, syncActiveFeatureSnapshot } from "./feature-system.js";
|
|
6
5
|
import { ensureDir, exists, withDirectoryLock, writeFileSafe } from "./fs-utils.js";
|
|
7
6
|
import { readKnowledgeSafely } from "./knowledge-store.js";
|
|
8
7
|
import { evaluateRetroGate } from "./retro-gate.js";
|
|
@@ -90,7 +89,7 @@ function toArchiveDate(date = new Date()) {
|
|
|
90
89
|
const dd = date.getDate().toString().padStart(2, "0");
|
|
91
90
|
return `${yyyy}-${mm}-${dd}`;
|
|
92
91
|
}
|
|
93
|
-
function
|
|
92
|
+
function slugifyRunName(value) {
|
|
94
93
|
const slug = value
|
|
95
94
|
.toLowerCase()
|
|
96
95
|
.trim()
|
|
@@ -98,14 +97,14 @@ function slugifyFeatureName(value) {
|
|
|
98
97
|
.replace(/^-+/u, "")
|
|
99
98
|
.replace(/-+$/u, "");
|
|
100
99
|
if (slug.length === 0) {
|
|
101
|
-
return "
|
|
100
|
+
return "run";
|
|
102
101
|
}
|
|
103
102
|
return slug.slice(0, 64);
|
|
104
103
|
}
|
|
105
|
-
async function
|
|
104
|
+
async function inferRunNameFromArtifacts(projectRoot) {
|
|
106
105
|
const ideaPath = path.join(projectRoot, ACTIVE_ARTIFACTS_REL_PATH, "00-idea.md");
|
|
107
106
|
if (!(await exists(ideaPath))) {
|
|
108
|
-
return "
|
|
107
|
+
return "run";
|
|
109
108
|
}
|
|
110
109
|
try {
|
|
111
110
|
const raw = await fs.readFile(ideaPath, "utf8");
|
|
@@ -114,12 +113,12 @@ async function inferFeatureNameFromArtifacts(projectRoot) {
|
|
|
114
113
|
.map((line) => line.trim())
|
|
115
114
|
.find((line) => line.length > 0);
|
|
116
115
|
if (!firstMeaningful) {
|
|
117
|
-
return "
|
|
116
|
+
return "run";
|
|
118
117
|
}
|
|
119
|
-
return firstMeaningful.replace(/^[-#*\s]+/u, "").trim() || "
|
|
118
|
+
return firstMeaningful.replace(/^[-#*\s]+/u, "").trim() || "run";
|
|
120
119
|
}
|
|
121
120
|
catch {
|
|
122
|
-
return "
|
|
121
|
+
return "run";
|
|
123
122
|
}
|
|
124
123
|
}
|
|
125
124
|
async function uniqueArchiveId(projectRoot, baseId) {
|
|
@@ -159,7 +158,7 @@ export async function listRuns(projectRoot) {
|
|
|
159
158
|
}
|
|
160
159
|
return runs.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
161
160
|
}
|
|
162
|
-
export async function archiveRun(projectRoot,
|
|
161
|
+
export async function archiveRun(projectRoot, runName, options = {}) {
|
|
163
162
|
await ensureRunSystem(projectRoot);
|
|
164
163
|
// Hold BOTH archive.lock and flow-state.lock for the entire archive:
|
|
165
164
|
// the outer archive lock serializes two concurrent archives; the
|
|
@@ -168,15 +167,14 @@ export async function archiveRun(projectRoot, featureName, options = {}) {
|
|
|
168
167
|
// which used to cause lost-update races.
|
|
169
168
|
return withDirectoryLock(archiveLockPath(projectRoot), async () => {
|
|
170
169
|
return withDirectoryLock(flowStateLockPathFor(projectRoot), async () => {
|
|
171
|
-
const activeFeature = await readActiveFeature(projectRoot);
|
|
172
170
|
const artifactsDir = activeArtifactsPath(projectRoot);
|
|
173
171
|
const runsDir = runsRoot(projectRoot);
|
|
174
172
|
await ensureDir(runsDir);
|
|
175
173
|
await ensureDir(artifactsDir);
|
|
176
|
-
const
|
|
177
|
-
?
|
|
178
|
-
: await
|
|
179
|
-
const archiveBaseId = `${toArchiveDate()}-${
|
|
174
|
+
const archiveRunName = (runName?.trim() && runName.trim().length > 0)
|
|
175
|
+
? runName.trim()
|
|
176
|
+
: await inferRunNameFromArtifacts(projectRoot);
|
|
177
|
+
const archiveBaseId = `${toArchiveDate()}-${slugifyRunName(archiveRunName)}`;
|
|
180
178
|
const archiveId = await uniqueArchiveId(projectRoot, archiveBaseId);
|
|
181
179
|
const archivePath = path.join(runsDir, archiveId);
|
|
182
180
|
const archiveArtifactsPath = path.join(archivePath, "artifacts");
|
|
@@ -256,11 +254,10 @@ export async function archiveRun(projectRoot, featureName, options = {}) {
|
|
|
256
254
|
stateReset = true;
|
|
257
255
|
await resetCarryoverStateFiles(projectRoot, resetState.activeRunId);
|
|
258
256
|
const manifest = {
|
|
259
|
-
version:
|
|
257
|
+
version: 2,
|
|
260
258
|
archiveId,
|
|
261
259
|
archivedAt,
|
|
262
|
-
|
|
263
|
-
activeFeature,
|
|
260
|
+
runName: archiveRunName,
|
|
264
261
|
sourceRunId: sourceState.activeRunId,
|
|
265
262
|
sourceCurrentStage: sourceState.currentStage,
|
|
266
263
|
sourceCompletedStages: sourceState.completedStages,
|
|
@@ -271,13 +268,11 @@ export async function archiveRun(projectRoot, featureName, options = {}) {
|
|
|
271
268
|
// Manifest landed — sentinel is no longer needed.
|
|
272
269
|
await fs.unlink(sentinelPath).catch(() => undefined);
|
|
273
270
|
const knowledgeStats = await readKnowledgeStats(projectRoot);
|
|
274
|
-
await syncActiveFeatureSnapshot(projectRoot);
|
|
275
271
|
return {
|
|
276
272
|
archiveId,
|
|
277
273
|
archivePath,
|
|
278
274
|
archivedAt,
|
|
279
|
-
|
|
280
|
-
activeFeature,
|
|
275
|
+
runName: archiveRunName,
|
|
281
276
|
resetState,
|
|
282
277
|
snapshottedStateFiles,
|
|
283
278
|
knowledge: knowledgeStats,
|
|
@@ -21,8 +21,8 @@ export interface WriteFlowStateOptions {
|
|
|
21
21
|
}
|
|
22
22
|
export interface ReadFlowStateOptions {
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
* Reserved compatibility switch from older runtimes. The repair layer was removed,
|
|
25
|
+
* so this flag is now a no-op and only preserved for API stability.
|
|
26
26
|
*/
|
|
27
27
|
repairFeatureSystem?: boolean;
|
|
28
28
|
}
|
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,9 +0,0 @@
|
|
|
1
|
-
export declare const DEFAULT_CONTEXT_MODE = "default";
|
|
2
|
-
export declare const CONTEXT_MODES: Record<string, string>;
|
|
3
|
-
export declare function contextModeFiles(): Record<string, string>;
|
|
4
|
-
export interface ContextModeState {
|
|
5
|
-
activeMode: string;
|
|
6
|
-
updatedAt: string;
|
|
7
|
-
availableModes: string[];
|
|
8
|
-
}
|
|
9
|
-
export declare function createInitialContextModeState(nowIso?: string): ContextModeState;
|
package/dist/content/contexts.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_CONTEXT_MODE = "default";
|
|
2
|
-
export const CONTEXT_MODES = {
|
|
3
|
-
default: `# Context Mode: default
|
|
4
|
-
|
|
5
|
-
Use for most day-to-day feature work.
|
|
6
|
-
|
|
7
|
-
## Focus
|
|
8
|
-
- Follow the active cclaw stage strictly.
|
|
9
|
-
- Keep changes within the current task blast radius.
|
|
10
|
-
- Prefer incremental progress with frequent verification.
|
|
11
|
-
|
|
12
|
-
## Decision posture
|
|
13
|
-
- Escalate only meaningful trade-offs.
|
|
14
|
-
- Ask for user confirmation only at explicit stage gates.
|
|
15
|
-
`,
|
|
16
|
-
execution: `# Context Mode: execution
|
|
17
|
-
|
|
18
|
-
Use when plan/spec are approved and the goal is high-throughput delivery.
|
|
19
|
-
|
|
20
|
-
## Focus
|
|
21
|
-
- Prioritize deterministic implementation flow (RED -> GREEN -> REFACTOR).
|
|
22
|
-
- Minimize conversational overhead; keep updates concise and evidence-first.
|
|
23
|
-
- Batch machine-only checks through subagent dispatch where supported.
|
|
24
|
-
|
|
25
|
-
## Decision posture
|
|
26
|
-
- Avoid reopening settled design debates unless a blocker appears.
|
|
27
|
-
- Stop immediately on failing quality gates or unresolved critical findings.
|
|
28
|
-
`,
|
|
29
|
-
review: `# Context Mode: review
|
|
30
|
-
|
|
31
|
-
Use for deep validation, risk discovery, and merge readiness.
|
|
32
|
-
|
|
33
|
-
## Focus
|
|
34
|
-
- Bias toward finding concrete defects, regressions, and evidence gaps.
|
|
35
|
-
- Cross-check spec, plan, tests, and implementation alignment.
|
|
36
|
-
- Treat unsupported claims as unverified until backed by command output.
|
|
37
|
-
|
|
38
|
-
## Decision posture
|
|
39
|
-
- Classify findings by severity and expected blast radius.
|
|
40
|
-
- Block ship decisions when critical issues remain unresolved.
|
|
41
|
-
`,
|
|
42
|
-
incident: `# Context Mode: incident
|
|
43
|
-
|
|
44
|
-
Use for production failures, emergency regressions, or urgent stabilization.
|
|
45
|
-
|
|
46
|
-
## Focus
|
|
47
|
-
- Reproduce first, then isolate, then fix.
|
|
48
|
-
- Favor smallest safe change with rollback clarity.
|
|
49
|
-
- Preserve timeline and evidence for post-incident learning.
|
|
50
|
-
|
|
51
|
-
## Decision posture
|
|
52
|
-
- Prefer containment over optimization.
|
|
53
|
-
- Require explicit evidence for declaring recovery complete.
|
|
54
|
-
`
|
|
55
|
-
};
|
|
56
|
-
export function contextModeFiles() {
|
|
57
|
-
return { ...CONTEXT_MODES };
|
|
58
|
-
}
|
|
59
|
-
export function createInitialContextModeState(nowIso = new Date().toISOString()) {
|
|
60
|
-
return {
|
|
61
|
-
activeMode: DEFAULT_CONTEXT_MODE,
|
|
62
|
-
updatedAt: nowIso,
|
|
63
|
-
availableModes: Object.keys(CONTEXT_MODES)
|
|
64
|
-
};
|
|
65
|
-
}
|
|
@@ -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
|
-
}
|