@blockspool/cli 0.4.3 → 0.5.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 (37) hide show
  1. package/dist/bin/blockspool.js +1 -1
  2. package/dist/lib/codebase-index.d.ts +46 -0
  3. package/dist/lib/codebase-index.d.ts.map +1 -0
  4. package/dist/lib/codebase-index.js +427 -0
  5. package/dist/lib/codebase-index.js.map +1 -0
  6. package/dist/lib/learnings.d.ts +68 -0
  7. package/dist/lib/learnings.d.ts.map +1 -0
  8. package/dist/lib/learnings.js +248 -0
  9. package/dist/lib/learnings.js.map +1 -0
  10. package/dist/lib/project-metadata.d.ts +34 -0
  11. package/dist/lib/project-metadata.d.ts.map +1 -0
  12. package/dist/lib/project-metadata.js +504 -0
  13. package/dist/lib/project-metadata.js.map +1 -0
  14. package/dist/lib/proposal-review.d.ts +26 -0
  15. package/dist/lib/proposal-review.d.ts.map +1 -0
  16. package/dist/lib/proposal-review.js +89 -0
  17. package/dist/lib/proposal-review.js.map +1 -0
  18. package/dist/lib/solo-auto.d.ts.map +1 -1
  19. package/dist/lib/solo-auto.js +189 -8
  20. package/dist/lib/solo-auto.js.map +1 -1
  21. package/dist/lib/solo-ci.d.ts +1 -1
  22. package/dist/lib/solo-ci.d.ts.map +1 -1
  23. package/dist/lib/solo-ci.js +6 -0
  24. package/dist/lib/solo-ci.js.map +1 -1
  25. package/dist/lib/solo-config.d.ts +8 -0
  26. package/dist/lib/solo-config.d.ts.map +1 -1
  27. package/dist/lib/solo-config.js +4 -0
  28. package/dist/lib/solo-config.js.map +1 -1
  29. package/dist/lib/solo-ticket.d.ts +6 -2
  30. package/dist/lib/solo-ticket.d.ts.map +1 -1
  31. package/dist/lib/solo-ticket.js +29 -3
  32. package/dist/lib/solo-ticket.js.map +1 -1
  33. package/dist/lib/spindle.d.ts +21 -1
  34. package/dist/lib/spindle.d.ts.map +1 -1
  35. package/dist/lib/spindle.js +152 -3
  36. package/dist/lib/spindle.js.map +1 -1
  37. package/package.json +1 -1
@@ -18,7 +18,7 @@ const program = new Command();
18
18
  program
19
19
  .name('blockspool')
20
20
  .description('Continuous codebase improvement tool')
21
- .version('0.2.0');
21
+ .version('0.5.1');
22
22
  // `blockspool solo <cmd>` — backwards compat
23
23
  program.addCommand(soloCommand);
24
24
  // Detect if argv[2] is a known solo subcommand name — if so, lift it.
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Pre-Scout Codebase Index — lightweight structural map built at session start.
3
+ *
4
+ * Walks directories 2 levels deep using `fs` only. No AST parsing, no heavy deps.
5
+ * Provides module map, dependency edges, test gaps, complexity hotspots, and entrypoints.
6
+ *
7
+ * Copied from packages/mcp/src/codebase-index.ts (no cross-package deps).
8
+ */
9
+ export interface CodebaseIndex {
10
+ built_at: string;
11
+ modules: ModuleEntry[];
12
+ dependency_edges: Record<string, string[]>;
13
+ untested_modules: string[];
14
+ large_files: LargeFileEntry[];
15
+ entrypoints: string[];
16
+ /** mtimes of files sampled for import scanning — used for change detection. Not included in prompt. */
17
+ sampled_file_mtimes: Record<string, number>;
18
+ }
19
+ export interface ModuleEntry {
20
+ path: string;
21
+ file_count: number;
22
+ purpose: string;
23
+ }
24
+ export interface LargeFileEntry {
25
+ path: string;
26
+ lines: number;
27
+ }
28
+ export declare function buildCodebaseIndex(projectRoot: string, excludeDirs?: string[]): CodebaseIndex;
29
+ /**
30
+ * Incrementally refresh the codebase index. Re-walks the directory tree (cheap)
31
+ * but only re-scans imports for modules whose file count changed or that are new.
32
+ * Unchanged modules keep their existing dependency edges.
33
+ */
34
+ export declare function refreshCodebaseIndex(existing: CodebaseIndex, projectRoot: string, excludeDirs?: string[]): CodebaseIndex;
35
+ /**
36
+ * Check if the codebase structure has changed since the last index build.
37
+ *
38
+ * Two-layer detection:
39
+ * 1. Directory mtimes — catches file additions/deletions, new dirs, git pulls, branch switches.
40
+ * 2. Sampled file mtimes — catches content edits to files we scanned for imports (dependency edges).
41
+ *
42
+ * Cost: ≤60 dir statSync + ≤250 file statSync. Zero file reads, zero tokens.
43
+ */
44
+ export declare function hasStructuralChanges(index: CodebaseIndex, projectRoot: string): boolean;
45
+ export declare function formatIndexForPrompt(index: CodebaseIndex, scoutCycle: number): string;
46
+ //# sourceMappingURL=codebase-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebase-index.d.ts","sourceRoot":"","sources":["../../src/lib/codebase-index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,uGAAuG;IACvG,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAmHD,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAAM,EAAO,GACzB,aAAa,CA+Lf;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAAM,EAAO,GACzB,aAAa,CA6Bf;AAMD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CA6CT;AAgBD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAkDrF"}
@@ -0,0 +1,427 @@
1
+ /**
2
+ * Pre-Scout Codebase Index — lightweight structural map built at session start.
3
+ *
4
+ * Walks directories 2 levels deep using `fs` only. No AST parsing, no heavy deps.
5
+ * Provides module map, dependency edges, test gaps, complexity hotspots, and entrypoints.
6
+ *
7
+ * Copied from packages/mcp/src/codebase-index.ts (no cross-package deps).
8
+ */
9
+ import * as fs from 'node:fs';
10
+ import * as path from 'node:path';
11
+ // ---------------------------------------------------------------------------
12
+ // Source file extensions
13
+ // ---------------------------------------------------------------------------
14
+ const SOURCE_EXTENSIONS = new Set([
15
+ '.ts', '.js', '.py', '.rs', '.go', '.rb', '.java', '.cs', '.ex', '.php', '.swift',
16
+ ]);
17
+ // ---------------------------------------------------------------------------
18
+ // Purpose inference from directory name
19
+ // ---------------------------------------------------------------------------
20
+ const PURPOSE_MAP = {
21
+ api: 'api',
22
+ apis: 'api',
23
+ routes: 'api',
24
+ handlers: 'api',
25
+ controllers: 'api',
26
+ endpoints: 'api',
27
+ services: 'services',
28
+ service: 'services',
29
+ lib: 'services',
30
+ core: 'services',
31
+ test: 'tests',
32
+ tests: 'tests',
33
+ __tests__: 'tests',
34
+ spec: 'tests',
35
+ specs: 'tests',
36
+ ui: 'ui',
37
+ components: 'ui',
38
+ views: 'ui',
39
+ pages: 'ui',
40
+ screens: 'ui',
41
+ utils: 'utils',
42
+ util: 'utils',
43
+ helpers: 'utils',
44
+ shared: 'utils',
45
+ common: 'utils',
46
+ config: 'config',
47
+ configs: 'config',
48
+ configuration: 'config',
49
+ settings: 'config',
50
+ };
51
+ function inferPurpose(dirName) {
52
+ const lower = dirName.toLowerCase();
53
+ return PURPOSE_MAP[lower] ?? 'unknown';
54
+ }
55
+ // ---------------------------------------------------------------------------
56
+ // Import regex patterns
57
+ // ---------------------------------------------------------------------------
58
+ // JS/TS: import ... from '...' or require('...')
59
+ const JS_IMPORT_RE = /(?:import\s+.*?\s+from\s+['"]([^'"]+)['"]|require\s*\(\s*['"]([^'"]+)['"]\s*\))/g;
60
+ // Python: from X import ... or import X
61
+ const PY_IMPORT_RE = /(?:from\s+([\w.]+)\s+import|^import\s+([\w.]+))/gm;
62
+ // Go: import "..."
63
+ const GO_IMPORT_RE = /import\s+"([^"]+)"/g;
64
+ function extractImports(content, filePath) {
65
+ const ext = path.extname(filePath);
66
+ const imports = [];
67
+ if (ext === '.ts' || ext === '.js') {
68
+ for (const m of content.matchAll(JS_IMPORT_RE)) {
69
+ const spec = m[1] ?? m[2];
70
+ if (spec)
71
+ imports.push(spec);
72
+ }
73
+ }
74
+ else if (ext === '.py') {
75
+ for (const m of content.matchAll(PY_IMPORT_RE)) {
76
+ const spec = m[1] ?? m[2];
77
+ if (spec)
78
+ imports.push(spec);
79
+ }
80
+ }
81
+ else if (ext === '.go') {
82
+ for (const m of content.matchAll(GO_IMPORT_RE)) {
83
+ if (m[1])
84
+ imports.push(m[1]);
85
+ }
86
+ }
87
+ return imports;
88
+ }
89
+ /**
90
+ * Resolve a relative import specifier to a module path relative to projectRoot.
91
+ * Returns null for non-relative (package) imports.
92
+ */
93
+ function resolveImportToModule(specifier, sourceFile, projectRoot, modulePaths) {
94
+ // Only resolve relative imports
95
+ if (!specifier.startsWith('.'))
96
+ return null;
97
+ const sourceDir = path.dirname(sourceFile);
98
+ const resolved = path.resolve(sourceDir, specifier);
99
+ const relative = path.relative(projectRoot, resolved);
100
+ // Find which module this resolved path falls under
101
+ for (const mod of modulePaths) {
102
+ if (relative === mod || relative.startsWith(mod + '/') || relative.startsWith(mod + path.sep)) {
103
+ return mod;
104
+ }
105
+ }
106
+ return null;
107
+ }
108
+ // ---------------------------------------------------------------------------
109
+ // buildCodebaseIndex
110
+ // ---------------------------------------------------------------------------
111
+ export function buildCodebaseIndex(projectRoot, excludeDirs = []) {
112
+ const excludeSet = new Set(excludeDirs.map(d => d.toLowerCase()));
113
+ // Step 1: Module map — walk dirs 2 levels deep
114
+ const modules = [];
115
+ const sourceFilesByModule = new Map();
116
+ function shouldExclude(name) {
117
+ return excludeSet.has(name.toLowerCase()) || name.startsWith('.');
118
+ }
119
+ function walkForModules(dir, depth) {
120
+ if (modules.length >= 50)
121
+ return;
122
+ let entries;
123
+ try {
124
+ entries = fs.readdirSync(dir, { withFileTypes: true });
125
+ }
126
+ catch {
127
+ return;
128
+ }
129
+ const sourceFiles = [];
130
+ const subdirs = [];
131
+ for (const entry of entries) {
132
+ if (entry.isFile() && SOURCE_EXTENSIONS.has(path.extname(entry.name))) {
133
+ sourceFiles.push(path.join(dir, entry.name));
134
+ }
135
+ else if (entry.isDirectory() && !shouldExclude(entry.name)) {
136
+ subdirs.push(entry);
137
+ }
138
+ }
139
+ // Register this dir as a module if it has source files
140
+ if (sourceFiles.length > 0 && depth > 0) {
141
+ const relPath = path.relative(projectRoot, dir);
142
+ if (relPath && modules.length < 50) {
143
+ modules.push({
144
+ path: relPath,
145
+ file_count: sourceFiles.length,
146
+ purpose: inferPurpose(path.basename(dir)),
147
+ });
148
+ sourceFilesByModule.set(relPath, sourceFiles);
149
+ }
150
+ }
151
+ // Recurse into subdirs (up to depth 2)
152
+ if (depth < 2) {
153
+ for (const sub of subdirs) {
154
+ if (modules.length >= 50)
155
+ break;
156
+ walkForModules(path.join(dir, sub.name), depth + 1);
157
+ }
158
+ }
159
+ }
160
+ walkForModules(projectRoot, 0);
161
+ const modulePaths = modules.map(m => m.path);
162
+ // Step 2: Import scanning — build dependency_edges + record file mtimes
163
+ const dependencyEdges = {};
164
+ const sampledFileMtimes = {};
165
+ for (const mod of modules) {
166
+ const files = sourceFilesByModule.get(mod.path) ?? [];
167
+ const deps = new Set();
168
+ // Read first 50 lines of up to 5 files
169
+ const filesToScan = files.slice(0, 5);
170
+ for (const filePath of filesToScan) {
171
+ try {
172
+ // Record mtime for change detection
173
+ const relFile = path.relative(projectRoot, filePath);
174
+ sampledFileMtimes[relFile] = fs.statSync(filePath).mtimeMs;
175
+ const fd = fs.openSync(filePath, 'r');
176
+ const buf = Buffer.alloc(4096); // ~50 lines worth
177
+ const bytesRead = fs.readSync(fd, buf, 0, 4096, 0);
178
+ fs.closeSync(fd);
179
+ const content = buf.toString('utf8', 0, bytesRead);
180
+ // Trim to ~50 lines
181
+ const lines = content.split('\n').slice(0, 50).join('\n');
182
+ const imports = extractImports(lines, filePath);
183
+ for (const spec of imports) {
184
+ const resolved = resolveImportToModule(spec, filePath, projectRoot, modulePaths);
185
+ if (resolved && resolved !== mod.path) {
186
+ deps.add(resolved);
187
+ }
188
+ }
189
+ }
190
+ catch {
191
+ // skip unreadable files
192
+ }
193
+ }
194
+ if (deps.size > 0) {
195
+ dependencyEdges[mod.path] = [...deps];
196
+ }
197
+ }
198
+ // Step 3: Test coverage — find untested modules
199
+ const untestedModules = [];
200
+ for (const mod of modules) {
201
+ if (mod.purpose === 'tests')
202
+ continue;
203
+ const modAbsPath = path.join(projectRoot, mod.path);
204
+ const modParent = path.dirname(modAbsPath);
205
+ const modName = path.basename(modAbsPath);
206
+ let hasTesting = false;
207
+ // Check for __tests__/ sibling
208
+ if (existsDir(path.join(modAbsPath, '__tests__'))) {
209
+ hasTesting = true;
210
+ }
211
+ // Check for parallel test/ or tests/ dir at same level
212
+ if (!hasTesting && (existsDir(path.join(modParent, 'test')) || existsDir(path.join(modParent, 'tests')))) {
213
+ hasTesting = true;
214
+ }
215
+ // Check for *.test.* or *.spec.* files within the module
216
+ if (!hasTesting) {
217
+ const files = sourceFilesByModule.get(mod.path) ?? [];
218
+ hasTesting = files.some(f => {
219
+ const base = path.basename(f);
220
+ return base.includes('.test.') || base.includes('.spec.');
221
+ });
222
+ }
223
+ if (!hasTesting) {
224
+ untestedModules.push(mod.path);
225
+ }
226
+ }
227
+ // Step 4: Large files — stat.size / 40 heuristic for LOC
228
+ const largeFiles = [];
229
+ for (const mod of modules) {
230
+ const files = sourceFilesByModule.get(mod.path) ?? [];
231
+ for (const filePath of files) {
232
+ if (largeFiles.length >= 20)
233
+ break;
234
+ try {
235
+ const stat = fs.statSync(filePath);
236
+ const estimatedLines = Math.round(stat.size / 40);
237
+ if (estimatedLines > 300) {
238
+ largeFiles.push({
239
+ path: path.relative(projectRoot, filePath),
240
+ lines: estimatedLines,
241
+ });
242
+ }
243
+ }
244
+ catch {
245
+ // skip
246
+ }
247
+ }
248
+ if (largeFiles.length >= 20)
249
+ break;
250
+ }
251
+ // Step 5: Entrypoints
252
+ const entrypoints = [];
253
+ const entrypointNames = [
254
+ 'index.ts', 'index.js', 'main.ts', 'main.js',
255
+ 'app.ts', 'app.js', 'server.ts', 'server.js',
256
+ 'main.py', 'app.py', 'main.go', 'main.rs',
257
+ 'index.php', 'main.swift', 'main.rb', 'main.ex',
258
+ ];
259
+ const searchDirs = [projectRoot, path.join(projectRoot, 'src')];
260
+ for (const dir of searchDirs) {
261
+ for (const name of entrypointNames) {
262
+ if (entrypoints.length >= 10)
263
+ break;
264
+ const full = path.join(dir, name);
265
+ try {
266
+ if (fs.statSync(full).isFile()) {
267
+ entrypoints.push(path.relative(projectRoot, full));
268
+ }
269
+ }
270
+ catch {
271
+ // doesn't exist
272
+ }
273
+ }
274
+ }
275
+ return {
276
+ built_at: new Date().toISOString(),
277
+ modules,
278
+ dependency_edges: dependencyEdges,
279
+ untested_modules: untestedModules,
280
+ large_files: largeFiles,
281
+ entrypoints,
282
+ sampled_file_mtimes: sampledFileMtimes,
283
+ };
284
+ }
285
+ // ---------------------------------------------------------------------------
286
+ // refreshCodebaseIndex — incremental reindex, only re-scans changed modules
287
+ // ---------------------------------------------------------------------------
288
+ /**
289
+ * Incrementally refresh the codebase index. Re-walks the directory tree (cheap)
290
+ * but only re-scans imports for modules whose file count changed or that are new.
291
+ * Unchanged modules keep their existing dependency edges.
292
+ */
293
+ export function refreshCodebaseIndex(existing, projectRoot, excludeDirs = []) {
294
+ const fresh = buildCodebaseIndex(projectRoot, excludeDirs);
295
+ // Build lookup of old modules by path
296
+ const oldByPath = new Map(existing.modules.map(m => [m.path, m]));
297
+ // For unchanged modules (same path + same file_count), keep old dependency edges
298
+ // to avoid re-reading file contents. New/changed modules get fresh edges.
299
+ const mergedEdges = {};
300
+ for (const mod of fresh.modules) {
301
+ const old = oldByPath.get(mod.path);
302
+ if (old && old.file_count === mod.file_count) {
303
+ // Module unchanged — reuse existing edges
304
+ const oldEdges = existing.dependency_edges[mod.path];
305
+ if (oldEdges) {
306
+ mergedEdges[mod.path] = oldEdges;
307
+ }
308
+ }
309
+ else {
310
+ // New or changed module — use freshly scanned edges
311
+ const freshEdges = fresh.dependency_edges[mod.path];
312
+ if (freshEdges) {
313
+ mergedEdges[mod.path] = freshEdges;
314
+ }
315
+ }
316
+ }
317
+ fresh.dependency_edges = mergedEdges;
318
+ return fresh;
319
+ }
320
+ // ---------------------------------------------------------------------------
321
+ // hasStructuralChanges — cheap mtime check to detect external modifications
322
+ // ---------------------------------------------------------------------------
323
+ /**
324
+ * Check if the codebase structure has changed since the last index build.
325
+ *
326
+ * Two-layer detection:
327
+ * 1. Directory mtimes — catches file additions/deletions, new dirs, git pulls, branch switches.
328
+ * 2. Sampled file mtimes — catches content edits to files we scanned for imports (dependency edges).
329
+ *
330
+ * Cost: ≤60 dir statSync + ≤250 file statSync. Zero file reads, zero tokens.
331
+ */
332
+ export function hasStructuralChanges(index, projectRoot) {
333
+ const builtAt = new Date(index.built_at).getTime();
334
+ // Layer 1: Check directory mtimes (structural changes — add/delete/rename)
335
+ const dirsToCheck = new Set();
336
+ for (const mod of index.modules) {
337
+ const absPath = path.join(projectRoot, mod.path);
338
+ dirsToCheck.add(absPath);
339
+ // Also check parent dir (catches new sibling modules)
340
+ dirsToCheck.add(path.dirname(absPath));
341
+ }
342
+ // Always check root and src/ for new top-level dirs
343
+ dirsToCheck.add(projectRoot);
344
+ dirsToCheck.add(path.join(projectRoot, 'src'));
345
+ for (const dir of dirsToCheck) {
346
+ try {
347
+ if (fs.statSync(dir).mtimeMs > builtAt) {
348
+ return true;
349
+ }
350
+ }
351
+ catch {
352
+ // Dir was removed — structural change if it was a known module
353
+ const rel = path.relative(projectRoot, dir);
354
+ if (index.modules.some(m => m.path === rel)) {
355
+ return true;
356
+ }
357
+ }
358
+ }
359
+ // Layer 2: Check sampled file mtimes (content edits that may change imports)
360
+ for (const [relFile, oldMtime] of Object.entries(index.sampled_file_mtimes)) {
361
+ try {
362
+ const currentMtime = fs.statSync(path.join(projectRoot, relFile)).mtimeMs;
363
+ if (currentMtime !== oldMtime) {
364
+ return true;
365
+ }
366
+ }
367
+ catch {
368
+ // File was deleted — structural change
369
+ return true;
370
+ }
371
+ }
372
+ return false;
373
+ }
374
+ function existsDir(p) {
375
+ try {
376
+ return fs.statSync(p).isDirectory();
377
+ }
378
+ catch {
379
+ return false;
380
+ }
381
+ }
382
+ // ---------------------------------------------------------------------------
383
+ // formatIndexForPrompt — chunked rendering
384
+ // ---------------------------------------------------------------------------
385
+ const CHUNK_SIZE = 15;
386
+ export function formatIndexForPrompt(index, scoutCycle) {
387
+ const { modules, dependency_edges, untested_modules, large_files, entrypoints } = index;
388
+ if (modules.length === 0) {
389
+ return '## Codebase Structure\n\nNo modules detected.';
390
+ }
391
+ const totalChunks = Math.max(1, Math.ceil(modules.length / CHUNK_SIZE));
392
+ const chunkIndex = scoutCycle % totalChunks;
393
+ const offset = chunkIndex * CHUNK_SIZE;
394
+ const focusModules = modules.slice(offset, offset + CHUNK_SIZE);
395
+ const otherModules = modules.filter((_, i) => i < offset || i >= offset + CHUNK_SIZE);
396
+ const parts = [];
397
+ parts.push(`## Codebase Structure (chunk ${chunkIndex + 1}/${totalChunks})`);
398
+ parts.push('');
399
+ parts.push('### Modules in Focus This Cycle');
400
+ for (const mod of focusModules) {
401
+ const deps = dependency_edges[mod.path];
402
+ const depStr = deps ? ` → imports: ${deps.join(', ')}` : '';
403
+ parts.push(`${mod.path}/ — ${mod.file_count} files (${mod.purpose})${depStr}`);
404
+ }
405
+ if (otherModules.length > 0) {
406
+ parts.push('');
407
+ parts.push('### Other Modules (not in focus — available for future cycles)');
408
+ parts.push(otherModules.map(m => m.path + '/').join(', '));
409
+ }
410
+ if (untested_modules.length > 0) {
411
+ parts.push('');
412
+ parts.push('### Untested Modules (high-value scout targets)');
413
+ parts.push(untested_modules.map(m => m + '/').join(', '));
414
+ }
415
+ if (large_files.length > 0) {
416
+ parts.push('');
417
+ parts.push('### Complexity Hotspots (>300 LOC)');
418
+ parts.push(large_files.map(f => `${f.path} (${f.lines})`).join(', '));
419
+ }
420
+ if (entrypoints.length > 0) {
421
+ parts.push('');
422
+ parts.push('### Entrypoints');
423
+ parts.push(entrypoints.join(', '));
424
+ }
425
+ return parts.join('\n');
426
+ }
427
+ //# sourceMappingURL=codebase-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebase-index.js","sourceRoot":"","sources":["../../src/lib/codebase-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Cross-run learning mechanism.
3
+ *
4
+ * Persists learnings to `.blockspool/learnings.json` and provides
5
+ * decay, consolidation, relevance scoring, and prompt formatting.
6
+ *
7
+ * Copied from packages/mcp/src/learnings.ts with titleSimilarity
8
+ * inlined to avoid cross-package dependency.
9
+ */
10
+ export interface Learning {
11
+ id: string;
12
+ text: string;
13
+ category: 'gotcha' | 'pattern' | 'warning' | 'context';
14
+ source: {
15
+ type: 'qa_failure' | 'ticket_failure' | 'ticket_success' | 'review_downgrade' | 'plan_rejection' | 'scope_violation' | 'manual';
16
+ detail?: string;
17
+ };
18
+ tags: string[];
19
+ weight: number;
20
+ created_at: string;
21
+ last_confirmed_at: string;
22
+ access_count: number;
23
+ }
24
+ /**
25
+ * Load learnings, apply decay, prune dead entries, write back.
26
+ * Called once per session start.
27
+ */
28
+ export declare function loadLearnings(projectRoot: string, decayRate?: number): Learning[];
29
+ /**
30
+ * Add a new learning with sensible defaults.
31
+ */
32
+ export declare function addLearning(projectRoot: string, input: {
33
+ text: string;
34
+ category: Learning['category'];
35
+ source: Learning['source'];
36
+ tags?: string[];
37
+ }): Learning;
38
+ /**
39
+ * Confirm a learning: bump weight +10 and update last_confirmed_at.
40
+ */
41
+ export declare function confirmLearning(projectRoot: string, id: string): void;
42
+ /**
43
+ * Record access: increment access_count for each id.
44
+ */
45
+ export declare function recordAccess(projectRoot: string, ids: string[]): void;
46
+ /**
47
+ * Consolidate near-duplicate learnings (>70% text similarity).
48
+ * Keeps the higher weight entry, sums access counts.
49
+ */
50
+ export declare function consolidateLearnings(projectRoot: string): void;
51
+ /**
52
+ * Format learnings for prompt injection.
53
+ * Sorts by weight descending, respects char budget.
54
+ */
55
+ export declare function formatLearningsForPrompt(learnings: Learning[], budget?: number): string;
56
+ /**
57
+ * Select learnings relevant to the current context.
58
+ * Scores by tag overlap × weight.
59
+ */
60
+ export declare function selectRelevant(learnings: Learning[], context: {
61
+ paths?: string[];
62
+ commands?: string[];
63
+ }): Learning[];
64
+ /**
65
+ * Extract tags from paths and commands for tag matching.
66
+ */
67
+ export declare function extractTags(paths: string[], commands: string[]): string[];
68
+ //# sourceMappingURL=learnings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnings.d.ts","sourceRoot":"","sources":["../../src/lib/learnings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuCH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACvD,MAAM,EAAE;QACN,IAAI,EACA,YAAY,GACZ,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,iBAAiB,GACjB,QAAQ,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAgDD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,GAAE,MAA2B,GAAG,QAAQ,EAAE,CA4BrG;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE;IACL,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,GACA,QAAQ,CAiBV;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAOrE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAUrE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CA0B9D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,MAAM,GAAE,MAAuB,GAAG,MAAM,CAqBvG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,QAAQ,EAAE,CAgBpH;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAWzE"}