@naveenadi/mnemonic 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 (80) hide show
  1. package/README.md +93 -0
  2. package/SKILL.md +158 -0
  3. package/bin/mne +8 -0
  4. package/dist/chunker/index.d.ts +8 -0
  5. package/dist/chunker/index.d.ts.map +1 -0
  6. package/dist/chunker/index.js +157 -0
  7. package/dist/chunker/index.js.map +1 -0
  8. package/dist/cli/commands.d.ts +2 -0
  9. package/dist/cli/commands.d.ts.map +1 -0
  10. package/dist/cli/commands.js +793 -0
  11. package/dist/cli/commands.js.map +1 -0
  12. package/dist/cli/index.d.ts +3 -0
  13. package/dist/cli/index.d.ts.map +1 -0
  14. package/dist/cli/index.js +7 -0
  15. package/dist/cli/index.js.map +1 -0
  16. package/dist/cli/mne.d.ts +3 -0
  17. package/dist/cli/mne.d.ts.map +1 -0
  18. package/dist/cli/mne.js +7 -0
  19. package/dist/cli/mne.js.map +1 -0
  20. package/dist/index.d.ts +13 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +15 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/llm/factory.d.ts +15 -0
  25. package/dist/llm/factory.d.ts.map +1 -0
  26. package/dist/llm/factory.js +60 -0
  27. package/dist/llm/factory.js.map +1 -0
  28. package/dist/llm/index.d.ts +19 -0
  29. package/dist/llm/index.d.ts.map +1 -0
  30. package/dist/llm/index.js +18 -0
  31. package/dist/llm/index.js.map +1 -0
  32. package/dist/llm/node-llama-cpp.d.ts +30 -0
  33. package/dist/llm/node-llama-cpp.d.ts.map +1 -0
  34. package/dist/llm/node-llama-cpp.js +143 -0
  35. package/dist/llm/node-llama-cpp.js.map +1 -0
  36. package/dist/llm/ollama.d.ts +19 -0
  37. package/dist/llm/ollama.d.ts.map +1 -0
  38. package/dist/llm/ollama.js +99 -0
  39. package/dist/llm/ollama.js.map +1 -0
  40. package/dist/mcp/server.d.ts +2 -0
  41. package/dist/mcp/server.d.ts.map +1 -0
  42. package/dist/mcp/server.js +360 -0
  43. package/dist/mcp/server.js.map +1 -0
  44. package/dist/pi-extension/index.d.ts +3 -0
  45. package/dist/pi-extension/index.d.ts.map +1 -0
  46. package/dist/pi-extension/index.js +193 -0
  47. package/dist/pi-extension/index.js.map +1 -0
  48. package/dist/search/fts.d.ts +17 -0
  49. package/dist/search/fts.d.ts.map +1 -0
  50. package/dist/search/fts.js +110 -0
  51. package/dist/search/fts.js.map +1 -0
  52. package/dist/search/fusion.d.ts +33 -0
  53. package/dist/search/fusion.d.ts.map +1 -0
  54. package/dist/search/fusion.js +97 -0
  55. package/dist/search/fusion.js.map +1 -0
  56. package/dist/search/pipeline.d.ts +34 -0
  57. package/dist/search/pipeline.d.ts.map +1 -0
  58. package/dist/search/pipeline.js +216 -0
  59. package/dist/search/pipeline.js.map +1 -0
  60. package/dist/search/vector.d.ts +20 -0
  61. package/dist/search/vector.d.ts.map +1 -0
  62. package/dist/search/vector.js +70 -0
  63. package/dist/search/vector.js.map +1 -0
  64. package/dist/store/collections.d.ts +23 -0
  65. package/dist/store/collections.d.ts.map +1 -0
  66. package/dist/store/collections.js +99 -0
  67. package/dist/store/collections.js.map +1 -0
  68. package/dist/store/database.d.ts +22 -0
  69. package/dist/store/database.d.ts.map +1 -0
  70. package/dist/store/database.js +209 -0
  71. package/dist/store/database.js.map +1 -0
  72. package/dist/store/documents.d.ts +68 -0
  73. package/dist/store/documents.d.ts.map +1 -0
  74. package/dist/store/documents.js +273 -0
  75. package/dist/store/documents.js.map +1 -0
  76. package/dist/types.d.ts +193 -0
  77. package/dist/types.d.ts.map +1 -0
  78. package/dist/types.js +3 -0
  79. package/dist/types.js.map +1 -0
  80. package/package.json +58 -0
@@ -0,0 +1,360 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
4
+ import { MnemonicDB } from '../store/database.js';
5
+ import { DocumentStore } from '../store/documents.js';
6
+ import { CollectionStore } from '../store/collections.js';
7
+ import { SearchPipeline } from '../search/pipeline.js';
8
+ import { detectLLMBackend } from '../llm/factory.js';
9
+ import { join } from 'node:path';
10
+ import { homedir } from 'node:os';
11
+ import { mkdirSync, writeFileSync } from 'node:fs';
12
+ let mcpCtx = { dbPath: '' };
13
+ export async function startMcpServer(dbPath, args) {
14
+ mcpCtx.dbPath = dbPath;
15
+ const httpPort = getArg(args, '--http') ? parseInt(getArg(args, '--port') ?? '8181', 10) : null;
16
+ const daemon = hasArg(args, '--daemon');
17
+ // Initialize database
18
+ const db = new MnemonicDB(dbPath);
19
+ db.init();
20
+ await db.loadVectors();
21
+ const docs = new DocumentStore(db);
22
+ const collections = new CollectionStore(db);
23
+ const pipeline = new SearchPipeline(db);
24
+ mcpCtx.db = db;
25
+ mcpCtx.docs = docs;
26
+ mcpCtx.collections = collections;
27
+ mcpCtx.pipeline = pipeline;
28
+ // Try to initialize LLM (non-blocking — will use available backend)
29
+ try {
30
+ const { backend } = await detectLLMBackend();
31
+ mcpCtx.llm = backend;
32
+ pipeline.setLLM(backend);
33
+ }
34
+ catch {
35
+ // No LLM available, search will fall back to BM25 only
36
+ }
37
+ const server = new Server({
38
+ name: 'mnemonic',
39
+ version: '0.1.0',
40
+ }, {
41
+ capabilities: {
42
+ tools: {},
43
+ },
44
+ });
45
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
46
+ tools: [
47
+ {
48
+ name: 'query',
49
+ description: `Hybrid search with typed sub-queries (lex/vec/hyde) combined via RRF + reranking.
50
+ Each search is a typed sub-query. Use 'lex' for exact keyword/BM25 search, 'vec' for semantic vector search,
51
+ and 'hyde' for hypothetical document embedding search. The first search gets 2x weight.
52
+
53
+ Parameters:
54
+ - searches: Array of { type: 'lex'|'vec'|'hyde', query: string } — the sub-queries to run. At least 1 required.
55
+ - intent: Optional disambiguation context that helps steer ranking away from nearby-but-wrong concepts.
56
+ - collections: Optional array of collection names to filter (OR). Defaults to all included collections.
57
+ - limit: Max results (default 10).
58
+ - minScore: Minimum relevance 0-1 (default 0).
59
+ - candidateLimit: Max candidates to rerank (default 40).
60
+ - rerank: Whether to run LLM reranking (default true).
61
+ - decay: Apply time decay (default false).
62
+ - boostLinks: Apply link boost (default false).`,
63
+ inputSchema: {
64
+ type: 'object',
65
+ properties: {
66
+ searches: {
67
+ type: 'array',
68
+ items: {
69
+ type: 'object',
70
+ properties: {
71
+ type: { type: 'string', enum: ['lex', 'vec', 'hyde'] },
72
+ query: { type: 'string' },
73
+ },
74
+ required: ['type', 'query'],
75
+ },
76
+ minItems: 1,
77
+ maxItems: 10,
78
+ },
79
+ intent: { type: 'string' },
80
+ collections: {
81
+ type: 'array',
82
+ items: { type: 'string' },
83
+ },
84
+ limit: { type: 'number', default: 10 },
85
+ minScore: { type: 'number', default: 0 },
86
+ candidateLimit: { type: 'number', default: 40 },
87
+ rerank: { type: 'boolean', default: true },
88
+ decay: { type: 'boolean', default: false },
89
+ boostLinks: { type: 'boolean', default: false },
90
+ },
91
+ required: ['searches'],
92
+ },
93
+ },
94
+ {
95
+ name: 'get',
96
+ description: `Retrieve a document by path or docid (with fuzzy matching suggestions).
97
+ Supports :from:count suffix for line ranges (e.g. #abc123:50:40).
98
+
99
+ Parameters:
100
+ - file: Path, docid (#abc123), or path:from:count (e.g. #abc123:120:40).
101
+ - fromLine: Start line (1-indexed); overrides the :from suffix.
102
+ - maxLines: Limit returned lines.
103
+ - lineNumbers: Prefix lines with numbers (default true).`,
104
+ inputSchema: {
105
+ type: 'object',
106
+ properties: {
107
+ file: { type: 'string', description: 'Path, docid (#abc123), or path:from:count' },
108
+ fromLine: { type: 'number', description: 'Start line (1-indexed)' },
109
+ maxLines: { type: 'number', description: 'Limit returned lines' },
110
+ lineNumbers: { type: 'boolean', default: true },
111
+ },
112
+ required: ['file'],
113
+ },
114
+ },
115
+ {
116
+ name: 'multi_get',
117
+ description: `Batch retrieve documents by glob pattern or comma-separated list.
118
+ Supports docids (#abc123) in comma-separated lists.
119
+
120
+ Parameters:
121
+ - pattern: Glob pattern or comma-separated list of paths/docids.
122
+ - maxBytes: Skip files larger than N (default 10240).
123
+ - maxLines: Limit lines per file.
124
+ - lineNumbers: Prefix lines with numbers (default true).`,
125
+ inputSchema: {
126
+ type: 'object',
127
+ properties: {
128
+ pattern: { type: 'string', description: 'Glob pattern or comma-separated list' },
129
+ maxBytes: { type: 'number', default: 10240 },
130
+ maxLines: { type: 'number', default: 100 },
131
+ lineNumbers: { type: 'boolean', default: true },
132
+ },
133
+ required: ['pattern'],
134
+ },
135
+ },
136
+ {
137
+ name: 'status',
138
+ description: 'Index health and collection info. Returns collection stats, document counts, vector status, and link graph info.',
139
+ inputSchema: {
140
+ type: 'object',
141
+ properties: {},
142
+ },
143
+ },
144
+ ],
145
+ }));
146
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
147
+ const { name, arguments: args } = request.params;
148
+ try {
149
+ switch (name) {
150
+ case 'query':
151
+ return handleQuery(args);
152
+ case 'get':
153
+ return handleGet(args);
154
+ case 'multi_get':
155
+ return handleMultiGet(args);
156
+ case 'status':
157
+ return handleStatus();
158
+ default:
159
+ throw new Error(`Unknown tool: ${name}`);
160
+ }
161
+ }
162
+ catch (err) {
163
+ return {
164
+ content: [{ type: 'text', text: `Error: ${err.message}` }],
165
+ isError: true,
166
+ };
167
+ }
168
+ });
169
+ if (httpPort) {
170
+ // HTTP transport using Node's built-in http module
171
+ const http = await import('node:http');
172
+ const url = await import('node:url');
173
+ const httpServer = http.createServer(async (req, res) => {
174
+ res.setHeader('Access-Control-Allow-Origin', '*');
175
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
176
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
177
+ if (req.method === 'OPTIONS') {
178
+ res.writeHead(200);
179
+ res.end();
180
+ return;
181
+ }
182
+ const parsedUrl = new URL(req.url ?? '/', `http://${req.headers.host}`);
183
+ if (parsedUrl.pathname === '/health') {
184
+ res.writeHead(200, { 'Content-Type': 'application/json' });
185
+ res.end(JSON.stringify({ status: 'ok', uptime: process.uptime() }));
186
+ return;
187
+ }
188
+ if (parsedUrl.pathname === '/mcp' && req.method === 'POST') {
189
+ let body = '';
190
+ req.on('data', (chunk) => (body += chunk));
191
+ req.on('end', async () => {
192
+ try {
193
+ const jsonBody = JSON.parse(body);
194
+ const result = await server.request(jsonBody, {});
195
+ res.writeHead(200, { 'Content-Type': 'application/json' });
196
+ res.end(JSON.stringify(result));
197
+ }
198
+ catch (err) {
199
+ res.writeHead(400, { 'Content-Type': 'application/json' });
200
+ res.end(JSON.stringify({ error: err.message }));
201
+ }
202
+ });
203
+ return;
204
+ }
205
+ res.writeHead(404);
206
+ res.end('Not found');
207
+ });
208
+ httpServer.listen(httpPort, () => {
209
+ console.log(`MCP server running on http://localhost:${httpPort}`);
210
+ });
211
+ if (daemon) {
212
+ // Write PID file
213
+ const pidDir = join(homedir(), '.cache', 'mnemonic');
214
+ mkdirSync(pidDir, { recursive: true });
215
+ writeFileSync(join(pidDir, 'mcp.pid'), String(process.pid));
216
+ }
217
+ }
218
+ else {
219
+ // Stdio transport
220
+ const transport = new StdioServerTransport();
221
+ await server.connect(transport);
222
+ }
223
+ }
224
+ // Command handlers
225
+ async function handleQuery(args) {
226
+ if (!mcpCtx.pipeline)
227
+ throw new Error('Search pipeline not initialized');
228
+ const { searches, intent, collections, limit, minScore, candidateLimit, rerank, decay, boostLinks } = args || {};
229
+ if (!searches || !Array.isArray(searches) || searches.length === 0) {
230
+ throw new Error('At least one search query is required');
231
+ }
232
+ const options = {
233
+ queries: searches.map((s) => ({
234
+ type: s.type,
235
+ query: s.query,
236
+ })),
237
+ intent,
238
+ collection: collections,
239
+ limit: limit ?? 10,
240
+ minScore: minScore ?? 0,
241
+ candidateLimit: candidateLimit ?? 40,
242
+ rerank: rerank !== false && !!mcpCtx.llm,
243
+ expand: false, // Already have explicit queries
244
+ hyde: false,
245
+ decay: decay ?? false,
246
+ boostLinks: boostLinks ?? false,
247
+ };
248
+ const results = await mcpCtx.pipeline.search(options);
249
+ return {
250
+ content: [
251
+ {
252
+ type: 'text',
253
+ text: JSON.stringify(results, null, 2),
254
+ },
255
+ ],
256
+ };
257
+ }
258
+ async function handleGet(args) {
259
+ if (!mcpCtx.docs)
260
+ throw new Error('Document store not initialized');
261
+ const { file, fromLine, maxLines, lineNumbers } = args || {};
262
+ if (!file)
263
+ throw new Error('file parameter is required');
264
+ const result = mcpCtx.docs.getBody(file, { fromLine, maxLines });
265
+ if ('error' in result) {
266
+ const similar = result.similarFiles;
267
+ return {
268
+ content: [
269
+ { type: 'text', text: `Document not found: ${file}` },
270
+ ...(similar?.length > 0 ? [{ type: 'text', text: `Similar files: ${similar.join(', ')}` }] : []),
271
+ ],
272
+ isError: true,
273
+ };
274
+ }
275
+ const meta = mcpCtx.docs.get(file);
276
+ let output = '';
277
+ if (!('error' in meta)) {
278
+ output += `mne://${meta.collection}/${meta.path} #${meta.docid}\n---\n`;
279
+ }
280
+ if (lineNumbers !== false) {
281
+ const start = fromLine ?? 1;
282
+ result.content.split('\n').forEach((line, i) => {
283
+ output += `${start + i}: ${line}\n`;
284
+ });
285
+ }
286
+ else {
287
+ output += result.content;
288
+ }
289
+ return {
290
+ content: [{ type: 'text', text: output }],
291
+ };
292
+ }
293
+ async function handleMultiGet(args) {
294
+ if (!mcpCtx.docs)
295
+ throw new Error('Document store not initialized');
296
+ const { pattern, maxBytes, maxLines, lineNumbers } = args || {};
297
+ if (!pattern)
298
+ throw new Error('pattern parameter is required');
299
+ const ids = pattern.includes(',') ? pattern.split(',').map((s) => s.trim()) : undefined;
300
+ const output = [];
301
+ if (ids) {
302
+ for (const id of ids) {
303
+ if (output.length > 10)
304
+ break; // Safety limit
305
+ const doc = mcpCtx.docs.getBody(id, { maxLines: maxLines ?? 50 });
306
+ if ('error' in doc) {
307
+ output.push(`# ${id}: Not found`);
308
+ continue;
309
+ }
310
+ const meta = mcpCtx.docs.get(id);
311
+ if (!('error' in meta)) {
312
+ output.push(`# ${meta.path} #${meta.docid}`);
313
+ output.push('---');
314
+ if (lineNumbers !== false) {
315
+ doc.content.split('\n').forEach((line, i) => {
316
+ output.push(`${i + 1}: ${line}`);
317
+ });
318
+ }
319
+ else {
320
+ output.push(doc.content);
321
+ }
322
+ output.push('');
323
+ }
324
+ }
325
+ }
326
+ return {
327
+ content: [{ type: 'text', text: output.join('\n') || 'No results' }],
328
+ };
329
+ }
330
+ async function handleStatus() {
331
+ if (!mcpCtx.db)
332
+ throw new Error('Database not initialized');
333
+ if (!mcpCtx.collections)
334
+ throw new Error('Collection store not initialized');
335
+ const cols = mcpCtx.collections.list();
336
+ return {
337
+ content: [
338
+ {
339
+ type: 'text',
340
+ text: JSON.stringify({
341
+ collections: cols,
342
+ hasVectors: mcpCtx.db.hasVectorIndex(),
343
+ hasLLM: !!mcpCtx.llm,
344
+ llmType: mcpCtx.llm?.constructor.name ?? 'none',
345
+ }, null, 2),
346
+ },
347
+ ],
348
+ };
349
+ }
350
+ // Helpers
351
+ function getArg(args, name) {
352
+ const idx = args.indexOf(name);
353
+ if (idx >= 0 && idx < args.length - 1)
354
+ return args[idx + 1];
355
+ return undefined;
356
+ }
357
+ function hasArg(args, ...names) {
358
+ return names.some((n) => args.includes(n));
359
+ }
360
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ export default function (pi: ExtensionAPI): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pi-extension/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAKpE,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,QAwNxC"}
@@ -0,0 +1,193 @@
1
+ import { Type } from 'typebox';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ export default function (pi) {
5
+ const dbPath = join(homedir(), '.cache', 'mnemonic', 'index.sqlite');
6
+ // ─── Tool: mnemonic_search ─────────────────────────────────────
7
+ pi.registerTool({
8
+ name: 'mnemonic_search',
9
+ label: 'Mnemonic Search',
10
+ description: 'Search indexed markdown knowledge bases with BM25 full-text search. Fast, no LLM needed.',
11
+ promptSnippet: 'Search local markdown knowledge bases',
12
+ promptGuidelines: [
13
+ 'Use mnemonic_search when you need to find information in the user\'s indexed markdown notes, docs, or wikis before resorting to web search.',
14
+ 'Use mnemonic_query for semantic/conceptual searches; prefer mnemonic_search when you know exact terms.',
15
+ ],
16
+ parameters: Type.Object({
17
+ query: Type.String({ description: 'Search query (keywords or phrases)' }),
18
+ collection: Type.Optional(Type.String({ description: 'Filter by collection name' })),
19
+ limit: Type.Optional(Type.Number({ default: 10, description: 'Number of results' })),
20
+ }),
21
+ async execute(toolCallId, params, signal, onUpdate, ctx) {
22
+ const { query, collection, limit } = params;
23
+ const { MnemonicDB } = await import('../store/database.js');
24
+ const { SearchPipeline } = await import('../search/pipeline.js');
25
+ const db = new MnemonicDB(dbPath);
26
+ db.init();
27
+ const pipeline = new SearchPipeline(db);
28
+ const results = pipeline.searchLex(query, {
29
+ collection: collection ? [collection] : undefined,
30
+ limit: limit ?? 10,
31
+ });
32
+ db.close();
33
+ const text = results.length === 0
34
+ ? 'No results found.'
35
+ : results.map((r, i) => `${i + 1}. ${r.path} #${r.docid}\n Title: ${r.title}\n Score: ${Math.round(r.score * 100)}%\n ${r.snippet || ''}`).join('\n\n');
36
+ return {
37
+ content: [{ type: 'text', text }],
38
+ details: { count: results.length, results },
39
+ };
40
+ },
41
+ });
42
+ // ─── Tool: mnemonic_query ─────────────────────────────────────
43
+ pi.registerTool({
44
+ name: 'mnemonic_query',
45
+ label: 'Mnemonic Query',
46
+ description: 'Hybrid semantic search over indexed markdown. Uses BM25 + vector search + optional LLM reranking for best quality. Use when the user asks conceptual questions or doesn\'t use exact keywords.',
47
+ promptSnippet: 'Hybrid semantic search over markdown knowledge bases',
48
+ promptGuidelines: [
49
+ 'Use mnemonic_query for conceptual or indirect questions where exact terms aren\'t known.',
50
+ 'Prefer mnemonic_query over mnemonic_search for most questions — it returns better results.',
51
+ 'Supply the intent parameter when the user\'s wording is ambiguous to disambiguate between nearby concepts.',
52
+ ],
53
+ parameters: Type.Object({
54
+ query: Type.String({ description: 'Natural language search query' }),
55
+ intent: Type.Optional(Type.String({ description: 'Disambiguation context. States what you want to find AND what to avoid.' })),
56
+ collection: Type.Optional(Type.String({ description: 'Filter by collection name' })),
57
+ limit: Type.Optional(Type.Number({ default: 10, description: 'Number of results' })),
58
+ rerank: Type.Optional(Type.Boolean({ default: true, description: 'Run LLM reranking for better quality' })),
59
+ }),
60
+ async execute(toolCallId, params, signal, onUpdate, ctx) {
61
+ const { query, intent, collection, limit, rerank } = params;
62
+ const { MnemonicDB } = await import('../store/database.js');
63
+ const { SearchPipeline } = await import('../search/pipeline.js');
64
+ const { detectLLMBackend } = await import('../llm/factory.js');
65
+ const db = new MnemonicDB(dbPath);
66
+ db.init();
67
+ await db.loadVectors();
68
+ const pipeline = new SearchPipeline(db);
69
+ // Try to get LLM for reranking
70
+ try {
71
+ const { backend } = await detectLLMBackend();
72
+ pipeline.setLLM(backend);
73
+ }
74
+ catch {
75
+ // No LLM — search will fall back to BM25 only
76
+ }
77
+ const results = await pipeline.search({
78
+ query,
79
+ intent,
80
+ collection: collection ? [collection] : undefined,
81
+ limit: limit ?? 10,
82
+ rerank: rerank !== false,
83
+ expand: true,
84
+ hyde: true,
85
+ });
86
+ // Cleanup LLM if loaded
87
+ if (pipeline.llm) {
88
+ await pipeline.llm.close();
89
+ }
90
+ db.close();
91
+ const text = results.length === 0
92
+ ? 'No results found.'
93
+ : results.map((r, i) => `${i + 1}. ${r.path} #${r.docid}\n Title: ${r.title}\n Score: ${Math.round(r.score * 100)}%${r.context.length ? `\n Context: ${r.context.join(' > ')}` : ''}${r.tags.length ? `\n Tags: ${r.tags.join(', ')}` : ''}\n ${r.snippet || ''}`).join('\n\n');
94
+ return {
95
+ content: [{ type: 'text', text }],
96
+ details: { count: results.length, results },
97
+ };
98
+ },
99
+ });
100
+ // ─── Tool: mnemonic_get ───────────────────────────────────────
101
+ pi.registerTool({
102
+ name: 'mnemonic_get',
103
+ label: 'Mnemonic Get',
104
+ description: 'Retrieve a full document from the mnemonic index by path or docid (#abc123). Supports line ranges with :from:count suffix.',
105
+ promptSnippet: 'Retrieve a full indexed document',
106
+ promptGuidelines: [
107
+ 'Use mnemonic_get after mnemonic_search or mnemonic_query to retrieve the full content of a matched document before answering.',
108
+ 'Use the :from:count suffix to read specific line ranges instead of fetching full documents.',
109
+ ],
110
+ parameters: Type.Object({
111
+ file: Type.String({ description: 'Path, docid (#abc123), or path:from:count (e.g. #abc123:50:40)' }),
112
+ maxLines: Type.Optional(Type.Number({ default: 100, description: 'Maximum lines to return' })),
113
+ fromLine: Type.Optional(Type.Number({ description: 'Start line (1-indexed)' })),
114
+ lineNumbers: Type.Optional(Type.Boolean({ default: true, description: 'Prefix lines with numbers' })),
115
+ }),
116
+ async execute(toolCallId, params, signal, onUpdate, ctx) {
117
+ const { file, maxLines, fromLine, lineNumbers } = params;
118
+ const { MnemonicDB } = await import('../store/database.js');
119
+ const { DocumentStore } = await import('../store/documents.js');
120
+ const db = new MnemonicDB(dbPath);
121
+ db.init();
122
+ const docs = new DocumentStore(db);
123
+ const result = docs.getBody(file, { fromLine, maxLines });
124
+ if ('error' in result) {
125
+ db.close();
126
+ return {
127
+ content: [{ type: 'text', text: `Document not found: ${file}${result.similarFiles?.length ? `\nSimilar: ${result.similarFiles.join(', ')}` : ''}` }],
128
+ isError: true,
129
+ };
130
+ }
131
+ const meta = docs.get(file);
132
+ db.close();
133
+ let output = '';
134
+ if (!('error' in meta)) {
135
+ output += `qmd://${meta.collection}/${meta.path} #${meta.docid}\n---\n`;
136
+ }
137
+ if (lineNumbers !== false) {
138
+ const start = fromLine ?? 1;
139
+ result.content.split('\n').forEach((line, i) => {
140
+ output += `${start + i}: ${line}\n`;
141
+ });
142
+ }
143
+ else {
144
+ output += result.content;
145
+ }
146
+ return {
147
+ content: [{ type: 'text', text: output }],
148
+ details: { totalLines: result.totalLines, docid: ('error' in meta) ? undefined : meta.docid },
149
+ };
150
+ },
151
+ });
152
+ // ─── Tool: mnemonic_status ─────────────────────────────────────
153
+ pi.registerTool({
154
+ name: 'mnemonic_status',
155
+ label: 'Mnemonic Status',
156
+ description: 'Show mnemonic index status: collections, document counts, vector status, and cache health.',
157
+ promptSnippet: 'Show mnemonic knowledge base status',
158
+ promptGuidelines: [
159
+ 'Use mnemonic_status at the start of a session to check what knowledge bases are available.',
160
+ ],
161
+ parameters: Type.Object({}),
162
+ async execute(toolCallId, params, signal, onUpdate, ctx) {
163
+ const { MnemonicDB } = await import('../store/database.js');
164
+ const { CollectionStore } = await import('../store/collections.js');
165
+ const { existsSync, readFileSync } = await import('node:fs');
166
+ const db = new MnemonicDB(dbPath);
167
+ db.init();
168
+ const collections = new CollectionStore(db);
169
+ const cols = collections.list();
170
+ const docCount = db.db.prepare('SELECT COUNT(*) as c FROM documents').get().c;
171
+ const chunkCount = db.db.prepare('SELECT COUNT(*) as c FROM chunks').get().c;
172
+ const linkCount = db.db.prepare('SELECT COUNT(*) as c FROM links').get().c;
173
+ const hasVectors = db.hasVectorIndex();
174
+ const dbSize = existsSync(dbPath) ? Math.round(readFileSync(dbPath).length / 1024) : 0;
175
+ db.close();
176
+ const text = [
177
+ `Index: ${dbPath}`,
178
+ `Size: ${dbSize} KB`,
179
+ `Collections: ${cols.length}`,
180
+ ...cols.map((c) => ` ${c.name}: ${c.docCount} docs, ${c.activeCount} embedded`),
181
+ `Total documents: ${docCount}`,
182
+ `Total chunks: ${chunkCount}`,
183
+ `Links: ${linkCount}`,
184
+ `Vectors: ${hasVectors ? 'yes' : 'no'}`,
185
+ ].join('\n');
186
+ return {
187
+ content: [{ type: 'text', text }],
188
+ details: { collections: cols, docCount, hasVectors },
189
+ };
190
+ },
191
+ });
192
+ }
193
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pi-extension/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { MnemonicDB } from '../store/database.js';
2
+ import type { SearchResult } from '../types.js';
3
+ export declare class FTSSearch {
4
+ private db;
5
+ constructor(db: MnemonicDB);
6
+ /** BM25 search via FTS5 */
7
+ search(query: string, options?: {
8
+ collection?: string[];
9
+ limit?: number;
10
+ minScore?: number;
11
+ }): SearchResult[];
12
+ /** Fallback to LIKE-based search when FTS5 syntax fails */
13
+ private fallbackSearch;
14
+ /** Clean a query for FTS5 syntax */
15
+ private cleanQuery;
16
+ }
17
+ //# sourceMappingURL=fts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fts.d.ts","sourceRoot":"","sources":["../../src/search/fts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,qBAAa,SAAS;IACR,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,UAAU;IAElC,2BAA2B;IAC3B,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QACP,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACd,GACL,YAAY,EAAE;IA8DjB,2DAA2D;IAC3D,OAAO,CAAC,cAAc;IA2DtB,oCAAoC;IACpC,OAAO,CAAC,UAAU;CAcnB"}