milens 0.7.0 → 0.7.2
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/.agents/skills/adapters/SKILL.md +59 -51
- package/.agents/skills/analyzer/SKILL.md +23 -21
- package/.agents/skills/apps/SKILL.md +65 -68
- package/.agents/skills/docs/SKILL.md +10 -25
- package/.agents/skills/milens/SKILL.md +11 -8
- package/.agents/skills/orchestrator/SKILL.md +13 -10
- package/.agents/skills/parser/SKILL.md +15 -12
- package/.agents/skills/root/SKILL.md +30 -29
- package/.agents/skills/scripts/SKILL.md +18 -16
- package/.agents/skills/security/SKILL.md +7 -7
- package/.agents/skills/server/SKILL.md +36 -26
- package/.agents/skills/store/SKILL.md +24 -23
- package/.agents/skills/test/SKILL.md +24 -22
- package/.agents/skills/ui/SKILL.md +6 -1
- package/README.md +12 -3
- package/adapters/README.md +144 -107
- package/adapters/claude-code/.claude/settings.json.hooks-snippet.json +26 -0
- package/adapters/claude-code/.claude-plugin/plugin.json +11 -0
- package/adapters/claude-code/.mcp.json +9 -0
- package/adapters/claude-code/CLAUDE.md +2 -0
- package/adapters/claude-code/hooks/hooks.json +27 -0
- package/adapters/codex/.codex/config.toml +3 -0
- package/adapters/copilot/.vscode/mcp.json +10 -0
- package/adapters/cursor/.cursor/mcp.json +9 -0
- package/adapters/cursor/.cursorrules +69 -9
- package/adapters/gemini/.gemini/settings.json +9 -0
- package/dist/agents-md.d.ts +1 -1
- package/dist/agents-md.js +47 -3
- package/dist/agents-md.js.map +1 -1
- package/dist/analyzer/config.d.ts +0 -1
- package/dist/analyzer/config.js +32 -0
- package/dist/analyzer/config.js.map +1 -1
- package/dist/analyzer/engine.d.ts +0 -1
- package/dist/analyzer/engine.js +67 -41
- package/dist/analyzer/engine.js.map +1 -1
- package/dist/analyzer/enrich.d.ts +0 -1
- package/dist/analyzer/enrich.js +81 -1
- package/dist/analyzer/enrich.js.map +1 -1
- package/dist/analyzer/resolver.d.ts +4 -2
- package/dist/analyzer/resolver.js +283 -36
- package/dist/analyzer/resolver.js.map +1 -1
- package/dist/analyzer/review.d.ts +2 -2
- package/dist/analyzer/review.js +39 -61
- package/dist/analyzer/review.js.map +1 -1
- package/dist/analyzer/risk.d.ts +20 -0
- package/dist/analyzer/risk.js +76 -0
- package/dist/analyzer/risk.js.map +1 -0
- package/dist/analyzer/scanner.d.ts +0 -1
- package/dist/analyzer/scanner.js +5 -4
- package/dist/analyzer/scanner.js.map +1 -1
- package/dist/analyzer/scope-resolver.d.ts +0 -1
- package/dist/analyzer/scope-resolver.js +2 -2
- package/dist/analyzer/scope-resolver.js.map +1 -1
- package/dist/build-info.d.ts +2 -0
- package/dist/build-info.js +4 -0
- package/dist/build-info.js.map +1 -0
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +225 -30
- package/dist/cli.js.map +1 -1
- package/dist/metrics.d.ts +0 -1
- package/dist/orchestrator/orchestrator.d.ts +1 -2
- package/dist/orchestrator/orchestrator.js +30 -7
- package/dist/orchestrator/orchestrator.js.map +1 -1
- package/dist/orchestrator/reporter.d.ts +0 -1
- package/dist/parser/extract.d.ts +7 -1
- package/dist/parser/extract.js +76 -29
- package/dist/parser/extract.js.map +1 -1
- package/dist/parser/lang-css.d.ts +0 -1
- package/dist/parser/lang-css.js +12 -0
- package/dist/parser/lang-css.js.map +1 -1
- package/dist/parser/lang-go.d.ts +0 -1
- package/dist/parser/lang-html.d.ts +0 -1
- package/dist/parser/lang-java.d.ts +0 -1
- package/dist/parser/lang-js.d.ts +0 -1
- package/dist/parser/lang-js.js +15 -4
- package/dist/parser/lang-js.js.map +1 -1
- package/dist/parser/lang-md.d.ts +0 -1
- package/dist/parser/lang-md.js +1 -0
- package/dist/parser/lang-md.js.map +1 -1
- package/dist/parser/lang-php.d.ts +0 -1
- package/dist/parser/lang-py.d.ts +0 -1
- package/dist/parser/lang-ruby.d.ts +0 -1
- package/dist/parser/lang-rust.d.ts +0 -1
- package/dist/parser/lang-ts.d.ts +0 -1
- package/dist/parser/lang-ts.js +40 -6
- package/dist/parser/lang-ts.js.map +1 -1
- package/dist/parser/lang-vue.d.ts +0 -1
- package/dist/parser/lang-vue.js +0 -21
- package/dist/parser/lang-vue.js.map +1 -1
- package/dist/parser/language-provider.d.ts +0 -1
- package/dist/parser/languages.d.ts +0 -1
- package/dist/parser/loader.d.ts +0 -1
- package/dist/security/deps.d.ts +0 -1
- package/dist/security/rules.d.ts +0 -1
- package/dist/security/rules.js +35 -35
- package/dist/security/rules.js.map +1 -1
- package/dist/server/guard-hook.d.ts +10 -0
- package/dist/server/guard-hook.js +179 -0
- package/dist/server/guard-hook.js.map +1 -0
- package/dist/server/hooks.d.ts +0 -1
- package/dist/server/hooks.js +2 -1
- package/dist/server/hooks.js.map +1 -1
- package/dist/server/mcp-prompts.d.ts +0 -1
- package/dist/server/mcp-prompts.js +509 -523
- package/dist/server/mcp-prompts.js.map +1 -1
- package/dist/server/mcp.d.ts +0 -1
- package/dist/server/mcp.js +324 -681
- package/dist/server/mcp.js.map +1 -1
- package/dist/server/test-plan.d.ts +1 -1
- package/dist/server/test-plan.js +25 -7
- package/dist/server/test-plan.js.map +1 -1
- package/dist/server/tools/deps.d.ts +28 -0
- package/dist/server/tools/deps.js +2 -0
- package/dist/server/tools/deps.js.map +1 -0
- package/dist/server/tools/findings-report.d.ts +3 -0
- package/dist/server/tools/findings-report.js +170 -0
- package/dist/server/tools/findings-report.js.map +1 -0
- package/dist/server/tools/resources.d.ts +3 -0
- package/dist/server/tools/resources.js +103 -0
- package/dist/server/tools/resources.js.map +1 -0
- package/dist/server/tools/security.d.ts +3 -0
- package/dist/server/tools/security.js +232 -0
- package/dist/server/tools/security.js.map +1 -0
- package/dist/server/tools/session.d.ts +3 -0
- package/dist/server/tools/session.js +160 -0
- package/dist/server/tools/session.js.map +1 -0
- package/dist/server/tools/testing.d.ts +3 -0
- package/dist/server/tools/testing.js +247 -0
- package/dist/server/tools/testing.js.map +1 -0
- package/dist/server/watcher.d.ts +0 -1
- package/dist/server/watcher.js +1 -1
- package/dist/server/watcher.js.map +1 -1
- package/dist/skills.d.ts +0 -1
- package/dist/skills.js +23 -11
- package/dist/skills.js.map +1 -1
- package/dist/store/annotations.d.ts +6 -1
- package/dist/store/annotations.js +56 -9
- package/dist/store/annotations.js.map +1 -1
- package/dist/store/confidence.d.ts +0 -1
- package/dist/store/confidence.js +2 -0
- package/dist/store/confidence.js.map +1 -1
- package/dist/store/db.d.ts +22 -1
- package/dist/store/db.js +225 -45
- package/dist/store/db.js.map +1 -1
- package/dist/store/registry.d.ts +1 -1
- package/dist/store/registry.js +17 -6
- package/dist/store/registry.js.map +1 -1
- package/dist/store/schema.sql +2 -1
- package/dist/store/vectors.d.ts +0 -1
- package/dist/types.d.ts +23 -2
- package/dist/ui/progress.d.ts +0 -1
- package/dist/uninstall.d.ts +1 -1
- package/dist/uninstall.js +33 -10
- package/dist/uninstall.js.map +1 -1
- package/dist/utils.d.ts +2 -1
- package/dist/utils.js +37 -2
- package/dist/utils.js.map +1 -1
- package/package.json +11 -8
- package/dist/agents-md.d.ts.map +0 -1
- package/dist/analyzer/config.d.ts.map +0 -1
- package/dist/analyzer/engine.d.ts.map +0 -1
- package/dist/analyzer/enrich.d.ts.map +0 -1
- package/dist/analyzer/resolver.d.ts.map +0 -1
- package/dist/analyzer/review.d.ts.map +0 -1
- package/dist/analyzer/scanner.d.ts.map +0 -1
- package/dist/analyzer/scope-resolver.d.ts.map +0 -1
- package/dist/analyzer/testplan.d.ts +0 -59
- package/dist/analyzer/testplan.d.ts.map +0 -1
- package/dist/analyzer/testplan.js +0 -218
- package/dist/analyzer/testplan.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/metrics.d.ts.map +0 -1
- package/dist/orchestrator/orchestrator.d.ts.map +0 -1
- package/dist/orchestrator/reporter.d.ts.map +0 -1
- package/dist/parser/extract.d.ts.map +0 -1
- package/dist/parser/lang-css.d.ts.map +0 -1
- package/dist/parser/lang-go.d.ts.map +0 -1
- package/dist/parser/lang-html.d.ts.map +0 -1
- package/dist/parser/lang-java.d.ts.map +0 -1
- package/dist/parser/lang-js.d.ts.map +0 -1
- package/dist/parser/lang-md.d.ts.map +0 -1
- package/dist/parser/lang-php.d.ts.map +0 -1
- package/dist/parser/lang-py.d.ts.map +0 -1
- package/dist/parser/lang-ruby.d.ts.map +0 -1
- package/dist/parser/lang-rust.d.ts.map +0 -1
- package/dist/parser/lang-ts.d.ts.map +0 -1
- package/dist/parser/lang-vue.d.ts.map +0 -1
- package/dist/parser/language-provider.d.ts.map +0 -1
- package/dist/parser/languages.d.ts.map +0 -1
- package/dist/parser/loader.d.ts.map +0 -1
- package/dist/security/deps.d.ts.map +0 -1
- package/dist/security/rules.d.ts.map +0 -1
- package/dist/server/hooks.d.ts.map +0 -1
- package/dist/server/mcp-prompts.d.ts.map +0 -1
- package/dist/server/mcp.d.ts.map +0 -1
- package/dist/server/test-plan.d.ts.map +0 -1
- package/dist/server/watcher.d.ts.map +0 -1
- package/dist/skills.d.ts.map +0 -1
- package/dist/store/annotations.d.ts.map +0 -1
- package/dist/store/confidence.d.ts.map +0 -1
- package/dist/store/db.d.ts.map +0 -1
- package/dist/store/registry.d.ts.map +0 -1
- package/dist/store/vectors.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/ui/progress.d.ts.map +0 -1
- package/dist/uninstall.d.ts.map +0 -1
- package/dist/utils.d.ts.map +0 -1
- package/docs/README.md +0 -25
- package/docs/diagram1.svg +0 -1
- package/docs/diagram2.svg +0 -1
- package/docs/diagram3.svg +0 -1
|
@@ -12,10 +12,10 @@ export class AnnotationStore {
|
|
|
12
12
|
}
|
|
13
13
|
prepareStatements() {
|
|
14
14
|
return {
|
|
15
|
-
insertAnnotation: this.db.prepare(`INSERT OR REPLACE INTO annotations (id, symbol, key, value, agent, session_id, confidence, created_at, updated_at)
|
|
16
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`),
|
|
15
|
+
insertAnnotation: this.db.prepare(`INSERT OR REPLACE INTO annotations (id, symbol, key, value, agent, session_id, confidence, symbol_hash, created_at, updated_at)
|
|
16
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`),
|
|
17
17
|
findBySymbolKey: this.db.prepare('SELECT * FROM annotations WHERE symbol = ? AND key = ?'),
|
|
18
|
-
updateAnnotation: this.db.prepare('UPDATE annotations SET value = ?, confidence = ?, updated_at = datetime(\'now\') WHERE id = ?'),
|
|
18
|
+
updateAnnotation: this.db.prepare('UPDATE annotations SET value = ?, confidence = ?, agent = ?, session_id = ?, symbol_hash = ?, updated_at = datetime(\'now\') WHERE id = ?'),
|
|
19
19
|
queryBySymbol: this.db.prepare('SELECT * FROM annotations WHERE symbol = ? ORDER BY confidence DESC, updated_at DESC LIMIT ?'),
|
|
20
20
|
queryByKey: this.db.prepare('SELECT * FROM annotations WHERE key = ? ORDER BY confidence DESC LIMIT ?'),
|
|
21
21
|
queryByAgent: this.db.prepare('SELECT * FROM annotations WHERE agent = ? ORDER BY updated_at DESC LIMIT ?'),
|
|
@@ -31,7 +31,9 @@ export class AnnotationStore {
|
|
|
31
31
|
getStale: this.db.prepare("SELECT * FROM annotations WHERE updated_at < datetime('now', ?) AND confidence < ? ORDER BY confidence ASC"),
|
|
32
32
|
archiveAnnotation: this.db.prepare("UPDATE annotations SET confidence = 0, updated_at = datetime('now') WHERE id = ?"),
|
|
33
33
|
deleteAnnotation: this.db.prepare('DELETE FROM annotations WHERE id = ?'),
|
|
34
|
+
setConfidence: this.db.prepare("UPDATE annotations SET confidence = ?, updated_at = datetime('now') WHERE id = ?"),
|
|
34
35
|
boostRecallConfidence: this.db.prepare("UPDATE annotations SET confidence = MIN(confidence + 0.05, 0.95), updated_at = datetime('now') WHERE id = ? AND confidence < 0.9"),
|
|
36
|
+
getEvolutionEvents: this.db.prepare('SELECT * FROM evolution_log WHERE annotation_id = ? ORDER BY created_at ASC'),
|
|
35
37
|
};
|
|
36
38
|
}
|
|
37
39
|
// ── Annotation CRUD ──
|
|
@@ -40,37 +42,47 @@ export class AnnotationStore {
|
|
|
40
42
|
throw new Error(`Invalid annotation key: "${key}". Valid: ${VALID_KEYS.join(', ')}`);
|
|
41
43
|
}
|
|
42
44
|
const annotationKey = key;
|
|
45
|
+
const initialConfidence = options?.confidence !== undefined
|
|
46
|
+
? Math.max(0, Math.min(1, options.confidence))
|
|
47
|
+
: 0.5;
|
|
43
48
|
const existing = this.stmts.findBySymbolKey.get(symbol, annotationKey);
|
|
44
49
|
if (existing) {
|
|
50
|
+
const updatedAgent = options?.agent ?? existing.agent;
|
|
51
|
+
const updatedSessionId = options?.sessionId ?? existing.session_id;
|
|
45
52
|
if (existing.value === value) {
|
|
46
53
|
const newConfidence = Math.min(existing.confidence + 0.1, 1.0);
|
|
47
|
-
this.stmts.updateAnnotation.run(value, newConfidence, existing.id);
|
|
54
|
+
this.stmts.updateAnnotation.run(value, newConfidence, updatedAgent, updatedSessionId, options?.symbolHash ?? existing.symbol_hash, existing.id);
|
|
48
55
|
const eventType = newConfidence >= 0.8 && existing.confidence < 0.8 ? 'promoted' : 'confidence_up';
|
|
49
56
|
this.logEvolutionEvent(existing.id, eventType, existing.value, value);
|
|
50
57
|
return rowToAnnotation({
|
|
51
58
|
...existing,
|
|
59
|
+
agent: updatedAgent,
|
|
60
|
+
session_id: updatedSessionId,
|
|
52
61
|
confidence: newConfidence,
|
|
53
62
|
updated_at: new Date().toISOString(),
|
|
54
63
|
});
|
|
55
64
|
}
|
|
56
|
-
this.stmts.updateAnnotation.run(value,
|
|
65
|
+
this.stmts.updateAnnotation.run(value, initialConfidence, updatedAgent, updatedSessionId, options?.symbolHash ?? existing.symbol_hash, existing.id);
|
|
57
66
|
this.logEvolutionEvent(existing.id, 'created', existing.value, value);
|
|
58
67
|
return rowToAnnotation({
|
|
59
68
|
...existing,
|
|
60
69
|
value,
|
|
61
|
-
|
|
70
|
+
agent: updatedAgent,
|
|
71
|
+
session_id: updatedSessionId,
|
|
72
|
+
confidence: initialConfidence,
|
|
62
73
|
updated_at: new Date().toISOString(),
|
|
63
74
|
});
|
|
64
75
|
}
|
|
65
76
|
const id = randomUUID();
|
|
66
77
|
const now = new Date().toISOString();
|
|
67
|
-
this.stmts.insertAnnotation.run(id, symbol, annotationKey, value, options?.agent ?? null, options?.sessionId ?? null,
|
|
78
|
+
this.stmts.insertAnnotation.run(id, symbol, annotationKey, value, options?.agent ?? null, options?.sessionId ?? null, initialConfidence, options?.symbolHash ?? null, now, now);
|
|
68
79
|
this.logEvolutionEvent(id, 'created', undefined, value);
|
|
69
80
|
return {
|
|
70
81
|
id, symbol, key: annotationKey, value,
|
|
71
82
|
agent: options?.agent,
|
|
72
83
|
sessionId: options?.sessionId,
|
|
73
|
-
confidence:
|
|
84
|
+
confidence: initialConfidence,
|
|
85
|
+
symbolHash: options?.symbolHash,
|
|
74
86
|
createdAt: now,
|
|
75
87
|
updatedAt: now,
|
|
76
88
|
};
|
|
@@ -100,7 +112,13 @@ export class AnnotationStore {
|
|
|
100
112
|
for (const row of rows) {
|
|
101
113
|
this.stmts.boostRecallConfidence.run(row.id);
|
|
102
114
|
}
|
|
103
|
-
return rows.map(
|
|
115
|
+
return rows.map(row => {
|
|
116
|
+
const ann = rowToAnnotation(row);
|
|
117
|
+
if (this.isAnnotationStale(ann)) {
|
|
118
|
+
ann.value = `⚠ STALE (code changed since annotation) ${ann.value}`;
|
|
119
|
+
}
|
|
120
|
+
return ann;
|
|
121
|
+
});
|
|
104
122
|
}
|
|
105
123
|
// ── Session management ──
|
|
106
124
|
sessionStart(agent) {
|
|
@@ -140,6 +158,10 @@ export class AnnotationStore {
|
|
|
140
158
|
this.db.prepare('INSERT INTO sessions (id, agent, status, started_at, context) VALUES (?, ?, ?, datetime(\'now\'), ?)').run(newId, toAgent, 'active', context);
|
|
141
159
|
return { newSessionId: newId, annotationsCopied: fromAnnCount };
|
|
142
160
|
}
|
|
161
|
+
// ── Confidence ──
|
|
162
|
+
setConfidence(id, confidence) {
|
|
163
|
+
this.stmts.setConfidence.run(confidence, id);
|
|
164
|
+
}
|
|
143
165
|
// ── Maintenance ──
|
|
144
166
|
getPromotableAnnotations() {
|
|
145
167
|
const rows = this.stmts.getPromotable.all();
|
|
@@ -161,6 +183,20 @@ export class AnnotationStore {
|
|
|
161
183
|
logEvolutionEvent(annotationId, event, oldValue, newValue) {
|
|
162
184
|
this.stmts.insertEvent.run(annotationId, event, oldValue ?? null, newValue ?? null);
|
|
163
185
|
}
|
|
186
|
+
getHistory(annotationId) {
|
|
187
|
+
const rows = this.stmts.getEvolutionEvents.all(annotationId);
|
|
188
|
+
return rows.map(rowToEvolutionEvent);
|
|
189
|
+
}
|
|
190
|
+
getCurrentSymbolHash(symbolName) {
|
|
191
|
+
const row = this.db.prepare('SELECT fh.hash FROM symbols s JOIN file_hashes fh ON s.file_path = fh.path WHERE s.name = ? LIMIT 1').get(symbolName);
|
|
192
|
+
return row?.hash ?? null;
|
|
193
|
+
}
|
|
194
|
+
isAnnotationStale(annotation) {
|
|
195
|
+
if (!annotation.symbolHash)
|
|
196
|
+
return false;
|
|
197
|
+
const current = this.getCurrentSymbolHash(annotation.symbol);
|
|
198
|
+
return current !== null && current !== annotation.symbolHash;
|
|
199
|
+
}
|
|
164
200
|
// ── Stats ──
|
|
165
201
|
getAnnotationCount() {
|
|
166
202
|
return this.stmts.countAll.get().c;
|
|
@@ -178,6 +214,17 @@ function rowToAnnotation(row) {
|
|
|
178
214
|
confidence: row.confidence,
|
|
179
215
|
createdAt: row.created_at,
|
|
180
216
|
updatedAt: row.updated_at,
|
|
217
|
+
symbolHash: row.symbol_hash ?? undefined,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function rowToEvolutionEvent(row) {
|
|
221
|
+
return {
|
|
222
|
+
id: row.id,
|
|
223
|
+
annotationId: String(row.annotation_id),
|
|
224
|
+
event: row.event,
|
|
225
|
+
oldValue: row.old_value ?? undefined,
|
|
226
|
+
newValue: row.new_value ?? undefined,
|
|
227
|
+
createdAt: row.created_at,
|
|
181
228
|
};
|
|
182
229
|
}
|
|
183
230
|
function rowToSession(row) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/store/annotations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,GAA6B;IAC3C,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,cAAc;IACzC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU;CACpC,CAAC;AAEX,MAAM,OAAO,eAAe;IAClB,EAAE,CAAyB;IAC3B,KAAK,CAAmD;IAEhE,YAAY,EAA0B;QACpC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACxC,CAAC;IAEO,iBAAiB;QACvB,OAAO;YACL,gBAAgB,EAAE,IAAI,CAAC,EAAE,CAAC,OAAO,CAC/B
|
|
1
|
+
{"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/store/annotations.ts"],"names":[],"mappings":"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"}
|
package/dist/store/confidence.js
CHANGED
|
@@ -9,6 +9,7 @@ export function boostConfidence(store, annotationId, increment = 0.1) {
|
|
|
9
9
|
const oldConf = ann.confidence;
|
|
10
10
|
const newConf = Math.min(oldConf + increment, 1.0);
|
|
11
11
|
if (newConf !== oldConf) {
|
|
12
|
+
store.setConfidence(annotationId, newConf);
|
|
12
13
|
store.logEvolutionEvent(annotationId, 'confidence_up', String(oldConf), String(newConf));
|
|
13
14
|
}
|
|
14
15
|
}
|
|
@@ -21,6 +22,7 @@ export function decayConfidence(store, annotationId, decrement = 0.1) {
|
|
|
21
22
|
const oldConf = ann.confidence;
|
|
22
23
|
const newConf = Math.max(oldConf - decrement, 0.0);
|
|
23
24
|
if (newConf !== oldConf) {
|
|
25
|
+
store.setConfidence(annotationId, newConf);
|
|
24
26
|
store.logEvolutionEvent(annotationId, 'confidence_down', String(oldConf), String(newConf));
|
|
25
27
|
}
|
|
26
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confidence.js","sourceRoot":"","sources":["../../src/store/confidence.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"confidence.js","sourceRoot":"","sources":["../../src/store/confidence.ts"],"names":[],"mappings":"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"}
|
package/dist/store/db.d.ts
CHANGED
|
@@ -41,6 +41,13 @@ export declare class Database {
|
|
|
41
41
|
getAllSymbols(): CodeSymbol[];
|
|
42
42
|
getAllLinks(): SymbolLink[];
|
|
43
43
|
findDeadCode(kind?: string, limit?: number): CodeSymbol[];
|
|
44
|
+
/**
|
|
45
|
+
* Find exported symbols that have incoming references, but ALL of those references
|
|
46
|
+
* originate from test files — meaning the symbol is "test-only referenced" and
|
|
47
|
+
* likely orphaned from production code. Returns symbols missed by the standard
|
|
48
|
+
* findDeadCode (which requires zero incoming links of any kind).
|
|
49
|
+
*/
|
|
50
|
+
findTestOnlyReferenced(limit?: number): CodeSymbol[];
|
|
44
51
|
getTypeHierarchy(symbolId: string): {
|
|
45
52
|
ancestors: Array<{
|
|
46
53
|
symbol: CodeSymbol;
|
|
@@ -56,6 +63,19 @@ export declare class Database {
|
|
|
56
63
|
depth: number;
|
|
57
64
|
via: string;
|
|
58
65
|
}> | null;
|
|
66
|
+
/**
|
|
67
|
+
* Same as findPath, but takes an already-resolved source symbol id instead
|
|
68
|
+
* of re-resolving by name. Needed when the caller has disambiguated among
|
|
69
|
+
* several same-named symbols (e.g. picking the right file-scoped `_top`
|
|
70
|
+
* module out of many) — passing the name back through findPath() would
|
|
71
|
+
* silently re-resolve to an arbitrary same-named symbol and discard that
|
|
72
|
+
* disambiguation.
|
|
73
|
+
*/
|
|
74
|
+
findPathFromId(fromId: string, toNameOrIds: string | string[], maxDepth?: number): Array<{
|
|
75
|
+
symbol: CodeSymbol;
|
|
76
|
+
depth: number;
|
|
77
|
+
via: string;
|
|
78
|
+
}> | null;
|
|
59
79
|
getChangedFiles(): string[];
|
|
60
80
|
deleteFileData(filePath: string): void;
|
|
61
81
|
rebuildSearch(): void;
|
|
@@ -103,6 +123,8 @@ export declare class Database {
|
|
|
103
123
|
clear(): void;
|
|
104
124
|
/** Clear only symbols, links, and file hashes for specific files (incremental re-index) */
|
|
105
125
|
clearFiles(filePaths: string[]): void;
|
|
126
|
+
/** Delete file_hashes rows for paths not in the given set (orphan cleanup after incremental analyze) */
|
|
127
|
+
pruneOrphanFileHashes(knownPaths: string[]): number;
|
|
106
128
|
logToolUsage(tool: string, durationMs: number, tokensOut: number, tokensSaved: number, repo?: string): void;
|
|
107
129
|
getToolUsageStats(repo?: string): {
|
|
108
130
|
totalCalls: number;
|
|
@@ -207,4 +229,3 @@ export declare class Database {
|
|
|
207
229
|
snapshotMetrics(): void;
|
|
208
230
|
close(): void;
|
|
209
231
|
}
|
|
210
|
-
//# sourceMappingURL=db.d.ts.map
|
package/dist/store/db.js
CHANGED
|
@@ -131,6 +131,9 @@ export class Database {
|
|
|
131
131
|
if (!annNames.has('updated_at')) {
|
|
132
132
|
this.db.exec(`ALTER TABLE annotations ADD COLUMN updated_at TEXT NOT NULL DEFAULT (datetime('now'))`);
|
|
133
133
|
}
|
|
134
|
+
if (!annNames.has('symbol_hash')) {
|
|
135
|
+
this.db.exec(`ALTER TABLE annotations ADD COLUMN symbol_hash TEXT`);
|
|
136
|
+
}
|
|
134
137
|
// Rebuild index if column was renamed
|
|
135
138
|
if (annNames.has('symbol_id')) {
|
|
136
139
|
this.db.exec(`DROP INDEX IF EXISTS idx_annotations_symbol`);
|
|
@@ -258,26 +261,113 @@ export class Database {
|
|
|
258
261
|
return rows.map(rowToLink);
|
|
259
262
|
}
|
|
260
263
|
findDeadCode(kind, limit = 50) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
264
|
+
// Next.js/SvelteKit/api conventions are matched both at the repo root AND nested
|
|
265
|
+
// under a package subdirectory (e.g. monorepos with frontend/app/... instead of
|
|
266
|
+
// app/...) — a root-only 'app/%' pattern silently misses every monorepo layout.
|
|
267
|
+
const frameworkExclude = `AND s.file_path NOT LIKE 'app/%/page.%' AND s.file_path NOT LIKE '%/app/%/page.%'
|
|
268
|
+
AND s.file_path NOT LIKE 'app/%/layout.%' AND s.file_path NOT LIKE '%/app/%/layout.%'
|
|
269
|
+
AND s.file_path NOT LIKE 'app/page.%' AND s.file_path NOT LIKE '%/app/page.%'
|
|
270
|
+
AND s.file_path NOT LIKE 'app/layout.%' AND s.file_path NOT LIKE '%/app/layout.%'
|
|
271
|
+
AND s.file_path NOT LIKE 'app/%/loading.%' AND s.file_path NOT LIKE '%/app/%/loading.%'
|
|
272
|
+
AND s.file_path NOT LIKE 'app/%/error.%' AND s.file_path NOT LIKE '%/app/%/error.%'
|
|
273
|
+
AND s.file_path NOT LIKE 'app/%/not-found.%' AND s.file_path NOT LIKE '%/app/%/not-found.%'
|
|
274
|
+
AND s.file_path NOT LIKE 'app/%/template.%' AND s.file_path NOT LIKE '%/app/%/template.%'
|
|
275
|
+
AND s.file_path NOT LIKE 'app/%/global-error.%' AND s.file_path NOT LIKE '%/app/%/global-error.%'
|
|
276
|
+
AND s.file_path NOT LIKE 'app/%/default.%' AND s.file_path NOT LIKE '%/app/%/default.%'
|
|
277
|
+
AND s.file_path NOT LIKE 'app/api/%/route.%' AND s.file_path NOT LIKE '%/app/api/%/route.%'
|
|
278
|
+
AND s.file_path NOT LIKE 'app/%/route.%' AND s.file_path NOT LIKE '%/app/%/route.%'
|
|
279
|
+
AND s.file_path NOT LIKE 'jest.config.%'
|
|
280
|
+
AND s.file_path NOT LIKE 'src/routes/+page.%' AND s.file_path NOT LIKE '%/src/routes/+page.%'
|
|
281
|
+
AND s.file_path NOT LIKE 'src/routes/+layout.%' AND s.file_path NOT LIKE '%/src/routes/+layout.%'
|
|
282
|
+
AND s.file_path NOT LIKE '%/alembic/versions/%'
|
|
283
|
+
AND s.file_path NOT LIKE '%/migrations/%'
|
|
284
|
+
AND s.file_path NOT LIKE 'api/%' AND s.file_path NOT LIKE '%/api/%'
|
|
285
|
+
AND NOT ((s.file_path LIKE 'app/%' OR s.file_path LIKE '%/app/%') AND s.name IN ('generateStaticParams', 'metadata', 'generateMetadata', 'viewport', 'generateViewport', 'revalidate', 'dynamic', 'fetchCache', 'runtime', 'preferredRegion', 'maxDuration'))`;
|
|
286
|
+
// Vue SFC root components imported via <Component/> template tags get their
|
|
287
|
+
// import link on _top [module], not on the [class] root symbol. Treat the class
|
|
288
|
+
// as referenced if its file's _top module has incoming links from other files.
|
|
289
|
+
const vueRootGuard = `AND NOT (s.file_path LIKE '%.vue' AND s.kind = 'class' AND EXISTS (
|
|
290
|
+
SELECT 1 FROM symbols s2
|
|
291
|
+
JOIN links l2 ON l2.to_id = s2.id AND l2.type != 'contains'
|
|
292
|
+
WHERE s2.file_path = s.file_path AND s2.kind = 'module' AND s2.name = '_top'
|
|
293
|
+
AND EXISTS (SELECT 1 FROM links l3 WHERE l3.to_id = s2.id AND l3.type = 'imports')
|
|
294
|
+
))`;
|
|
265
295
|
const sql = kind
|
|
266
296
|
? `SELECT s.* FROM symbols s
|
|
267
297
|
LEFT JOIN links l ON l.to_id = s.id AND l.type != 'contains'
|
|
268
|
-
WHERE s.exported = 1 AND s.kind = ? AND l.id IS NULL
|
|
298
|
+
WHERE s.exported = 1 AND s.kind = ? AND s.kind != 'section' AND l.id IS NULL
|
|
269
299
|
${frameworkExclude}
|
|
300
|
+
${vueRootGuard}
|
|
270
301
|
LIMIT ?`
|
|
271
302
|
: `SELECT s.* FROM symbols s
|
|
272
303
|
LEFT JOIN links l ON l.to_id = s.id AND l.type != 'contains'
|
|
273
|
-
WHERE s.exported = 1 AND l.id IS NULL
|
|
304
|
+
WHERE s.exported = 1 AND s.kind != 'section' AND l.id IS NULL
|
|
274
305
|
${frameworkExclude}
|
|
306
|
+
${vueRootGuard}
|
|
275
307
|
LIMIT ?`;
|
|
276
308
|
const rows = kind
|
|
277
309
|
? this.db.prepare(sql).all(kind, limit)
|
|
278
310
|
: this.db.prepare(sql).all(limit);
|
|
279
311
|
return rows.map(rowToSymbol);
|
|
280
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Find exported symbols that have incoming references, but ALL of those references
|
|
315
|
+
* originate from test files — meaning the symbol is "test-only referenced" and
|
|
316
|
+
* likely orphaned from production code. Returns symbols missed by the standard
|
|
317
|
+
* findDeadCode (which requires zero incoming links of any kind).
|
|
318
|
+
*/
|
|
319
|
+
findTestOnlyReferenced(limit = 50) {
|
|
320
|
+
// Next.js/SvelteKit/api conventions are matched both at the repo root AND nested
|
|
321
|
+
// under a package subdirectory (e.g. monorepos with frontend/app/... instead of
|
|
322
|
+
// app/...) — a root-only 'app/%' pattern silently misses every monorepo layout.
|
|
323
|
+
const frameworkExclude = `AND s.file_path NOT LIKE 'app/%/page.%' AND s.file_path NOT LIKE '%/app/%/page.%'
|
|
324
|
+
AND s.file_path NOT LIKE 'app/%/layout.%' AND s.file_path NOT LIKE '%/app/%/layout.%'
|
|
325
|
+
AND s.file_path NOT LIKE 'app/page.%' AND s.file_path NOT LIKE '%/app/page.%'
|
|
326
|
+
AND s.file_path NOT LIKE 'app/layout.%' AND s.file_path NOT LIKE '%/app/layout.%'
|
|
327
|
+
AND s.file_path NOT LIKE 'app/%/loading.%' AND s.file_path NOT LIKE '%/app/%/loading.%'
|
|
328
|
+
AND s.file_path NOT LIKE 'app/%/error.%' AND s.file_path NOT LIKE '%/app/%/error.%'
|
|
329
|
+
AND s.file_path NOT LIKE 'app/%/not-found.%' AND s.file_path NOT LIKE '%/app/%/not-found.%'
|
|
330
|
+
AND s.file_path NOT LIKE 'app/%/template.%' AND s.file_path NOT LIKE '%/app/%/template.%'
|
|
331
|
+
AND s.file_path NOT LIKE 'app/%/global-error.%' AND s.file_path NOT LIKE '%/app/%/global-error.%'
|
|
332
|
+
AND s.file_path NOT LIKE 'app/%/default.%' AND s.file_path NOT LIKE '%/app/%/default.%'
|
|
333
|
+
AND s.file_path NOT LIKE 'app/api/%/route.%' AND s.file_path NOT LIKE '%/app/api/%/route.%'
|
|
334
|
+
AND s.file_path NOT LIKE 'app/%/route.%' AND s.file_path NOT LIKE '%/app/%/route.%'
|
|
335
|
+
AND s.file_path NOT LIKE 'jest.config.%'
|
|
336
|
+
AND s.file_path NOT LIKE 'src/routes/+page.%' AND s.file_path NOT LIKE '%/src/routes/+page.%'
|
|
337
|
+
AND s.file_path NOT LIKE 'src/routes/+layout.%' AND s.file_path NOT LIKE '%/src/routes/+layout.%'
|
|
338
|
+
AND s.file_path NOT LIKE '%/alembic/versions/%'
|
|
339
|
+
AND s.file_path NOT LIKE '%/migrations/%'
|
|
340
|
+
AND s.file_path NOT LIKE 'api/%' AND s.file_path NOT LIKE '%/api/%'
|
|
341
|
+
AND NOT ((s.file_path LIKE 'app/%' OR s.file_path LIKE '%/app/%') AND s.name IN ('generateStaticParams', 'metadata', 'generateMetadata', 'viewport', 'generateViewport', 'revalidate', 'dynamic', 'fetchCache', 'runtime', 'preferredRegion', 'maxDuration'))`;
|
|
342
|
+
// Get ALL exported symbols that HAVE at least one incoming link (not caught by findDeadCode).
|
|
343
|
+
// No SQL LIMIT here: the JS post-filter below narrows this down to test-only-referenced
|
|
344
|
+
// symbols, which can be a small minority of low-heat candidates — applying `limit` before
|
|
345
|
+
// that filter would silently drop real orphans that don't happen to rank in the top N by heat.
|
|
346
|
+
const sql = `SELECT s.*, COUNT(l.id) as incoming_count FROM symbols s
|
|
347
|
+
JOIN links l ON l.to_id = s.id AND l.type != 'contains'
|
|
348
|
+
WHERE s.exported = 1 AND s.kind != 'section'
|
|
349
|
+
${frameworkExclude}
|
|
350
|
+
GROUP BY s.id
|
|
351
|
+
HAVING incoming_count > 0
|
|
352
|
+
ORDER BY s.heat DESC`;
|
|
353
|
+
const rows = this.db.prepare(sql).all();
|
|
354
|
+
const candidates = rows.map(rowToSymbol);
|
|
355
|
+
// Post-filter: check if ALL incoming links come from test files
|
|
356
|
+
const results = [];
|
|
357
|
+
for (const sym of candidates) {
|
|
358
|
+
const incoming = this.getIncomingLinks(sym.id).filter(l => l.type !== 'contains');
|
|
359
|
+
if (incoming.length === 0)
|
|
360
|
+
continue;
|
|
361
|
+
const allFromTests = incoming.every(l => {
|
|
362
|
+
const from = this.findSymbolById(l.fromId);
|
|
363
|
+
return from && this.isTestFile(from.filePath);
|
|
364
|
+
});
|
|
365
|
+
if (allFromTests) {
|
|
366
|
+
results.push(sym);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return results.slice(0, limit);
|
|
370
|
+
}
|
|
281
371
|
getTypeHierarchy(symbolId) {
|
|
282
372
|
const ancestors = this.db.prepare(`
|
|
283
373
|
WITH RECURSIVE up(id, depth) AS (
|
|
@@ -309,29 +399,83 @@ export class Database {
|
|
|
309
399
|
const toSyms = this.findSymbolByName(toName);
|
|
310
400
|
if (fromSyms.length === 0 || toSyms.length === 0)
|
|
311
401
|
return null;
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
402
|
+
return this.findPathFromId(fromSyms[0].id, toSyms.map(s => s.id), maxDepth);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Same as findPath, but takes an already-resolved source symbol id instead
|
|
406
|
+
* of re-resolving by name. Needed when the caller has disambiguated among
|
|
407
|
+
* several same-named symbols (e.g. picking the right file-scoped `_top`
|
|
408
|
+
* module out of many) — passing the name back through findPath() would
|
|
409
|
+
* silently re-resolve to an arbitrary same-named symbol and discard that
|
|
410
|
+
* disambiguation.
|
|
411
|
+
*/
|
|
412
|
+
findPathFromId(fromId, toNameOrIds, maxDepth = 5) {
|
|
413
|
+
const toIds = Array.isArray(toNameOrIds)
|
|
414
|
+
? new Set(toNameOrIds)
|
|
415
|
+
: new Set(this.findSymbolByName(toNameOrIds).map(s => s.id));
|
|
416
|
+
if (toIds.size === 0)
|
|
417
|
+
return null;
|
|
418
|
+
// Anchor branch 2 seeds the search by descending ONE 'contains' hop from the exact
|
|
419
|
+
// origin symbol into its own contained methods, then taking one real edge from there.
|
|
420
|
+
// This only ever applies to the literal starting symbol (later branches never re-descend
|
|
421
|
+
// into contains children mid-path) — a class/struct/trait passed as `fromId` typically
|
|
422
|
+
// has zero direct calls/imports edges of its own (its real behavior lives in its
|
|
423
|
+
// methods), so without this seed the search dead-ends immediately at depth 0 for any
|
|
424
|
+
// class-to-X query. Safe: it can't produce a false "relationship" between unrelated
|
|
425
|
+
// sibling methods, since it's scoped to fromId's own children only, never applied again
|
|
426
|
+
// to a class reached later in the chain.
|
|
315
427
|
const rows = this.db.prepare(`
|
|
316
|
-
WITH RECURSIVE
|
|
317
|
-
SELECT to_id, 1, type
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
428
|
+
WITH RECURSIVE chain(node_id, depth, via, path_ids) AS (
|
|
429
|
+
SELECT l.to_id, 1, l.type, ',' || l.from_id || ',' || l.to_id || ','
|
|
430
|
+
FROM links l WHERE l.from_id = ? AND l.type != 'contains'
|
|
431
|
+
UNION ALL
|
|
432
|
+
SELECT l2.to_id, 2, l2.type, ',' || l.from_id || ',' || l.to_id || ',' || l2.to_id || ','
|
|
433
|
+
FROM links l JOIN links l2 ON l2.from_id = l.to_id
|
|
434
|
+
WHERE l.from_id = ? AND l.type = 'contains' AND l2.type != 'contains'
|
|
435
|
+
UNION ALL
|
|
436
|
+
SELECT l.to_id, c.depth + 1, l.type, c.path_ids || l.to_id || ','
|
|
437
|
+
FROM links l JOIN chain c ON l.from_id = c.node_id
|
|
438
|
+
WHERE l.type != 'contains' AND c.depth < ?
|
|
439
|
+
AND c.path_ids NOT LIKE '%,' || l.to_id || ',%'
|
|
440
|
+
UNION ALL
|
|
441
|
+
SELECT l.from_id, c.depth + 1, l.type, c.path_ids || l.from_id || ','
|
|
442
|
+
FROM links l JOIN chain c ON l.to_id = c.node_id
|
|
443
|
+
WHERE l.type = 'contains' AND c.depth < ?
|
|
444
|
+
AND c.path_ids NOT LIKE '%,' || l.from_id || ',%'
|
|
322
445
|
)
|
|
323
|
-
SELECT
|
|
324
|
-
`).all(fromId, maxDepth);
|
|
446
|
+
SELECT node_id, depth, via, path_ids FROM chain ORDER BY depth
|
|
447
|
+
`).all(fromId, fromId, maxDepth, maxDepth);
|
|
448
|
+
// Find the first (shortest-depth) row matching the target
|
|
449
|
+
const targetRow = rows.find(r => toIds.has(r.node_id));
|
|
450
|
+
if (!targetRow)
|
|
451
|
+
return null;
|
|
452
|
+
// Reconstruct path from path_ids chain
|
|
453
|
+
const idChain = targetRow.path_ids.split(',').filter((s) => s.length > 0);
|
|
454
|
+
// idChain[0] = fromId, idChain[last] = target node_id
|
|
325
455
|
const result = [];
|
|
326
|
-
for (
|
|
327
|
-
|
|
328
|
-
if (
|
|
329
|
-
|
|
456
|
+
for (let i = 0; i < idChain.length; i++) {
|
|
457
|
+
const sym = this.findSymbolById(idChain[i]);
|
|
458
|
+
if (!sym)
|
|
459
|
+
continue;
|
|
460
|
+
// Determine via for this hop: lookup link from idChain[i] → idChain[i+1]. Prefer a
|
|
461
|
+
// real calls/imports/etc. edge when one exists between the two nodes; only report
|
|
462
|
+
// 'contains' (in either direction — the traversal now allows both a class-to-method
|
|
463
|
+
// seed step and a method-to-class arrival step) when that's the only relationship.
|
|
464
|
+
let via = 'calls';
|
|
465
|
+
if (i < idChain.length - 1) {
|
|
466
|
+
const linkRow = this.db.prepare('SELECT type FROM links WHERE from_id = ? AND to_id = ? AND type != ? LIMIT 1').get(idChain[i], idChain[i + 1], 'contains');
|
|
467
|
+
if (linkRow) {
|
|
468
|
+
via = linkRow.type;
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
const containsRow = this.db.prepare('SELECT type FROM links WHERE ((from_id = ? AND to_id = ?) OR (from_id = ? AND to_id = ?)) AND type = ? LIMIT 1').get(idChain[i], idChain[i + 1], idChain[i + 1], idChain[i], 'contains');
|
|
472
|
+
if (containsRow)
|
|
473
|
+
via = containsRow.type;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
result.push({ symbol: sym, depth: i, via });
|
|
330
477
|
}
|
|
331
|
-
|
|
332
|
-
if (!found)
|
|
333
|
-
return null;
|
|
334
|
-
return result.filter(r => r.depth <= found.depth);
|
|
478
|
+
return result;
|
|
335
479
|
}
|
|
336
480
|
getChangedFiles() {
|
|
337
481
|
const rows = this.db.prepare('SELECT DISTINCT file_path FROM symbols').all();
|
|
@@ -402,9 +546,21 @@ export class Database {
|
|
|
402
546
|
visited.add(currentId);
|
|
403
547
|
const incoming = this.getIncomingLinks(currentId).filter(l => l.type === 'calls' || l.type === 'imports');
|
|
404
548
|
const sym = this.findSymbolById(currentId);
|
|
405
|
-
if (incoming.length === 0
|
|
549
|
+
if (incoming.length === 0) {
|
|
406
550
|
// Reached an entrypoint — save this path
|
|
407
|
-
|
|
551
|
+
// _top modules represent file-level entrypoints (e.g., top-level code execution)
|
|
552
|
+
// Class methods: if the method is contained by an exported class, treat it as
|
|
553
|
+
// a de facto entrypoint (framework-invoked handlers like NestJS controllers).
|
|
554
|
+
const isExportedClassMember = !sym?.exported && sym?.kind === 'method' &&
|
|
555
|
+
this.getIncomingLinks(currentId).some(l => {
|
|
556
|
+
if (l.type !== 'contains')
|
|
557
|
+
return false;
|
|
558
|
+
const containingClass = this.findSymbolById(l.fromId);
|
|
559
|
+
return containingClass?.exported === true;
|
|
560
|
+
});
|
|
561
|
+
if (sym?.exported || (sym?.kind === 'module' && sym?.name === '_top') || isExportedClassMember) {
|
|
562
|
+
paths.push({ path: [...currentPath] });
|
|
563
|
+
}
|
|
408
564
|
visited.delete(currentId);
|
|
409
565
|
return;
|
|
410
566
|
}
|
|
@@ -496,6 +652,16 @@ export class Database {
|
|
|
496
652
|
DELETE FROM symbols WHERE file_path IN (${placeholders})
|
|
497
653
|
`).run(...filePaths);
|
|
498
654
|
}
|
|
655
|
+
/** Delete file_hashes rows for paths not in the given set (orphan cleanup after incremental analyze) */
|
|
656
|
+
pruneOrphanFileHashes(knownPaths) {
|
|
657
|
+
if (knownPaths.length === 0)
|
|
658
|
+
return 0;
|
|
659
|
+
const placeholders = knownPaths.map(() => '?').join(',');
|
|
660
|
+
const result = this.db.prepare(`
|
|
661
|
+
DELETE FROM file_hashes WHERE path NOT IN (${placeholders})
|
|
662
|
+
`).run(...knownPaths);
|
|
663
|
+
return result.changes;
|
|
664
|
+
}
|
|
499
665
|
// ── Tool usage tracking ──
|
|
500
666
|
logToolUsage(tool, durationMs, tokensOut, tokensSaved, repo) {
|
|
501
667
|
this.db.prepare(`INSERT INTO tool_usage (tool, duration_ms, tokens_out, tokens_saved, repo)
|
|
@@ -555,7 +721,10 @@ export class Database {
|
|
|
555
721
|
}
|
|
556
722
|
// ── Test file detection ──
|
|
557
723
|
isTestFile(filePath) {
|
|
558
|
-
|
|
724
|
+
const codeExt = /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rb|java|php|rs)$/i;
|
|
725
|
+
if (!codeExt.test(filePath))
|
|
726
|
+
return false;
|
|
727
|
+
return /[/\\]tests?[/\\]/.test(filePath) || /\.(test|spec)\./i.test(filePath);
|
|
559
728
|
}
|
|
560
729
|
// ── Heat / hubs ──
|
|
561
730
|
getTopHubs(limit) {
|
|
@@ -669,30 +838,41 @@ export class Database {
|
|
|
669
838
|
const target = this.findSymbolById(symbolId);
|
|
670
839
|
if (!target)
|
|
671
840
|
return [];
|
|
672
|
-
const
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
841
|
+
const CONTAINER_KINDS = new Set(['class', 'struct', 'trait']);
|
|
842
|
+
const buildSig = (id) => {
|
|
843
|
+
const sig = new Set();
|
|
844
|
+
const sym = this.findSymbolById(id);
|
|
845
|
+
const incoming = this.getIncomingLinks(id).filter(l => l.type !== 'contains');
|
|
846
|
+
const outgoing = this.getOutgoingLinks(id).filter(l => l.type !== 'contains');
|
|
847
|
+
for (const link of incoming)
|
|
848
|
+
sig.add(link.fromId);
|
|
849
|
+
for (const link of outgoing)
|
|
850
|
+
sig.add(link.toId);
|
|
851
|
+
if (sym && CONTAINER_KINDS.has(sym.kind)) {
|
|
852
|
+
const contained = this.getOutgoingLinks(id).filter(l => l.type === 'contains');
|
|
853
|
+
for (const cl of contained) {
|
|
854
|
+
const mIn = this.getIncomingLinks(cl.toId).filter(l => l.type !== 'contains');
|
|
855
|
+
const mOut = this.getOutgoingLinks(cl.toId).filter(l => l.type !== 'contains');
|
|
856
|
+
for (const link of mIn)
|
|
857
|
+
sig.add(link.fromId);
|
|
858
|
+
for (const link of mOut)
|
|
859
|
+
sig.add(link.toId);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
return sig;
|
|
863
|
+
};
|
|
864
|
+
const targetSig = buildSig(symbolId);
|
|
679
865
|
// Search across all exported symbols, not just same-file siblings
|
|
680
866
|
const allSymbols = this.getAllSymbols().filter(s => s.id !== symbolId && s.exported);
|
|
681
867
|
const results = [];
|
|
682
868
|
for (const candidate of allSymbols) {
|
|
683
|
-
const
|
|
684
|
-
const candOutgoing = this.getOutgoingLinks(candidate.id).filter(l => l.type !== 'contains');
|
|
685
|
-
const candidateLinks = new Set();
|
|
686
|
-
for (const link of candIncoming)
|
|
687
|
-
candidateLinks.add(link.fromId);
|
|
688
|
-
for (const link of candOutgoing)
|
|
689
|
-
candidateLinks.add(link.toId);
|
|
869
|
+
const candidateSig = buildSig(candidate.id);
|
|
690
870
|
let intersection = 0;
|
|
691
|
-
for (const id of
|
|
692
|
-
if (
|
|
871
|
+
for (const id of targetSig) {
|
|
872
|
+
if (candidateSig.has(id))
|
|
693
873
|
intersection++;
|
|
694
874
|
}
|
|
695
|
-
const union = new Set([...
|
|
875
|
+
const union = new Set([...targetSig, ...candidateSig]).size;
|
|
696
876
|
const similarity = union > 0 ? intersection / union : 0;
|
|
697
877
|
if (similarity >= 0.15) {
|
|
698
878
|
results.push({ symbol: candidate, similarity: Math.round(similarity * 100) / 100 });
|