cclaw-cli 0.51.30 → 0.55.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -16
- package/dist/artifact-linter/brainstorm.d.ts +2 -0
- package/dist/artifact-linter/brainstorm.js +245 -0
- package/dist/artifact-linter/design.d.ts +2 -0
- package/dist/artifact-linter/design.js +323 -0
- package/dist/artifact-linter/plan.d.ts +2 -0
- package/dist/artifact-linter/plan.js +162 -0
- package/dist/artifact-linter/review-army.d.ts +24 -0
- package/dist/artifact-linter/review-army.js +365 -0
- package/dist/artifact-linter/review.d.ts +2 -0
- package/dist/artifact-linter/review.js +65 -0
- package/dist/artifact-linter/scope.d.ts +2 -0
- package/dist/artifact-linter/scope.js +115 -0
- package/dist/artifact-linter/shared.d.ts +246 -0
- package/dist/artifact-linter/shared.js +1488 -0
- package/dist/artifact-linter/ship.d.ts +2 -0
- package/dist/artifact-linter/ship.js +46 -0
- package/dist/artifact-linter/spec.d.ts +2 -0
- package/dist/artifact-linter/spec.js +108 -0
- package/dist/artifact-linter/tdd.d.ts +2 -0
- package/dist/artifact-linter/tdd.js +124 -0
- package/dist/artifact-linter.d.ts +4 -76
- package/dist/artifact-linter.js +56 -2949
- package/dist/cli.d.ts +1 -6
- package/dist/cli.js +4 -159
- package/dist/codex-feature-flag.d.ts +1 -1
- package/dist/codex-feature-flag.js +1 -1
- package/dist/config.d.ts +3 -2
- package/dist/config.js +67 -3
- package/dist/constants.d.ts +1 -7
- package/dist/constants.js +9 -15
- package/dist/content/cancel-command.js +2 -2
- package/dist/content/closeout-guidance.js +10 -7
- package/dist/content/core-agents.d.ts +18 -0
- package/dist/content/core-agents.js +46 -2
- package/dist/content/decision-protocol.d.ts +1 -1
- package/dist/content/decision-protocol.js +1 -1
- package/dist/content/examples.js +6 -6
- package/dist/content/harness-doc.js +20 -2
- package/dist/content/hook-inline-snippets.d.ts +17 -4
- package/dist/content/hook-inline-snippets.js +218 -5
- package/dist/content/hook-manifest.d.ts +2 -2
- package/dist/content/hook-manifest.js +2 -2
- package/dist/content/hooks.d.ts +1 -0
- package/dist/content/hooks.js +32 -137
- package/dist/content/idea-command.d.ts +8 -0
- package/dist/content/{ideate-command.js → idea-command.js} +57 -50
- package/dist/content/idea-frames.d.ts +31 -0
- package/dist/content/{ideate-frames.js → idea-frames.js} +9 -9
- package/dist/content/idea-ranking.d.ts +25 -0
- package/dist/content/{ideate-ranking.js → idea-ranking.js} +5 -5
- package/dist/content/iron-laws.d.ts +0 -1
- package/dist/content/iron-laws.js +31 -16
- package/dist/content/learnings.js +1 -1
- package/dist/content/meta-skill.js +7 -7
- package/dist/content/node-hooks.d.ts +10 -0
- package/dist/content/node-hooks.js +43 -9
- package/dist/content/opencode-plugin.js +3 -3
- package/dist/content/skills.js +19 -7
- package/dist/content/stage-schema.js +44 -2
- package/dist/content/stages/_lint-metadata/index.js +26 -2
- package/dist/content/stages/brainstorm.js +13 -7
- package/dist/content/stages/design.js +16 -11
- package/dist/content/stages/plan.js +7 -4
- package/dist/content/stages/review.js +4 -4
- package/dist/content/stages/schema-types.d.ts +1 -1
- package/dist/content/stages/scope.js +15 -12
- package/dist/content/stages/ship.js +2 -2
- package/dist/content/stages/spec.js +9 -3
- package/dist/content/stages/tdd.js +14 -4
- package/dist/content/start-command.js +11 -10
- package/dist/content/status-command.js +3 -3
- package/dist/content/subagents.js +60 -6
- package/dist/content/templates.d.ts +1 -1
- package/dist/content/templates.js +102 -150
- package/dist/content/tree-command.js +2 -2
- package/dist/content/utility-skills.d.ts +2 -2
- package/dist/content/utility-skills.js +2 -2
- package/dist/content/view-command.js +4 -2
- package/dist/delegation.d.ts +2 -0
- package/dist/delegation.js +2 -1
- package/dist/early-loop.d.ts +66 -0
- package/dist/early-loop.js +275 -0
- package/dist/gate-evidence.d.ts +8 -0
- package/dist/gate-evidence.js +141 -5
- package/dist/harness-adapters.d.ts +2 -2
- package/dist/harness-adapters.js +47 -18
- package/dist/install.js +153 -29
- package/dist/internal/advance-stage/advance.d.ts +50 -0
- package/dist/internal/advance-stage/advance.js +480 -0
- package/dist/internal/advance-stage/cancel-run.d.ts +8 -0
- package/dist/internal/advance-stage/cancel-run.js +19 -0
- package/dist/internal/advance-stage/flow-state-coercion.d.ts +3 -0
- package/dist/internal/advance-stage/flow-state-coercion.js +81 -0
- package/dist/internal/advance-stage/helpers.d.ts +14 -0
- package/dist/internal/advance-stage/helpers.js +145 -0
- package/dist/internal/advance-stage/hook.d.ts +8 -0
- package/dist/internal/advance-stage/hook.js +40 -0
- package/dist/internal/advance-stage/parsers.d.ts +54 -0
- package/dist/internal/advance-stage/parsers.js +307 -0
- package/dist/internal/advance-stage/review-loop.d.ts +7 -0
- package/dist/internal/advance-stage/review-loop.js +170 -0
- package/dist/internal/advance-stage/rewind.d.ts +14 -0
- package/dist/internal/advance-stage/rewind.js +108 -0
- package/dist/internal/advance-stage/start-flow.d.ts +11 -0
- package/dist/internal/advance-stage/start-flow.js +136 -0
- package/dist/internal/advance-stage/verify.d.ts +29 -0
- package/dist/internal/advance-stage/verify.js +225 -0
- package/dist/internal/advance-stage.js +21 -1470
- package/dist/internal/compound-readiness.d.ts +1 -1
- package/dist/internal/compound-readiness.js +2 -2
- package/dist/internal/early-loop-status.d.ts +7 -0
- package/dist/internal/early-loop-status.js +90 -0
- package/dist/internal/runtime-integrity.d.ts +7 -0
- package/dist/internal/runtime-integrity.js +288 -0
- package/dist/internal/tdd-red-evidence.js +1 -1
- package/dist/knowledge-store.d.ts +3 -8
- package/dist/knowledge-store.js +16 -29
- package/dist/managed-resources.js +24 -2
- package/dist/policy.js +4 -6
- package/dist/run-archive.d.ts +1 -1
- package/dist/run-archive.js +12 -12
- package/dist/run-persistence.js +111 -11
- package/dist/tdd-cycle.d.ts +3 -3
- package/dist/tdd-cycle.js +1 -1
- package/dist/types.d.ts +18 -10
- package/package.json +1 -1
- package/dist/content/ideate-command.d.ts +0 -8
- package/dist/content/ideate-frames.d.ts +0 -31
- package/dist/content/ideate-ranking.d.ts +0 -25
- package/dist/content/next-command.d.ts +0 -20
- package/dist/content/next-command.js +0 -298
- package/dist/content/seed-shelf.d.ts +0 -36
- package/dist/content/seed-shelf.js +0 -301
- package/dist/content/stage-common-guidance.d.ts +0 -1
- package/dist/content/stage-common-guidance.js +0 -106
- package/dist/doctor-registry.d.ts +0 -10
- package/dist/doctor-registry.js +0 -186
- package/dist/doctor.d.ts +0 -17
- package/dist/doctor.js +0 -2201
- package/dist/internal/hook-manifest.d.ts +0 -16
- package/dist/internal/hook-manifest.js +0 -77
package/dist/cli.d.ts
CHANGED
|
@@ -2,18 +2,13 @@
|
|
|
2
2
|
import type { FlowTrack, HarnessId } from "./types.js";
|
|
3
3
|
import type { ArchiveDisposition } from "./runs.js";
|
|
4
4
|
export { parseHarnessSelectionAnswer } from "./harness-selection.js";
|
|
5
|
-
type CommandName = "init" | "sync" | "
|
|
5
|
+
type CommandName = "init" | "sync" | "upgrade" | "uninstall" | "archive" | "internal";
|
|
6
6
|
interface ParsedArgs {
|
|
7
7
|
command?: CommandName;
|
|
8
8
|
harnesses?: HarnessId[];
|
|
9
9
|
track?: FlowTrack;
|
|
10
10
|
dryRun?: boolean;
|
|
11
11
|
interactive?: boolean;
|
|
12
|
-
reconcileGates?: boolean;
|
|
13
|
-
doctorJson?: boolean;
|
|
14
|
-
doctorExplain?: boolean;
|
|
15
|
-
doctorQuiet?: boolean;
|
|
16
|
-
doctorOnly?: string[];
|
|
17
12
|
archiveName?: string;
|
|
18
13
|
archiveSkipRetro?: boolean;
|
|
19
14
|
archiveSkipRetroReason?: string;
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,6 @@ import path from "node:path";
|
|
|
4
4
|
import { existsSync, realpathSync } from "node:fs";
|
|
5
5
|
import { createInterface } from "node:readline/promises";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
import { doctorChecks, doctorSucceeded } from "./doctor.js";
|
|
8
7
|
import { initCclaw, syncCclaw, uninstallCclaw, upgradeCclaw } from "./install.js";
|
|
9
8
|
import { error, info } from "./logger.js";
|
|
10
9
|
import { FLOW_TRACKS, HARNESS_IDS } from "./types.js";
|
|
@@ -20,7 +19,6 @@ import { runInternalCommand } from "./internal/advance-stage.js";
|
|
|
20
19
|
const INSTALLER_COMMANDS = [
|
|
21
20
|
"init",
|
|
22
21
|
"sync",
|
|
23
|
-
"doctor",
|
|
24
22
|
"upgrade",
|
|
25
23
|
"uninstall",
|
|
26
24
|
"archive",
|
|
@@ -42,12 +40,6 @@ Commands:
|
|
|
42
40
|
sync Reconcile generated runtime files with the current config.
|
|
43
41
|
Flags: --harnesses=<list> Update configured harnesses before syncing.
|
|
44
42
|
--interactive Pick harnesses from a numbered TTY menu.
|
|
45
|
-
doctor Check install/runtime wiring and print concrete fixes for failures.
|
|
46
|
-
Flags: --explain Include docs pointers for every check.
|
|
47
|
-
--json Emit machine-readable check results.
|
|
48
|
-
--quiet Show only failing checks.
|
|
49
|
-
--only=<filter> Limit displayed checks (error,warning,hook:,state:,...).
|
|
50
|
-
--reconcile-gates Refresh derived gate status before checking; does not repair missing artifacts/tests.
|
|
51
43
|
upgrade Refresh generated files in .cclaw. Preserves your config.yaml.
|
|
52
44
|
archive Archive the active run and reset flow state for the next run.
|
|
53
45
|
Flags: --name=<slug> Override archive folder suffix.
|
|
@@ -69,10 +61,9 @@ Examples:
|
|
|
69
61
|
npx cclaw-cli archive --disposition=cancelled --reason="deprioritized"
|
|
70
62
|
npx cclaw-cli upgrade
|
|
71
63
|
|
|
72
|
-
Happy-path work happens inside your harness via /cc, /cc-
|
|
73
|
-
and /cc-cancel.
|
|
74
|
-
|
|
75
|
-
still needed to prove provider auth and model execution.
|
|
64
|
+
Happy-path work happens inside your harness via /cc, /cc-idea,
|
|
65
|
+
and /cc-cancel. Installer/support operations are init/sync/upgrade/uninstall
|
|
66
|
+
plus explicit archive actions.
|
|
76
67
|
|
|
77
68
|
Docs: https://github.com/zuevrs/cclaw
|
|
78
69
|
Local: README.md and generated .cclaw/skills/*.md
|
|
@@ -139,7 +130,7 @@ function buildInitSurfacePreview(harnesses) {
|
|
|
139
130
|
".cclaw/agents/*.md",
|
|
140
131
|
".cclaw/hooks/*",
|
|
141
132
|
".cclaw/rules/**",
|
|
142
|
-
".cclaw/
|
|
133
|
+
".cclaw/archive/**",
|
|
143
134
|
".cclaw/artifacts/**",
|
|
144
135
|
".cclaw/knowledge.jsonl",
|
|
145
136
|
".cclaw/state/*.json|*.jsonl",
|
|
@@ -316,98 +307,6 @@ async function resolveSyncInputs(parsed, ctx) {
|
|
|
316
307
|
}, ctx, "Sync harness reconfiguration")
|
|
317
308
|
};
|
|
318
309
|
}
|
|
319
|
-
function parseDoctorOnly(raw) {
|
|
320
|
-
return raw
|
|
321
|
-
.split(",")
|
|
322
|
-
.map((item) => item.trim().toLowerCase())
|
|
323
|
-
.filter((item) => item.length > 0);
|
|
324
|
-
}
|
|
325
|
-
function filterDoctorChecks(checks, filters) {
|
|
326
|
-
if (!filters || filters.length === 0) {
|
|
327
|
-
return checks;
|
|
328
|
-
}
|
|
329
|
-
return checks.filter((check) => {
|
|
330
|
-
const name = check.name.toLowerCase();
|
|
331
|
-
return filters.some((filter) => {
|
|
332
|
-
if (filter === "error" || filter === "warning" || filter === "info") {
|
|
333
|
-
return check.severity === filter;
|
|
334
|
-
}
|
|
335
|
-
return name.includes(filter);
|
|
336
|
-
});
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
function doctorCountsBySeverity(checks) {
|
|
340
|
-
const result = {
|
|
341
|
-
error: { total: 0, failing: 0 },
|
|
342
|
-
warning: { total: 0, failing: 0 },
|
|
343
|
-
info: { total: 0, failing: 0 }
|
|
344
|
-
};
|
|
345
|
-
for (const check of checks) {
|
|
346
|
-
const bucket = result[check.severity];
|
|
347
|
-
bucket.total += 1;
|
|
348
|
-
if (!check.ok) {
|
|
349
|
-
bucket.failing += 1;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
return result;
|
|
353
|
-
}
|
|
354
|
-
const DOCTOR_ACTION_GROUP_LABELS = {
|
|
355
|
-
sync: "Can fix with cclaw sync",
|
|
356
|
-
"user-action": "Requires user action",
|
|
357
|
-
"stage-work": "Requires stage work",
|
|
358
|
-
informational: "Informational warning"
|
|
359
|
-
};
|
|
360
|
-
function doctorActionGroupOrder(group) {
|
|
361
|
-
return group === "sync" ? 0 : group === "user-action" ? 1 : group === "stage-work" ? 2 : 3;
|
|
362
|
-
}
|
|
363
|
-
function printDoctorText(ctx, checks, options) {
|
|
364
|
-
const orderedSeverities = ["error", "warning", "info"];
|
|
365
|
-
const view = options.quiet ? checks.filter((check) => !check.ok) : checks;
|
|
366
|
-
const actionGroups = [...new Set(view.map((check) => check.actionGroup))]
|
|
367
|
-
.sort((left, right) => doctorActionGroupOrder(left) - doctorActionGroupOrder(right));
|
|
368
|
-
for (const actionGroup of actionGroups) {
|
|
369
|
-
const groupChecks = view.filter((check) => check.actionGroup === actionGroup);
|
|
370
|
-
const failingInGroup = groupChecks.filter((check) => !check.ok).length;
|
|
371
|
-
ctx.stdout.write(`
|
|
372
|
-
[${DOCTOR_ACTION_GROUP_LABELS[actionGroup]}] ${failingInGroup}/${groupChecks.length} failing
|
|
373
|
-
`);
|
|
374
|
-
for (const severity of orderedSeverities) {
|
|
375
|
-
const inBucket = groupChecks.filter((check) => check.severity === severity);
|
|
376
|
-
if (inBucket.length === 0)
|
|
377
|
-
continue;
|
|
378
|
-
ctx.stdout.write(` ${severity.toUpperCase()}
|
|
379
|
-
`);
|
|
380
|
-
for (const check of inBucket) {
|
|
381
|
-
const status = check.ok ? "PASS" : "FAIL";
|
|
382
|
-
ctx.stdout.write(` ${status} ${check.name} :: ${check.summary}
|
|
383
|
-
`);
|
|
384
|
-
if (!options.quiet) {
|
|
385
|
-
ctx.stdout.write(` details: ${check.details}
|
|
386
|
-
`);
|
|
387
|
-
}
|
|
388
|
-
if (!check.ok || options.explain) {
|
|
389
|
-
ctx.stdout.write(` next action: ${check.fix}
|
|
390
|
-
`);
|
|
391
|
-
if (check.docRef) {
|
|
392
|
-
ctx.stdout.write(` reference: ${check.docRef}
|
|
393
|
-
`);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
const counts = doctorCountsBySeverity(checks);
|
|
400
|
-
const failingErrors = checks.filter((check) => check.severity === "error" && !check.ok).length;
|
|
401
|
-
ctx.stdout.write(`\nTotals: error ${counts.error.failing}/${counts.error.total} failing, ` +
|
|
402
|
-
`warning ${counts.warning.failing}/${counts.warning.total} failing, ` +
|
|
403
|
-
`info ${counts.info.failing}/${counts.info.total} failing\n`);
|
|
404
|
-
if (failingErrors > 0) {
|
|
405
|
-
ctx.stdout.write(`Doctor status: BLOCKED (${failingErrors} failing error checks)\n`);
|
|
406
|
-
}
|
|
407
|
-
else {
|
|
408
|
-
ctx.stdout.write("Doctor status: HEALTHY (no failing error checks)\n");
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
310
|
function parseArgs(argv) {
|
|
412
311
|
const parsed = {};
|
|
413
312
|
const helpFlag = argv.find((arg) => arg === "--help" || arg === "-h");
|
|
@@ -439,13 +338,6 @@ function parseArgs(argv) {
|
|
|
439
338
|
flag === "--no-interactive" ||
|
|
440
339
|
(parsed.command === "init" && flag === "--dry-run");
|
|
441
340
|
}
|
|
442
|
-
if (parsed.command === "doctor") {
|
|
443
|
-
return flag === "--reconcile-gates" ||
|
|
444
|
-
flag === "--json" ||
|
|
445
|
-
flag === "--explain" ||
|
|
446
|
-
flag === "--quiet" ||
|
|
447
|
-
flag.startsWith("--only=");
|
|
448
|
-
}
|
|
449
341
|
if (parsed.command === "archive") {
|
|
450
342
|
return flag.startsWith("--name=") ||
|
|
451
343
|
flag === "--skip-retro" ||
|
|
@@ -482,26 +374,6 @@ function parseArgs(argv) {
|
|
|
482
374
|
parsed.dryRun = true;
|
|
483
375
|
continue;
|
|
484
376
|
}
|
|
485
|
-
if (flag === "--reconcile-gates") {
|
|
486
|
-
parsed.reconcileGates = true;
|
|
487
|
-
continue;
|
|
488
|
-
}
|
|
489
|
-
if (flag === "--json") {
|
|
490
|
-
parsed.doctorJson = true;
|
|
491
|
-
continue;
|
|
492
|
-
}
|
|
493
|
-
if (flag === "--explain") {
|
|
494
|
-
parsed.doctorExplain = true;
|
|
495
|
-
continue;
|
|
496
|
-
}
|
|
497
|
-
if (flag === "--quiet") {
|
|
498
|
-
parsed.doctorQuiet = true;
|
|
499
|
-
continue;
|
|
500
|
-
}
|
|
501
|
-
if (flag.startsWith("--only=")) {
|
|
502
|
-
parsed.doctorOnly = parseDoctorOnly(flag.replace("--only=", ""));
|
|
503
|
-
continue;
|
|
504
|
-
}
|
|
505
377
|
if (flag.startsWith("--name=")) {
|
|
506
378
|
parsed.archiveName = flag.replace("--name=", "").trim();
|
|
507
379
|
continue;
|
|
@@ -587,33 +459,6 @@ async function runCommand(parsed, ctx) {
|
|
|
587
459
|
info(ctx, `Synchronized harness shims from current .cclaw config${harnessNote}`);
|
|
588
460
|
return 0;
|
|
589
461
|
}
|
|
590
|
-
if (command === "doctor") {
|
|
591
|
-
const checks = await doctorChecks(ctx.cwd, {
|
|
592
|
-
reconcileCurrentStageGates: parsed.reconcileGates === true
|
|
593
|
-
});
|
|
594
|
-
const filteredChecks = filterDoctorChecks(checks, parsed.doctorOnly);
|
|
595
|
-
const explain = parsed.doctorExplain === true;
|
|
596
|
-
const quiet = parsed.doctorQuiet === true;
|
|
597
|
-
if (parsed.doctorJson === true) {
|
|
598
|
-
const counts = doctorCountsBySeverity(filteredChecks);
|
|
599
|
-
ctx.stdout.write(`${JSON.stringify({
|
|
600
|
-
ok: doctorSucceeded(filteredChecks),
|
|
601
|
-
globalOk: doctorSucceeded(checks),
|
|
602
|
-
filters: parsed.doctorOnly ?? [],
|
|
603
|
-
counts,
|
|
604
|
-
checks: filteredChecks
|
|
605
|
-
}, null, 2)}\n`);
|
|
606
|
-
}
|
|
607
|
-
else {
|
|
608
|
-
if (filteredChecks.length === 0) {
|
|
609
|
-
ctx.stdout.write("No checks matched the --only filter.\n");
|
|
610
|
-
}
|
|
611
|
-
else {
|
|
612
|
-
printDoctorText(ctx, filteredChecks, { explain, quiet });
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
return doctorSucceeded(filteredChecks) ? 0 : 2;
|
|
616
|
-
}
|
|
617
462
|
if (command === "upgrade") {
|
|
618
463
|
await upgradeCclaw(ctx.cwd);
|
|
619
464
|
info(ctx, "Upgraded .cclaw runtime and regenerated generated files");
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* ```
|
|
12
12
|
*
|
|
13
13
|
* in `$CODEX_HOME/config.toml` (default: `~/.codex/config.toml`).
|
|
14
|
-
* cclaw init/sync can prompt the user to flip this flag for them;
|
|
14
|
+
* cclaw init/sync can prompt the user to flip this flag for them; sync/runtime diagnostics report the concrete repair when it is missing;
|
|
15
15
|
* this module owns the detection / mutation code so the prompt logic in
|
|
16
16
|
* `cli.ts` stays small and testable.
|
|
17
17
|
*
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* ```
|
|
12
12
|
*
|
|
13
13
|
* in `$CODEX_HOME/config.toml` (default: `~/.codex/config.toml`).
|
|
14
|
-
* cclaw init/sync can prompt the user to flip this flag for them;
|
|
14
|
+
* cclaw init/sync can prompt the user to flip this flag for them; sync/runtime diagnostics report the concrete repair when it is missing;
|
|
15
15
|
* this module owns the detection / mutation code so the prompt logic in
|
|
16
16
|
* `cli.ts` stays small and testable.
|
|
17
17
|
*
|
package/dist/config.d.ts
CHANGED
|
@@ -24,9 +24,10 @@ export declare const DEFAULT_TDD_TEST_PATH_PATTERNS: readonly string[];
|
|
|
24
24
|
export declare const DEFAULT_TDD_TEST_GLOBS: readonly string[];
|
|
25
25
|
export declare const DEFAULT_TDD_PRODUCTION_PATH_PATTERNS: readonly string[];
|
|
26
26
|
export declare const DEFAULT_COMPOUND_RECURRENCE_THRESHOLD = 3;
|
|
27
|
+
export declare const DEFAULT_EARLY_LOOP_MAX_ITERATIONS = 3;
|
|
27
28
|
/**
|
|
28
29
|
* Populated runtime view of config values that downstream callers (install,
|
|
29
|
-
* observe,
|
|
30
|
+
* observe, sync/runtime checks) consume. Always has the derived guard modes populated,
|
|
30
31
|
* regardless of whether the user wrote `strictness`, the legacy keys, both,
|
|
31
32
|
* or neither.
|
|
32
33
|
*/
|
|
@@ -49,7 +50,7 @@ export declare function readConfig(projectRoot: string, options?: ReadConfigOpti
|
|
|
49
50
|
* the user set them explicitly. Keeps the default template small and honest:
|
|
50
51
|
* only knobs a new user would meaningfully flip show up.
|
|
51
52
|
*/
|
|
52
|
-
type AdvancedConfigKey = "vcs" | "tddTestGlobs" | "tdd" | "compound" | "defaultTrack" | "languageRulePacks" | "trackHeuristics" | "sliceReview" | "ironLaws" | "optInAudits" | "reviewLoop";
|
|
53
|
+
type AdvancedConfigKey = "vcs" | "tddTestGlobs" | "tdd" | "compound" | "earlyLoop" | "defaultTrack" | "languageRulePacks" | "trackHeuristics" | "sliceReview" | "ironLaws" | "optInAudits" | "reviewLoop";
|
|
53
54
|
/**
|
|
54
55
|
* Options controlling the serialisation shape of `config.yaml`.
|
|
55
56
|
*
|
package/dist/config.js
CHANGED
|
@@ -21,6 +21,8 @@ const ALLOWED_CONFIG_KEYS = new Set([
|
|
|
21
21
|
"tddTestGlobs",
|
|
22
22
|
"tdd",
|
|
23
23
|
"compound",
|
|
24
|
+
"earlyLoop",
|
|
25
|
+
"early_loop",
|
|
24
26
|
"gitHookGuards",
|
|
25
27
|
"defaultTrack",
|
|
26
28
|
"languageRulePacks",
|
|
@@ -131,9 +133,10 @@ export const DEFAULT_TDD_TEST_PATH_PATTERNS = [
|
|
|
131
133
|
export const DEFAULT_TDD_TEST_GLOBS = [...DEFAULT_TDD_TEST_PATH_PATTERNS];
|
|
132
134
|
export const DEFAULT_TDD_PRODUCTION_PATH_PATTERNS = [];
|
|
133
135
|
export const DEFAULT_COMPOUND_RECURRENCE_THRESHOLD = 3;
|
|
136
|
+
export const DEFAULT_EARLY_LOOP_MAX_ITERATIONS = 3;
|
|
134
137
|
/**
|
|
135
138
|
* Populated runtime view of config values that downstream callers (install,
|
|
136
|
-
* observe,
|
|
139
|
+
* observe, sync/runtime checks) consume. Always has the derived guard modes populated,
|
|
137
140
|
* regardless of whether the user wrote `strictness`, the legacy keys, both,
|
|
138
141
|
* or neither.
|
|
139
142
|
*/
|
|
@@ -155,11 +158,19 @@ export function createDefaultConfig(harnesses = DEFAULT_HARNESSES, defaultTrack
|
|
|
155
158
|
compound: {
|
|
156
159
|
recurrenceThreshold: DEFAULT_COMPOUND_RECURRENCE_THRESHOLD
|
|
157
160
|
},
|
|
161
|
+
earlyLoop: {
|
|
162
|
+
enabled: true,
|
|
163
|
+
maxIterations: DEFAULT_EARLY_LOOP_MAX_ITERATIONS
|
|
164
|
+
},
|
|
158
165
|
gitHookGuards: false,
|
|
159
166
|
defaultTrack,
|
|
160
167
|
languageRulePacks: [],
|
|
161
168
|
ironLaws: {
|
|
162
169
|
strictLaws: []
|
|
170
|
+
},
|
|
171
|
+
optInAudits: {
|
|
172
|
+
scopePreAudit: false,
|
|
173
|
+
staleDiagramAudit: true
|
|
163
174
|
}
|
|
164
175
|
};
|
|
165
176
|
}
|
|
@@ -327,6 +338,46 @@ export async function readConfig(projectRoot, options = {}) {
|
|
|
327
338
|
compoundRecurrenceThreshold = compoundRaw.recurrenceThreshold;
|
|
328
339
|
}
|
|
329
340
|
}
|
|
341
|
+
const hasEarlyLoopField = Object.prototype.hasOwnProperty.call(parsed, "earlyLoop");
|
|
342
|
+
const hasLegacyEarlyLoopField = Object.prototype.hasOwnProperty.call(parsed, "early_loop");
|
|
343
|
+
if (hasEarlyLoopField && hasLegacyEarlyLoopField) {
|
|
344
|
+
emitConfigWarningOnce(warningState, "CCLAW_CONFIG_EARLY_LOOP_ALIAS", `[cclaw] Both "earlyLoop" and legacy "early_loop" are set in ${fullPath}. Using "earlyLoop".`);
|
|
345
|
+
}
|
|
346
|
+
const earlyLoopRaw = hasEarlyLoopField
|
|
347
|
+
? parsed.earlyLoop
|
|
348
|
+
: parsed.early_loop;
|
|
349
|
+
let earlyLoopEnabled = true;
|
|
350
|
+
let earlyLoopMaxIterations = DEFAULT_EARLY_LOOP_MAX_ITERATIONS;
|
|
351
|
+
if (hasEarlyLoopField || hasLegacyEarlyLoopField) {
|
|
352
|
+
if (!isRecord(earlyLoopRaw)) {
|
|
353
|
+
throw configValidationError(fullPath, `"${hasEarlyLoopField ? "earlyLoop" : "early_loop"}" must be an object`);
|
|
354
|
+
}
|
|
355
|
+
const unknownEarlyLoopKeys = Object.keys(earlyLoopRaw).filter((key) => key !== "enabled" && key !== "maxIterations" && key !== "max_iterations");
|
|
356
|
+
if (unknownEarlyLoopKeys.length > 0) {
|
|
357
|
+
throw configValidationError(fullPath, `"${hasEarlyLoopField ? "earlyLoop" : "early_loop"}" has unknown key(s): ${unknownEarlyLoopKeys.join(", ")}`);
|
|
358
|
+
}
|
|
359
|
+
if (earlyLoopRaw.enabled !== undefined && typeof earlyLoopRaw.enabled !== "boolean") {
|
|
360
|
+
throw configValidationError(fullPath, `"${hasEarlyLoopField ? "earlyLoop" : "early_loop"}.enabled" must be a boolean`);
|
|
361
|
+
}
|
|
362
|
+
if (earlyLoopRaw.maxIterations !== undefined &&
|
|
363
|
+
earlyLoopRaw.max_iterations !== undefined &&
|
|
364
|
+
earlyLoopRaw.maxIterations !== earlyLoopRaw.max_iterations) {
|
|
365
|
+
emitConfigWarningOnce(warningState, "CCLAW_CONFIG_EARLY_LOOP_MAX_ITERATIONS_ALIAS", `[cclaw] Both "${hasEarlyLoopField ? "earlyLoop.maxIterations" : "early_loop.maxIterations"}" and "${hasEarlyLoopField ? "earlyLoop.max_iterations" : "early_loop.max_iterations"}" are set in ${fullPath}. Using "maxIterations".`);
|
|
366
|
+
}
|
|
367
|
+
const rawMaxIterations = earlyLoopRaw.maxIterations ?? earlyLoopRaw.max_iterations;
|
|
368
|
+
if (rawMaxIterations !== undefined &&
|
|
369
|
+
(typeof rawMaxIterations !== "number" ||
|
|
370
|
+
!Number.isInteger(rawMaxIterations) ||
|
|
371
|
+
rawMaxIterations < 1)) {
|
|
372
|
+
throw configValidationError(fullPath, `"${hasEarlyLoopField ? "earlyLoop" : "early_loop"}.maxIterations" must be a positive integer`);
|
|
373
|
+
}
|
|
374
|
+
if (typeof earlyLoopRaw.enabled === "boolean") {
|
|
375
|
+
earlyLoopEnabled = earlyLoopRaw.enabled;
|
|
376
|
+
}
|
|
377
|
+
if (typeof rawMaxIterations === "number") {
|
|
378
|
+
earlyLoopMaxIterations = rawMaxIterations;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
330
381
|
const gitHookGuardsRaw = parsed.gitHookGuards;
|
|
331
382
|
if (Object.prototype.hasOwnProperty.call(parsed, "gitHookGuards") &&
|
|
332
383
|
typeof gitHookGuardsRaw !== "boolean") {
|
|
@@ -483,7 +534,13 @@ export async function readConfig(projectRoot, options = {}) {
|
|
|
483
534
|
: false,
|
|
484
535
|
staleDiagramAudit: typeof optInAuditsRaw.staleDiagramAudit === "boolean"
|
|
485
536
|
? optInAuditsRaw.staleDiagramAudit
|
|
486
|
-
:
|
|
537
|
+
: true
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
if (!optInAudits) {
|
|
541
|
+
optInAudits = {
|
|
542
|
+
scopePreAudit: false,
|
|
543
|
+
staleDiagramAudit: true
|
|
487
544
|
};
|
|
488
545
|
}
|
|
489
546
|
const reviewLoopRaw = parsed.reviewLoop;
|
|
@@ -544,6 +601,10 @@ export async function readConfig(projectRoot, options = {}) {
|
|
|
544
601
|
compound: {
|
|
545
602
|
recurrenceThreshold: compoundRecurrenceThreshold
|
|
546
603
|
},
|
|
604
|
+
earlyLoop: {
|
|
605
|
+
enabled: earlyLoopEnabled,
|
|
606
|
+
maxIterations: earlyLoopMaxIterations
|
|
607
|
+
},
|
|
547
608
|
gitHookGuards,
|
|
548
609
|
defaultTrack,
|
|
549
610
|
languageRulePacks,
|
|
@@ -570,6 +631,7 @@ function buildSerializableConfig(config, options = {}) {
|
|
|
570
631
|
"tddTestGlobs",
|
|
571
632
|
"tdd",
|
|
572
633
|
"compound",
|
|
634
|
+
"earlyLoop",
|
|
573
635
|
"gitHookGuards",
|
|
574
636
|
"defaultTrack",
|
|
575
637
|
"languageRulePacks",
|
|
@@ -626,6 +688,7 @@ export async function detectAdvancedKeys(projectRoot) {
|
|
|
626
688
|
"tddTestGlobs",
|
|
627
689
|
"tdd",
|
|
628
690
|
"compound",
|
|
691
|
+
"earlyLoop",
|
|
629
692
|
"defaultTrack",
|
|
630
693
|
"languageRulePacks",
|
|
631
694
|
"trackHeuristics",
|
|
@@ -636,7 +699,8 @@ export async function detectAdvancedKeys(projectRoot) {
|
|
|
636
699
|
];
|
|
637
700
|
const present = new Set();
|
|
638
701
|
for (const key of advancedCandidates) {
|
|
639
|
-
if (Object.prototype.hasOwnProperty.call(parsedUnknown, key)
|
|
702
|
+
if (Object.prototype.hasOwnProperty.call(parsedUnknown, key) ||
|
|
703
|
+
(key === "earlyLoop" && Object.prototype.hasOwnProperty.call(parsedUnknown, "early_loop"))) {
|
|
640
704
|
present.add(key);
|
|
641
705
|
}
|
|
642
706
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -10,16 +10,10 @@ export declare const FLOW_VERSION = "1.0.0";
|
|
|
10
10
|
export declare const SHIP_FINALIZATION_MODES: readonly ["FINALIZE_MERGE_LOCAL", "FINALIZE_OPEN_PR", "FINALIZE_KEEP_BRANCH", "FINALIZE_DISCARD_BRANCH", "FINALIZE_NO_VCS"];
|
|
11
11
|
export type ShipFinalizationMode = (typeof SHIP_FINALIZATION_MODES)[number];
|
|
12
12
|
export declare const DEFAULT_HARNESSES: HarnessId[];
|
|
13
|
-
export declare const REQUIRED_DIRS: readonly [".cclaw", ".cclaw/commands", ".cclaw/skills", ".cclaw/templates", ".cclaw/templates/state-contracts", ".cclaw/artifacts", ".cclaw/
|
|
13
|
+
export declare const REQUIRED_DIRS: readonly [".cclaw", ".cclaw/commands", ".cclaw/skills", ".cclaw/templates", ".cclaw/templates/state-contracts", ".cclaw/artifacts", ".cclaw/archive", ".cclaw/state", ".cclaw/rules", ".cclaw/agents", ".cclaw/hooks", ".cclaw/skills/review-prompts"];
|
|
14
14
|
export declare const REQUIRED_GITIGNORE_PATTERNS: readonly ["# cclaw generated artifacts", ".cclaw/", ".claude/commands/cc-*.md", ".claude/commands/cc.md", ".cursor/commands/cc-*.md", ".cursor/commands/cc.md", ".opencode/commands/cc-*.md", ".opencode/commands/cc.md", ".agents/skills/cc/SKILL.md", ".agents/skills/cc-*/SKILL.md", ".claude/hooks/hooks.json", ".cursor/hooks.json", ".codex/hooks.json", ".opencode/plugins/cclaw-plugin.mjs", ".cursor/rules/cclaw-workflow.mdc"];
|
|
15
15
|
/**
|
|
16
16
|
* Canonical stage -> skill folder mapping.
|
|
17
|
-
*
|
|
18
|
-
* Intentional divergence from stage ids:
|
|
19
|
-
* - stage ids stay short and flow-oriented (`spec`, `tdd`, `ship`)
|
|
20
|
-
* - skill folders stay descriptive and user-facing for `.cclaw/skills/*`.
|
|
21
|
-
*
|
|
22
|
-
* Keep this map as the single source of truth for generated skill paths.
|
|
23
17
|
*/
|
|
24
18
|
export declare const STAGE_TO_SKILL_FOLDER: Record<FlowStage, string>;
|
|
25
19
|
export declare const SUBAGENT_SKILL_FOLDERS: readonly ["subagent-dev", "parallel-dispatch"];
|
package/dist/constants.js
CHANGED
|
@@ -59,8 +59,8 @@ export const REQUIRED_DIRS = [
|
|
|
59
59
|
`${RUNTIME_ROOT}/templates`,
|
|
60
60
|
`${RUNTIME_ROOT}/templates/state-contracts`,
|
|
61
61
|
`${RUNTIME_ROOT}/artifacts`,
|
|
62
|
+
`${RUNTIME_ROOT}/archive`,
|
|
62
63
|
`${RUNTIME_ROOT}/state`,
|
|
63
|
-
`${RUNTIME_ROOT}/runs`,
|
|
64
64
|
`${RUNTIME_ROOT}/rules`,
|
|
65
65
|
`${RUNTIME_ROOT}/agents`,
|
|
66
66
|
`${RUNTIME_ROOT}/hooks`,
|
|
@@ -89,22 +89,16 @@ export const REQUIRED_GITIGNORE_PATTERNS = [
|
|
|
89
89
|
];
|
|
90
90
|
/**
|
|
91
91
|
* Canonical stage -> skill folder mapping.
|
|
92
|
-
*
|
|
93
|
-
* Intentional divergence from stage ids:
|
|
94
|
-
* - stage ids stay short and flow-oriented (`spec`, `tdd`, `ship`)
|
|
95
|
-
* - skill folders stay descriptive and user-facing for `.cclaw/skills/*`.
|
|
96
|
-
*
|
|
97
|
-
* Keep this map as the single source of truth for generated skill paths.
|
|
98
92
|
*/
|
|
99
93
|
export const STAGE_TO_SKILL_FOLDER = {
|
|
100
|
-
brainstorm: "
|
|
101
|
-
scope: "scope
|
|
102
|
-
design: "
|
|
103
|
-
spec: "
|
|
104
|
-
plan: "
|
|
105
|
-
tdd: "
|
|
106
|
-
review: "
|
|
107
|
-
ship: "
|
|
94
|
+
brainstorm: "brainstorm",
|
|
95
|
+
scope: "scope",
|
|
96
|
+
design: "design",
|
|
97
|
+
spec: "spec",
|
|
98
|
+
plan: "plan",
|
|
99
|
+
tdd: "tdd",
|
|
100
|
+
review: "review",
|
|
101
|
+
ship: "ship"
|
|
108
102
|
};
|
|
109
103
|
export const SUBAGENT_SKILL_FOLDERS = [
|
|
110
104
|
"subagent-dev",
|
|
@@ -6,7 +6,7 @@ Use this command when the user wants to stop the active run without claiming com
|
|
|
6
6
|
## Protocol
|
|
7
7
|
|
|
8
8
|
1. Ask for a concise cancellation reason if the user has not already provided one.
|
|
9
|
-
2. Run \`cclaw
|
|
9
|
+
2. Run \`node .cclaw/hooks/cancel-run.mjs --reason="<reason>"\` from the project root. Use \`--disposition=abandoned\` only when the user explicitly frames the run as abandoned rather than cancelled.
|
|
10
10
|
3. Report the archive path and reset run id. Make clear that the archived run is not a completed ship.
|
|
11
11
|
|
|
12
12
|
Cancelled and abandoned archives are allowed from any stage, but they require a required reason so future readers know why the run ended.
|
|
@@ -20,6 +20,6 @@ description: Cancel or abandon the active cclaw run with a required reason. Use
|
|
|
20
20
|
|
|
21
21
|
# Cancel cclaw Run
|
|
22
22
|
|
|
23
|
-
Load and follow \`.cclaw/commands/cancel.md\`. This is a non-completion path: require a reason and archive with cancelled or abandoned disposition.
|
|
23
|
+
Load and follow \`.cclaw/commands/cancel.md\`. This is a non-completion path: require a reason, run the generated cancel helper, and archive with cancelled or abandoned disposition.
|
|
24
24
|
`;
|
|
25
25
|
}
|
|
@@ -17,11 +17,13 @@ export function closeoutNextCommandGuidance() {
|
|
|
17
17
|
}
|
|
18
18
|
export function closeoutSubstateProtocolBullets() {
|
|
19
19
|
return `When \`currentStage === "ship"\`, route by **${closeoutSubstateInline()}**:
|
|
20
|
-
- \`"idle"\` or missing ->
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
- \`"idle"\` or missing -> outcome: initialize closeout by setting
|
|
21
|
+
${closeoutSubstateInline()} = \`"retro_review"\`, then continue \`/cc\`
|
|
22
|
+
into the in-stage retro protocol (draft + one structured accept/edit/skip ask).
|
|
23
|
+
- \`"retro_review"\` -> outcome: finish retro acceptance/edit/skip and advance
|
|
24
|
+
closeout; the draft already exists, so continue it and do not regenerate it.
|
|
25
|
+
- \`"compound_review"\` -> outcome: execute the in-stage compound closeout scan
|
|
26
|
+
(not \`ce:compound\`) and advance toward archive readiness:
|
|
25
27
|
read \`.cclaw/state/compound-readiness.json\` plus the relevant tail of
|
|
26
28
|
\`.cclaw/knowledge.jsonl\`, assess overlap before adding duplicate knowledge,
|
|
27
29
|
separate bug-track learnings (turn into rules/tests/remediation) from
|
|
@@ -31,8 +33,9 @@ export function closeoutSubstateProtocolBullets() {
|
|
|
31
33
|
session transcripts for matching historical learnings; only do it after opt-in.
|
|
32
34
|
Ask **one** structured question (apply / skip) per candidate cluster or a
|
|
33
35
|
single accept-all / skip choice, then advance substate.
|
|
34
|
-
- \`"ready_to_archive"\` ->
|
|
35
|
-
|
|
36
|
+
- \`"ready_to_archive"\` -> outcome: continue \`/cc\` so the runtime archive step
|
|
37
|
+
executes, snapshots, and resets active state.
|
|
38
|
+
- \`"archived"\` (transient) -> outcome: report "run archived" and stop (flow complete).`;
|
|
36
39
|
}
|
|
37
40
|
export function closeoutFlowMapSentence() {
|
|
38
41
|
return `The first stage names are the critical path. \`retro\`, \`compound\`, and \`archive\` are post-ship closeout substates under ${closeoutSubstateInline()}, not separate stage schemas or commands. Continue them with \`/cc\`; do not route compound closeout through \`ce:compound\`.`;
|
|
@@ -70,6 +70,15 @@ export declare const CCLAW_AGENTS: readonly [{
|
|
|
70
70
|
readonly relatedStages: ["brainstorm", "scope"];
|
|
71
71
|
readonly returnSchema: AgentReturnSchema;
|
|
72
72
|
readonly body: string;
|
|
73
|
+
}, {
|
|
74
|
+
readonly name: "product-strategist";
|
|
75
|
+
readonly description: "PROACTIVE during scope. MUST BE USED when selected scope mode is SCOPE EXPANSION or SELECTIVE EXPANSION to pressure-test 10x vision, strategic upside, and long-term trajectory before lock.";
|
|
76
|
+
readonly tools: ["Read", "Grep", "Glob", "WebSearch"];
|
|
77
|
+
readonly model: "deep";
|
|
78
|
+
readonly activation: "proactive";
|
|
79
|
+
readonly relatedStages: ["scope"];
|
|
80
|
+
readonly returnSchema: AgentReturnSchema;
|
|
81
|
+
readonly body: string;
|
|
73
82
|
}, {
|
|
74
83
|
readonly name: "critic";
|
|
75
84
|
readonly description: "PROACTIVE during brainstorm/scope/design when premises, alternatives, cost, rollback, or hidden assumptions need adversarial pressure.";
|
|
@@ -97,6 +106,15 @@ export declare const CCLAW_AGENTS: readonly [{
|
|
|
97
106
|
readonly relatedStages: ["spec"];
|
|
98
107
|
readonly returnSchema: AgentReturnSchema;
|
|
99
108
|
readonly body: string;
|
|
109
|
+
}, {
|
|
110
|
+
readonly name: "spec-document-reviewer";
|
|
111
|
+
readonly description: "PROACTIVE during spec when self-review surfaces issues, subsystem boundaries feel broad, or the artifact needs a final plan-readiness pass.";
|
|
112
|
+
readonly tools: ["Read", "Grep", "Glob"];
|
|
113
|
+
readonly model: "balanced";
|
|
114
|
+
readonly activation: "proactive";
|
|
115
|
+
readonly relatedStages: ["spec"];
|
|
116
|
+
readonly returnSchema: AgentReturnSchema;
|
|
117
|
+
readonly body: string;
|
|
100
118
|
}, {
|
|
101
119
|
readonly name: "reviewer";
|
|
102
120
|
readonly description: "MANDATORY during review. MUST BE USED to run a two-pass audit: spec compliance first, then correctness/maintainability/performance/architecture.";
|
|
@@ -162,6 +162,28 @@ export const CCLAW_AGENTS = [
|
|
|
162
162
|
"**Role boundary:** frame value and problem fit. Do NOT choose implementation architecture."
|
|
163
163
|
].join("\n")
|
|
164
164
|
},
|
|
165
|
+
{
|
|
166
|
+
name: "product-strategist",
|
|
167
|
+
description: "PROACTIVE during scope. MUST BE USED when selected scope mode is SCOPE EXPANSION or SELECTIVE EXPANSION to pressure-test 10x vision, strategic upside, and long-term trajectory before lock.",
|
|
168
|
+
tools: ["Read", "Grep", "Glob", "WebSearch"],
|
|
169
|
+
model: "deep",
|
|
170
|
+
activation: "proactive",
|
|
171
|
+
relatedStages: ["scope"],
|
|
172
|
+
returnSchema: ADVISORY_RETURN_SCHEMA,
|
|
173
|
+
body: [
|
|
174
|
+
"You are a **product strategy specialist** focused on expansion decisions.",
|
|
175
|
+
"",
|
|
176
|
+
"Produce concise evidence for:",
|
|
177
|
+
"- 10x vision and ideal outcome versus baseline scope",
|
|
178
|
+
"- concrete expansion proposals (not cosmetic variants)",
|
|
179
|
+
"- expected upside, reversibility, and trajectory impact",
|
|
180
|
+
"- explicit add/defer/skip recommendation per proposal",
|
|
181
|
+
"",
|
|
182
|
+
"Operate only when scope mode is SCOPE EXPANSION or SELECTIVE EXPANSION; otherwise return `None - mode does not require strategist pass`.",
|
|
183
|
+
"",
|
|
184
|
+
"**Role boundary:** challenge strategic scope and trajectory; do NOT choose implementation architecture."
|
|
185
|
+
].join("\n")
|
|
186
|
+
},
|
|
165
187
|
{
|
|
166
188
|
name: "critic",
|
|
167
189
|
description: "PROACTIVE during brainstorm/scope/design when premises, alternatives, cost, rollback, or hidden assumptions need adversarial pressure.",
|
|
@@ -216,6 +238,28 @@ export const CCLAW_AGENTS = [
|
|
|
216
238
|
"**Role boundary:** validate the spec; do NOT write plan tasks or implementation."
|
|
217
239
|
].join("\n")
|
|
218
240
|
},
|
|
241
|
+
{
|
|
242
|
+
name: "spec-document-reviewer",
|
|
243
|
+
description: "PROACTIVE during spec when self-review surfaces issues, subsystem boundaries feel broad, or the artifact needs a final plan-readiness pass.",
|
|
244
|
+
tools: ["Read", "Grep", "Glob"],
|
|
245
|
+
model: "balanced",
|
|
246
|
+
activation: "proactive",
|
|
247
|
+
relatedStages: ["spec"],
|
|
248
|
+
returnSchema: REVIEW_RETURN_SCHEMA,
|
|
249
|
+
body: [
|
|
250
|
+
"You are a **spec document reviewer** focused on plan-readiness.",
|
|
251
|
+
"",
|
|
252
|
+
"Run a concise pass over:",
|
|
253
|
+
"- completeness of required spec sections",
|
|
254
|
+
"- consistency across acceptance criteria, assumptions, and mapping",
|
|
255
|
+
"- clarity / ambiguity / placeholder drift",
|
|
256
|
+
"- single-subsystem scope fit and YAGNI pressure",
|
|
257
|
+
"",
|
|
258
|
+
"Return `PASS`, `PASS_WITH_GAPS`, `FAIL`, or `BLOCKED` with concrete evidence refs and minimal corrective actions.",
|
|
259
|
+
"",
|
|
260
|
+
"**Role boundary:** review the spec artifact only; do NOT write plan tasks or implementation."
|
|
261
|
+
].join("\n")
|
|
262
|
+
},
|
|
219
263
|
{
|
|
220
264
|
name: "reviewer",
|
|
221
265
|
description: "MANDATORY during review. MUST BE USED to run a two-pass audit: spec compliance first, then correctness/maintainability/performance/architecture.",
|
|
@@ -511,8 +555,8 @@ export function agentRoutingTable() {
|
|
|
511
555
|
export function agentCostTierTable() {
|
|
512
556
|
return `| Tier | Use for | Example agents |
|
|
513
557
|
|---|---|---|
|
|
514
|
-
| \`deep\` | one heavy planning pass per stage | planner |
|
|
515
|
-
| \`balanced\` | discovery, criticism, review, TDD, and bounded worker execution | product-manager, critic, reviewer, security-reviewer, test-author, implementer, fixer |
|
|
558
|
+
| \`deep\` | one heavy planning/strategy pass per stage | planner, product-strategist |
|
|
559
|
+
| \`balanced\` | discovery, criticism, review, TDD, and bounded worker execution | product-manager, critic, spec-document-reviewer, reviewer, security-reviewer, test-author, implementer, fixer |
|
|
516
560
|
| \`fast\` | bounded maintenance updates with limited blast radius | doc-updater |
|
|
517
561
|
`;
|
|
518
562
|
}
|
|
@@ -9,4 +9,4 @@ export declare const STRUCTURED_ASK_TOOL_LIST_IDEATE = "`AskUserQuestion` on Cla
|
|
|
9
9
|
export declare function structuredAskFallbackSentence(toolList?: string): string;
|
|
10
10
|
export declare function decisionProtocolInstruction(subject: string, optionsClause: string, recommendationClause: string, toolList?: string): string;
|
|
11
11
|
export declare function structuredAskSingleChoiceInstruction(subject: string, choicesClause: string, toolList?: string): string;
|
|
12
|
-
export declare function
|
|
12
|
+
export declare function ideaStructuredAskToolsWithFallback(): string;
|
|
@@ -15,6 +15,6 @@ export function decisionProtocolInstruction(subject, optionsClause, recommendati
|
|
|
15
15
|
export function structuredAskSingleChoiceInstruction(subject, choicesClause, toolList = STRUCTURED_ASK_TOOL_LIST_GENERIC) {
|
|
16
16
|
return `For ${subject}: use the native structured-ask tool (${toolList}) only if runtime schema is confirmed; otherwise collect ${choicesClause} with a plain-text single-choice prompt.`;
|
|
17
17
|
}
|
|
18
|
-
export function
|
|
18
|
+
export function ideaStructuredAskToolsWithFallback() {
|
|
19
19
|
return `${STRUCTURED_ASK_TOOL_LIST_IDEATE}; fall back to a plain-text lettered list when the tool is hidden or errors`;
|
|
20
20
|
}
|