@jmtrin/opencode-kevin 0.6.0 → 0.7.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/README.md +582 -580
- package/dist/migrations/001_initial.sql +91 -91
- package/dist/migrations/003_v02_signal.sql +57 -57
- package/dist/migrations/004_v03_knowledge.sql +138 -138
- package/dist/migrations/005_v04_signal.sql +57 -57
- package/dist/migrations/006_v05_glassbox.sql +118 -118
- package/dist/migrations/007_v06_pull.sql +144 -144
- package/dist/migrations/008_v07_truth.sql +124 -0
- package/dist/plugin/ConflictDetector.d.ts +35 -0
- package/dist/plugin/ConflictDetector.js +283 -0
- package/dist/plugin/ConflictDetector.js.map +1 -0
- package/dist/plugin/ConventionMiner.d.ts +35 -0
- package/dist/plugin/ConventionMiner.js +243 -0
- package/dist/plugin/ConventionMiner.js.map +1 -0
- package/dist/plugin/Curator.js +45 -14
- package/dist/plugin/Curator.js.map +1 -1
- package/dist/plugin/MemoryService.d.ts +18 -0
- package/dist/plugin/MemoryService.js +92 -2
- package/dist/plugin/MemoryService.js.map +1 -1
- package/dist/plugin/Migrate.js +31 -2
- package/dist/plugin/Migrate.js.map +1 -1
- package/dist/plugin/Reflector.js +13 -0
- package/dist/plugin/Reflector.js.map +1 -1
- package/dist/plugin/RepoTruth.d.ts +80 -0
- package/dist/plugin/RepoTruth.js +600 -0
- package/dist/plugin/RepoTruth.js.map +1 -0
- package/dist/plugin/Retrospective.js +8 -0
- package/dist/plugin/Retrospective.js.map +1 -1
- package/dist/plugin/index.d.ts +7 -2
- package/dist/plugin/index.js +135 -2
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/kevin_audit.d.ts +41 -1
- package/dist/plugin/kevin_audit.js +98 -3
- package/dist/plugin/kevin_audit.js.map +1 -1
- package/dist/plugin/kevin_conflicts.d.ts +9 -0
- package/dist/plugin/kevin_conflicts.js +51 -0
- package/dist/plugin/kevin_conflicts.js.map +1 -0
- package/dist/plugin/kevin_facts.d.ts +42 -0
- package/dist/plugin/kevin_facts.js +37 -0
- package/dist/plugin/kevin_facts.js.map +1 -0
- package/dist/plugin/metrics.d.ts +3 -3
- package/dist/plugin/metrics.js +12 -2
- package/dist/plugin/metrics.js.map +1 -1
- package/dist/plugin/replay-types.d.ts +2 -2
- package/migrations/001_initial.sql +91 -91
- package/migrations/003_v02_signal.sql +57 -57
- package/migrations/004_v03_knowledge.sql +138 -138
- package/migrations/005_v04_signal.sql +57 -57
- package/migrations/006_v05_glassbox.sql +118 -118
- package/migrations/007_v06_pull.sql +144 -144
- package/migrations/008_v07_truth.sql +124 -0
- package/package.json +3 -2
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
import { readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { fingerprint } from "./fingerprint.js";
|
|
4
|
+
import { uuidv7 } from "./uuid.js";
|
|
5
|
+
// v0.7.0 (K7-005 / plan §5.1, D7-01 / D7-13)
|
|
6
|
+
// ============================================================
|
|
7
|
+
// RepoTruth — repository as ground truth.
|
|
8
|
+
//
|
|
9
|
+
// Reads EXACTLY two files from the project root, both JSON:
|
|
10
|
+
// package.json and tsconfig.json
|
|
11
|
+
// That is the whole read set (D7-01). There is no TOML/YAML parser
|
|
12
|
+
// and no new runtime dependency in this release; each file costs one
|
|
13
|
+
// JSON.parse inside a try/catch that returns [] on ANY failure.
|
|
14
|
+
//
|
|
15
|
+
// Bounds (D7-13): a hard cap of 500 facts per project. When the cap
|
|
16
|
+
// is hit, extraction stops at a deterministic point and the
|
|
17
|
+
// truncation is RECORDED as a repo_facts row with key_path='_truncated'
|
|
18
|
+
// and value='<total extractable keys>'. A silent truncation would turn
|
|
19
|
+
// every dropped fact into a false contradiction.
|
|
20
|
+
// ============================================================
|
|
21
|
+
const MAX_FACTS_PER_PROJECT = 500;
|
|
22
|
+
function stringifyScalar(v) {
|
|
23
|
+
switch (typeof v) {
|
|
24
|
+
case "string":
|
|
25
|
+
return v;
|
|
26
|
+
case "number":
|
|
27
|
+
case "boolean":
|
|
28
|
+
return String(v);
|
|
29
|
+
default:
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Extraction — bounded and explicit. The extractor NEVER recurses into
|
|
35
|
+
// arbitrary nested objects: compilerOptions scalars are taken one level
|
|
36
|
+
// deep, and include/exclude are joined deterministically into one value.
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
function extractFromPackageJson(parsed) {
|
|
39
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
const pkg = parsed;
|
|
43
|
+
const out = [];
|
|
44
|
+
const push = (keyPath, value) => {
|
|
45
|
+
out.push({ file: "package.json", keyPath, value });
|
|
46
|
+
};
|
|
47
|
+
// Group order: name, version, packageManager, type, then engines.*,
|
|
48
|
+
// scripts.*, dependencies.* / devDependencies.* / optionalDependencies.*.
|
|
49
|
+
for (const key of ["name", "version", "packageManager", "type"]) {
|
|
50
|
+
const v = stringifyScalar(pkg[key]);
|
|
51
|
+
if (v !== null)
|
|
52
|
+
push(key, v);
|
|
53
|
+
}
|
|
54
|
+
// engines.* — scalars one level deep.
|
|
55
|
+
if (typeof pkg.engines === "object" && pkg.engines !== null) {
|
|
56
|
+
const engines = pkg.engines;
|
|
57
|
+
for (const k of Object.keys(engines)) {
|
|
58
|
+
const v = stringifyScalar(engines[k]);
|
|
59
|
+
if (v !== null)
|
|
60
|
+
push(`engines.${k}`, v);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// scripts.* — every key and its value.
|
|
64
|
+
if (typeof pkg.scripts === "object" && pkg.scripts !== null) {
|
|
65
|
+
const scripts = pkg.scripts;
|
|
66
|
+
for (const k of Object.keys(scripts)) {
|
|
67
|
+
const v = stringifyScalar(scripts[k]);
|
|
68
|
+
if (v !== null)
|
|
69
|
+
push(`scripts.${k}`, v);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// dependencies.* / devDependencies.* / optionalDependencies.* — package
|
|
73
|
+
// name and version range.
|
|
74
|
+
for (const group of [
|
|
75
|
+
"dependencies",
|
|
76
|
+
"devDependencies",
|
|
77
|
+
"optionalDependencies",
|
|
78
|
+
]) {
|
|
79
|
+
if (typeof pkg[group] === "object" && pkg[group] !== null) {
|
|
80
|
+
const map = pkg[group];
|
|
81
|
+
for (const k of Object.keys(map)) {
|
|
82
|
+
const v = stringifyScalar(map[k]);
|
|
83
|
+
if (v !== null)
|
|
84
|
+
push(`${group}.${k}`, v);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
function joinDeterministic(list) {
|
|
91
|
+
if (!Array.isArray(list))
|
|
92
|
+
return null;
|
|
93
|
+
// Deterministic: sort so the joined value is stable across runs and
|
|
94
|
+
// independent of source ordering.
|
|
95
|
+
const strs = [];
|
|
96
|
+
for (const item of list) {
|
|
97
|
+
const s = stringifyScalar(item);
|
|
98
|
+
if (s !== null)
|
|
99
|
+
strs.push(s);
|
|
100
|
+
}
|
|
101
|
+
strs.sort();
|
|
102
|
+
return strs.join(" ");
|
|
103
|
+
}
|
|
104
|
+
function extractFromTsconfig(parsed) {
|
|
105
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
const cfg = parsed;
|
|
109
|
+
const out = [];
|
|
110
|
+
// compilerOptions.* — scalar values one level deep (string, number,
|
|
111
|
+
// boolean). Nested objects under compilerOptions are deliberately not
|
|
112
|
+
// walked (D7-01 keeps the extractor flat).
|
|
113
|
+
const options = cfg.compilerOptions;
|
|
114
|
+
if (typeof options === "object" && options !== null) {
|
|
115
|
+
const rec = options;
|
|
116
|
+
for (const key of Object.keys(rec)) {
|
|
117
|
+
const v = stringifyScalar(rec[key]);
|
|
118
|
+
if (v !== null)
|
|
119
|
+
out.push({
|
|
120
|
+
file: "tsconfig.json",
|
|
121
|
+
keyPath: `compilerOptions.${key}`,
|
|
122
|
+
value: v,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// include / exclude — joined deterministically into a single value.
|
|
127
|
+
for (const listKey of ["include", "exclude"]) {
|
|
128
|
+
const joined = joinDeterministic(cfg[listKey]);
|
|
129
|
+
if (joined !== null) {
|
|
130
|
+
out.push({ file: "tsconfig.json", keyPath: listKey, value: joined });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* v0.7.0 (K7-006 / plan §5.2) — read a fact file safely. Returns `null`
|
|
137
|
+
* when the file is missing, unreadable, malformed JSON, or parses to a
|
|
138
|
+
* non-object — the caller treats that as "no facts". The extra non-object
|
|
139
|
+
* guard is load-bearing: `typeof null === 'object'`, so a bare `null`,
|
|
140
|
+
* array or number must not be treated as a valid fact source.
|
|
141
|
+
*/
|
|
142
|
+
function readJsonFile(filePath) {
|
|
143
|
+
let raw;
|
|
144
|
+
try {
|
|
145
|
+
raw = readFileSync(filePath, "utf8");
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const parsed = JSON.parse(raw);
|
|
152
|
+
if (typeof parsed !== "object" ||
|
|
153
|
+
parsed === null ||
|
|
154
|
+
Array.isArray(parsed)) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
return parsed;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function normalizedKeyPath(fact) {
|
|
164
|
+
// The stringified `include`/`exclude` may contain spaces; the key path
|
|
165
|
+
// itself is `"include"`/`"exclude"`, which is already stable. This helper
|
|
166
|
+
// exists so a single deterministic key is used for fingerprinting.
|
|
167
|
+
return fact.keyPath;
|
|
168
|
+
}
|
|
169
|
+
export class RepoTruth {
|
|
170
|
+
store;
|
|
171
|
+
projectId;
|
|
172
|
+
projectRoot;
|
|
173
|
+
metrics;
|
|
174
|
+
hasTable = true;
|
|
175
|
+
lastMtimes = new Map();
|
|
176
|
+
lastFacts = new Map();
|
|
177
|
+
lastScanAt = null;
|
|
178
|
+
// v0.7.0 (K7-007 / plan §5.1, D7-05) — the dependency packages that were
|
|
179
|
+
// present at the immediately-preceding scan, keyed by project_id. Check 2
|
|
180
|
+
// (missing dependency) fires only for a package that *disappeared* — it
|
|
181
|
+
// must have existed at the previous scan. In-memory: contradictions() runs
|
|
182
|
+
// on demand in the same process that produced the scans.
|
|
183
|
+
prevDeps = new Map();
|
|
184
|
+
constructor(store, projectId, projectRoot, metrics) {
|
|
185
|
+
this.store = store;
|
|
186
|
+
this.projectId = projectId;
|
|
187
|
+
this.projectRoot = projectRoot;
|
|
188
|
+
this.metrics = metrics ?? null;
|
|
189
|
+
}
|
|
190
|
+
ensureTables() {
|
|
191
|
+
if (!this.hasTable)
|
|
192
|
+
return;
|
|
193
|
+
try {
|
|
194
|
+
const row = this.store
|
|
195
|
+
.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'repo_facts'")
|
|
196
|
+
.get();
|
|
197
|
+
if (!row)
|
|
198
|
+
this.hasTable = false;
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Pre-008 database: repo_facts does not exist. Degrade gracefully —
|
|
202
|
+
// scan() becomes a no-op and facts() returns [] rather than throwing.
|
|
203
|
+
this.hasTable = false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* v0.7.0 (K7-005/006 / plan §5.1-5.2, D7-13) — refresh the repository
|
|
208
|
+
* truth. The steady state of an idle session is two `stat` calls: a file
|
|
209
|
+
* whose `source_mtime` is unchanged is NOT re-parsed (no JSON.parse, no
|
|
210
|
+
* readFileSync). A changed file replaces that file's facts for THIS
|
|
211
|
+
* project only; a file no longer present has its facts removed for this
|
|
212
|
+
* project only. The project-wide 500-fact cap is applied to the combined,
|
|
213
|
+
* deterministically-ordered fact set and the truncation is recorded, never
|
|
214
|
+
* silent. Returns the project's stored fact view after the scan (including
|
|
215
|
+
* a `_truncated` row when the cap was hit), so repeated scans of unchanged
|
|
216
|
+
* files return identical results.
|
|
217
|
+
*/
|
|
218
|
+
scan(_now) {
|
|
219
|
+
this.ensureTables();
|
|
220
|
+
if (!this.hasTable)
|
|
221
|
+
return [];
|
|
222
|
+
const mtimes = this.fileMtimes();
|
|
223
|
+
const ordered = [];
|
|
224
|
+
const fileMtimeToStore = {};
|
|
225
|
+
const existingTruncation = this.storedTruncation();
|
|
226
|
+
const forceFullScan = existingTruncation !== null &&
|
|
227
|
+
["package.json", "tsconfig.json"].some((file) => {
|
|
228
|
+
const current = mtimes[file];
|
|
229
|
+
if (current === null) {
|
|
230
|
+
return (this.hasStoredFileFacts(file) ||
|
|
231
|
+
(this.lastMtimes.has(file) && this.lastMtimes.get(file) !== null));
|
|
232
|
+
}
|
|
233
|
+
return this.getStoredMtime(file) !== current;
|
|
234
|
+
});
|
|
235
|
+
let parsedAny = false;
|
|
236
|
+
let changedAny = false;
|
|
237
|
+
// Deterministic order: package.json first, then tsconfig.json; within
|
|
238
|
+
// each group, source key order for a freshly parsed file and stored
|
|
239
|
+
// order (by key_path) for an unchanged file.
|
|
240
|
+
for (const file of ["package.json", "tsconfig.json"]) {
|
|
241
|
+
const current = mtimes[file];
|
|
242
|
+
if (current === null) {
|
|
243
|
+
// File gone: it contributes no facts and its rows are dropped.
|
|
244
|
+
fileMtimeToStore[file] = null;
|
|
245
|
+
if (this.hasStoredFileFacts(file) ||
|
|
246
|
+
(this.lastMtimes.has(file) && this.lastMtimes.get(file) !== null)) {
|
|
247
|
+
changedAny = true;
|
|
248
|
+
}
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const stored = this.getStoredMtime(file);
|
|
252
|
+
let facts;
|
|
253
|
+
if (!forceFullScan && stored === current) {
|
|
254
|
+
// Unchanged: reuse stored facts, no parsing.
|
|
255
|
+
facts = this.lastFacts.get(file) ?? this.storedFileFacts(file);
|
|
256
|
+
fileMtimeToStore[file] = stored;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
facts = this.extractFile(file);
|
|
260
|
+
parsedAny = true;
|
|
261
|
+
changedAny = true;
|
|
262
|
+
fileMtimeToStore[file] = current;
|
|
263
|
+
}
|
|
264
|
+
ordered.push(...facts);
|
|
265
|
+
}
|
|
266
|
+
if (!changedAny)
|
|
267
|
+
return this.currentScanFacts();
|
|
268
|
+
// Bound the combined set at the documented cap; record any truncation.
|
|
269
|
+
const total = existingTruncation !== null && !parsedAny
|
|
270
|
+
? existingTruncation
|
|
271
|
+
: ordered.length;
|
|
272
|
+
let toPersist = ordered.slice(0, MAX_FACTS_PER_PROJECT);
|
|
273
|
+
if (total > MAX_FACTS_PER_PROJECT) {
|
|
274
|
+
toPersist = toPersist.concat({
|
|
275
|
+
file: "package.json",
|
|
276
|
+
keyPath: "_truncated",
|
|
277
|
+
value: String(total),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
// Record which dependency packages ARE present right now (the state
|
|
281
|
+
// this scan is about to replace) so check 2 can tell a disappeared
|
|
282
|
+
// dependency from one that was never present (K7-007 / D7-05).
|
|
283
|
+
this.prevDeps.set(this.projectId, this.currentDepPackages());
|
|
284
|
+
this.persistAll(toPersist, fileMtimeToStore);
|
|
285
|
+
for (const file of ["package.json", "tsconfig.json"]) {
|
|
286
|
+
this.lastFacts.set(file, toPersist.filter((fact) => fact.file === file && fact.keyPath !== "_truncated"));
|
|
287
|
+
}
|
|
288
|
+
for (const file of ["package.json", "tsconfig.json"]) {
|
|
289
|
+
this.lastMtimes.set(file, mtimes[file]);
|
|
290
|
+
}
|
|
291
|
+
this.lastScanAt = (_now ?? new Date()).toISOString();
|
|
292
|
+
if (parsedAny) {
|
|
293
|
+
this.metrics?.incr("repo_facts_scanned", this.storedFactCount());
|
|
294
|
+
}
|
|
295
|
+
// Return the correctly-bounded fact set in deterministic source order
|
|
296
|
+
// (package.json then tsconfig.json, group order then source key order),
|
|
297
|
+
// so the returned keys are stable and match the documented extraction.
|
|
298
|
+
return toPersist;
|
|
299
|
+
}
|
|
300
|
+
hasStoredFileFacts(file) {
|
|
301
|
+
const row = this.store
|
|
302
|
+
.prepare(`SELECT 1 AS present FROM repo_facts
|
|
303
|
+
WHERE project_id = ? AND file = ?
|
|
304
|
+
LIMIT 1`)
|
|
305
|
+
.get(this.projectId, file);
|
|
306
|
+
return row !== undefined;
|
|
307
|
+
}
|
|
308
|
+
currentScanFacts() {
|
|
309
|
+
const facts = [
|
|
310
|
+
...(this.lastFacts.get("package.json") ??
|
|
311
|
+
this.storedFileFacts("package.json")),
|
|
312
|
+
...(this.lastFacts.get("tsconfig.json") ??
|
|
313
|
+
this.storedFileFacts("tsconfig.json")),
|
|
314
|
+
];
|
|
315
|
+
const truncated = this.storedTruncation();
|
|
316
|
+
return truncated === null
|
|
317
|
+
? facts
|
|
318
|
+
: facts.slice(0, MAX_FACTS_PER_PROJECT).concat({
|
|
319
|
+
file: "package.json",
|
|
320
|
+
keyPath: "_truncated",
|
|
321
|
+
value: String(truncated),
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
storedFileFacts(file) {
|
|
325
|
+
const rows = this.store
|
|
326
|
+
.prepare(`SELECT file, key_path AS keyPath, value
|
|
327
|
+
FROM repo_facts
|
|
328
|
+
WHERE project_id = ? AND file = ? AND key_path <> '_truncated'
|
|
329
|
+
ORDER BY id`)
|
|
330
|
+
.all(this.projectId, file);
|
|
331
|
+
return rows;
|
|
332
|
+
}
|
|
333
|
+
getStoredMtime(file) {
|
|
334
|
+
const row = this.store
|
|
335
|
+
.prepare(`SELECT source_mtime AS m
|
|
336
|
+
FROM repo_facts
|
|
337
|
+
WHERE project_id = ? AND file = ? AND key_path <> '_truncated'
|
|
338
|
+
LIMIT 1`)
|
|
339
|
+
.get(this.projectId, file);
|
|
340
|
+
return row?.m ?? this.lastMtimes.get(file) ?? null;
|
|
341
|
+
}
|
|
342
|
+
persistAll(facts, fileMtimeToStore) {
|
|
343
|
+
const delAll = this.store.prepare("DELETE FROM repo_facts WHERE project_id = ?");
|
|
344
|
+
const insert = this.store.prepare(`INSERT INTO repo_facts (id, project_id, file, key_path, value, fingerprint, source_mtime, scanned_at)
|
|
345
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'))`);
|
|
346
|
+
this.store.transaction(() => {
|
|
347
|
+
delAll.run(this.projectId);
|
|
348
|
+
for (const fact of facts) {
|
|
349
|
+
const mtime = fact.keyPath === "_truncated"
|
|
350
|
+
? (fileMtimeToStore["package.json"] ?? null)
|
|
351
|
+
: (fileMtimeToStore[fact.file] ?? null);
|
|
352
|
+
insert.run(uuidv7(), this.projectId, fact.file, fact.keyPath, fact.value, fingerprint(normalizedKeyPath(fact), this.projectId), mtime);
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
storedFactCount() {
|
|
357
|
+
const row = this.store
|
|
358
|
+
.prepare(`SELECT COUNT(*) AS c FROM repo_facts
|
|
359
|
+
WHERE project_id = ? AND key_path <> '_truncated'`)
|
|
360
|
+
.get(this.projectId);
|
|
361
|
+
return row.c;
|
|
362
|
+
}
|
|
363
|
+
storedTruncation() {
|
|
364
|
+
const row = this.store
|
|
365
|
+
.prepare(`SELECT value FROM repo_facts
|
|
366
|
+
WHERE project_id = ? AND key_path = '_truncated'
|
|
367
|
+
LIMIT 1`)
|
|
368
|
+
.get(this.projectId);
|
|
369
|
+
if (!row)
|
|
370
|
+
return null;
|
|
371
|
+
const count = Number(row.value);
|
|
372
|
+
return Number.isFinite(count) && count > MAX_FACTS_PER_PROJECT
|
|
373
|
+
? count
|
|
374
|
+
: null;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* v0.7.0 (K7-006 / plan §5.2) — extract a file's facts WITHOUT writing
|
|
378
|
+
* anything. Used by scan to keep a single source of truth for extraction.
|
|
379
|
+
*/
|
|
380
|
+
extractFile(file) {
|
|
381
|
+
const filePath = join(this.projectRoot, file);
|
|
382
|
+
const parsed = readJsonFile(filePath);
|
|
383
|
+
if (parsed === null)
|
|
384
|
+
return [];
|
|
385
|
+
if (file === "package.json")
|
|
386
|
+
return extractFromPackageJson(parsed);
|
|
387
|
+
if (file === "tsconfig.json")
|
|
388
|
+
return extractFromTsconfig(parsed);
|
|
389
|
+
return [];
|
|
390
|
+
}
|
|
391
|
+
fileMtimes() {
|
|
392
|
+
const out = {};
|
|
393
|
+
for (const file of ["package.json", "tsconfig.json"]) {
|
|
394
|
+
try {
|
|
395
|
+
const st = statSync(join(this.projectRoot, file));
|
|
396
|
+
out[file] = String(st.mtimeMs);
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
out[file] = null;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return out;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* v0.7.0 (K7-006 / plan §5.2, D7-02) — the project-scoped stored facts.
|
|
406
|
+
* Every read filters on `project_id`, so a second project's facts never
|
|
407
|
+
* leak into this project's view.
|
|
408
|
+
*/
|
|
409
|
+
facts() {
|
|
410
|
+
this.ensureTables();
|
|
411
|
+
if (!this.hasTable)
|
|
412
|
+
return [];
|
|
413
|
+
const rows = this.store
|
|
414
|
+
.prepare(`SELECT file, key_path AS keyPath, value
|
|
415
|
+
FROM repo_facts
|
|
416
|
+
WHERE project_id = ?
|
|
417
|
+
ORDER BY file, key_path`)
|
|
418
|
+
.all(this.projectId);
|
|
419
|
+
return rows;
|
|
420
|
+
}
|
|
421
|
+
/** v0.7.0 (K7-009) — human-readable fact rows for `kevin_facts`. */
|
|
422
|
+
storeFacts() {
|
|
423
|
+
this.ensureTables();
|
|
424
|
+
if (!this.hasTable)
|
|
425
|
+
return [];
|
|
426
|
+
const rows = this.store
|
|
427
|
+
.prepare(`SELECT id, project_id AS projectId, file, key_path AS keyPath, value,
|
|
428
|
+
fingerprint, source_mtime AS sourceMtime, scanned_at AS scannedAt
|
|
429
|
+
FROM repo_facts
|
|
430
|
+
WHERE project_id = ?
|
|
431
|
+
ORDER BY file, key_path`)
|
|
432
|
+
.all(this.projectId);
|
|
433
|
+
return rows;
|
|
434
|
+
}
|
|
435
|
+
/** Timestamp of the latest scan in this process or persisted facts. */
|
|
436
|
+
scannedAt() {
|
|
437
|
+
if (this.lastScanAt)
|
|
438
|
+
return this.lastScanAt;
|
|
439
|
+
this.ensureTables();
|
|
440
|
+
if (!this.hasTable)
|
|
441
|
+
return null;
|
|
442
|
+
const row = this.store
|
|
443
|
+
.prepare("SELECT MAX(scanned_at) AS scannedAt FROM repo_facts WHERE project_id = ?")
|
|
444
|
+
.get(this.projectId);
|
|
445
|
+
return row?.scannedAt ?? null;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* v0.7.0 (K7-007 / plan §5.1, D7-05) — exact-match contradiction detection:
|
|
449
|
+
* the three and only three checks. Each returns a human-readable reason;
|
|
450
|
+
* empty when consistent. Pure read — writes nothing (K7-008 and K7-014 own
|
|
451
|
+
* the penalty and conflict-row writes).
|
|
452
|
+
*/
|
|
453
|
+
contradictions(memory) {
|
|
454
|
+
this.ensureTables();
|
|
455
|
+
if (!this.hasTable)
|
|
456
|
+
return [];
|
|
457
|
+
const reasons = [];
|
|
458
|
+
const current = this.facts();
|
|
459
|
+
reasons.push(...this.checkMissingScripts(memory, current));
|
|
460
|
+
reasons.push(...this.checkMissingDependencies(memory, current));
|
|
461
|
+
reasons.push(...this.checkChangedCompilerOptions(memory, current));
|
|
462
|
+
return reasons;
|
|
463
|
+
}
|
|
464
|
+
checkMissingScripts(memory, current) {
|
|
465
|
+
const scriptNames = referencedScripts(memory.content);
|
|
466
|
+
const present = new Set(current
|
|
467
|
+
.filter((f) => f.file === "package.json" && f.keyPath.startsWith("scripts."))
|
|
468
|
+
.map((f) => f.keyPath.slice("scripts.".length)));
|
|
469
|
+
const reasons = [];
|
|
470
|
+
for (const name of scriptNames) {
|
|
471
|
+
if (!present.has(name)) {
|
|
472
|
+
reasons.push(`\`${scriptInvocation(name)}\` is referenced but \`scripts.${name}\` does not exist in this project`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return reasons;
|
|
476
|
+
}
|
|
477
|
+
checkMissingDependencies(memory, current) {
|
|
478
|
+
const packages = referencedPackages(memory.content);
|
|
479
|
+
if (packages.length === 0)
|
|
480
|
+
return [];
|
|
481
|
+
// Packages currently declared as dependencies, keyed by name.
|
|
482
|
+
const present = new Set();
|
|
483
|
+
for (const f of current) {
|
|
484
|
+
if (!f.keyPath.startsWith("dependencies.") &&
|
|
485
|
+
!f.keyPath.startsWith("devDependencies.") &&
|
|
486
|
+
!f.keyPath.startsWith("optionalDependencies.")) {
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
const name = f.keyPath.slice(f.keyPath.indexOf(".") + 1);
|
|
490
|
+
present.add(name);
|
|
491
|
+
}
|
|
492
|
+
const previous = this.prevDeps.get(this.projectId) ?? new Set();
|
|
493
|
+
const reasons = [];
|
|
494
|
+
for (const pkg of packages) {
|
|
495
|
+
// Fire only for a DISAPPEARED dependency: absent now but present at
|
|
496
|
+
// the previous scan. A package that was never a dependency is not a
|
|
497
|
+
// contradiction (D7-05 — mention is not assertion).
|
|
498
|
+
if (!present.has(pkg) && previous.has(pkg)) {
|
|
499
|
+
reasons.push(`dependency \`${pkg}\` is referenced but no longer declared in dependencies/devDependencies/optionalDependencies`);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return reasons;
|
|
503
|
+
}
|
|
504
|
+
checkChangedCompilerOptions(memory, current) {
|
|
505
|
+
const assertions = compilerOptionAssertions(memory.content);
|
|
506
|
+
if (assertions.size === 0)
|
|
507
|
+
return [];
|
|
508
|
+
const facts = new Map();
|
|
509
|
+
for (const f of current) {
|
|
510
|
+
if (f.file === "tsconfig.json" &&
|
|
511
|
+
f.keyPath.startsWith("compilerOptions.")) {
|
|
512
|
+
facts.set(f.keyPath.slice("compilerOptions.".length), f.value);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
const reasons = [];
|
|
516
|
+
for (const [option, asserted] of assertions) {
|
|
517
|
+
const factValue = facts.get(option);
|
|
518
|
+
if (factValue === undefined)
|
|
519
|
+
continue;
|
|
520
|
+
const currentBool = normalizeBool(factValue);
|
|
521
|
+
const assertedBool = normalizeBool(asserted);
|
|
522
|
+
if (assertedBool !== null &&
|
|
523
|
+
currentBool !== null &&
|
|
524
|
+
assertedBool !== currentBool) {
|
|
525
|
+
reasons.push(`\`compilerOptions.${option}\` is asserted as \`${asserted}\` but the current value is \`${factValue}\``);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return reasons;
|
|
529
|
+
}
|
|
530
|
+
currentDepPackages() {
|
|
531
|
+
const out = new Set();
|
|
532
|
+
const rows = this.store
|
|
533
|
+
.prepare(`SELECT key_path AS keyPath FROM repo_facts
|
|
534
|
+
WHERE project_id = ? AND (key_path LIKE 'dependencies.%' OR key_path LIKE 'devDependencies.%' OR key_path LIKE 'optionalDependencies.%')`)
|
|
535
|
+
.all(this.projectId);
|
|
536
|
+
for (const r of rows) {
|
|
537
|
+
out.add(r.keyPath.slice(r.keyPath.indexOf(".") + 1));
|
|
538
|
+
}
|
|
539
|
+
return out;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
// v0.7.0 (K7-007 / plan §5.1, D7-05) — pure, exact-match helpers. No fuzzy
|
|
543
|
+
// similarity, no edit distance, no substring-implies-assertion.
|
|
544
|
+
/** `npm run lint`, `pnpm run test`, `yarn build` → the script names. */
|
|
545
|
+
function referencedScripts(content) {
|
|
546
|
+
const out = [];
|
|
547
|
+
const re = /\b(?:npm|pnpm)\s+run\s+([A-Za-z0-9_.:@/\-]+)|\byarn\s+([A-Za-z0-9_.:@/\-]+)/g;
|
|
548
|
+
let m = re.exec(content);
|
|
549
|
+
while (m !== null) {
|
|
550
|
+
const name = m[1] ?? m[2];
|
|
551
|
+
if (name)
|
|
552
|
+
out.push(name);
|
|
553
|
+
m = re.exec(content);
|
|
554
|
+
}
|
|
555
|
+
return [...new Set(out)];
|
|
556
|
+
}
|
|
557
|
+
function scriptInvocation(name) {
|
|
558
|
+
return `npm run ${name}`;
|
|
559
|
+
}
|
|
560
|
+
/** Package names the memory asserts as in-use/dependencies. */
|
|
561
|
+
function referencedPackages(content) {
|
|
562
|
+
const out = [];
|
|
563
|
+
const re = /\b(?:use[s]?|need[s]?|require[s]?|depends?\s+on|instal?l|dependencies?)\s+(?:the\s+)?(?:package\s+)?[`'"]?([@]?[A-Za-z0-9][A-Za-z0-9._\-@/]*)/gi;
|
|
564
|
+
let m = re.exec(content);
|
|
565
|
+
while (m !== null) {
|
|
566
|
+
const pkg = (m[1] ?? "").replace(/[`'",.;:)]+$/, "");
|
|
567
|
+
if (pkg)
|
|
568
|
+
out.push(pkg);
|
|
569
|
+
m = re.exec(content);
|
|
570
|
+
}
|
|
571
|
+
return [...new Set(out)];
|
|
572
|
+
}
|
|
573
|
+
/** `compilerOptions.strict` mentions with the polarity the memory asserts. */
|
|
574
|
+
function compilerOptionAssertions(content) {
|
|
575
|
+
const out = new Map();
|
|
576
|
+
const optionRe = /compilerOptions\.([A-Za-z0-9_]+)/g;
|
|
577
|
+
let m = optionRe.exec(content);
|
|
578
|
+
while (m !== null) {
|
|
579
|
+
const option = m[1] ?? "";
|
|
580
|
+
// The asserted polarity is read from the nearest boolean token within
|
|
581
|
+
// the following 3 words (e.g. "strict is false", "strict: true").
|
|
582
|
+
const tail = content.slice(m.index).slice(0, 40);
|
|
583
|
+
const polarity = tail.match(/\b(true|false|on|off|enabled|disabled)\b/i);
|
|
584
|
+
if (polarity)
|
|
585
|
+
out.set(option, polarity[1] ?? "");
|
|
586
|
+
m = optionRe.exec(content);
|
|
587
|
+
}
|
|
588
|
+
return out;
|
|
589
|
+
}
|
|
590
|
+
/** Interpret a stringified value as a boolean, or null when it is not one. */
|
|
591
|
+
function normalizeBool(v) {
|
|
592
|
+
const s = v.trim().toLowerCase();
|
|
593
|
+
if (s === "true" || s === "on" || s === "enabled" || s === "1")
|
|
594
|
+
return true;
|
|
595
|
+
if (s === "false" || s === "off" || s === "disabled" || s === "0")
|
|
596
|
+
return false;
|
|
597
|
+
return null;
|
|
598
|
+
}
|
|
599
|
+
export { MAX_FACTS_PER_PROJECT };
|
|
600
|
+
//# sourceMappingURL=RepoTruth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RepoTruth.js","sourceRoot":"","sources":["../../plugin/RepoTruth.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,6 +41,14 @@ export const METRIC_KEY_LABELS = {
|
|
|
41
41
|
artifact_writes_total: "Escrituras de artefacto (escritas)",
|
|
42
42
|
artifact_writes_noop: "Escrituras de artefacto (sin cambios)",
|
|
43
43
|
injections_blocked_confidence: "Inyecciones bloqueadas (confianza baja)",
|
|
44
|
+
// v0.7.0 (K7-004 / plan §8.3) — the K7 metric keys need their own
|
|
45
|
+
// Spanish labels; the audit regression forbids raw-key fallback for any
|
|
46
|
+
// key in METRIC_KEYS.
|
|
47
|
+
repo_facts_scanned: "Hechos del repositorio escaneados",
|
|
48
|
+
memories_contradicted: "Memorias contradichas",
|
|
49
|
+
conventions_mined: "Convenciones minadas",
|
|
50
|
+
conflicts_detected: "Conflictos detectados",
|
|
51
|
+
error_lessons_suppressed: "Lecciones de error suprimidas",
|
|
44
52
|
};
|
|
45
53
|
function originLabel(origin) {
|
|
46
54
|
if (origin === "reflector")
|