@promptwheel/core 0.6.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 (169) hide show
  1. package/dist/codebase-index/index.d.ts +23 -0
  2. package/dist/codebase-index/index.d.ts.map +1 -0
  3. package/dist/codebase-index/index.js +361 -0
  4. package/dist/codebase-index/index.js.map +1 -0
  5. package/dist/codebase-index/shared.d.ts +95 -0
  6. package/dist/codebase-index/shared.d.ts.map +1 -0
  7. package/dist/codebase-index/shared.js +319 -0
  8. package/dist/codebase-index/shared.js.map +1 -0
  9. package/dist/config/defaults.d.ts +45 -0
  10. package/dist/config/defaults.d.ts.map +1 -0
  11. package/dist/config/defaults.js +79 -0
  12. package/dist/config/defaults.js.map +1 -0
  13. package/dist/critic/shared.d.ts +49 -0
  14. package/dist/critic/shared.d.ts.map +1 -0
  15. package/dist/critic/shared.js +204 -0
  16. package/dist/critic/shared.js.map +1 -0
  17. package/dist/db/adapter.d.ts +191 -0
  18. package/dist/db/adapter.d.ts.map +1 -0
  19. package/dist/db/adapter.js +40 -0
  20. package/dist/db/adapter.js.map +1 -0
  21. package/dist/db/contract.d.ts +47 -0
  22. package/dist/db/contract.d.ts.map +1 -0
  23. package/dist/db/contract.js +258 -0
  24. package/dist/db/contract.js.map +1 -0
  25. package/dist/db/index.d.ts +6 -0
  26. package/dist/db/index.d.ts.map +1 -0
  27. package/dist/db/index.js +7 -0
  28. package/dist/db/index.js.map +1 -0
  29. package/dist/dedup/shared.d.ts +82 -0
  30. package/dist/dedup/shared.d.ts.map +1 -0
  31. package/dist/dedup/shared.js +215 -0
  32. package/dist/dedup/shared.js.map +1 -0
  33. package/dist/exec/index.d.ts +5 -0
  34. package/dist/exec/index.d.ts.map +1 -0
  35. package/dist/exec/index.js +5 -0
  36. package/dist/exec/index.js.map +1 -0
  37. package/dist/exec/types.d.ts +64 -0
  38. package/dist/exec/types.d.ts.map +1 -0
  39. package/dist/exec/types.js +8 -0
  40. package/dist/exec/types.js.map +1 -0
  41. package/dist/formulas/shared.d.ts +42 -0
  42. package/dist/formulas/shared.d.ts.map +1 -0
  43. package/dist/formulas/shared.js +204 -0
  44. package/dist/formulas/shared.js.map +1 -0
  45. package/dist/guidelines/shared.d.ts +46 -0
  46. package/dist/guidelines/shared.d.ts.map +1 -0
  47. package/dist/guidelines/shared.js +128 -0
  48. package/dist/guidelines/shared.js.map +1 -0
  49. package/dist/index.d.ts +35 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +51 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/learnings/shared.d.ts +112 -0
  54. package/dist/learnings/shared.d.ts.map +1 -0
  55. package/dist/learnings/shared.js +402 -0
  56. package/dist/learnings/shared.js.map +1 -0
  57. package/dist/proposals/shared.d.ts +137 -0
  58. package/dist/proposals/shared.d.ts.map +1 -0
  59. package/dist/proposals/shared.js +254 -0
  60. package/dist/proposals/shared.js.map +1 -0
  61. package/dist/repos/index.d.ts +15 -0
  62. package/dist/repos/index.d.ts.map +1 -0
  63. package/dist/repos/index.js +11 -0
  64. package/dist/repos/index.js.map +1 -0
  65. package/dist/repos/projects.d.ts +41 -0
  66. package/dist/repos/projects.d.ts.map +1 -0
  67. package/dist/repos/projects.js +75 -0
  68. package/dist/repos/projects.js.map +1 -0
  69. package/dist/repos/run_steps.d.ts +152 -0
  70. package/dist/repos/run_steps.d.ts.map +1 -0
  71. package/dist/repos/run_steps.js +328 -0
  72. package/dist/repos/run_steps.js.map +1 -0
  73. package/dist/repos/runs.d.ts +92 -0
  74. package/dist/repos/runs.d.ts.map +1 -0
  75. package/dist/repos/runs.js +185 -0
  76. package/dist/repos/runs.js.map +1 -0
  77. package/dist/repos/tickets.d.ts +71 -0
  78. package/dist/repos/tickets.d.ts.map +1 -0
  79. package/dist/repos/tickets.js +158 -0
  80. package/dist/repos/tickets.js.map +1 -0
  81. package/dist/scope/shared.d.ts +67 -0
  82. package/dist/scope/shared.d.ts.map +1 -0
  83. package/dist/scope/shared.js +355 -0
  84. package/dist/scope/shared.js.map +1 -0
  85. package/dist/scout/index.d.ts +18 -0
  86. package/dist/scout/index.d.ts.map +1 -0
  87. package/dist/scout/index.js +445 -0
  88. package/dist/scout/index.js.map +1 -0
  89. package/dist/scout/kimi-runner.d.ts +21 -0
  90. package/dist/scout/kimi-runner.d.ts.map +1 -0
  91. package/dist/scout/kimi-runner.js +76 -0
  92. package/dist/scout/kimi-runner.js.map +1 -0
  93. package/dist/scout/mcp-batch-server.d.ts +37 -0
  94. package/dist/scout/mcp-batch-server.d.ts.map +1 -0
  95. package/dist/scout/mcp-batch-server.js +144 -0
  96. package/dist/scout/mcp-batch-server.js.map +1 -0
  97. package/dist/scout/openai-local-runner.d.ts +20 -0
  98. package/dist/scout/openai-local-runner.d.ts.map +1 -0
  99. package/dist/scout/openai-local-runner.js +82 -0
  100. package/dist/scout/openai-local-runner.js.map +1 -0
  101. package/dist/scout/prompt.d.ts +49 -0
  102. package/dist/scout/prompt.d.ts.map +1 -0
  103. package/dist/scout/prompt.js +153 -0
  104. package/dist/scout/prompt.js.map +1 -0
  105. package/dist/scout/runner.d.ts +101 -0
  106. package/dist/scout/runner.d.ts.map +1 -0
  107. package/dist/scout/runner.js +521 -0
  108. package/dist/scout/runner.js.map +1 -0
  109. package/dist/scout/scanner.d.ts +61 -0
  110. package/dist/scout/scanner.d.ts.map +1 -0
  111. package/dist/scout/scanner.js +315 -0
  112. package/dist/scout/scanner.js.map +1 -0
  113. package/dist/scout/types.d.ts +221 -0
  114. package/dist/scout/types.d.ts.map +1 -0
  115. package/dist/scout/types.js +44 -0
  116. package/dist/scout/types.js.map +1 -0
  117. package/dist/sectors/shared.d.ts +146 -0
  118. package/dist/sectors/shared.d.ts.map +1 -0
  119. package/dist/sectors/shared.js +408 -0
  120. package/dist/sectors/shared.js.map +1 -0
  121. package/dist/services/index.d.ts +10 -0
  122. package/dist/services/index.d.ts.map +1 -0
  123. package/dist/services/index.js +9 -0
  124. package/dist/services/index.js.map +1 -0
  125. package/dist/services/qa.d.ts +76 -0
  126. package/dist/services/qa.d.ts.map +1 -0
  127. package/dist/services/qa.js +228 -0
  128. package/dist/services/qa.js.map +1 -0
  129. package/dist/services/scout.d.ts +164 -0
  130. package/dist/services/scout.d.ts.map +1 -0
  131. package/dist/services/scout.js +215 -0
  132. package/dist/services/scout.js.map +1 -0
  133. package/dist/spindle/shared.d.ts +14 -0
  134. package/dist/spindle/shared.d.ts.map +1 -0
  135. package/dist/spindle/shared.js +65 -0
  136. package/dist/spindle/shared.js.map +1 -0
  137. package/dist/tools/shared.d.ts +35 -0
  138. package/dist/tools/shared.d.ts.map +1 -0
  139. package/dist/tools/shared.js +247 -0
  140. package/dist/tools/shared.js.map +1 -0
  141. package/dist/trace/shared.d.ts +147 -0
  142. package/dist/trace/shared.d.ts.map +1 -0
  143. package/dist/trace/shared.js +414 -0
  144. package/dist/trace/shared.js.map +1 -0
  145. package/dist/trajectory/shared.d.ts +69 -0
  146. package/dist/trajectory/shared.d.ts.map +1 -0
  147. package/dist/trajectory/shared.js +336 -0
  148. package/dist/trajectory/shared.js.map +1 -0
  149. package/dist/utils/id.d.ts +12 -0
  150. package/dist/utils/id.d.ts.map +1 -0
  151. package/dist/utils/id.js +24 -0
  152. package/dist/utils/id.js.map +1 -0
  153. package/dist/utils/id.test.d.ts +5 -0
  154. package/dist/utils/id.test.d.ts.map +1 -0
  155. package/dist/utils/id.test.js +173 -0
  156. package/dist/utils/id.test.js.map +1 -0
  157. package/dist/utils/index.d.ts +6 -0
  158. package/dist/utils/index.d.ts.map +1 -0
  159. package/dist/utils/index.js +6 -0
  160. package/dist/utils/index.js.map +1 -0
  161. package/dist/utils/json.d.ts +9 -0
  162. package/dist/utils/json.d.ts.map +1 -0
  163. package/dist/utils/json.js +19 -0
  164. package/dist/utils/json.js.map +1 -0
  165. package/dist/waves/shared.d.ts +106 -0
  166. package/dist/waves/shared.d.ts.map +1 -0
  167. package/dist/waves/shared.js +356 -0
  168. package/dist/waves/shared.js.map +1 -0
  169. package/package.json +126 -0
@@ -0,0 +1,521 @@
1
+ /**
2
+ * Scout runner - Executes LLM CLI backends for analysis
3
+ */
4
+ import { spawn } from 'node:child_process';
5
+ import { writeFileSync, readFileSync, mkdtempSync, rmSync } from 'node:fs';
6
+ import { tmpdir } from 'node:os';
7
+ import { join } from 'node:path';
8
+ /**
9
+ * Run Claude Code CLI with a prompt
10
+ */
11
+ export async function runClaude(options) {
12
+ const { prompt, cwd, timeoutMs, model = 'opus', signal } = options;
13
+ const start = Date.now();
14
+ return new Promise((resolve) => {
15
+ // Check if already aborted
16
+ if (signal?.aborted) {
17
+ resolve({
18
+ success: false,
19
+ output: '',
20
+ error: 'Aborted before start',
21
+ durationMs: Date.now() - start,
22
+ });
23
+ return;
24
+ }
25
+ const args = [
26
+ '-p', // Prompt will be sent via stdin to avoid arg length limits
27
+ '--model', model,
28
+ '--output-format', 'text',
29
+ '--allowedTools', '', // Disable tools - content provided in prompt
30
+ ];
31
+ const proc = spawn('claude', args, {
32
+ cwd,
33
+ env: {
34
+ ...process.env,
35
+ CLAUDE_CODE_NON_INTERACTIVE: '1',
36
+ },
37
+ stdio: ['pipe', 'pipe', 'pipe'],
38
+ });
39
+ // Send prompt via stdin to avoid OS arg length limits (MAX_ARG_STRLEN ~128KB on Linux)
40
+ proc.stdin.write(prompt);
41
+ proc.stdin.end();
42
+ let stdout = '';
43
+ let stderr = '';
44
+ let killed = false;
45
+ // Timeout handler
46
+ const timeout = setTimeout(() => {
47
+ killed = true;
48
+ proc.kill('SIGTERM');
49
+ // Grace period before SIGKILL
50
+ setTimeout(() => proc.kill('SIGKILL'), 5000);
51
+ }, timeoutMs);
52
+ // Abort signal handler
53
+ const abortHandler = () => {
54
+ killed = true;
55
+ proc.kill('SIGTERM');
56
+ };
57
+ signal?.addEventListener('abort', abortHandler);
58
+ proc.stdout.on('data', (data) => {
59
+ stdout += data.toString();
60
+ });
61
+ proc.stderr.on('data', (data) => {
62
+ stderr += data.toString();
63
+ });
64
+ proc.on('close', (code) => {
65
+ clearTimeout(timeout);
66
+ signal?.removeEventListener('abort', abortHandler);
67
+ const durationMs = Date.now() - start;
68
+ if (killed) {
69
+ resolve({
70
+ success: false,
71
+ output: stdout,
72
+ error: signal?.aborted ? 'Aborted by signal' : 'Timeout exceeded',
73
+ durationMs,
74
+ });
75
+ return;
76
+ }
77
+ if (code !== 0) {
78
+ resolve({
79
+ success: false,
80
+ output: stdout,
81
+ error: stderr || `Process exited with code ${code}`,
82
+ durationMs,
83
+ });
84
+ return;
85
+ }
86
+ resolve({
87
+ success: true,
88
+ output: stdout,
89
+ durationMs,
90
+ });
91
+ });
92
+ proc.on('error', (err) => {
93
+ clearTimeout(timeout);
94
+ signal?.removeEventListener('abort', abortHandler);
95
+ resolve({
96
+ success: false,
97
+ output: '',
98
+ error: err.message,
99
+ durationMs: Date.now() - start,
100
+ });
101
+ });
102
+ });
103
+ }
104
+ /**
105
+ * Claude Code CLI scout backend (default)
106
+ */
107
+ export class ClaudeScoutBackend {
108
+ name = 'claude';
109
+ run(options) {
110
+ return runClaude(options);
111
+ }
112
+ }
113
+ /**
114
+ * Codex CLI scout backend
115
+ *
116
+ * Spawns `codex exec` in read-only sandbox mode for analysis.
117
+ * Uses --output-last-message for reliable output extraction.
118
+ */
119
+ export class CodexScoutBackend {
120
+ name = 'codex';
121
+ apiKey;
122
+ defaultModel;
123
+ constructor(opts) {
124
+ this.apiKey = opts?.apiKey;
125
+ this.defaultModel = opts?.model ?? 'gpt-5.3-codex';
126
+ }
127
+ async run(options) {
128
+ const { prompt, cwd, timeoutMs, model, signal, onRawOutput } = options;
129
+ const start = Date.now();
130
+ if (signal?.aborted) {
131
+ return { success: false, output: '', error: 'Aborted before start', durationMs: 0 };
132
+ }
133
+ const tmpDir = mkdtempSync(join(tmpdir(), 'promptwheel-codex-'));
134
+ const outPath = join(tmpDir, 'output.md');
135
+ const schemaPath = join(tmpDir, 'schema.json');
136
+ // Write JSON schema so Codex returns structured output
137
+ // OpenAI requires additionalProperties: false on every object
138
+ writeFileSync(schemaPath, JSON.stringify({
139
+ type: 'object',
140
+ properties: {
141
+ proposals: {
142
+ type: 'array',
143
+ items: {
144
+ type: 'object',
145
+ properties: {
146
+ category: { type: 'string' },
147
+ title: { type: 'string' },
148
+ description: { type: 'string' },
149
+ acceptance_criteria: { type: 'array', items: { type: 'string' } },
150
+ verification_commands: { type: 'array', items: { type: 'string' } },
151
+ allowed_paths: { type: 'array', items: { type: 'string' } },
152
+ files: { type: 'array', items: { type: 'string' } },
153
+ confidence: { type: 'number' },
154
+ impact_score: { type: 'number' },
155
+ rationale: { type: 'string' },
156
+ estimated_complexity: { type: 'string' },
157
+ },
158
+ required: ['category', 'title', 'description', 'confidence', 'impact_score', 'files',
159
+ 'acceptance_criteria', 'verification_commands', 'allowed_paths', 'rationale', 'estimated_complexity'],
160
+ additionalProperties: false,
161
+ },
162
+ },
163
+ },
164
+ required: ['proposals'],
165
+ additionalProperties: false,
166
+ }));
167
+ try {
168
+ const effectiveModel = model ?? this.defaultModel;
169
+ const args = [
170
+ 'exec',
171
+ '--json',
172
+ '--sandbox', 'read-only',
173
+ '--output-last-message', outPath,
174
+ '--output-schema', schemaPath,
175
+ '--model', effectiveModel,
176
+ '--cd', cwd,
177
+ '-',
178
+ ];
179
+ const env = { ...process.env };
180
+ if (this.apiKey) {
181
+ env.OPENAI_API_KEY = this.apiKey;
182
+ }
183
+ return await new Promise((resolve) => {
184
+ const proc = spawn('codex', args, {
185
+ cwd,
186
+ env,
187
+ stdio: ['pipe', 'pipe', 'pipe'],
188
+ });
189
+ // Send prompt via stdin
190
+ proc.stdin.write(prompt);
191
+ proc.stdin.end();
192
+ let stdout = '';
193
+ let stderr = '';
194
+ let killed = false;
195
+ const timeout = timeoutMs > 0 ? setTimeout(() => {
196
+ killed = true;
197
+ proc.kill('SIGTERM');
198
+ setTimeout(() => proc.kill('SIGKILL'), 5000);
199
+ }, timeoutMs) : null;
200
+ const abortHandler = () => { killed = true; proc.kill('SIGTERM'); };
201
+ signal?.addEventListener('abort', abortHandler);
202
+ proc.stdout.on('data', (d) => {
203
+ const text = d.toString();
204
+ stdout += text;
205
+ onRawOutput?.(text);
206
+ });
207
+ proc.stderr.on('data', (d) => {
208
+ const text = d.toString();
209
+ stderr += text;
210
+ onRawOutput?.(`[stderr] ${text}`);
211
+ });
212
+ proc.on('close', (code) => {
213
+ if (timeout)
214
+ clearTimeout(timeout);
215
+ signal?.removeEventListener('abort', abortHandler);
216
+ const durationMs = Date.now() - start;
217
+ if (killed) {
218
+ resolve({ success: false, output: stdout, error: signal?.aborted ? 'Aborted by signal' : 'Timeout exceeded', durationMs });
219
+ return;
220
+ }
221
+ // Prefer --output-last-message file over stdout (stdout is JSONL telemetry)
222
+ let output = stdout;
223
+ try {
224
+ output = readFileSync(outPath, 'utf-8');
225
+ }
226
+ catch {
227
+ // Fall back to stdout if file wasn't written
228
+ }
229
+ if (code !== 0) {
230
+ resolve({ success: false, output, error: stderr || `codex exited with code ${code}`, durationMs });
231
+ return;
232
+ }
233
+ resolve({ success: true, output, durationMs });
234
+ });
235
+ proc.on('error', (err) => {
236
+ if (timeout)
237
+ clearTimeout(timeout);
238
+ signal?.removeEventListener('abort', abortHandler);
239
+ resolve({ success: false, output: '', error: err.message, durationMs: Date.now() - start });
240
+ });
241
+ });
242
+ }
243
+ finally {
244
+ try {
245
+ rmSync(tmpDir, { recursive: true, force: true });
246
+ }
247
+ catch { /* best-effort cleanup */ }
248
+ }
249
+ }
250
+ }
251
+ /**
252
+ * Codex MCP scout backend — persistent single session
253
+ *
254
+ * Instead of spawning N cold `codex exec` processes, spawns ONE session
255
+ * that connects to our MCP batch server. Codex calls tools in a loop
256
+ * to pull batches and submit results. One warm session, zero cold starts.
257
+ *
258
+ * Opt-in via --codex-mcp flag.
259
+ */
260
+ export class CodexMcpScoutBackend {
261
+ name = 'codex';
262
+ apiKey;
263
+ defaultModel;
264
+ constructor(opts) {
265
+ this.apiKey = opts?.apiKey;
266
+ this.defaultModel = opts?.model ?? 'gpt-5.3-codex';
267
+ }
268
+ /** Single-batch fallback (not normally used — runAll is preferred) */
269
+ async run(options) {
270
+ // Delegate to the regular CodexScoutBackend for single-batch
271
+ const backend = new CodexScoutBackend({ apiKey: this.apiKey, model: this.defaultModel });
272
+ return backend.run(options);
273
+ }
274
+ /**
275
+ * Process all batches in a single persistent Codex session via MCP.
276
+ *
277
+ * 1. Writes batch prompts to a temp JSON file
278
+ * 2. Spawns `codex exec` with MCP config pointing to our batch server
279
+ * 3. Codex loops over get_next_batch → analyze → submit_results
280
+ * 4. Collects results when signal_done fires
281
+ */
282
+ async runAll(allOptions) {
283
+ const start = Date.now();
284
+ const cwd = allOptions[0]?.cwd ?? process.cwd();
285
+ const model = allOptions[0]?.model ?? this.defaultModel;
286
+ const signal = allOptions[0]?.signal;
287
+ const timeoutMs = Math.max(...allOptions.map(o => o.timeoutMs)) * allOptions.length;
288
+ if (signal?.aborted) {
289
+ return allOptions.map(() => ({ success: false, output: '', error: 'Aborted before start', durationMs: 0 }));
290
+ }
291
+ const prompts = allOptions.map(o => o.prompt);
292
+ const tmpDir = mkdtempSync(join(tmpdir(), 'promptwheel-mcp-'));
293
+ const dataPath = join(tmpDir, 'batches.json');
294
+ const outPath = join(tmpDir, 'output.md');
295
+ writeFileSync(dataPath, JSON.stringify(prompts));
296
+ // Resolve path to the MCP batch server entrypoint
297
+ // In production: dist/scout/mcp-batch-server.js
298
+ // We use import.meta.url to find our own location
299
+ const selfUrl = import.meta?.url;
300
+ let serverScript;
301
+ if (selfUrl) {
302
+ const { fileURLToPath } = await import('node:url');
303
+ const selfPath = fileURLToPath(selfUrl);
304
+ const dir = selfPath.substring(0, selfPath.lastIndexOf('/'));
305
+ serverScript = join(dir, 'mcp-batch-server.js');
306
+ }
307
+ else {
308
+ serverScript = join(process.cwd(), 'node_modules', '@promptwheel', 'core', 'dist', 'scout', 'mcp-batch-server.js');
309
+ }
310
+ // Build MCP config for codex exec
311
+ const mcpConfig = {
312
+ mcpServers: {
313
+ 'batch-server': {
314
+ command: 'node',
315
+ args: [serverScript, '--data', dataPath, '--results-dir', tmpDir],
316
+ },
317
+ },
318
+ };
319
+ const mcpConfigPath = join(tmpDir, 'mcp-config.json');
320
+ writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig));
321
+ const systemPrompt = `You have access to a batch analysis MCP server with three tools: get_next_batch, submit_results, and signal_done.
322
+
323
+ Your job:
324
+ 1. Call get_next_batch() to get a batch of code files to analyze
325
+ 2. Read the prompt carefully and analyze the code
326
+ 3. Generate proposals as a JSON object with a "proposals" array
327
+ 4. Call submit_results({ batchId: <id>, output: <your JSON string> })
328
+ 5. Repeat steps 1-4 until get_next_batch() returns { done: true }
329
+ 6. Call signal_done() to confirm completion
330
+
331
+ IMPORTANT: Each batch prompt contains code files and instructions. Follow the instructions exactly.
332
+ Return your analysis as a JSON string in the output field of submit_results.`;
333
+ try {
334
+ const args = [
335
+ 'exec',
336
+ '--sandbox', 'read-only',
337
+ '--output-last-message', outPath,
338
+ '--model', model,
339
+ '--cd', cwd,
340
+ '-c', mcpConfigPath,
341
+ '-',
342
+ ];
343
+ const env = { ...process.env };
344
+ if (this.apiKey) {
345
+ env.OPENAI_API_KEY = this.apiKey;
346
+ }
347
+ const result = await new Promise((resolve) => {
348
+ const proc = spawn('codex', args, {
349
+ cwd,
350
+ env,
351
+ stdio: ['pipe', 'pipe', 'pipe'],
352
+ });
353
+ proc.stdin.write(systemPrompt);
354
+ proc.stdin.end();
355
+ let stdout = '';
356
+ let stderr = '';
357
+ let killed = false;
358
+ const timeout = setTimeout(() => {
359
+ killed = true;
360
+ proc.kill('SIGTERM');
361
+ setTimeout(() => proc.kill('SIGKILL'), 5000);
362
+ }, timeoutMs);
363
+ const abortHandler = () => { killed = true; proc.kill('SIGTERM'); };
364
+ signal?.addEventListener('abort', abortHandler);
365
+ proc.stdout.on('data', (d) => { stdout += d.toString(); });
366
+ proc.stderr.on('data', (d) => { stderr += d.toString(); });
367
+ proc.on('close', (code) => {
368
+ clearTimeout(timeout);
369
+ signal?.removeEventListener('abort', abortHandler);
370
+ if (killed) {
371
+ resolve({ success: false, output: stdout, error: signal?.aborted ? 'Aborted by signal' : 'Timeout exceeded' });
372
+ return;
373
+ }
374
+ // Read the batch server's collected results from the data temp dir
375
+ // The MCP server writes results as side-effect; we read them via the output file
376
+ let output = stdout;
377
+ try {
378
+ output = readFileSync(outPath, 'utf-8');
379
+ }
380
+ catch {
381
+ // Fall back to stdout
382
+ }
383
+ if (code !== 0) {
384
+ resolve({ success: false, output, error: stderr || `codex exited with code ${code}` });
385
+ return;
386
+ }
387
+ resolve({ success: true, output });
388
+ });
389
+ proc.on('error', (err) => {
390
+ clearTimeout(timeout);
391
+ signal?.removeEventListener('abort', abortHandler);
392
+ resolve({ success: false, output: '', error: err.message });
393
+ });
394
+ });
395
+ const durationMs = Date.now() - start;
396
+ if (!result.success) {
397
+ return allOptions.map(() => ({
398
+ success: false,
399
+ output: result.output,
400
+ error: result.error,
401
+ durationMs,
402
+ }));
403
+ }
404
+ // Parse collected results from the MCP server
405
+ // The server stores results in a Map<batchId, output>
406
+ // We need to reconstruct from what Codex submitted
407
+ // Since the MCP server runs in-process with Codex (via stdio),
408
+ // we parse the output looking for per-batch JSON results
409
+ //
410
+ // Strategy: try to split the output by batch, or treat entire output
411
+ // as a single result and distribute
412
+ const results = [];
413
+ // Try reading a results file that the MCP server may have written
414
+ const resultsPath = join(tmpDir, 'results.json');
415
+ let batchResults = null;
416
+ try {
417
+ const raw = readFileSync(resultsPath, 'utf-8');
418
+ const parsed = JSON.parse(raw);
419
+ batchResults = new Map(Object.entries(parsed).map(([k, v]) => [parseInt(k, 10), v]));
420
+ }
421
+ catch {
422
+ // Results file not available — Codex submitted via MCP tools
423
+ // We need to extract from the Codex output
424
+ }
425
+ if (batchResults && batchResults.size > 0) {
426
+ for (let i = 0; i < allOptions.length; i++) {
427
+ const batchOutput = batchResults.get(i);
428
+ results.push({
429
+ success: !!batchOutput,
430
+ output: batchOutput ?? '',
431
+ error: batchOutput ? undefined : 'No result for batch',
432
+ durationMs: Math.round(durationMs / allOptions.length),
433
+ });
434
+ }
435
+ }
436
+ else {
437
+ // Fallback: return the entire output as a single result for batch 0,
438
+ // empty results for the rest. The caller will parse what it can.
439
+ for (let i = 0; i < allOptions.length; i++) {
440
+ results.push({
441
+ success: i === 0 && result.success,
442
+ output: i === 0 ? result.output : '',
443
+ error: i === 0 ? undefined : 'Batch not processed (MCP session may have ended early)',
444
+ durationMs: Math.round(durationMs / allOptions.length),
445
+ });
446
+ }
447
+ }
448
+ return results;
449
+ }
450
+ finally {
451
+ try {
452
+ rmSync(tmpDir, { recursive: true, force: true });
453
+ }
454
+ catch { /* best-effort */ }
455
+ }
456
+ }
457
+ }
458
+ /**
459
+ * Parse JSON from Claude's output
460
+ *
461
+ * Handles common issues like markdown code blocks
462
+ */
463
+ export function parseClaudeOutput(output) {
464
+ // Try direct parse first
465
+ try {
466
+ return JSON.parse(output.trim());
467
+ }
468
+ catch {
469
+ // Ignore and try other methods
470
+ }
471
+ // Try extracting from markdown code block
472
+ const jsonMatch = output.match(/```(?:json)?\s*([\s\S]*?)```/);
473
+ if (jsonMatch) {
474
+ try {
475
+ return JSON.parse(jsonMatch[1].trim());
476
+ }
477
+ catch {
478
+ // Ignore
479
+ }
480
+ }
481
+ // Try finding JSON object by balanced-brace matching
482
+ // Walk from each '{' and count braces to find the complete object,
483
+ // skipping braces inside string literals.
484
+ for (let start = output.indexOf('{'); start !== -1; start = output.indexOf('{', start + 1)) {
485
+ let depth = 0;
486
+ let inString = false;
487
+ let escape = false;
488
+ for (let i = start; i < output.length; i++) {
489
+ const ch = output[i];
490
+ if (escape) {
491
+ escape = false;
492
+ continue;
493
+ }
494
+ if (ch === '\\' && inString) {
495
+ escape = true;
496
+ continue;
497
+ }
498
+ if (ch === '"') {
499
+ inString = !inString;
500
+ continue;
501
+ }
502
+ if (inString)
503
+ continue;
504
+ if (ch === '{')
505
+ depth++;
506
+ else if (ch === '}') {
507
+ depth--;
508
+ if (depth === 0) {
509
+ try {
510
+ return JSON.parse(output.slice(start, i + 1));
511
+ }
512
+ catch {
513
+ break; // This '{' didn't yield valid JSON, try the next one
514
+ }
515
+ }
516
+ }
517
+ }
518
+ }
519
+ return null;
520
+ }
521
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/scout/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * File scanner - Discovers and reads files for analysis
3
+ */
4
+ /**
5
+ * File info with content
6
+ */
7
+ export interface ScannedFile {
8
+ path: string;
9
+ content: string;
10
+ size: number;
11
+ }
12
+ /**
13
+ * Options for file scanning
14
+ */
15
+ export interface ScanOptions {
16
+ /** Base directory */
17
+ cwd: string;
18
+ /** Glob-like patterns to include */
19
+ include: string[];
20
+ /** Glob-like patterns to exclude */
21
+ exclude?: string[];
22
+ /** Maximum file size in bytes (default: 100KB) */
23
+ maxFileSize?: number;
24
+ /** Maximum total files (default: 500) */
25
+ maxFiles?: number;
26
+ }
27
+ /**
28
+ * Scan a directory for files matching the given patterns
29
+ */
30
+ export declare function scanFiles(options: ScanOptions): ScannedFile[];
31
+ /**
32
+ * Group files into batches for processing
33
+ */
34
+ export declare function batchFiles(files: ScannedFile[], batchSize?: number): ScannedFile[][];
35
+ /**
36
+ * Estimate token count for a string (~4 chars per token)
37
+ */
38
+ export declare function estimateTokens(content: string): number;
39
+ /**
40
+ * Group files into batches by token budget instead of fixed count.
41
+ * Packs small files together; oversized files get their own batch.
42
+ */
43
+ export declare function batchFilesByTokens(files: ScannedFile[], maxTokensPerBatch?: number): ScannedFile[][];
44
+ /**
45
+ * Module group definition for dependency-aware batching.
46
+ */
47
+ export interface ModuleGroup {
48
+ /** Module directory path (e.g., "src/services") */
49
+ path: string;
50
+ /** Paths of modules this one imports from */
51
+ dependencies?: string[];
52
+ }
53
+ /**
54
+ * Group files into batches by module boundaries, keeping related files together.
55
+ *
56
+ * Files are first assigned to their module (by longest matching directory prefix).
57
+ * Modules + their dependencies are packed into the same batch when they fit the token budget.
58
+ * Orphan files (not matching any module) are batched together at the end.
59
+ */
60
+ export declare function batchFilesByModule(files: ScannedFile[], modules: ModuleGroup[], maxTokensPerBatch?: number): ScannedFile[][];
61
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/scout/scanner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAsKD;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,EAAE,CAI7D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,SAAS,GAAE,MAAU,GAAG,WAAW,EAAE,EAAE,CAQvF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAAE,EACpB,iBAAiB,GAAE,MAAc,GAChC,WAAW,EAAE,EAAE,CA2BjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,EAAE,WAAW,EAAE,EACtB,iBAAiB,GAAE,MAAc,GAChC,WAAW,EAAE,EAAE,CAiHjB"}