cclaw-cli 0.11.0 → 0.13.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.
Files changed (67) hide show
  1. package/README.md +4 -3
  2. package/dist/cli.d.ts +8 -0
  3. package/dist/cli.js +311 -10
  4. package/dist/config.js +19 -0
  5. package/dist/constants.d.ts +2 -2
  6. package/dist/constants.js +13 -1
  7. package/dist/content/core-agents.d.ts +44 -0
  8. package/dist/content/core-agents.js +225 -0
  9. package/dist/content/diff-command.d.ts +2 -0
  10. package/dist/content/diff-command.js +83 -0
  11. package/dist/content/doctor-references.d.ts +2 -0
  12. package/dist/content/doctor-references.js +144 -0
  13. package/dist/content/examples.js +1 -1
  14. package/dist/content/feature-command.d.ts +2 -0
  15. package/dist/content/feature-command.js +120 -0
  16. package/dist/content/harnesses-doc.d.ts +1 -0
  17. package/dist/content/harnesses-doc.js +103 -0
  18. package/dist/content/hook-events.d.ts +4 -0
  19. package/dist/content/hook-events.js +42 -0
  20. package/dist/content/hooks.js +47 -1
  21. package/dist/content/meta-skill.js +3 -2
  22. package/dist/content/next-command.js +8 -6
  23. package/dist/content/observe.d.ts +5 -1
  24. package/dist/content/observe.js +134 -2
  25. package/dist/content/protocols.js +34 -6
  26. package/dist/content/research-playbooks.d.ts +8 -0
  27. package/dist/content/research-playbooks.js +135 -0
  28. package/dist/content/retro-command.d.ts +2 -0
  29. package/dist/content/retro-command.js +77 -0
  30. package/dist/content/rewind-command.d.ts +3 -0
  31. package/dist/content/rewind-command.js +120 -0
  32. package/dist/content/skills.js +20 -0
  33. package/dist/content/stage-schema.d.ts +3 -1
  34. package/dist/content/stage-schema.js +20 -51
  35. package/dist/content/status-command.js +43 -35
  36. package/dist/content/subagents.d.ts +1 -1
  37. package/dist/content/subagents.js +23 -38
  38. package/dist/content/tdd-log-command.d.ts +2 -0
  39. package/dist/content/tdd-log-command.js +75 -0
  40. package/dist/content/templates.d.ts +1 -1
  41. package/dist/content/templates.js +84 -16
  42. package/dist/content/tree-command.d.ts +2 -0
  43. package/dist/content/tree-command.js +91 -0
  44. package/dist/delegation.d.ts +1 -0
  45. package/dist/delegation.js +27 -1
  46. package/dist/doctor-registry.d.ts +8 -0
  47. package/dist/doctor-registry.js +127 -0
  48. package/dist/doctor.d.ts +5 -0
  49. package/dist/doctor.js +261 -7
  50. package/dist/feature-system.d.ts +18 -0
  51. package/dist/feature-system.js +247 -0
  52. package/dist/flow-state.d.ts +25 -0
  53. package/dist/flow-state.js +8 -1
  54. package/dist/harness-adapters.d.ts +7 -0
  55. package/dist/harness-adapters.js +127 -13
  56. package/dist/init-detect.d.ts +2 -0
  57. package/dist/init-detect.js +45 -0
  58. package/dist/install.js +98 -3
  59. package/dist/policy.js +27 -0
  60. package/dist/runs.d.ts +33 -1
  61. package/dist/runs.js +365 -6
  62. package/dist/tdd-cycle.d.ts +22 -0
  63. package/dist/tdd-cycle.js +82 -0
  64. package/dist/types.d.ts +4 -0
  65. package/package.json +2 -1
  66. package/dist/content/agents.d.ts +0 -48
  67. package/dist/content/agents.js +0 -411
package/dist/install.js CHANGED
@@ -10,6 +10,12 @@ import { learnSkillMarkdown, learnCommandContract } from "./content/learnings.js
10
10
  import { nextCommandContract, nextCommandSkillMarkdown } from "./content/next-command.js";
11
11
  import { startCommandContract, startCommandSkillMarkdown } from "./content/start-command.js";
12
12
  import { statusCommandContract, statusCommandSkillMarkdown } from "./content/status-command.js";
13
+ import { treeCommandContract, treeCommandSkillMarkdown } from "./content/tree-command.js";
14
+ import { diffCommandContract, diffCommandSkillMarkdown } from "./content/diff-command.js";
15
+ import { featureCommandContract, featureCommandSkillMarkdown } from "./content/feature-command.js";
16
+ import { tddLogCommandContract, tddLogCommandSkillMarkdown } from "./content/tdd-log-command.js";
17
+ import { retroCommandContract, retroCommandSkillMarkdown } from "./content/retro-command.js";
18
+ import { rewindAcknowledgeCommandContract, rewindCommandContract, rewindCommandSkillMarkdown } from "./content/rewind-command.js";
13
19
  import { subagentDrivenDevSkill, parallelAgentsSkill } from "./content/subagents.js";
14
20
  import { sessionHooksSkillMarkdown } from "./content/session-hooks.js";
15
21
  import { sessionStartScript, stopCheckpointScript, preCompactScript, opencodePluginJs, claudeHooksJson, cursorHooksJson, codexHooksJson } from "./content/hooks.js";
@@ -21,11 +27,15 @@ import { TDD_WAVE_WALKTHROUGH_MARKDOWN, stageSkillFolder, stageSkillMarkdown } f
21
27
  import { stageCommonGuidanceMarkdown } from "./content/stage-common-guidance.js";
22
28
  import { STAGE_EXAMPLES_REFERENCE_DIR, stageExamplesReferenceMarkdown } from "./content/examples.js";
23
29
  import { LANGUAGE_RULE_PACK_DIR, LANGUAGE_RULE_PACK_FILES, LANGUAGE_RULE_PACK_GENERATORS, LEGACY_LANGUAGE_RULE_PACK_FOLDERS, UTILITY_SKILL_FOLDERS, UTILITY_SKILL_MAP } from "./content/utility-skills.js";
30
+ import { RESEARCH_PLAYBOOKS } from "./content/research-playbooks.js";
24
31
  import { HARNESS_TOOL_REFS_DIR, HARNESS_TOOL_REFS_INDEX_MD, harnessToolRefMarkdown } from "./content/harness-tool-refs.js";
32
+ import { DOCTOR_REFERENCE_MARKDOWN } from "./content/doctor-references.js";
33
+ import { harnessIntegrationDocMarkdown } from "./content/harnesses-doc.js";
34
+ import { HOOK_EVENTS_BY_HARNESS, HOOK_SEMANTIC_EVENTS } from "./content/hook-events.js";
25
35
  import { createInitialFlowState } from "./flow-state.js";
26
36
  import { ensureDir, exists, writeFileSafe } from "./fs-utils.js";
27
37
  import { ensureGitignore, removeGitignorePatterns } from "./gitignore.js";
28
- import { HARNESS_ADAPTERS, syncHarnessShims, removeCclawFromAgentsMd } from "./harness-adapters.js";
38
+ import { HARNESS_ADAPTERS, harnessTier, syncHarnessShims, removeCclawFromAgentsMd } from "./harness-adapters.js";
29
39
  import { validateHookDocument } from "./hook-schema.js";
30
40
  import { ensureRunSystem, readFlowState } from "./runs.js";
31
41
  const OPENCODE_PLUGIN_REL_PATH = ".opencode/plugins/cclaw-plugin.mjs";
@@ -193,6 +203,12 @@ async function writeSkills(projectRoot, config) {
193
203
  await writeFileSafe(runtimePath(projectRoot, "skills", "flow-next-step", "SKILL.md"), nextCommandSkillMarkdown());
194
204
  await writeFileSafe(runtimePath(projectRoot, "skills", "flow-start", "SKILL.md"), startCommandSkillMarkdown());
195
205
  await writeFileSafe(runtimePath(projectRoot, "skills", "flow-status", "SKILL.md"), statusCommandSkillMarkdown());
206
+ await writeFileSafe(runtimePath(projectRoot, "skills", "flow-tree", "SKILL.md"), treeCommandSkillMarkdown());
207
+ await writeFileSafe(runtimePath(projectRoot, "skills", "flow-diff", "SKILL.md"), diffCommandSkillMarkdown());
208
+ await writeFileSafe(runtimePath(projectRoot, "skills", "feature-workspaces", "SKILL.md"), featureCommandSkillMarkdown());
209
+ await writeFileSafe(runtimePath(projectRoot, "skills", "tdd-cycle-log", "SKILL.md"), tddLogCommandSkillMarkdown());
210
+ await writeFileSafe(runtimePath(projectRoot, "skills", "flow-retro", "SKILL.md"), retroCommandSkillMarkdown());
211
+ await writeFileSafe(runtimePath(projectRoot, "skills", "flow-rewind", "SKILL.md"), rewindCommandSkillMarkdown());
196
212
  await writeFileSafe(runtimePath(projectRoot, "skills", "subagent-dev", "SKILL.md"), subagentDrivenDevSkill());
197
213
  await writeFileSafe(runtimePath(projectRoot, "skills", "parallel-dispatch", "SKILL.md"), parallelAgentsSkill());
198
214
  await writeFileSafe(runtimePath(projectRoot, "skills", "session", "SKILL.md"), sessionHooksSkillMarkdown());
@@ -204,6 +220,10 @@ async function writeSkills(projectRoot, config) {
204
220
  const generator = UTILITY_SKILL_MAP[folder];
205
221
  await writeFileSafe(runtimePath(projectRoot, "skills", folder, "SKILL.md"), generator());
206
222
  }
223
+ // In-thread research procedures (no YAML frontmatter, not delegated personas).
224
+ for (const [fileName, markdown] of Object.entries(RESEARCH_PLAYBOOKS)) {
225
+ await writeFileSafe(runtimePath(projectRoot, "skills", "research", fileName), markdown);
226
+ }
207
227
  // Language rule packs live under .cclaw/rules/lang/<pack>.md. They are opt-in:
208
228
  // only the packs listed in config.languageRulePacks are materialised. Any
209
229
  // legacy per-language skill folders from v0.7.0 (.cclaw/skills/language-*)
@@ -231,12 +251,24 @@ async function writeSkills(projectRoot, config) {
231
251
  for (const harness of harnessIds) {
232
252
  await writeFileSafe(runtimePath(projectRoot, ...harnessRefsDir, `${harness}.md`), harnessToolRefMarkdown(harness));
233
253
  }
254
+ const doctorRefsDir = ["references", "doctor"];
255
+ for (const [fileName, markdown] of Object.entries(DOCTOR_REFERENCE_MARKDOWN)) {
256
+ await writeFileSafe(runtimePath(projectRoot, ...doctorRefsDir, fileName), markdown);
257
+ }
258
+ await writeFileSafe(runtimePath(projectRoot, "references", "harnesses.md"), harnessIntegrationDocMarkdown());
234
259
  }
235
260
  async function writeUtilityCommands(projectRoot) {
236
261
  await writeFileSafe(runtimePath(projectRoot, "commands", "learn.md"), learnCommandContract());
237
262
  await writeFileSafe(runtimePath(projectRoot, "commands", "next.md"), nextCommandContract());
238
263
  await writeFileSafe(runtimePath(projectRoot, "commands", "start.md"), startCommandContract());
239
264
  await writeFileSafe(runtimePath(projectRoot, "commands", "status.md"), statusCommandContract());
265
+ await writeFileSafe(runtimePath(projectRoot, "commands", "tree.md"), treeCommandContract());
266
+ await writeFileSafe(runtimePath(projectRoot, "commands", "diff.md"), diffCommandContract());
267
+ await writeFileSafe(runtimePath(projectRoot, "commands", "feature.md"), featureCommandContract());
268
+ await writeFileSafe(runtimePath(projectRoot, "commands", "tdd-log.md"), tddLogCommandContract());
269
+ await writeFileSafe(runtimePath(projectRoot, "commands", "retro.md"), retroCommandContract());
270
+ await writeFileSafe(runtimePath(projectRoot, "commands", "rewind.md"), rewindCommandContract());
271
+ await writeFileSafe(runtimePath(projectRoot, "commands", "rewind-ack.md"), rewindAcknowledgeCommandContract());
240
272
  }
241
273
  function toObject(value) {
242
274
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -537,7 +569,10 @@ async function writeHooks(projectRoot, config) {
537
569
  await writeFileSafe(path.join(hooksDir, "prompt-guard.sh"), promptGuardScript({
538
570
  strictMode: config.promptGuardMode === "strict"
539
571
  }));
540
- await writeFileSafe(path.join(hooksDir, "workflow-guard.sh"), workflowGuardScript());
572
+ await writeFileSafe(path.join(hooksDir, "workflow-guard.sh"), workflowGuardScript({
573
+ tddEnforcementMode: config.tddEnforcement ?? "advisory",
574
+ tddTestGlobs: config.tddTestGlobs
575
+ }));
541
576
  await writeFileSafe(path.join(hooksDir, "context-monitor.sh"), contextMonitorScript());
542
577
  const opencodePluginSource = opencodePluginJs();
543
578
  await writeFileSafe(path.join(hooksDir, "opencode-plugin.mjs"), opencodePluginSource);
@@ -747,13 +782,13 @@ Drop this section if no hard rule applies. Keep it crisp:
747
782
  async function ensureSessionStateFiles(projectRoot) {
748
783
  const stateDir = runtimePath(projectRoot, "state");
749
784
  await ensureDir(stateDir);
785
+ const flow = await readFlowState(projectRoot);
750
786
  const activityPath = path.join(stateDir, "stage-activity.jsonl");
751
787
  if (!(await exists(activityPath))) {
752
788
  await writeFileSafe(activityPath, "");
753
789
  }
754
790
  const checkpointPath = path.join(stateDir, "checkpoint.json");
755
791
  if (!(await exists(checkpointPath))) {
756
- const flow = await readFlowState(projectRoot);
757
792
  const initialCheckpoint = {
758
793
  stage: flow.currentStage,
759
794
  runId: flow.activeRunId,
@@ -783,6 +818,21 @@ async function ensureSessionStateFiles(projectRoot) {
783
818
  if (!(await exists(knowledgeDigestPath))) {
784
819
  await writeFileSafe(knowledgeDigestPath, "# Knowledge digest (auto-generated)\n\n(no entries yet)\n");
785
820
  }
821
+ const preambleLogPath = path.join(stateDir, "preamble-log.jsonl");
822
+ if (!(await exists(preambleLogPath))) {
823
+ await writeFileSafe(preambleLogPath, "");
824
+ }
825
+ const tddCycleLogPath = path.join(stateDir, "tdd-cycle-log.jsonl");
826
+ if (!(await exists(tddCycleLogPath))) {
827
+ await writeFileSafe(tddCycleLogPath, "");
828
+ }
829
+ const flowSnapshotPath = path.join(stateDir, "flow-state.snapshot.json");
830
+ if (!(await exists(flowSnapshotPath))) {
831
+ await writeFileSafe(flowSnapshotPath, `${JSON.stringify({
832
+ capturedAt: new Date().toISOString(),
833
+ state: flow
834
+ }, null, 2)}\n`);
835
+ }
786
836
  }
787
837
  async function writeRulebook(projectRoot) {
788
838
  await writeFileSafe(runtimePath(projectRoot, "rules", "RULES.md"), RULEBOOK_MARKDOWN);
@@ -846,6 +896,33 @@ async function writeAdapterManifest(projectRoot, harnesses) {
846
896
  };
847
897
  await writeFileSafe(runtimePath(projectRoot, "adapters", "manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`);
848
898
  }
899
+ async function writeHarnessGapsState(projectRoot, harnesses) {
900
+ const report = harnesses.map((harness) => {
901
+ const capabilities = HARNESS_ADAPTERS[harness].capabilities;
902
+ const hookMap = HOOK_EVENTS_BY_HARNESS[harness];
903
+ const missingHookEvents = HOOK_SEMANTIC_EVENTS.filter((eventName) => !hookMap[eventName]);
904
+ const missingCapabilities = [];
905
+ if (capabilities.nativeSubagentDispatch !== "full") {
906
+ missingCapabilities.push(`nativeSubagentDispatch:${capabilities.nativeSubagentDispatch}`);
907
+ }
908
+ if (capabilities.hookSurface !== "full") {
909
+ missingCapabilities.push(`hookSurface:${capabilities.hookSurface}`);
910
+ }
911
+ if (capabilities.structuredAsk === "plain-text") {
912
+ missingCapabilities.push("structuredAsk:none");
913
+ }
914
+ return {
915
+ harness,
916
+ tier: harnessTier(harness),
917
+ missingCapabilities,
918
+ missingHookEvents
919
+ };
920
+ });
921
+ await writeFileSafe(runtimePath(projectRoot, "state", "harness-gaps.json"), `${JSON.stringify({
922
+ generatedAt: new Date().toISOString(),
923
+ harnesses: report
924
+ }, null, 2)}\n`);
925
+ }
849
926
  async function cleanLegacyArtifacts(projectRoot) {
850
927
  // Remove deprecated utility skill folders from older releases.
851
928
  for (const legacyFolder of [
@@ -878,6 +955,23 @@ async function cleanLegacyArtifacts(projectRoot) {
878
955
  catch {
879
956
  // best-effort cleanup
880
957
  }
958
+ // Core-5 migration: remove deprecated generated agent personas.
959
+ for (const legacyAgentFile of [
960
+ "spec-reviewer.md",
961
+ "code-reviewer.md",
962
+ "repo-research-analyst.md",
963
+ "learnings-researcher.md",
964
+ "framework-docs-researcher.md",
965
+ "best-practices-researcher.md",
966
+ "git-history-analyzer.md"
967
+ ]) {
968
+ try {
969
+ await fs.rm(runtimePath(projectRoot, "agents", legacyAgentFile), { force: true });
970
+ }
971
+ catch {
972
+ // best-effort cleanup
973
+ }
974
+ }
881
975
  for (const legacyPlugin of [
882
976
  path.join(projectRoot, ".opencode/plugins/viby-plugin.mjs"),
883
977
  path.join(projectRoot, ".opencode/plugins/opencode-plugin.mjs"),
@@ -950,6 +1044,7 @@ async function materializeRuntime(projectRoot, config, forceStateReset) {
950
1044
  await ensureRunSystem(projectRoot, { createIfMissing: false });
951
1045
  await ensureSessionStateFiles(projectRoot);
952
1046
  await writeAdapterManifest(projectRoot, harnesses);
1047
+ await writeHarnessGapsState(projectRoot, harnesses);
953
1048
  await ensureKnowledgeStore(projectRoot);
954
1049
  await ensureCustomSkillsScaffold(projectRoot);
955
1050
  await writeHooks(projectRoot, config);
package/dist/policy.js CHANGED
@@ -90,6 +90,27 @@ export async function policyChecks(projectRoot, options = {}) {
90
90
  { file: runtimeFile("skills/learnings/SKILL.md"), needle: "## Subcommands", name: "utility_skill:learnings:subcommands" },
91
91
  { file: runtimeFile("skills/learnings/SKILL.md"), needle: "## HARD-GATE", name: "utility_skill:learnings:hard_gate" },
92
92
  { file: runtimeFile("commands/learn.md"), needle: "## Subcommands", name: "utility_command:learn:subcommands" },
93
+ { file: runtimeFile("commands/status.md"), needle: "bar:", name: "utility_command:status:visual_bar" },
94
+ { file: runtimeFile("commands/status.md"), needle: "/cc-tree · /cc-diff", name: "utility_command:status:tree_diff_link" },
95
+ { file: runtimeFile("commands/tree.md"), needle: "## Algorithm", name: "utility_command:tree:algorithm" },
96
+ { file: runtimeFile("skills/flow-tree/SKILL.md"), needle: "## Protocol", name: "utility_skill:tree:protocol" },
97
+ { file: runtimeFile("skills/flow-tree/SKILL.md"), needle: "## HARD-GATE", name: "utility_skill:tree:hard_gate" },
98
+ { file: runtimeFile("commands/diff.md"), needle: "## Algorithm", name: "utility_command:diff:algorithm" },
99
+ { file: runtimeFile("skills/flow-diff/SKILL.md"), needle: "## Protocol", name: "utility_skill:diff:protocol" },
100
+ { file: runtimeFile("skills/flow-diff/SKILL.md"), needle: "## HARD-GATE", name: "utility_skill:diff:hard_gate" },
101
+ { file: runtimeFile("commands/feature.md"), needle: "## Subcommands", name: "utility_command:feature:subcommands" },
102
+ { file: runtimeFile("skills/feature-workspaces/SKILL.md"), needle: "## Protocol", name: "utility_skill:feature:protocol" },
103
+ { file: runtimeFile("skills/feature-workspaces/SKILL.md"), needle: "## HARD-GATE", name: "utility_skill:feature:hard_gate" },
104
+ { file: runtimeFile("commands/tdd-log.md"), needle: "## Subcommands", name: "utility_command:tdd_log:subcommands" },
105
+ { file: runtimeFile("skills/tdd-cycle-log/SKILL.md"), needle: "## Protocol", name: "utility_skill:tdd_log:protocol" },
106
+ { file: runtimeFile("skills/tdd-cycle-log/SKILL.md"), needle: "## HARD-GATE", name: "utility_skill:tdd_log:hard_gate" },
107
+ { file: runtimeFile("commands/retro.md"), needle: "## Algorithm", name: "utility_command:retro:algorithm" },
108
+ { file: runtimeFile("skills/flow-retro/SKILL.md"), needle: "## Protocol", name: "utility_skill:retro:protocol" },
109
+ { file: runtimeFile("skills/flow-retro/SKILL.md"), needle: "## HARD-GATE", name: "utility_skill:retro:hard_gate" },
110
+ { file: runtimeFile("commands/rewind.md"), needle: "## Algorithm", name: "utility_command:rewind:algorithm" },
111
+ { file: runtimeFile("commands/rewind-ack.md"), needle: "## Algorithm", name: "utility_command:rewind_ack:algorithm" },
112
+ { file: runtimeFile("skills/flow-rewind/SKILL.md"), needle: "## Protocol", name: "utility_skill:rewind:protocol" },
113
+ { file: runtimeFile("skills/flow-rewind/SKILL.md"), needle: "## HARD-GATE", name: "utility_skill:rewind:hard_gate" },
93
114
  { file: runtimeFile("skills/subagent-dev/SKILL.md"), needle: "## HARD-GATE", name: "utility_skill:sdd:hard_gate" },
94
115
  { file: runtimeFile("skills/subagent-dev/SKILL.md"), needle: "## Status Contract", name: "utility_skill:sdd:status_contract" },
95
116
  { file: runtimeFile("skills/subagent-dev/SKILL.md"), needle: "Implementer", name: "utility_skill:sdd:implementer_template" },
@@ -98,6 +119,11 @@ export async function policyChecks(projectRoot, options = {}) {
98
119
  { file: runtimeFile("skills/parallel-dispatch/SKILL.md"), needle: "Review Army", name: "utility_skill:parallel:review_army" },
99
120
  { file: runtimeFile("skills/parallel-dispatch/SKILL.md"), needle: "Reconciliation", name: "utility_skill:parallel:reconciliation" },
100
121
  { file: runtimeFile("skills/parallel-dispatch/SKILL.md"), needle: "## Model & Harness Routing Notes", name: "utility_skill:parallel:routing_notes" },
122
+ { file: runtimeFile("skills/research/repo-scan.md"), needle: "# Repo Scan Playbook", name: "utility_skill:research:repo_scan" },
123
+ { file: runtimeFile("skills/research/learnings-lookup.md"), needle: "# Learnings Lookup Playbook", name: "utility_skill:research:learnings_lookup" },
124
+ { file: runtimeFile("skills/research/framework-docs-lookup.md"), needle: "# Framework Docs Lookup Playbook", name: "utility_skill:research:framework_docs_lookup" },
125
+ { file: runtimeFile("skills/research/best-practices-lookup.md"), needle: "# Best Practices Lookup Playbook", name: "utility_skill:research:best_practices_lookup" },
126
+ { file: runtimeFile("skills/research/git-history.md"), needle: "# Git History Playbook", name: "utility_skill:research:git_history" },
101
127
  { file: runtimeFile("skills/session/SKILL.md"), needle: "## HARD-GATE", name: "utility_skill:session:hard_gate" },
102
128
  { file: runtimeFile("skills/session/SKILL.md"), needle: "## Session Start Protocol", name: "utility_skill:session:start" },
103
129
  { file: runtimeFile("skills/session/SKILL.md"), needle: "## Session Stop Protocol", name: "utility_skill:session:stop" },
@@ -153,6 +179,7 @@ export async function policyChecks(projectRoot, options = {}) {
153
179
  { file: runtimeFile("hooks/prompt-guard.sh"), needle: "write_to_cclaw_runtime", name: "hooks:guard:risky_write_advisory" },
154
180
  { file: runtimeFile("hooks/workflow-guard.sh"), needle: "stage_invocation_without_recent_flow_read", name: "hooks:workflow_guard:flow_read_reason" },
155
181
  { file: runtimeFile("hooks/workflow-guard.sh"), needle: "stage_jump_", name: "hooks:workflow_guard:stage_jump_reason" },
182
+ { file: runtimeFile("hooks/workflow-guard.sh"), needle: "tdd_write_without_open_red", name: "hooks:workflow_guard:tdd_red_first" },
156
183
  { file: runtimeFile("hooks/context-monitor.sh"), needle: "remaining is", name: "hooks:context:threshold_warning" },
157
184
  { file: runtimeFile("hooks/opencode-plugin.mjs"), needle: "activeRunId", name: "hooks:opencode:active_run" },
158
185
  { file: runtimeFile("hooks/session-start.sh"), needle: "Knowledge digest", name: "hooks:session_start:knowledge_digest" },
package/dist/runs.d.ts CHANGED
@@ -22,6 +22,7 @@ export interface ArchiveRunResult {
22
22
  archivePath: string;
23
23
  archivedAt: string;
24
24
  featureName: string;
25
+ activeFeature: string;
25
26
  resetState: FlowState;
26
27
  snapshottedStateFiles: string[];
27
28
  /** Knowledge curation hint: total active entries + soft threshold (50). */
@@ -31,20 +32,46 @@ export interface ArchiveRunResult {
31
32
  overThreshold: boolean;
32
33
  knowledgePath: string;
33
34
  };
35
+ retro: {
36
+ required: boolean;
37
+ completed: boolean;
38
+ skipped: boolean;
39
+ skipReason?: string;
40
+ compoundEntries: number;
41
+ };
34
42
  }
35
43
  export interface ArchiveManifest {
36
44
  version: 1;
37
45
  archiveId: string;
38
46
  archivedAt: string;
39
47
  featureName: string;
48
+ activeFeature: string;
40
49
  sourceRunId: string;
41
50
  sourceCurrentStage: FlowStage;
42
51
  sourceCompletedStages: FlowStage[];
43
52
  snapshottedStateFiles: string[];
53
+ retro: ArchiveRunResult["retro"];
54
+ }
55
+ export interface RewindRunOptions {
56
+ to: FlowStage;
57
+ reason?: string;
58
+ }
59
+ export interface RewindRunResult {
60
+ rewindId: string;
61
+ from: FlowStage;
62
+ to: FlowStage;
63
+ invalidatedStages: FlowStage[];
64
+ staleArtifacts: string[];
65
+ archivePath: string;
66
+ nextState: FlowState;
44
67
  }
45
68
  interface EnsureRunSystemOptions {
46
69
  createIfMissing?: boolean;
47
70
  }
71
+ export interface ArchiveRunOptions {
72
+ skipRetro?: boolean;
73
+ skipRetroReason?: string;
74
+ }
48
75
  export declare class CorruptFlowStateError extends Error {
49
76
  readonly statePath: string;
50
77
  readonly quarantinedPath: string;
@@ -54,7 +81,12 @@ export declare function readFlowState(projectRoot: string): Promise<FlowState>;
54
81
  export declare function writeFlowState(projectRoot: string, state: FlowState, options?: WriteFlowStateOptions): Promise<void>;
55
82
  export declare function ensureRunSystem(projectRoot: string, _options?: EnsureRunSystemOptions): Promise<FlowState>;
56
83
  export declare function listRuns(projectRoot: string): Promise<CclawRunMeta[]>;
57
- export declare function archiveRun(projectRoot: string, featureName?: string): Promise<ArchiveRunResult>;
84
+ export declare function archiveRun(projectRoot: string, featureName?: string, options?: ArchiveRunOptions): Promise<ArchiveRunResult>;
85
+ export declare function rewindRun(projectRoot: string, options: RewindRunOptions): Promise<RewindRunResult>;
86
+ export declare function acknowledgeStaleStage(projectRoot: string, stage: FlowStage): Promise<{
87
+ acknowledged: boolean;
88
+ remaining: FlowStage[];
89
+ }>;
58
90
  /**
59
91
  * Counts entries in the canonical JSONL knowledge store. An "active" entry is one
60
92
  * non-empty line that parses as JSON with the required `type` field belonging to the