@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.
- package/dist/codebase-index/index.d.ts +23 -0
- package/dist/codebase-index/index.d.ts.map +1 -0
- package/dist/codebase-index/index.js +361 -0
- package/dist/codebase-index/index.js.map +1 -0
- package/dist/codebase-index/shared.d.ts +95 -0
- package/dist/codebase-index/shared.d.ts.map +1 -0
- package/dist/codebase-index/shared.js +319 -0
- package/dist/codebase-index/shared.js.map +1 -0
- package/dist/config/defaults.d.ts +45 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +79 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/critic/shared.d.ts +49 -0
- package/dist/critic/shared.d.ts.map +1 -0
- package/dist/critic/shared.js +204 -0
- package/dist/critic/shared.js.map +1 -0
- package/dist/db/adapter.d.ts +191 -0
- package/dist/db/adapter.d.ts.map +1 -0
- package/dist/db/adapter.js +40 -0
- package/dist/db/adapter.js.map +1 -0
- package/dist/db/contract.d.ts +47 -0
- package/dist/db/contract.d.ts.map +1 -0
- package/dist/db/contract.js +258 -0
- package/dist/db/contract.js.map +1 -0
- package/dist/db/index.d.ts +6 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +7 -0
- package/dist/db/index.js.map +1 -0
- package/dist/dedup/shared.d.ts +82 -0
- package/dist/dedup/shared.d.ts.map +1 -0
- package/dist/dedup/shared.js +215 -0
- package/dist/dedup/shared.js.map +1 -0
- package/dist/exec/index.d.ts +5 -0
- package/dist/exec/index.d.ts.map +1 -0
- package/dist/exec/index.js +5 -0
- package/dist/exec/index.js.map +1 -0
- package/dist/exec/types.d.ts +64 -0
- package/dist/exec/types.d.ts.map +1 -0
- package/dist/exec/types.js +8 -0
- package/dist/exec/types.js.map +1 -0
- package/dist/formulas/shared.d.ts +42 -0
- package/dist/formulas/shared.d.ts.map +1 -0
- package/dist/formulas/shared.js +204 -0
- package/dist/formulas/shared.js.map +1 -0
- package/dist/guidelines/shared.d.ts +46 -0
- package/dist/guidelines/shared.d.ts.map +1 -0
- package/dist/guidelines/shared.js +128 -0
- package/dist/guidelines/shared.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/learnings/shared.d.ts +112 -0
- package/dist/learnings/shared.d.ts.map +1 -0
- package/dist/learnings/shared.js +402 -0
- package/dist/learnings/shared.js.map +1 -0
- package/dist/proposals/shared.d.ts +137 -0
- package/dist/proposals/shared.d.ts.map +1 -0
- package/dist/proposals/shared.js +254 -0
- package/dist/proposals/shared.js.map +1 -0
- package/dist/repos/index.d.ts +15 -0
- package/dist/repos/index.d.ts.map +1 -0
- package/dist/repos/index.js +11 -0
- package/dist/repos/index.js.map +1 -0
- package/dist/repos/projects.d.ts +41 -0
- package/dist/repos/projects.d.ts.map +1 -0
- package/dist/repos/projects.js +75 -0
- package/dist/repos/projects.js.map +1 -0
- package/dist/repos/run_steps.d.ts +152 -0
- package/dist/repos/run_steps.d.ts.map +1 -0
- package/dist/repos/run_steps.js +328 -0
- package/dist/repos/run_steps.js.map +1 -0
- package/dist/repos/runs.d.ts +92 -0
- package/dist/repos/runs.d.ts.map +1 -0
- package/dist/repos/runs.js +185 -0
- package/dist/repos/runs.js.map +1 -0
- package/dist/repos/tickets.d.ts +71 -0
- package/dist/repos/tickets.d.ts.map +1 -0
- package/dist/repos/tickets.js +158 -0
- package/dist/repos/tickets.js.map +1 -0
- package/dist/scope/shared.d.ts +67 -0
- package/dist/scope/shared.d.ts.map +1 -0
- package/dist/scope/shared.js +355 -0
- package/dist/scope/shared.js.map +1 -0
- package/dist/scout/index.d.ts +18 -0
- package/dist/scout/index.d.ts.map +1 -0
- package/dist/scout/index.js +445 -0
- package/dist/scout/index.js.map +1 -0
- package/dist/scout/kimi-runner.d.ts +21 -0
- package/dist/scout/kimi-runner.d.ts.map +1 -0
- package/dist/scout/kimi-runner.js +76 -0
- package/dist/scout/kimi-runner.js.map +1 -0
- package/dist/scout/mcp-batch-server.d.ts +37 -0
- package/dist/scout/mcp-batch-server.d.ts.map +1 -0
- package/dist/scout/mcp-batch-server.js +144 -0
- package/dist/scout/mcp-batch-server.js.map +1 -0
- package/dist/scout/openai-local-runner.d.ts +20 -0
- package/dist/scout/openai-local-runner.d.ts.map +1 -0
- package/dist/scout/openai-local-runner.js +82 -0
- package/dist/scout/openai-local-runner.js.map +1 -0
- package/dist/scout/prompt.d.ts +49 -0
- package/dist/scout/prompt.d.ts.map +1 -0
- package/dist/scout/prompt.js +153 -0
- package/dist/scout/prompt.js.map +1 -0
- package/dist/scout/runner.d.ts +101 -0
- package/dist/scout/runner.d.ts.map +1 -0
- package/dist/scout/runner.js +521 -0
- package/dist/scout/runner.js.map +1 -0
- package/dist/scout/scanner.d.ts +61 -0
- package/dist/scout/scanner.d.ts.map +1 -0
- package/dist/scout/scanner.js +315 -0
- package/dist/scout/scanner.js.map +1 -0
- package/dist/scout/types.d.ts +221 -0
- package/dist/scout/types.d.ts.map +1 -0
- package/dist/scout/types.js +44 -0
- package/dist/scout/types.js.map +1 -0
- package/dist/sectors/shared.d.ts +146 -0
- package/dist/sectors/shared.d.ts.map +1 -0
- package/dist/sectors/shared.js +408 -0
- package/dist/sectors/shared.js.map +1 -0
- package/dist/services/index.d.ts +10 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +9 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/qa.d.ts +76 -0
- package/dist/services/qa.d.ts.map +1 -0
- package/dist/services/qa.js +228 -0
- package/dist/services/qa.js.map +1 -0
- package/dist/services/scout.d.ts +164 -0
- package/dist/services/scout.d.ts.map +1 -0
- package/dist/services/scout.js +215 -0
- package/dist/services/scout.js.map +1 -0
- package/dist/spindle/shared.d.ts +14 -0
- package/dist/spindle/shared.d.ts.map +1 -0
- package/dist/spindle/shared.js +65 -0
- package/dist/spindle/shared.js.map +1 -0
- package/dist/tools/shared.d.ts +35 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +247 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/trace/shared.d.ts +147 -0
- package/dist/trace/shared.d.ts.map +1 -0
- package/dist/trace/shared.js +414 -0
- package/dist/trace/shared.js.map +1 -0
- package/dist/trajectory/shared.d.ts +69 -0
- package/dist/trajectory/shared.d.ts.map +1 -0
- package/dist/trajectory/shared.js +336 -0
- package/dist/trajectory/shared.js.map +1 -0
- package/dist/utils/id.d.ts +12 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +24 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/id.test.d.ts +5 -0
- package/dist/utils/id.test.d.ts.map +1 -0
- package/dist/utils/id.test.js +173 -0
- package/dist/utils/id.test.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/json.d.ts +9 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +19 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/waves/shared.d.ts +106 -0
- package/dist/waves/shared.d.ts.map +1 -0
- package/dist/waves/shared.js +356 -0
- package/dist/waves/shared.js.map +1 -0
- package/package.json +126 -0
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
* Pure algorithms (classification, import extraction, formatting) live in ./shared.ts.
|
|
8
|
+
* This file provides the I/O-heavy functions that use the filesystem and git.
|
|
9
|
+
*
|
|
10
|
+
* Single source of truth — imported by both @promptwheel/cli and @promptwheel/mcp.
|
|
11
|
+
*/
|
|
12
|
+
export { type CodebaseIndex, type ClassificationConfidence, type ModuleEntry, type LargeFileEntry, type ClassifyResult, SOURCE_EXTENSIONS, PURPOSE_HINT, NON_PRODUCTION_PURPOSES, CHUNK_SIZE, purposeHintFromDirName, sampleEvenly, countNonProdFiles, classifyModule, extractImports, resolveImportToModule, formatIndexForPrompt, } from './shared.js';
|
|
13
|
+
import type { CodebaseIndex } from './shared.js';
|
|
14
|
+
/**
|
|
15
|
+
* Use `git ls-files` to discover which top-level directories contain tracked
|
|
16
|
+
* (or unignored) files. Returns null if git is unavailable or the project
|
|
17
|
+
* is not a git repo — callers should fall back to hardcoded excludes.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getTrackedDirectories(projectRoot: string): Set<string> | null;
|
|
20
|
+
export declare function buildCodebaseIndex(projectRoot: string, excludeDirs?: string[], useGitTracking?: boolean): CodebaseIndex;
|
|
21
|
+
export declare function refreshCodebaseIndex(existing: CodebaseIndex, projectRoot: string, excludeDirs?: string[], useGitTracking?: boolean): CodebaseIndex;
|
|
22
|
+
export declare function hasStructuralChanges(index: CodebaseIndex, projectRoot: string): boolean;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codebase-index/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,wBAAwB,EAC7B,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,iBAAiB,EACjB,YAAY,EACZ,uBAAuB,EACvB,UAAU,EACV,sBAAsB,EACtB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,aAAa,EAA+B,MAAM,aAAa,CAAC;AAyC9E;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAe7E;AAMD,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAAM,EAAO,EAC1B,cAAc,UAAO,GACpB,aAAa,CAkPf;AAMD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAAM,EAAO,EAC1B,cAAc,UAAO,GACpB,aAAa,CAwBf;AAMD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CAuCT"}
|
|
@@ -0,0 +1,361 @@
|
|
|
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
|
+
* Pure algorithms (classification, import extraction, formatting) live in ./shared.ts.
|
|
8
|
+
* This file provides the I/O-heavy functions that use the filesystem and git.
|
|
9
|
+
*
|
|
10
|
+
* Single source of truth — imported by both @promptwheel/cli and @promptwheel/mcp.
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'node:fs';
|
|
13
|
+
import * as path from 'node:path';
|
|
14
|
+
import { execFileSync } from 'node:child_process';
|
|
15
|
+
// Re-export everything from shared (pure algorithms + types + constants)
|
|
16
|
+
export { SOURCE_EXTENSIONS, PURPOSE_HINT, NON_PRODUCTION_PURPOSES, CHUNK_SIZE, purposeHintFromDirName, sampleEvenly, countNonProdFiles, classifyModule, extractImports, resolveImportToModule, formatIndexForPrompt, } from './shared.js';
|
|
17
|
+
import { SOURCE_EXTENSIONS, sampleEvenly, classifyModule, extractImports, resolveImportToModule, } from './shared.js';
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// I/O helpers
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Read a short header snippet from a file (first 512 bytes, ~12 lines).
|
|
23
|
+
* Cheaper than the full 4KB read used for import scanning.
|
|
24
|
+
*/
|
|
25
|
+
function readHeader(filePath) {
|
|
26
|
+
try {
|
|
27
|
+
const fd = fs.openSync(filePath, 'r');
|
|
28
|
+
const buf = Buffer.alloc(512);
|
|
29
|
+
const bytesRead = fs.readSync(fd, buf, 0, 512, 0);
|
|
30
|
+
fs.closeSync(fd);
|
|
31
|
+
return buf.toString('utf8', 0, bytesRead);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function existsDir(p) {
|
|
38
|
+
try {
|
|
39
|
+
return fs.statSync(p).isDirectory();
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Git-aware directory filtering
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
/**
|
|
49
|
+
* Use `git ls-files` to discover which top-level directories contain tracked
|
|
50
|
+
* (or unignored) files. Returns null if git is unavailable or the project
|
|
51
|
+
* is not a git repo — callers should fall back to hardcoded excludes.
|
|
52
|
+
*/
|
|
53
|
+
export function getTrackedDirectories(projectRoot) {
|
|
54
|
+
try {
|
|
55
|
+
const stdout = execFileSync('git', ['ls-files', '--cached', '--others', '--exclude-standard'], {
|
|
56
|
+
cwd: projectRoot, maxBuffer: 10 * 1024 * 1024, encoding: 'utf8',
|
|
57
|
+
});
|
|
58
|
+
const dirs = new Set();
|
|
59
|
+
for (const line of stdout.split('\n')) {
|
|
60
|
+
if (!line)
|
|
61
|
+
continue;
|
|
62
|
+
const parts = line.split('/');
|
|
63
|
+
if (parts.length > 1)
|
|
64
|
+
dirs.add(parts[0]);
|
|
65
|
+
}
|
|
66
|
+
return dirs;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null; // Not a git repo or git not available
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
// buildCodebaseIndex
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
export function buildCodebaseIndex(projectRoot, excludeDirs = [], useGitTracking = true) {
|
|
76
|
+
const excludeSet = new Set(excludeDirs.map(d => d.toLowerCase()));
|
|
77
|
+
// Git-aware filtering: only walk directories that contain tracked files
|
|
78
|
+
const trackedDirs = useGitTracking ? getTrackedDirectories(projectRoot) : null;
|
|
79
|
+
// Step 1: Module map — walk dirs 2 levels deep
|
|
80
|
+
const modules = [];
|
|
81
|
+
const sourceFilesByModule = new Map();
|
|
82
|
+
function shouldExclude(name) {
|
|
83
|
+
if (excludeSet.has(name.toLowerCase()) || name.startsWith('.'))
|
|
84
|
+
return true;
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
function walkForModules(dir, depth) {
|
|
88
|
+
if (modules.length >= 80)
|
|
89
|
+
return;
|
|
90
|
+
let entries;
|
|
91
|
+
try {
|
|
92
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const sourceFiles = [];
|
|
98
|
+
const subdirs = [];
|
|
99
|
+
for (const entry of entries) {
|
|
100
|
+
if (entry.isFile() && SOURCE_EXTENSIONS.has(path.extname(entry.name))) {
|
|
101
|
+
sourceFiles.push(path.join(dir, entry.name));
|
|
102
|
+
}
|
|
103
|
+
else if (entry.isDirectory() && !shouldExclude(entry.name)) {
|
|
104
|
+
// At depth 0 (project root), skip directories not tracked by git
|
|
105
|
+
if (depth === 0 && trackedDirs && !trackedDirs.has(entry.name)) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
subdirs.push(entry);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Register this dir as a module if it has source files
|
|
112
|
+
if (sourceFiles.length > 0 && depth > 0) {
|
|
113
|
+
const relPath = path.relative(projectRoot, dir);
|
|
114
|
+
if (relPath && modules.length < 80) {
|
|
115
|
+
// Placeholder — classified after import scanning (Step 2)
|
|
116
|
+
modules.push({
|
|
117
|
+
path: relPath,
|
|
118
|
+
file_count: sourceFiles.length,
|
|
119
|
+
production_file_count: sourceFiles.length,
|
|
120
|
+
purpose: 'unknown',
|
|
121
|
+
production: true,
|
|
122
|
+
classification_confidence: 'low',
|
|
123
|
+
});
|
|
124
|
+
sourceFilesByModule.set(relPath, sourceFiles);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Recurse into subdirs (up to depth 2)
|
|
128
|
+
if (depth < 3) {
|
|
129
|
+
for (const sub of subdirs) {
|
|
130
|
+
if (modules.length >= 80)
|
|
131
|
+
break;
|
|
132
|
+
walkForModules(path.join(dir, sub.name), depth + 1);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
walkForModules(projectRoot, 0);
|
|
137
|
+
const modulePaths = modules.map(m => m.path);
|
|
138
|
+
// Step 2: Import scanning + content sampling — build dependency_edges, classify modules
|
|
139
|
+
const dependencyEdges = {};
|
|
140
|
+
const sampledFileMtimes = {};
|
|
141
|
+
const contentByModule = new Map();
|
|
142
|
+
for (const mod of modules) {
|
|
143
|
+
const files = sourceFilesByModule.get(mod.path) ?? [];
|
|
144
|
+
const deps = new Set();
|
|
145
|
+
const snippets = [];
|
|
146
|
+
// Sample up to 5 files evenly for full import scanning (4KB read)
|
|
147
|
+
const filesToScan = sampleEvenly(files, 5);
|
|
148
|
+
for (const filePath of filesToScan) {
|
|
149
|
+
try {
|
|
150
|
+
// Record mtime for change detection
|
|
151
|
+
const relFile = path.relative(projectRoot, filePath);
|
|
152
|
+
sampledFileMtimes[relFile] = fs.statSync(filePath).mtimeMs;
|
|
153
|
+
const fd = fs.openSync(filePath, 'r');
|
|
154
|
+
const buf = Buffer.alloc(4096);
|
|
155
|
+
const bytesRead = fs.readSync(fd, buf, 0, 4096, 0);
|
|
156
|
+
fs.closeSync(fd);
|
|
157
|
+
// Skip binary files (check for null bytes in first 512 bytes of actual content)
|
|
158
|
+
const checkLen = Math.min(bytesRead, 512);
|
|
159
|
+
if (checkLen > 0 && buf.subarray(0, checkLen).indexOf(0) !== -1)
|
|
160
|
+
continue;
|
|
161
|
+
const content = buf.toString('utf8', 0, bytesRead);
|
|
162
|
+
// Trim to ~50 lines
|
|
163
|
+
const lines = content.split('\n').slice(0, 50).join('\n');
|
|
164
|
+
snippets.push(lines);
|
|
165
|
+
const imports = extractImports(lines, filePath);
|
|
166
|
+
for (const spec of imports) {
|
|
167
|
+
const resolved = resolveImportToModule(spec, filePath, projectRoot, modulePaths);
|
|
168
|
+
if (resolved && resolved !== mod.path) {
|
|
169
|
+
deps.add(resolved);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// skip unreadable files
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Sample additional files for classification (header-only, 512B — cheap)
|
|
178
|
+
const scannedSet = new Set(filesToScan);
|
|
179
|
+
const extraFiles = sampleEvenly(files.filter(f => !scannedSet.has(f)), 10);
|
|
180
|
+
for (const filePath of extraFiles) {
|
|
181
|
+
const header = readHeader(filePath);
|
|
182
|
+
if (header)
|
|
183
|
+
snippets.push(header);
|
|
184
|
+
}
|
|
185
|
+
contentByModule.set(mod.path, snippets);
|
|
186
|
+
if (deps.size > 0) {
|
|
187
|
+
dependencyEdges[mod.path] = [...deps];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Step 2b: Classify modules using ALL file names + sampled content
|
|
191
|
+
for (const mod of modules) {
|
|
192
|
+
const files = sourceFilesByModule.get(mod.path) ?? [];
|
|
193
|
+
const allFileNames = files.map(f => path.basename(f));
|
|
194
|
+
const snippets = contentByModule.get(mod.path) ?? [];
|
|
195
|
+
const { purpose, production, productionFileCount, confidence } = classifyModule(path.basename(path.join(projectRoot, mod.path)), allFileNames, snippets, mod.file_count);
|
|
196
|
+
mod.purpose = purpose;
|
|
197
|
+
mod.production = production;
|
|
198
|
+
mod.production_file_count = productionFileCount;
|
|
199
|
+
mod.classification_confidence = confidence;
|
|
200
|
+
}
|
|
201
|
+
// Step 3: Test coverage — find untested modules
|
|
202
|
+
const untestedModules = [];
|
|
203
|
+
for (const mod of modules) {
|
|
204
|
+
if (mod.purpose === 'tests')
|
|
205
|
+
continue;
|
|
206
|
+
const modAbsPath = path.join(projectRoot, mod.path);
|
|
207
|
+
const modParent = path.dirname(modAbsPath);
|
|
208
|
+
let hasTesting = false;
|
|
209
|
+
if (existsDir(path.join(modAbsPath, '__tests__'))) {
|
|
210
|
+
hasTesting = true;
|
|
211
|
+
}
|
|
212
|
+
if (!hasTesting && (existsDir(path.join(modParent, 'test')) || existsDir(path.join(modParent, 'tests')))) {
|
|
213
|
+
hasTesting = true;
|
|
214
|
+
}
|
|
215
|
+
if (!hasTesting) {
|
|
216
|
+
const files = sourceFilesByModule.get(mod.path) ?? [];
|
|
217
|
+
hasTesting = files.some(f => {
|
|
218
|
+
const base = path.basename(f);
|
|
219
|
+
return base.includes('.test.') || base.includes('.spec.');
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (!hasTesting) {
|
|
223
|
+
untestedModules.push(mod.path);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Step 4: Large files — stat.size / 40 heuristic for LOC
|
|
227
|
+
const largeFiles = [];
|
|
228
|
+
for (const mod of modules) {
|
|
229
|
+
const files = sourceFilesByModule.get(mod.path) ?? [];
|
|
230
|
+
for (const filePath of files) {
|
|
231
|
+
if (largeFiles.length >= 20)
|
|
232
|
+
break;
|
|
233
|
+
try {
|
|
234
|
+
const stat = fs.statSync(filePath);
|
|
235
|
+
// Heuristic: ~45 bytes/line for code (accounts for indentation)
|
|
236
|
+
const estimatedLines = Math.round(stat.size / 45);
|
|
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', 'manage.py', 'wsgi.py',
|
|
257
|
+
'main.go',
|
|
258
|
+
'main.rs', 'lib.rs',
|
|
259
|
+
'index.php', 'artisan',
|
|
260
|
+
'main.swift',
|
|
261
|
+
'main.rb', 'config/application.rb',
|
|
262
|
+
'main.ex', 'lib.ex',
|
|
263
|
+
'main.dart', 'lib/main.dart',
|
|
264
|
+
'Main.java', 'Application.java',
|
|
265
|
+
'Program.cs', 'Main.cs', // C#
|
|
266
|
+
'Main.scala', // Scala
|
|
267
|
+
'main.c', 'main.cpp',
|
|
268
|
+
'Main.hs',
|
|
269
|
+
'main.zig',
|
|
270
|
+
];
|
|
271
|
+
const searchDirs = [projectRoot, path.join(projectRoot, 'src'), path.join(projectRoot, 'cmd')];
|
|
272
|
+
for (const dir of searchDirs) {
|
|
273
|
+
for (const name of entrypointNames) {
|
|
274
|
+
if (entrypoints.length >= 10)
|
|
275
|
+
break;
|
|
276
|
+
const full = path.join(dir, name);
|
|
277
|
+
try {
|
|
278
|
+
if (fs.statSync(full).isFile()) {
|
|
279
|
+
entrypoints.push(path.relative(projectRoot, full));
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
// doesn't exist
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
built_at: new Date().toISOString(),
|
|
289
|
+
modules,
|
|
290
|
+
dependency_edges: dependencyEdges,
|
|
291
|
+
untested_modules: untestedModules,
|
|
292
|
+
large_files: largeFiles,
|
|
293
|
+
entrypoints,
|
|
294
|
+
sampled_file_mtimes: sampledFileMtimes,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
// ---------------------------------------------------------------------------
|
|
298
|
+
// refreshCodebaseIndex
|
|
299
|
+
// ---------------------------------------------------------------------------
|
|
300
|
+
export function refreshCodebaseIndex(existing, projectRoot, excludeDirs = [], useGitTracking = true) {
|
|
301
|
+
const fresh = buildCodebaseIndex(projectRoot, excludeDirs, useGitTracking);
|
|
302
|
+
const oldByPath = new Map(existing.modules.map(m => [m.path, m]));
|
|
303
|
+
const mergedEdges = {};
|
|
304
|
+
for (const mod of fresh.modules) {
|
|
305
|
+
const old = oldByPath.get(mod.path);
|
|
306
|
+
if (old && old.file_count === mod.file_count) {
|
|
307
|
+
const oldEdges = existing.dependency_edges[mod.path];
|
|
308
|
+
if (oldEdges) {
|
|
309
|
+
mergedEdges[mod.path] = oldEdges;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
const freshEdges = fresh.dependency_edges[mod.path];
|
|
314
|
+
if (freshEdges) {
|
|
315
|
+
mergedEdges[mod.path] = freshEdges;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
fresh.dependency_edges = mergedEdges;
|
|
320
|
+
return fresh;
|
|
321
|
+
}
|
|
322
|
+
// ---------------------------------------------------------------------------
|
|
323
|
+
// hasStructuralChanges
|
|
324
|
+
// ---------------------------------------------------------------------------
|
|
325
|
+
export function hasStructuralChanges(index, projectRoot) {
|
|
326
|
+
const builtAt = new Date(index.built_at).getTime();
|
|
327
|
+
const dirsToCheck = new Set();
|
|
328
|
+
for (const mod of index.modules) {
|
|
329
|
+
const absPath = path.join(projectRoot, mod.path);
|
|
330
|
+
dirsToCheck.add(absPath);
|
|
331
|
+
dirsToCheck.add(path.dirname(absPath));
|
|
332
|
+
}
|
|
333
|
+
dirsToCheck.add(projectRoot);
|
|
334
|
+
dirsToCheck.add(path.join(projectRoot, 'src'));
|
|
335
|
+
for (const dir of dirsToCheck) {
|
|
336
|
+
try {
|
|
337
|
+
if (fs.statSync(dir).mtimeMs > builtAt) {
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
const rel = path.relative(projectRoot, dir);
|
|
343
|
+
if (index.modules.some(m => m.path === rel)) {
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
for (const [relFile, oldMtime] of Object.entries(index.sampled_file_mtimes)) {
|
|
349
|
+
try {
|
|
350
|
+
const currentMtime = fs.statSync(path.join(projectRoot, relFile)).mtimeMs;
|
|
351
|
+
if (currentMtime !== oldMtime) {
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
return true;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/codebase-index/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codebase index shared algorithms — pure functions for module classification,
|
|
3
|
+
* import extraction, dependency resolution, and prompt formatting.
|
|
4
|
+
*
|
|
5
|
+
* No filesystem, git, or child_process I/O. The I/O-heavy functions
|
|
6
|
+
* (buildCodebaseIndex, refreshCodebaseIndex, hasStructuralChanges) live
|
|
7
|
+
* in ./index.ts and import these pure algorithms.
|
|
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 type ClassificationConfidence = 'high' | 'medium' | 'low';
|
|
20
|
+
export interface ModuleEntry {
|
|
21
|
+
path: string;
|
|
22
|
+
file_count: number;
|
|
23
|
+
production_file_count: number;
|
|
24
|
+
purpose: string;
|
|
25
|
+
production: boolean;
|
|
26
|
+
/** How confident the classifier is. 'low' means no signals matched — assumed production. */
|
|
27
|
+
classification_confidence: ClassificationConfidence;
|
|
28
|
+
}
|
|
29
|
+
export interface LargeFileEntry {
|
|
30
|
+
path: string;
|
|
31
|
+
lines: number;
|
|
32
|
+
}
|
|
33
|
+
export interface ClassifyResult {
|
|
34
|
+
purpose: string;
|
|
35
|
+
production: boolean;
|
|
36
|
+
productionFileCount: number;
|
|
37
|
+
confidence: ClassificationConfidence;
|
|
38
|
+
}
|
|
39
|
+
export declare const SOURCE_EXTENSIONS: Set<string>;
|
|
40
|
+
/** Directory-name hint — fast path when the name is unambiguous. */
|
|
41
|
+
export declare const PURPOSE_HINT: Record<string, string>;
|
|
42
|
+
export declare const NON_PRODUCTION_PURPOSES: Set<string>;
|
|
43
|
+
/** Chunk size for prompt rendering. */
|
|
44
|
+
export declare const CHUNK_SIZE = 15;
|
|
45
|
+
/** File-name patterns that indicate non-production files (even within production modules). */
|
|
46
|
+
export declare const NON_PROD_FILE_RE: RegExp;
|
|
47
|
+
/**
|
|
48
|
+
* Polyglot test-content patterns — matches test framework calls across languages.
|
|
49
|
+
*/
|
|
50
|
+
export declare const TEST_CONTENT_RE: RegExp;
|
|
51
|
+
export declare const GENERATED_RE: RegExp;
|
|
52
|
+
export declare const CONFIG_CONTENT_RE: RegExp;
|
|
53
|
+
export declare const CONFIG_EXT_RE: RegExp;
|
|
54
|
+
export declare const FIXTURE_CONTENT_RE: RegExp;
|
|
55
|
+
export declare const JS_IMPORT_RE: RegExp;
|
|
56
|
+
export declare const PY_IMPORT_RE: RegExp;
|
|
57
|
+
export declare const GO_IMPORT_RE: RegExp;
|
|
58
|
+
/** Map directory name to a purpose hint. Returns 'unknown' if no match. */
|
|
59
|
+
export declare function purposeHintFromDirName(dirName: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Pick up to `count` items, evenly spaced across the array.
|
|
62
|
+
* Avoids alphabetical bias of always sampling the first N.
|
|
63
|
+
*/
|
|
64
|
+
export declare function sampleEvenly<T>(arr: T[], count: number): T[];
|
|
65
|
+
/** Count non-production files by name pattern within a file list. */
|
|
66
|
+
export declare function countNonProdFiles(fileNames: string[]): number;
|
|
67
|
+
/**
|
|
68
|
+
* Classify a module by analyzing its file names and content snippets.
|
|
69
|
+
*
|
|
70
|
+
* Uses file-name patterns (checked against ALL files — cheap string matching)
|
|
71
|
+
* and content analysis (sampled snippets from evenly-distributed files).
|
|
72
|
+
*
|
|
73
|
+
* Thresholds use both ratio AND absolute count to avoid misclassifying
|
|
74
|
+
* large mixed modules (40% test in a 500-file module ≠ production).
|
|
75
|
+
*/
|
|
76
|
+
export declare function classifyModule(dirName: string, allFileNames: string[], contentSnippets: string[], totalFileCount: number): ClassifyResult;
|
|
77
|
+
/**
|
|
78
|
+
* Extract import specifiers from file content using polyglot regex patterns.
|
|
79
|
+
* Supports JS/TS, Python, and Go.
|
|
80
|
+
*/
|
|
81
|
+
export declare function extractImports(content: string, filePath: string): string[];
|
|
82
|
+
/**
|
|
83
|
+
* Resolve a relative import specifier to a module path relative to projectRoot.
|
|
84
|
+
* Returns null for non-relative (package) imports.
|
|
85
|
+
*/
|
|
86
|
+
export declare function resolveImportToModule(specifier: string, sourceFile: string, projectRoot: string, modulePaths: string[]): string | null;
|
|
87
|
+
/**
|
|
88
|
+
* Format a codebase index for injection into a scout prompt.
|
|
89
|
+
*
|
|
90
|
+
* Chunks modules (15 per chunk) and rotates by cycle number so all modules
|
|
91
|
+
* get exposure over multiple cycles. Includes untested modules, hotspots,
|
|
92
|
+
* and entrypoints.
|
|
93
|
+
*/
|
|
94
|
+
export declare function formatIndexForPrompt(index: CodebaseIndex, scoutCycle: number): string;
|
|
95
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/codebase-index/shared.ts"],"names":[],"mappings":"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"}
|