cclaw-cli 6.10.0 → 6.11.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/dist/artifact-linter/shared.d.ts +7 -4
- package/dist/artifact-linter/shared.js +4 -4
- package/dist/artifact-linter/tdd.d.ts +42 -21
- package/dist/artifact-linter/tdd.js +379 -140
- package/dist/artifact-linter.js +46 -40
- package/dist/content/core-agents.d.ts +14 -0
- package/dist/content/core-agents.js +35 -0
- package/dist/content/examples.js +4 -4
- package/dist/content/hooks.js +68 -3
- package/dist/content/skills.js +1 -1
- package/dist/content/stage-schema.js +0 -3
- package/dist/content/stages/tdd.js +21 -20
- package/dist/content/subagents.js +10 -9
- package/dist/content/templates.d.ts +6 -0
- package/dist/content/templates.js +38 -20
- package/dist/delegation.d.ts +27 -0
- package/dist/delegation.js +13 -1
- package/dist/install.js +9 -0
- package/dist/internal/advance-stage.js +2 -6
- package/package.json +1 -1
- package/dist/tdd-slices.d.ts +0 -90
- package/dist/tdd-slices.js +0 -375
|
@@ -976,10 +976,14 @@ ${renderBehaviorAnchorTemplateLine("tdd")}
|
|
|
976
976
|
- Open questions:
|
|
977
977
|
- Drift from upstream (or \`None\`):
|
|
978
978
|
|
|
979
|
+
<!-- auto-start: slices-index -->
|
|
980
|
+
## Slices Index
|
|
981
|
+
|
|
982
|
+
_Auto-rendered from \`tdd-slices/S-*.md\` once slice-documenter or controller writes per-slice files. Do not edit by hand._
|
|
983
|
+
<!-- auto-end: slices-index -->
|
|
984
|
+
|
|
979
985
|
## Test Discovery
|
|
980
|
-
|
|
981
|
-
|---|---|---|---|
|
|
982
|
-
| S-1 | | | |
|
|
986
|
+
> Overall narrative for how this stage discovered the existing test surface. Per-slice details live in \`tdd-slices/S-<id>.md\`.
|
|
983
987
|
|
|
984
988
|
## System-Wide Impact Check
|
|
985
989
|
| Slice | Callbacks/state/interfaces/contracts affected | Coverage decision |
|
|
@@ -987,20 +991,17 @@ ${renderBehaviorAnchorTemplateLine("tdd")}
|
|
|
987
991
|
| S-1 | | covered/out-of-scope because |
|
|
988
992
|
|
|
989
993
|
## RED Evidence
|
|
990
|
-
|
|
991
|
-
|---|---|---|---|
|
|
992
|
-
| S-1 | | | |
|
|
994
|
+
> From v6.11.0 the per-slice RED rows are auto-satisfied by \`phase=red\` events in \`delegation-events.jsonl\` (controller dispatches \`test-author --slice S-<id> --phase red\`). Legacy hand-filled tables continue to validate as a fallback. Use \`Evidence: <path>\` or \`Evidence: spanId:<id>\` pointers if you prefer a manual reference.
|
|
993
995
|
|
|
994
996
|
## Acceptance & Failure Map
|
|
995
997
|
| Slice | Source ID | AC ID | Expected behavior | RED-link |
|
|
996
998
|
|---|---|---|---|---|
|
|
997
999
|
| S-1 | SRC-1 | AC-1 | | |
|
|
998
1000
|
|
|
999
|
-
> Each slice maps to the active track's source item (plan slice on standard/medium, or the \`Quick Reproduction Contract\` bug slice / spec acceptance item on quick) and to a spec criterion. The RED-link column is satisfied by either a \`spanId:<id>\` from the delegation ledger
|
|
1001
|
+
> Each slice maps to the active track's source item (plan slice on standard/medium, or the \`Quick Reproduction Contract\` bug slice / spec acceptance item on quick) and to a spec criterion. The RED-link column is satisfied by either a \`spanId:<id>\` from the delegation ledger or an \`<artifacts-dir>/<file>\` evidence pointer. From v6.11.0 the column is auto-derivable: a \`phase=red\` event in \`delegation-events.jsonl\` with non-empty evidenceRefs auto-satisfies the row.
|
|
1000
1002
|
|
|
1001
1003
|
## GREEN Evidence
|
|
1002
|
-
-
|
|
1003
|
-
- Full suite result:
|
|
1004
|
+
> From v6.11.0 GREEN rows are auto-satisfied by \`phase=green\` events in \`delegation-events.jsonl\` (controller dispatches \`slice-implementer --slice S-<id> --phase green\`). Legacy hand-filled tables continue to validate as a fallback. Use \`Evidence: <path>\` or \`Evidence: spanId:<id>\` pointers if you prefer a manual reference.
|
|
1004
1005
|
|
|
1005
1006
|
## REFACTOR Notes
|
|
1006
1007
|
- What changed:
|
|
@@ -1017,19 +1018,11 @@ ${renderBehaviorAnchorTemplateLine("tdd")}
|
|
|
1017
1018
|
- Acknowledged: yes — code that landed before its test will be deleted and rewritten from the test.
|
|
1018
1019
|
- Exceptions invoked (or \`- None.\`):
|
|
1019
1020
|
|
|
1020
|
-
|
|
1021
|
-
> Required for every new test in this stage. Each row proves the test was *observed* failing before any production code was written.
|
|
1022
|
-
|
|
1023
|
-
| Slice | Test name | Observed at (ISO ts) | Failure reason snippet | Source command/log |
|
|
1024
|
-
|---|---|---|---|---|
|
|
1025
|
-
| S-1 | | | | |
|
|
1026
|
-
|
|
1021
|
+
<!-- auto-start: tdd-slice-summary -->
|
|
1027
1022
|
## Vertical Slice Cycle
|
|
1028
|
-
> Per slice: RED -> GREEN -> REFACTOR within the same cycle (refactor not deferred). The linter checks structural presence of all three phases.
|
|
1029
1023
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
| S-1 | | | |
|
|
1024
|
+
_Auto-rendered from \`delegation-events.jsonl\` once \`test-author\` and \`slice-implementer\` are dispatched with \`--slice <id> --phase red|green|refactor|refactor-deferred\`. Do not edit by hand._
|
|
1025
|
+
<!-- auto-end: tdd-slice-summary -->
|
|
1033
1026
|
|
|
1034
1027
|
## Assertion Correctness Notes
|
|
1035
1028
|
> For each new test assertion, name a *plausible subtle bug* that would still pass it (mental mutation test). If you cannot, the assertion is too coarse — strengthen it.
|
|
@@ -1623,6 +1616,31 @@ Track-specific skips are allowed only when \`flow-state.track\` + \`skippedStage
|
|
|
1623
1616
|
- Preamble budget: keep role/status announcements brief and avoid repeating
|
|
1624
1617
|
them unless the stage or role changes.
|
|
1625
1618
|
`;
|
|
1619
|
+
/**
|
|
1620
|
+
* v6.11.0 (S2) — per-slice prose file written by `slice-documenter`
|
|
1621
|
+
* (or the controller) to `<artifacts-dir>/tdd-slices/S-<id>.md`. The
|
|
1622
|
+
* main `06-tdd.md` is auto-indexed via `## Slices Index`.
|
|
1623
|
+
*/
|
|
1624
|
+
export function tddSliceFileTemplate(sliceId) {
|
|
1625
|
+
return `# Slice ${sliceId}
|
|
1626
|
+
|
|
1627
|
+
## Plan unit
|
|
1628
|
+
T-...
|
|
1629
|
+
|
|
1630
|
+
## Acceptance criteria
|
|
1631
|
+
AC-...
|
|
1632
|
+
|
|
1633
|
+
## Why this slice
|
|
1634
|
+
|
|
1635
|
+
## What was tested
|
|
1636
|
+
|
|
1637
|
+
## What was implemented
|
|
1638
|
+
|
|
1639
|
+
## REFACTOR notes
|
|
1640
|
+
|
|
1641
|
+
## Learnings
|
|
1642
|
+
`;
|
|
1643
|
+
}
|
|
1626
1644
|
export function buildRulesJson() {
|
|
1627
1645
|
return {
|
|
1628
1646
|
version: 1,
|
package/dist/delegation.d.ts
CHANGED
|
@@ -140,7 +140,34 @@ export type DelegationEntry = {
|
|
|
140
140
|
* `src/content/hooks.ts::delegationRecordScript`.
|
|
141
141
|
*/
|
|
142
142
|
claimedPaths?: string[];
|
|
143
|
+
/**
|
|
144
|
+
* v6.11.0 (D1) — TDD slice identifier, e.g. `"S-1"`. Recorded by the
|
|
145
|
+
* controller when dispatching `test-author` / `slice-implementer` /
|
|
146
|
+
* `slice-documenter` so the artifact linter can auto-derive the
|
|
147
|
+
* Watched-RED Proof + Vertical Slice Cycle tables from
|
|
148
|
+
* `delegation-events.jsonl` instead of requiring agents to maintain
|
|
149
|
+
* the markdown by hand. Optional: legacy and non-TDD rows omit it.
|
|
150
|
+
*
|
|
151
|
+
* keep in sync with the inline copy in
|
|
152
|
+
* `src/content/hooks.ts::delegationRecordScript`.
|
|
153
|
+
*/
|
|
154
|
+
sliceId?: string;
|
|
155
|
+
/**
|
|
156
|
+
* v6.11.0 (D1) — explicit phase tag for TDD slice events. Combined
|
|
157
|
+
* with `sliceId`, the linter validates RED -> GREEN -> REFACTOR
|
|
158
|
+
* monotonicity per slice. `refactor-deferred` requires a rationale
|
|
159
|
+
* either via `--refactor-rationale` (recorded into evidenceRefs[0])
|
|
160
|
+
* or an `evidenceRefs` entry that contains the rationale text.
|
|
161
|
+
* `doc` is reserved for the parallel `slice-documenter` subagent
|
|
162
|
+
* (Phase C). Optional: legacy and non-TDD rows omit it.
|
|
163
|
+
*
|
|
164
|
+
* keep in sync with the inline copy in
|
|
165
|
+
* `src/content/hooks.ts::delegationRecordScript`.
|
|
166
|
+
*/
|
|
167
|
+
phase?: "red" | "green" | "refactor" | "refactor-deferred" | "doc";
|
|
143
168
|
};
|
|
169
|
+
export declare const DELEGATION_PHASES: readonly ["red", "green", "refactor", "refactor-deferred", "doc"];
|
|
170
|
+
export type DelegationPhase = (typeof DELEGATION_PHASES)[number];
|
|
144
171
|
export declare const DELEGATION_LEDGER_SCHEMA_VERSION: 3;
|
|
145
172
|
export type DelegationLedger = {
|
|
146
173
|
runId: string;
|
package/dist/delegation.js
CHANGED
|
@@ -38,6 +38,13 @@ export const DELEGATION_DISPATCH_SURFACE_PATH_PREFIXES = {
|
|
|
38
38
|
"role-switch": [],
|
|
39
39
|
"manual": []
|
|
40
40
|
};
|
|
41
|
+
export const DELEGATION_PHASES = [
|
|
42
|
+
"red",
|
|
43
|
+
"green",
|
|
44
|
+
"refactor",
|
|
45
|
+
"refactor-deferred",
|
|
46
|
+
"doc"
|
|
47
|
+
];
|
|
41
48
|
export const DELEGATION_LEDGER_SCHEMA_VERSION = 3;
|
|
42
49
|
function delegationLogPath(projectRoot) {
|
|
43
50
|
return path.join(projectRoot, RUNTIME_ROOT, "state", "delegation-log.json");
|
|
@@ -226,7 +233,12 @@ function isDelegationEntry(value) {
|
|
|
226
233
|
(o.allowParallel === undefined || typeof o.allowParallel === "boolean") &&
|
|
227
234
|
(o.supersededBy === undefined || typeof o.supersededBy === "string") &&
|
|
228
235
|
(o.claimedPaths === undefined ||
|
|
229
|
-
(Array.isArray(o.claimedPaths) && o.claimedPaths.every((item) => typeof item === "string")))
|
|
236
|
+
(Array.isArray(o.claimedPaths) && o.claimedPaths.every((item) => typeof item === "string"))) &&
|
|
237
|
+
(o.sliceId === undefined ||
|
|
238
|
+
(typeof o.sliceId === "string" && o.sliceId.length > 0)) &&
|
|
239
|
+
(o.phase === undefined ||
|
|
240
|
+
(typeof o.phase === "string" &&
|
|
241
|
+
DELEGATION_PHASES.includes(o.phase))));
|
|
230
242
|
}
|
|
231
243
|
function isDelegationDispatchSurface(value) {
|
|
232
244
|
return typeof value === "string" && DELEGATION_DISPATCH_SURFACES.includes(value);
|
package/dist/install.js
CHANGED
|
@@ -168,6 +168,14 @@ const DEPRECATED_STATE_FILES = [
|
|
|
168
168
|
// now reads cycle phase progression directly from the artifact table.
|
|
169
169
|
"tdd-cycle-log.jsonl"
|
|
170
170
|
];
|
|
171
|
+
// v6.11.0 (R5): files under `<runtime>/artifacts/` that previous releases
|
|
172
|
+
// generated and v6.11.0 removed. `cclaw-cli sync` deletes each so existing
|
|
173
|
+
// installs lose the obsolete sidecar without requiring manual cleanup.
|
|
174
|
+
const DEPRECATED_ARTIFACT_FILES = [
|
|
175
|
+
// v6.10.0 sidecar — replaced in v6.11.0 by phase events in
|
|
176
|
+
// delegation-events.jsonl + auto-rendered tables in 06-tdd.md.
|
|
177
|
+
"06-tdd-slices.jsonl"
|
|
178
|
+
];
|
|
171
179
|
const DEPRECATED_HOOK_FILES = [
|
|
172
180
|
"observe.sh",
|
|
173
181
|
"summarize-observations.sh",
|
|
@@ -851,6 +859,7 @@ async function cleanLegacyArtifacts(projectRoot) {
|
|
|
851
859
|
...DEPRECATED_COMMAND_FILES.map((file) => runtimePath(projectRoot, "commands", file)),
|
|
852
860
|
...DEPRECATED_SKILL_FILES.map((segments) => runtimePath(projectRoot, "skills", ...segments)),
|
|
853
861
|
...DEPRECATED_STATE_FILES.map((file) => runtimePath(projectRoot, "state", file)),
|
|
862
|
+
...DEPRECATED_ARTIFACT_FILES.map((file) => runtimePath(projectRoot, "artifacts", file)),
|
|
854
863
|
...DEPRECATED_RUNTIME_ROOT_FILES.map((file) => runtimePath(projectRoot, file)),
|
|
855
864
|
...DEPRECATED_HOOK_FILES.map((file) => runtimePath(projectRoot, "hooks", file))
|
|
856
865
|
]) {
|
|
@@ -15,7 +15,6 @@ import { parseFlowStateRepairArgs, runFlowStateRepair } from "./flow-state-repai
|
|
|
15
15
|
import { parseWaiverGrantArgs, runWaiverGrant } from "./waiver-grant.js";
|
|
16
16
|
import { FlowStateGuardMismatchError, verifyFlowStateGuard } from "../run-persistence.js";
|
|
17
17
|
import { DelegationTimestampError, DispatchCapError, DispatchDuplicateError, DispatchOverlapError } from "../delegation.js";
|
|
18
|
-
import { parseTddSliceRecordArgs, runTddSliceRecord } from "../tdd-slices.js";
|
|
19
18
|
import { parsePlanSplitWavesArgs, runPlanSplitWaves } from "./plan-split-waves.js";
|
|
20
19
|
/**
|
|
21
20
|
* Subcommands that mutate or consult flow-state.json via the CLI runtime.
|
|
@@ -34,7 +33,7 @@ const GUARD_ENFORCED_SUBCOMMANDS = new Set([
|
|
|
34
33
|
export async function runInternalCommand(projectRoot, argv, io) {
|
|
35
34
|
const [subcommand, ...tokens] = argv;
|
|
36
35
|
if (!subcommand) {
|
|
37
|
-
io.stderr.write("cclaw internal requires a subcommand: advance-stage | start-flow | cancel-run | rewind | verify-flow-state-diff | verify-current-state | envelope-validate | tdd-red-evidence | tdd-loop-status |
|
|
36
|
+
io.stderr.write("cclaw internal requires a subcommand: advance-stage | start-flow | cancel-run | rewind | verify-flow-state-diff | verify-current-state | envelope-validate | tdd-red-evidence | tdd-loop-status | early-loop-status | compound-readiness | runtime-integrity | hook | flow-state-repair | waiver-grant | plan-split-waves\n");
|
|
38
37
|
return 1;
|
|
39
38
|
}
|
|
40
39
|
try {
|
|
@@ -86,13 +85,10 @@ export async function runInternalCommand(projectRoot, argv, io) {
|
|
|
86
85
|
if (subcommand === "waiver-grant") {
|
|
87
86
|
return await runWaiverGrant(projectRoot, parseWaiverGrantArgs(tokens), io);
|
|
88
87
|
}
|
|
89
|
-
if (subcommand === "tdd-slice-record") {
|
|
90
|
-
return await runTddSliceRecord(projectRoot, parseTddSliceRecordArgs(tokens), io);
|
|
91
|
-
}
|
|
92
88
|
if (subcommand === "plan-split-waves") {
|
|
93
89
|
return await runPlanSplitWaves(projectRoot, parsePlanSplitWavesArgs(tokens), io);
|
|
94
90
|
}
|
|
95
|
-
io.stderr.write(`Unknown internal subcommand: ${subcommand}. Expected advance-stage | start-flow | cancel-run | rewind | verify-flow-state-diff | verify-current-state | envelope-validate | tdd-red-evidence | tdd-loop-status |
|
|
91
|
+
io.stderr.write(`Unknown internal subcommand: ${subcommand}. Expected advance-stage | start-flow | cancel-run | rewind | verify-flow-state-diff | verify-current-state | envelope-validate | tdd-red-evidence | tdd-loop-status | early-loop-status | compound-readiness | runtime-integrity | hook | flow-state-repair | waiver-grant | plan-split-waves\n`);
|
|
96
92
|
return 1;
|
|
97
93
|
}
|
|
98
94
|
catch (err) {
|
package/package.json
CHANGED
package/dist/tdd-slices.d.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v6.10.0 — sidecar ledger that replaces the per-slice markdown tables in
|
|
3
|
-
* `06-tdd.md` (Watched-RED Proof, Vertical Slice Cycle, RED/GREEN Evidence).
|
|
4
|
-
*
|
|
5
|
-
* The file lives next to the TDD artifact (`<artifacts-dir>/06-tdd-slices.jsonl`)
|
|
6
|
-
* and is append-only — every CLI call writes a new row, and consumers fold
|
|
7
|
-
* rows by `sliceId` taking the latest entry (by file order). Markdown tables
|
|
8
|
-
* remain a legacy fallback when this sidecar is absent or empty.
|
|
9
|
-
*/
|
|
10
|
-
export interface TddSliceLedgerEntry {
|
|
11
|
-
runId: string;
|
|
12
|
-
sliceId: string;
|
|
13
|
-
status: "red" | "green" | "refactor-deferred" | "refactor-done";
|
|
14
|
-
testFile: string;
|
|
15
|
-
testCommand: string;
|
|
16
|
-
redObservedAt?: string;
|
|
17
|
-
redOutputRef?: string;
|
|
18
|
-
greenAt?: string;
|
|
19
|
-
greenOutputRef?: string;
|
|
20
|
-
refactorAt?: string;
|
|
21
|
-
refactorRationale?: string;
|
|
22
|
-
claimedPaths: string[];
|
|
23
|
-
acceptanceCriterionId?: string;
|
|
24
|
-
planUnitId?: string;
|
|
25
|
-
schemaVersion: 1;
|
|
26
|
-
}
|
|
27
|
-
export declare const TDD_SLICE_LEDGER_FILENAME = "06-tdd-slices.jsonl";
|
|
28
|
-
export declare const TDD_SLICE_LEDGER_SCHEMA_VERSION: 1;
|
|
29
|
-
export declare const TDD_SLICE_STATUSES: readonly ["red", "green", "refactor-deferred", "refactor-done"];
|
|
30
|
-
export type TddSliceStatus = (typeof TDD_SLICE_STATUSES)[number];
|
|
31
|
-
/**
|
|
32
|
-
* Resolve `<artifacts-dir>/06-tdd-slices.jsonl`. Mirrors the convention used
|
|
33
|
-
* by the rest of the runtime (see `artifact-paths.ts::searchRoots`): the
|
|
34
|
-
* sidecar always lives under `.cclaw/artifacts/` regardless of the active
|
|
35
|
-
* topic slug for the TDD artifact.
|
|
36
|
-
*/
|
|
37
|
-
export declare function tddSliceLedgerPath(projectRoot: string): string;
|
|
38
|
-
export declare function isTddSliceLedgerEntry(value: unknown): value is TddSliceLedgerEntry;
|
|
39
|
-
export declare function readTddSliceLedger(projectRoot: string): Promise<{
|
|
40
|
-
entries: TddSliceLedgerEntry[];
|
|
41
|
-
corruptLines: number[];
|
|
42
|
-
}>;
|
|
43
|
-
/**
|
|
44
|
-
* Latest-row-wins fold by `sliceId`. Returns one entry per slice, ordered by
|
|
45
|
-
* the index of its latest row. Mirrors the pattern used by
|
|
46
|
-
* `computeActiveSubagents` for the delegation ledger.
|
|
47
|
-
*/
|
|
48
|
-
export declare function foldTddSliceLedger(entries: TddSliceLedgerEntry[]): TddSliceLedgerEntry[];
|
|
49
|
-
/**
|
|
50
|
-
* Atomic append under a directory lock — reuses the same `withDirectoryLock`
|
|
51
|
-
* primitive that `appendDelegation` uses so concurrent CLI invocations don't
|
|
52
|
-
* tear a half-written JSON line.
|
|
53
|
-
*/
|
|
54
|
-
export declare function appendSliceEntry(projectRoot: string, entry: TddSliceLedgerEntry): Promise<void>;
|
|
55
|
-
export interface TddSliceRecordArgs {
|
|
56
|
-
sliceId: string;
|
|
57
|
-
status: TddSliceStatus;
|
|
58
|
-
testFile?: string;
|
|
59
|
-
testCommand?: string;
|
|
60
|
-
claimedPaths?: string[];
|
|
61
|
-
redOutputRef?: string;
|
|
62
|
-
greenOutputRef?: string;
|
|
63
|
-
redObservedAt?: string;
|
|
64
|
-
greenAt?: string;
|
|
65
|
-
refactorAt?: string;
|
|
66
|
-
refactorRationale?: string;
|
|
67
|
-
acceptanceCriterionId?: string;
|
|
68
|
-
planUnitId?: string;
|
|
69
|
-
json: boolean;
|
|
70
|
-
}
|
|
71
|
-
export declare function parseTddSliceRecordArgs(tokens: string[]): TddSliceRecordArgs;
|
|
72
|
-
interface TddSliceRecordIo {
|
|
73
|
-
stdout: {
|
|
74
|
-
write(chunk: string): boolean;
|
|
75
|
-
};
|
|
76
|
-
stderr: {
|
|
77
|
-
write(chunk: string): boolean;
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Consume parsed CLI flags, fold against the existing sidecar to inherit
|
|
82
|
-
* fields recorded on earlier rows of the same slice, auto-stamp the
|
|
83
|
-
* status-relevant timestamp when not provided, and append the new row.
|
|
84
|
-
*
|
|
85
|
-
* The CLI surface is intentionally lenient: only the very first call for a
|
|
86
|
-
* slice (status=red) needs `--test-file`, `--command`, `--paths`. Subsequent
|
|
87
|
-
* green/refactor calls inherit those values from the latest prior row.
|
|
88
|
-
*/
|
|
89
|
-
export declare function runTddSliceRecord(projectRoot: string, args: TddSliceRecordArgs, io: TddSliceRecordIo): Promise<number>;
|
|
90
|
-
export {};
|