aiwcli 0.12.6 → 0.12.7

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 (124) hide show
  1. package/bin/dev.cmd +3 -3
  2. package/bin/dev.js +16 -16
  3. package/bin/run.cmd +3 -3
  4. package/bin/run.js +21 -21
  5. package/dist/commands/branch.js +7 -2
  6. package/dist/lib/bmad-installer.js +37 -37
  7. package/dist/lib/terminal.d.ts +2 -0
  8. package/dist/lib/terminal.js +57 -7
  9. package/dist/templates/CLAUDE.md +205 -205
  10. package/dist/templates/_shared/.claude/commands/handoff-resume.md +12 -12
  11. package/dist/templates/_shared/.claude/commands/handoff.md +12 -12
  12. package/dist/templates/_shared/.claude/settings.json +65 -65
  13. package/dist/templates/_shared/.codex/workflows/handoff.md +226 -226
  14. package/dist/templates/_shared/.windsurf/workflows/handoff.md +226 -226
  15. package/dist/templates/_shared/handoff-system/CLAUDE.md +421 -421
  16. package/dist/templates/_shared/handoff-system/lib/document-generator.ts +215 -215
  17. package/dist/templates/_shared/handoff-system/lib/handoff-reader.ts +158 -158
  18. package/dist/templates/_shared/handoff-system/scripts/resume_handoff.ts +373 -373
  19. package/dist/templates/_shared/handoff-system/scripts/save_handoff.ts +469 -469
  20. package/dist/templates/_shared/handoff-system/workflows/handoff-resume.md +66 -66
  21. package/dist/templates/_shared/handoff-system/workflows/handoff.md +254 -254
  22. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -2
  23. package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -159
  24. package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -147
  25. package/dist/templates/_shared/hooks-ts/file-suggestion.ts +128 -128
  26. package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -49
  27. package/dist/templates/_shared/hooks-ts/session_end.ts +196 -196
  28. package/dist/templates/_shared/hooks-ts/session_start.ts +163 -163
  29. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -48
  30. package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -74
  31. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +93 -93
  32. package/dist/templates/_shared/lib-ts/CLAUDE.md +367 -367
  33. package/dist/templates/_shared/lib-ts/base/atomic-write.ts +138 -138
  34. package/dist/templates/_shared/lib-ts/base/constants.ts +303 -303
  35. package/dist/templates/_shared/lib-ts/base/git-state.ts +58 -58
  36. package/dist/templates/_shared/lib-ts/base/hook-utils.ts +582 -582
  37. package/dist/templates/_shared/lib-ts/base/inference.ts +301 -301
  38. package/dist/templates/_shared/lib-ts/base/logger.ts +247 -247
  39. package/dist/templates/_shared/lib-ts/base/state-io.ts +202 -202
  40. package/dist/templates/_shared/lib-ts/base/stop-words.ts +184 -184
  41. package/dist/templates/_shared/lib-ts/base/utils.ts +184 -184
  42. package/dist/templates/_shared/lib-ts/context/context-formatter.ts +566 -566
  43. package/dist/templates/_shared/lib-ts/context/context-selector.ts +524 -524
  44. package/dist/templates/_shared/lib-ts/context/context-store.ts +712 -712
  45. package/dist/templates/_shared/lib-ts/context/plan-manager.ts +312 -312
  46. package/dist/templates/_shared/lib-ts/context/task-tracker.ts +185 -185
  47. package/dist/templates/_shared/lib-ts/package.json +20 -20
  48. package/dist/templates/_shared/lib-ts/templates/formatters.ts +102 -102
  49. package/dist/templates/_shared/lib-ts/templates/plan-context.ts +58 -58
  50. package/dist/templates/_shared/lib-ts/tsconfig.json +13 -13
  51. package/dist/templates/_shared/lib-ts/types.ts +186 -186
  52. package/dist/templates/_shared/scripts/resolve_context.ts +33 -33
  53. package/dist/templates/_shared/scripts/status_line.ts +690 -690
  54. package/dist/templates/cc-native/.claude/commands/cc-native/rlm/ask.md +136 -136
  55. package/dist/templates/cc-native/.claude/commands/cc-native/rlm/index.md +21 -21
  56. package/dist/templates/cc-native/.claude/commands/cc-native/rlm/overview.md +56 -56
  57. package/dist/templates/cc-native/.claude/commands/cc-native/specdev.md +10 -10
  58. package/dist/templates/cc-native/.windsurf/workflows/cc-native/fix.md +8 -8
  59. package/dist/templates/cc-native/.windsurf/workflows/cc-native/implement.md +8 -8
  60. package/dist/templates/cc-native/.windsurf/workflows/cc-native/research.md +8 -8
  61. package/dist/templates/cc-native/CC-NATIVE-README.md +189 -189
  62. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +304 -304
  63. package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +143 -143
  64. package/dist/templates/cc-native/_cc-native/agents/PLAN-ORCHESTRATOR.md +213 -213
  65. package/dist/templates/cc-native/_cc-native/agents/plan-questions/PLAN-QUESTIONER.md +70 -70
  66. package/dist/templates/cc-native/_cc-native/cc-native.config.json +96 -96
  67. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +247 -247
  68. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +76 -76
  69. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +54 -54
  70. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +51 -51
  71. package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +53 -53
  72. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -61
  73. package/dist/templates/cc-native/_cc-native/lib-ts/agent-selection.ts +163 -163
  74. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +156 -156
  75. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/format.ts +597 -597
  76. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/index.ts +26 -26
  77. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/tracker.ts +107 -107
  78. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/write.ts +119 -119
  79. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +21 -21
  80. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +319 -319
  81. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +144 -144
  82. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -57
  83. package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -83
  84. package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +119 -119
  85. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +79 -79
  86. package/dist/templates/cc-native/_cc-native/lib-ts/graduation.ts +132 -132
  87. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +116 -116
  88. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +168 -168
  89. package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +70 -70
  90. package/dist/templates/cc-native/_cc-native/lib-ts/output-builder.ts +130 -130
  91. package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +80 -80
  92. package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +41 -41
  93. package/dist/templates/cc-native/_cc-native/lib-ts/plan-questions.ts +101 -101
  94. package/dist/templates/cc-native/_cc-native/lib-ts/review-pipeline.ts +511 -511
  95. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +71 -71
  96. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/base/base-agent.ts +217 -217
  97. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +12 -12
  98. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/claude-agent.ts +66 -66
  99. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/codex-agent.ts +184 -184
  100. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/gemini-agent.ts +39 -39
  101. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/orchestrator-claude-agent.ts +196 -196
  102. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/schemas.ts +201 -201
  103. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +21 -21
  104. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/CLAUDE.md +480 -480
  105. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +287 -287
  106. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +148 -148
  107. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +54 -54
  108. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +58 -58
  109. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +208 -208
  110. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +460 -460
  111. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +446 -446
  112. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +280 -280
  113. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +274 -274
  114. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +201 -201
  115. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +278 -278
  116. package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +184 -184
  117. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +275 -275
  118. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -18
  119. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +329 -329
  120. package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +72 -72
  121. package/dist/templates/cc-native/_cc-native/workflows/specdev.md +9 -9
  122. package/oclif.manifest.json +1 -1
  123. package/package.json +108 -108
  124. package/dist/templates/cc-native/_cc-native/lib-ts/nul +0 -3
@@ -1,119 +1,119 @@
1
- /**
2
- * Corroboration-based verdict computation for plan review.
3
- *
4
- * Replaces the old per-verdict aggregation with proportional thresholding:
5
- * high-severity issues in a dimension only block when the total count
6
- * exceeds 2× the number of distinct agents contributing to that dimension.
7
- *
8
- * **Why proportional thresholding:**
9
- * The agent pool has dimensional imbalance (e.g., 10 completeness agents vs
10
- * 1 maintainability agent). A fixed "2+ agents agree = block" would mean
11
- * any 2 completeness agents always block. Proportional scaling (issues > 2×agents)
12
- * sets a fair bar regardless of how many agents focus on each dimension.
13
- *
14
- * **Convergence problem this solves:**
15
- * Agents with opposing philosophies (simplicity-guardian vs completeness-gaps)
16
- * produce contradictory high-severity issues. Because the old system treated
17
- * every agent's finding as independently authoritative, plans oscillated —
18
- * addressing one agent's feedback triggered the opposing agent.
19
- *
20
- * **Revert path:** Change one line in cc-native-plan-review.ts back to
21
- * `computeReviewDecision(allVerdicts)`. Old function kept in verdict.ts.
22
- */
23
-
24
- import type {
25
- ReviewerResult,
26
- ReviewIssue,
27
- IssueDimension,
28
- CorroborationResult,
29
- CorroboratedGroup,
30
- SoloFinding,
31
- } from "./types.js";
32
-
33
- /**
34
- * Compute a corroboration-based review decision from all reviewer results.
35
- *
36
- * Algorithm:
37
- * 1. Collect all high-severity issues with a `dimension` field
38
- * 2. Group by dimension, tracking distinct agent names per group
39
- * 3. For each dimension: block if `issues.length > 2 × agentCount`
40
- * 4. Issues without `dimension` are unclassified (never block)
41
- * 5. Non-high issues are ignored (informational only)
42
- *
43
- * @param allResults - Map of reviewer name → ReviewerResult (CLI + agent)
44
- * @returns CorroborationResult with blocking groups, solo findings, and verdict
45
- */
46
- export function computeCorroboratedDecision(
47
- allResults: Record<string, ReviewerResult>,
48
- ): CorroborationResult {
49
- // Accumulator: dimension → { issues, agentNames }
50
- const dimMap = new Map<
51
- IssueDimension,
52
- {
53
- issues: Array<{ agent: string; issue: ReviewIssue }>;
54
- agentNames: Set<string>;
55
- }
56
- >();
57
-
58
- const unclassified: Array<{ agent: string; issue: ReviewIssue }> = [];
59
-
60
- for (const [agentName, result] of Object.entries(allResults)) {
61
- if (!result.data) continue;
62
- const issues = result.data.issues as ReviewIssue[] | undefined;
63
- if (!Array.isArray(issues)) continue;
64
-
65
- for (const issue of issues) {
66
- // Only high-severity issues participate in corroboration
67
- if (issue.severity !== "high") continue;
68
-
69
- // Issues without dimension are unclassified — cannot block
70
- if (!issue.dimension) {
71
- unclassified.push({ agent: agentName, issue });
72
- continue;
73
- }
74
-
75
- let group = dimMap.get(issue.dimension);
76
- if (!group) {
77
- group = { issues: [], agentNames: new Set() };
78
- dimMap.set(issue.dimension, group);
79
- }
80
- group.issues.push({ agent: agentName, issue });
81
- group.agentNames.add(agentName);
82
- }
83
- }
84
-
85
- const blocking: CorroboratedGroup[] = [];
86
- const solo: SoloFinding[] = [];
87
-
88
- for (const [dimension, group] of dimMap) {
89
- const agentCount = group.agentNames.size;
90
- const threshold = 2 * agentCount;
91
-
92
- if (group.issues.length >= threshold) {
93
- blocking.push({
94
- dimension,
95
- issues: group.issues,
96
- agentCount,
97
- threshold,
98
- });
99
- } else {
100
- solo.push({
101
- dimension,
102
- issues: group.issues,
103
- agentCount,
104
- threshold,
105
- });
106
- }
107
- }
108
-
109
- return {
110
- blocking,
111
- solo,
112
- unclassified,
113
- verdict: blocking.length > 0
114
- ? "fail"
115
- : solo.length > 0
116
- ? "warn"
117
- : "pass",
118
- };
119
- }
1
+ /**
2
+ * Corroboration-based verdict computation for plan review.
3
+ *
4
+ * Replaces the old per-verdict aggregation with proportional thresholding:
5
+ * high-severity issues in a dimension only block when the total count
6
+ * exceeds 2× the number of distinct agents contributing to that dimension.
7
+ *
8
+ * **Why proportional thresholding:**
9
+ * The agent pool has dimensional imbalance (e.g., 10 completeness agents vs
10
+ * 1 maintainability agent). A fixed "2+ agents agree = block" would mean
11
+ * any 2 completeness agents always block. Proportional scaling (issues > 2×agents)
12
+ * sets a fair bar regardless of how many agents focus on each dimension.
13
+ *
14
+ * **Convergence problem this solves:**
15
+ * Agents with opposing philosophies (simplicity-guardian vs completeness-gaps)
16
+ * produce contradictory high-severity issues. Because the old system treated
17
+ * every agent's finding as independently authoritative, plans oscillated —
18
+ * addressing one agent's feedback triggered the opposing agent.
19
+ *
20
+ * **Revert path:** Change one line in cc-native-plan-review.ts back to
21
+ * `computeReviewDecision(allVerdicts)`. Old function kept in verdict.ts.
22
+ */
23
+
24
+ import type {
25
+ ReviewerResult,
26
+ ReviewIssue,
27
+ IssueDimension,
28
+ CorroborationResult,
29
+ CorroboratedGroup,
30
+ SoloFinding,
31
+ } from "./types.js";
32
+
33
+ /**
34
+ * Compute a corroboration-based review decision from all reviewer results.
35
+ *
36
+ * Algorithm:
37
+ * 1. Collect all high-severity issues with a `dimension` field
38
+ * 2. Group by dimension, tracking distinct agent names per group
39
+ * 3. For each dimension: block if `issues.length > 2 × agentCount`
40
+ * 4. Issues without `dimension` are unclassified (never block)
41
+ * 5. Non-high issues are ignored (informational only)
42
+ *
43
+ * @param allResults - Map of reviewer name → ReviewerResult (CLI + agent)
44
+ * @returns CorroborationResult with blocking groups, solo findings, and verdict
45
+ */
46
+ export function computeCorroboratedDecision(
47
+ allResults: Record<string, ReviewerResult>,
48
+ ): CorroborationResult {
49
+ // Accumulator: dimension → { issues, agentNames }
50
+ const dimMap = new Map<
51
+ IssueDimension,
52
+ {
53
+ issues: Array<{ agent: string; issue: ReviewIssue }>;
54
+ agentNames: Set<string>;
55
+ }
56
+ >();
57
+
58
+ const unclassified: Array<{ agent: string; issue: ReviewIssue }> = [];
59
+
60
+ for (const [agentName, result] of Object.entries(allResults)) {
61
+ if (!result.data) continue;
62
+ const issues = result.data.issues as ReviewIssue[] | undefined;
63
+ if (!Array.isArray(issues)) continue;
64
+
65
+ for (const issue of issues) {
66
+ // Only high-severity issues participate in corroboration
67
+ if (issue.severity !== "high") continue;
68
+
69
+ // Issues without dimension are unclassified — cannot block
70
+ if (!issue.dimension) {
71
+ unclassified.push({ agent: agentName, issue });
72
+ continue;
73
+ }
74
+
75
+ let group = dimMap.get(issue.dimension);
76
+ if (!group) {
77
+ group = { issues: [], agentNames: new Set() };
78
+ dimMap.set(issue.dimension, group);
79
+ }
80
+ group.issues.push({ agent: agentName, issue });
81
+ group.agentNames.add(agentName);
82
+ }
83
+ }
84
+
85
+ const blocking: CorroboratedGroup[] = [];
86
+ const solo: SoloFinding[] = [];
87
+
88
+ for (const [dimension, group] of dimMap) {
89
+ const agentCount = group.agentNames.size;
90
+ const threshold = 2 * agentCount;
91
+
92
+ if (group.issues.length >= threshold) {
93
+ blocking.push({
94
+ dimension,
95
+ issues: group.issues,
96
+ agentCount,
97
+ threshold,
98
+ });
99
+ } else {
100
+ solo.push({
101
+ dimension,
102
+ issues: group.issues,
103
+ agentCount,
104
+ threshold,
105
+ });
106
+ }
107
+ }
108
+
109
+ return {
110
+ blocking,
111
+ solo,
112
+ unclassified,
113
+ verdict: blocking.length > 0
114
+ ? "fail"
115
+ : solo.length > 0
116
+ ? "warn"
117
+ : "pass",
118
+ };
119
+ }
@@ -1,80 +1,80 @@
1
- /**
2
- * Per-context debug logging for cc-native hooks.
3
- * Thin delegation layer over the unified logger.
4
- * See cc-native-plan-review-spec.md §4.13
5
- *
6
- * Can be disabled via CCNATIVE_DEBUG_DISABLE=1 environment variable.
7
- */
8
-
9
- import * as fs from "node:fs";
1
+ /**
2
+ * Per-context debug logging for cc-native hooks.
3
+ * Thin delegation layer over the unified logger.
4
+ * See cc-native-plan-review-spec.md §4.13
5
+ *
6
+ * Can be disabled via CCNATIVE_DEBUG_DISABLE=1 environment variable.
7
+ */
8
+
9
+ import * as fs from "node:fs";
10
10
  import * as path from "node:path";
11
-
12
- import { hookLog } from "../../_shared/lib-ts/base/logger.js";
13
-
14
- /** Feature flag — set CCNATIVE_DEBUG_DISABLE=1 to turn off */
15
- const DEBUG_ENABLED = !["1", "true", "yes"].includes(
16
- (process.env.CCNATIVE_DEBUG_DISABLE ?? "").toLowerCase(),
17
- );
18
-
19
- /**
20
- * Get or create debug directory within context folder.
21
- */
22
- export function getDebugDir(contextPath: string): string {
23
- const debugDir = path.join(contextPath, "debug");
24
- fs.mkdirSync(debugDir, { recursive: true });
25
- return debugDir;
26
- }
27
-
28
- /**
29
- * Write a debug log entry. Delegates to unified logger.
30
- */
31
- export function debugLog(
32
- contextPath: string,
33
- sessionName: string,
34
- component: string,
35
- message: string,
36
- data?: unknown,
37
- ): void {
38
- if (!DEBUG_ENABLED) return;
39
-
40
- hookLog("debug", sessionName, message, {
41
- component,
42
- data,
43
- });
44
- }
45
-
46
- /**
47
- * Log raw output (stdout, stderr, etc). Delegates to unified logger.
48
- */
49
- export function debugRaw(
50
- contextPath: string,
51
- sessionName: string,
52
- component: string,
53
- label: string,
54
- raw: string,
55
- maxLen = 10_000,
56
- ): void {
57
- if (!DEBUG_ENABLED) return;
58
-
59
- const truncated = raw.length > maxLen ? raw.slice(0, maxLen) : raw;
60
- const suffix =
61
- raw.length > maxLen ? ` [TRUNCATED from ${raw.length} chars]` : "";
62
-
63
- hookLog("debug", sessionName, `${label}${suffix}: ${truncated}`, {
64
- component,
65
- });
66
- }
67
-
68
- /**
69
- * Remove debug folder during context archive.
70
- */
71
- export function cleanupDebugFolder(contextPath: string): void {
72
- try {
73
- const debugDir = path.join(contextPath, "debug");
74
- if (fs.existsSync(debugDir)) {
75
- fs.rmSync(debugDir, { recursive: true, force: true });
76
- }
77
- } catch {
78
- // Best effort cleanup
79
- }
80
- }
11
+
12
+ import { hookLog } from "../../_shared/lib-ts/base/logger.js";
13
+
14
+ /** Feature flag — set CCNATIVE_DEBUG_DISABLE=1 to turn off */
15
+ const DEBUG_ENABLED = !["1", "true", "yes"].includes(
16
+ (process.env.CCNATIVE_DEBUG_DISABLE ?? "").toLowerCase(),
17
+ );
18
+
19
+ /**
20
+ * Get or create debug directory within context folder.
21
+ */
22
+ export function getDebugDir(contextPath: string): string {
23
+ const debugDir = path.join(contextPath, "debug");
24
+ fs.mkdirSync(debugDir, { recursive: true });
25
+ return debugDir;
26
+ }
27
+
28
+ /**
29
+ * Write a debug log entry. Delegates to unified logger.
30
+ */
31
+ export function debugLog(
32
+ contextPath: string,
33
+ sessionName: string,
34
+ component: string,
35
+ message: string,
36
+ data?: unknown,
37
+ ): void {
38
+ if (!DEBUG_ENABLED) return;
39
+
40
+ hookLog("debug", sessionName, message, {
41
+ component,
42
+ data,
43
+ });
44
+ }
45
+
46
+ /**
47
+ * Log raw output (stdout, stderr, etc). Delegates to unified logger.
48
+ */
49
+ export function debugRaw(
50
+ contextPath: string,
51
+ sessionName: string,
52
+ component: string,
53
+ label: string,
54
+ raw: string,
55
+ maxLen = 10_000,
56
+ ): void {
57
+ if (!DEBUG_ENABLED) return;
58
+
59
+ const truncated = raw.length > maxLen ? raw.slice(0, maxLen) : raw;
60
+ const suffix =
61
+ raw.length > maxLen ? ` [TRUNCATED from ${raw.length} chars]` : "";
62
+
63
+ hookLog("debug", sessionName, `${label}${suffix}: ${truncated}`, {
64
+ component,
65
+ });
66
+ }
67
+
68
+ /**
69
+ * Remove debug folder during context archive.
70
+ */
71
+ export function cleanupDebugFolder(contextPath: string): void {
72
+ try {
73
+ const debugDir = path.join(contextPath, "debug");
74
+ if (fs.existsSync(debugDir)) {
75
+ fs.rmSync(debugDir, { recursive: true, force: true });
76
+ }
77
+ } catch {
78
+ // Best effort cleanup
79
+ }
80
+ }
@@ -1,132 +1,132 @@
1
- /**
2
- * Graduation logic: pass eligibility, pass streaks, graduation threshold, iteration advancement.
3
- * Extracted from cc-native-plan-review.ts.
4
- */
5
-
6
- import type {
7
- IterationState,
8
- ReviewerResult,
9
- CombinedReviewResult,
10
- IterationAdvancement,
11
- } from "./types.js";
12
-
13
- // ---------------------------------------------------------------------------
14
- // Pass Eligibility
15
- // ---------------------------------------------------------------------------
16
-
17
- /**
18
- * Determine which agents are pass-eligible this iteration.
19
- * Criteria: verdict === "pass" OR zero high-severity issues.
20
- * Agents with "skip"/"error" are NOT eligible (no signal).
21
- */
22
- export function computePassEligible(agentResults: Record<string, ReviewerResult>): string[] {
23
- const eligible: string[] = [];
24
- for (const [name, result] of Object.entries(agentResults)) {
25
- if (result.verdict === "skip" || result.verdict === "error") continue;
26
- if (result.verdict === "pass") { eligible.push(name); continue; }
27
- const issues = Array.isArray(result.data?.issues)
28
- ? (result.data.issues as Array<{ severity?: string }>) : [];
29
- if (issues.filter(i => i.severity === "high").length === 0) {
30
- eligible.push(name);
31
- }
32
- }
33
- return eligible;
34
- }
35
-
36
- // ---------------------------------------------------------------------------
37
- // Tracker Issue Extraction
38
- // ---------------------------------------------------------------------------
39
-
40
- /**
41
- * Extract top high-severity issues for the review tracker.
42
- */
43
- export function extractTopIssuesForTracker(
44
- combined: CombinedReviewResult,
45
- maxCount = 5,
46
- ): string[] {
47
- const allReviewers = Object.values(combined.agents);
48
- const issues: string[] = [];
49
- for (const r of allReviewers) {
50
- if (!r.data) continue;
51
- const issueList = r.data.issues as Array<Record<string, unknown>> | undefined;
52
- if (!issueList) continue;
53
- for (const issue of issueList) {
54
- if (issue.severity === "high") {
55
- const text = String(issue.issue ?? "").trim();
56
- if (text) {
57
- issues.push(`[${r.name}] ${text}`);
58
- }
59
- }
60
- }
61
- if (issues.length >= maxCount) break;
62
- }
63
- return issues.slice(0, maxCount);
64
- }
65
-
66
- // ---------------------------------------------------------------------------
67
- // Iteration Advancement
68
- // ---------------------------------------------------------------------------
69
-
70
- const GRADUATION_THRESHOLD = 2;
71
-
72
- /**
73
- * Advance iteration state after a review cycle. Returns a new state copy
74
- * (does not mutate input).
75
- *
76
- * - On pass/warrant: sets current past max (stop iterating)
77
- * - On deny: increments current toward max (safety valve)
78
- * - Updates pass streaks and graduates agents that reached threshold
79
- */
80
- export function advanceIterationState(
81
- state: IterationState,
82
- planHash: string,
83
- planPath: string,
84
- verdict: string,
85
- shouldDeny: boolean,
86
- passEligible: string[],
87
- agentResults: Record<string, ReviewerResult>,
88
- graduationThreshold = GRADUATION_THRESHOLD,
89
- ): IterationAdvancement {
90
- const updated: IterationState = {
91
- ...state,
92
- history: [...state.history, { hash: planHash, verdict, timestamp: new Date().toISOString() }],
93
- lastPlanHash: planHash,
94
- lastPlanPath: planPath,
95
- graduated: [...state.graduated],
96
- passStreaks: { ...(state.passStreaks ?? {}) },
97
- };
98
-
99
- if (!shouldDeny) {
100
- // Pass/warrant: stop iterating
101
- updated.current = updated.max + 1;
102
- } else {
103
- // Deny: advance toward max
104
- updated.current = state.current + 1;
105
- }
106
-
107
- // Update pass streaks — only for agents that actually ran this iteration
108
- const passEligibleSet = new Set(passEligible);
109
- const graduatedSet = new Set(updated.graduated);
110
-
111
- for (const name of Object.keys(agentResults)) {
112
- if (graduatedSet.has(name)) continue;
113
- if (passEligibleSet.has(name)) {
114
- updated.passStreaks[name] = (updated.passStreaks[name] ?? 0) + 1;
115
- } else {
116
- updated.passStreaks[name] = 0;
117
- }
118
- }
119
-
120
- // Graduate agents that reached threshold
121
- const newGraduates: string[] = [];
122
- for (const [name, streak] of Object.entries(updated.passStreaks)) {
123
- if (streak >= graduationThreshold && !graduatedSet.has(name)) {
124
- newGraduates.push(name);
125
- }
126
- }
127
- if (newGraduates.length > 0) {
128
- updated.graduated = [...updated.graduated, ...newGraduates];
129
- }
130
-
131
- return { updatedState: updated, newGraduates };
132
- }
1
+ /**
2
+ * Graduation logic: pass eligibility, pass streaks, graduation threshold, iteration advancement.
3
+ * Extracted from cc-native-plan-review.ts.
4
+ */
5
+
6
+ import type {
7
+ IterationState,
8
+ ReviewerResult,
9
+ CombinedReviewResult,
10
+ IterationAdvancement,
11
+ } from "./types.js";
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Pass Eligibility
15
+ // ---------------------------------------------------------------------------
16
+
17
+ /**
18
+ * Determine which agents are pass-eligible this iteration.
19
+ * Criteria: verdict === "pass" OR zero high-severity issues.
20
+ * Agents with "skip"/"error" are NOT eligible (no signal).
21
+ */
22
+ export function computePassEligible(agentResults: Record<string, ReviewerResult>): string[] {
23
+ const eligible: string[] = [];
24
+ for (const [name, result] of Object.entries(agentResults)) {
25
+ if (result.verdict === "skip" || result.verdict === "error") continue;
26
+ if (result.verdict === "pass") { eligible.push(name); continue; }
27
+ const issues = Array.isArray(result.data?.issues)
28
+ ? (result.data.issues as Array<{ severity?: string }>) : [];
29
+ if (issues.filter(i => i.severity === "high").length === 0) {
30
+ eligible.push(name);
31
+ }
32
+ }
33
+ return eligible;
34
+ }
35
+
36
+ // ---------------------------------------------------------------------------
37
+ // Tracker Issue Extraction
38
+ // ---------------------------------------------------------------------------
39
+
40
+ /**
41
+ * Extract top high-severity issues for the review tracker.
42
+ */
43
+ export function extractTopIssuesForTracker(
44
+ combined: CombinedReviewResult,
45
+ maxCount = 5,
46
+ ): string[] {
47
+ const allReviewers = Object.values(combined.agents);
48
+ const issues: string[] = [];
49
+ for (const r of allReviewers) {
50
+ if (!r.data) continue;
51
+ const issueList = r.data.issues as Array<Record<string, unknown>> | undefined;
52
+ if (!issueList) continue;
53
+ for (const issue of issueList) {
54
+ if (issue.severity === "high") {
55
+ const text = String(issue.issue ?? "").trim();
56
+ if (text) {
57
+ issues.push(`[${r.name}] ${text}`);
58
+ }
59
+ }
60
+ }
61
+ if (issues.length >= maxCount) break;
62
+ }
63
+ return issues.slice(0, maxCount);
64
+ }
65
+
66
+ // ---------------------------------------------------------------------------
67
+ // Iteration Advancement
68
+ // ---------------------------------------------------------------------------
69
+
70
+ const GRADUATION_THRESHOLD = 2;
71
+
72
+ /**
73
+ * Advance iteration state after a review cycle. Returns a new state copy
74
+ * (does not mutate input).
75
+ *
76
+ * - On pass/warrant: sets current past max (stop iterating)
77
+ * - On deny: increments current toward max (safety valve)
78
+ * - Updates pass streaks and graduates agents that reached threshold
79
+ */
80
+ export function advanceIterationState(
81
+ state: IterationState,
82
+ planHash: string,
83
+ planPath: string,
84
+ verdict: string,
85
+ shouldDeny: boolean,
86
+ passEligible: string[],
87
+ agentResults: Record<string, ReviewerResult>,
88
+ graduationThreshold = GRADUATION_THRESHOLD,
89
+ ): IterationAdvancement {
90
+ const updated: IterationState = {
91
+ ...state,
92
+ history: [...state.history, { hash: planHash, verdict, timestamp: new Date().toISOString() }],
93
+ lastPlanHash: planHash,
94
+ lastPlanPath: planPath,
95
+ graduated: [...state.graduated],
96
+ passStreaks: { ...(state.passStreaks ?? {}) },
97
+ };
98
+
99
+ if (!shouldDeny) {
100
+ // Pass/warrant: stop iterating
101
+ updated.current = updated.max + 1;
102
+ } else {
103
+ // Deny: advance toward max
104
+ updated.current = state.current + 1;
105
+ }
106
+
107
+ // Update pass streaks — only for agents that actually ran this iteration
108
+ const passEligibleSet = new Set(passEligible);
109
+ const graduatedSet = new Set(updated.graduated);
110
+
111
+ for (const name of Object.keys(agentResults)) {
112
+ if (graduatedSet.has(name)) continue;
113
+ if (passEligibleSet.has(name)) {
114
+ updated.passStreaks[name] = (updated.passStreaks[name] ?? 0) + 1;
115
+ } else {
116
+ updated.passStreaks[name] = 0;
117
+ }
118
+ }
119
+
120
+ // Graduate agents that reached threshold
121
+ const newGraduates: string[] = [];
122
+ for (const [name, streak] of Object.entries(updated.passStreaks)) {
123
+ if (streak >= graduationThreshold && !graduatedSet.has(name)) {
124
+ newGraduates.push(name);
125
+ }
126
+ }
127
+ if (newGraduates.length > 0) {
128
+ updated.graduated = [...updated.graduated, ...newGraduates];
129
+ }
130
+
131
+ return { updatedState: updated, newGraduates };
132
+ }