@cleocode/cleo 2026.4.49 → 2026.4.51
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/index.js +504 -9
- package/dist/cli/index.js.map +4 -4
- package/package.json +8 -8
package/dist/cli/index.js
CHANGED
|
@@ -9071,12 +9071,13 @@ __export(brain_schema_exports, {
|
|
|
9071
9071
|
brainPageEdges: () => brainPageEdges,
|
|
9072
9072
|
brainPageNodes: () => brainPageNodes,
|
|
9073
9073
|
brainPatterns: () => brainPatterns,
|
|
9074
|
+
brainPlasticityEvents: () => brainPlasticityEvents,
|
|
9074
9075
|
brainRetrievalLog: () => brainRetrievalLog,
|
|
9075
9076
|
brainSchemaMeta: () => brainSchemaMeta,
|
|
9076
9077
|
brainStickyNotes: () => brainStickyNotes
|
|
9077
9078
|
});
|
|
9078
9079
|
import { sql as sql2 } from "drizzle-orm";
|
|
9079
|
-
var BRAIN_MEMORY_TIERS, BRAIN_COGNITIVE_TYPES, BRAIN_SOURCE_CONFIDENCE, BRAIN_DECISION_TYPES, BRAIN_CONFIDENCE_LEVELS, BRAIN_OUTCOME_TYPES, BRAIN_PATTERN_TYPES, BRAIN_IMPACT_LEVELS, BRAIN_LINK_TYPES, BRAIN_OBSERVATION_TYPES2, BRAIN_OBSERVATION_SOURCE_TYPES, BRAIN_MEMORY_TYPES, BRAIN_STICKY_STATUSES, BRAIN_STICKY_COLORS, BRAIN_STICKY_PRIORITIES, brainDecisions, brainPatterns, brainLearnings, brainObservations, brainStickyNotes, brainMemoryLinks, brainSchemaMeta, BRAIN_NODE_TYPES, BRAIN_EDGE_TYPES, brainPageNodes, brainPageEdges, brainRetrievalLog;
|
|
9080
|
+
var BRAIN_MEMORY_TIERS, BRAIN_COGNITIVE_TYPES, BRAIN_SOURCE_CONFIDENCE, BRAIN_DECISION_TYPES, BRAIN_CONFIDENCE_LEVELS, BRAIN_OUTCOME_TYPES, BRAIN_PATTERN_TYPES, BRAIN_IMPACT_LEVELS, BRAIN_LINK_TYPES, BRAIN_OBSERVATION_TYPES2, BRAIN_OBSERVATION_SOURCE_TYPES, BRAIN_MEMORY_TYPES, BRAIN_STICKY_STATUSES, BRAIN_STICKY_COLORS, BRAIN_STICKY_PRIORITIES, brainDecisions, brainPatterns, brainLearnings, brainObservations, brainStickyNotes, brainMemoryLinks, brainSchemaMeta, BRAIN_NODE_TYPES, BRAIN_EDGE_TYPES, brainPageNodes, brainPageEdges, brainRetrievalLog, brainPlasticityEvents;
|
|
9080
9081
|
var init_brain_schema = __esm({
|
|
9081
9082
|
"packages/core/src/store/brain-schema.ts"() {
|
|
9082
9083
|
"use strict";
|
|
@@ -9505,8 +9506,11 @@ var init_brain_schema = __esm({
|
|
|
9505
9506
|
// Graph bridging (memory ↔ code)
|
|
9506
9507
|
"references",
|
|
9507
9508
|
// observation → references → symbol
|
|
9508
|
-
"modified_by"
|
|
9509
|
+
"modified_by",
|
|
9509
9510
|
// file → modified_by → session
|
|
9511
|
+
// Plasticity (Hebbian + STDP co-retrieval)
|
|
9512
|
+
"co_retrieved"
|
|
9513
|
+
// A → co_retrieved → B (Hebbian: frequently retrieved together)
|
|
9510
9514
|
];
|
|
9511
9515
|
brainPageNodes = sqliteTable(
|
|
9512
9516
|
"brain_page_nodes",
|
|
@@ -9603,6 +9607,37 @@ var init_brain_schema = __esm({
|
|
|
9603
9607
|
index("idx_retrieval_log_source").on(table.source)
|
|
9604
9608
|
]
|
|
9605
9609
|
);
|
|
9610
|
+
brainPlasticityEvents = sqliteTable(
|
|
9611
|
+
"brain_plasticity_events",
|
|
9612
|
+
{
|
|
9613
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
9614
|
+
/** from_id of the affected brain_page_edges row. */
|
|
9615
|
+
sourceNode: text("source_node").notNull(),
|
|
9616
|
+
/** to_id of the affected brain_page_edges row. */
|
|
9617
|
+
targetNode: text("target_node").notNull(),
|
|
9618
|
+
/**
|
|
9619
|
+
* Signed weight delta applied to the edge.
|
|
9620
|
+
* Positive = potentiation (LTP), negative = depression (LTD).
|
|
9621
|
+
*/
|
|
9622
|
+
deltaW: real("delta_w").notNull(),
|
|
9623
|
+
/**
|
|
9624
|
+
* STDP event kind: `ltp` (Long-Term Potentiation) or `ltd` (Long-Term
|
|
9625
|
+
* Depression).
|
|
9626
|
+
*/
|
|
9627
|
+
kind: text("kind", { enum: ["ltp", "ltd"] }).notNull(),
|
|
9628
|
+
/** ISO 8601 timestamp when this event was applied. */
|
|
9629
|
+
timestamp: text("timestamp").notNull().default(sql2`(datetime('now'))`),
|
|
9630
|
+
/** Session ID that triggered the STDP pass, if available. */
|
|
9631
|
+
sessionId: text("session_id")
|
|
9632
|
+
},
|
|
9633
|
+
(table) => [
|
|
9634
|
+
index("idx_plasticity_source").on(table.sourceNode),
|
|
9635
|
+
index("idx_plasticity_target").on(table.targetNode),
|
|
9636
|
+
index("idx_plasticity_timestamp").on(table.timestamp),
|
|
9637
|
+
index("idx_plasticity_session").on(table.sessionId),
|
|
9638
|
+
index("idx_plasticity_kind").on(table.kind)
|
|
9639
|
+
]
|
|
9640
|
+
);
|
|
9606
9641
|
}
|
|
9607
9642
|
});
|
|
9608
9643
|
|
|
@@ -15014,6 +15049,14 @@ function runBrainMigrations(nativeDb, db) {
|
|
|
15014
15049
|
);
|
|
15015
15050
|
}
|
|
15016
15051
|
ensureColumns(nativeDb, "brain_observations", [{ name: "agent", ddl: "text" }], "brain");
|
|
15052
|
+
if (tableExists(nativeDb, "brain_page_edges")) {
|
|
15053
|
+
nativeDb.prepare(
|
|
15054
|
+
`UPDATE brain_page_edges
|
|
15055
|
+
SET edge_type = 'co_retrieved'
|
|
15056
|
+
WHERE edge_type = 'relates_to'
|
|
15057
|
+
AND provenance LIKE 'consolidation:%'`
|
|
15058
|
+
).run();
|
|
15059
|
+
}
|
|
15017
15060
|
}
|
|
15018
15061
|
function loadBrainVecExtension(nativeDb) {
|
|
15019
15062
|
try {
|
|
@@ -24415,6 +24458,160 @@ var init_anthropic_key_resolver = __esm({
|
|
|
24415
24458
|
}
|
|
24416
24459
|
});
|
|
24417
24460
|
|
|
24461
|
+
// packages/core/src/memory/decision-cross-link.ts
|
|
24462
|
+
function extractReferencedSymbols(text3) {
|
|
24463
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24464
|
+
const refs = [];
|
|
24465
|
+
for (const match of text3.matchAll(FILE_PATH_RE)) {
|
|
24466
|
+
const raw = match[1];
|
|
24467
|
+
if (!raw) continue;
|
|
24468
|
+
const nodeId = `file:${raw}`;
|
|
24469
|
+
if (seen.has(nodeId)) continue;
|
|
24470
|
+
seen.add(nodeId);
|
|
24471
|
+
refs.push({ raw, nodeId, nodeType: "file", label: raw });
|
|
24472
|
+
}
|
|
24473
|
+
for (const match of text3.matchAll(SYMBOL_RE)) {
|
|
24474
|
+
const raw = match[0];
|
|
24475
|
+
if (!raw || raw.length < 4) continue;
|
|
24476
|
+
if (SYMBOL_STOP_WORDS.has(raw.toLowerCase())) continue;
|
|
24477
|
+
const nodeId = `symbol:${raw}`;
|
|
24478
|
+
if (seen.has(nodeId)) continue;
|
|
24479
|
+
seen.add(nodeId);
|
|
24480
|
+
refs.push({ raw, nodeId, nodeType: "symbol", label: raw });
|
|
24481
|
+
}
|
|
24482
|
+
return refs;
|
|
24483
|
+
}
|
|
24484
|
+
async function linkDecisionToTargets(projectRoot, decisionId, refs) {
|
|
24485
|
+
const fromId = `decision:${decisionId}`;
|
|
24486
|
+
const writes = refs.map(async (ref) => {
|
|
24487
|
+
await upsertGraphNode(
|
|
24488
|
+
projectRoot,
|
|
24489
|
+
ref.nodeId,
|
|
24490
|
+
ref.nodeType,
|
|
24491
|
+
ref.label,
|
|
24492
|
+
0.5,
|
|
24493
|
+
// placeholder quality until nexus indexes it
|
|
24494
|
+
ref.raw
|
|
24495
|
+
);
|
|
24496
|
+
await addGraphEdge(
|
|
24497
|
+
projectRoot,
|
|
24498
|
+
fromId,
|
|
24499
|
+
ref.nodeId,
|
|
24500
|
+
"applies_to",
|
|
24501
|
+
1,
|
|
24502
|
+
"auto:decision-cross-link"
|
|
24503
|
+
);
|
|
24504
|
+
});
|
|
24505
|
+
await Promise.allSettled(writes);
|
|
24506
|
+
}
|
|
24507
|
+
async function autoCrossLinkDecision(projectRoot, decisionId, decisionText, rationale) {
|
|
24508
|
+
try {
|
|
24509
|
+
const combined = `${decisionText} ${rationale}`;
|
|
24510
|
+
const refs = extractReferencedSymbols(combined);
|
|
24511
|
+
if (refs.length === 0) return;
|
|
24512
|
+
await linkDecisionToTargets(projectRoot, decisionId, refs);
|
|
24513
|
+
} catch {
|
|
24514
|
+
}
|
|
24515
|
+
}
|
|
24516
|
+
var FILE_PATH_RE, SYMBOL_RE, SYMBOL_STOP_WORDS;
|
|
24517
|
+
var init_decision_cross_link = __esm({
|
|
24518
|
+
"packages/core/src/memory/decision-cross-link.ts"() {
|
|
24519
|
+
"use strict";
|
|
24520
|
+
init_graph_auto_populate();
|
|
24521
|
+
FILE_PATH_RE = /(?:^|[\s`"'([\]{,])((\/[\w.\-/]+|[\w.-]+(?:\/[\w.-]+)+)\.(ts|tsx|js|jsx|rs|json))(?=$|[\s`"')[\]{,])/gm;
|
|
24522
|
+
SYMBOL_RE = /(?<![`"'/\w.])(?:[A-Z][a-zA-Z0-9]{2,}|[a-z][a-zA-Z0-9]*(?:[A-Z][a-zA-Z0-9]*)+|[a-z][a-z0-9]*(?:_[a-z][a-z0-9]*){2,})(?![`"'/\w])/g;
|
|
24523
|
+
SYMBOL_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
24524
|
+
"this",
|
|
24525
|
+
"that",
|
|
24526
|
+
"with",
|
|
24527
|
+
"from",
|
|
24528
|
+
"into",
|
|
24529
|
+
"when",
|
|
24530
|
+
"then",
|
|
24531
|
+
"also",
|
|
24532
|
+
"both",
|
|
24533
|
+
"each",
|
|
24534
|
+
"such",
|
|
24535
|
+
"over",
|
|
24536
|
+
"after",
|
|
24537
|
+
"before",
|
|
24538
|
+
"always",
|
|
24539
|
+
"never",
|
|
24540
|
+
"should",
|
|
24541
|
+
"must",
|
|
24542
|
+
"will",
|
|
24543
|
+
"would",
|
|
24544
|
+
"could",
|
|
24545
|
+
"have",
|
|
24546
|
+
"been",
|
|
24547
|
+
"there",
|
|
24548
|
+
"their",
|
|
24549
|
+
"they",
|
|
24550
|
+
"them",
|
|
24551
|
+
"these",
|
|
24552
|
+
"those",
|
|
24553
|
+
"some",
|
|
24554
|
+
"only",
|
|
24555
|
+
"just",
|
|
24556
|
+
"more",
|
|
24557
|
+
"most",
|
|
24558
|
+
"many",
|
|
24559
|
+
"much",
|
|
24560
|
+
"well",
|
|
24561
|
+
"very",
|
|
24562
|
+
"here",
|
|
24563
|
+
"where",
|
|
24564
|
+
"which",
|
|
24565
|
+
"what",
|
|
24566
|
+
"why",
|
|
24567
|
+
"how",
|
|
24568
|
+
"the",
|
|
24569
|
+
"and",
|
|
24570
|
+
"but",
|
|
24571
|
+
"for",
|
|
24572
|
+
"not",
|
|
24573
|
+
"are",
|
|
24574
|
+
"was",
|
|
24575
|
+
"were",
|
|
24576
|
+
"has",
|
|
24577
|
+
"had",
|
|
24578
|
+
"its",
|
|
24579
|
+
"the",
|
|
24580
|
+
"data",
|
|
24581
|
+
"true",
|
|
24582
|
+
"false",
|
|
24583
|
+
"null",
|
|
24584
|
+
"none",
|
|
24585
|
+
"type",
|
|
24586
|
+
"test",
|
|
24587
|
+
"spec",
|
|
24588
|
+
"todo",
|
|
24589
|
+
"fixme",
|
|
24590
|
+
"note",
|
|
24591
|
+
"example",
|
|
24592
|
+
"index",
|
|
24593
|
+
"config",
|
|
24594
|
+
"error",
|
|
24595
|
+
"value",
|
|
24596
|
+
"input",
|
|
24597
|
+
"output",
|
|
24598
|
+
"result",
|
|
24599
|
+
"return",
|
|
24600
|
+
"default",
|
|
24601
|
+
"source",
|
|
24602
|
+
"target",
|
|
24603
|
+
"import",
|
|
24604
|
+
"export",
|
|
24605
|
+
"class",
|
|
24606
|
+
"interface",
|
|
24607
|
+
"function",
|
|
24608
|
+
"const",
|
|
24609
|
+
"async",
|
|
24610
|
+
"await"
|
|
24611
|
+
]);
|
|
24612
|
+
}
|
|
24613
|
+
});
|
|
24614
|
+
|
|
24418
24615
|
// packages/core/src/memory/decisions.ts
|
|
24419
24616
|
var decisions_exports = {};
|
|
24420
24617
|
__export(decisions_exports, {
|
|
@@ -24553,6 +24750,8 @@ async function storeDecision(projectRoot, params) {
|
|
|
24553
24750
|
"auto:store-decision"
|
|
24554
24751
|
);
|
|
24555
24752
|
}
|
|
24753
|
+
autoCrossLinkDecision(projectRoot, saved.id, saved.decision, saved.rationale).catch(() => {
|
|
24754
|
+
});
|
|
24556
24755
|
} catch {
|
|
24557
24756
|
}
|
|
24558
24757
|
detectSupersession(projectRoot, {
|
|
@@ -24621,6 +24820,7 @@ var init_decisions2 = __esm({
|
|
|
24621
24820
|
init_brain_accessor();
|
|
24622
24821
|
init_cross_db_cleanup();
|
|
24623
24822
|
init_sqlite2();
|
|
24823
|
+
init_decision_cross_link();
|
|
24624
24824
|
init_graph_auto_populate();
|
|
24625
24825
|
init_quality_scoring();
|
|
24626
24826
|
init_temporal_supersession();
|
|
@@ -45691,6 +45891,30 @@ var init_auto_extract = __esm({
|
|
|
45691
45891
|
}
|
|
45692
45892
|
});
|
|
45693
45893
|
|
|
45894
|
+
// packages/core/src/memory/edge-types.ts
|
|
45895
|
+
var EDGE_TYPES;
|
|
45896
|
+
var init_edge_types = __esm({
|
|
45897
|
+
"packages/core/src/memory/edge-types.ts"() {
|
|
45898
|
+
"use strict";
|
|
45899
|
+
EDGE_TYPES = {
|
|
45900
|
+
// Plasticity (Hebbian / STDP co-retrieval)
|
|
45901
|
+
CO_RETRIEVED: "co_retrieved",
|
|
45902
|
+
// Temporal supersession
|
|
45903
|
+
SUPERSEDES: "supersedes",
|
|
45904
|
+
// Task / decision / pattern → target context
|
|
45905
|
+
APPLIES_TO: "applies_to",
|
|
45906
|
+
// Provenance
|
|
45907
|
+
DERIVED_FROM: "derived_from",
|
|
45908
|
+
// Observation → symbol/file impact
|
|
45909
|
+
AFFECTS: "affects",
|
|
45910
|
+
// Observation → symbol name mention
|
|
45911
|
+
MENTIONS: "mentions",
|
|
45912
|
+
// Observation → symbol/file structural link
|
|
45913
|
+
DOCUMENTS: "documents"
|
|
45914
|
+
};
|
|
45915
|
+
}
|
|
45916
|
+
});
|
|
45917
|
+
|
|
45694
45918
|
// packages/core/src/memory/brain-consolidator.ts
|
|
45695
45919
|
var brain_consolidator_exports = {};
|
|
45696
45920
|
__export(brain_consolidator_exports, {
|
|
@@ -45924,7 +46148,7 @@ function extractSymbolCandidates(text3) {
|
|
|
45924
46148
|
const syms = /* @__PURE__ */ new Set();
|
|
45925
46149
|
for (const m2 of text3.matchAll(SYMBOL_PATTERN)) {
|
|
45926
46150
|
const s3 = m2[1];
|
|
45927
|
-
if (s3 && s3.length >= 4 && !
|
|
46151
|
+
if (s3 && s3.length >= 4 && !SYMBOL_STOP_WORDS2.has(s3.toLowerCase())) {
|
|
45928
46152
|
syms.add(s3);
|
|
45929
46153
|
}
|
|
45930
46154
|
}
|
|
@@ -46233,7 +46457,7 @@ async function listCodeLinks(projectRoot, limit = 100) {
|
|
|
46233
46457
|
}
|
|
46234
46458
|
return entries;
|
|
46235
46459
|
}
|
|
46236
|
-
var FILE_PATH_PATTERN, SYMBOL_PATTERN,
|
|
46460
|
+
var FILE_PATH_PATTERN, SYMBOL_PATTERN, SYMBOL_STOP_WORDS2;
|
|
46237
46461
|
var init_graph_memory_bridge = __esm({
|
|
46238
46462
|
"packages/core/src/memory/graph-memory-bridge.ts"() {
|
|
46239
46463
|
"use strict";
|
|
@@ -46243,7 +46467,7 @@ var init_graph_memory_bridge = __esm({
|
|
|
46243
46467
|
init_typed_query();
|
|
46244
46468
|
FILE_PATH_PATTERN = /(?:^|\s|['"`(])([a-zA-Z0-9_\-./]+\.(?:ts|tsx|js|jsx|rs|go|py|mjs|cjs))(?:$|\s|['"`)])/g;
|
|
46245
46469
|
SYMBOL_PATTERN = /\b([a-zA-Z_][a-zA-Z0-9_]*(?:[A-Z][a-zA-Z0-9_]*)+|[a-zA-Z_]{4,}[a-zA-Z0-9_]*)\b/g;
|
|
46246
|
-
|
|
46470
|
+
SYMBOL_STOP_WORDS2 = /* @__PURE__ */ new Set([
|
|
46247
46471
|
"true",
|
|
46248
46472
|
"false",
|
|
46249
46473
|
"null",
|
|
@@ -46287,6 +46511,207 @@ var init_graph_memory_bridge = __esm({
|
|
|
46287
46511
|
}
|
|
46288
46512
|
});
|
|
46289
46513
|
|
|
46514
|
+
// packages/core/src/memory/brain-stdp.ts
|
|
46515
|
+
var brain_stdp_exports = {};
|
|
46516
|
+
__export(brain_stdp_exports, {
|
|
46517
|
+
applyStdpPlasticity: () => applyStdpPlasticity,
|
|
46518
|
+
getPlasticityStats: () => getPlasticityStats
|
|
46519
|
+
});
|
|
46520
|
+
async function applyStdpPlasticity(projectRoot, sessionWindowMs = 5 * 60 * 1e3) {
|
|
46521
|
+
const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
|
|
46522
|
+
await getBrainDb2(projectRoot);
|
|
46523
|
+
const nativeDb = getBrainNativeDb2();
|
|
46524
|
+
const result = {
|
|
46525
|
+
ltpEvents: 0,
|
|
46526
|
+
ltdEvents: 0,
|
|
46527
|
+
edgesCreated: 0,
|
|
46528
|
+
pairsExamined: 0
|
|
46529
|
+
};
|
|
46530
|
+
if (!nativeDb) return result;
|
|
46531
|
+
try {
|
|
46532
|
+
nativeDb.prepare("SELECT 1 FROM brain_retrieval_log LIMIT 1").get();
|
|
46533
|
+
} catch {
|
|
46534
|
+
return result;
|
|
46535
|
+
}
|
|
46536
|
+
try {
|
|
46537
|
+
nativeDb.prepare("SELECT 1 FROM brain_plasticity_events LIMIT 1").get();
|
|
46538
|
+
} catch {
|
|
46539
|
+
return result;
|
|
46540
|
+
}
|
|
46541
|
+
const now2 = Date.now();
|
|
46542
|
+
const cutoffMs = now2 - sessionWindowMs;
|
|
46543
|
+
const cutoffIso = new Date(cutoffMs).toISOString().replace("T", " ").slice(0, 19);
|
|
46544
|
+
const nowIso = new Date(now2).toISOString().replace("T", " ").slice(0, 19);
|
|
46545
|
+
let logRows = [];
|
|
46546
|
+
try {
|
|
46547
|
+
logRows = typedAll(
|
|
46548
|
+
nativeDb.prepare(
|
|
46549
|
+
`SELECT id, entry_ids, created_at, retrieval_order, delta_ms
|
|
46550
|
+
FROM brain_retrieval_log
|
|
46551
|
+
WHERE created_at >= ?
|
|
46552
|
+
ORDER BY created_at ASC, id ASC
|
|
46553
|
+
LIMIT 2000`
|
|
46554
|
+
),
|
|
46555
|
+
cutoffIso
|
|
46556
|
+
);
|
|
46557
|
+
} catch {
|
|
46558
|
+
return result;
|
|
46559
|
+
}
|
|
46560
|
+
if (logRows.length === 0) return result;
|
|
46561
|
+
const spikes = [];
|
|
46562
|
+
let globalOrder = 0;
|
|
46563
|
+
for (const row of logRows) {
|
|
46564
|
+
let ids;
|
|
46565
|
+
try {
|
|
46566
|
+
ids = JSON.parse(row.entry_ids);
|
|
46567
|
+
} catch {
|
|
46568
|
+
continue;
|
|
46569
|
+
}
|
|
46570
|
+
const rowTime = (/* @__PURE__ */ new Date(row.created_at.replace(" ", "T") + "Z")).getTime();
|
|
46571
|
+
for (const rawId of ids) {
|
|
46572
|
+
const entryId = rawId.includes(":") ? rawId : `observation:${rawId}`;
|
|
46573
|
+
spikes.push({
|
|
46574
|
+
entryId,
|
|
46575
|
+
rowId: row.id,
|
|
46576
|
+
retrievedAt: rowTime,
|
|
46577
|
+
order: row.retrieval_order ?? globalOrder
|
|
46578
|
+
});
|
|
46579
|
+
globalOrder++;
|
|
46580
|
+
}
|
|
46581
|
+
}
|
|
46582
|
+
spikes.sort((a, b2) => a.retrievedAt - b2.retrievedAt || a.order - b2.order);
|
|
46583
|
+
const prepareGetEdge = nativeDb.prepare(
|
|
46584
|
+
`SELECT weight FROM brain_page_edges
|
|
46585
|
+
WHERE from_id = ? AND to_id = ? AND edge_type = 'co_retrieved'`
|
|
46586
|
+
);
|
|
46587
|
+
const prepareUpdateEdge = nativeDb.prepare(
|
|
46588
|
+
`UPDATE brain_page_edges
|
|
46589
|
+
SET weight = MAX(?, MIN(?, weight + ?))
|
|
46590
|
+
WHERE from_id = ? AND to_id = ? AND edge_type = 'co_retrieved'`
|
|
46591
|
+
);
|
|
46592
|
+
const prepareInsertEdge = nativeDb.prepare(
|
|
46593
|
+
`INSERT OR IGNORE INTO brain_page_edges
|
|
46594
|
+
(from_id, to_id, edge_type, weight, provenance, created_at)
|
|
46595
|
+
VALUES (?, ?, 'co_retrieved', ?, 'plasticity:stdp-ltp', ?)`
|
|
46596
|
+
);
|
|
46597
|
+
const prepareLogEvent = nativeDb.prepare(
|
|
46598
|
+
`INSERT INTO brain_plasticity_events
|
|
46599
|
+
(source_node, target_node, delta_w, kind, timestamp)
|
|
46600
|
+
VALUES (?, ?, ?, ?, ?)`
|
|
46601
|
+
);
|
|
46602
|
+
for (let i = 0; i < spikes.length; i++) {
|
|
46603
|
+
const spikeA = spikes[i];
|
|
46604
|
+
for (let j2 = i + 1; j2 < spikes.length; j2++) {
|
|
46605
|
+
const spikeB = spikes[j2];
|
|
46606
|
+
const deltaT = spikeB.retrievedAt - spikeA.retrievedAt;
|
|
46607
|
+
if (deltaT > sessionWindowMs) break;
|
|
46608
|
+
if (spikeA.entryId === spikeB.entryId) continue;
|
|
46609
|
+
result.pairsExamined++;
|
|
46610
|
+
const deltaW = A_PRE * Math.exp(-deltaT / TAU_PRE_MS);
|
|
46611
|
+
if (deltaW < 1e-6) continue;
|
|
46612
|
+
const existingEdge = prepareGetEdge.get(spikeA.entryId, spikeB.entryId);
|
|
46613
|
+
try {
|
|
46614
|
+
if (existingEdge !== void 0) {
|
|
46615
|
+
prepareUpdateEdge.run(WEIGHT_MIN, WEIGHT_MAX, deltaW, spikeA.entryId, spikeB.entryId);
|
|
46616
|
+
} else {
|
|
46617
|
+
const initialWeight = Math.min(WEIGHT_MAX, deltaW);
|
|
46618
|
+
prepareInsertEdge.run(spikeA.entryId, spikeB.entryId, initialWeight, nowIso);
|
|
46619
|
+
result.edgesCreated++;
|
|
46620
|
+
}
|
|
46621
|
+
prepareLogEvent.run(spikeA.entryId, spikeB.entryId, deltaW, "ltp", nowIso);
|
|
46622
|
+
result.ltpEvents++;
|
|
46623
|
+
} catch {
|
|
46624
|
+
}
|
|
46625
|
+
const deltaWNeg = -(A_POST * Math.exp(-deltaT / TAU_POST_MS));
|
|
46626
|
+
const existingReverseEdge = prepareGetEdge.get(spikeB.entryId, spikeA.entryId);
|
|
46627
|
+
if (existingReverseEdge !== void 0 && Math.abs(deltaWNeg) >= 1e-6) {
|
|
46628
|
+
try {
|
|
46629
|
+
prepareUpdateEdge.run(WEIGHT_MIN, WEIGHT_MAX, deltaWNeg, spikeB.entryId, spikeA.entryId);
|
|
46630
|
+
prepareLogEvent.run(spikeB.entryId, spikeA.entryId, deltaWNeg, "ltd", nowIso);
|
|
46631
|
+
result.ltdEvents++;
|
|
46632
|
+
} catch {
|
|
46633
|
+
}
|
|
46634
|
+
}
|
|
46635
|
+
}
|
|
46636
|
+
}
|
|
46637
|
+
return result;
|
|
46638
|
+
}
|
|
46639
|
+
async function getPlasticityStats(projectRoot, limit = 20) {
|
|
46640
|
+
const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
|
|
46641
|
+
await getBrainDb2(projectRoot);
|
|
46642
|
+
const nativeDb = getBrainNativeDb2();
|
|
46643
|
+
const empty = {
|
|
46644
|
+
totalEvents: 0,
|
|
46645
|
+
ltpCount: 0,
|
|
46646
|
+
ltdCount: 0,
|
|
46647
|
+
netDeltaW: 0,
|
|
46648
|
+
lastEventAt: null,
|
|
46649
|
+
recentEvents: []
|
|
46650
|
+
};
|
|
46651
|
+
if (!nativeDb) return empty;
|
|
46652
|
+
try {
|
|
46653
|
+
nativeDb.prepare("SELECT 1 FROM brain_plasticity_events LIMIT 1").get();
|
|
46654
|
+
} catch {
|
|
46655
|
+
return empty;
|
|
46656
|
+
}
|
|
46657
|
+
let agg;
|
|
46658
|
+
try {
|
|
46659
|
+
agg = nativeDb.prepare(
|
|
46660
|
+
`SELECT
|
|
46661
|
+
COUNT(*) AS total,
|
|
46662
|
+
SUM(CASE WHEN kind = 'ltp' THEN 1 ELSE 0 END) AS ltp_count,
|
|
46663
|
+
SUM(CASE WHEN kind = 'ltd' THEN 1 ELSE 0 END) AS ltd_count,
|
|
46664
|
+
SUM(delta_w) AS net_delta_w,
|
|
46665
|
+
MAX(timestamp) AS last_event_at
|
|
46666
|
+
FROM brain_plasticity_events`
|
|
46667
|
+
).get();
|
|
46668
|
+
} catch {
|
|
46669
|
+
return empty;
|
|
46670
|
+
}
|
|
46671
|
+
let recentRows = [];
|
|
46672
|
+
try {
|
|
46673
|
+
recentRows = typedAll(
|
|
46674
|
+
nativeDb.prepare(
|
|
46675
|
+
`SELECT id, source_node, target_node, delta_w, kind, timestamp, session_id
|
|
46676
|
+
FROM brain_plasticity_events
|
|
46677
|
+
ORDER BY timestamp DESC, id DESC
|
|
46678
|
+
LIMIT ?`
|
|
46679
|
+
),
|
|
46680
|
+
limit
|
|
46681
|
+
);
|
|
46682
|
+
} catch {
|
|
46683
|
+
}
|
|
46684
|
+
return {
|
|
46685
|
+
totalEvents: agg?.total ?? 0,
|
|
46686
|
+
ltpCount: agg?.ltp_count ?? 0,
|
|
46687
|
+
ltdCount: agg?.ltd_count ?? 0,
|
|
46688
|
+
netDeltaW: agg?.net_delta_w ?? 0,
|
|
46689
|
+
lastEventAt: agg?.last_event_at ?? null,
|
|
46690
|
+
recentEvents: recentRows.map((r) => ({
|
|
46691
|
+
id: r.id,
|
|
46692
|
+
sourceNode: r.source_node,
|
|
46693
|
+
targetNode: r.target_node,
|
|
46694
|
+
deltaW: r.delta_w,
|
|
46695
|
+
kind: r.kind,
|
|
46696
|
+
timestamp: r.timestamp,
|
|
46697
|
+
sessionId: r.session_id
|
|
46698
|
+
}))
|
|
46699
|
+
};
|
|
46700
|
+
}
|
|
46701
|
+
var TAU_PRE_MS, TAU_POST_MS, A_PRE, A_POST, WEIGHT_MIN, WEIGHT_MAX;
|
|
46702
|
+
var init_brain_stdp = __esm({
|
|
46703
|
+
"packages/core/src/memory/brain-stdp.ts"() {
|
|
46704
|
+
"use strict";
|
|
46705
|
+
init_typed_query();
|
|
46706
|
+
TAU_PRE_MS = 2e4;
|
|
46707
|
+
TAU_POST_MS = 2e4;
|
|
46708
|
+
A_PRE = 0.05;
|
|
46709
|
+
A_POST = 0.06;
|
|
46710
|
+
WEIGHT_MIN = 0;
|
|
46711
|
+
WEIGHT_MAX = 1;
|
|
46712
|
+
}
|
|
46713
|
+
});
|
|
46714
|
+
|
|
46290
46715
|
// packages/core/src/memory/brain-lifecycle.ts
|
|
46291
46716
|
var brain_lifecycle_exports = {};
|
|
46292
46717
|
__export(brain_lifecycle_exports, {
|
|
@@ -46592,6 +47017,13 @@ async function runConsolidation(projectRoot) {
|
|
|
46592
47017
|
} catch (err) {
|
|
46593
47018
|
console.warn("[consolidation] Step 8 graph memory bridge failed:", err);
|
|
46594
47019
|
}
|
|
47020
|
+
try {
|
|
47021
|
+
const { applyStdpPlasticity: applyStdpPlasticity2 } = await Promise.resolve().then(() => (init_brain_stdp(), brain_stdp_exports));
|
|
47022
|
+
const stdpResult = await applyStdpPlasticity2(projectRoot);
|
|
47023
|
+
result.stdpPlasticity = stdpResult;
|
|
47024
|
+
} catch (err) {
|
|
47025
|
+
console.warn("[consolidation] Step 9 STDP plasticity failed:", err);
|
|
47026
|
+
}
|
|
46595
47027
|
return result;
|
|
46596
47028
|
}
|
|
46597
47029
|
async function deduplicateByEmbedding(projectRoot) {
|
|
@@ -46753,16 +47185,16 @@ async function strengthenCoRetrievedEdges(projectRoot) {
|
|
|
46753
47185
|
const updateStmt = nativeDb.prepare(`
|
|
46754
47186
|
UPDATE brain_page_edges
|
|
46755
47187
|
SET weight = MIN(1.0, weight + 0.1)
|
|
46756
|
-
WHERE from_id = ? AND to_id = ? AND edge_type =
|
|
47188
|
+
WHERE from_id = ? AND to_id = ? AND edge_type = ?
|
|
46757
47189
|
`);
|
|
46758
|
-
const updateResult = updateStmt.run(nodeFrom, nodeTo);
|
|
47190
|
+
const updateResult = updateStmt.run(nodeFrom, nodeTo, EDGE_TYPES.CO_RETRIEVED);
|
|
46759
47191
|
const changes = typeof updateResult.changes === "number" ? updateResult.changes : 0;
|
|
46760
47192
|
if (changes === 0) {
|
|
46761
47193
|
nativeDb.prepare(`
|
|
46762
47194
|
INSERT OR IGNORE INTO brain_page_edges
|
|
46763
47195
|
(from_id, to_id, edge_type, weight, provenance, created_at)
|
|
46764
|
-
VALUES (?, ?,
|
|
46765
|
-
`).run(nodeFrom, nodeTo, now2);
|
|
47196
|
+
VALUES (?, ?, ?, 0.3, 'consolidation:co-retrieval', ?)
|
|
47197
|
+
`).run(nodeFrom, nodeTo, EDGE_TYPES.CO_RETRIEVED, now2);
|
|
46766
47198
|
}
|
|
46767
47199
|
strengthened++;
|
|
46768
47200
|
} catch {
|
|
@@ -46776,6 +47208,7 @@ var init_brain_lifecycle = __esm({
|
|
|
46776
47208
|
"use strict";
|
|
46777
47209
|
init_brain_accessor();
|
|
46778
47210
|
init_typed_query();
|
|
47211
|
+
init_edge_types();
|
|
46779
47212
|
STOP_WORDS3 = /* @__PURE__ */ new Set([
|
|
46780
47213
|
"the",
|
|
46781
47214
|
"a",
|
|
@@ -60729,6 +61162,7 @@ var init_extraction_gate = __esm({
|
|
|
60729
61162
|
// packages/core/src/memory/index.ts
|
|
60730
61163
|
var memory_exports = {};
|
|
60731
61164
|
__export(memory_exports, {
|
|
61165
|
+
EDGE_TYPES: () => EDGE_TYPES,
|
|
60732
61166
|
RRF_K: () => RRF_K,
|
|
60733
61167
|
addResearch: () => addResearch,
|
|
60734
61168
|
appendExtendedManifest: () => appendExtendedManifest,
|
|
@@ -61412,6 +61846,7 @@ var init_memory = __esm({
|
|
|
61412
61846
|
init_brain_retrieval();
|
|
61413
61847
|
init_brain_search();
|
|
61414
61848
|
init_decisions2();
|
|
61849
|
+
init_edge_types();
|
|
61415
61850
|
init_extraction_gate();
|
|
61416
61851
|
init_learnings();
|
|
61417
61852
|
init_patterns();
|
|
@@ -71602,6 +72037,7 @@ var init_remote = __esm({
|
|
|
71602
72037
|
// packages/core/src/research/index.ts
|
|
71603
72038
|
var research_exports = {};
|
|
71604
72039
|
__export(research_exports, {
|
|
72040
|
+
EDGE_TYPES: () => EDGE_TYPES,
|
|
71605
72041
|
RRF_K: () => RRF_K,
|
|
71606
72042
|
addResearch: () => addResearch,
|
|
71607
72043
|
appendExtendedManifest: () => appendExtendedManifest,
|
|
@@ -112790,6 +113226,7 @@ __export(internal_exports, {
|
|
|
112790
113226
|
analyzeDependencies: () => analyzeDependencies2,
|
|
112791
113227
|
analyzeEpic: () => analyzeEpic,
|
|
112792
113228
|
analyzeTaskImpact: () => analyzeTaskImpact,
|
|
113229
|
+
applyStdpPlasticity: () => applyStdpPlasticity,
|
|
112793
113230
|
applyStrictnessPreset: () => applyStrictnessPreset,
|
|
112794
113231
|
applyTemporalDecay: () => applyTemporalDecay,
|
|
112795
113232
|
archiveSessions: () => archiveSessions,
|
|
@@ -113117,6 +113554,7 @@ __export(internal_exports, {
|
|
|
113117
113554
|
getPackageRoot: () => getPackageRoot,
|
|
113118
113555
|
getParallelStatus: () => getParallelStatus,
|
|
113119
113556
|
getPipelineStageOrder: () => getPipelineStageOrder,
|
|
113557
|
+
getPlasticityStats: () => getPlasticityStats,
|
|
113120
113558
|
getProjectAgentRef: () => getProjectAgentRef2,
|
|
113121
113559
|
getProjectInfo: () => getProjectInfo,
|
|
113122
113560
|
getProjectInfoSync: () => getProjectInfoSync,
|
|
@@ -113583,6 +114021,7 @@ var init_internal = __esm({
|
|
|
113583
114021
|
init_brain_maintenance();
|
|
113584
114022
|
init_brain_purge();
|
|
113585
114023
|
init_brain_retrieval();
|
|
114024
|
+
init_brain_stdp();
|
|
113586
114025
|
init_claude_mem_migration();
|
|
113587
114026
|
init_engine_compat();
|
|
113588
114027
|
init_pipeline_manifest_sqlite();
|
|
@@ -135777,6 +136216,62 @@ function registerBrainCommand(program) {
|
|
|
135777
136216
|
process.exit(1);
|
|
135778
136217
|
}
|
|
135779
136218
|
});
|
|
136219
|
+
const plasticity = brain.command("plasticity").description("STDP timing-dependent plasticity operations (T626 phase 5)");
|
|
136220
|
+
plasticity.command("stats").description(
|
|
136221
|
+
"Show recent STDP plasticity events: LTP/LTD counts, net weight delta, and most recent events."
|
|
136222
|
+
).option("--limit <n>", "Maximum recent events to show (default 20)", "20").option("--json", "Output results as JSON").action(async (opts) => {
|
|
136223
|
+
const root = getProjectRoot();
|
|
136224
|
+
const isJson = !!opts.json;
|
|
136225
|
+
const limit = Number(opts.limit ?? "20") || 20;
|
|
136226
|
+
try {
|
|
136227
|
+
const stats2 = await getPlasticityStats(root, limit);
|
|
136228
|
+
if (isJson) {
|
|
136229
|
+
console.log(
|
|
136230
|
+
JSON.stringify(
|
|
136231
|
+
{
|
|
136232
|
+
success: true,
|
|
136233
|
+
data: stats2,
|
|
136234
|
+
meta: { operation: "brain.plasticity.stats", timestamp: (/* @__PURE__ */ new Date()).toISOString() }
|
|
136235
|
+
},
|
|
136236
|
+
null,
|
|
136237
|
+
2
|
|
136238
|
+
)
|
|
136239
|
+
);
|
|
136240
|
+
return;
|
|
136241
|
+
}
|
|
136242
|
+
console.log("\nBrain Plasticity Stats (STDP)");
|
|
136243
|
+
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");
|
|
136244
|
+
console.log(` Total events: ${stats2.totalEvents}`);
|
|
136245
|
+
console.log(` LTP (potentiation): ${stats2.ltpCount}`);
|
|
136246
|
+
console.log(` LTD (depression): ${stats2.ltdCount}`);
|
|
136247
|
+
const sign = stats2.netDeltaW >= 0 ? "+" : "";
|
|
136248
|
+
console.log(` Net \u0394w: ${sign}${stats2.netDeltaW.toFixed(4)}`);
|
|
136249
|
+
console.log(` Last event: ${stats2.lastEventAt ?? "(none)"}`);
|
|
136250
|
+
if (stats2.recentEvents.length > 0) {
|
|
136251
|
+
console.log(`
|
|
136252
|
+
Recent Events (newest first, limit=${limit})`);
|
|
136253
|
+
for (const ev of stats2.recentEvents) {
|
|
136254
|
+
const evSign = ev.deltaW >= 0 ? "+" : "";
|
|
136255
|
+
const src = ev.sourceNode.slice(0, 30).padEnd(30);
|
|
136256
|
+
const tgt = ev.targetNode.slice(0, 30).padEnd(30);
|
|
136257
|
+
console.log(
|
|
136258
|
+
` [${ev.kind.toUpperCase()}] ${src} \u2192 ${tgt} \u0394w=${evSign}${ev.deltaW.toFixed(4)} ${ev.timestamp}`
|
|
136259
|
+
);
|
|
136260
|
+
}
|
|
136261
|
+
} else {
|
|
136262
|
+
console.log("\n No plasticity events recorded yet.");
|
|
136263
|
+
console.log(" Run `cleo brain maintenance` or `cleo session end` to trigger STDP.");
|
|
136264
|
+
}
|
|
136265
|
+
} catch (err) {
|
|
136266
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
136267
|
+
if (isJson) {
|
|
136268
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
136269
|
+
} else {
|
|
136270
|
+
console.error(`Brain plasticity stats failed: ${message}`);
|
|
136271
|
+
}
|
|
136272
|
+
process.exit(1);
|
|
136273
|
+
}
|
|
136274
|
+
});
|
|
135780
136275
|
brain.command("quality").description(
|
|
135781
136276
|
"Show memory quality metrics: retrieval rates, top/never-retrieved entries, quality distribution, and noise ratio."
|
|
135782
136277
|
).option("--json", "Output results as JSON").action(async (opts) => {
|