@blockspool/core 0.3.2 → 0.4.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 (93) hide show
  1. package/dist/db/adapter.d.ts +191 -0
  2. package/dist/db/adapter.d.ts.map +1 -0
  3. package/dist/db/adapter.js +40 -0
  4. package/dist/db/adapter.js.map +1 -0
  5. package/dist/db/contract.d.ts +47 -0
  6. package/dist/db/contract.d.ts.map +1 -0
  7. package/dist/db/contract.js +258 -0
  8. package/dist/db/contract.js.map +1 -0
  9. package/dist/db/index.d.ts +6 -0
  10. package/dist/db/index.d.ts.map +1 -0
  11. package/dist/db/index.js +7 -0
  12. package/dist/db/index.js.map +1 -0
  13. package/dist/exec/index.d.ts +5 -0
  14. package/dist/exec/index.d.ts.map +1 -0
  15. package/dist/exec/index.js +5 -0
  16. package/dist/exec/index.js.map +1 -0
  17. package/dist/exec/types.d.ts +64 -0
  18. package/dist/exec/types.d.ts.map +1 -0
  19. package/dist/exec/types.js +8 -0
  20. package/dist/exec/types.js.map +1 -0
  21. package/dist/index.d.ts +23 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +27 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/repos/index.d.ts +15 -0
  26. package/dist/repos/index.d.ts.map +1 -0
  27. package/dist/repos/index.js +11 -0
  28. package/dist/repos/index.js.map +1 -0
  29. package/dist/repos/projects.d.ts +41 -0
  30. package/dist/repos/projects.d.ts.map +1 -0
  31. package/dist/repos/projects.js +74 -0
  32. package/dist/repos/projects.js.map +1 -0
  33. package/dist/repos/run_steps.d.ts +152 -0
  34. package/dist/repos/run_steps.d.ts.map +1 -0
  35. package/dist/repos/run_steps.js +321 -0
  36. package/dist/repos/run_steps.js.map +1 -0
  37. package/dist/repos/runs.d.ts +92 -0
  38. package/dist/repos/runs.d.ts.map +1 -0
  39. package/dist/repos/runs.js +177 -0
  40. package/dist/repos/runs.js.map +1 -0
  41. package/dist/repos/tickets.d.ts +71 -0
  42. package/dist/repos/tickets.d.ts.map +1 -0
  43. package/dist/repos/tickets.js +128 -0
  44. package/dist/repos/tickets.js.map +1 -0
  45. package/dist/scout/index.d.ts +15 -0
  46. package/dist/scout/index.d.ts.map +1 -0
  47. package/dist/scout/index.js +383 -0
  48. package/dist/scout/index.js.map +1 -0
  49. package/dist/scout/prompt.d.ts +32 -0
  50. package/dist/scout/prompt.d.ts.map +1 -0
  51. package/dist/scout/prompt.js +104 -0
  52. package/dist/scout/prompt.js.map +1 -0
  53. package/dist/scout/runner.d.ts +68 -0
  54. package/dist/scout/runner.d.ts.map +1 -0
  55. package/dist/scout/runner.js +270 -0
  56. package/dist/scout/runner.js.map +1 -0
  57. package/dist/scout/scanner.d.ts +35 -0
  58. package/dist/scout/scanner.d.ts.map +1 -0
  59. package/dist/scout/scanner.js +164 -0
  60. package/dist/scout/scanner.js.map +1 -0
  61. package/dist/scout/types.d.ts +179 -0
  62. package/dist/scout/types.d.ts.map +1 -0
  63. package/dist/scout/types.js +44 -0
  64. package/dist/scout/types.js.map +1 -0
  65. package/dist/services/index.d.ts +10 -0
  66. package/dist/services/index.d.ts.map +1 -0
  67. package/dist/services/index.js +9 -0
  68. package/dist/services/index.js.map +1 -0
  69. package/dist/services/qa.d.ts +76 -0
  70. package/dist/services/qa.d.ts.map +1 -0
  71. package/dist/services/qa.js +239 -0
  72. package/dist/services/qa.js.map +1 -0
  73. package/dist/services/scout.d.ts +120 -0
  74. package/dist/services/scout.d.ts.map +1 -0
  75. package/dist/services/scout.js +205 -0
  76. package/dist/services/scout.js.map +1 -0
  77. package/dist/utils/id.d.ts +12 -0
  78. package/dist/utils/id.d.ts.map +1 -0
  79. package/dist/utils/id.js +24 -0
  80. package/dist/utils/id.js.map +1 -0
  81. package/dist/utils/id.test.d.ts +5 -0
  82. package/dist/utils/id.test.d.ts.map +1 -0
  83. package/dist/utils/id.test.js +173 -0
  84. package/dist/utils/id.test.js.map +1 -0
  85. package/dist/utils/index.d.ts +6 -0
  86. package/dist/utils/index.d.ts.map +1 -0
  87. package/dist/utils/index.js +6 -0
  88. package/dist/utils/index.js.map +1 -0
  89. package/dist/utils/json.d.ts +9 -0
  90. package/dist/utils/json.d.ts.map +1 -0
  91. package/dist/utils/json.js +19 -0
  92. package/dist/utils/json.js.map +1 -0
  93. package/package.json +1 -1
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Scout prompt template
3
+ *
4
+ * This prompt is sent to Claude to analyze code and generate improvement proposals.
5
+ */
6
+ import type { ProposalCategory } from './types.js';
7
+ /**
8
+ * Build the scout prompt for analyzing a batch of files
9
+ */
10
+ export declare function buildScoutPrompt(options: {
11
+ files: Array<{
12
+ path: string;
13
+ content: string;
14
+ }>;
15
+ scope: string;
16
+ types?: ProposalCategory[];
17
+ excludeTypes?: ProposalCategory[];
18
+ maxProposals: number;
19
+ minConfidence: number;
20
+ recentlyCompletedTitles?: string[];
21
+ customPrompt?: string;
22
+ /** Files the scout can read but must NOT propose changes to */
23
+ protectedFiles?: string[];
24
+ }): string;
25
+ /**
26
+ * Build a focused prompt for a single category
27
+ */
28
+ export declare function buildCategoryPrompt(category: ProposalCategory, files: Array<{
29
+ path: string;
30
+ content: string;
31
+ }>, maxProposals?: number): string;
32
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/scout/prompt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B,GAAG,MAAM,CAkGT;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EAC/C,YAAY,GAAE,MAAU,GACvB,MAAM,CAQR"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Scout prompt template
3
+ *
4
+ * This prompt is sent to Claude to analyze code and generate improvement proposals.
5
+ */
6
+ /**
7
+ * Build the scout prompt for analyzing a batch of files
8
+ */
9
+ export function buildScoutPrompt(options) {
10
+ const { files, scope, types, excludeTypes, maxProposals, minConfidence, recentlyCompletedTitles, customPrompt, protectedFiles, } = options;
11
+ const protectedNote = protectedFiles?.length
12
+ ? `\n\n**DO NOT propose changes to these files** (read-only context): ${protectedFiles.join(', ')}\n`
13
+ : '';
14
+ const categoryFilter = types?.length
15
+ ? `Focus ONLY on these categories: ${types.join(', ')}`
16
+ : excludeTypes?.length
17
+ ? `EXCLUDE these categories: ${excludeTypes.join(', ')}`
18
+ : 'Consider all categories';
19
+ const strategicFocus = customPrompt
20
+ ? `\n## Strategic Focus\n\n${customPrompt}\n`
21
+ : '';
22
+ const recentContext = recentlyCompletedTitles?.length
23
+ ? `\n\nAVOID proposing work similar to these recently completed tickets:\n${recentlyCompletedTitles.map(t => `- ${t}`).join('\n')}`
24
+ : '';
25
+ const fileContents = files
26
+ .map(f => `### ${f.path}\n\`\`\`\n${f.content}\n\`\`\``)
27
+ .join('\n\n');
28
+ return `You are a senior software engineer reviewing code for improvement opportunities.
29
+
30
+ Analyze these files from scope "${scope}" and identify actionable improvements.
31
+
32
+ ${categoryFilter}
33
+
34
+ ## Categories
35
+
36
+ - **refactor**: Code quality, readability, maintainability improvements including:
37
+ - DRY violations (duplicate code that should be consolidated)
38
+ - Dead code removal (unused functions, imports, variables)
39
+ - Over-engineering (unnecessary abstractions, premature optimization)
40
+ - Inconsistent patterns (code that doesn't match surrounding conventions)
41
+ - Bloat cleanup (removing complexity that doesn't add value)
42
+ - **docs**: Missing/outdated documentation, comments, README updates
43
+ - **test**: Missing tests, edge cases, coverage gaps
44
+ - **perf**: Performance optimizations, algorithmic improvements
45
+ - **security**: Security vulnerabilities, input validation, auth issues
46
+
47
+ ## Requirements
48
+
49
+ 1. Each proposal MUST be:
50
+ - Specific and actionable (not vague)
51
+ - Self-contained (completable in one PR)
52
+ - Have at least one verification command
53
+ - Have confidence >= ${minConfidence}
54
+
55
+ 2. Verification commands should be:
56
+ - Runnable without manual setup
57
+ - NOT include grep/wc/file-specific test commands
58
+ - Prefer "npm run build" for non-test categories
59
+ - Prefer "npm test" for test categories
60
+
61
+ 3. Generate at most ${maxProposals} proposals, prioritized by impact.
62
+ ${protectedNote}${strategicFocus}${recentContext}
63
+
64
+ ## Files to Analyze
65
+
66
+ ${fileContents}
67
+
68
+ ## Output Format
69
+
70
+ Respond with ONLY a JSON object (no markdown, no explanation):
71
+
72
+ {
73
+ "proposals": [
74
+ {
75
+ "category": "refactor|docs|test|perf|security",
76
+ "title": "Short actionable title (imperative mood)",
77
+ "description": "What needs to be done and why",
78
+ "acceptance_criteria": ["Criterion 1", "Criterion 2"],
79
+ "verification_commands": ["npm run build"],
80
+ "allowed_paths": ["path/to/file.ts"],
81
+ "files": ["path/to/file.ts"],
82
+ "confidence": 75,
83
+ "impact_score": 5,
84
+ "rationale": "Why this improvement matters",
85
+ "estimated_complexity": "trivial|simple|moderate|complex"
86
+ }
87
+ ]
88
+ }
89
+
90
+ If no improvements are needed, return: {"proposals": []}`;
91
+ }
92
+ /**
93
+ * Build a focused prompt for a single category
94
+ */
95
+ export function buildCategoryPrompt(category, files, maxProposals = 5) {
96
+ return buildScoutPrompt({
97
+ files,
98
+ scope: '*',
99
+ types: [category],
100
+ maxProposals,
101
+ minConfidence: 50,
102
+ });
103
+ }
104
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/scout/prompt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAWhC;IACC,MAAM,EACJ,KAAK,EACL,KAAK,EACL,KAAK,EACL,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,uBAAuB,EACvB,YAAY,EACZ,cAAc,GACf,GAAG,OAAO,CAAC;IAEZ,MAAM,aAAa,GAAG,cAAc,EAAE,MAAM;QAC1C,CAAC,CAAC,sEAAsE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;QACrG,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,cAAc,GAAG,KAAK,EAAE,MAAM;QAClC,CAAC,CAAC,mCAAmC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACvD,CAAC,CAAC,YAAY,EAAE,MAAM;YACpB,CAAC,CAAC,6BAA6B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACxD,CAAC,CAAC,yBAAyB,CAAC;IAEhC,MAAM,cAAc,GAAG,YAAY;QACjC,CAAC,CAAC,2BAA2B,YAAY,IAAI;QAC7C,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,aAAa,GAAG,uBAAuB,EAAE,MAAM;QACnD,CAAC,CAAC,0EAA0E,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACnI,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,YAAY,GAAG,KAAK;SACvB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,OAAO,UAAU,CAAC;SACvD,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO;;kCAEyB,KAAK;;EAErC,cAAc;;;;;;;;;;;;;;;;;;;;;0BAqBU,aAAa;;;;;;;;sBAQjB,YAAY;EAChC,aAAa,GAAG,cAAc,GAAG,aAAa;;;;EAI9C,YAAY;;;;;;;;;;;;;;;;;;;;;;;;yDAwB2C,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAA0B,EAC1B,KAA+C,EAC/C,eAAuB,CAAC;IAExB,OAAO,gBAAgB,CAAC;QACtB,KAAK;QACL,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,CAAC,QAAQ,CAAC;QACjB,YAAY;QACZ,aAAa,EAAE,EAAE;KAClB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Scout runner - Executes LLM CLI backends for analysis
3
+ */
4
+ export interface RunnerOptions {
5
+ /** Prompt to send to the LLM */
6
+ prompt: string;
7
+ /** Working directory */
8
+ cwd: string;
9
+ /** Timeout in ms */
10
+ timeoutMs: number;
11
+ /** Model to use */
12
+ model?: string;
13
+ /** Cancellation signal */
14
+ signal?: AbortSignal;
15
+ }
16
+ export interface RunnerResult {
17
+ /** Whether execution succeeded */
18
+ success: boolean;
19
+ /** Output from the LLM */
20
+ output: string;
21
+ /** Error message if failed */
22
+ error?: string;
23
+ /** Duration in ms */
24
+ durationMs: number;
25
+ }
26
+ /**
27
+ * Pluggable scout backend interface
28
+ */
29
+ export interface ScoutBackend {
30
+ /** Human-readable name for logging */
31
+ readonly name: string;
32
+ /** Run a scout prompt and return the result */
33
+ run(options: RunnerOptions): Promise<RunnerResult>;
34
+ }
35
+ /**
36
+ * Run Claude Code CLI with a prompt
37
+ */
38
+ export declare function runClaude(options: RunnerOptions): Promise<RunnerResult>;
39
+ /**
40
+ * Claude Code CLI scout backend (default)
41
+ */
42
+ export declare class ClaudeScoutBackend implements ScoutBackend {
43
+ readonly name = "claude";
44
+ run(options: RunnerOptions): Promise<RunnerResult>;
45
+ }
46
+ /**
47
+ * Codex CLI scout backend
48
+ *
49
+ * Spawns `codex exec` in read-only sandbox mode for analysis.
50
+ * Uses --output-last-message for reliable output extraction.
51
+ */
52
+ export declare class CodexScoutBackend implements ScoutBackend {
53
+ readonly name = "codex";
54
+ private apiKey?;
55
+ private defaultModel;
56
+ constructor(opts?: {
57
+ apiKey?: string;
58
+ model?: string;
59
+ });
60
+ run(options: RunnerOptions): Promise<RunnerResult>;
61
+ }
62
+ /**
63
+ * Parse JSON from Claude's output
64
+ *
65
+ * Handles common issues like markdown code blocks
66
+ */
67
+ export declare function parseClaudeOutput<T>(output: string): T | null;
68
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/scout/runner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,GAAG,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACpD;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAwG7E;AAED;;GAEG;AACH,qBAAa,kBAAmB,YAAW,YAAY;IACrD,QAAQ,CAAC,IAAI,YAAY;IAEzB,GAAG,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CAGnD;AAED;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IACpD,QAAQ,CAAC,IAAI,WAAW;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,YAAY,CAAS;gBAEjB,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAKhD,GAAG,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CA2HzD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CA6B7D"}
@@ -0,0 +1,270 @@
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,
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: ['ignore', 'pipe', 'pipe'],
38
+ });
39
+ let stdout = '';
40
+ let stderr = '';
41
+ let killed = false;
42
+ // Timeout handler
43
+ const timeout = setTimeout(() => {
44
+ killed = true;
45
+ proc.kill('SIGTERM');
46
+ // Grace period before SIGKILL
47
+ setTimeout(() => proc.kill('SIGKILL'), 5000);
48
+ }, timeoutMs);
49
+ // Abort signal handler
50
+ const abortHandler = () => {
51
+ killed = true;
52
+ proc.kill('SIGTERM');
53
+ };
54
+ signal?.addEventListener('abort', abortHandler);
55
+ proc.stdout.on('data', (data) => {
56
+ stdout += data.toString();
57
+ });
58
+ proc.stderr.on('data', (data) => {
59
+ stderr += data.toString();
60
+ });
61
+ proc.on('close', (code) => {
62
+ clearTimeout(timeout);
63
+ signal?.removeEventListener('abort', abortHandler);
64
+ const durationMs = Date.now() - start;
65
+ if (killed) {
66
+ resolve({
67
+ success: false,
68
+ output: stdout,
69
+ error: signal?.aborted ? 'Aborted by signal' : 'Timeout exceeded',
70
+ durationMs,
71
+ });
72
+ return;
73
+ }
74
+ if (code !== 0) {
75
+ resolve({
76
+ success: false,
77
+ output: stdout,
78
+ error: stderr || `Process exited with code ${code}`,
79
+ durationMs,
80
+ });
81
+ return;
82
+ }
83
+ resolve({
84
+ success: true,
85
+ output: stdout,
86
+ durationMs,
87
+ });
88
+ });
89
+ proc.on('error', (err) => {
90
+ clearTimeout(timeout);
91
+ signal?.removeEventListener('abort', abortHandler);
92
+ resolve({
93
+ success: false,
94
+ output: '',
95
+ error: err.message,
96
+ durationMs: Date.now() - start,
97
+ });
98
+ });
99
+ });
100
+ }
101
+ /**
102
+ * Claude Code CLI scout backend (default)
103
+ */
104
+ export class ClaudeScoutBackend {
105
+ name = 'claude';
106
+ run(options) {
107
+ return runClaude(options);
108
+ }
109
+ }
110
+ /**
111
+ * Codex CLI scout backend
112
+ *
113
+ * Spawns `codex exec` in read-only sandbox mode for analysis.
114
+ * Uses --output-last-message for reliable output extraction.
115
+ */
116
+ export class CodexScoutBackend {
117
+ name = 'codex';
118
+ apiKey;
119
+ defaultModel;
120
+ constructor(opts) {
121
+ this.apiKey = opts?.apiKey;
122
+ this.defaultModel = opts?.model ?? 'gpt-5.2-codex';
123
+ }
124
+ async run(options) {
125
+ const { prompt, cwd, timeoutMs, model, signal } = options;
126
+ const start = Date.now();
127
+ if (signal?.aborted) {
128
+ return { success: false, output: '', error: 'Aborted before start', durationMs: 0 };
129
+ }
130
+ const tmpDir = mkdtempSync(join(tmpdir(), 'blockspool-codex-'));
131
+ const outPath = join(tmpDir, 'output.md');
132
+ const schemaPath = join(tmpDir, 'schema.json');
133
+ // Write JSON schema so Codex returns structured output
134
+ writeFileSync(schemaPath, JSON.stringify({
135
+ type: 'object',
136
+ properties: {
137
+ proposals: {
138
+ type: 'array',
139
+ items: {
140
+ type: 'object',
141
+ properties: {
142
+ category: { type: 'string' },
143
+ title: { type: 'string' },
144
+ description: { type: 'string' },
145
+ acceptance_criteria: { type: 'array', items: { type: 'string' } },
146
+ verification_commands: { type: 'array', items: { type: 'string' } },
147
+ allowed_paths: { type: 'array', items: { type: 'string' } },
148
+ files: { type: 'array', items: { type: 'string' } },
149
+ confidence: { type: 'number' },
150
+ impact_score: { type: 'number' },
151
+ rationale: { type: 'string' },
152
+ estimated_complexity: { type: 'string' },
153
+ },
154
+ required: ['category', 'title', 'description', 'confidence', 'impact_score', 'files'],
155
+ },
156
+ },
157
+ },
158
+ required: ['proposals'],
159
+ }));
160
+ try {
161
+ const effectiveModel = model ?? this.defaultModel;
162
+ const args = [
163
+ 'exec',
164
+ '--json',
165
+ '--sandbox', 'read-only',
166
+ '--ask-for-approval', 'never',
167
+ '--output-last-message', outPath,
168
+ '--output-schema', schemaPath,
169
+ '--model', effectiveModel,
170
+ '--cd', cwd,
171
+ '-',
172
+ ];
173
+ const env = { ...process.env };
174
+ if (this.apiKey) {
175
+ env.CODEX_API_KEY = this.apiKey;
176
+ }
177
+ return await new Promise((resolve) => {
178
+ const proc = spawn('codex', args, {
179
+ cwd,
180
+ env,
181
+ stdio: ['pipe', 'pipe', 'pipe'],
182
+ });
183
+ // Send prompt via stdin
184
+ proc.stdin.write(prompt);
185
+ proc.stdin.end();
186
+ let stdout = '';
187
+ let stderr = '';
188
+ let killed = false;
189
+ const timeout = setTimeout(() => {
190
+ killed = true;
191
+ proc.kill('SIGTERM');
192
+ setTimeout(() => proc.kill('SIGKILL'), 5000);
193
+ }, timeoutMs);
194
+ const abortHandler = () => { killed = true; proc.kill('SIGTERM'); };
195
+ signal?.addEventListener('abort', abortHandler);
196
+ proc.stdout.on('data', (d) => { stdout += d.toString(); });
197
+ proc.stderr.on('data', (d) => { stderr += d.toString(); });
198
+ proc.on('close', (code) => {
199
+ clearTimeout(timeout);
200
+ signal?.removeEventListener('abort', abortHandler);
201
+ const durationMs = Date.now() - start;
202
+ if (killed) {
203
+ resolve({ success: false, output: stdout, error: signal?.aborted ? 'Aborted by signal' : 'Timeout exceeded', durationMs });
204
+ return;
205
+ }
206
+ // Prefer --output-last-message file over stdout (stdout is JSONL telemetry)
207
+ let output = stdout;
208
+ try {
209
+ output = readFileSync(outPath, 'utf-8');
210
+ }
211
+ catch {
212
+ // Fall back to stdout if file wasn't written
213
+ }
214
+ if (code !== 0) {
215
+ resolve({ success: false, output, error: stderr || `codex exited with code ${code}`, durationMs });
216
+ return;
217
+ }
218
+ resolve({ success: true, output, durationMs });
219
+ });
220
+ proc.on('error', (err) => {
221
+ clearTimeout(timeout);
222
+ signal?.removeEventListener('abort', abortHandler);
223
+ resolve({ success: false, output: '', error: err.message, durationMs: Date.now() - start });
224
+ });
225
+ });
226
+ }
227
+ finally {
228
+ try {
229
+ rmSync(tmpDir, { recursive: true, force: true });
230
+ }
231
+ catch { /* best-effort cleanup */ }
232
+ }
233
+ }
234
+ }
235
+ /**
236
+ * Parse JSON from Claude's output
237
+ *
238
+ * Handles common issues like markdown code blocks
239
+ */
240
+ export function parseClaudeOutput(output) {
241
+ // Try direct parse first
242
+ try {
243
+ return JSON.parse(output.trim());
244
+ }
245
+ catch {
246
+ // Ignore and try other methods
247
+ }
248
+ // Try extracting from markdown code block
249
+ const jsonMatch = output.match(/```(?:json)?\s*([\s\S]*?)```/);
250
+ if (jsonMatch) {
251
+ try {
252
+ return JSON.parse(jsonMatch[1].trim());
253
+ }
254
+ catch {
255
+ // Ignore
256
+ }
257
+ }
258
+ // Try finding JSON object/array in output
259
+ const objectMatch = output.match(/\{[\s\S]*\}/);
260
+ if (objectMatch) {
261
+ try {
262
+ return JSON.parse(objectMatch[0]);
263
+ }
264
+ catch {
265
+ // Ignore
266
+ }
267
+ }
268
+ return null;
269
+ }
270
+ //# 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,35 @@
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
+ //# 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"}