@blockspool/core 0.3.0 → 0.3.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 (145) hide show
  1. package/package.json +1 -1
  2. package/dist/db/adapter.d.ts +0 -191
  3. package/dist/db/adapter.d.ts.map +0 -1
  4. package/dist/db/adapter.js +0 -40
  5. package/dist/db/adapter.js.map +0 -1
  6. package/dist/db/contract.d.ts +0 -47
  7. package/dist/db/contract.d.ts.map +0 -1
  8. package/dist/db/contract.js +0 -258
  9. package/dist/db/contract.js.map +0 -1
  10. package/dist/db/index.d.ts +0 -6
  11. package/dist/db/index.d.ts.map +0 -1
  12. package/dist/db/index.js +0 -7
  13. package/dist/db/index.js.map +0 -1
  14. package/dist/exec/index.d.ts +0 -5
  15. package/dist/exec/index.d.ts.map +0 -1
  16. package/dist/exec/index.js +0 -5
  17. package/dist/exec/index.js.map +0 -1
  18. package/dist/exec/types.d.ts +0 -64
  19. package/dist/exec/types.d.ts.map +0 -1
  20. package/dist/exec/types.js +0 -8
  21. package/dist/exec/types.js.map +0 -1
  22. package/dist/index.d.ts +0 -23
  23. package/dist/index.d.ts.map +0 -1
  24. package/dist/index.js +0 -27
  25. package/dist/index.js.map +0 -1
  26. package/dist/repos/index.d.ts +0 -15
  27. package/dist/repos/index.d.ts.map +0 -1
  28. package/dist/repos/index.js +0 -11
  29. package/dist/repos/index.js.map +0 -1
  30. package/dist/repos/projects.d.ts +0 -41
  31. package/dist/repos/projects.d.ts.map +0 -1
  32. package/dist/repos/projects.js +0 -74
  33. package/dist/repos/projects.js.map +0 -1
  34. package/dist/repos/run_steps.d.ts +0 -152
  35. package/dist/repos/run_steps.d.ts.map +0 -1
  36. package/dist/repos/run_steps.js +0 -321
  37. package/dist/repos/run_steps.js.map +0 -1
  38. package/dist/repos/runs.d.ts +0 -92
  39. package/dist/repos/runs.d.ts.map +0 -1
  40. package/dist/repos/runs.js +0 -177
  41. package/dist/repos/runs.js.map +0 -1
  42. package/dist/repos/tickets.d.ts +0 -71
  43. package/dist/repos/tickets.d.ts.map +0 -1
  44. package/dist/repos/tickets.js +0 -128
  45. package/dist/repos/tickets.js.map +0 -1
  46. package/dist/scout/index.d.ts +0 -15
  47. package/dist/scout/index.d.ts.map +0 -1
  48. package/dist/scout/index.js +0 -382
  49. package/dist/scout/index.js.map +0 -1
  50. package/dist/scout/prompt.d.ts +0 -30
  51. package/dist/scout/prompt.d.ts.map +0 -1
  52. package/dist/scout/prompt.js +0 -101
  53. package/dist/scout/prompt.js.map +0 -1
  54. package/dist/scout/runner.d.ts +0 -68
  55. package/dist/scout/runner.d.ts.map +0 -1
  56. package/dist/scout/runner.js +0 -241
  57. package/dist/scout/runner.js.map +0 -1
  58. package/dist/scout/scanner.d.ts +0 -35
  59. package/dist/scout/scanner.d.ts.map +0 -1
  60. package/dist/scout/scanner.js +0 -164
  61. package/dist/scout/scanner.js.map +0 -1
  62. package/dist/scout/types.d.ts +0 -177
  63. package/dist/scout/types.d.ts.map +0 -1
  64. package/dist/scout/types.js +0 -44
  65. package/dist/scout/types.js.map +0 -1
  66. package/dist/services/index.d.ts +0 -10
  67. package/dist/services/index.d.ts.map +0 -1
  68. package/dist/services/index.js +0 -9
  69. package/dist/services/index.js.map +0 -1
  70. package/dist/services/qa.d.ts +0 -76
  71. package/dist/services/qa.d.ts.map +0 -1
  72. package/dist/services/qa.js +0 -239
  73. package/dist/services/qa.js.map +0 -1
  74. package/dist/services/scout.d.ts +0 -118
  75. package/dist/services/scout.d.ts.map +0 -1
  76. package/dist/services/scout.js +0 -204
  77. package/dist/services/scout.js.map +0 -1
  78. package/dist/test/db-contract-sqlite.test.d.ts +0 -2
  79. package/dist/test/db-contract-sqlite.test.d.ts.map +0 -1
  80. package/dist/test/db-contract-sqlite.test.js +0 -176
  81. package/dist/test/db-contract-sqlite.test.js.map +0 -1
  82. package/dist/test/learnings-format.test.d.ts +0 -9
  83. package/dist/test/learnings-format.test.d.ts.map +0 -1
  84. package/dist/test/learnings-format.test.js +0 -174
  85. package/dist/test/learnings-format.test.js.map +0 -1
  86. package/dist/test/repos-integration.test.d.ts +0 -2
  87. package/dist/test/repos-integration.test.d.ts.map +0 -1
  88. package/dist/test/repos-integration.test.js +0 -565
  89. package/dist/test/repos-integration.test.js.map +0 -1
  90. package/dist/test/scout-full-pure.test.d.ts +0 -2
  91. package/dist/test/scout-full-pure.test.d.ts.map +0 -1
  92. package/dist/test/scout-full-pure.test.js +0 -122
  93. package/dist/test/scout-full-pure.test.js.map +0 -1
  94. package/dist/test/scout-integration.test.d.ts +0 -13
  95. package/dist/test/scout-integration.test.d.ts.map +0 -1
  96. package/dist/test/scout-integration.test.js +0 -229
  97. package/dist/test/scout-integration.test.js.map +0 -1
  98. package/dist/test/scout-prompt.test.d.ts +0 -2
  99. package/dist/test/scout-prompt.test.d.ts.map +0 -1
  100. package/dist/test/scout-prompt.test.js +0 -79
  101. package/dist/test/scout-prompt.test.js.map +0 -1
  102. package/dist/test/scout-runner-parse.test.d.ts +0 -2
  103. package/dist/test/scout-runner-parse.test.d.ts.map +0 -1
  104. package/dist/test/scout-runner-parse.test.js +0 -44
  105. package/dist/test/scout-runner-parse.test.js.map +0 -1
  106. package/dist/test/scout-runner-spawn.test.d.ts +0 -11
  107. package/dist/test/scout-runner-spawn.test.d.ts.map +0 -1
  108. package/dist/test/scout-runner-spawn.test.js +0 -359
  109. package/dist/test/scout-runner-spawn.test.js.map +0 -1
  110. package/dist/test/scout-scanner-fs.test.d.ts +0 -2
  111. package/dist/test/scout-scanner-fs.test.d.ts.map +0 -1
  112. package/dist/test/scout-scanner-fs.test.js +0 -188
  113. package/dist/test/scout-scanner-fs.test.js.map +0 -1
  114. package/dist/test/scout-scanner-pure.test.d.ts +0 -2
  115. package/dist/test/scout-scanner-pure.test.d.ts.map +0 -1
  116. package/dist/test/scout-scanner-pure.test.js +0 -131
  117. package/dist/test/scout-scanner-pure.test.js.map +0 -1
  118. package/dist/test/services-integration.test.d.ts +0 -2
  119. package/dist/test/services-integration.test.d.ts.map +0 -1
  120. package/dist/test/services-integration.test.js +0 -327
  121. package/dist/test/services-integration.test.js.map +0 -1
  122. package/dist/test/services-qa.test.d.ts +0 -2
  123. package/dist/test/services-qa.test.d.ts.map +0 -1
  124. package/dist/test/services-qa.test.js +0 -255
  125. package/dist/test/services-qa.test.js.map +0 -1
  126. package/dist/test/services-scout.test.d.ts +0 -2
  127. package/dist/test/services-scout.test.d.ts.map +0 -1
  128. package/dist/test/services-scout.test.js +0 -269
  129. package/dist/test/services-scout.test.js.map +0 -1
  130. package/dist/utils/id.d.ts +0 -12
  131. package/dist/utils/id.d.ts.map +0 -1
  132. package/dist/utils/id.js +0 -24
  133. package/dist/utils/id.js.map +0 -1
  134. package/dist/utils/id.test.d.ts +0 -5
  135. package/dist/utils/id.test.d.ts.map +0 -1
  136. package/dist/utils/id.test.js +0 -173
  137. package/dist/utils/id.test.js.map +0 -1
  138. package/dist/utils/index.d.ts +0 -6
  139. package/dist/utils/index.d.ts.map +0 -1
  140. package/dist/utils/index.js +0 -6
  141. package/dist/utils/index.js.map +0 -1
  142. package/dist/utils/json.d.ts +0 -9
  143. package/dist/utils/json.d.ts.map +0 -1
  144. package/dist/utils/json.js +0 -19
  145. package/dist/utils/json.js.map +0 -1
@@ -1,30 +0,0 @@
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
- }): string;
23
- /**
24
- * Build a focused prompt for a single category
25
- */
26
- export declare function buildCategoryPrompt(category: ProposalCategory, files: Array<{
27
- path: string;
28
- content: string;
29
- }>, maxProposals?: number): string;
30
- //# sourceMappingURL=prompt.d.ts.map
@@ -1 +0,0 @@
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;CACvB,GAAG,MAAM,CA6FT;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"}
@@ -1,101 +0,0 @@
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, } = options;
11
- const categoryFilter = types?.length
12
- ? `Focus ONLY on these categories: ${types.join(', ')}`
13
- : excludeTypes?.length
14
- ? `EXCLUDE these categories: ${excludeTypes.join(', ')}`
15
- : 'Consider all categories';
16
- const strategicFocus = customPrompt
17
- ? `\n## Strategic Focus\n\n${customPrompt}\n`
18
- : '';
19
- const recentContext = recentlyCompletedTitles?.length
20
- ? `\n\nAVOID proposing work similar to these recently completed tickets:\n${recentlyCompletedTitles.map(t => `- ${t}`).join('\n')}`
21
- : '';
22
- const fileContents = files
23
- .map(f => `### ${f.path}\n\`\`\`\n${f.content}\n\`\`\``)
24
- .join('\n\n');
25
- return `You are a senior software engineer reviewing code for improvement opportunities.
26
-
27
- Analyze these files from scope "${scope}" and identify actionable improvements.
28
-
29
- ${categoryFilter}
30
-
31
- ## Categories
32
-
33
- - **refactor**: Code quality, readability, maintainability improvements including:
34
- - DRY violations (duplicate code that should be consolidated)
35
- - Dead code removal (unused functions, imports, variables)
36
- - Over-engineering (unnecessary abstractions, premature optimization)
37
- - Inconsistent patterns (code that doesn't match surrounding conventions)
38
- - Bloat cleanup (removing complexity that doesn't add value)
39
- - **docs**: Missing/outdated documentation, comments, README updates
40
- - **test**: Missing tests, edge cases, coverage gaps
41
- - **perf**: Performance optimizations, algorithmic improvements
42
- - **security**: Security vulnerabilities, input validation, auth issues
43
-
44
- ## Requirements
45
-
46
- 1. Each proposal MUST be:
47
- - Specific and actionable (not vague)
48
- - Self-contained (completable in one PR)
49
- - Have at least one verification command
50
- - Have confidence >= ${minConfidence}
51
-
52
- 2. Verification commands should be:
53
- - Runnable without manual setup
54
- - NOT include grep/wc/file-specific test commands
55
- - Prefer "npm run build" for non-test categories
56
- - Prefer "npm test" for test categories
57
-
58
- 3. Generate at most ${maxProposals} proposals, prioritized by impact.
59
- ${strategicFocus}${recentContext}
60
-
61
- ## Files to Analyze
62
-
63
- ${fileContents}
64
-
65
- ## Output Format
66
-
67
- Respond with ONLY a JSON object (no markdown, no explanation):
68
-
69
- {
70
- "proposals": [
71
- {
72
- "category": "refactor|docs|test|perf|security",
73
- "title": "Short actionable title (imperative mood)",
74
- "description": "What needs to be done and why",
75
- "acceptance_criteria": ["Criterion 1", "Criterion 2"],
76
- "verification_commands": ["npm run build"],
77
- "allowed_paths": ["path/to/file.ts"],
78
- "files": ["path/to/file.ts"],
79
- "confidence": 75,
80
- "impact_score": 5,
81
- "rationale": "Why this improvement matters",
82
- "estimated_complexity": "trivial|simple|moderate|complex"
83
- }
84
- ]
85
- }
86
-
87
- If no improvements are needed, return: {"proposals": []}`;
88
- }
89
- /**
90
- * Build a focused prompt for a single category
91
- */
92
- export function buildCategoryPrompt(category, files, maxProposals = 5) {
93
- return buildScoutPrompt({
94
- files,
95
- scope: '*',
96
- types: [category],
97
- maxProposals,
98
- minConfidence: 50,
99
- });
100
- }
101
- //# sourceMappingURL=prompt.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/scout/prompt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAShC;IACC,MAAM,EACJ,KAAK,EACL,KAAK,EACL,KAAK,EACL,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,uBAAuB,EACvB,YAAY,GACb,GAAG,OAAO,CAAC;IAEZ,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,cAAc,GAAG,aAAa;;;;EAI9B,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"}
@@ -1,68 +0,0 @@
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
@@ -1 +0,0 @@
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;CA6FzD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CA6B7D"}
@@ -1,241 +0,0 @@
1
- /**
2
- * Scout runner - Executes LLM CLI backends for analysis
3
- */
4
- import { spawn } from 'node:child_process';
5
- import { 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 ?? 'o4-mini';
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
- try {
133
- const effectiveModel = model ?? this.defaultModel;
134
- const args = [
135
- 'exec',
136
- '--json',
137
- '--sandbox', 'read-only',
138
- '--ask-for-approval', 'never',
139
- '--output-last-message', outPath,
140
- '--model', effectiveModel,
141
- '--cd', cwd,
142
- '-',
143
- ];
144
- const env = { ...process.env };
145
- if (this.apiKey) {
146
- env.CODEX_API_KEY = this.apiKey;
147
- }
148
- return await new Promise((resolve) => {
149
- const proc = spawn('codex', args, {
150
- cwd,
151
- env,
152
- stdio: ['pipe', 'pipe', 'pipe'],
153
- });
154
- // Send prompt via stdin
155
- proc.stdin.write(prompt);
156
- proc.stdin.end();
157
- let stdout = '';
158
- let stderr = '';
159
- let killed = false;
160
- const timeout = setTimeout(() => {
161
- killed = true;
162
- proc.kill('SIGTERM');
163
- setTimeout(() => proc.kill('SIGKILL'), 5000);
164
- }, timeoutMs);
165
- const abortHandler = () => { killed = true; proc.kill('SIGTERM'); };
166
- signal?.addEventListener('abort', abortHandler);
167
- proc.stdout.on('data', (d) => { stdout += d.toString(); });
168
- proc.stderr.on('data', (d) => { stderr += d.toString(); });
169
- proc.on('close', (code) => {
170
- clearTimeout(timeout);
171
- signal?.removeEventListener('abort', abortHandler);
172
- const durationMs = Date.now() - start;
173
- if (killed) {
174
- resolve({ success: false, output: stdout, error: signal?.aborted ? 'Aborted by signal' : 'Timeout exceeded', durationMs });
175
- return;
176
- }
177
- // Prefer --output-last-message file over stdout (stdout is JSONL telemetry)
178
- let output = stdout;
179
- try {
180
- output = readFileSync(outPath, 'utf-8');
181
- }
182
- catch {
183
- // Fall back to stdout if file wasn't written
184
- }
185
- if (code !== 0) {
186
- resolve({ success: false, output, error: stderr || `codex exited with code ${code}`, durationMs });
187
- return;
188
- }
189
- resolve({ success: true, output, durationMs });
190
- });
191
- proc.on('error', (err) => {
192
- clearTimeout(timeout);
193
- signal?.removeEventListener('abort', abortHandler);
194
- resolve({ success: false, output: '', error: err.message, durationMs: Date.now() - start });
195
- });
196
- });
197
- }
198
- finally {
199
- try {
200
- rmSync(tmpDir, { recursive: true, force: true });
201
- }
202
- catch { /* best-effort cleanup */ }
203
- }
204
- }
205
- }
206
- /**
207
- * Parse JSON from Claude's output
208
- *
209
- * Handles common issues like markdown code blocks
210
- */
211
- export function parseClaudeOutput(output) {
212
- // Try direct parse first
213
- try {
214
- return JSON.parse(output.trim());
215
- }
216
- catch {
217
- // Ignore and try other methods
218
- }
219
- // Try extracting from markdown code block
220
- const jsonMatch = output.match(/```(?:json)?\s*([\s\S]*?)```/);
221
- if (jsonMatch) {
222
- try {
223
- return JSON.parse(jsonMatch[1].trim());
224
- }
225
- catch {
226
- // Ignore
227
- }
228
- }
229
- // Try finding JSON object/array in output
230
- const objectMatch = output.match(/\{[\s\S]*\}/);
231
- if (objectMatch) {
232
- try {
233
- return JSON.parse(objectMatch[0]);
234
- }
235
- catch {
236
- // Ignore
237
- }
238
- }
239
- return null;
240
- }
241
- //# sourceMappingURL=runner.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/scout/runner.ts"],"names":[],"mappings":"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"}
@@ -1,35 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,164 +0,0 @@
1
- /**
2
- * File scanner - Discovers and reads files for analysis
3
- */
4
- import * as fs from 'node:fs';
5
- import * as path from 'node:path';
6
- /**
7
- * Default exclusion patterns
8
- */
9
- const DEFAULT_EXCLUDES = [
10
- 'node_modules',
11
- '.git',
12
- 'dist',
13
- 'build',
14
- 'coverage',
15
- '.next',
16
- '.cache',
17
- '*.min.js',
18
- '*.map',
19
- '*.lock',
20
- 'package-lock.json',
21
- 'yarn.lock',
22
- 'pnpm-lock.yaml',
23
- ];
24
- /**
25
- * Check if a path matches a simple glob pattern
26
- *
27
- * Supports:
28
- * - ** for recursive matching
29
- * - * for single segment matching
30
- * - Direct path matching
31
- */
32
- function matchesPattern(filePath, pattern) {
33
- // Normalize paths
34
- const normalizedPath = filePath.replace(/\\/g, '/');
35
- const normalizedPattern = pattern.replace(/\\/g, '/');
36
- // Direct match
37
- if (normalizedPath === normalizedPattern) {
38
- return true;
39
- }
40
- // Check if pattern is a directory prefix (without glob)
41
- if (!normalizedPattern.includes('*') && normalizedPath.startsWith(normalizedPattern + '/')) {
42
- return true;
43
- }
44
- // Simple glob matching
45
- if (normalizedPattern.includes('*')) {
46
- // Escape regex special chars except *
47
- const escaped = normalizedPattern
48
- .replace(/[.+^${}()|[\]\\]/g, '\\$&');
49
- // Convert glob patterns to regex
50
- // Note: **/ should be optional to match files directly in the directory
51
- // e.g., src/services/**/*.ts should match both src/services/auditor.ts
52
- // and src/services/sub/file.ts
53
- const regexPattern = escaped
54
- .replace(/\*\*\//g, '<<<DOUBLESTARSLASH>>>')
55
- .replace(/\*\*/g, '<<<DOUBLESTAR>>>')
56
- .replace(/\*/g, '[^/]*')
57
- .replace(/<<<DOUBLESTARSLASH>>>/g, '(.*\\/)?')
58
- .replace(/<<<DOUBLESTAR>>>/g, '.*');
59
- const regex = new RegExp(`^${regexPattern}$`);
60
- return regex.test(normalizedPath);
61
- }
62
- return false;
63
- }
64
- /**
65
- * Check if a path should be excluded
66
- */
67
- function shouldExclude(filePath, excludePatterns) {
68
- const allExcludes = [...DEFAULT_EXCLUDES, ...excludePatterns];
69
- for (const pattern of allExcludes) {
70
- if (matchesPattern(filePath, pattern)) {
71
- return true;
72
- }
73
- // Also check if any path segment matches (for things like node_modules)
74
- const segments = filePath.split('/');
75
- if (segments.some(seg => matchesPattern(seg, pattern))) {
76
- return true;
77
- }
78
- }
79
- return false;
80
- }
81
- /**
82
- * Check if a file matches any include pattern
83
- */
84
- function shouldInclude(filePath, includePatterns) {
85
- // If no patterns specified, include source-like files
86
- if (includePatterns.length === 0) {
87
- const ext = path.extname(filePath).toLowerCase();
88
- return ['.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.rs', '.java', '.rb', '.md'].includes(ext);
89
- }
90
- return includePatterns.some(pattern => matchesPattern(filePath, pattern));
91
- }
92
- /**
93
- * Recursively scan directory for files
94
- */
95
- function walkDir(dir, baseDir, options, files) {
96
- const maxFileSize = options.maxFileSize ?? 100 * 1024; // 100KB
97
- const maxFiles = options.maxFiles ?? 500;
98
- if (files.length >= maxFiles) {
99
- return;
100
- }
101
- let entries;
102
- try {
103
- entries = fs.readdirSync(dir, { withFileTypes: true });
104
- }
105
- catch {
106
- return; // Skip unreadable directories
107
- }
108
- for (const entry of entries) {
109
- if (files.length >= maxFiles) {
110
- break;
111
- }
112
- const fullPath = path.join(dir, entry.name);
113
- const relativePath = path.relative(baseDir, fullPath);
114
- // Check exclusions first
115
- if (shouldExclude(relativePath, options.exclude ?? [])) {
116
- continue;
117
- }
118
- if (entry.isDirectory()) {
119
- walkDir(fullPath, baseDir, options, files);
120
- }
121
- else if (entry.isFile()) {
122
- // Check inclusion
123
- if (!shouldInclude(relativePath, options.include)) {
124
- continue;
125
- }
126
- // Check file size
127
- try {
128
- const stat = fs.statSync(fullPath);
129
- if (stat.size > maxFileSize) {
130
- continue;
131
- }
132
- // Read content
133
- const content = fs.readFileSync(fullPath, 'utf-8');
134
- files.push({
135
- path: relativePath,
136
- content,
137
- size: stat.size,
138
- });
139
- }
140
- catch {
141
- // Skip unreadable files
142
- }
143
- }
144
- }
145
- }
146
- /**
147
- * Scan a directory for files matching the given patterns
148
- */
149
- export function scanFiles(options) {
150
- const files = [];
151
- walkDir(options.cwd, options.cwd, options, files);
152
- return files;
153
- }
154
- /**
155
- * Group files into batches for processing
156
- */
157
- export function batchFiles(files, batchSize = 3) {
158
- const batches = [];
159
- for (let i = 0; i < files.length; i += batchSize) {
160
- batches.push(files.slice(i, i + batchSize));
161
- }
162
- return batches;
163
- }
164
- //# sourceMappingURL=scanner.js.map