@borntorecycle/mcp-the-brain 0.1.0

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 (54) hide show
  1. package/README.md +74 -0
  2. package/dist/bin/mcp-the-brain.d.ts +3 -0
  3. package/dist/bin/mcp-the-brain.d.ts.map +1 -0
  4. package/dist/bin/mcp-the-brain.js +3 -0
  5. package/dist/bin/mcp-the-brain.js.map +1 -0
  6. package/dist/src/config.d.ts +15 -0
  7. package/dist/src/config.d.ts.map +1 -0
  8. package/dist/src/config.js +83 -0
  9. package/dist/src/config.js.map +1 -0
  10. package/dist/src/server.d.ts +2 -0
  11. package/dist/src/server.d.ts.map +1 -0
  12. package/dist/src/server.js +161 -0
  13. package/dist/src/server.js.map +1 -0
  14. package/dist/src/store/indexStore.d.ts +20 -0
  15. package/dist/src/store/indexStore.d.ts.map +1 -0
  16. package/dist/src/store/indexStore.js +63 -0
  17. package/dist/src/store/indexStore.js.map +1 -0
  18. package/dist/src/store/markdownStore.d.ts +27 -0
  19. package/dist/src/store/markdownStore.d.ts.map +1 -0
  20. package/dist/src/store/markdownStore.js +176 -0
  21. package/dist/src/store/markdownStore.js.map +1 -0
  22. package/dist/src/store/vectorStore.d.ts +26 -0
  23. package/dist/src/store/vectorStore.d.ts.map +1 -0
  24. package/dist/src/store/vectorStore.js +164 -0
  25. package/dist/src/store/vectorStore.js.map +1 -0
  26. package/dist/src/tools/listBySubsystem.d.ts +15 -0
  27. package/dist/src/tools/listBySubsystem.d.ts.map +1 -0
  28. package/dist/src/tools/listBySubsystem.js +28 -0
  29. package/dist/src/tools/listBySubsystem.js.map +1 -0
  30. package/dist/src/tools/promoteToShared.d.ts +14 -0
  31. package/dist/src/tools/promoteToShared.d.ts.map +1 -0
  32. package/dist/src/tools/promoteToShared.js +63 -0
  33. package/dist/src/tools/promoteToShared.js.map +1 -0
  34. package/dist/src/tools/rebuildIndex.d.ts +14 -0
  35. package/dist/src/tools/rebuildIndex.d.ts.map +1 -0
  36. package/dist/src/tools/rebuildIndex.js +60 -0
  37. package/dist/src/tools/rebuildIndex.js.map +1 -0
  38. package/dist/src/tools/recallKnowledge.d.ts +36 -0
  39. package/dist/src/tools/recallKnowledge.d.ts.map +1 -0
  40. package/dist/src/tools/recallKnowledge.js +141 -0
  41. package/dist/src/tools/recallKnowledge.js.map +1 -0
  42. package/dist/src/tools/recordEntry.d.ts +24 -0
  43. package/dist/src/tools/recordEntry.d.ts.map +1 -0
  44. package/dist/src/tools/recordEntry.js +82 -0
  45. package/dist/src/tools/recordEntry.js.map +1 -0
  46. package/dist/src/tools/updateEntry.d.ts +26 -0
  47. package/dist/src/tools/updateEntry.d.ts.map +1 -0
  48. package/dist/src/tools/updateEntry.js +45 -0
  49. package/dist/src/tools/updateEntry.js.map +1 -0
  50. package/dist/src/types.d.ts +73 -0
  51. package/dist/src/types.d.ts.map +1 -0
  52. package/dist/src/types.js +3 -0
  53. package/dist/src/types.js.map +1 -0
  54. package/package.json +44 -0
@@ -0,0 +1,176 @@
1
+ // ─── Markdown Store: Read/Write memory entry .md files ───
2
+ import { readFileSync, writeFileSync, readdirSync, existsSync, mkdirSync } from 'node:fs';
3
+ import { join, relative } from 'node:path';
4
+ import matter from 'gray-matter';
5
+ /** Subdirectory names for each memory type */
6
+ const TYPE_DIRS = {
7
+ 'outcome': 'outcomes',
8
+ 'pattern': 'patterns',
9
+ 'module-knowledge': 'module-knowledge',
10
+ };
11
+ /**
12
+ * Parse the structured body sections from the markdown content.
13
+ */
14
+ function parseBody(content) {
15
+ const titleMatch = content.match(/^## (.+)$/m);
16
+ const title = titleMatch ? titleMatch[1].trim() : '';
17
+ const extract = (label) => {
18
+ const re = new RegExp(`\\*\\*${label}:\\*\\*\\s*(.+?)(?=\\n\\*\\*[A-Z]|$)`, 's');
19
+ const m = content.match(re);
20
+ return m ? m[1].trim() : '';
21
+ };
22
+ return {
23
+ title,
24
+ context: extract('Context'),
25
+ result: extract('Result'),
26
+ reason: extract('Reason'),
27
+ lesson: extract('Lesson'),
28
+ action: extract('Action'),
29
+ };
30
+ }
31
+ /**
32
+ * Read a single memory entry from a .md file.
33
+ */
34
+ export function readEntry(filePath, source) {
35
+ const raw = readFileSync(filePath, 'utf-8');
36
+ const { data, content } = matter(raw);
37
+ const frontmatter = data;
38
+ const body = parseBody(content);
39
+ return {
40
+ frontmatter,
41
+ body,
42
+ rawContent: content,
43
+ filePath,
44
+ source,
45
+ };
46
+ }
47
+ /**
48
+ * Read all memory entries from a memory root directory.
49
+ */
50
+ export function readAllEntries(memoryRoot, source) {
51
+ const entries = [];
52
+ for (const typeDir of Object.values(TYPE_DIRS)) {
53
+ const dirPath = join(memoryRoot, typeDir);
54
+ if (!existsSync(dirPath))
55
+ continue;
56
+ const files = readdirSync(dirPath).filter(f => f.endsWith('.md'));
57
+ for (const file of files) {
58
+ try {
59
+ entries.push(readEntry(join(dirPath, file), source));
60
+ }
61
+ catch (err) {
62
+ // Skip malformed files with a warning to stderr (safe for stdio MCP)
63
+ process.stderr.write(`⚠ Skipping malformed entry ${file}: ${err.message}\n`);
64
+ }
65
+ }
66
+ }
67
+ return entries;
68
+ }
69
+ /**
70
+ * Write a new memory entry as a .md file.
71
+ * Returns the relative file path within the memory root.
72
+ */
73
+ export function writeEntry(memoryRoot, frontmatter, body) {
74
+ const typeDir = TYPE_DIRS[frontmatter.type];
75
+ const dirPath = join(memoryRoot, typeDir);
76
+ // Auto-create directory if needed
77
+ if (!existsSync(dirPath)) {
78
+ mkdirSync(dirPath, { recursive: true });
79
+ }
80
+ const fileName = `${frontmatter.id}.md`;
81
+ const filePath = join(dirPath, fileName);
82
+ // Check for duplicate ID
83
+ if (existsSync(filePath)) {
84
+ throw new Error(`Entry ID ${frontmatter.id} already exists at ${filePath}`);
85
+ }
86
+ const mdContent = buildMarkdown(frontmatter, body);
87
+ writeFileSync(filePath, mdContent, 'utf-8');
88
+ return join(typeDir, fileName);
89
+ }
90
+ /**
91
+ * Update an existing memory entry's frontmatter and/or body.
92
+ */
93
+ export function updateEntryFile(memoryRoot, id, updates) {
94
+ // Find the entry file
95
+ const entry = findEntryById(memoryRoot, id, 'project');
96
+ if (!entry) {
97
+ throw new Error(`Entry ${id} not found in ${memoryRoot}`);
98
+ }
99
+ const newFrontmatter = { ...entry.frontmatter, ...pickFrontmatterFields(updates) };
100
+ const newBody = { ...entry.body, ...pickBodyFields(updates) };
101
+ // Validate superseded-by constraint
102
+ if (newFrontmatter.status === 'superseded' && !newFrontmatter['superseded-by']) {
103
+ throw new Error(`Cannot set status to "superseded" without providing "superseded-by" ID.`);
104
+ }
105
+ const mdContent = buildMarkdown(newFrontmatter, newBody);
106
+ writeFileSync(entry.filePath, mdContent, 'utf-8');
107
+ }
108
+ /**
109
+ * Find an entry by ID across the type directories.
110
+ */
111
+ export function findEntryById(memoryRoot, id, source) {
112
+ for (const typeDir of Object.values(TYPE_DIRS)) {
113
+ const filePath = join(memoryRoot, typeDir, `${id}.md`);
114
+ if (existsSync(filePath)) {
115
+ return readEntry(filePath, source);
116
+ }
117
+ }
118
+ return null;
119
+ }
120
+ /**
121
+ * Get the relative file path for an entry within the memory root.
122
+ */
123
+ export function getEntryRelativePath(memoryRoot, entry) {
124
+ return relative(memoryRoot, entry.filePath).replace(/\\/g, '/');
125
+ }
126
+ // ─── Internal helpers ───
127
+ function buildMarkdown(fm, body) {
128
+ const yamlObj = {
129
+ id: fm.id,
130
+ type: fm.type,
131
+ date: fm.date,
132
+ subsystems: fm.subsystems,
133
+ tags: fm.tags,
134
+ 'related-adrs': fm['related-adrs'],
135
+ status: fm.status,
136
+ confidence: fm.confidence,
137
+ 'superseded-by': fm['superseded-by'],
138
+ };
139
+ if (fm.project) {
140
+ yamlObj.project = fm.project;
141
+ }
142
+ const frontStr = matter.stringify('', yamlObj).trim();
143
+ const bodyStr = [
144
+ `## ${body.title}`,
145
+ '',
146
+ `**Context:** ${body.context}`,
147
+ `**Result:** ${body.result}`,
148
+ `**Reason:** ${body.reason}`,
149
+ `**Lesson:** ${body.lesson}`,
150
+ `**Action:** ${body.action}`,
151
+ '',
152
+ ].join('\n');
153
+ return `${frontStr}\n${bodyStr}`;
154
+ }
155
+ function pickFrontmatterFields(obj) {
156
+ const keys = [
157
+ 'id', 'type', 'date', 'subsystems', 'tags', 'related-adrs',
158
+ 'status', 'confidence', 'superseded-by', 'project',
159
+ ];
160
+ const result = {};
161
+ for (const k of keys) {
162
+ if (k in obj)
163
+ result[k] = obj[k];
164
+ }
165
+ return result;
166
+ }
167
+ function pickBodyFields(obj) {
168
+ const keys = ['title', 'context', 'result', 'reason', 'lesson', 'action'];
169
+ const result = {};
170
+ for (const k of keys) {
171
+ if (k in obj)
172
+ result[k] = obj[k];
173
+ }
174
+ return result;
175
+ }
176
+ //# sourceMappingURL=markdownStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownStore.js","sourceRoot":"","sources":["../../../src/store/markdownStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { BrainConfig, VectorSearchResult, DegradationInfo } from '../types.js';
2
+ /**
3
+ * Check if Ollama is reachable.
4
+ */
5
+ export declare function isOllamaAvailable(): Promise<boolean>;
6
+ /**
7
+ * Generate an embedding vector using Ollama.
8
+ */
9
+ export declare function embed(text: string, model: string): Promise<number[] | null>;
10
+ /**
11
+ * Build the embedding text for a memory entry.
12
+ */
13
+ export declare function buildEmbeddingText(title: string, context: string, result: string, lesson: string): string;
14
+ /**
15
+ * Upsert a vector into the LanceDB table.
16
+ */
17
+ export declare function upsertVector(memoryRoot: string, id: string, vector: number[]): Promise<boolean>;
18
+ /**
19
+ * Search for similar vectors.
20
+ */
21
+ export declare function vectorSearch(memoryRoot: string, queryVector: number[], limit?: number): Promise<VectorSearchResult[]>;
22
+ /**
23
+ * Check degradation status.
24
+ */
25
+ export declare function checkDegradation(config: BrainConfig): Promise<DegradationInfo>;
26
+ //# sourceMappingURL=vectorStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vectorStore.d.ts","sourceRoot":"","sources":["../../../src/store/vectorStore.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAsBpF;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAS1D;AAED;;GAEG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAoBjF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzG;AA2BD;;GAEG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,OAAO,CAAC,CA8BlB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EAAE,EACrB,KAAK,GAAE,MAAU,GAChB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAsB/B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAcpF"}
@@ -0,0 +1,164 @@
1
+ // ─── Vector Store: LanceDB + Ollama embeddings ───
2
+ // Optional — degrades gracefully if dependencies or Ollama are unavailable.
3
+ /** Embedding vector dimension for nomic-embed-text */
4
+ const EMBEDDING_DIM = 768;
5
+ /** Ollama local API endpoint */
6
+ const OLLAMA_URL = 'http://localhost:11434';
7
+ // LanceDB is an optional dependency — loaded dynamically
8
+ let lancedb = null;
9
+ async function loadLanceDB() {
10
+ if (lancedb)
11
+ return lancedb;
12
+ try {
13
+ lancedb = await import('@lancedb/lancedb');
14
+ return lancedb;
15
+ }
16
+ catch {
17
+ process.stderr.write('⚠ @lancedb/lancedb not installed — vector search unavailable\n');
18
+ return null;
19
+ }
20
+ }
21
+ /**
22
+ * Check if Ollama is reachable.
23
+ */
24
+ export async function isOllamaAvailable() {
25
+ try {
26
+ const res = await fetch(`${OLLAMA_URL}/api/tags`, {
27
+ signal: AbortSignal.timeout(2000),
28
+ });
29
+ return res.ok;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ /**
36
+ * Generate an embedding vector using Ollama.
37
+ */
38
+ export async function embed(text, model) {
39
+ try {
40
+ const res = await fetch(`${OLLAMA_URL}/api/embeddings`, {
41
+ method: 'POST',
42
+ headers: { 'Content-Type': 'application/json' },
43
+ body: JSON.stringify({ model, prompt: text }),
44
+ signal: AbortSignal.timeout(10000),
45
+ });
46
+ if (!res.ok) {
47
+ process.stderr.write(`⚠ Ollama embedding failed: HTTP ${res.status}\n`);
48
+ return null;
49
+ }
50
+ const data = await res.json();
51
+ return data.embedding ?? null;
52
+ }
53
+ catch (err) {
54
+ process.stderr.write(`⚠ Ollama embedding error: ${err.message}\n`);
55
+ return null;
56
+ }
57
+ }
58
+ /**
59
+ * Build the embedding text for a memory entry.
60
+ */
61
+ export function buildEmbeddingText(title, context, result, lesson) {
62
+ return [title, context, result, lesson].filter(Boolean).join(' | ');
63
+ }
64
+ /**
65
+ * Open or create a LanceDB table for a memory root.
66
+ * Returns null if LanceDB is not available.
67
+ */
68
+ async function openTable(memoryRoot, tableName = 'memories') {
69
+ const lance = await loadLanceDB();
70
+ if (!lance)
71
+ return null;
72
+ const dbPath = `${memoryRoot}/.lance`;
73
+ try {
74
+ const db = await lance.connect(dbPath);
75
+ try {
76
+ return await db.openTable(tableName);
77
+ }
78
+ catch {
79
+ // Table doesn't exist yet — will be created on first upsert
80
+ return null;
81
+ }
82
+ }
83
+ catch (err) {
84
+ process.stderr.write(`⚠ LanceDB error: ${err.message}\n`);
85
+ return null;
86
+ }
87
+ }
88
+ /**
89
+ * Upsert a vector into the LanceDB table.
90
+ */
91
+ export async function upsertVector(memoryRoot, id, vector) {
92
+ const lance = await loadLanceDB();
93
+ if (!lance)
94
+ return false;
95
+ const dbPath = `${memoryRoot}/.lance`;
96
+ try {
97
+ const db = await lance.connect(dbPath);
98
+ let table;
99
+ try {
100
+ table = await db.openTable('memories');
101
+ }
102
+ catch {
103
+ // Create table with first entry
104
+ await db.createTable('memories', [{ id, vector }]);
105
+ return true;
106
+ }
107
+ // Delete existing entry if present, then add
108
+ try {
109
+ await table.delete(`id = '${id}'`);
110
+ }
111
+ catch {
112
+ // Entry didn't exist — fine
113
+ }
114
+ await table.add([{ id, vector }]);
115
+ return true;
116
+ }
117
+ catch (err) {
118
+ process.stderr.write(`⚠ Vector upsert failed: ${err.message}\n`);
119
+ return false;
120
+ }
121
+ }
122
+ /**
123
+ * Search for similar vectors.
124
+ */
125
+ export async function vectorSearch(memoryRoot, queryVector, limit = 5) {
126
+ const lance = await loadLanceDB();
127
+ if (!lance)
128
+ return [];
129
+ const dbPath = `${memoryRoot}/.lance`;
130
+ try {
131
+ const db = await lance.connect(dbPath);
132
+ const table = await db.openTable('memories');
133
+ const results = await table
134
+ .search(queryVector)
135
+ .limit(limit)
136
+ .toArray();
137
+ return results.map(r => ({
138
+ id: r.id,
139
+ score: r._distance != null ? 1 / (1 + r._distance) : 0,
140
+ }));
141
+ }
142
+ catch (err) {
143
+ process.stderr.write(`⚠ Vector search failed: ${err.message}\n`);
144
+ return [];
145
+ }
146
+ }
147
+ /**
148
+ * Check degradation status.
149
+ */
150
+ export async function checkDegradation(config) {
151
+ const ollamaOk = await isOllamaAvailable();
152
+ const lance = await loadLanceDB();
153
+ if (!ollamaOk && !lance) {
154
+ return { degraded: true, reason: 'ollama_unavailable_and_lancedb_missing' };
155
+ }
156
+ if (!ollamaOk) {
157
+ return { degraded: true, reason: 'ollama_unavailable' };
158
+ }
159
+ if (!lance) {
160
+ return { degraded: true, reason: 'lancedb_missing' };
161
+ }
162
+ return { degraded: false };
163
+ }
164
+ //# sourceMappingURL=vectorStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vectorStore.js","sourceRoot":"","sources":["../../../src/store/vectorStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { BrainConfig, IndexEntry } from '../types.js';
2
+ export interface ListBySubsystemParams {
3
+ subsystem: string;
4
+ scope?: 'project' | 'shared' | 'all';
5
+ }
6
+ export interface ListBySubsystemResult {
7
+ entries: Array<IndexEntry & {
8
+ source: 'project' | 'shared';
9
+ }>;
10
+ }
11
+ /**
12
+ * Main list_by_subsystem implementation.
13
+ */
14
+ export declare function listBySubsystem(cwd: string, config: BrainConfig, params: ListBySubsystemParams): ListBySubsystemResult;
15
+ //# sourceMappingURL=listBySubsystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listBySubsystem.d.ts","sourceRoot":"","sources":["../../../src/tools/listBySubsystem.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI3D,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,KAAK,CAAC;CACtC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,KAAK,CAAC,UAAU,GAAG;QAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,qBAAqB,GAC5B,qBAAqB,CA4BvB"}
@@ -0,0 +1,28 @@
1
+ // ─── Tool: list_by_subsystem — List all entries for a given module ───
2
+ import { readIndex } from '../store/indexStore.js';
3
+ import { resolveMemoryRoot, resolveSharedRoot } from '../config.js';
4
+ /**
5
+ * Main list_by_subsystem implementation.
6
+ */
7
+ export function listBySubsystem(cwd, config, params) {
8
+ const { subsystem, scope = 'all' } = params;
9
+ const results = [];
10
+ if (scope === 'project' || scope === 'all') {
11
+ const projectRoot = resolveMemoryRoot(cwd, config);
12
+ const projectIdx = readIndex(projectRoot);
13
+ results.push(...projectIdx
14
+ .filter(e => e.subsystems.includes(subsystem))
15
+ .map(e => ({ ...e, source: 'project' })));
16
+ }
17
+ if (scope === 'shared' || scope === 'all') {
18
+ const sharedRoot = resolveSharedRoot(config);
19
+ const sharedIdx = readIndex(sharedRoot);
20
+ results.push(...sharedIdx
21
+ .filter(e => e.subsystems.includes(subsystem))
22
+ .map(e => ({ ...e, source: 'shared' })));
23
+ }
24
+ // Sort by date descending
25
+ results.sort((a, b) => b.date.localeCompare(a.date));
26
+ return { entries: results };
27
+ }
28
+ //# sourceMappingURL=listBySubsystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listBySubsystem.js","sourceRoot":"","sources":["../../../src/tools/listBySubsystem.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAGxE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAWpE;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAW,EACX,MAAmB,EACnB,MAA6B;IAE7B,MAAM,EAAE,SAAS,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,MAAM,CAAC;IAC5C,MAAM,OAAO,GAAyD,EAAE,CAAC;IAEzE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QAC3C,MAAM,WAAW,GAAG,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;QAC1C,OAAO,CAAC,IAAI,CACV,GAAG,UAAU;aACV,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;aAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,SAAkB,EAAE,CAAC,CAAC,CACpD,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CACV,GAAG,SAAS;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;aAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,QAAiB,EAAE,CAAC,CAAC,CACnD,CAAC;IACJ,CAAC;IAED,0BAA0B;IAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAErD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { BrainConfig } from '../types.js';
2
+ export interface PromoteParams {
3
+ id: string;
4
+ removeProjectSpecific?: string[];
5
+ }
6
+ export interface PromoteResult {
7
+ sharedId: string;
8
+ file: string;
9
+ }
10
+ /**
11
+ * Main promote_to_shared implementation.
12
+ */
13
+ export declare function promoteToShared(cwd: string, config: BrainConfig, params: PromoteParams): Promise<PromoteResult>;
14
+ //# sourceMappingURL=promoteToShared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promoteToShared.d.ts","sourceRoot":"","sources":["../../../src/tools/promoteToShared.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAiC,MAAM,aAAa,CAAC;AAM9E,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,CAgExB"}
@@ -0,0 +1,63 @@
1
+ // ─── Tool: promote_to_shared — Copy a project entry to shared memory ───
2
+ import { existsSync, mkdirSync } from 'node:fs';
3
+ import { findEntryById, writeEntry } from '../store/markdownStore.js';
4
+ import { upsertIndexEntry } from '../store/indexStore.js';
5
+ import { embed, upsertVector, buildEmbeddingText, isOllamaAvailable } from '../store/vectorStore.js';
6
+ import { resolveMemoryRoot, resolveSharedRoot } from '../config.js';
7
+ /**
8
+ * Main promote_to_shared implementation.
9
+ */
10
+ export async function promoteToShared(cwd, config, params) {
11
+ const projectRoot = resolveMemoryRoot(cwd, config);
12
+ const sharedRoot = resolveSharedRoot(config);
13
+ // Read the project entry
14
+ const entry = findEntryById(projectRoot, params.id, 'project');
15
+ if (!entry) {
16
+ throw new Error(`Entry ${params.id} not found in project memory.`);
17
+ }
18
+ // Ensure shared root exists
19
+ if (!existsSync(sharedRoot)) {
20
+ mkdirSync(sharedRoot, { recursive: true });
21
+ }
22
+ // Check for collision: use projectName/id as shared ID
23
+ const sharedId = `${config.projectName}/${params.id}`;
24
+ // Build shared frontmatter (add project field, use original ID for file name)
25
+ const sharedFrontmatter = {
26
+ ...entry.frontmatter,
27
+ project: config.projectName,
28
+ };
29
+ // Optionally remove project-specific fields (e.g., subsystems that are project-specific)
30
+ if (params.removeProjectSpecific) {
31
+ for (const field of params.removeProjectSpecific) {
32
+ if (field === 'subsystems')
33
+ sharedFrontmatter.subsystems = [];
34
+ if (field === 'related-adrs')
35
+ sharedFrontmatter['related-adrs'] = [];
36
+ }
37
+ }
38
+ // Write to shared memory
39
+ const relativeFile = writeEntry(sharedRoot, sharedFrontmatter, entry.body);
40
+ // Update shared index
41
+ upsertIndexEntry(sharedRoot, {
42
+ id: entry.frontmatter.id,
43
+ type: entry.frontmatter.type,
44
+ file: relativeFile,
45
+ title: entry.body.title,
46
+ date: entry.frontmatter.date,
47
+ subsystems: sharedFrontmatter.subsystems,
48
+ tags: entry.frontmatter.tags,
49
+ relatedAdrs: sharedFrontmatter['related-adrs'],
50
+ status: entry.frontmatter.status,
51
+ confidence: entry.frontmatter.confidence,
52
+ });
53
+ // Generate embedding in shared LanceDB if Ollama available
54
+ if (await isOllamaAvailable()) {
55
+ const text = buildEmbeddingText(entry.body.title, entry.body.context, entry.body.result, entry.body.lesson);
56
+ const vector = await embed(text, config.embedding.model);
57
+ if (vector) {
58
+ await upsertVector(sharedRoot, entry.frontmatter.id, vector);
59
+ }
60
+ }
61
+ return { sharedId, file: relativeFile };
62
+ }
63
+ //# sourceMappingURL=promoteToShared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promoteToShared.js","sourceRoot":"","sources":["../../../src/tools/promoteToShared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { BrainConfig, MemoryScope } from '../types.js';
2
+ export interface RebuildParams {
3
+ scope?: MemoryScope;
4
+ }
5
+ export interface RebuildResult {
6
+ entriesIndexed: number;
7
+ embeddingsGenerated: number;
8
+ scope: string;
9
+ }
10
+ /**
11
+ * Main rebuild_index implementation.
12
+ */
13
+ export declare function rebuildIndex(cwd: string, config: BrainConfig, params: RebuildParams): Promise<RebuildResult>;
14
+ //# sourceMappingURL=rebuildIndex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebuildIndex.d.ts","sourceRoot":"","sources":["../../../src/tools/rebuildIndex.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM5D,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,CA8BxB"}
@@ -0,0 +1,60 @@
1
+ // ─── Tool: rebuild_index — Regenerate index.json + vector embeddings ───
2
+ import { existsSync } from 'node:fs';
3
+ import { readAllEntries, getEntryRelativePath } from '../store/markdownStore.js';
4
+ import { writeIndex, entryToIndexEntry } from '../store/indexStore.js';
5
+ import { embed, upsertVector, buildEmbeddingText, isOllamaAvailable } from '../store/vectorStore.js';
6
+ import { resolveMemoryRoot, resolveSharedRoot } from '../config.js';
7
+ /**
8
+ * Main rebuild_index implementation.
9
+ */
10
+ export async function rebuildIndex(cwd, config, params) {
11
+ const { scope = 'all' } = params;
12
+ let totalIndexed = 0;
13
+ let totalEmbeddings = 0;
14
+ const ollamaAvailable = await isOllamaAvailable();
15
+ if (scope === 'project' || scope === 'all') {
16
+ const projectRoot = resolveMemoryRoot(cwd, config);
17
+ if (existsSync(projectRoot)) {
18
+ const result = await rebuildForRoot(projectRoot, 'project', config, ollamaAvailable);
19
+ totalIndexed += result.indexed;
20
+ totalEmbeddings += result.embeddings;
21
+ }
22
+ }
23
+ if (scope === 'shared' || scope === 'all') {
24
+ const sharedRoot = resolveSharedRoot(config);
25
+ if (existsSync(sharedRoot)) {
26
+ const result = await rebuildForRoot(sharedRoot, 'shared', config, ollamaAvailable);
27
+ totalIndexed += result.indexed;
28
+ totalEmbeddings += result.embeddings;
29
+ }
30
+ }
31
+ return {
32
+ entriesIndexed: totalIndexed,
33
+ embeddingsGenerated: totalEmbeddings,
34
+ scope,
35
+ };
36
+ }
37
+ async function rebuildForRoot(memoryRoot, source, config, ollamaAvailable) {
38
+ const entries = readAllEntries(memoryRoot, source);
39
+ // Rebuild index.json
40
+ const indexEntries = entries.map(entry => {
41
+ const relFile = getEntryRelativePath(memoryRoot, entry);
42
+ return entryToIndexEntry(entry, relFile);
43
+ });
44
+ writeIndex(memoryRoot, indexEntries);
45
+ // Rebuild embeddings
46
+ let embeddings = 0;
47
+ if (ollamaAvailable) {
48
+ for (const entry of entries) {
49
+ const text = buildEmbeddingText(entry.body.title, entry.body.context, entry.body.result, entry.body.lesson);
50
+ const vector = await embed(text, config.embedding.model);
51
+ if (vector) {
52
+ await upsertVector(memoryRoot, entry.frontmatter.id, vector);
53
+ embeddings++;
54
+ }
55
+ }
56
+ }
57
+ process.stderr.write(`✓ Rebuilt ${source} index: ${entries.length} entries, ${embeddings} embeddings\n`);
58
+ return { indexed: entries.length, embeddings };
59
+ }
60
+ //# sourceMappingURL=rebuildIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebuildIndex.js","sourceRoot":"","sources":["../../../src/tools/rebuildIndex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { BrainConfig, MemoryType, MemoryScope, DegradationInfo } from '../types.js';
2
+ export interface RecallParams {
3
+ query: string;
4
+ subsystems?: string[];
5
+ tags?: string[];
6
+ type?: MemoryType;
7
+ limit?: number;
8
+ scope?: MemoryScope;
9
+ }
10
+ export interface RecallResult {
11
+ entries: Array<{
12
+ id: string;
13
+ type: MemoryType;
14
+ title: string;
15
+ date: string;
16
+ subsystems: string[];
17
+ tags: string[];
18
+ status: string;
19
+ confidence: string;
20
+ source: 'project' | 'shared';
21
+ body: {
22
+ context: string;
23
+ result: string;
24
+ reason: string;
25
+ lesson: string;
26
+ action: string;
27
+ };
28
+ }>;
29
+ degradation: DegradationInfo;
30
+ totalMatches: number;
31
+ }
32
+ /**
33
+ * Main recall_knowledge implementation.
34
+ */
35
+ export declare function recallKnowledge(cwd: string, config: BrainConfig, params: RecallParams): Promise<RecallResult>;
36
+ //# sourceMappingURL=recallKnowledge.d.ts.map