@nxuss/lemma 1.23.0 → 1.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -6
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +15 -3
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/infra/errorCause.d.ts +36 -0
- package/dist/cjs/infra/errorCause.d.ts.map +1 -0
- package/dist/cjs/infra/errorCause.js +143 -0
- package/dist/cjs/infra/errorCause.js.map +1 -0
- package/dist/cjs/infra/providers/JenkinsProvider.d.ts.map +1 -1
- package/dist/cjs/infra/providers/JenkinsProvider.js +5 -0
- package/dist/cjs/infra/providers/JenkinsProvider.js.map +1 -1
- package/dist/cjs/infra/providers/OKDProvider.d.ts.map +1 -1
- package/dist/cjs/infra/providers/OKDProvider.js +5 -1
- package/dist/cjs/infra/providers/OKDProvider.js.map +1 -1
- package/dist/cjs/infra/providers/TerraformProvider.d.ts.map +1 -1
- package/dist/cjs/infra/providers/TerraformProvider.js +3 -1
- package/dist/cjs/infra/providers/TerraformProvider.js.map +1 -1
- package/dist/cjs/mcp/index.js +21 -0
- package/dist/cjs/mcp/index.js.map +1 -1
- package/dist/cjs/mcp/tool-profiles.d.ts +6 -4
- package/dist/cjs/mcp/tool-profiles.d.ts.map +1 -1
- package/dist/cjs/mcp/tool-profiles.js.map +1 -1
- package/dist/cjs/mcp/tools/context-tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/context-tools.js +3 -1
- package/dist/cjs/mcp/tools/context-tools.js.map +1 -1
- package/dist/cjs/mcp/tools/memory.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/memory.js +45 -10
- package/dist/cjs/mcp/tools/memory.js.map +1 -1
- package/dist/cjs/mcp/tools/misc.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/misc.js +21 -9
- package/dist/cjs/mcp/tools/misc.js.map +1 -1
- package/dist/cjs/mcp/tools/squeeze-cache.d.ts +6 -0
- package/dist/cjs/mcp/tools/squeeze-cache.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/squeeze-cache.js +57 -17
- package/dist/cjs/mcp/tools/squeeze-cache.js.map +1 -1
- package/dist/cjs/mcp/tools/workspace.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/workspace.js +7 -2
- package/dist/cjs/mcp/tools/workspace.js.map +1 -1
- package/dist/cjs/mcp/tools.d.ts +9 -0
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +72 -12
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/cjs/mcp/utils.d.ts.map +1 -1
- package/dist/cjs/mcp/utils.js +18 -4
- package/dist/cjs/mcp/utils.js.map +1 -1
- package/dist/cjs/mcp/workspaceShared.d.ts +1 -0
- package/dist/cjs/mcp/workspaceShared.d.ts.map +1 -1
- package/dist/cjs/mcp/workspaceShared.js +27 -0
- package/dist/cjs/mcp/workspaceShared.js.map +1 -1
- package/dist/cjs/subconscious/TheBrainV2.d.ts +43 -0
- package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/cjs/subconscious/TheBrainV2.js +79 -7
- package/dist/cjs/subconscious/TheBrainV2.js.map +1 -1
- package/dist/cjs/utils/AnomalyInventory.d.ts +29 -0
- package/dist/cjs/utils/AnomalyInventory.d.ts.map +1 -0
- package/dist/cjs/utils/AnomalyInventory.js +58 -0
- package/dist/cjs/utils/AnomalyInventory.js.map +1 -0
- package/dist/cjs/utils/ExecutiveReport.d.ts +10 -0
- package/dist/cjs/utils/ExecutiveReport.d.ts.map +1 -1
- package/dist/cjs/utils/ExecutiveReport.js +17 -1
- package/dist/cjs/utils/ExecutiveReport.js.map +1 -1
- package/dist/cjs/utils/SavingsLedger.d.ts +45 -2
- package/dist/cjs/utils/SavingsLedger.d.ts.map +1 -1
- package/dist/cjs/utils/SavingsLedger.js +89 -5
- package/dist/cjs/utils/SavingsLedger.js.map +1 -1
- package/dist/cjs/utils/SessionEvidence.d.ts +28 -0
- package/dist/cjs/utils/SessionEvidence.d.ts.map +1 -0
- package/dist/cjs/utils/SessionEvidence.js +55 -0
- package/dist/cjs/utils/SessionEvidence.js.map +1 -0
- package/dist/cjs/utils/StateHashCache.d.ts +10 -0
- package/dist/cjs/utils/StateHashCache.d.ts.map +1 -1
- package/dist/cjs/utils/StateHashCache.js +15 -0
- package/dist/cjs/utils/StateHashCache.js.map +1 -1
- package/dist/cjs/utils/reportSavings.d.ts +4 -0
- package/dist/cjs/utils/reportSavings.d.ts.map +1 -1
- package/dist/cjs/utils/reportSavings.js.map +1 -1
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +15 -3
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/infra/errorCause.d.ts +36 -0
- package/dist/esm/infra/errorCause.d.ts.map +1 -0
- package/dist/esm/infra/errorCause.js +138 -0
- package/dist/esm/infra/errorCause.js.map +1 -0
- package/dist/esm/infra/providers/JenkinsProvider.d.ts.map +1 -1
- package/dist/esm/infra/providers/JenkinsProvider.js +5 -0
- package/dist/esm/infra/providers/JenkinsProvider.js.map +1 -1
- package/dist/esm/infra/providers/OKDProvider.d.ts.map +1 -1
- package/dist/esm/infra/providers/OKDProvider.js +5 -1
- package/dist/esm/infra/providers/OKDProvider.js.map +1 -1
- package/dist/esm/infra/providers/TerraformProvider.d.ts.map +1 -1
- package/dist/esm/infra/providers/TerraformProvider.js +3 -1
- package/dist/esm/infra/providers/TerraformProvider.js.map +1 -1
- package/dist/esm/mcp/index.js +21 -0
- package/dist/esm/mcp/index.js.map +1 -1
- package/dist/esm/mcp/tool-profiles.d.ts +6 -4
- package/dist/esm/mcp/tool-profiles.d.ts.map +1 -1
- package/dist/esm/mcp/tool-profiles.js.map +1 -1
- package/dist/esm/mcp/tools/context-tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools/context-tools.js +3 -1
- package/dist/esm/mcp/tools/context-tools.js.map +1 -1
- package/dist/esm/mcp/tools/memory.d.ts.map +1 -1
- package/dist/esm/mcp/tools/memory.js +45 -10
- package/dist/esm/mcp/tools/memory.js.map +1 -1
- package/dist/esm/mcp/tools/misc.d.ts.map +1 -1
- package/dist/esm/mcp/tools/misc.js +21 -9
- package/dist/esm/mcp/tools/misc.js.map +1 -1
- package/dist/esm/mcp/tools/squeeze-cache.d.ts +6 -0
- package/dist/esm/mcp/tools/squeeze-cache.d.ts.map +1 -1
- package/dist/esm/mcp/tools/squeeze-cache.js +56 -17
- package/dist/esm/mcp/tools/squeeze-cache.js.map +1 -1
- package/dist/esm/mcp/tools/workspace.d.ts.map +1 -1
- package/dist/esm/mcp/tools/workspace.js +8 -3
- package/dist/esm/mcp/tools/workspace.js.map +1 -1
- package/dist/esm/mcp/tools.d.ts +9 -0
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +71 -12
- package/dist/esm/mcp/tools.js.map +1 -1
- package/dist/esm/mcp/utils.d.ts.map +1 -1
- package/dist/esm/mcp/utils.js +18 -4
- package/dist/esm/mcp/utils.js.map +1 -1
- package/dist/esm/mcp/workspaceShared.d.ts +1 -0
- package/dist/esm/mcp/workspaceShared.d.ts.map +1 -1
- package/dist/esm/mcp/workspaceShared.js +26 -0
- package/dist/esm/mcp/workspaceShared.js.map +1 -1
- package/dist/esm/subconscious/TheBrainV2.d.ts +43 -0
- package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/esm/subconscious/TheBrainV2.js +79 -7
- package/dist/esm/subconscious/TheBrainV2.js.map +1 -1
- package/dist/esm/utils/AnomalyInventory.d.ts +29 -0
- package/dist/esm/utils/AnomalyInventory.d.ts.map +1 -0
- package/dist/esm/utils/AnomalyInventory.js +49 -0
- package/dist/esm/utils/AnomalyInventory.js.map +1 -0
- package/dist/esm/utils/ExecutiveReport.d.ts +10 -0
- package/dist/esm/utils/ExecutiveReport.d.ts.map +1 -1
- package/dist/esm/utils/ExecutiveReport.js +17 -1
- package/dist/esm/utils/ExecutiveReport.js.map +1 -1
- package/dist/esm/utils/SavingsLedger.d.ts +45 -2
- package/dist/esm/utils/SavingsLedger.d.ts.map +1 -1
- package/dist/esm/utils/SavingsLedger.js +89 -5
- package/dist/esm/utils/SavingsLedger.js.map +1 -1
- package/dist/esm/utils/SessionEvidence.d.ts +28 -0
- package/dist/esm/utils/SessionEvidence.d.ts.map +1 -0
- package/dist/esm/utils/SessionEvidence.js +49 -0
- package/dist/esm/utils/SessionEvidence.js.map +1 -0
- package/dist/esm/utils/StateHashCache.d.ts +10 -0
- package/dist/esm/utils/StateHashCache.d.ts.map +1 -1
- package/dist/esm/utils/StateHashCache.js +14 -0
- package/dist/esm/utils/StateHashCache.js.map +1 -1
- package/dist/esm/utils/reportSavings.d.ts +4 -0
- package/dist/esm/utils/reportSavings.d.ts.map +1 -1
- package/dist/esm/utils/reportSavings.js.map +1 -1
- package/package.json +1 -1
|
@@ -331,6 +331,12 @@ function parseEntriesWithStats(raw) {
|
|
|
331
331
|
// don't. Rebuilding from termFreq covers both without a migration step.
|
|
332
332
|
if (!Array.isArray(entry.terms))
|
|
333
333
|
entry.terms = Object.keys(entry.termFreq || {});
|
|
334
|
+
// Entries written before clear-path persistence keep only hashes: backfill the
|
|
335
|
+
// labels from the hash keys so old memories become navigable on first read.
|
|
336
|
+
// Next save() persists the backfill — no separate migration step, no rewrite.
|
|
337
|
+
syncClearEvidencePaths(entry);
|
|
338
|
+
for (const claim of entry.claims || [])
|
|
339
|
+
syncClearEvidencePaths(claim);
|
|
334
340
|
out.set(entry.id, entry);
|
|
335
341
|
}
|
|
336
342
|
catch {
|
|
@@ -1114,16 +1120,38 @@ function trackedClaimArtifactCount(claim) {
|
|
|
1114
1120
|
return Object.keys(claim.fileHashes || {}).length + Object.keys(claim.symbolHashes || {}).length;
|
|
1115
1121
|
}
|
|
1116
1122
|
/** Builds the persisted `Claim[]` for an entry from the caller-supplied claim inputs. */
|
|
1123
|
+
/**
|
|
1124
|
+
* Re-derive the clear-path labels from the hash keys they describe. One-way only:
|
|
1125
|
+
* hashes are the source of truth, these fields are the navigable label. Called on
|
|
1126
|
+
* every path that (re)writes evidence — store(), reanchorEvidence(), and the load
|
|
1127
|
+
* backfill — so the three can never disagree about which file a memory means.
|
|
1128
|
+
*/
|
|
1129
|
+
function syncClearEvidencePaths(target) {
|
|
1130
|
+
const files = target.fileHashes ? Object.keys(target.fileHashes).sort() : [];
|
|
1131
|
+
if (files.length > 0)
|
|
1132
|
+
target.filePaths = files;
|
|
1133
|
+
else
|
|
1134
|
+
delete target.filePaths;
|
|
1135
|
+
const syms = target.symbolHashes ? Object.keys(target.symbolHashes).sort() : [];
|
|
1136
|
+
if (syms.length > 0)
|
|
1137
|
+
target.symbols = syms;
|
|
1138
|
+
else
|
|
1139
|
+
delete target.symbols;
|
|
1140
|
+
}
|
|
1117
1141
|
function buildClaims(inputs) {
|
|
1118
1142
|
return inputs
|
|
1119
1143
|
.filter((c) => c?.text)
|
|
1120
|
-
.map((c) =>
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1144
|
+
.map((c) => {
|
|
1145
|
+
const claim = {
|
|
1146
|
+
id: crypto_1.default.createHash('sha1').update(c.text.trim().toLowerCase()).digest('hex').substring(0, 10),
|
|
1147
|
+
text: c.text.trim(),
|
|
1148
|
+
fileHashes: c.filePaths && c.filePaths.length > 0 ? hashFilesForFreshness(c.filePaths) : undefined,
|
|
1149
|
+
symbolHashes: c.symbols && c.symbols.length > 0 ? hashSymbolsForFreshness(c.symbols) : undefined,
|
|
1150
|
+
symbolNormalizedHashes: c.symbols && c.symbols.length > 0 ? hashSymbolsNormalizedForFreshness(c.symbols) : undefined,
|
|
1151
|
+
};
|
|
1152
|
+
syncClearEvidencePaths(claim);
|
|
1153
|
+
return claim;
|
|
1154
|
+
});
|
|
1127
1155
|
}
|
|
1128
1156
|
/**
|
|
1129
1157
|
* Same hash-compare as checkEntryFreshness, scoped to one claim's own evidence — a claim
|
|
@@ -1352,6 +1380,22 @@ class TheBrainV2 {
|
|
|
1352
1380
|
this.save();
|
|
1353
1381
|
}, 500);
|
|
1354
1382
|
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Synchronously persist pending writes, if any. The debounced scheduleSave() above
|
|
1385
|
+
* is correct for a long-lived server but loses data when the process is about to
|
|
1386
|
+
* die: one-shot clients (lemma-call, the Muse skill path) kill the MCP server right
|
|
1387
|
+
* after the tool response, so without this every one-shot store/update/forget is
|
|
1388
|
+
* silently dropped. Installed as a SIGTERM/SIGINT handler by the MCP bootstrap —
|
|
1389
|
+
* never called on the hot path, where the debounce still applies.
|
|
1390
|
+
*/
|
|
1391
|
+
flushSync() {
|
|
1392
|
+
if (this.flushTimer) {
|
|
1393
|
+
clearTimeout(this.flushTimer);
|
|
1394
|
+
this.flushTimer = null;
|
|
1395
|
+
}
|
|
1396
|
+
if (this.dirty)
|
|
1397
|
+
this.save();
|
|
1398
|
+
}
|
|
1355
1399
|
save() {
|
|
1356
1400
|
const fd = acquireLock();
|
|
1357
1401
|
let wroteClean = false;
|
|
@@ -1575,6 +1619,9 @@ class TheBrainV2 {
|
|
|
1575
1619
|
...(git.commit ? { gitCommit: git.commit } : {}),
|
|
1576
1620
|
...(git.branch ? { gitBranch: git.branch } : {}),
|
|
1577
1621
|
};
|
|
1622
|
+
// Persist the tracked paths in clear next to the hashes (AN-03) — the labels
|
|
1623
|
+
// display and navigation read from here; freshness keeps reading the hashes.
|
|
1624
|
+
syncClearEvidencePaths(entry);
|
|
1578
1625
|
this.entries.set(id, entry);
|
|
1579
1626
|
// Update inverted index
|
|
1580
1627
|
for (const term of entry.terms) {
|
|
@@ -1687,6 +1734,11 @@ class TheBrainV2 {
|
|
|
1687
1734
|
const entry = this.entries.get(id);
|
|
1688
1735
|
if (!entry)
|
|
1689
1736
|
continue;
|
|
1737
|
+
// A superseded entry is a known-wrong conclusion with a named successor (AN-22) — it
|
|
1738
|
+
// must never rank as if still live, unlike a downvote which only demotes. get_memory
|
|
1739
|
+
// still resolves it directly and points at the successor; search() just never offers it.
|
|
1740
|
+
if (entry.supersededBy)
|
|
1741
|
+
continue;
|
|
1690
1742
|
const bm25 = bm25Score(queryTerms, entry.termFreq, entry.terms.length, this.avgDocLength || 10, idf);
|
|
1691
1743
|
const docTermSet = new Set(entry.terms);
|
|
1692
1744
|
const jaccard = jaccardSimilarity(queryTermSet, docTermSet);
|
|
@@ -2470,6 +2522,11 @@ class TheBrainV2 {
|
|
|
2470
2522
|
}
|
|
2471
2523
|
}
|
|
2472
2524
|
}
|
|
2525
|
+
// Hashes were just rewritten — re-derive the clear labels so they track the same
|
|
2526
|
+
// files (covers both the re-point and the re-anchor branches above, and update()).
|
|
2527
|
+
syncClearEvidencePaths(entry);
|
|
2528
|
+
for (const claim of entry.claims || [])
|
|
2529
|
+
syncClearEvidencePaths(claim);
|
|
2473
2530
|
return retracked;
|
|
2474
2531
|
}
|
|
2475
2532
|
refresh(id, opts = {}) {
|
|
@@ -2521,6 +2578,16 @@ class TheBrainV2 {
|
|
|
2521
2578
|
const entry = this.entries.get(id);
|
|
2522
2579
|
if (!entry)
|
|
2523
2580
|
return { ok: false, message: `No entry with id "${id}" in the Brain.` };
|
|
2581
|
+
if (patch.supersededBy !== undefined) {
|
|
2582
|
+
const successorId = patch.supersededBy.trim();
|
|
2583
|
+
if (successorId && successorId === id) {
|
|
2584
|
+
return { ok: false, message: `"${id}" cannot supersede itself.` };
|
|
2585
|
+
}
|
|
2586
|
+
if (successorId && !this.entries.has(successorId)) {
|
|
2587
|
+
return { ok: false, message: `supersededBy target "${successorId}" is not an entry in the Brain — check the id with get_memory first.` };
|
|
2588
|
+
}
|
|
2589
|
+
entry.supersededBy = successorId || undefined;
|
|
2590
|
+
}
|
|
2524
2591
|
// Same one-way redaction as store(): a corrected response pasted with a fresh secret
|
|
2525
2592
|
// must not be the one write path that persists credentials.
|
|
2526
2593
|
let updateRedactions = 0;
|
|
@@ -3066,6 +3133,7 @@ class TheBrainV2 {
|
|
|
3066
3133
|
let downvoted = 0;
|
|
3067
3134
|
let unscoped = 0;
|
|
3068
3135
|
let untracked = 0;
|
|
3136
|
+
let withClearPaths = 0;
|
|
3069
3137
|
let oldest = '';
|
|
3070
3138
|
let totalTokensSaved = 0;
|
|
3071
3139
|
const savers = [];
|
|
@@ -3082,6 +3150,9 @@ class TheBrainV2 {
|
|
|
3082
3150
|
projects.add(entry.projectId);
|
|
3083
3151
|
if (trackedArtifactCount(entry) === 0)
|
|
3084
3152
|
untracked++;
|
|
3153
|
+
else if (entry.filePaths !== undefined || entry.symbols !== undefined ||
|
|
3154
|
+
(entry.claims || []).some((c) => c.filePaths !== undefined || c.symbols !== undefined))
|
|
3155
|
+
withClearPaths++;
|
|
3085
3156
|
if (entry.tokensSaved) {
|
|
3086
3157
|
totalTokensSaved += entry.tokensSaved;
|
|
3087
3158
|
savers.push({ id: entry.id, query: entry.query.slice(0, 80), tokensSaved: entry.tokensSaved, hits: entry.hits });
|
|
@@ -3102,6 +3173,7 @@ class TheBrainV2 {
|
|
|
3102
3173
|
base.projects = projects.size;
|
|
3103
3174
|
base.unscopedEntries = unscoped;
|
|
3104
3175
|
base.untrackedEntries = untracked;
|
|
3176
|
+
base.withClearPaths = withClearPaths;
|
|
3105
3177
|
base.tombstones = this.tombstones.size;
|
|
3106
3178
|
if (oldest)
|
|
3107
3179
|
base.oldestEntry = oldest;
|