@cleocode/cleo 2026.4.37 → 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 +881 -40
- 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
|
|
|
@@ -45369,11 +45614,11 @@ var brain_consolidator_exports = {};
|
|
|
45369
45614
|
__export(brain_consolidator_exports, {
|
|
45370
45615
|
detectContradictions: () => detectContradictions
|
|
45371
45616
|
});
|
|
45372
|
-
function
|
|
45617
|
+
function extractKeywords2(text3) {
|
|
45373
45618
|
const words = text3.toLowerCase().replace(/[^a-z0-9\s\-_]/g, " ").split(/\s+/);
|
|
45374
45619
|
const keywords = /* @__PURE__ */ new Set();
|
|
45375
45620
|
for (const w2 of words) {
|
|
45376
|
-
if (w2.length >= 4 && !
|
|
45621
|
+
if (w2.length >= 4 && !STOP_WORDS2.has(w2)) {
|
|
45377
45622
|
keywords.add(w2);
|
|
45378
45623
|
}
|
|
45379
45624
|
}
|
|
@@ -45422,7 +45667,7 @@ async function detectContradictions(projectRoot) {
|
|
|
45422
45667
|
const keywordMap = /* @__PURE__ */ new Map();
|
|
45423
45668
|
const negationMap = /* @__PURE__ */ new Map();
|
|
45424
45669
|
for (const entry of entries) {
|
|
45425
|
-
keywordMap.set(entry.id,
|
|
45670
|
+
keywordMap.set(entry.id, extractKeywords2(entry.text));
|
|
45426
45671
|
negationMap.set(entry.id, findNegationMarkers(entry.text));
|
|
45427
45672
|
}
|
|
45428
45673
|
for (let i = 0; i < entries.length; i++) {
|
|
@@ -45436,7 +45681,7 @@ async function detectContradictions(projectRoot) {
|
|
|
45436
45681
|
const keywordsB = keywordMap.get(entryB.id);
|
|
45437
45682
|
const negationsB = negationMap.get(entryB.id);
|
|
45438
45683
|
const shared = keywordIntersection(keywordsA, keywordsB);
|
|
45439
|
-
if (shared.length <
|
|
45684
|
+
if (shared.length < MIN_SHARED_KEYWORDS2) continue;
|
|
45440
45685
|
const negationsOnlyInA = negationsA.filter((m2) => !negationsB.includes(m2));
|
|
45441
45686
|
const negationsOnlyInB = negationsB.filter((m2) => !negationsA.includes(m2));
|
|
45442
45687
|
const negationFlip = negationsOnlyInA.length > 0 || negationsOnlyInB.length > 0;
|
|
@@ -45454,8 +45699,8 @@ async function detectContradictions(projectRoot) {
|
|
|
45454
45699
|
sharedKeywords: shared.slice(0, 10),
|
|
45455
45700
|
negationMarkers: negMarkers.slice(0, 5)
|
|
45456
45701
|
});
|
|
45457
|
-
const nodeA =
|
|
45458
|
-
const nodeB =
|
|
45702
|
+
const nodeA = buildNodeId2(table, entryA.id);
|
|
45703
|
+
const nodeB = buildNodeId2(table, entryB.id);
|
|
45459
45704
|
try {
|
|
45460
45705
|
nativeDb.prepare(`
|
|
45461
45706
|
INSERT OR IGNORE INTO brain_page_edges
|
|
@@ -45484,7 +45729,7 @@ async function detectContradictions(projectRoot) {
|
|
|
45484
45729
|
}
|
|
45485
45730
|
return results;
|
|
45486
45731
|
}
|
|
45487
|
-
function
|
|
45732
|
+
function buildNodeId2(table, entryId) {
|
|
45488
45733
|
const typeMap = {
|
|
45489
45734
|
brain_observations: "observation",
|
|
45490
45735
|
brain_learnings: "learning",
|
|
@@ -45494,13 +45739,13 @@ function buildNodeId(table, entryId) {
|
|
|
45494
45739
|
const type = typeMap[table] ?? "entry";
|
|
45495
45740
|
return `${type}:${entryId}`;
|
|
45496
45741
|
}
|
|
45497
|
-
var
|
|
45742
|
+
var MIN_SHARED_KEYWORDS2, NEGATION_MARKERS, STOP_WORDS2;
|
|
45498
45743
|
var init_brain_consolidator = __esm({
|
|
45499
45744
|
"packages/core/src/memory/brain-consolidator.ts"() {
|
|
45500
45745
|
"use strict";
|
|
45501
45746
|
init_brain_sqlite();
|
|
45502
45747
|
init_typed_query();
|
|
45503
|
-
|
|
45748
|
+
MIN_SHARED_KEYWORDS2 = 3;
|
|
45504
45749
|
NEGATION_MARKERS = [
|
|
45505
45750
|
"not",
|
|
45506
45751
|
"never",
|
|
@@ -45521,7 +45766,7 @@ var init_brain_consolidator = __esm({
|
|
|
45521
45766
|
"undone",
|
|
45522
45767
|
"superseded"
|
|
45523
45768
|
];
|
|
45524
|
-
|
|
45769
|
+
STOP_WORDS2 = /* @__PURE__ */ new Set([
|
|
45525
45770
|
"the",
|
|
45526
45771
|
"a",
|
|
45527
45772
|
"an",
|
|
@@ -45609,11 +45854,11 @@ async function applyTemporalDecay(projectRoot, options) {
|
|
|
45609
45854
|
tablesProcessed: ["brain_learnings"]
|
|
45610
45855
|
};
|
|
45611
45856
|
}
|
|
45612
|
-
function
|
|
45857
|
+
function extractKeywords3(text3) {
|
|
45613
45858
|
const words = text3.toLowerCase().replace(/[^a-z0-9\s-]/g, "").split(/\s+/);
|
|
45614
45859
|
const keywords = /* @__PURE__ */ new Set();
|
|
45615
45860
|
for (const w2 of words) {
|
|
45616
|
-
if (w2.length >= 4 && !
|
|
45861
|
+
if (w2.length >= 4 && !STOP_WORDS3.has(w2)) {
|
|
45617
45862
|
keywords.add(w2);
|
|
45618
45863
|
}
|
|
45619
45864
|
}
|
|
@@ -45651,7 +45896,7 @@ async function consolidateMemories(projectRoot, options) {
|
|
|
45651
45896
|
}
|
|
45652
45897
|
const entries = oldObservations.map((obs) => ({
|
|
45653
45898
|
...obs,
|
|
45654
|
-
keywords:
|
|
45899
|
+
keywords: extractKeywords3(`${obs.title} ${obs.narrative ?? ""}`),
|
|
45655
45900
|
clustered: false
|
|
45656
45901
|
}));
|
|
45657
45902
|
const clusters = [];
|
|
@@ -46053,13 +46298,13 @@ async function strengthenCoRetrievedEdges(projectRoot) {
|
|
|
46053
46298
|
}
|
|
46054
46299
|
return strengthened;
|
|
46055
46300
|
}
|
|
46056
|
-
var
|
|
46301
|
+
var STOP_WORDS3;
|
|
46057
46302
|
var init_brain_lifecycle = __esm({
|
|
46058
46303
|
"packages/core/src/memory/brain-lifecycle.ts"() {
|
|
46059
46304
|
"use strict";
|
|
46060
46305
|
init_brain_accessor();
|
|
46061
46306
|
init_typed_query();
|
|
46062
|
-
|
|
46307
|
+
STOP_WORDS3 = /* @__PURE__ */ new Set([
|
|
46063
46308
|
"the",
|
|
46064
46309
|
"a",
|
|
46065
46310
|
"an",
|
|
@@ -46664,6 +46909,358 @@ var init_session_hooks = __esm({
|
|
|
46664
46909
|
}
|
|
46665
46910
|
});
|
|
46666
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
|
+
|
|
46667
47264
|
// packages/core/src/hooks/handlers/task-hooks.ts
|
|
46668
47265
|
async function handleToolStart(projectRoot, payload) {
|
|
46669
47266
|
const { observeBrain: observeBrain2 } = await Promise.resolve().then(() => (init_brain_retrieval(), brain_retrieval_exports));
|
|
@@ -46697,6 +47294,13 @@ async function handleToolComplete(projectRoot, payload) {
|
|
|
46697
47294
|
} catch {
|
|
46698
47295
|
}
|
|
46699
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
|
+
});
|
|
46700
47304
|
await maybeRefreshMemoryBridge(projectRoot);
|
|
46701
47305
|
}
|
|
46702
47306
|
var init_task_hooks = __esm({
|
|
@@ -53194,7 +53798,7 @@ function generateRecommendation2(changeType, affectedCount, cascadeDepth, taskId
|
|
|
53194
53798
|
}
|
|
53195
53799
|
}
|
|
53196
53800
|
function scoreTaskMatch(change, task) {
|
|
53197
|
-
const
|
|
53801
|
+
const STOP_WORDS5 = /* @__PURE__ */ new Set([
|
|
53198
53802
|
"a",
|
|
53199
53803
|
"an",
|
|
53200
53804
|
"the",
|
|
@@ -53216,7 +53820,7 @@ function scoreTaskMatch(change, task) {
|
|
|
53216
53820
|
"do",
|
|
53217
53821
|
"not"
|
|
53218
53822
|
]);
|
|
53219
|
-
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));
|
|
53220
53824
|
const changeTokens = new Set(tokenise(change));
|
|
53221
53825
|
if (changeTokens.size === 0) return 0;
|
|
53222
53826
|
const taskText = `${task.title ?? ""} ${task.description ?? ""}`;
|
|
@@ -59666,6 +60270,7 @@ __export(memory_exports, {
|
|
|
59666
60270
|
bulkLink: () => bulkLink,
|
|
59667
60271
|
compactManifest: () => compactManifest,
|
|
59668
60272
|
consolidateMemories: () => consolidateMemories,
|
|
60273
|
+
correlateOutcomes: () => correlateOutcomes,
|
|
59669
60274
|
detectContradictions: () => detectContradictions,
|
|
59670
60275
|
ensureFts5Tables: () => ensureFts5Tables,
|
|
59671
60276
|
fetchBrainEntries: () => fetchBrainEntries,
|
|
@@ -59676,6 +60281,7 @@ __export(memory_exports, {
|
|
|
59676
60281
|
getLinkedLearnings: () => getLinkedLearnings,
|
|
59677
60282
|
getLinkedPatterns: () => getLinkedPatterns,
|
|
59678
60283
|
getMemoryLinks: () => getMemoryLinks,
|
|
60284
|
+
getMemoryQualityReport: () => getMemoryQualityReport,
|
|
59679
60285
|
getTaskLinks: () => getTaskLinks,
|
|
59680
60286
|
hybridSearch: () => hybridSearch,
|
|
59681
60287
|
learningStats: () => learningStats,
|
|
@@ -59717,6 +60323,7 @@ __export(memory_exports, {
|
|
|
59717
60323
|
storePattern: () => storePattern,
|
|
59718
60324
|
storeVerifiedCandidate: () => storeVerifiedCandidate,
|
|
59719
60325
|
timelineBrain: () => timelineBrain,
|
|
60326
|
+
trackMemoryUsage: () => trackMemoryUsage,
|
|
59720
60327
|
unlinkMemoryFromTask: () => unlinkMemoryFromTask,
|
|
59721
60328
|
updateDecisionOutcome: () => updateDecisionOutcome,
|
|
59722
60329
|
updateResearch: () => updateResearch,
|
|
@@ -60339,6 +60946,7 @@ var init_memory = __esm({
|
|
|
60339
60946
|
init_extraction_gate();
|
|
60340
60947
|
init_learnings();
|
|
60341
60948
|
init_patterns();
|
|
60949
|
+
init_quality_feedback();
|
|
60342
60950
|
}
|
|
60343
60951
|
});
|
|
60344
60952
|
|
|
@@ -64053,8 +64661,8 @@ var init_deps = __esm({
|
|
|
64053
64661
|
});
|
|
64054
64662
|
|
|
64055
64663
|
// packages/core/src/nexus/discover.ts
|
|
64056
|
-
function
|
|
64057
|
-
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));
|
|
64058
64666
|
}
|
|
64059
64667
|
async function discoverRelated(taskQuery, method = "auto", limit = 10) {
|
|
64060
64668
|
if (!validateSyntax(taskQuery)) {
|
|
@@ -64077,7 +64685,7 @@ async function discoverRelated(taskQuery, method = "auto", limit = 10) {
|
|
|
64077
64685
|
const sourceLabels = new Set(sourceTask.labels ?? []);
|
|
64078
64686
|
const sourceDesc = (sourceTask.description ?? "").toLowerCase();
|
|
64079
64687
|
const sourceTitle = (sourceTask.title ?? "").toLowerCase();
|
|
64080
|
-
const sourceWords =
|
|
64688
|
+
const sourceWords = extractKeywords4(sourceTitle + " " + sourceDesc);
|
|
64081
64689
|
const parsed = parseQuery(taskQuery);
|
|
64082
64690
|
const registry2 = await readRegistry();
|
|
64083
64691
|
if (!registry2) {
|
|
@@ -64112,7 +64720,7 @@ async function discoverRelated(taskQuery, method = "auto", limit = 10) {
|
|
|
64112
64720
|
}
|
|
64113
64721
|
if (method === "description" || method === "auto") {
|
|
64114
64722
|
const taskDesc = ((task.description ?? "") + " " + (task.title ?? "")).toLowerCase();
|
|
64115
|
-
const taskWords =
|
|
64723
|
+
const taskWords = extractKeywords4(taskDesc);
|
|
64116
64724
|
const commonWords = sourceWords.filter((w2) => taskWords.includes(w2));
|
|
64117
64725
|
if (commonWords.length > 0) {
|
|
64118
64726
|
const descScore = commonWords.length / Math.max(sourceWords.length, taskWords.length, 1);
|
|
@@ -64211,14 +64819,14 @@ async function searchAcrossProjects(pattern, projectFilter, limit = 20) {
|
|
|
64211
64819
|
const sliced = results.slice(0, limit);
|
|
64212
64820
|
return { pattern, results: sliced, resultCount: sliced.length };
|
|
64213
64821
|
}
|
|
64214
|
-
var
|
|
64822
|
+
var STOP_WORDS4;
|
|
64215
64823
|
var init_discover = __esm({
|
|
64216
64824
|
"packages/core/src/nexus/discover.ts"() {
|
|
64217
64825
|
"use strict";
|
|
64218
64826
|
init_data_accessor();
|
|
64219
64827
|
init_query4();
|
|
64220
64828
|
init_registry3();
|
|
64221
|
-
|
|
64829
|
+
STOP_WORDS4 = /* @__PURE__ */ new Set([
|
|
64222
64830
|
"the",
|
|
64223
64831
|
"a",
|
|
64224
64832
|
"an",
|
|
@@ -66038,7 +66646,7 @@ __export(nexus_exports, {
|
|
|
66038
66646
|
criticalPath: () => criticalPath,
|
|
66039
66647
|
discoverRelated: () => discoverRelated,
|
|
66040
66648
|
executeTransfer: () => executeTransfer,
|
|
66041
|
-
extractKeywords: () =>
|
|
66649
|
+
extractKeywords: () => extractKeywords4,
|
|
66042
66650
|
generateProjectHash: () => generateProjectHash,
|
|
66043
66651
|
getCurrentProject: () => getCurrentProject,
|
|
66044
66652
|
getNexusCacheDir: () => getNexusCacheDir,
|
|
@@ -70464,6 +71072,7 @@ __export(research_exports, {
|
|
|
70464
71072
|
bulkLink: () => bulkLink,
|
|
70465
71073
|
compactManifest: () => compactManifest,
|
|
70466
71074
|
consolidateMemories: () => consolidateMemories,
|
|
71075
|
+
correlateOutcomes: () => correlateOutcomes,
|
|
70467
71076
|
detectContradictions: () => detectContradictions,
|
|
70468
71077
|
ensureFts5Tables: () => ensureFts5Tables,
|
|
70469
71078
|
fetchBrainEntries: () => fetchBrainEntries,
|
|
@@ -70474,6 +71083,7 @@ __export(research_exports, {
|
|
|
70474
71083
|
getLinkedLearnings: () => getLinkedLearnings,
|
|
70475
71084
|
getLinkedPatterns: () => getLinkedPatterns,
|
|
70476
71085
|
getMemoryLinks: () => getMemoryLinks,
|
|
71086
|
+
getMemoryQualityReport: () => getMemoryQualityReport,
|
|
70477
71087
|
getTaskLinks: () => getTaskLinks,
|
|
70478
71088
|
hybridSearch: () => hybridSearch,
|
|
70479
71089
|
learningStats: () => learningStats,
|
|
@@ -70515,6 +71125,7 @@ __export(research_exports, {
|
|
|
70515
71125
|
storePattern: () => storePattern,
|
|
70516
71126
|
storeVerifiedCandidate: () => storeVerifiedCandidate,
|
|
70517
71127
|
timelineBrain: () => timelineBrain,
|
|
71128
|
+
trackMemoryUsage: () => trackMemoryUsage,
|
|
70518
71129
|
unlinkMemoryFromTask: () => unlinkMemoryFromTask,
|
|
70519
71130
|
updateDecisionOutcome: () => updateDecisionOutcome,
|
|
70520
71131
|
updateResearch: () => updateResearch,
|
|
@@ -90884,6 +91495,22 @@ async function memoryGraphRemove(params, projectRoot) {
|
|
|
90884
91495
|
};
|
|
90885
91496
|
}
|
|
90886
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
|
+
}
|
|
90887
91514
|
var init_engine_compat = __esm({
|
|
90888
91515
|
"packages/core/src/memory/engine-compat.ts"() {
|
|
90889
91516
|
"use strict";
|
|
@@ -109522,12 +110149,12 @@ import { join as join119 } from "node:path";
|
|
|
109522
110149
|
function typedAll4(db, sql14, ...params) {
|
|
109523
110150
|
return db.prepare(sql14).all(...params);
|
|
109524
110151
|
}
|
|
109525
|
-
function
|
|
110152
|
+
function typedGet2(db, sql14, ...params) {
|
|
109526
110153
|
return db.prepare(sql14).get(...params);
|
|
109527
110154
|
}
|
|
109528
110155
|
function queryIndexMeta(db, projectId) {
|
|
109529
110156
|
try {
|
|
109530
|
-
const nodeMeta =
|
|
110157
|
+
const nodeMeta = typedGet2(
|
|
109531
110158
|
db,
|
|
109532
110159
|
`SELECT COUNT(*) as total_nodes,
|
|
109533
110160
|
COUNT(CASE WHEN kind = 'file' THEN 1 END) as file_count,
|
|
@@ -109536,7 +110163,7 @@ function queryIndexMeta(db, projectId) {
|
|
|
109536
110163
|
WHERE project_id = ?`,
|
|
109537
110164
|
projectId
|
|
109538
110165
|
);
|
|
109539
|
-
const relMeta =
|
|
110166
|
+
const relMeta = typedGet2(
|
|
109540
110167
|
db,
|
|
109541
110168
|
`SELECT COUNT(*) as total_relations
|
|
109542
110169
|
FROM nexus_relations
|
|
@@ -109631,7 +110258,7 @@ function queryCommunities(db, projectId, limit = 6) {
|
|
|
109631
110258
|
}
|
|
109632
110259
|
function queryProcessCount(db, projectId) {
|
|
109633
110260
|
try {
|
|
109634
|
-
const row =
|
|
110261
|
+
const row = typedGet2(
|
|
109635
110262
|
db,
|
|
109636
110263
|
`SELECT COUNT(*) as count
|
|
109637
110264
|
FROM nexus_nodes
|
|
@@ -111232,6 +111859,7 @@ __export(internal_exports, {
|
|
|
111232
111859
|
coreValidateProtocol: () => coreValidateProtocol,
|
|
111233
111860
|
coreValidateSchema: () => coreValidateSchema,
|
|
111234
111861
|
coreValidateTask: () => coreValidateTask,
|
|
111862
|
+
correlateOutcomes: () => correlateOutcomes,
|
|
111235
111863
|
createBackup: () => createBackup,
|
|
111236
111864
|
createConduit: () => createConduit,
|
|
111237
111865
|
createDataAccessor: () => createDataAccessor,
|
|
@@ -111384,6 +112012,7 @@ __export(internal_exports, {
|
|
|
111384
112012
|
getLinksByTaskId: () => getLinksByTaskId,
|
|
111385
112013
|
getLogDir: () => getLogDir,
|
|
111386
112014
|
getLogger: () => getLogger,
|
|
112015
|
+
getMemoryQualityReport: () => getMemoryQualityReport,
|
|
111387
112016
|
getMigrationStatus: () => getMigrationStatus2,
|
|
111388
112017
|
getNativeDb: () => getNativeDb,
|
|
111389
112018
|
getNativeOperations: () => getNativeOperations,
|
|
@@ -111554,6 +112183,7 @@ __export(internal_exports, {
|
|
|
111554
112183
|
memoryPatternFind: () => memoryPatternFind,
|
|
111555
112184
|
memoryPatternStats: () => memoryPatternStats,
|
|
111556
112185
|
memoryPatternStore: () => memoryPatternStore,
|
|
112186
|
+
memoryQualityReport: () => memoryQualityReport,
|
|
111557
112187
|
memoryReasonSimilar: () => memoryReasonSimilar,
|
|
111558
112188
|
memoryReasonWhy: () => memoryReasonWhy,
|
|
111559
112189
|
memorySearchHybrid: () => memorySearchHybrid,
|
|
@@ -111766,6 +112396,7 @@ __export(internal_exports, {
|
|
|
111766
112396
|
tokenUsageMethodSchema: () => tokenUsageMethodSchema,
|
|
111767
112397
|
tokenUsageTransportSchema: () => tokenUsageTransportSchema,
|
|
111768
112398
|
touchLink: () => touchLink,
|
|
112399
|
+
trackMemoryUsage: () => trackMemoryUsage,
|
|
111769
112400
|
ui: () => ui_exports,
|
|
111770
112401
|
uncancelTask: () => uncancelTask,
|
|
111771
112402
|
unpackBundle: () => unpackBundle,
|
|
@@ -111853,6 +112484,7 @@ var init_internal = __esm({
|
|
|
111853
112484
|
init_claude_mem_migration();
|
|
111854
112485
|
init_engine_compat();
|
|
111855
112486
|
init_pipeline_manifest_sqlite();
|
|
112487
|
+
init_quality_feedback();
|
|
111856
112488
|
init_token_service();
|
|
111857
112489
|
init_deps();
|
|
111858
112490
|
init_discover();
|
|
@@ -115018,6 +115650,66 @@ var init_registry5 = __esm({
|
|
|
115018
115650
|
sessionRequired: false,
|
|
115019
115651
|
requiredParams: []
|
|
115020
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
|
+
},
|
|
115021
115713
|
{
|
|
115022
115714
|
gateway: "mutate",
|
|
115023
115715
|
domain: "pipeline",
|
|
@@ -123521,6 +124213,33 @@ var init_memory2 = __esm({
|
|
|
123521
124213
|
);
|
|
123522
124214
|
return wrapResult(result, "query", "memory", operation, startTime);
|
|
123523
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
|
+
}
|
|
123524
124243
|
default:
|
|
123525
124244
|
return unsupportedOp("query", "memory", operation, startTime);
|
|
123526
124245
|
}
|
|
@@ -123691,6 +124410,21 @@ var init_memory2 = __esm({
|
|
|
123691
124410
|
);
|
|
123692
124411
|
return wrapResult(result, "mutate", "memory", operation, startTime);
|
|
123693
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
|
+
}
|
|
123694
124428
|
default:
|
|
123695
124429
|
return unsupportedOp("mutate", "memory", operation, startTime);
|
|
123696
124430
|
}
|
|
@@ -123723,7 +124457,11 @@ var init_memory2 = __esm({
|
|
|
123723
124457
|
"graph.stats",
|
|
123724
124458
|
"reason.why",
|
|
123725
124459
|
"reason.similar",
|
|
123726
|
-
"search.hybrid"
|
|
124460
|
+
"search.hybrid",
|
|
124461
|
+
"quality",
|
|
124462
|
+
"code.links",
|
|
124463
|
+
"code.memories-for-code",
|
|
124464
|
+
"code.for-memory"
|
|
123727
124465
|
],
|
|
123728
124466
|
mutate: [
|
|
123729
124467
|
"observe",
|
|
@@ -123732,7 +124470,9 @@ var init_memory2 = __esm({
|
|
|
123732
124470
|
"learning.store",
|
|
123733
124471
|
"link",
|
|
123734
124472
|
"graph.add",
|
|
123735
|
-
"graph.remove"
|
|
124473
|
+
"graph.remove",
|
|
124474
|
+
"code.link",
|
|
124475
|
+
"code.auto-link"
|
|
123736
124476
|
]
|
|
123737
124477
|
};
|
|
123738
124478
|
}
|
|
@@ -133450,6 +134190,66 @@ function registerBrainCommand(program) {
|
|
|
133450
134190
|
process.exit(1);
|
|
133451
134191
|
}
|
|
133452
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
|
+
});
|
|
133453
134253
|
}
|
|
133454
134254
|
|
|
133455
134255
|
// packages/cleo/src/cli/commands/briefing.ts
|
|
@@ -136519,6 +137319,47 @@ function registerMemoryBrainCommand(program) {
|
|
|
136519
137319
|
{ command: "memory", operation: "memory.search.hybrid" }
|
|
136520
137320
|
);
|
|
136521
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
|
+
});
|
|
136522
137363
|
}
|
|
136523
137364
|
|
|
136524
137365
|
// packages/cleo/src/cli/commands/migrate-claude-mem.ts
|