aiwcli 0.12.7 → 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 (134) hide show
  1. package/dist/commands/clean.d.ts +7 -0
  2. package/dist/commands/clean.js +17 -8
  3. package/dist/commands/clear.d.ts +85 -0
  4. package/dist/commands/clear.js +455 -347
  5. package/dist/commands/init/index.d.ts +15 -0
  6. package/dist/commands/init/index.js +79 -38
  7. package/dist/lib/gitignore-manager.js +12 -13
  8. package/dist/lib/settings-hierarchy.d.ts +13 -1
  9. package/dist/lib/settings-hierarchy.js +1 -1
  10. package/dist/lib/template-linter.d.ts +4 -0
  11. package/dist/lib/template-linter.js +1 -1
  12. package/dist/lib/tty-detection.d.ts +1 -0
  13. package/dist/lib/tty-detection.js +1 -0
  14. package/dist/templates/CLAUDE.md +27 -0
  15. package/dist/templates/_shared/.claude/settings.json +7 -7
  16. package/dist/templates/_shared/.claude/{commands/handoff.md → skills/handoff/SKILL.md} +4 -3
  17. package/dist/templates/_shared/.claude/{commands/handoff-resume.md → skills/handoff-resume/SKILL.md} +3 -2
  18. package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +43 -0
  19. package/dist/templates/_shared/.codex/workflows/handoff.md +1 -1
  20. package/dist/templates/_shared/.codex/workflows/meta-plan.md +347 -0
  21. package/dist/templates/_shared/.windsurf/workflows/handoff.md +1 -1
  22. package/dist/templates/_shared/.windsurf/workflows/meta-plan.md +347 -0
  23. package/dist/templates/_shared/hooks-ts/lint_after_edit.ts +59 -0
  24. package/dist/templates/_shared/hooks-ts/session_end.ts +11 -10
  25. package/dist/templates/_shared/hooks-ts/session_start.ts +15 -12
  26. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +12 -12
  27. package/dist/templates/_shared/lib-ts/CLAUDE.md +3 -3
  28. package/dist/templates/_shared/lib-ts/base/constants.ts +324 -306
  29. package/dist/templates/_shared/lib-ts/base/hook-utils.ts +26 -7
  30. package/dist/templates/_shared/lib-ts/base/inference.ts +19 -19
  31. package/dist/templates/_shared/lib-ts/base/lint-dispatch.ts +287 -0
  32. package/dist/templates/_shared/lib-ts/base/state-io.ts +4 -3
  33. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +3 -3
  34. package/dist/templates/_shared/lib-ts/context/CLAUDE.md +134 -0
  35. package/dist/templates/_shared/lib-ts/context/context-formatter.ts +16 -15
  36. package/dist/templates/_shared/lib-ts/context/context-selector.ts +16 -16
  37. package/dist/templates/_shared/lib-ts/context/context-store.ts +15 -14
  38. package/dist/templates/_shared/lib-ts/context/plan-manager.ts +2 -2
  39. package/dist/templates/_shared/scripts/resolve-run.ts +61 -0
  40. package/dist/templates/_shared/scripts/resolve_context.ts +1 -1
  41. package/dist/templates/_shared/scripts/status_line.ts +100 -94
  42. package/dist/templates/_shared/{handoff-system → skills/handoff-system}/CLAUDE.md +433 -421
  43. package/dist/templates/_shared/{handoff-system → skills/handoff-system}/lib/document-generator.ts +5 -4
  44. package/dist/templates/_shared/{handoff-system → skills/handoff-system}/lib/handoff-reader.ts +2 -1
  45. package/dist/templates/_shared/{handoff-system → skills/handoff-system}/scripts/resume_handoff.ts +6 -6
  46. package/dist/templates/_shared/{handoff-system → skills/handoff-system}/scripts/save_handoff.ts +16 -17
  47. package/dist/templates/_shared/{handoff-system → skills/handoff-system}/workflows/handoff-resume.md +2 -2
  48. package/dist/templates/_shared/{handoff-system → skills/handoff-system}/workflows/handoff.md +3 -3
  49. package/dist/templates/_shared/skills/meta-plan/CLAUDE.md +44 -0
  50. package/dist/templates/_shared/skills/meta-plan/workflows/meta-plan.md +347 -0
  51. package/dist/templates/cc-native/.claude/commands/cc-native/specdev.md +1 -1
  52. package/dist/templates/cc-native/.claude/settings.json +86 -57
  53. package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +64 -0
  54. package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/format.ts +599 -597
  55. package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/index.ts +26 -26
  56. package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/tracker.ts +107 -106
  57. package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/write.ts +119 -118
  58. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +237 -247
  59. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +76 -74
  60. package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +76 -0
  61. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +163 -156
  62. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +15 -16
  63. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +116 -116
  64. package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +3 -3
  65. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +16 -12
  66. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +2 -3
  67. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +31 -31
  68. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +7 -6
  69. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +9 -7
  70. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +17 -14
  71. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +41 -37
  72. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +43 -33
  73. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +20 -20
  74. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +9 -8
  75. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +4 -3
  76. package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +9 -10
  77. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +20 -19
  78. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +329 -329
  79. package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +149 -0
  80. package/dist/templates/cc-native/_cc-native/plan-review/agents/CLAUDE.md +143 -0
  81. package/dist/templates/cc-native/_cc-native/plan-review/agents/PLAN-ORCHESTRATOR.md +213 -0
  82. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-questions/PLAN-QUESTIONER.md +70 -0
  83. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-EVOLUTION.md +62 -0
  84. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-PATTERNS.md +61 -0
  85. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-STRUCTURE.md +62 -0
  86. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ASSUMPTION-TRACER.md +56 -0
  87. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CLARITY-AUDITOR.md +53 -0
  88. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-FEASIBILITY.md +66 -0
  89. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-GAPS.md +70 -0
  90. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-ORDERING.md +62 -0
  91. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CONSTRAINT-VALIDATOR.md +72 -0
  92. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-ADR-VALIDATOR.md +61 -0
  93. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-SCALE-MATCHER.md +64 -0
  94. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DEVILS-ADVOCATE.md +56 -0
  95. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DOCUMENTATION-PHILOSOPHY.md +86 -0
  96. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HANDOFF-READINESS.md +59 -0
  97. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HIDDEN-COMPLEXITY.md +58 -0
  98. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/INCREMENTAL-DELIVERY.md +66 -0
  99. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-DEPENDENCY.md +62 -0
  100. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-FMEA.md +66 -0
  101. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-PREMORTEM.md +71 -0
  102. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-REVERSIBILITY.md +74 -0
  103. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SCOPE-BOUNDARY.md +77 -0
  104. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SIMPLICITY-GUARDIAN.md +62 -0
  105. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SKEPTIC.md +68 -0
  106. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-BEHAVIOR-AUDITOR.md +61 -0
  107. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-CHARACTERIZATION.md +71 -0
  108. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-FIRST-VALIDATOR.md +61 -0
  109. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-PYRAMID-ANALYZER.md +61 -0
  110. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-COSTS.md +67 -0
  111. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-STAKEHOLDERS.md +65 -0
  112. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-COVERAGE.md +74 -0
  113. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-STRENGTH.md +69 -0
  114. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/agent-selection.ts +162 -163
  115. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/corroboration.ts +119 -119
  116. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/graduation.ts +132 -132
  117. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/orchestrator.ts +70 -70
  118. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/output-builder.ts +121 -130
  119. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/plan-questions.ts +101 -102
  120. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/review-pipeline.ts +507 -511
  121. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/agent.ts +73 -74
  122. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/base/base-agent.ts +217 -217
  123. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/index.ts +12 -12
  124. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/claude-agent.ts +66 -66
  125. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/codex-agent.ts +185 -185
  126. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/gemini-agent.ts +39 -39
  127. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/orchestrator-claude-agent.ts +196 -196
  128. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/schemas.ts +201 -201
  129. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/types.ts +23 -23
  130. package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/verdict.ts +72 -72
  131. package/dist/templates/cc-native/_cc-native/{workflows → plan-review/workflows}/specdev.md +9 -9
  132. package/oclif.manifest.json +1 -1
  133. package/package.json +6 -5
  134. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +0 -21
@@ -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 "../../lib-ts/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,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 "../../lib-ts/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,70 +1,70 @@
1
- /**
2
- * Plan orchestrator — analyzes complexity and selects reviewer agents.
3
- * Uses OrchestratorClaudeAgent (BaseCliAgent framework) for subprocess execution.
4
- * See cc-native-plan-review-spec.md §4.8
5
- */
6
-
7
- import { OrchestratorClaudeAgent } from "./reviewers/providers/orchestrator-claude-agent.js";
8
- import type { AgentConfig, OrchestratorConfig, OrchestratorResult } from "./types.js";
9
- import { logInfo, logWarn } from "../../_shared/lib-ts/base/logger.js";
10
-
11
- // Re-export for backward compatibility (moved to reviewers/schemas.ts)
12
- export { buildOrchestratorSchema } from "./reviewers/schemas.js";
13
-
14
- // ---------------------------------------------------------------------------
15
- // Orchestrator
16
- // ---------------------------------------------------------------------------
17
-
18
- /**
19
- * Run the orchestrator agent to analyze plan complexity and select reviewers.
20
- * Never throws — returns fallback OrchestratorResult on failure.
21
- */
22
- export async function runOrchestrator(
23
- plan: string,
24
- agentLibrary: AgentConfig[],
25
- config: OrchestratorConfig,
26
- settings: Record<string, unknown>,
27
- mandatoryNames?: Set<string>,
28
- ): Promise<OrchestratorResult> {
29
- logInfo("orchestrator", "Starting plan analysis...");
30
-
31
- const mandatory = mandatoryNames ?? new Set<string>();
32
-
33
- // Create a synthetic AgentConfig for the orchestrator
34
- const orchestratorAgent: AgentConfig = {
35
- name: "orchestrator",
36
- model: config.model,
37
- provider: "claude",
38
- focus: "plan analysis and agent selection",
39
- categories: [],
40
- description: "Plan orchestrator",
41
- system_prompt: "",
42
- };
43
-
44
- try {
45
- const agent = new OrchestratorClaudeAgent(
46
- orchestratorAgent,
47
- agentLibrary,
48
- mandatory,
49
- settings,
50
- config.timeout,
51
- );
52
-
53
- const result = await agent.review(plan);
54
-
55
- logInfo("orchestrator", `Result: complexity=${result.complexity}, category=${result.category}, agents=${JSON.stringify(result.selected_agents)}`);
56
-
57
- return result;
58
- } catch (error) {
59
- logWarn("orchestrator", `Unexpected error: ${error}`);
60
- const nonMandatory = agentLibrary.filter((a) => !mandatory.has(a.name));
61
- const fallbackCount = ((settings.agentSelection as Record<string, unknown>)?.fallbackCount as number) ?? 2;
62
- return {
63
- complexity: "medium",
64
- category: "code",
65
- selected_agents: nonMandatory.slice(0, fallbackCount).map((a) => a.name),
66
- reasoning: `Orchestrator failed: ${error}`,
67
- error: String(error),
68
- };
69
- }
70
- }
1
+ /**
2
+ * Plan orchestrator — analyzes complexity and selects reviewer agents.
3
+ * Uses OrchestratorClaudeAgent (BaseCliAgent framework) for subprocess execution.
4
+ * See cc-native-plan-review-spec.md §4.8
5
+ */
6
+
7
+ import { OrchestratorClaudeAgent } from "./reviewers/providers/orchestrator-claude-agent.js";
8
+ import { logInfo, logWarn } from "../../../_shared/lib-ts/base/logger.js";
9
+ import type { AgentConfig, OrchestratorConfig, OrchestratorResult } from "../../lib-ts/types.js";
10
+
11
+ // Re-export for backward compatibility (moved to reviewers/schemas.ts)
12
+ export { buildOrchestratorSchema } from "./reviewers/schemas.js";
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Orchestrator
16
+ // ---------------------------------------------------------------------------
17
+
18
+ /**
19
+ * Run the orchestrator agent to analyze plan complexity and select reviewers.
20
+ * Never throws — returns fallback OrchestratorResult on failure.
21
+ */
22
+ export async function runOrchestrator(
23
+ plan: string,
24
+ agentLibrary: AgentConfig[],
25
+ config: OrchestratorConfig,
26
+ settings: Record<string, unknown>,
27
+ mandatoryNames?: Set<string>,
28
+ ): Promise<OrchestratorResult> {
29
+ logInfo("orchestrator", "Starting plan analysis...");
30
+
31
+ const mandatory = mandatoryNames ?? new Set<string>();
32
+
33
+ // Create a synthetic AgentConfig for the orchestrator
34
+ const orchestratorAgent: AgentConfig = {
35
+ name: "orchestrator",
36
+ model: config.model,
37
+ provider: "claude",
38
+ focus: "plan analysis and agent selection",
39
+ categories: [],
40
+ description: "Plan orchestrator",
41
+ system_prompt: "",
42
+ };
43
+
44
+ try {
45
+ const agent = new OrchestratorClaudeAgent(
46
+ orchestratorAgent,
47
+ agentLibrary,
48
+ mandatory,
49
+ settings,
50
+ config.timeout,
51
+ );
52
+
53
+ const result = await agent.review(plan);
54
+
55
+ logInfo("orchestrator", `Result: complexity=${result.complexity}, category=${result.category}, agents=${JSON.stringify(result.selected_agents)}`);
56
+
57
+ return result;
58
+ } catch (error) {
59
+ logWarn("orchestrator", `Unexpected error: ${error}`);
60
+ const nonMandatory = agentLibrary.filter((a) => !mandatory.has(a.name));
61
+ const fallbackCount = ((settings.agentSelection as Record<string, unknown>)?.fallbackCount as number) ?? 2;
62
+ return {
63
+ complexity: "medium",
64
+ category: "code",
65
+ selected_agents: nonMandatory.slice(0, fallbackCount).map((a) => a.name),
66
+ reasoning: `Orchestrator failed: ${error}`,
67
+ error: String(error),
68
+ };
69
+ }
70
+ }