@cleocode/cleo 2026.4.36 → 2026.4.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/brain.d.ts.map +1 -1
- package/dist/cli/commands/brain.js +60 -1
- package/dist/cli/commands/brain.js.map +1 -1
- package/dist/cli/commands/memory-brain.d.ts.map +1 -1
- package/dist/cli/commands/memory-brain.js +38 -0
- package/dist/cli/commands/memory-brain.js.map +1 -1
- package/dist/cli/commands/nexus.d.ts.map +1 -1
- package/dist/cli/commands/nexus.js +75 -2
- package/dist/cli/commands/nexus.js.map +1 -1
- package/dist/cli/index.js +884 -41
- package/dist/cli/index.js.map +4 -4
- package/dist/dispatch/domains/memory.d.ts.map +1 -1
- package/dist/dispatch/domains/memory.js +6 -1
- package/dist/dispatch/domains/memory.js.map +1 -1
- package/dist/dispatch/engines/memory-engine.d.ts +1 -1
- package/dist/dispatch/engines/memory-engine.d.ts.map +1 -1
- package/dist/dispatch/engines/memory-engine.js +1 -1
- package/dist/dispatch/engines/memory-engine.js.map +1 -1
- package/dist/dispatch/engines/orchestrate-engine.d.ts.map +1 -1
- package/dist/dispatch/engines/orchestrate-engine.js +50 -0
- package/dist/dispatch/engines/orchestrate-engine.js.map +1 -1
- package/dist/dispatch/lib/engine.d.ts +1 -1
- package/dist/dispatch/lib/engine.d.ts.map +1 -1
- package/dist/dispatch/lib/engine.js +1 -1
- package/dist/dispatch/lib/engine.js.map +1 -1
- package/dist/dispatch/registry.d.ts.map +1 -1
- package/dist/dispatch/registry.js +89 -0
- package/dist/dispatch/registry.js.map +1 -1
- package/dist/dispatch/types.d.ts +1 -1
- package/dist/dispatch/types.d.ts.map +1 -1
- package/dist/dispatch/types.js +1 -0
- package/dist/dispatch/types.js.map +1 -1
- package/package.json +8 -8
package/dist/cli/index.js
CHANGED
|
@@ -22109,6 +22109,210 @@ var init_quality_scoring = __esm({
|
|
|
22109
22109
|
}
|
|
22110
22110
|
});
|
|
22111
22111
|
|
|
22112
|
+
// packages/core/src/store/typed-query.ts
|
|
22113
|
+
function typedAll(stmt, ...params) {
|
|
22114
|
+
return stmt.all(...params);
|
|
22115
|
+
}
|
|
22116
|
+
function typedGet(stmt, ...params) {
|
|
22117
|
+
return stmt.get(...params);
|
|
22118
|
+
}
|
|
22119
|
+
var init_typed_query = __esm({
|
|
22120
|
+
"packages/core/src/store/typed-query.ts"() {
|
|
22121
|
+
"use strict";
|
|
22122
|
+
}
|
|
22123
|
+
});
|
|
22124
|
+
|
|
22125
|
+
// packages/core/src/memory/temporal-supersession.ts
|
|
22126
|
+
function extractKeywords(text3) {
|
|
22127
|
+
const words = text3.toLowerCase().replace(/[^a-z0-9\s\-_]/g, " ").split(/\s+/);
|
|
22128
|
+
const keywords = /* @__PURE__ */ new Set();
|
|
22129
|
+
for (const w2 of words) {
|
|
22130
|
+
if (w2.length >= 4 && !STOP_WORDS.has(w2)) {
|
|
22131
|
+
keywords.add(w2);
|
|
22132
|
+
}
|
|
22133
|
+
}
|
|
22134
|
+
return keywords;
|
|
22135
|
+
}
|
|
22136
|
+
function keywordSimilarity(textA, textB) {
|
|
22137
|
+
const kwA = extractKeywords(textA);
|
|
22138
|
+
const kwB = extractKeywords(textB);
|
|
22139
|
+
if (kwA.size === 0 || kwB.size === 0) return { similarity: 0, shared: [] };
|
|
22140
|
+
const shared = [];
|
|
22141
|
+
for (const w2 of kwA) {
|
|
22142
|
+
if (kwB.has(w2)) shared.push(w2);
|
|
22143
|
+
}
|
|
22144
|
+
if (shared.length < MIN_SHARED_KEYWORDS) return { similarity: 0, shared: [] };
|
|
22145
|
+
const union3 = kwA.size + kwB.size - shared.length;
|
|
22146
|
+
const similarity = union3 > 0 ? shared.length / union3 : 0;
|
|
22147
|
+
return { similarity, shared };
|
|
22148
|
+
}
|
|
22149
|
+
function buildNodeId(type, entryId) {
|
|
22150
|
+
return `${type}:${entryId}`;
|
|
22151
|
+
}
|
|
22152
|
+
async function locateEntry(projectRoot, entryId) {
|
|
22153
|
+
await getBrainDb(projectRoot);
|
|
22154
|
+
const nativeDb = getBrainNativeDb();
|
|
22155
|
+
if (!nativeDb) return null;
|
|
22156
|
+
for (const tc of SUPERSEDABLE_TABLES) {
|
|
22157
|
+
const row = typedGet(
|
|
22158
|
+
nativeDb.prepare(`SELECT id FROM ${tc.table} WHERE id = ? LIMIT 1`),
|
|
22159
|
+
entryId
|
|
22160
|
+
);
|
|
22161
|
+
if (row) {
|
|
22162
|
+
return { tableConfig: tc, nodeId: buildNodeId(tc.type, entryId) };
|
|
22163
|
+
}
|
|
22164
|
+
}
|
|
22165
|
+
return null;
|
|
22166
|
+
}
|
|
22167
|
+
async function supersedeMemory(projectRoot, oldId, newId, reason) {
|
|
22168
|
+
if (!oldId?.trim()) throw new Error("oldId is required");
|
|
22169
|
+
if (!newId?.trim()) throw new Error("newId is required");
|
|
22170
|
+
if (!reason?.trim()) throw new Error("reason is required");
|
|
22171
|
+
if (oldId === newId) throw new Error("oldId and newId must be different entries");
|
|
22172
|
+
await getBrainDb(projectRoot);
|
|
22173
|
+
const nativeDb = getBrainNativeDb();
|
|
22174
|
+
if (!nativeDb) throw new Error("brain.db is unavailable");
|
|
22175
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
22176
|
+
const oldLocation = await locateEntry(projectRoot, oldId);
|
|
22177
|
+
if (!oldLocation) throw new Error(`Entry not found: ${oldId}`);
|
|
22178
|
+
const newLocation = await locateEntry(projectRoot, newId);
|
|
22179
|
+
if (!newLocation) throw new Error(`Entry not found: ${newId}`);
|
|
22180
|
+
const { tableConfig: oldTc, nodeId: oldNodeId } = oldLocation;
|
|
22181
|
+
const { nodeId: newNodeId } = newLocation;
|
|
22182
|
+
try {
|
|
22183
|
+
nativeDb.prepare(
|
|
22184
|
+
`UPDATE ${oldTc.table} SET invalid_at = ?, updated_at = ? WHERE id = ? AND invalid_at IS NULL`
|
|
22185
|
+
).run(now2, now2, oldId);
|
|
22186
|
+
} catch {
|
|
22187
|
+
}
|
|
22188
|
+
const provenanceText = reason.substring(0, 500);
|
|
22189
|
+
try {
|
|
22190
|
+
nativeDb.prepare(
|
|
22191
|
+
`INSERT OR IGNORE INTO brain_page_edges
|
|
22192
|
+
(from_id, to_id, edge_type, weight, provenance, created_at)
|
|
22193
|
+
VALUES (?, ?, 'supersedes', 1.0, ?, ?)`
|
|
22194
|
+
).run(newNodeId, oldNodeId, provenanceText, now2);
|
|
22195
|
+
} catch (err) {
|
|
22196
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
22197
|
+
throw new Error(`Failed to create supersedes edge: ${message}`);
|
|
22198
|
+
}
|
|
22199
|
+
return {
|
|
22200
|
+
success: true,
|
|
22201
|
+
oldId,
|
|
22202
|
+
newId,
|
|
22203
|
+
edgeType: "supersedes"
|
|
22204
|
+
};
|
|
22205
|
+
}
|
|
22206
|
+
async function detectSupersession(projectRoot, newEntry) {
|
|
22207
|
+
try {
|
|
22208
|
+
await getBrainDb(projectRoot);
|
|
22209
|
+
const nativeDb = getBrainNativeDb();
|
|
22210
|
+
if (!nativeDb) return [];
|
|
22211
|
+
const newLocation = await locateEntry(projectRoot, newEntry.id);
|
|
22212
|
+
if (!newLocation) return [];
|
|
22213
|
+
const { tableConfig } = newLocation;
|
|
22214
|
+
const existing = typedAll(
|
|
22215
|
+
nativeDb.prepare(`
|
|
22216
|
+
SELECT id, COALESCE(${tableConfig.textCol}, '') AS text,
|
|
22217
|
+
created_at, quality_score
|
|
22218
|
+
FROM ${tableConfig.table}
|
|
22219
|
+
WHERE invalid_at IS NULL
|
|
22220
|
+
AND id != ?
|
|
22221
|
+
ORDER BY created_at DESC
|
|
22222
|
+
LIMIT 200
|
|
22223
|
+
`),
|
|
22224
|
+
newEntry.id
|
|
22225
|
+
);
|
|
22226
|
+
if (existing.length === 0) return [];
|
|
22227
|
+
const candidates = [];
|
|
22228
|
+
for (const row of existing) {
|
|
22229
|
+
if (row.created_at >= newEntry.createdAt) continue;
|
|
22230
|
+
const { similarity, shared } = keywordSimilarity(newEntry.text, row.text);
|
|
22231
|
+
if (similarity >= KEYWORD_OVERLAP_THRESHOLD) {
|
|
22232
|
+
candidates.push({
|
|
22233
|
+
existingId: row.id,
|
|
22234
|
+
similarity,
|
|
22235
|
+
table: tableConfig.table,
|
|
22236
|
+
sharedKeywords: shared.slice(0, 10)
|
|
22237
|
+
});
|
|
22238
|
+
}
|
|
22239
|
+
}
|
|
22240
|
+
candidates.sort((a, b2) => b2.similarity - a.similarity);
|
|
22241
|
+
return candidates;
|
|
22242
|
+
} catch (err) {
|
|
22243
|
+
console.warn("[temporal-supersession] detectSupersession failed:", err);
|
|
22244
|
+
return [];
|
|
22245
|
+
}
|
|
22246
|
+
}
|
|
22247
|
+
var KEYWORD_OVERLAP_THRESHOLD, MIN_SHARED_KEYWORDS, STOP_WORDS, SUPERSEDABLE_TABLES;
|
|
22248
|
+
var init_temporal_supersession = __esm({
|
|
22249
|
+
"packages/core/src/memory/temporal-supersession.ts"() {
|
|
22250
|
+
"use strict";
|
|
22251
|
+
init_brain_sqlite();
|
|
22252
|
+
init_typed_query();
|
|
22253
|
+
KEYWORD_OVERLAP_THRESHOLD = 0.8;
|
|
22254
|
+
MIN_SHARED_KEYWORDS = 3;
|
|
22255
|
+
STOP_WORDS = /* @__PURE__ */ new Set([
|
|
22256
|
+
"the",
|
|
22257
|
+
"a",
|
|
22258
|
+
"an",
|
|
22259
|
+
"is",
|
|
22260
|
+
"are",
|
|
22261
|
+
"was",
|
|
22262
|
+
"were",
|
|
22263
|
+
"be",
|
|
22264
|
+
"been",
|
|
22265
|
+
"being",
|
|
22266
|
+
"have",
|
|
22267
|
+
"has",
|
|
22268
|
+
"had",
|
|
22269
|
+
"do",
|
|
22270
|
+
"does",
|
|
22271
|
+
"did",
|
|
22272
|
+
"will",
|
|
22273
|
+
"would",
|
|
22274
|
+
"could",
|
|
22275
|
+
"should",
|
|
22276
|
+
"may",
|
|
22277
|
+
"might",
|
|
22278
|
+
"shall",
|
|
22279
|
+
"can",
|
|
22280
|
+
"to",
|
|
22281
|
+
"of",
|
|
22282
|
+
"in",
|
|
22283
|
+
"for",
|
|
22284
|
+
"on",
|
|
22285
|
+
"with",
|
|
22286
|
+
"at",
|
|
22287
|
+
"by",
|
|
22288
|
+
"from",
|
|
22289
|
+
"as",
|
|
22290
|
+
"into",
|
|
22291
|
+
"through",
|
|
22292
|
+
"and",
|
|
22293
|
+
"but",
|
|
22294
|
+
"or",
|
|
22295
|
+
"nor",
|
|
22296
|
+
"so",
|
|
22297
|
+
"yet",
|
|
22298
|
+
"this",
|
|
22299
|
+
"that",
|
|
22300
|
+
"these",
|
|
22301
|
+
"those",
|
|
22302
|
+
"it",
|
|
22303
|
+
"its",
|
|
22304
|
+
"not",
|
|
22305
|
+
"no"
|
|
22306
|
+
]);
|
|
22307
|
+
SUPERSEDABLE_TABLES = [
|
|
22308
|
+
{ table: "brain_decisions", textCol: "decision", type: "decision" },
|
|
22309
|
+
{ table: "brain_learnings", textCol: "insight", type: "learning" },
|
|
22310
|
+
{ table: "brain_patterns", textCol: "pattern", type: "pattern" },
|
|
22311
|
+
{ table: "brain_observations", textCol: "narrative", type: "observation" }
|
|
22312
|
+
];
|
|
22313
|
+
}
|
|
22314
|
+
});
|
|
22315
|
+
|
|
22112
22316
|
// packages/core/src/memory/patterns.ts
|
|
22113
22317
|
var patterns_exports = {};
|
|
22114
22318
|
__export(patterns_exports, {
|
|
@@ -22206,6 +22410,22 @@ async function storePattern(projectRoot, params) {
|
|
|
22206
22410
|
{ type: saved.type, impact: saved.impact ?? void 0 }
|
|
22207
22411
|
).catch(() => {
|
|
22208
22412
|
});
|
|
22413
|
+
detectSupersession(projectRoot, {
|
|
22414
|
+
id: saved.id,
|
|
22415
|
+
text: saved.pattern + " " + saved.context,
|
|
22416
|
+
createdAt: saved.extractedAt ?? (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19)
|
|
22417
|
+
}).then((candidates) => {
|
|
22418
|
+
for (const candidate of candidates) {
|
|
22419
|
+
supersedeMemory(
|
|
22420
|
+
projectRoot,
|
|
22421
|
+
candidate.existingId,
|
|
22422
|
+
saved.id,
|
|
22423
|
+
"auto:pattern-supersedes \u2014 high overlap detected at store time"
|
|
22424
|
+
).catch(() => {
|
|
22425
|
+
});
|
|
22426
|
+
}
|
|
22427
|
+
}).catch(() => {
|
|
22428
|
+
});
|
|
22209
22429
|
return {
|
|
22210
22430
|
...saved,
|
|
22211
22431
|
examples: JSON.parse(saved.examplesJson || "[]")
|
|
@@ -22262,6 +22482,7 @@ var init_patterns = __esm({
|
|
|
22262
22482
|
init_brain_accessor();
|
|
22263
22483
|
init_graph_auto_populate();
|
|
22264
22484
|
init_quality_scoring();
|
|
22485
|
+
init_temporal_supersession();
|
|
22265
22486
|
}
|
|
22266
22487
|
});
|
|
22267
22488
|
|
|
@@ -22353,6 +22574,22 @@ async function storeLearning(projectRoot, params) {
|
|
|
22353
22574
|
{ source: saved.source, confidence: saved.confidence, actionable: saved.actionable }
|
|
22354
22575
|
).catch(() => {
|
|
22355
22576
|
});
|
|
22577
|
+
detectSupersession(projectRoot, {
|
|
22578
|
+
id: saved.id,
|
|
22579
|
+
text: saved.insight,
|
|
22580
|
+
createdAt: saved.createdAt ?? (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19)
|
|
22581
|
+
}).then((candidates) => {
|
|
22582
|
+
for (const candidate of candidates) {
|
|
22583
|
+
supersedeMemory(
|
|
22584
|
+
projectRoot,
|
|
22585
|
+
candidate.existingId,
|
|
22586
|
+
saved.id,
|
|
22587
|
+
"auto:learning-supersedes \u2014 high overlap detected at store time"
|
|
22588
|
+
).catch(() => {
|
|
22589
|
+
});
|
|
22590
|
+
}
|
|
22591
|
+
}).catch(() => {
|
|
22592
|
+
});
|
|
22356
22593
|
return {
|
|
22357
22594
|
...saved,
|
|
22358
22595
|
applicableTypes: JSON.parse(saved.applicableTypesJson || "[]")
|
|
@@ -22413,6 +22650,7 @@ var init_learnings = __esm({
|
|
|
22413
22650
|
init_brain_accessor();
|
|
22414
22651
|
init_graph_auto_populate();
|
|
22415
22652
|
init_quality_scoring();
|
|
22653
|
+
init_temporal_supersession();
|
|
22416
22654
|
}
|
|
22417
22655
|
});
|
|
22418
22656
|
|
|
@@ -22451,16 +22689,6 @@ var init_mvi_helpers = __esm({
|
|
|
22451
22689
|
}
|
|
22452
22690
|
});
|
|
22453
22691
|
|
|
22454
|
-
// packages/core/src/store/typed-query.ts
|
|
22455
|
-
function typedAll(stmt, ...params) {
|
|
22456
|
-
return stmt.all(...params);
|
|
22457
|
-
}
|
|
22458
|
-
var init_typed_query = __esm({
|
|
22459
|
-
"packages/core/src/store/typed-query.ts"() {
|
|
22460
|
-
"use strict";
|
|
22461
|
-
}
|
|
22462
|
-
});
|
|
22463
|
-
|
|
22464
22692
|
// packages/core/src/memory/brain-similarity.ts
|
|
22465
22693
|
function parseIdPrefix(id) {
|
|
22466
22694
|
if (id.startsWith("D-") || /^D\d/.test(id)) return "decision";
|
|
@@ -24245,6 +24473,22 @@ async function storeDecision(projectRoot, params) {
|
|
|
24245
24473
|
}
|
|
24246
24474
|
} catch {
|
|
24247
24475
|
}
|
|
24476
|
+
detectSupersession(projectRoot, {
|
|
24477
|
+
id: saved.id,
|
|
24478
|
+
text: saved.decision + " " + saved.rationale,
|
|
24479
|
+
createdAt: saved.createdAt ?? (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19)
|
|
24480
|
+
}).then((candidates) => {
|
|
24481
|
+
for (const candidate of candidates) {
|
|
24482
|
+
supersedeMemory(
|
|
24483
|
+
projectRoot,
|
|
24484
|
+
candidate.existingId,
|
|
24485
|
+
saved.id,
|
|
24486
|
+
"auto:decision-supersedes \u2014 high overlap detected at store time"
|
|
24487
|
+
).catch(() => {
|
|
24488
|
+
});
|
|
24489
|
+
}
|
|
24490
|
+
}).catch(() => {
|
|
24491
|
+
});
|
|
24248
24492
|
return saved;
|
|
24249
24493
|
}
|
|
24250
24494
|
async function recallDecision(projectRoot, id) {
|
|
@@ -24297,6 +24541,7 @@ var init_decisions2 = __esm({
|
|
|
24297
24541
|
init_sqlite2();
|
|
24298
24542
|
init_graph_auto_populate();
|
|
24299
24543
|
init_quality_scoring();
|
|
24544
|
+
init_temporal_supersession();
|
|
24300
24545
|
}
|
|
24301
24546
|
});
|
|
24302
24547
|
|
|
@@ -45205,7 +45450,9 @@ async function extractFromTranscript(options) {
|
|
|
45205
45450
|
const maxTranscriptChars = llmCfg?.maxTranscriptChars ?? 6e4;
|
|
45206
45451
|
const client = options.client ?? await buildAnthropicClient();
|
|
45207
45452
|
if (!client) {
|
|
45208
|
-
report.warnings.push(
|
|
45453
|
+
report.warnings.push(
|
|
45454
|
+
"No Anthropic API key found (checked ANTHROPIC_API_KEY env and ~/.claude/.credentials.json) \u2014 extraction skipped"
|
|
45455
|
+
);
|
|
45209
45456
|
return report;
|
|
45210
45457
|
}
|
|
45211
45458
|
const clipped = clipTranscript(transcript, maxTranscriptChars);
|
|
@@ -45367,11 +45614,11 @@ var brain_consolidator_exports = {};
|
|
|
45367
45614
|
__export(brain_consolidator_exports, {
|
|
45368
45615
|
detectContradictions: () => detectContradictions
|
|
45369
45616
|
});
|
|
45370
|
-
function
|
|
45617
|
+
function extractKeywords2(text3) {
|
|
45371
45618
|
const words = text3.toLowerCase().replace(/[^a-z0-9\s\-_]/g, " ").split(/\s+/);
|
|
45372
45619
|
const keywords = /* @__PURE__ */ new Set();
|
|
45373
45620
|
for (const w2 of words) {
|
|
45374
|
-
if (w2.length >= 4 && !
|
|
45621
|
+
if (w2.length >= 4 && !STOP_WORDS2.has(w2)) {
|
|
45375
45622
|
keywords.add(w2);
|
|
45376
45623
|
}
|
|
45377
45624
|
}
|
|
@@ -45420,7 +45667,7 @@ async function detectContradictions(projectRoot) {
|
|
|
45420
45667
|
const keywordMap = /* @__PURE__ */ new Map();
|
|
45421
45668
|
const negationMap = /* @__PURE__ */ new Map();
|
|
45422
45669
|
for (const entry of entries) {
|
|
45423
|
-
keywordMap.set(entry.id,
|
|
45670
|
+
keywordMap.set(entry.id, extractKeywords2(entry.text));
|
|
45424
45671
|
negationMap.set(entry.id, findNegationMarkers(entry.text));
|
|
45425
45672
|
}
|
|
45426
45673
|
for (let i = 0; i < entries.length; i++) {
|
|
@@ -45434,7 +45681,7 @@ async function detectContradictions(projectRoot) {
|
|
|
45434
45681
|
const keywordsB = keywordMap.get(entryB.id);
|
|
45435
45682
|
const negationsB = negationMap.get(entryB.id);
|
|
45436
45683
|
const shared = keywordIntersection(keywordsA, keywordsB);
|
|
45437
|
-
if (shared.length <
|
|
45684
|
+
if (shared.length < MIN_SHARED_KEYWORDS2) continue;
|
|
45438
45685
|
const negationsOnlyInA = negationsA.filter((m2) => !negationsB.includes(m2));
|
|
45439
45686
|
const negationsOnlyInB = negationsB.filter((m2) => !negationsA.includes(m2));
|
|
45440
45687
|
const negationFlip = negationsOnlyInA.length > 0 || negationsOnlyInB.length > 0;
|
|
@@ -45452,8 +45699,8 @@ async function detectContradictions(projectRoot) {
|
|
|
45452
45699
|
sharedKeywords: shared.slice(0, 10),
|
|
45453
45700
|
negationMarkers: negMarkers.slice(0, 5)
|
|
45454
45701
|
});
|
|
45455
|
-
const nodeA =
|
|
45456
|
-
const nodeB =
|
|
45702
|
+
const nodeA = buildNodeId2(table, entryA.id);
|
|
45703
|
+
const nodeB = buildNodeId2(table, entryB.id);
|
|
45457
45704
|
try {
|
|
45458
45705
|
nativeDb.prepare(`
|
|
45459
45706
|
INSERT OR IGNORE INTO brain_page_edges
|
|
@@ -45482,7 +45729,7 @@ async function detectContradictions(projectRoot) {
|
|
|
45482
45729
|
}
|
|
45483
45730
|
return results;
|
|
45484
45731
|
}
|
|
45485
|
-
function
|
|
45732
|
+
function buildNodeId2(table, entryId) {
|
|
45486
45733
|
const typeMap = {
|
|
45487
45734
|
brain_observations: "observation",
|
|
45488
45735
|
brain_learnings: "learning",
|
|
@@ -45492,13 +45739,13 @@ function buildNodeId(table, entryId) {
|
|
|
45492
45739
|
const type = typeMap[table] ?? "entry";
|
|
45493
45740
|
return `${type}:${entryId}`;
|
|
45494
45741
|
}
|
|
45495
|
-
var
|
|
45742
|
+
var MIN_SHARED_KEYWORDS2, NEGATION_MARKERS, STOP_WORDS2;
|
|
45496
45743
|
var init_brain_consolidator = __esm({
|
|
45497
45744
|
"packages/core/src/memory/brain-consolidator.ts"() {
|
|
45498
45745
|
"use strict";
|
|
45499
45746
|
init_brain_sqlite();
|
|
45500
45747
|
init_typed_query();
|
|
45501
|
-
|
|
45748
|
+
MIN_SHARED_KEYWORDS2 = 3;
|
|
45502
45749
|
NEGATION_MARKERS = [
|
|
45503
45750
|
"not",
|
|
45504
45751
|
"never",
|
|
@@ -45519,7 +45766,7 @@ var init_brain_consolidator = __esm({
|
|
|
45519
45766
|
"undone",
|
|
45520
45767
|
"superseded"
|
|
45521
45768
|
];
|
|
45522
|
-
|
|
45769
|
+
STOP_WORDS2 = /* @__PURE__ */ new Set([
|
|
45523
45770
|
"the",
|
|
45524
45771
|
"a",
|
|
45525
45772
|
"an",
|
|
@@ -45607,11 +45854,11 @@ async function applyTemporalDecay(projectRoot, options) {
|
|
|
45607
45854
|
tablesProcessed: ["brain_learnings"]
|
|
45608
45855
|
};
|
|
45609
45856
|
}
|
|
45610
|
-
function
|
|
45857
|
+
function extractKeywords3(text3) {
|
|
45611
45858
|
const words = text3.toLowerCase().replace(/[^a-z0-9\s-]/g, "").split(/\s+/);
|
|
45612
45859
|
const keywords = /* @__PURE__ */ new Set();
|
|
45613
45860
|
for (const w2 of words) {
|
|
45614
|
-
if (w2.length >= 4 && !
|
|
45861
|
+
if (w2.length >= 4 && !STOP_WORDS3.has(w2)) {
|
|
45615
45862
|
keywords.add(w2);
|
|
45616
45863
|
}
|
|
45617
45864
|
}
|
|
@@ -45649,7 +45896,7 @@ async function consolidateMemories(projectRoot, options) {
|
|
|
45649
45896
|
}
|
|
45650
45897
|
const entries = oldObservations.map((obs) => ({
|
|
45651
45898
|
...obs,
|
|
45652
|
-
keywords:
|
|
45899
|
+
keywords: extractKeywords3(`${obs.title} ${obs.narrative ?? ""}`),
|
|
45653
45900
|
clustered: false
|
|
45654
45901
|
}));
|
|
45655
45902
|
const clusters = [];
|
|
@@ -46051,13 +46298,13 @@ async function strengthenCoRetrievedEdges(projectRoot) {
|
|
|
46051
46298
|
}
|
|
46052
46299
|
return strengthened;
|
|
46053
46300
|
}
|
|
46054
|
-
var
|
|
46301
|
+
var STOP_WORDS3;
|
|
46055
46302
|
var init_brain_lifecycle = __esm({
|
|
46056
46303
|
"packages/core/src/memory/brain-lifecycle.ts"() {
|
|
46057
46304
|
"use strict";
|
|
46058
46305
|
init_brain_accessor();
|
|
46059
46306
|
init_typed_query();
|
|
46060
|
-
|
|
46307
|
+
STOP_WORDS3 = /* @__PURE__ */ new Set([
|
|
46061
46308
|
"the",
|
|
46062
46309
|
"a",
|
|
46063
46310
|
"an",
|
|
@@ -46662,6 +46909,358 @@ var init_session_hooks = __esm({
|
|
|
46662
46909
|
}
|
|
46663
46910
|
});
|
|
46664
46911
|
|
|
46912
|
+
// packages/core/src/memory/quality-feedback.ts
|
|
46913
|
+
var quality_feedback_exports = {};
|
|
46914
|
+
__export(quality_feedback_exports, {
|
|
46915
|
+
correlateOutcomes: () => correlateOutcomes,
|
|
46916
|
+
getMemoryQualityReport: () => getMemoryQualityReport,
|
|
46917
|
+
trackMemoryUsage: () => trackMemoryUsage
|
|
46918
|
+
});
|
|
46919
|
+
async function ensureUsageLogTable(projectRoot) {
|
|
46920
|
+
const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
|
|
46921
|
+
await getBrainDb2(projectRoot);
|
|
46922
|
+
const nativeDb = getBrainNativeDb2();
|
|
46923
|
+
if (!nativeDb) return;
|
|
46924
|
+
try {
|
|
46925
|
+
nativeDb.prepare(
|
|
46926
|
+
`CREATE TABLE IF NOT EXISTS brain_usage_log (
|
|
46927
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
46928
|
+
entry_id TEXT NOT NULL,
|
|
46929
|
+
task_id TEXT,
|
|
46930
|
+
used INTEGER NOT NULL DEFAULT 0,
|
|
46931
|
+
outcome TEXT NOT NULL DEFAULT 'unknown',
|
|
46932
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
46933
|
+
)`
|
|
46934
|
+
).run();
|
|
46935
|
+
nativeDb.prepare(
|
|
46936
|
+
`CREATE INDEX IF NOT EXISTS idx_brain_usage_log_entry_id
|
|
46937
|
+
ON brain_usage_log(entry_id)`
|
|
46938
|
+
).run();
|
|
46939
|
+
nativeDb.prepare(
|
|
46940
|
+
`CREATE INDEX IF NOT EXISTS idx_brain_usage_log_task_id
|
|
46941
|
+
ON brain_usage_log(task_id)`
|
|
46942
|
+
).run();
|
|
46943
|
+
} catch {
|
|
46944
|
+
}
|
|
46945
|
+
}
|
|
46946
|
+
async function ensurePruneCandidateColumn(projectRoot) {
|
|
46947
|
+
const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
|
|
46948
|
+
await getBrainDb2(projectRoot);
|
|
46949
|
+
const nativeDb = getBrainNativeDb2();
|
|
46950
|
+
if (!nativeDb) return;
|
|
46951
|
+
const tables = [
|
|
46952
|
+
"brain_decisions",
|
|
46953
|
+
"brain_patterns",
|
|
46954
|
+
"brain_learnings",
|
|
46955
|
+
"brain_observations"
|
|
46956
|
+
];
|
|
46957
|
+
for (const tbl of tables) {
|
|
46958
|
+
try {
|
|
46959
|
+
nativeDb.prepare(`ALTER TABLE ${tbl} ADD COLUMN prune_candidate INTEGER DEFAULT 0`).run();
|
|
46960
|
+
} catch {
|
|
46961
|
+
}
|
|
46962
|
+
}
|
|
46963
|
+
}
|
|
46964
|
+
async function trackMemoryUsage(projectRoot, memoryId, used, taskId, outcome = "unknown") {
|
|
46965
|
+
if (!memoryId?.trim()) return;
|
|
46966
|
+
await ensureUsageLogTable(projectRoot);
|
|
46967
|
+
const { getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
|
|
46968
|
+
const nativeDb = getBrainNativeDb2();
|
|
46969
|
+
if (!nativeDb) return;
|
|
46970
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
46971
|
+
try {
|
|
46972
|
+
nativeDb.prepare(
|
|
46973
|
+
`INSERT INTO brain_usage_log (entry_id, task_id, used, outcome, created_at)
|
|
46974
|
+
VALUES (?, ?, ?, ?, ?)`
|
|
46975
|
+
).run(memoryId, taskId ?? null, used ? 1 : 0, outcome, now2);
|
|
46976
|
+
} catch {
|
|
46977
|
+
}
|
|
46978
|
+
}
|
|
46979
|
+
function tableForId(id) {
|
|
46980
|
+
if (id.startsWith("D-") || /^D\d/.test(id)) return "brain_decisions";
|
|
46981
|
+
if (id.startsWith("P-") || /^P\d/.test(id)) return "brain_patterns";
|
|
46982
|
+
if (id.startsWith("L-") || /^L\d/.test(id)) return "brain_learnings";
|
|
46983
|
+
if (id.startsWith("O-") || id.startsWith("CM-") || /^O/.test(id)) return "brain_observations";
|
|
46984
|
+
return null;
|
|
46985
|
+
}
|
|
46986
|
+
function applyQualityDelta(nativeDb, table, id, delta, now2) {
|
|
46987
|
+
if (!nativeDb) return;
|
|
46988
|
+
try {
|
|
46989
|
+
nativeDb.prepare(
|
|
46990
|
+
`UPDATE ${table}
|
|
46991
|
+
SET quality_score = MAX(0.0, MIN(1.0, COALESCE(quality_score, 0.5) + ?)),
|
|
46992
|
+
updated_at = ?
|
|
46993
|
+
WHERE id = ?`
|
|
46994
|
+
).run(delta, now2, id);
|
|
46995
|
+
} catch {
|
|
46996
|
+
}
|
|
46997
|
+
}
|
|
46998
|
+
async function correlateOutcomes(projectRoot) {
|
|
46999
|
+
await ensureUsageLogTable(projectRoot);
|
|
47000
|
+
await ensurePruneCandidateColumn(projectRoot);
|
|
47001
|
+
const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
|
|
47002
|
+
await getBrainDb2(projectRoot);
|
|
47003
|
+
const nativeDb = getBrainNativeDb2();
|
|
47004
|
+
const ranAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47005
|
+
if (!nativeDb) {
|
|
47006
|
+
return { boosted: 0, penalized: 0, flaggedForPruning: 0, ranAt };
|
|
47007
|
+
}
|
|
47008
|
+
const now2 = ranAt.replace("T", " ").slice(0, 19);
|
|
47009
|
+
let boosted = 0;
|
|
47010
|
+
let penalized = 0;
|
|
47011
|
+
let usageRows = [];
|
|
47012
|
+
try {
|
|
47013
|
+
usageRows = typedAll(
|
|
47014
|
+
nativeDb.prepare(
|
|
47015
|
+
`SELECT entry_id, outcome, SUM(used) AS used_count
|
|
47016
|
+
FROM brain_usage_log
|
|
47017
|
+
WHERE outcome IN ('success', 'failure')
|
|
47018
|
+
GROUP BY entry_id, outcome`
|
|
47019
|
+
)
|
|
47020
|
+
);
|
|
47021
|
+
} catch {
|
|
47022
|
+
usageRows = [];
|
|
47023
|
+
}
|
|
47024
|
+
for (const row of usageRows) {
|
|
47025
|
+
const table = tableForId(row.entry_id);
|
|
47026
|
+
if (!table) continue;
|
|
47027
|
+
if (row.outcome === "success" && row.used_count > 0) {
|
|
47028
|
+
applyQualityDelta(nativeDb, table, row.entry_id, 0.05, now2);
|
|
47029
|
+
boosted++;
|
|
47030
|
+
} else if (row.outcome === "failure" && row.used_count > 0) {
|
|
47031
|
+
applyQualityDelta(nativeDb, table, row.entry_id, -0.05, now2);
|
|
47032
|
+
penalized++;
|
|
47033
|
+
}
|
|
47034
|
+
}
|
|
47035
|
+
const cutoffDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3).toISOString().replace("T", " ").slice(0, 19);
|
|
47036
|
+
let flaggedForPruning = 0;
|
|
47037
|
+
const pruneTargetTables = [
|
|
47038
|
+
{ table: "brain_decisions", dateCol: "created_at" },
|
|
47039
|
+
{ table: "brain_patterns", dateCol: "extracted_at" },
|
|
47040
|
+
{ table: "brain_learnings", dateCol: "created_at" },
|
|
47041
|
+
{ table: "brain_observations", dateCol: "created_at" }
|
|
47042
|
+
];
|
|
47043
|
+
for (const { table, dateCol } of pruneTargetTables) {
|
|
47044
|
+
try {
|
|
47045
|
+
const result = nativeDb.prepare(
|
|
47046
|
+
`UPDATE ${table}
|
|
47047
|
+
SET prune_candidate = 1
|
|
47048
|
+
WHERE COALESCE(citation_count, 0) = 0
|
|
47049
|
+
AND ${dateCol} < ?`
|
|
47050
|
+
).run(cutoffDate);
|
|
47051
|
+
flaggedForPruning += result.changes ?? 0;
|
|
47052
|
+
} catch {
|
|
47053
|
+
}
|
|
47054
|
+
}
|
|
47055
|
+
return { boosted, penalized, flaggedForPruning, ranAt };
|
|
47056
|
+
}
|
|
47057
|
+
async function getMemoryQualityReport(projectRoot) {
|
|
47058
|
+
await ensureUsageLogTable(projectRoot);
|
|
47059
|
+
const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
|
|
47060
|
+
await getBrainDb2(projectRoot);
|
|
47061
|
+
const nativeDb = getBrainNativeDb2();
|
|
47062
|
+
const emptyReport = {
|
|
47063
|
+
totalRetrievals: 0,
|
|
47064
|
+
uniqueEntriesRetrieved: 0,
|
|
47065
|
+
usageRate: 0,
|
|
47066
|
+
topRetrieved: [],
|
|
47067
|
+
neverRetrieved: [],
|
|
47068
|
+
qualityDistribution: { low: 0, medium: 0, high: 0 },
|
|
47069
|
+
tierDistribution: { short: 0, medium: 0, long: 0, unknown: 0 },
|
|
47070
|
+
noiseRatio: 0
|
|
47071
|
+
};
|
|
47072
|
+
if (!nativeDb) return emptyReport;
|
|
47073
|
+
let totalRetrievals = 0;
|
|
47074
|
+
let uniqueEntriesRetrieved = 0;
|
|
47075
|
+
try {
|
|
47076
|
+
const logCount = typedAll(
|
|
47077
|
+
nativeDb.prepare("SELECT COUNT(*) AS cnt FROM brain_retrieval_log")
|
|
47078
|
+
);
|
|
47079
|
+
totalRetrievals = logCount[0]?.cnt ?? 0;
|
|
47080
|
+
const uniqueCount = typedAll(
|
|
47081
|
+
nativeDb.prepare(
|
|
47082
|
+
`SELECT COUNT(DISTINCT value) AS cnt
|
|
47083
|
+
FROM brain_retrieval_log,
|
|
47084
|
+
json_each('["' || replace(entry_ids, ',', '","') || '"]')`
|
|
47085
|
+
)
|
|
47086
|
+
);
|
|
47087
|
+
uniqueEntriesRetrieved = uniqueCount[0]?.cnt ?? 0;
|
|
47088
|
+
} catch {
|
|
47089
|
+
}
|
|
47090
|
+
let usageRate = 0;
|
|
47091
|
+
try {
|
|
47092
|
+
const totalUsage = typedAll(
|
|
47093
|
+
nativeDb.prepare("SELECT COUNT(*) AS cnt FROM brain_usage_log")
|
|
47094
|
+
);
|
|
47095
|
+
const usedCount = typedAll(
|
|
47096
|
+
nativeDb.prepare("SELECT COUNT(*) AS cnt FROM brain_usage_log WHERE used = 1")
|
|
47097
|
+
);
|
|
47098
|
+
const total = totalUsage[0]?.cnt ?? 0;
|
|
47099
|
+
const used = usedCount[0]?.cnt ?? 0;
|
|
47100
|
+
usageRate = total > 0 ? used / total : 0;
|
|
47101
|
+
} catch {
|
|
47102
|
+
}
|
|
47103
|
+
const topRetrieved = [];
|
|
47104
|
+
try {
|
|
47105
|
+
const rows = typedAll(
|
|
47106
|
+
nativeDb.prepare(
|
|
47107
|
+
`SELECT id,
|
|
47108
|
+
'decision' AS type,
|
|
47109
|
+
decision AS title,
|
|
47110
|
+
COALESCE(citation_count, 0) AS citation_count
|
|
47111
|
+
FROM brain_decisions
|
|
47112
|
+
UNION ALL
|
|
47113
|
+
SELECT id,
|
|
47114
|
+
'pattern' AS type,
|
|
47115
|
+
pattern AS title,
|
|
47116
|
+
COALESCE(citation_count, 0) AS citation_count
|
|
47117
|
+
FROM brain_patterns
|
|
47118
|
+
UNION ALL
|
|
47119
|
+
SELECT id,
|
|
47120
|
+
'learning' AS type,
|
|
47121
|
+
insight AS title,
|
|
47122
|
+
COALESCE(citation_count, 0) AS citation_count
|
|
47123
|
+
FROM brain_learnings
|
|
47124
|
+
UNION ALL
|
|
47125
|
+
SELECT id,
|
|
47126
|
+
'observation' AS type,
|
|
47127
|
+
title AS title,
|
|
47128
|
+
COALESCE(citation_count, 0) AS citation_count
|
|
47129
|
+
FROM brain_observations
|
|
47130
|
+
ORDER BY citation_count DESC
|
|
47131
|
+
LIMIT 10`
|
|
47132
|
+
)
|
|
47133
|
+
);
|
|
47134
|
+
for (const r of rows) {
|
|
47135
|
+
topRetrieved.push({
|
|
47136
|
+
id: r.id,
|
|
47137
|
+
type: r.type,
|
|
47138
|
+
title: String(r.title ?? "").slice(0, 120),
|
|
47139
|
+
citationCount: r.citation_count
|
|
47140
|
+
});
|
|
47141
|
+
}
|
|
47142
|
+
} catch {
|
|
47143
|
+
}
|
|
47144
|
+
const neverRetrieved = [];
|
|
47145
|
+
try {
|
|
47146
|
+
const rows = typedAll(
|
|
47147
|
+
nativeDb.prepare(
|
|
47148
|
+
`SELECT id,
|
|
47149
|
+
'decision' AS type,
|
|
47150
|
+
decision AS title,
|
|
47151
|
+
COALESCE(quality_score, 0.5) AS quality_score
|
|
47152
|
+
FROM brain_decisions
|
|
47153
|
+
WHERE COALESCE(citation_count, 0) = 0
|
|
47154
|
+
UNION ALL
|
|
47155
|
+
SELECT id,
|
|
47156
|
+
'pattern' AS type,
|
|
47157
|
+
pattern AS title,
|
|
47158
|
+
COALESCE(quality_score, 0.5) AS quality_score
|
|
47159
|
+
FROM brain_patterns
|
|
47160
|
+
WHERE COALESCE(citation_count, 0) = 0
|
|
47161
|
+
UNION ALL
|
|
47162
|
+
SELECT id,
|
|
47163
|
+
'learning' AS type,
|
|
47164
|
+
insight AS title,
|
|
47165
|
+
COALESCE(quality_score, 0.5) AS quality_score
|
|
47166
|
+
FROM brain_learnings
|
|
47167
|
+
WHERE COALESCE(citation_count, 0) = 0
|
|
47168
|
+
UNION ALL
|
|
47169
|
+
SELECT id,
|
|
47170
|
+
'observation' AS type,
|
|
47171
|
+
title AS title,
|
|
47172
|
+
COALESCE(quality_score, 0.5) AS quality_score
|
|
47173
|
+
FROM brain_observations
|
|
47174
|
+
WHERE COALESCE(citation_count, 0) = 0
|
|
47175
|
+
ORDER BY quality_score ASC
|
|
47176
|
+
LIMIT 10`
|
|
47177
|
+
)
|
|
47178
|
+
);
|
|
47179
|
+
for (const r of rows) {
|
|
47180
|
+
neverRetrieved.push({
|
|
47181
|
+
id: r.id,
|
|
47182
|
+
type: r.type,
|
|
47183
|
+
title: String(r.title ?? "").slice(0, 120),
|
|
47184
|
+
qualityScore: r.quality_score
|
|
47185
|
+
});
|
|
47186
|
+
}
|
|
47187
|
+
} catch {
|
|
47188
|
+
}
|
|
47189
|
+
let qualityDistribution = { low: 0, medium: 0, high: 0 };
|
|
47190
|
+
try {
|
|
47191
|
+
const rows = typedAll(
|
|
47192
|
+
nativeDb.prepare(
|
|
47193
|
+
`SELECT
|
|
47194
|
+
SUM(CASE WHEN qs < 0.3 THEN 1 ELSE 0 END) AS low,
|
|
47195
|
+
SUM(CASE WHEN qs >= 0.3 AND qs <= 0.6 THEN 1 ELSE 0 END) AS medium,
|
|
47196
|
+
SUM(CASE WHEN qs > 0.6 THEN 1 ELSE 0 END) AS high
|
|
47197
|
+
FROM (
|
|
47198
|
+
SELECT COALESCE(quality_score, 0.5) AS qs FROM brain_decisions
|
|
47199
|
+
UNION ALL
|
|
47200
|
+
SELECT COALESCE(quality_score, 0.5) AS qs FROM brain_patterns
|
|
47201
|
+
UNION ALL
|
|
47202
|
+
SELECT COALESCE(quality_score, 0.5) AS qs FROM brain_learnings
|
|
47203
|
+
UNION ALL
|
|
47204
|
+
SELECT COALESCE(quality_score, 0.5) AS qs FROM brain_observations
|
|
47205
|
+
)`
|
|
47206
|
+
)
|
|
47207
|
+
);
|
|
47208
|
+
if (rows[0]) {
|
|
47209
|
+
qualityDistribution = {
|
|
47210
|
+
low: rows[0].low ?? 0,
|
|
47211
|
+
medium: rows[0].medium ?? 0,
|
|
47212
|
+
high: rows[0].high ?? 0
|
|
47213
|
+
};
|
|
47214
|
+
}
|
|
47215
|
+
} catch {
|
|
47216
|
+
}
|
|
47217
|
+
const tierDistribution = { short: 0, medium: 0, long: 0, unknown: 0 };
|
|
47218
|
+
try {
|
|
47219
|
+
const rows = typedAll(
|
|
47220
|
+
nativeDb.prepare(
|
|
47221
|
+
`SELECT memory_tier AS tier, COUNT(*) AS cnt
|
|
47222
|
+
FROM (
|
|
47223
|
+
SELECT memory_tier FROM brain_decisions
|
|
47224
|
+
UNION ALL
|
|
47225
|
+
SELECT memory_tier FROM brain_patterns
|
|
47226
|
+
UNION ALL
|
|
47227
|
+
SELECT memory_tier FROM brain_learnings
|
|
47228
|
+
UNION ALL
|
|
47229
|
+
SELECT memory_tier FROM brain_observations
|
|
47230
|
+
)
|
|
47231
|
+
GROUP BY memory_tier`
|
|
47232
|
+
)
|
|
47233
|
+
);
|
|
47234
|
+
for (const r of rows) {
|
|
47235
|
+
const tier = r.tier?.toLowerCase() ?? "unknown";
|
|
47236
|
+
if (tier === "short" || tier === "medium" || tier === "long") {
|
|
47237
|
+
tierDistribution[tier] += r.cnt;
|
|
47238
|
+
} else {
|
|
47239
|
+
tierDistribution.unknown += r.cnt;
|
|
47240
|
+
}
|
|
47241
|
+
}
|
|
47242
|
+
} catch {
|
|
47243
|
+
}
|
|
47244
|
+
const totalEntries = qualityDistribution.low + qualityDistribution.medium + qualityDistribution.high;
|
|
47245
|
+
const noiseRatio = totalEntries > 0 ? qualityDistribution.low / totalEntries : 0;
|
|
47246
|
+
return {
|
|
47247
|
+
totalRetrievals,
|
|
47248
|
+
uniqueEntriesRetrieved,
|
|
47249
|
+
usageRate,
|
|
47250
|
+
topRetrieved,
|
|
47251
|
+
neverRetrieved,
|
|
47252
|
+
qualityDistribution,
|
|
47253
|
+
tierDistribution,
|
|
47254
|
+
noiseRatio
|
|
47255
|
+
};
|
|
47256
|
+
}
|
|
47257
|
+
var init_quality_feedback = __esm({
|
|
47258
|
+
"packages/core/src/memory/quality-feedback.ts"() {
|
|
47259
|
+
"use strict";
|
|
47260
|
+
init_typed_query();
|
|
47261
|
+
}
|
|
47262
|
+
});
|
|
47263
|
+
|
|
46665
47264
|
// packages/core/src/hooks/handlers/task-hooks.ts
|
|
46666
47265
|
async function handleToolStart(projectRoot, payload) {
|
|
46667
47266
|
const { observeBrain: observeBrain2 } = await Promise.resolve().then(() => (init_brain_retrieval(), brain_retrieval_exports));
|
|
@@ -46695,6 +47294,13 @@ async function handleToolComplete(projectRoot, payload) {
|
|
|
46695
47294
|
} catch {
|
|
46696
47295
|
}
|
|
46697
47296
|
});
|
|
47297
|
+
setImmediate(async () => {
|
|
47298
|
+
try {
|
|
47299
|
+
const { correlateOutcomes: correlateOutcomes2 } = await Promise.resolve().then(() => (init_quality_feedback(), quality_feedback_exports));
|
|
47300
|
+
await correlateOutcomes2(projectRoot);
|
|
47301
|
+
} catch {
|
|
47302
|
+
}
|
|
47303
|
+
});
|
|
46698
47304
|
await maybeRefreshMemoryBridge(projectRoot);
|
|
46699
47305
|
}
|
|
46700
47306
|
var init_task_hooks = __esm({
|
|
@@ -53192,7 +53798,7 @@ function generateRecommendation2(changeType, affectedCount, cascadeDepth, taskId
|
|
|
53192
53798
|
}
|
|
53193
53799
|
}
|
|
53194
53800
|
function scoreTaskMatch(change, task) {
|
|
53195
|
-
const
|
|
53801
|
+
const STOP_WORDS5 = /* @__PURE__ */ new Set([
|
|
53196
53802
|
"a",
|
|
53197
53803
|
"an",
|
|
53198
53804
|
"the",
|
|
@@ -53214,7 +53820,7 @@ function scoreTaskMatch(change, task) {
|
|
|
53214
53820
|
"do",
|
|
53215
53821
|
"not"
|
|
53216
53822
|
]);
|
|
53217
|
-
const tokenise = (text3) => text3.toLowerCase().split(/\W+/).filter((t) => t.length > 2 && !
|
|
53823
|
+
const tokenise = (text3) => text3.toLowerCase().split(/\W+/).filter((t) => t.length > 2 && !STOP_WORDS5.has(t));
|
|
53218
53824
|
const changeTokens = new Set(tokenise(change));
|
|
53219
53825
|
if (changeTokens.size === 0) return 0;
|
|
53220
53826
|
const taskText = `${task.title ?? ""} ${task.description ?? ""}`;
|
|
@@ -59664,6 +60270,7 @@ __export(memory_exports, {
|
|
|
59664
60270
|
bulkLink: () => bulkLink,
|
|
59665
60271
|
compactManifest: () => compactManifest,
|
|
59666
60272
|
consolidateMemories: () => consolidateMemories,
|
|
60273
|
+
correlateOutcomes: () => correlateOutcomes,
|
|
59667
60274
|
detectContradictions: () => detectContradictions,
|
|
59668
60275
|
ensureFts5Tables: () => ensureFts5Tables,
|
|
59669
60276
|
fetchBrainEntries: () => fetchBrainEntries,
|
|
@@ -59674,6 +60281,7 @@ __export(memory_exports, {
|
|
|
59674
60281
|
getLinkedLearnings: () => getLinkedLearnings,
|
|
59675
60282
|
getLinkedPatterns: () => getLinkedPatterns,
|
|
59676
60283
|
getMemoryLinks: () => getMemoryLinks,
|
|
60284
|
+
getMemoryQualityReport: () => getMemoryQualityReport,
|
|
59677
60285
|
getTaskLinks: () => getTaskLinks,
|
|
59678
60286
|
hybridSearch: () => hybridSearch,
|
|
59679
60287
|
learningStats: () => learningStats,
|
|
@@ -59715,6 +60323,7 @@ __export(memory_exports, {
|
|
|
59715
60323
|
storePattern: () => storePattern,
|
|
59716
60324
|
storeVerifiedCandidate: () => storeVerifiedCandidate,
|
|
59717
60325
|
timelineBrain: () => timelineBrain,
|
|
60326
|
+
trackMemoryUsage: () => trackMemoryUsage,
|
|
59718
60327
|
unlinkMemoryFromTask: () => unlinkMemoryFromTask,
|
|
59719
60328
|
updateDecisionOutcome: () => updateDecisionOutcome,
|
|
59720
60329
|
updateResearch: () => updateResearch,
|
|
@@ -60337,6 +60946,7 @@ var init_memory = __esm({
|
|
|
60337
60946
|
init_extraction_gate();
|
|
60338
60947
|
init_learnings();
|
|
60339
60948
|
init_patterns();
|
|
60949
|
+
init_quality_feedback();
|
|
60340
60950
|
}
|
|
60341
60951
|
});
|
|
60342
60952
|
|
|
@@ -64051,8 +64661,8 @@ var init_deps = __esm({
|
|
|
64051
64661
|
});
|
|
64052
64662
|
|
|
64053
64663
|
// packages/core/src/nexus/discover.ts
|
|
64054
|
-
function
|
|
64055
|
-
return text3.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/\s+/).filter((w2) => w2.length > 2 && !
|
|
64664
|
+
function extractKeywords4(text3) {
|
|
64665
|
+
return text3.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/\s+/).filter((w2) => w2.length > 2 && !STOP_WORDS4.has(w2));
|
|
64056
64666
|
}
|
|
64057
64667
|
async function discoverRelated(taskQuery, method = "auto", limit = 10) {
|
|
64058
64668
|
if (!validateSyntax(taskQuery)) {
|
|
@@ -64075,7 +64685,7 @@ async function discoverRelated(taskQuery, method = "auto", limit = 10) {
|
|
|
64075
64685
|
const sourceLabels = new Set(sourceTask.labels ?? []);
|
|
64076
64686
|
const sourceDesc = (sourceTask.description ?? "").toLowerCase();
|
|
64077
64687
|
const sourceTitle = (sourceTask.title ?? "").toLowerCase();
|
|
64078
|
-
const sourceWords =
|
|
64688
|
+
const sourceWords = extractKeywords4(sourceTitle + " " + sourceDesc);
|
|
64079
64689
|
const parsed = parseQuery(taskQuery);
|
|
64080
64690
|
const registry2 = await readRegistry();
|
|
64081
64691
|
if (!registry2) {
|
|
@@ -64110,7 +64720,7 @@ async function discoverRelated(taskQuery, method = "auto", limit = 10) {
|
|
|
64110
64720
|
}
|
|
64111
64721
|
if (method === "description" || method === "auto") {
|
|
64112
64722
|
const taskDesc = ((task.description ?? "") + " " + (task.title ?? "")).toLowerCase();
|
|
64113
|
-
const taskWords =
|
|
64723
|
+
const taskWords = extractKeywords4(taskDesc);
|
|
64114
64724
|
const commonWords = sourceWords.filter((w2) => taskWords.includes(w2));
|
|
64115
64725
|
if (commonWords.length > 0) {
|
|
64116
64726
|
const descScore = commonWords.length / Math.max(sourceWords.length, taskWords.length, 1);
|
|
@@ -64209,14 +64819,14 @@ async function searchAcrossProjects(pattern, projectFilter, limit = 20) {
|
|
|
64209
64819
|
const sliced = results.slice(0, limit);
|
|
64210
64820
|
return { pattern, results: sliced, resultCount: sliced.length };
|
|
64211
64821
|
}
|
|
64212
|
-
var
|
|
64822
|
+
var STOP_WORDS4;
|
|
64213
64823
|
var init_discover = __esm({
|
|
64214
64824
|
"packages/core/src/nexus/discover.ts"() {
|
|
64215
64825
|
"use strict";
|
|
64216
64826
|
init_data_accessor();
|
|
64217
64827
|
init_query4();
|
|
64218
64828
|
init_registry3();
|
|
64219
|
-
|
|
64829
|
+
STOP_WORDS4 = /* @__PURE__ */ new Set([
|
|
64220
64830
|
"the",
|
|
64221
64831
|
"a",
|
|
64222
64832
|
"an",
|
|
@@ -66036,7 +66646,7 @@ __export(nexus_exports, {
|
|
|
66036
66646
|
criticalPath: () => criticalPath,
|
|
66037
66647
|
discoverRelated: () => discoverRelated,
|
|
66038
66648
|
executeTransfer: () => executeTransfer,
|
|
66039
|
-
extractKeywords: () =>
|
|
66649
|
+
extractKeywords: () => extractKeywords4,
|
|
66040
66650
|
generateProjectHash: () => generateProjectHash,
|
|
66041
66651
|
getCurrentProject: () => getCurrentProject,
|
|
66042
66652
|
getNexusCacheDir: () => getNexusCacheDir,
|
|
@@ -70462,6 +71072,7 @@ __export(research_exports, {
|
|
|
70462
71072
|
bulkLink: () => bulkLink,
|
|
70463
71073
|
compactManifest: () => compactManifest,
|
|
70464
71074
|
consolidateMemories: () => consolidateMemories,
|
|
71075
|
+
correlateOutcomes: () => correlateOutcomes,
|
|
70465
71076
|
detectContradictions: () => detectContradictions,
|
|
70466
71077
|
ensureFts5Tables: () => ensureFts5Tables,
|
|
70467
71078
|
fetchBrainEntries: () => fetchBrainEntries,
|
|
@@ -70472,6 +71083,7 @@ __export(research_exports, {
|
|
|
70472
71083
|
getLinkedLearnings: () => getLinkedLearnings,
|
|
70473
71084
|
getLinkedPatterns: () => getLinkedPatterns,
|
|
70474
71085
|
getMemoryLinks: () => getMemoryLinks,
|
|
71086
|
+
getMemoryQualityReport: () => getMemoryQualityReport,
|
|
70475
71087
|
getTaskLinks: () => getTaskLinks,
|
|
70476
71088
|
hybridSearch: () => hybridSearch,
|
|
70477
71089
|
learningStats: () => learningStats,
|
|
@@ -70513,6 +71125,7 @@ __export(research_exports, {
|
|
|
70513
71125
|
storePattern: () => storePattern,
|
|
70514
71126
|
storeVerifiedCandidate: () => storeVerifiedCandidate,
|
|
70515
71127
|
timelineBrain: () => timelineBrain,
|
|
71128
|
+
trackMemoryUsage: () => trackMemoryUsage,
|
|
70516
71129
|
unlinkMemoryFromTask: () => unlinkMemoryFromTask,
|
|
70517
71130
|
updateDecisionOutcome: () => updateDecisionOutcome,
|
|
70518
71131
|
updateResearch: () => updateResearch,
|
|
@@ -90882,6 +91495,22 @@ async function memoryGraphRemove(params, projectRoot) {
|
|
|
90882
91495
|
};
|
|
90883
91496
|
}
|
|
90884
91497
|
}
|
|
91498
|
+
async function memoryQualityReport(projectRoot) {
|
|
91499
|
+
try {
|
|
91500
|
+
const root = resolveRoot(projectRoot);
|
|
91501
|
+
const { getMemoryQualityReport: getMemoryQualityReport2 } = await Promise.resolve().then(() => (init_quality_feedback(), quality_feedback_exports));
|
|
91502
|
+
const report = await getMemoryQualityReport2(root);
|
|
91503
|
+
return { success: true, data: report };
|
|
91504
|
+
} catch (error48) {
|
|
91505
|
+
return {
|
|
91506
|
+
success: false,
|
|
91507
|
+
error: {
|
|
91508
|
+
code: "E_QUALITY_REPORT",
|
|
91509
|
+
message: error48 instanceof Error ? error48.message : String(error48)
|
|
91510
|
+
}
|
|
91511
|
+
};
|
|
91512
|
+
}
|
|
91513
|
+
}
|
|
90885
91514
|
var init_engine_compat = __esm({
|
|
90886
91515
|
"packages/core/src/memory/engine-compat.ts"() {
|
|
90887
91516
|
"use strict";
|
|
@@ -109520,12 +110149,12 @@ import { join as join119 } from "node:path";
|
|
|
109520
110149
|
function typedAll4(db, sql14, ...params) {
|
|
109521
110150
|
return db.prepare(sql14).all(...params);
|
|
109522
110151
|
}
|
|
109523
|
-
function
|
|
110152
|
+
function typedGet2(db, sql14, ...params) {
|
|
109524
110153
|
return db.prepare(sql14).get(...params);
|
|
109525
110154
|
}
|
|
109526
110155
|
function queryIndexMeta(db, projectId) {
|
|
109527
110156
|
try {
|
|
109528
|
-
const nodeMeta =
|
|
110157
|
+
const nodeMeta = typedGet2(
|
|
109529
110158
|
db,
|
|
109530
110159
|
`SELECT COUNT(*) as total_nodes,
|
|
109531
110160
|
COUNT(CASE WHEN kind = 'file' THEN 1 END) as file_count,
|
|
@@ -109534,7 +110163,7 @@ function queryIndexMeta(db, projectId) {
|
|
|
109534
110163
|
WHERE project_id = ?`,
|
|
109535
110164
|
projectId
|
|
109536
110165
|
);
|
|
109537
|
-
const relMeta =
|
|
110166
|
+
const relMeta = typedGet2(
|
|
109538
110167
|
db,
|
|
109539
110168
|
`SELECT COUNT(*) as total_relations
|
|
109540
110169
|
FROM nexus_relations
|
|
@@ -109629,7 +110258,7 @@ function queryCommunities(db, projectId, limit = 6) {
|
|
|
109629
110258
|
}
|
|
109630
110259
|
function queryProcessCount(db, projectId) {
|
|
109631
110260
|
try {
|
|
109632
|
-
const row =
|
|
110261
|
+
const row = typedGet2(
|
|
109633
110262
|
db,
|
|
109634
110263
|
`SELECT COUNT(*) as count
|
|
109635
110264
|
FROM nexus_nodes
|
|
@@ -111230,6 +111859,7 @@ __export(internal_exports, {
|
|
|
111230
111859
|
coreValidateProtocol: () => coreValidateProtocol,
|
|
111231
111860
|
coreValidateSchema: () => coreValidateSchema,
|
|
111232
111861
|
coreValidateTask: () => coreValidateTask,
|
|
111862
|
+
correlateOutcomes: () => correlateOutcomes,
|
|
111233
111863
|
createBackup: () => createBackup,
|
|
111234
111864
|
createConduit: () => createConduit,
|
|
111235
111865
|
createDataAccessor: () => createDataAccessor,
|
|
@@ -111382,6 +112012,7 @@ __export(internal_exports, {
|
|
|
111382
112012
|
getLinksByTaskId: () => getLinksByTaskId,
|
|
111383
112013
|
getLogDir: () => getLogDir,
|
|
111384
112014
|
getLogger: () => getLogger,
|
|
112015
|
+
getMemoryQualityReport: () => getMemoryQualityReport,
|
|
111385
112016
|
getMigrationStatus: () => getMigrationStatus2,
|
|
111386
112017
|
getNativeDb: () => getNativeDb,
|
|
111387
112018
|
getNativeOperations: () => getNativeOperations,
|
|
@@ -111552,6 +112183,7 @@ __export(internal_exports, {
|
|
|
111552
112183
|
memoryPatternFind: () => memoryPatternFind,
|
|
111553
112184
|
memoryPatternStats: () => memoryPatternStats,
|
|
111554
112185
|
memoryPatternStore: () => memoryPatternStore,
|
|
112186
|
+
memoryQualityReport: () => memoryQualityReport,
|
|
111555
112187
|
memoryReasonSimilar: () => memoryReasonSimilar,
|
|
111556
112188
|
memoryReasonWhy: () => memoryReasonWhy,
|
|
111557
112189
|
memorySearchHybrid: () => memorySearchHybrid,
|
|
@@ -111764,6 +112396,7 @@ __export(internal_exports, {
|
|
|
111764
112396
|
tokenUsageMethodSchema: () => tokenUsageMethodSchema,
|
|
111765
112397
|
tokenUsageTransportSchema: () => tokenUsageTransportSchema,
|
|
111766
112398
|
touchLink: () => touchLink,
|
|
112399
|
+
trackMemoryUsage: () => trackMemoryUsage,
|
|
111767
112400
|
ui: () => ui_exports,
|
|
111768
112401
|
uncancelTask: () => uncancelTask,
|
|
111769
112402
|
unpackBundle: () => unpackBundle,
|
|
@@ -111851,6 +112484,7 @@ var init_internal = __esm({
|
|
|
111851
112484
|
init_claude_mem_migration();
|
|
111852
112485
|
init_engine_compat();
|
|
111853
112486
|
init_pipeline_manifest_sqlite();
|
|
112487
|
+
init_quality_feedback();
|
|
111854
112488
|
init_token_service();
|
|
111855
112489
|
init_deps();
|
|
111856
112490
|
init_discover();
|
|
@@ -115016,6 +115650,66 @@ var init_registry5 = __esm({
|
|
|
115016
115650
|
sessionRequired: false,
|
|
115017
115651
|
requiredParams: []
|
|
115018
115652
|
},
|
|
115653
|
+
{
|
|
115654
|
+
gateway: "query",
|
|
115655
|
+
domain: "memory",
|
|
115656
|
+
operation: "quality",
|
|
115657
|
+
description: "Memory quality report: retrieval stats, noise ratio, tier distribution",
|
|
115658
|
+
tier: 1,
|
|
115659
|
+
idempotent: true,
|
|
115660
|
+
sessionRequired: false,
|
|
115661
|
+
requiredParams: []
|
|
115662
|
+
},
|
|
115663
|
+
{
|
|
115664
|
+
gateway: "query",
|
|
115665
|
+
domain: "memory",
|
|
115666
|
+
operation: "code.links",
|
|
115667
|
+
description: "List code_reference edges connecting memories to nexus code symbols",
|
|
115668
|
+
tier: 1,
|
|
115669
|
+
idempotent: true,
|
|
115670
|
+
sessionRequired: false,
|
|
115671
|
+
requiredParams: []
|
|
115672
|
+
},
|
|
115673
|
+
{
|
|
115674
|
+
gateway: "query",
|
|
115675
|
+
domain: "memory",
|
|
115676
|
+
operation: "code.memories-for-code",
|
|
115677
|
+
description: "Find memories linked to a code symbol via code_reference edges",
|
|
115678
|
+
tier: 1,
|
|
115679
|
+
idempotent: true,
|
|
115680
|
+
sessionRequired: false,
|
|
115681
|
+
requiredParams: ["symbol"]
|
|
115682
|
+
},
|
|
115683
|
+
{
|
|
115684
|
+
gateway: "query",
|
|
115685
|
+
domain: "memory",
|
|
115686
|
+
operation: "code.for-memory",
|
|
115687
|
+
description: "Find code symbols linked to a memory entry via code_reference edges",
|
|
115688
|
+
tier: 1,
|
|
115689
|
+
idempotent: true,
|
|
115690
|
+
sessionRequired: false,
|
|
115691
|
+
requiredParams: ["memoryId"]
|
|
115692
|
+
},
|
|
115693
|
+
{
|
|
115694
|
+
gateway: "mutate",
|
|
115695
|
+
domain: "memory",
|
|
115696
|
+
operation: "code.link",
|
|
115697
|
+
description: "Create code_reference edge from memory to nexus symbol",
|
|
115698
|
+
tier: 1,
|
|
115699
|
+
idempotent: false,
|
|
115700
|
+
sessionRequired: false,
|
|
115701
|
+
requiredParams: ["memoryId", "codeSymbol"]
|
|
115702
|
+
},
|
|
115703
|
+
{
|
|
115704
|
+
gateway: "mutate",
|
|
115705
|
+
domain: "memory",
|
|
115706
|
+
operation: "code.auto-link",
|
|
115707
|
+
description: "Scan memories for entity references and auto-link to nexus nodes",
|
|
115708
|
+
tier: 1,
|
|
115709
|
+
idempotent: true,
|
|
115710
|
+
sessionRequired: false,
|
|
115711
|
+
requiredParams: []
|
|
115712
|
+
},
|
|
115019
115713
|
{
|
|
115020
115714
|
gateway: "mutate",
|
|
115021
115715
|
domain: "pipeline",
|
|
@@ -123519,6 +124213,33 @@ var init_memory2 = __esm({
|
|
|
123519
124213
|
);
|
|
123520
124214
|
return wrapResult(result, "query", "memory", operation, startTime);
|
|
123521
124215
|
}
|
|
124216
|
+
case "quality": {
|
|
124217
|
+
const result = await memoryQualityReport(projectRoot);
|
|
124218
|
+
return wrapResult(result, "query", "memory", operation, startTime);
|
|
124219
|
+
}
|
|
124220
|
+
case "code.links": {
|
|
124221
|
+
const { listCodeLinks } = await Promise.resolve().then(() => (init_internal(), internal_exports));
|
|
124222
|
+
const result = await listCodeLinks(projectRoot);
|
|
124223
|
+
return wrapResult(result, "query", "memory", operation, startTime);
|
|
124224
|
+
}
|
|
124225
|
+
case "code.memories-for-code": {
|
|
124226
|
+
const symbol2 = params?.symbol;
|
|
124227
|
+
if (!symbol2) {
|
|
124228
|
+
return errorResult("query", "memory", operation, "E_INVALID_INPUT", "symbol is required", startTime);
|
|
124229
|
+
}
|
|
124230
|
+
const { queryMemoriesForCode } = await Promise.resolve().then(() => (init_internal(), internal_exports));
|
|
124231
|
+
const result = await queryMemoriesForCode(projectRoot, symbol2);
|
|
124232
|
+
return wrapResult({ success: true, data: result }, "query", "memory", operation, startTime);
|
|
124233
|
+
}
|
|
124234
|
+
case "code.for-memory": {
|
|
124235
|
+
const memoryId = params?.memoryId;
|
|
124236
|
+
if (!memoryId) {
|
|
124237
|
+
return errorResult("query", "memory", operation, "E_INVALID_INPUT", "memoryId is required", startTime);
|
|
124238
|
+
}
|
|
124239
|
+
const { queryCodeForMemory } = await Promise.resolve().then(() => (init_internal(), internal_exports));
|
|
124240
|
+
const result = await queryCodeForMemory(projectRoot, memoryId);
|
|
124241
|
+
return wrapResult({ success: true, data: result }, "query", "memory", operation, startTime);
|
|
124242
|
+
}
|
|
123522
124243
|
default:
|
|
123523
124244
|
return unsupportedOp("query", "memory", operation, startTime);
|
|
123524
124245
|
}
|
|
@@ -123689,6 +124410,21 @@ var init_memory2 = __esm({
|
|
|
123689
124410
|
);
|
|
123690
124411
|
return wrapResult(result, "mutate", "memory", operation, startTime);
|
|
123691
124412
|
}
|
|
124413
|
+
case "code.link": {
|
|
124414
|
+
const memoryId = params?.memoryId;
|
|
124415
|
+
const codeSymbol = params?.codeSymbol;
|
|
124416
|
+
if (!memoryId || !codeSymbol) {
|
|
124417
|
+
return errorResult("mutate", "memory", operation, "E_INVALID_INPUT", "memoryId and codeSymbol are required", startTime);
|
|
124418
|
+
}
|
|
124419
|
+
const { linkMemoryToCode } = await Promise.resolve().then(() => (init_internal(), internal_exports));
|
|
124420
|
+
const linked = await linkMemoryToCode(projectRoot, memoryId, codeSymbol);
|
|
124421
|
+
return wrapResult({ success: true, data: { linked } }, "mutate", "memory", operation, startTime);
|
|
124422
|
+
}
|
|
124423
|
+
case "code.auto-link": {
|
|
124424
|
+
const { autoLinkMemories } = await Promise.resolve().then(() => (init_internal(), internal_exports));
|
|
124425
|
+
const result = await autoLinkMemories(projectRoot);
|
|
124426
|
+
return wrapResult({ success: true, data: result }, "mutate", "memory", operation, startTime);
|
|
124427
|
+
}
|
|
123692
124428
|
default:
|
|
123693
124429
|
return unsupportedOp("mutate", "memory", operation, startTime);
|
|
123694
124430
|
}
|
|
@@ -123721,7 +124457,11 @@ var init_memory2 = __esm({
|
|
|
123721
124457
|
"graph.stats",
|
|
123722
124458
|
"reason.why",
|
|
123723
124459
|
"reason.similar",
|
|
123724
|
-
"search.hybrid"
|
|
124460
|
+
"search.hybrid",
|
|
124461
|
+
"quality",
|
|
124462
|
+
"code.links",
|
|
124463
|
+
"code.memories-for-code",
|
|
124464
|
+
"code.for-memory"
|
|
123725
124465
|
],
|
|
123726
124466
|
mutate: [
|
|
123727
124467
|
"observe",
|
|
@@ -123730,7 +124470,9 @@ var init_memory2 = __esm({
|
|
|
123730
124470
|
"learning.store",
|
|
123731
124471
|
"link",
|
|
123732
124472
|
"graph.add",
|
|
123733
|
-
"graph.remove"
|
|
124473
|
+
"graph.remove",
|
|
124474
|
+
"code.link",
|
|
124475
|
+
"code.auto-link"
|
|
123734
124476
|
]
|
|
123735
124477
|
};
|
|
123736
124478
|
}
|
|
@@ -133448,6 +134190,66 @@ function registerBrainCommand(program) {
|
|
|
133448
134190
|
process.exit(1);
|
|
133449
134191
|
}
|
|
133450
134192
|
});
|
|
134193
|
+
brain.command("quality").description(
|
|
134194
|
+
"Show memory quality metrics: retrieval rates, top/never-retrieved entries, quality distribution, and noise ratio."
|
|
134195
|
+
).option("--json", "Output results as JSON").action(async (opts) => {
|
|
134196
|
+
const root = getProjectRoot();
|
|
134197
|
+
const isJson = !!opts.json;
|
|
134198
|
+
try {
|
|
134199
|
+
const report = await getMemoryQualityReport(root);
|
|
134200
|
+
if (isJson) {
|
|
134201
|
+
console.log(
|
|
134202
|
+
JSON.stringify(
|
|
134203
|
+
{
|
|
134204
|
+
success: true,
|
|
134205
|
+
data: report,
|
|
134206
|
+
meta: { operation: "brain.quality", timestamp: (/* @__PURE__ */ new Date()).toISOString() }
|
|
134207
|
+
},
|
|
134208
|
+
null,
|
|
134209
|
+
2
|
|
134210
|
+
)
|
|
134211
|
+
);
|
|
134212
|
+
return;
|
|
134213
|
+
}
|
|
134214
|
+
console.log("\nBrain Memory Quality Report");
|
|
134215
|
+
console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
134216
|
+
console.log(` Total retrievals: ${report.totalRetrievals}`);
|
|
134217
|
+
console.log(` Unique entries hit: ${report.uniqueEntriesRetrieved}`);
|
|
134218
|
+
console.log(` Usage rate: ${(report.usageRate * 100).toFixed(1)}%`);
|
|
134219
|
+
console.log(` Noise ratio: ${(report.noiseRatio * 100).toFixed(1)}%`);
|
|
134220
|
+
console.log("\nQuality Distribution");
|
|
134221
|
+
console.log(` Low (<0.3): ${report.qualityDistribution.low}`);
|
|
134222
|
+
console.log(` Med (0.3-0.6): ${report.qualityDistribution.medium}`);
|
|
134223
|
+
console.log(` High (>0.6): ${report.qualityDistribution.high}`);
|
|
134224
|
+
console.log("\nTier Distribution");
|
|
134225
|
+
console.log(` Short: ${report.tierDistribution.short}`);
|
|
134226
|
+
console.log(` Medium: ${report.tierDistribution.medium}`);
|
|
134227
|
+
console.log(` Long: ${report.tierDistribution.long}`);
|
|
134228
|
+
if (report.tierDistribution.unknown > 0) {
|
|
134229
|
+
console.log(` Unknown: ${report.tierDistribution.unknown}`);
|
|
134230
|
+
}
|
|
134231
|
+
if (report.topRetrieved.length > 0) {
|
|
134232
|
+
console.log("\nTop 10 Most Retrieved");
|
|
134233
|
+
for (const e of report.topRetrieved) {
|
|
134234
|
+
console.log(` [${e.citationCount}x] ${e.id} ${e.title.slice(0, 60)}`);
|
|
134235
|
+
}
|
|
134236
|
+
}
|
|
134237
|
+
if (report.neverRetrieved.length > 0) {
|
|
134238
|
+
console.log("\nNever Retrieved (pruning candidates)");
|
|
134239
|
+
for (const e of report.neverRetrieved) {
|
|
134240
|
+
console.log(` q=${e.qualityScore.toFixed(2)} ${e.id} ${e.title.slice(0, 60)}`);
|
|
134241
|
+
}
|
|
134242
|
+
}
|
|
134243
|
+
} catch (err) {
|
|
134244
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
134245
|
+
if (isJson) {
|
|
134246
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
134247
|
+
} else {
|
|
134248
|
+
console.error(`Brain quality report failed: ${message}`);
|
|
134249
|
+
}
|
|
134250
|
+
process.exit(1);
|
|
134251
|
+
}
|
|
134252
|
+
});
|
|
133451
134253
|
}
|
|
133452
134254
|
|
|
133453
134255
|
// packages/cleo/src/cli/commands/briefing.ts
|
|
@@ -136517,6 +137319,47 @@ function registerMemoryBrainCommand(program) {
|
|
|
136517
137319
|
{ command: "memory", operation: "memory.search.hybrid" }
|
|
136518
137320
|
);
|
|
136519
137321
|
});
|
|
137322
|
+
memory.command("code-links").description("Show code \u2194 memory connections (code_reference edges between brain and nexus)").option("--limit <n>", "Maximum entries to return (default 100)", parseInt).option("--json", "Output as JSON").action(async (opts) => {
|
|
137323
|
+
await dispatchFromCli(
|
|
137324
|
+
"query",
|
|
137325
|
+
"memory",
|
|
137326
|
+
"code.links",
|
|
137327
|
+
{
|
|
137328
|
+
...opts["limit"] !== void 0 && { limit: opts["limit"] }
|
|
137329
|
+
},
|
|
137330
|
+
{ command: "memory", operation: "memory.code.links" }
|
|
137331
|
+
);
|
|
137332
|
+
});
|
|
137333
|
+
memory.command("code-auto-link").description("Scan brain memory nodes for entity references and auto-link to nexus code nodes").option("--json", "Output as JSON").action(async () => {
|
|
137334
|
+
await dispatchFromCli(
|
|
137335
|
+
"mutate",
|
|
137336
|
+
"memory",
|
|
137337
|
+
"code.auto-link",
|
|
137338
|
+
{},
|
|
137339
|
+
{
|
|
137340
|
+
command: "memory",
|
|
137341
|
+
operation: "memory.code.auto-link"
|
|
137342
|
+
}
|
|
137343
|
+
);
|
|
137344
|
+
});
|
|
137345
|
+
memory.command("code-memories-for-code <symbol>").description("Find brain memory nodes that reference a given nexus code symbol").option("--json", "Output as JSON").action(async (symbol2) => {
|
|
137346
|
+
await dispatchFromCli(
|
|
137347
|
+
"query",
|
|
137348
|
+
"memory",
|
|
137349
|
+
"code.memories-for-code",
|
|
137350
|
+
{ symbol: symbol2 },
|
|
137351
|
+
{ command: "memory", operation: "memory.code.memories-for-code" }
|
|
137352
|
+
);
|
|
137353
|
+
});
|
|
137354
|
+
memory.command("code-for-memory <memoryId>").description("Find nexus code nodes referenced by a given brain memory entry").option("--json", "Output as JSON").action(async (memoryId) => {
|
|
137355
|
+
await dispatchFromCli(
|
|
137356
|
+
"query",
|
|
137357
|
+
"memory",
|
|
137358
|
+
"code.for-memory",
|
|
137359
|
+
{ memoryId },
|
|
137360
|
+
{ command: "memory", operation: "memory.code.for-memory" }
|
|
137361
|
+
);
|
|
137362
|
+
});
|
|
136520
137363
|
}
|
|
136521
137364
|
|
|
136522
137365
|
// packages/cleo/src/cli/commands/migrate-claude-mem.ts
|