@cleocode/brain 2026.6.14 → 2026.6.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/src/adapters/agent-registry.d.ts +35 -0
  2. package/dist/src/adapters/agent-registry.d.ts.map +1 -0
  3. package/dist/src/adapters/agent-registry.js +96 -0
  4. package/dist/src/adapters/agent-registry.js.map +1 -0
  5. package/dist/src/adapters/brain.d.ts +35 -0
  6. package/dist/src/adapters/brain.d.ts.map +1 -0
  7. package/dist/src/adapters/brain.js +303 -0
  8. package/dist/src/adapters/brain.js.map +1 -0
  9. package/dist/src/adapters/conduit.d.ts +25 -0
  10. package/dist/src/adapters/conduit.d.ts.map +1 -0
  11. package/dist/src/adapters/conduit.js +94 -0
  12. package/dist/src/adapters/conduit.js.map +1 -0
  13. package/dist/src/adapters/index.d.ts +32 -0
  14. package/dist/src/adapters/index.d.ts.map +1 -0
  15. package/dist/src/adapters/index.js +194 -0
  16. package/dist/src/adapters/index.js.map +1 -0
  17. package/dist/src/adapters/nexus.d.ts +24 -0
  18. package/dist/src/adapters/nexus.d.ts.map +1 -0
  19. package/dist/src/adapters/nexus.js +83 -0
  20. package/dist/src/adapters/nexus.js.map +1 -0
  21. package/dist/src/adapters/tasks.d.ts +23 -0
  22. package/dist/src/adapters/tasks.d.ts.map +1 -0
  23. package/dist/src/adapters/tasks.js +143 -0
  24. package/dist/src/adapters/tasks.js.map +1 -0
  25. package/dist/src/cleo-home.d.ts +47 -0
  26. package/dist/src/cleo-home.d.ts.map +1 -0
  27. package/dist/src/cleo-home.js +73 -0
  28. package/dist/src/cleo-home.js.map +1 -0
  29. package/dist/src/db-connections.d.ts +143 -0
  30. package/dist/src/db-connections.d.ts.map +1 -0
  31. package/dist/src/db-connections.js +215 -0
  32. package/dist/src/db-connections.js.map +1 -0
  33. package/dist/src/index.d.ts +26 -0
  34. package/dist/src/index.d.ts.map +1 -0
  35. package/dist/src/index.js +29 -0
  36. package/dist/src/index.js.map +1 -0
  37. package/dist/src/project-context.d.ts +47 -0
  38. package/dist/src/project-context.d.ts.map +1 -0
  39. package/dist/src/project-context.js +52 -0
  40. package/dist/src/project-context.js.map +1 -0
  41. package/dist/src/types.d.ts +22 -0
  42. package/dist/src/types.d.ts.map +1 -0
  43. package/dist/src/types.js +22 -0
  44. package/dist/src/types.js.map +1 -0
  45. package/dist/tsconfig.build.tsbuildinfo +1 -0
  46. package/package.json +4 -4
@@ -0,0 +1,35 @@
1
+ /**
2
+ * AGENT-REGISTRY substrate adapter for the Living Brain API.
3
+ *
4
+ * Read-only visualization path. Queries the LEGACY standalone `signaldock.db`
5
+ * (resolved by `getAgentRegistryDbPath`) and returns BrainNodes/BrainEdges for
6
+ * agents and agent-to-agent social connections. The legacy standalone file still
7
+ * carries the BARE table names (`agents`, `agent_connections`); the brain-package
8
+ * read path is migrated to the consolidated `cleo.db` separately in E6 (T11249),
9
+ * so the SQL below intentionally still targets the bare names.
10
+ *
11
+ * The substrate identifier + node-id prefix were renamed `signaldock` →
12
+ * `agent-registry` under T11622 (display identifiers, decoupled from the physical
13
+ * table names).
14
+ *
15
+ * Node IDs are prefixed with "agent-registry:" to prevent collisions.
16
+ * Agents are the cross-substrate identity bridge — they appear in TASKS
17
+ * (assignee), CONDUIT (from/to), and BRAIN (source agent).
18
+ *
19
+ * @task T11622 (Signaldock → Agent Registry rename; folds T11578 AC2)
20
+ */
21
+ import type { BrainEdge, BrainNode, BrainQueryOptions } from '../types.js';
22
+ /**
23
+ * Returns all BrainNodes and BrainEdges sourced from the Agent Registry.
24
+ *
25
+ * Fetches all active agents plus their declared connections.
26
+ * Agent nodes serve as the cross-substrate identity anchors.
27
+ *
28
+ * @param options - Query options (limit).
29
+ * @returns Nodes and edges from the AGENT-REGISTRY substrate.
30
+ */
31
+ export declare function getAgentRegistrySubstrate(options?: BrainQueryOptions): {
32
+ nodes: BrainNode[];
33
+ edges: BrainEdge[];
34
+ };
35
+ //# sourceMappingURL=agent-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-registry.d.ts","sourceRoot":"","sources":["../../../src/adapters/agent-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AA+B3E;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,iBAAsB,GAAG;IAC1E,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB,CAoEA"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * AGENT-REGISTRY substrate adapter for the Living Brain API.
3
+ *
4
+ * Read-only visualization path. Queries the LEGACY standalone `signaldock.db`
5
+ * (resolved by `getAgentRegistryDbPath`) and returns BrainNodes/BrainEdges for
6
+ * agents and agent-to-agent social connections. The legacy standalone file still
7
+ * carries the BARE table names (`agents`, `agent_connections`); the brain-package
8
+ * read path is migrated to the consolidated `cleo.db` separately in E6 (T11249),
9
+ * so the SQL below intentionally still targets the bare names.
10
+ *
11
+ * The substrate identifier + node-id prefix were renamed `signaldock` →
12
+ * `agent-registry` under T11622 (display identifiers, decoupled from the physical
13
+ * table names).
14
+ *
15
+ * Node IDs are prefixed with "agent-registry:" to prevent collisions.
16
+ * Agents are the cross-substrate identity bridge — they appear in TASKS
17
+ * (assignee), CONDUIT (from/to), and BRAIN (source agent).
18
+ *
19
+ * @task T11622 (Signaldock → Agent Registry rename; folds T11578 AC2)
20
+ */
21
+ import { allTyped, getAgentRegistryDb } from '../db-connections.js';
22
+ /**
23
+ * Converts a UNIX epoch seconds value to an ISO-8601 string.
24
+ * Returns null when the value is not a finite positive number.
25
+ *
26
+ * @param epoch - UNIX timestamp in seconds, or null.
27
+ * @returns ISO-8601 string or null.
28
+ */
29
+ function epochToIso(epoch) {
30
+ if (epoch === null || !Number.isFinite(epoch) || epoch <= 0)
31
+ return null;
32
+ return new Date(epoch * 1000).toISOString();
33
+ }
34
+ /**
35
+ * Returns all BrainNodes and BrainEdges sourced from the Agent Registry.
36
+ *
37
+ * Fetches all active agents plus their declared connections.
38
+ * Agent nodes serve as the cross-substrate identity anchors.
39
+ *
40
+ * @param options - Query options (limit).
41
+ * @returns Nodes and edges from the AGENT-REGISTRY substrate.
42
+ */
43
+ export function getAgentRegistrySubstrate(options = {}) {
44
+ const db = getAgentRegistryDb();
45
+ if (!db)
46
+ return { nodes: [], edges: [] };
47
+ const perSubstrateLimit = Math.ceil((options.limit ?? 500) / 5);
48
+ const nodes = [];
49
+ const edges = [];
50
+ try {
51
+ // Active agents (legacy standalone signaldock.db bare table)
52
+ const agentRows = allTyped(db.prepare(`SELECT agent_id, name, status, created_at
53
+ FROM agents
54
+ WHERE status != 'deleted'
55
+ ORDER BY created_at DESC
56
+ LIMIT ?`), perSubstrateLimit);
57
+ const agentIds = new Set();
58
+ for (const row of agentRows) {
59
+ agentIds.add(row.agent_id);
60
+ nodes.push({
61
+ id: `agent-registry:${row.agent_id}`,
62
+ kind: 'agent',
63
+ substrate: 'agent-registry',
64
+ label: row.name,
65
+ weight: row.status === 'active' ? 1.0 : 0.5,
66
+ createdAt: epochToIso(row.created_at),
67
+ meta: {
68
+ status: row.status,
69
+ created_at: row.created_at,
70
+ },
71
+ });
72
+ }
73
+ // Agent connections (declared social graph)
74
+ if (agentIds.size > 0) {
75
+ const placeholders = [...agentIds].map(() => '?').join(',');
76
+ const connRows = allTyped(db.prepare(`SELECT from_agent_id, to_agent_id, connection_type, strength
77
+ FROM agent_connections
78
+ WHERE from_agent_id IN (${placeholders})
79
+ AND to_agent_id IN (${placeholders})`), ...agentIds, ...agentIds);
80
+ for (const row of connRows) {
81
+ edges.push({
82
+ source: `agent-registry:${row.from_agent_id}`,
83
+ target: `agent-registry:${row.to_agent_id}`,
84
+ type: row.connection_type,
85
+ weight: row.strength ?? 0.5,
86
+ substrate: 'agent-registry',
87
+ });
88
+ }
89
+ }
90
+ }
91
+ catch {
92
+ // Return partial results on error
93
+ }
94
+ return { nodes, edges };
95
+ }
96
+ //# sourceMappingURL=agent-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../../../src/adapters/agent-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAYpE;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,KAAoB;IACtC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACzE,OAAO,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;AAC9C,CAAC;AAUD;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,UAA6B,EAAE;IAIvE,MAAM,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAEzC,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAEhE,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,6DAA6D;QAC7D,MAAM,SAAS,GAAG,QAAQ,CACxB,EAAE,CAAC,OAAO,CACR;;;;iBAIS,CACV,EACD,iBAAiB,CAClB,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QACnC,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC5B,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,kBAAkB,GAAG,CAAC,QAAQ,EAAE;gBACpC,IAAI,EAAE,OAAO;gBACb,SAAS,EAAE,gBAAgB;gBAC3B,KAAK,EAAE,GAAG,CAAC,IAAI;gBACf,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;gBAC3C,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC;gBACrC,IAAI,EAAE;oBACJ,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,UAAU,EAAE,GAAG,CAAC,UAAU;iBAC3B;aACF,CAAC,CAAC;QACL,CAAC;QAED,4CAA4C;QAC5C,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,YAAY,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5D,MAAM,QAAQ,GAAG,QAAQ,CACvB,EAAE,CAAC,OAAO,CACR;;qCAE2B,YAAY;mCACd,YAAY,GAAG,CACzC,EACD,GAAG,QAAQ,EACX,GAAG,QAAQ,CACZ,CAAC;YAEF,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC;oBACT,MAAM,EAAE,kBAAkB,GAAG,CAAC,aAAa,EAAE;oBAC7C,MAAM,EAAE,kBAAkB,GAAG,CAAC,WAAW,EAAE;oBAC3C,IAAI,EAAE,GAAG,CAAC,eAAe;oBACzB,MAAM,EAAE,GAAG,CAAC,QAAQ,IAAI,GAAG;oBAC3B,SAAS,EAAE,gBAAgB;iBAC5B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * BRAIN substrate adapter for the Living Brain API.
3
+ *
4
+ * Queries brain.db and returns BrainNodes/BrainEdges for all typed memory tables:
5
+ * observations, decisions, patterns, learnings, plus the graph layer
6
+ * (brain_page_nodes / brain_page_edges).
7
+ *
8
+ * Cross-substrate bridges are synthesized for:
9
+ * - brain_page_edges whose to_id references a task (task:T-xxx → tasks:T-xxx)
10
+ * - brain_page_edges whose to_id is a nexus-style path (foo.ts::Symbol → nexus:...)
11
+ * - brain_memory_links rows (memory_type + memory_id → task_id link)
12
+ * - brain_observations.files_modified_json (observation → nexus file path)
13
+ *
14
+ * Node IDs are prefixed with "brain:" to prevent collisions.
15
+ */
16
+ import type { BrainEdge, BrainNode, BrainQueryOptions } from '../types.js';
17
+ /**
18
+ * Returns all BrainNodes and BrainEdges sourced from brain.db.
19
+ *
20
+ * Pulls from all four typed memory tables plus brain_page_edges.
21
+ * Emits intra-brain edges between loaded nodes, cross-substrate
22
+ * brain→tasks bridges, cross-substrate brain→nexus bridges, and
23
+ * brain_memory_links as cross-substrate edges.
24
+ *
25
+ * Applies `minWeight` filter where quality_score is available.
26
+ * Node count is bounded by `limit / 5` to share budget with other substrates.
27
+ *
28
+ * @param options - Query options (limit, minWeight).
29
+ * @returns Nodes and edges from the BRAIN substrate.
30
+ */
31
+ export declare function getBrainSubstrate(options?: BrainQueryOptions): {
32
+ nodes: BrainNode[];
33
+ edges: BrainEdge[];
34
+ };
35
+ //# sourceMappingURL=brain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain.d.ts","sourceRoot":"","sources":["../../../src/adapters/brain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAyH3E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,iBAAsB,GAAG;IAClE,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB,CAwPA"}
@@ -0,0 +1,303 @@
1
+ /**
2
+ * BRAIN substrate adapter for the Living Brain API.
3
+ *
4
+ * Queries brain.db and returns BrainNodes/BrainEdges for all typed memory tables:
5
+ * observations, decisions, patterns, learnings, plus the graph layer
6
+ * (brain_page_nodes / brain_page_edges).
7
+ *
8
+ * Cross-substrate bridges are synthesized for:
9
+ * - brain_page_edges whose to_id references a task (task:T-xxx → tasks:T-xxx)
10
+ * - brain_page_edges whose to_id is a nexus-style path (foo.ts::Symbol → nexus:...)
11
+ * - brain_memory_links rows (memory_type + memory_id → task_id link)
12
+ * - brain_observations.files_modified_json (observation → nexus file path)
13
+ *
14
+ * Node IDs are prefixed with "brain:" to prevent collisions.
15
+ */
16
+ import { allTyped, getBrainDb } from '../db-connections.js';
17
+ import { resolveDefaultProjectContext } from '../project-context.js';
18
+ /**
19
+ * Converts a brain_page_edges type-prefixed ID (e.g. "observation:O-abc")
20
+ * into the BrainNode ID prefix (e.g. "brain:O-abc").
21
+ *
22
+ * Returns null when the prefix is not a recognised brain type.
23
+ *
24
+ * @param typeId - Type-prefixed ID from brain_page_edges.from_id or to_id.
25
+ * @returns BrainNode-prefixed ID or null.
26
+ */
27
+ function brainTypeIdToBrainNodeId(typeId) {
28
+ const sep = typeId.indexOf(':');
29
+ if (sep === -1)
30
+ return null;
31
+ const prefix = typeId.slice(0, sep);
32
+ const rawId = typeId.slice(sep + 1);
33
+ if (prefix === 'observation' ||
34
+ prefix === 'decision' ||
35
+ prefix === 'pattern' ||
36
+ prefix === 'learning') {
37
+ return `brain:${rawId}`;
38
+ }
39
+ return null;
40
+ }
41
+ /**
42
+ * Returns true when a brain_page_edges to_id looks like a nexus node path
43
+ * (contains "::" separator used by nexus for file::Symbol paths, or is a
44
+ * relative file path with a known extension).
45
+ *
46
+ * @param toId - to_id value from brain_page_edges.
47
+ * @returns True when the ID appears to reference a nexus node.
48
+ */
49
+ function isNexusStyleId(toId) {
50
+ // Nexus symbol IDs contain :: (file::SymbolName)
51
+ if (toId.includes('::'))
52
+ return true;
53
+ // Nexus file IDs are relative paths (no type: prefix, contain a /)
54
+ if (!toId.includes(':') && toId.includes('/'))
55
+ return true;
56
+ return false;
57
+ }
58
+ /**
59
+ * Returns true when a brain_page_edges ID looks like a task reference
60
+ * (e.g. "task:T532").
61
+ *
62
+ * @param id - ID from brain_page_edges.
63
+ * @returns True when the ID references a task node.
64
+ */
65
+ function isTaskId(id) {
66
+ return id.startsWith('task:');
67
+ }
68
+ /**
69
+ * Converts a brain_page_edges task-reference to a tasks-substrate BrainNode ID.
70
+ * e.g. "task:T532" → "tasks:T532"
71
+ *
72
+ * @param taskRef - Task reference from brain_page_edges.
73
+ * @returns tasks-substrate BrainNode ID.
74
+ */
75
+ function taskRefToBrainNodeId(taskRef) {
76
+ return `tasks:${taskRef.slice('task:'.length)}`;
77
+ }
78
+ /**
79
+ * Returns all BrainNodes and BrainEdges sourced from brain.db.
80
+ *
81
+ * Pulls from all four typed memory tables plus brain_page_edges.
82
+ * Emits intra-brain edges between loaded nodes, cross-substrate
83
+ * brain→tasks bridges, cross-substrate brain→nexus bridges, and
84
+ * brain_memory_links as cross-substrate edges.
85
+ *
86
+ * Applies `minWeight` filter where quality_score is available.
87
+ * Node count is bounded by `limit / 5` to share budget with other substrates.
88
+ *
89
+ * @param options - Query options (limit, minWeight).
90
+ * @returns Nodes and edges from the BRAIN substrate.
91
+ */
92
+ export function getBrainSubstrate(options = {}) {
93
+ const ctx = options.projectCtx ?? resolveDefaultProjectContext();
94
+ const db = getBrainDb(ctx);
95
+ if (!db)
96
+ return { nodes: [], edges: [] };
97
+ const minWeight = options.minWeight ?? 0;
98
+ const perSubstrateLimit = Math.ceil((options.limit ?? 500) / 5);
99
+ const nodes = [];
100
+ const edges = [];
101
+ try {
102
+ // Observations — normalise created_at to ISO-8601 with 'T' separator via strftime
103
+ const obsRows = allTyped(db.prepare(`SELECT id, title, quality_score, memory_tier,
104
+ strftime('%Y-%m-%dT%H:%M:%S', created_at) AS created_at,
105
+ source_session_id, files_modified_json
106
+ FROM brain_observations
107
+ WHERE (quality_score IS NULL OR quality_score >= ?)
108
+ ORDER BY quality_score DESC, created_at DESC
109
+ LIMIT ?`), minWeight, Math.ceil(perSubstrateLimit * 0.4));
110
+ for (const row of obsRows) {
111
+ nodes.push({
112
+ id: `brain:${row.id}`,
113
+ kind: 'observation',
114
+ substrate: 'brain',
115
+ label: row.title,
116
+ weight: row.quality_score ?? undefined,
117
+ createdAt: row.created_at,
118
+ meta: {
119
+ memory_tier: row.memory_tier,
120
+ created_at: row.created_at,
121
+ source_session_id: row.source_session_id,
122
+ },
123
+ });
124
+ }
125
+ // Decisions — normalise created_at to ISO-8601 with 'T' separator via strftime
126
+ const decRows = allTyped(db.prepare(`SELECT id, decision, quality_score, context_task_id,
127
+ strftime('%Y-%m-%dT%H:%M:%S', created_at) AS created_at
128
+ FROM brain_decisions
129
+ WHERE (quality_score IS NULL OR quality_score >= ?)
130
+ ORDER BY quality_score DESC, created_at DESC
131
+ LIMIT ?`), minWeight, Math.ceil(perSubstrateLimit * 0.25));
132
+ for (const row of decRows) {
133
+ nodes.push({
134
+ id: `brain:${row.id}`,
135
+ kind: 'decision',
136
+ substrate: 'brain',
137
+ label: row.decision.slice(0, 100),
138
+ weight: row.quality_score ?? undefined,
139
+ createdAt: row.created_at,
140
+ meta: {
141
+ context_task_id: row.context_task_id,
142
+ created_at: row.created_at,
143
+ },
144
+ });
145
+ }
146
+ // Patterns — uses 'pattern' text column (not 'title') and 'extracted_at' (not 'created_at').
147
+ // SQLite strftime is used to normalise the timestamp to ISO-8601 with 'T' separator.
148
+ const patRows = allTyped(db.prepare(`SELECT id, pattern, type, quality_score,
149
+ strftime('%Y-%m-%dT%H:%M:%S', extracted_at) AS extracted_at
150
+ FROM brain_patterns
151
+ WHERE (quality_score IS NULL OR quality_score >= ?)
152
+ ORDER BY quality_score DESC, extracted_at DESC
153
+ LIMIT ?`), minWeight, Math.ceil(perSubstrateLimit * 0.2));
154
+ for (const row of patRows) {
155
+ nodes.push({
156
+ id: `brain:${row.id}`,
157
+ kind: 'pattern',
158
+ substrate: 'brain',
159
+ label: row.pattern.slice(0, 100),
160
+ weight: row.quality_score ?? undefined,
161
+ createdAt: row.extracted_at,
162
+ meta: { pattern_type: row.type, created_at: row.extracted_at },
163
+ });
164
+ }
165
+ // Learnings — uses 'insight' text column (not 'title').
166
+ // Normalise created_at to ISO-8601 with 'T' separator via strftime.
167
+ const learnRows = allTyped(db.prepare(`SELECT id, insight, quality_score,
168
+ strftime('%Y-%m-%dT%H:%M:%S', created_at) AS created_at
169
+ FROM brain_learnings
170
+ WHERE (quality_score IS NULL OR quality_score >= ?)
171
+ ORDER BY quality_score DESC, created_at DESC
172
+ LIMIT ?`), minWeight, Math.ceil(perSubstrateLimit * 0.15));
173
+ for (const row of learnRows) {
174
+ nodes.push({
175
+ id: `brain:${row.id}`,
176
+ kind: 'learning',
177
+ substrate: 'brain',
178
+ label: row.insight.slice(0, 100),
179
+ weight: row.quality_score ?? undefined,
180
+ createdAt: row.created_at,
181
+ meta: { created_at: row.created_at },
182
+ });
183
+ }
184
+ // Build lookup: type-prefixed ID (e.g. "observation:O-abc") → BrainNode ID
185
+ // (e.g. "brain:O-abc"). This is needed because brain_page_edges stores
186
+ // IDs in type-prefixed format while BrainNode IDs use the "brain:" prefix.
187
+ const typeIdToBrainNodeId = new Map();
188
+ for (const n of nodes) {
189
+ const rawId = n.id.slice('brain:'.length);
190
+ // Determine which type prefix this node would have in brain_page_edges
191
+ let typePrefix;
192
+ if (n.kind === 'observation')
193
+ typePrefix = 'observation';
194
+ else if (n.kind === 'decision')
195
+ typePrefix = 'decision';
196
+ else if (n.kind === 'pattern')
197
+ typePrefix = 'pattern';
198
+ else
199
+ typePrefix = 'learning';
200
+ typeIdToBrainNodeId.set(`${typePrefix}:${rawId}`, n.id);
201
+ }
202
+ // brain_page_edges: query all and classify each edge
203
+ const pageEdgeRows = allTyped(db.prepare(`SELECT from_id, to_id, edge_type, weight FROM brain_page_edges`));
204
+ for (const row of pageEdgeRows) {
205
+ const sourceBrainNodeId = typeIdToBrainNodeId.get(row.from_id) ?? brainTypeIdToBrainNodeId(row.from_id);
206
+ if (!sourceBrainNodeId)
207
+ continue; // source not a recognised brain node
208
+ if (isTaskId(row.to_id)) {
209
+ // Cross-substrate: brain → tasks
210
+ edges.push({
211
+ source: sourceBrainNodeId,
212
+ target: taskRefToBrainNodeId(row.to_id),
213
+ type: row.edge_type,
214
+ weight: row.weight ?? 0.5,
215
+ substrate: 'cross',
216
+ });
217
+ }
218
+ else if (isNexusStyleId(row.to_id)) {
219
+ // Cross-substrate: brain → nexus (code_reference, etc.)
220
+ edges.push({
221
+ source: sourceBrainNodeId,
222
+ target: `nexus:${row.to_id}`,
223
+ type: row.edge_type,
224
+ weight: row.weight ?? 0.5,
225
+ substrate: 'cross',
226
+ });
227
+ }
228
+ else {
229
+ // Intra-brain: both IDs should be brain nodes
230
+ const targetBrainNodeId = typeIdToBrainNodeId.get(row.to_id) ?? brainTypeIdToBrainNodeId(row.to_id);
231
+ if (targetBrainNodeId) {
232
+ edges.push({
233
+ source: sourceBrainNodeId,
234
+ target: targetBrainNodeId,
235
+ type: row.edge_type,
236
+ weight: row.weight ?? 0.5,
237
+ substrate: 'brain',
238
+ });
239
+ }
240
+ }
241
+ }
242
+ // brain_memory_links: cross-substrate edges from typed memory nodes to tasks
243
+ const memLinkRows = allTyped(db.prepare(`SELECT memory_type, memory_id, task_id, link_type
244
+ FROM brain_memory_links`));
245
+ for (const row of memLinkRows) {
246
+ const sourceTypeId = `${row.memory_type}:${row.memory_id}`;
247
+ const sourceBrainNodeId = typeIdToBrainNodeId.get(sourceTypeId) ?? brainTypeIdToBrainNodeId(sourceTypeId);
248
+ if (!sourceBrainNodeId)
249
+ continue; // source node not in loaded set
250
+ edges.push({
251
+ source: sourceBrainNodeId,
252
+ target: `tasks:${row.task_id}`,
253
+ type: row.link_type,
254
+ weight: 0.7,
255
+ substrate: 'cross',
256
+ });
257
+ }
258
+ // brain_observations.files_modified_json: cross-substrate observation → nexus file
259
+ for (const row of obsRows) {
260
+ if (!row.files_modified_json)
261
+ continue;
262
+ let filePaths;
263
+ try {
264
+ filePaths = JSON.parse(row.files_modified_json);
265
+ }
266
+ catch {
267
+ continue;
268
+ }
269
+ if (!Array.isArray(filePaths))
270
+ continue;
271
+ const sourceBrainNodeId = `brain:${row.id}`;
272
+ for (const rawPath of filePaths) {
273
+ if (typeof rawPath !== 'string' || rawPath.length === 0)
274
+ continue;
275
+ edges.push({
276
+ source: sourceBrainNodeId,
277
+ target: `nexus:${rawPath}`,
278
+ type: 'modified_by',
279
+ weight: 0.6,
280
+ substrate: 'cross',
281
+ });
282
+ }
283
+ }
284
+ // Soft FK: brain_decisions.context_task_id → tasks (direct, not via page_edges)
285
+ // This handles decisions whose context_task_id may not yet appear in brain_page_edges.
286
+ for (const dec of decRows) {
287
+ if (dec.context_task_id) {
288
+ edges.push({
289
+ source: `brain:${dec.id}`,
290
+ target: `tasks:${dec.context_task_id}`,
291
+ type: 'applies_to',
292
+ weight: 0.8,
293
+ substrate: 'cross',
294
+ });
295
+ }
296
+ }
297
+ }
298
+ catch {
299
+ // Return partial results on error
300
+ }
301
+ return { nodes, edges };
302
+ }
303
+ //# sourceMappingURL=brain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain.js","sourceRoot":"","sources":["../../../src/adapters/brain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * CONDUIT substrate adapter for the Living Brain API.
3
+ *
4
+ * Queries conduit.db and returns BrainNodes/BrainEdges for agent-to-agent messages.
5
+ * Each message becomes a node; `from_agent_id → to_agent_id` becomes an edge.
6
+ * Co-authoring agent pairs produce cross-substrate edges to SIGNALDOCK.
7
+ *
8
+ * Node IDs are prefixed with "conduit:" to prevent collisions.
9
+ */
10
+ import type { BrainEdge, BrainNode, BrainQueryOptions } from '../types.js';
11
+ /**
12
+ * Returns all BrainNodes and BrainEdges sourced from conduit.db.
13
+ *
14
+ * Fetches the most recent messages (capped at perSubstrateLimit).
15
+ * Synthesizes agent→agent edges and cross-substrate agent references
16
+ * pointing to signaldock.
17
+ *
18
+ * @param options - Query options (limit).
19
+ * @returns Nodes and edges from the CONDUIT substrate.
20
+ */
21
+ export declare function getConduitSubstrate(options?: BrainQueryOptions): {
22
+ nodes: BrainNode[];
23
+ edges: BrainEdge[];
24
+ };
25
+ //# sourceMappingURL=conduit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conduit.d.ts","sourceRoot":"","sources":["../../../src/adapters/conduit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAyB3E;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,iBAAsB,GAAG;IACpE,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB,CAqEA"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * CONDUIT substrate adapter for the Living Brain API.
3
+ *
4
+ * Queries conduit.db and returns BrainNodes/BrainEdges for agent-to-agent messages.
5
+ * Each message becomes a node; `from_agent_id → to_agent_id` becomes an edge.
6
+ * Co-authoring agent pairs produce cross-substrate edges to SIGNALDOCK.
7
+ *
8
+ * Node IDs are prefixed with "conduit:" to prevent collisions.
9
+ */
10
+ import { allTyped, getConduitDb } from '../db-connections.js';
11
+ import { resolveDefaultProjectContext } from '../project-context.js';
12
+ /**
13
+ * Converts a UNIX epoch seconds value to an ISO-8601 string.
14
+ * Returns null when the value is not a finite positive number.
15
+ *
16
+ * @param epoch - UNIX timestamp in seconds.
17
+ * @returns ISO-8601 string or null.
18
+ */
19
+ function epochToIso(epoch) {
20
+ if (!Number.isFinite(epoch) || epoch <= 0)
21
+ return null;
22
+ return new Date(epoch * 1000).toISOString();
23
+ }
24
+ /**
25
+ * Returns all BrainNodes and BrainEdges sourced from conduit.db.
26
+ *
27
+ * Fetches the most recent messages (capped at perSubstrateLimit).
28
+ * Synthesizes agent→agent edges and cross-substrate agent references
29
+ * pointing to signaldock.
30
+ *
31
+ * @param options - Query options (limit).
32
+ * @returns Nodes and edges from the CONDUIT substrate.
33
+ */
34
+ export function getConduitSubstrate(options = {}) {
35
+ const ctx = options.projectCtx ?? resolveDefaultProjectContext();
36
+ const db = getConduitDb(ctx);
37
+ if (!db)
38
+ return { nodes: [], edges: [] };
39
+ const perSubstrateLimit = Math.ceil((options.limit ?? 500) / 5);
40
+ const nodes = [];
41
+ const edges = [];
42
+ try {
43
+ // Most recent messages
44
+ const msgRows = allTyped(db.prepare(`SELECT id, content, from_agent_id, to_agent_id, created_at, conversation_id
45
+ FROM messages
46
+ ORDER BY created_at DESC
47
+ LIMIT ?`), perSubstrateLimit);
48
+ const agentPairs = new Map();
49
+ for (const row of msgRows) {
50
+ // Message node — truncate content for label
51
+ const label = row.content.length > 80 ? `${row.content.slice(0, 80)}…` : row.content;
52
+ nodes.push({
53
+ id: `conduit:${row.id}`,
54
+ kind: 'message',
55
+ substrate: 'conduit',
56
+ label,
57
+ createdAt: epochToIso(row.created_at),
58
+ meta: {
59
+ from_agent_id: row.from_agent_id,
60
+ to_agent_id: row.to_agent_id,
61
+ conversation_id: row.conversation_id,
62
+ created_at: row.created_at,
63
+ },
64
+ });
65
+ // Aggregate agent pairs for social-graph edges
66
+ if (row.from_agent_id && row.to_agent_id) {
67
+ const key = `${row.from_agent_id}→${row.to_agent_id}`;
68
+ const existing = agentPairs.get(key);
69
+ if (existing) {
70
+ existing.count++;
71
+ }
72
+ else {
73
+ agentPairs.set(key, { count: 1, from: row.from_agent_id, to: row.to_agent_id });
74
+ }
75
+ }
76
+ }
77
+ // Cross-substrate: agent social graph edges pointing to signaldock agent nodes
78
+ for (const [, pair] of agentPairs) {
79
+ const weight = Math.min(1.0, pair.count / 10);
80
+ edges.push({
81
+ source: `agent-registry:${pair.from}`,
82
+ target: `agent-registry:${pair.to}`,
83
+ type: 'messages',
84
+ weight,
85
+ substrate: 'cross',
86
+ });
87
+ }
88
+ }
89
+ catch {
90
+ // Return partial results on error
91
+ }
92
+ return { nodes, edges };
93
+ }
94
+ //# sourceMappingURL=conduit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conduit.js","sourceRoot":"","sources":["../../../src/adapters/conduit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Barrel for all substrate adapters.
3
+ *
4
+ * Re-exports individual adapter functions and provides the unified
5
+ * `getAllSubstrates()` function that merges results from all five databases
6
+ * into a single BrainGraph.
7
+ */
8
+ export { getAgentRegistrySubstrate } from './agent-registry.js';
9
+ export { getBrainSubstrate } from './brain.js';
10
+ export { getConduitSubstrate } from './conduit.js';
11
+ export { getNexusSubstrate } from './nexus.js';
12
+ export { getTasksSubstrate } from './tasks.js';
13
+ import type { BrainGraph, BrainQueryOptions } from '../types.js';
14
+ /**
15
+ * Queries all five substrates and merges the results into a unified BrainGraph.
16
+ *
17
+ * When `options.substrates` is provided, only those substrates are queried.
18
+ * Node IDs are substrate-prefixed, so deduplication is safe to perform
19
+ * by ID equality alone.
20
+ *
21
+ * After all substrates are loaded, performs a second-pass stub-node load:
22
+ * any edge target ID not yet in the loaded node set is fetched as a minimal
23
+ * stub (id, substrate, kind, label). This recovers cross-substrate edges
24
+ * that would otherwise be silently dropped.
25
+ *
26
+ * Stub nodes carry `meta.isStub: true` for optional UI differentiation.
27
+ *
28
+ * @param options - Query options forwarded to each substrate adapter.
29
+ * @returns Merged BrainGraph across all requested substrates, with stub nodes for unresolved edge targets.
30
+ */
31
+ export declare function getAllSubstrates(options?: BrainQueryOptions): BrainGraph;
32
+ //# sourceMappingURL=index.d.ts.map