@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.
Files changed (52) hide show
  1. package/README.md +582 -580
  2. package/dist/migrations/001_initial.sql +91 -91
  3. package/dist/migrations/003_v02_signal.sql +57 -57
  4. package/dist/migrations/004_v03_knowledge.sql +138 -138
  5. package/dist/migrations/005_v04_signal.sql +57 -57
  6. package/dist/migrations/006_v05_glassbox.sql +118 -118
  7. package/dist/migrations/007_v06_pull.sql +144 -144
  8. package/dist/migrations/008_v07_truth.sql +124 -0
  9. package/dist/plugin/ConflictDetector.d.ts +35 -0
  10. package/dist/plugin/ConflictDetector.js +283 -0
  11. package/dist/plugin/ConflictDetector.js.map +1 -0
  12. package/dist/plugin/ConventionMiner.d.ts +35 -0
  13. package/dist/plugin/ConventionMiner.js +243 -0
  14. package/dist/plugin/ConventionMiner.js.map +1 -0
  15. package/dist/plugin/Curator.js +45 -14
  16. package/dist/plugin/Curator.js.map +1 -1
  17. package/dist/plugin/MemoryService.d.ts +18 -0
  18. package/dist/plugin/MemoryService.js +92 -2
  19. package/dist/plugin/MemoryService.js.map +1 -1
  20. package/dist/plugin/Migrate.js +31 -2
  21. package/dist/plugin/Migrate.js.map +1 -1
  22. package/dist/plugin/Reflector.js +13 -0
  23. package/dist/plugin/Reflector.js.map +1 -1
  24. package/dist/plugin/RepoTruth.d.ts +80 -0
  25. package/dist/plugin/RepoTruth.js +600 -0
  26. package/dist/plugin/RepoTruth.js.map +1 -0
  27. package/dist/plugin/Retrospective.js +8 -0
  28. package/dist/plugin/Retrospective.js.map +1 -1
  29. package/dist/plugin/index.d.ts +7 -2
  30. package/dist/plugin/index.js +135 -2
  31. package/dist/plugin/index.js.map +1 -1
  32. package/dist/plugin/kevin_audit.d.ts +41 -1
  33. package/dist/plugin/kevin_audit.js +98 -3
  34. package/dist/plugin/kevin_audit.js.map +1 -1
  35. package/dist/plugin/kevin_conflicts.d.ts +9 -0
  36. package/dist/plugin/kevin_conflicts.js +51 -0
  37. package/dist/plugin/kevin_conflicts.js.map +1 -0
  38. package/dist/plugin/kevin_facts.d.ts +42 -0
  39. package/dist/plugin/kevin_facts.js +37 -0
  40. package/dist/plugin/kevin_facts.js.map +1 -0
  41. package/dist/plugin/metrics.d.ts +3 -3
  42. package/dist/plugin/metrics.js +12 -2
  43. package/dist/plugin/metrics.js.map +1 -1
  44. package/dist/plugin/replay-types.d.ts +2 -2
  45. package/migrations/001_initial.sql +91 -91
  46. package/migrations/003_v02_signal.sql +57 -57
  47. package/migrations/004_v03_knowledge.sql +138 -138
  48. package/migrations/005_v04_signal.sql +57 -57
  49. package/migrations/006_v05_glassbox.sql +118 -118
  50. package/migrations/007_v06_pull.sql +144 -144
  51. package/migrations/008_v07_truth.sql +124 -0
  52. 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")