aiwcli 0.11.1 → 0.12.1

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 (117) hide show
  1. package/dist/commands/clear.d.ts +8 -0
  2. package/dist/commands/clear.js +86 -0
  3. package/dist/lib/bmad-installer.d.ts +2 -27
  4. package/dist/lib/bmad-installer.js +3 -43
  5. package/dist/lib/claude-settings-types.d.ts +2 -1
  6. package/dist/lib/env-compat.d.ts +0 -8
  7. package/dist/lib/env-compat.js +0 -12
  8. package/dist/lib/git/index.d.ts +0 -1
  9. package/dist/lib/gitignore-manager.d.ts +0 -2
  10. package/dist/lib/gitignore-manager.js +1 -1
  11. package/dist/lib/hooks-merger.d.ts +1 -15
  12. package/dist/lib/hooks-merger.js +1 -1
  13. package/dist/lib/index.d.ts +3 -7
  14. package/dist/lib/index.js +3 -11
  15. package/dist/lib/output.d.ts +2 -1
  16. package/dist/lib/settings-hierarchy.d.ts +1 -13
  17. package/dist/lib/settings-hierarchy.js +1 -1
  18. package/dist/lib/template-installer.d.ts +5 -9
  19. package/dist/lib/template-installer.js +3 -13
  20. package/dist/lib/template-linter.d.ts +3 -10
  21. package/dist/lib/template-linter.js +2 -2
  22. package/dist/lib/template-resolver.d.ts +6 -0
  23. package/dist/lib/template-resolver.js +10 -0
  24. package/dist/lib/template-settings-reconstructor.d.ts +1 -1
  25. package/dist/lib/template-settings-reconstructor.js +17 -24
  26. package/dist/lib/terminal.d.ts +3 -14
  27. package/dist/lib/terminal.js +0 -4
  28. package/dist/lib/version.d.ts +2 -11
  29. package/dist/lib/version.js +3 -3
  30. package/dist/lib/windsurf-hooks-merger.d.ts +1 -15
  31. package/dist/lib/windsurf-hooks-merger.js +1 -1
  32. package/dist/templates/_shared/.codex/workflows/handoff.md +1 -1
  33. package/dist/templates/_shared/.windsurf/workflows/handoff.md +1 -1
  34. package/dist/templates/_shared/hooks-ts/session_end.ts +75 -4
  35. package/dist/templates/_shared/hooks-ts/session_start.ts +11 -13
  36. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +6 -8
  37. package/dist/templates/_shared/lib-ts/CLAUDE.md +56 -7
  38. package/dist/templates/_shared/lib-ts/base/hook-utils.ts +176 -29
  39. package/dist/templates/_shared/lib-ts/base/logger.ts +1 -1
  40. package/dist/templates/_shared/lib-ts/base/state-io.ts +11 -2
  41. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +181 -165
  42. package/dist/templates/_shared/lib-ts/context/plan-manager.ts +14 -13
  43. package/dist/templates/_shared/lib-ts/handoff/handoff-reader.ts +3 -2
  44. package/dist/templates/_shared/lib-ts/package.json +1 -2
  45. package/dist/templates/_shared/lib-ts/templates/plan-context.ts +27 -34
  46. package/dist/templates/_shared/lib-ts/types.ts +17 -2
  47. package/dist/templates/_shared/scripts/resume_handoff.ts +4 -4
  48. package/dist/templates/_shared/scripts/save_handoff.ts +7 -7
  49. package/dist/templates/_shared/scripts/status_line.ts +104 -71
  50. package/dist/templates/_shared/workflows/handoff.md +1 -1
  51. package/dist/templates/cc-native/.claude/settings.json +182 -175
  52. package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +23 -1
  53. package/dist/templates/cc-native/_cc-native/agents/plan-questions/PLAN-QUESTIONER.md +70 -0
  54. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +6 -1
  55. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +142 -111
  56. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +54 -0
  57. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +52 -0
  58. package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +53 -0
  59. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +19 -19
  60. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +6 -5
  61. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +114 -83
  62. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +107 -10
  63. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +1 -1
  64. package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +6 -2
  65. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +0 -4
  66. package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +40 -219
  67. package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +41 -0
  68. package/dist/templates/cc-native/_cc-native/lib-ts/plan-questions.ts +102 -0
  69. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +26 -227
  70. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/base/base-agent.ts +217 -0
  71. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +4 -2
  72. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/claude-agent.ts +65 -0
  73. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/codex-agent.ts +185 -0
  74. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/gemini-agent.ts +39 -0
  75. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/orchestrator-claude-agent.ts +195 -0
  76. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/schemas.ts +201 -0
  77. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +2 -2
  78. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +17 -16
  79. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +13 -108
  80. package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +3 -3
  81. package/dist/templates/cc-native/_cc-native/plan-review.config.json +2 -14
  82. package/oclif.manifest.json +1 -1
  83. package/package.json +1 -2
  84. package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.ts +0 -119
  85. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/codex.ts +0 -130
  86. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/gemini.ts +0 -107
  87. /package/dist/templates/cc-native/_cc-native/agents/{ARCH-EVOLUTION.md → plan-review/ARCH-EVOLUTION.md} +0 -0
  88. /package/dist/templates/cc-native/_cc-native/agents/{ARCH-PATTERNS.md → plan-review/ARCH-PATTERNS.md} +0 -0
  89. /package/dist/templates/cc-native/_cc-native/agents/{ARCH-STRUCTURE.md → plan-review/ARCH-STRUCTURE.md} +0 -0
  90. /package/dist/templates/cc-native/_cc-native/agents/{ASSUMPTION-TRACER.md → plan-review/ASSUMPTION-TRACER.md} +0 -0
  91. /package/dist/templates/cc-native/_cc-native/agents/{CLARITY-AUDITOR.md → plan-review/CLARITY-AUDITOR.md} +0 -0
  92. /package/dist/templates/cc-native/_cc-native/agents/{COMPLETENESS-FEASIBILITY.md → plan-review/COMPLETENESS-FEASIBILITY.md} +0 -0
  93. /package/dist/templates/cc-native/_cc-native/agents/{COMPLETENESS-GAPS.md → plan-review/COMPLETENESS-GAPS.md} +0 -0
  94. /package/dist/templates/cc-native/_cc-native/agents/{COMPLETENESS-ORDERING.md → plan-review/COMPLETENESS-ORDERING.md} +0 -0
  95. /package/dist/templates/cc-native/_cc-native/agents/{CONSTRAINT-VALIDATOR.md → plan-review/CONSTRAINT-VALIDATOR.md} +0 -0
  96. /package/dist/templates/cc-native/_cc-native/agents/{DESIGN-ADR-VALIDATOR.md → plan-review/DESIGN-ADR-VALIDATOR.md} +0 -0
  97. /package/dist/templates/cc-native/_cc-native/agents/{DESIGN-SCALE-MATCHER.md → plan-review/DESIGN-SCALE-MATCHER.md} +0 -0
  98. /package/dist/templates/cc-native/_cc-native/agents/{DEVILS-ADVOCATE.md → plan-review/DEVILS-ADVOCATE.md} +0 -0
  99. /package/dist/templates/cc-native/_cc-native/agents/{DOCUMENTATION-PHILOSOPHY.md → plan-review/DOCUMENTATION-PHILOSOPHY.md} +0 -0
  100. /package/dist/templates/cc-native/_cc-native/agents/{HANDOFF-READINESS.md → plan-review/HANDOFF-READINESS.md} +0 -0
  101. /package/dist/templates/cc-native/_cc-native/agents/{HIDDEN-COMPLEXITY.md → plan-review/HIDDEN-COMPLEXITY.md} +0 -0
  102. /package/dist/templates/cc-native/_cc-native/agents/{INCREMENTAL-DELIVERY.md → plan-review/INCREMENTAL-DELIVERY.md} +0 -0
  103. /package/dist/templates/cc-native/_cc-native/agents/{RISK-DEPENDENCY.md → plan-review/RISK-DEPENDENCY.md} +0 -0
  104. /package/dist/templates/cc-native/_cc-native/agents/{RISK-FMEA.md → plan-review/RISK-FMEA.md} +0 -0
  105. /package/dist/templates/cc-native/_cc-native/agents/{RISK-PREMORTEM.md → plan-review/RISK-PREMORTEM.md} +0 -0
  106. /package/dist/templates/cc-native/_cc-native/agents/{RISK-REVERSIBILITY.md → plan-review/RISK-REVERSIBILITY.md} +0 -0
  107. /package/dist/templates/cc-native/_cc-native/agents/{SCOPE-BOUNDARY.md → plan-review/SCOPE-BOUNDARY.md} +0 -0
  108. /package/dist/templates/cc-native/_cc-native/agents/{SIMPLICITY-GUARDIAN.md → plan-review/SIMPLICITY-GUARDIAN.md} +0 -0
  109. /package/dist/templates/cc-native/_cc-native/agents/{SKEPTIC.md → plan-review/SKEPTIC.md} +0 -0
  110. /package/dist/templates/cc-native/_cc-native/agents/{TESTDRIVEN-BEHAVIOR-AUDITOR.md → plan-review/TESTDRIVEN-BEHAVIOR-AUDITOR.md} +0 -0
  111. /package/dist/templates/cc-native/_cc-native/agents/{TESTDRIVEN-CHARACTERIZATION.md → plan-review/TESTDRIVEN-CHARACTERIZATION.md} +0 -0
  112. /package/dist/templates/cc-native/_cc-native/agents/{TESTDRIVEN-FIRST-VALIDATOR.md → plan-review/TESTDRIVEN-FIRST-VALIDATOR.md} +0 -0
  113. /package/dist/templates/cc-native/_cc-native/agents/{TESTDRIVEN-PYRAMID-ANALYZER.md → plan-review/TESTDRIVEN-PYRAMID-ANALYZER.md} +0 -0
  114. /package/dist/templates/cc-native/_cc-native/agents/{TRADEOFF-COSTS.md → plan-review/TRADEOFF-COSTS.md} +0 -0
  115. /package/dist/templates/cc-native/_cc-native/agents/{TRADEOFF-STAKEHOLDERS.md → plan-review/TRADEOFF-STAKEHOLDERS.md} +0 -0
  116. /package/dist/templates/cc-native/_cc-native/agents/{VERIFY-COVERAGE.md → plan-review/VERIFY-COVERAGE.md} +0 -0
  117. /package/dist/templates/cc-native/_cc-native/agents/{VERIFY-STRENGTH.md → plan-review/VERIFY-STRENGTH.md} +0 -0
@@ -1,67 +1,15 @@
1
1
  /**
2
2
  * Plan orchestrator — analyzes complexity and selects reviewer agents.
3
+ * Uses OrchestratorClaudeAgent (BaseCliAgent framework) for subprocess execution.
3
4
  * See cc-native-plan-review-spec.md §4.8
4
5
  */
5
6
 
6
- import { logDebug, logInfo, logWarn, logError } from "../../_shared/lib-ts/base/logger.js";
7
- import { getInternalSubprocessEnv, findExecutable, execFileAsync } from "../../_shared/lib-ts/base/subprocess-utils.js";
8
- import { parseCliOutput } from "./cli-output-parser.js";
9
- import type { AgentConfig, OrchestratorConfig, OrchestratorResult, ComplexityCategory } from "./types.js";
10
- import { ORCHESTRATOR_SCHEMA } from "./types.js";
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";
11
10
 
12
- // ---------------------------------------------------------------------------
13
- // Constants
14
- // ---------------------------------------------------------------------------
15
-
16
- const DEFAULT_AGENT_SELECTION: Record<string, unknown> = {
17
- simple: { min: 3, max: 3 },
18
- medium: { min: 8, max: 8 },
19
- high: { min: 12, max: 12 },
20
- fallbackCount: 3,
21
- };
22
-
23
- const DEFAULT_COMPLEXITY_CATEGORIES = [
24
- "code",
25
- "infrastructure",
26
- "documentation",
27
- "life",
28
- "business",
29
- "design",
30
- "research",
31
- ];
32
-
33
- // ---------------------------------------------------------------------------
34
- // Schema Builder
35
- // ---------------------------------------------------------------------------
36
-
37
- /**
38
- * Build orchestrator JSON schema with enum-constrained agent names.
39
- */
40
- export function buildOrchestratorSchema(
41
- validAgentNames: string[],
42
- categories: string[],
43
- ): Record<string, unknown> {
44
- const itemsSchema: Record<string, unknown> = { type: "string" };
45
- if (validAgentNames.length > 0) {
46
- itemsSchema.enum = validAgentNames;
47
- }
48
-
49
- return {
50
- type: "object",
51
- properties: {
52
- complexity: { type: "string", enum: ["simple", "medium", "high"] },
53
- category: { type: "string", enum: categories },
54
- selectedAgents: {
55
- type: "array",
56
- items: itemsSchema,
57
- },
58
- reasoning: { type: "string" },
59
- skipReason: { type: "string" },
60
- },
61
- required: ["complexity", "category", "selectedAgents", "reasoning"],
62
- additionalProperties: false,
63
- };
64
- }
11
+ // Re-export for backward compatibility (moved to reviewers/schemas.ts)
12
+ export { buildOrchestratorSchema } from "./reviewers/schemas.js";
65
13
 
66
14
  // ---------------------------------------------------------------------------
67
15
  // Orchestrator
@@ -81,170 +29,43 @@ export async function runOrchestrator(
81
29
  logInfo("orchestrator", "Starting plan analysis...");
82
30
 
83
31
  const mandatory = mandatoryNames ?? new Set<string>();
84
- const selection = (settings.agentSelection as Record<string, unknown>) ?? DEFAULT_AGENT_SELECTION;
85
- const categories = (settings.complexityCategories as string[]) ?? DEFAULT_COMPLEXITY_CATEGORIES;
86
- const fallbackCount = (selection.fallbackCount as number) ?? 2;
87
32
 
88
- // Filter out mandatory agents they always run
89
- const nonMandatory = agentLibrary.filter(
90
- (a) => a.enabled && !mandatory.has(a.name),
91
- );
92
- const validNames = nonMandatory.map((a) => a.name);
93
-
94
- logDebug("orchestrator", `Mandatory agents (always run): ${[...mandatory].sort().join(", ")}`);
95
- logDebug("orchestrator", `Non-mandatory agents for selection: ${validNames.join(", ")}`);
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
+ enabled: config.enabled,
40
+ categories: [],
41
+ description: "Plan orchestrator",
42
+ system_prompt: "",
43
+ };
96
44
 
97
- const claudePath = findExecutable("claude");
98
- if (!claudePath) {
99
- logWarn(
100
- "orchestrator",
101
- "Claude CLI not found on PATH, falling back to medium complexity",
45
+ try {
46
+ const agent = new OrchestratorClaudeAgent(
47
+ orchestratorAgent,
48
+ agentLibrary,
49
+ mandatory,
50
+ settings,
51
+ config.timeout,
102
52
  );
103
- return makeFallback(nonMandatory, fallbackCount, "Orchestrator skipped - Claude CLI not found", "claude CLI not found on PATH");
104
- }
105
-
106
- logDebug("orchestrator", `Found Claude CLI at: ${claudePath}`);
107
-
108
- // Build agent list from non-mandatory agents
109
- const agentList = nonMandatory
110
- .map(
111
- (a) =>
112
- `- ${a.name} [${a.categories.join(", ")}]\n Focus: ${a.focus}\n Expertise: ${a.description}`,
113
- )
114
- .join("\n");
115
- const categoryList = categories.join("/");
116
-
117
- // Compute additional agent counts
118
- const mandatoryCount = agentLibrary.filter((a) => mandatory.has(a.name)).length;
119
- const simpleAdditional = Math.max(0, ((selection.simple as Record<string, number> | undefined)?.max ?? 3) - mandatoryCount);
120
- const mediumAdditional = Math.max(0, ((selection.medium as Record<string, number> | undefined)?.max ?? 8) - mandatoryCount);
121
- const highAdditional = Math.max(0, ((selection.high as Record<string, number> | undefined)?.max ?? 12) - mandatoryCount);
122
-
123
- const systemPrompt = `You are a plan orchestrator for code review. Your job is to analyze plans and select appropriate reviewer agents.
124
-
125
- You MUST call StructuredOutput immediately with your analysis. Do NOT ask questions or use any other tools.
126
-
127
- When selecting agents:
128
- - Match agent expertise to plan requirements
129
- - Consider what each agent specializes in
130
- - Only select agents whose categories match the plan category
131
- - Fewer agents for simple plans, more for complex plans`;
132
-
133
- const prompt = `Analyze this plan and select appropriate reviewer agents.
134
-
135
- Available agents (select ONLY from this list):
136
- ${agentList}
137
-
138
- Selection rules (number of ADDITIONAL agents to select from the list above):
139
- - simple complexity = ${simpleAdditional} agents
140
- - medium complexity = ${mediumAdditional} agents
141
- - high complexity = ${highAdditional} agents
142
- - Only select agents whose categories match the plan category (${categoryList})
143
- - Non-technical plans (life, business) typically need 0 code-focused agents
144
- - Note: mandatory agents run separately and are NOT listed above
145
-
146
- PLAN:
147
- <<<
148
- ${plan}
149
- >>>
150
53
 
151
- Call StructuredOutput now with: complexity, category, selectedAgents, reasoning`;
152
-
153
- const schema =
154
- validNames.length > 0
155
- ? buildOrchestratorSchema(validNames, categories)
156
- : ORCHESTRATOR_SCHEMA;
157
- const schemaJson = JSON.stringify(schema);
158
-
159
- const cmdArgs = [
160
- "--model", config.model,
161
- "--output-format", "json",
162
- "--json-schema", schemaJson,
163
- "--max-turns", "3",
164
- "--setting-sources", "",
165
- "--system-prompt", systemPrompt,
166
- "-p",
167
- ];
168
-
169
- logInfo("orchestrator", `Running with model: ${config.model}, timeout: ${config.timeout}s`);
170
-
171
- const env = getInternalSubprocessEnv();
172
-
173
- const result = await execFileAsync(claudePath, cmdArgs, {
174
- input: prompt,
175
- timeout: config.timeout * 1000,
176
- env: env as Record<string, string>,
177
- maxBuffer: 10 * 1024 * 1024,
178
- shell: process.platform === "win32",
179
- });
180
-
181
- if (result.killed || result.signal === "SIGTERM") {
182
- logWarn("orchestrator", `TIMEOUT after ${config.timeout}s, falling back to medium complexity`);
183
- return makeFallback(nonMandatory, fallbackCount, "Orchestrator timed out - defaulting to medium complexity", `Orchestrator timed out after ${config.timeout}s`);
184
- }
185
-
186
- const raw = result.stdout.trim();
187
- if (result.stderr) logDebug("orchestrator", `stderr: ${result.stderr.slice(0, 300)}`);
188
-
189
- if (!raw && !result.stderr && result.exitCode !== 0) {
190
- logError("orchestrator", `Process exited with code ${result.exitCode}, falling back to medium complexity`);
191
- return makeFallback(nonMandatory, fallbackCount, `Orchestrator failed (exit ${result.exitCode})`, `Exit code ${result.exitCode}`);
192
- }
193
-
194
- const obj = parseCliOutput(raw);
195
-
196
- logDebug("orchestrator", `Raw output length: ${raw.length} chars`);
197
- if (raw) logDebug("orchestrator", `Raw output (first 500 chars): ${raw.slice(0, 500)}`);
198
- logDebug("orchestrator", `Parsed obj: ${JSON.stringify(obj)}`);
199
-
200
- if (!obj) {
201
- logWarn("orchestrator", "Failed to parse output, falling back to medium complexity");
202
- return makeFallback(nonMandatory, fallbackCount, "Orchestrator output could not be parsed", "Failed to parse orchestrator output");
54
+ const result = await agent.review(plan);
55
+
56
+ logInfo("orchestrator", `Result: complexity=${result.complexity}, category=${result.category}, agents=${JSON.stringify(result.selected_agents)}`);
57
+
58
+ return result;
59
+ } catch (error) {
60
+ logWarn("orchestrator", `Unexpected error: ${error}`);
61
+ const nonMandatory = agentLibrary.filter((a) => a.enabled && !mandatory.has(a.name));
62
+ const fallbackCount = ((settings.agentSelection as Record<string, unknown>)?.fallbackCount as number) ?? 2;
63
+ return {
64
+ complexity: "medium",
65
+ category: "code",
66
+ selected_agents: nonMandatory.slice(0, fallbackCount).map((a) => a.name),
67
+ reasoning: `Orchestrator failed: ${error}`,
68
+ error: String(error),
69
+ };
203
70
  }
204
-
205
- // Extract and validate fields
206
- const rawComplexity = String(obj.complexity ?? "medium");
207
- const complexity: ComplexityCategory =
208
- rawComplexity === "simple" || rawComplexity === "medium" || rawComplexity === "high"
209
- ? rawComplexity
210
- : "medium";
211
-
212
- let category = (obj.category as string) ?? "code";
213
- if (!categories.includes(category)) category = "code";
214
-
215
- let selectedAgents = obj.selectedAgents;
216
- if (!Array.isArray(selectedAgents)) selectedAgents = [];
217
-
218
- const reasoning = String(obj.reasoning ?? "").trim() || "No reasoning provided";
219
- const skipReason = obj.skipReason as string | undefined;
220
-
221
- logInfo("orchestrator", `Result: complexity=${complexity}, category=${category}, agents=${JSON.stringify(selectedAgents)}`);
222
- logDebug("orchestrator", `Reasoning: ${reasoning}`);
223
-
224
- return {
225
- complexity,
226
- category,
227
- selected_agents: selectedAgents as string[],
228
- reasoning,
229
- skip_reason: skipReason || undefined,
230
- };
231
- }
232
-
233
- // ---------------------------------------------------------------------------
234
- // Helpers
235
- // ---------------------------------------------------------------------------
236
-
237
- function makeFallback(
238
- nonMandatory: AgentConfig[],
239
- fallbackCount: number,
240
- reasoning: string,
241
- error: string,
242
- ): OrchestratorResult {
243
- return {
244
- complexity: "medium",
245
- category: "code",
246
- selected_agents: nonMandatory.slice(0, fallbackCount).map((a) => a.name),
247
- reasoning,
248
- error,
249
- };
250
71
  }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Plan quality guidance for context emission.
3
+ *
4
+ * Provides prompt text that guides the main agent to review plans before
5
+ * presenting them to the user. Emitted via emitContext() — NOT appended to plan files.
6
+ *
7
+ * Used by both SubagentStop hook (Plan agents) and PostToolUse:Write hook (direct writes).
8
+ */
9
+
10
+ /**
11
+ * Returns the plan quality review prompt to emit as context after a plan is written.
12
+ * This guides the main agent to review the plan before calling ExitPlanMode.
13
+ *
14
+ * Design principles:
15
+ * - No hardcoded skill names — agent discovers relevant skills from system-reminders
16
+ * - Documentation focuses on WHY (preserve decisions) not WHERE (file paths)
17
+ * - Concise — every token in emitted context costs attention budget
18
+ * - Trusts the agent's judgment — guidance, not mandate
19
+ */
20
+ export function getPlanQualityReviewContext(): string {
21
+ return `## Plan Quality Review
22
+
23
+ Before presenting this plan, review it from the perspective of an agent with zero conversation history.
24
+
25
+ ### Self-Check
26
+ - File paths are absolute and verified (not "the auth file" or "as discussed")
27
+ - Function and class names are exact references (not "the handler" or "it")
28
+ - Each step is specific enough to execute without this conversation's context
29
+ - Verification steps are binary-testable (pass/fail in one check)
30
+
31
+ ### Skills Integration
32
+ Review the skills listed in your system-reminder messages. Where a step would benefit from a specific skill, reference it inline (e.g., "Use \`SkillName\` skill for [specific purpose]"). Only reference skills relevant to this plan's domain.
33
+
34
+ ### Documentation Reasoning
35
+ Evaluate whether the plan captures decisions that would be lost when this session ends. The implementation agent should understand:
36
+ - What was decided and why alternatives were rejected
37
+ - What constraints exist that aren't obvious from the code
38
+ - What would break if assumptions change
39
+
40
+ If the plan has gaps, address them before presenting to the user.`;
41
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Plan question generation — runs a fresh-context agent to identify
3
+ * questions, assumptions, and ambiguities in a plan before review.
4
+ * See cc-native-plan-review.ts for integration point (questions gate).
5
+ */
6
+
7
+ import * as path from "node:path";
8
+
9
+ import { aggregateAgents } from "./aggregate-agents.js";
10
+ import { runAgentReview } from "./reviewers/index.js";
11
+ import { QUESTIONS_SCHEMA } from "./reviewers/schemas.js";
12
+ import type { AgentConfig, ModelsConfig } from "./types.js";
13
+ import { logInfo, logWarn, logError } from "../../_shared/lib-ts/base/logger.js";
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Types
17
+ // ---------------------------------------------------------------------------
18
+
19
+ export interface PlanQuestionsResult {
20
+ questions: string[];
21
+ assumptions: string[];
22
+ ambiguities: string[];
23
+ }
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Provider assignment (local copy — avoids circular import from hook)
27
+ // ---------------------------------------------------------------------------
28
+
29
+ import { findExecutable } from "../../_shared/lib-ts/base/subprocess-utils.js";
30
+
31
+ function assignProvider(agent: AgentConfig): AgentConfig {
32
+ // Default to claude provider with the agent's configured model
33
+ const found = findExecutable("claude");
34
+ if (found) {
35
+ return { ...agent, provider: "claude" };
36
+ }
37
+ logWarn("plan-questions", "Claude CLI not found, using agent defaults");
38
+ return agent;
39
+ }
40
+
41
+ // ---------------------------------------------------------------------------
42
+ // Main
43
+ // ---------------------------------------------------------------------------
44
+
45
+ const HOOK = "plan-questions";
46
+
47
+ /**
48
+ * Run the plan-questions agent to generate questions about a plan.
49
+ * Returns structured questions/assumptions/ambiguities, or null on failure.
50
+ *
51
+ * The agent runs in a fresh context (no codebase, no session history)
52
+ * and uses QUESTIONS_SCHEMA instead of REVIEW_SCHEMA — the agent runner
53
+ * is schema-agnostic.
54
+ */
55
+ export async function runPlanQuestions(
56
+ plan: string,
57
+ aiwcliDir: string,
58
+ timeout: number,
59
+ contextPath?: string,
60
+ sessionName?: string,
61
+ ): Promise<PlanQuestionsResult | null> {
62
+ // Load the plan-questions agent from agents/plan-questions/
63
+ const questionsAgentDir = path.join(aiwcliDir, "_cc-native", "agents", "plan-questions");
64
+ const agents = aggregateAgents(questionsAgentDir);
65
+
66
+ if (agents.length === 0) {
67
+ logWarn(HOOK, `No agents found in ${questionsAgentDir}`);
68
+ return null;
69
+ }
70
+
71
+ // Use the first agent (PLAN-QUESTIONER)
72
+ let agent = agents[0]!;
73
+ logInfo(HOOK, `Using plan-questions agent: ${agent.name}`);
74
+
75
+ // Assign provider
76
+ agent = assignProvider(agent);
77
+
78
+ // Run the agent with QUESTIONS_SCHEMA
79
+ const result = await runAgentReview(
80
+ plan,
81
+ agent,
82
+ QUESTIONS_SCHEMA,
83
+ timeout,
84
+ contextPath,
85
+ sessionName ?? "unknown",
86
+ );
87
+
88
+ if (!result.ok) {
89
+ logError(HOOK, `Plan-questions agent failed: ${result.err}`);
90
+ return null;
91
+ }
92
+
93
+ // Extract structured data
94
+ const data = result.data ?? {};
95
+ const questions = Array.isArray(data.questions) ? (data.questions as string[]) : [];
96
+ const assumptions = Array.isArray(data.assumptions) ? (data.assumptions as string[]) : [];
97
+ const ambiguities = Array.isArray(data.ambiguities) ? (data.ambiguities as string[]) : [];
98
+
99
+ logInfo(HOOK, `Plan-questions result: ${questions.length} questions, ${assumptions.length} assumptions, ${ambiguities.length} ambiguities`);
100
+
101
+ return { questions, assumptions, ambiguities };
102
+ }