mor 0.0.2 → 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 (58) hide show
  1. package/README.md +160 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +587 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/config.d.ts +3 -0
  6. package/dist/config.js +56 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/db.d.ts +37 -0
  9. package/dist/db.js +134 -0
  10. package/dist/db.js.map +1 -0
  11. package/dist/embeddings/none.d.ts +6 -0
  12. package/dist/embeddings/none.js +8 -0
  13. package/dist/embeddings/none.js.map +1 -0
  14. package/dist/embeddings/ollama.d.ts +9 -0
  15. package/dist/embeddings/ollama.js +28 -0
  16. package/dist/embeddings/ollama.js.map +1 -0
  17. package/dist/embeddings/openai.d.ts +10 -0
  18. package/dist/embeddings/openai.js +33 -0
  19. package/dist/embeddings/openai.js.map +1 -0
  20. package/dist/embeddings/provider.d.ts +7 -0
  21. package/dist/embeddings/provider.js +15 -0
  22. package/dist/embeddings/provider.js.map +1 -0
  23. package/dist/index.d.ts +9 -0
  24. package/dist/index.js +160 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/mcp.d.ts +1 -0
  27. package/dist/mcp.js +188 -0
  28. package/dist/mcp.js.map +1 -0
  29. package/dist/memory.d.ts +20 -0
  30. package/dist/memory.js +124 -0
  31. package/dist/memory.js.map +1 -0
  32. package/dist/operations.d.ts +61 -0
  33. package/dist/operations.js +122 -0
  34. package/dist/operations.js.map +1 -0
  35. package/dist/query.d.ts +3 -0
  36. package/dist/query.js +44 -0
  37. package/dist/query.js.map +1 -0
  38. package/dist/remote.d.ts +35 -0
  39. package/dist/remote.js +77 -0
  40. package/dist/remote.js.map +1 -0
  41. package/dist/server.d.ts +7 -0
  42. package/dist/server.js +241 -0
  43. package/dist/server.js.map +1 -0
  44. package/dist/types.d.ts +50 -0
  45. package/dist/types.js +10 -0
  46. package/dist/types.js.map +1 -0
  47. package/package.json +35 -17
  48. package/.dir-locals.el +0 -6
  49. package/.editorconfig +0 -15
  50. package/.eslintrc +0 -26
  51. package/.npmignore +0 -32
  52. package/LICENSE +0 -21
  53. package/alg/dfs.js +0 -36
  54. package/alg/revDfs.js +0 -36
  55. package/cli.js +0 -106
  56. package/mor-core.js +0 -60
  57. package/mor-link.js +0 -23
  58. package/mor-outdated.js +0 -26
package/dist/mcp.js ADDED
@@ -0,0 +1,188 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import path from 'node:path';
4
+ import { z } from 'zod';
5
+ import { isRemote, loadConfig } from './config.js';
6
+ import { LocalOperations } from './operations.js';
7
+ import { RemoteOperations } from './remote.js';
8
+ function createOps() {
9
+ const config = loadConfig();
10
+ if (isRemote(config))
11
+ return new RemoteOperations(config);
12
+ return new LocalOperations(config);
13
+ }
14
+ export async function startMcpServer() {
15
+ const server = new McpServer({
16
+ name: 'mor',
17
+ version: '0.1.0',
18
+ });
19
+ const ops = createOps();
20
+ server.registerTool('memory_search', {
21
+ description: 'Search memories by query string. Returns matching memories with scores.',
22
+ inputSchema: {
23
+ query: z.string().describe('Search query'),
24
+ limit: z.number().optional().describe('Max results (default 20)'),
25
+ },
26
+ }, async ({ query, limit }) => {
27
+ const results = await ops.search(query, limit ?? 20);
28
+ const text = results
29
+ .map((r) => {
30
+ const tags = r.memory.tags.length > 0
31
+ ? `\nTags: ${r.memory.tags.join(', ')}`
32
+ : '';
33
+ return `## ${r.memory.title}\nID: ${r.memory.id}\nFile: ${path.basename(r.memory.filePath)}${tags}\nScore: ${r.score.toFixed(3)}\n\n${r.memory.content}`;
34
+ })
35
+ .join('\n\n---\n\n');
36
+ return {
37
+ content: [
38
+ { type: 'text', text: text || 'No memories found.' },
39
+ ],
40
+ };
41
+ });
42
+ server.registerTool('memory_read', {
43
+ description: 'Read a specific memory by UUID, UUID prefix, filename, or search query.',
44
+ inputSchema: {
45
+ query: z
46
+ .string()
47
+ .describe('UUID, UUID prefix, filename, or search query'),
48
+ },
49
+ }, async ({ query }) => {
50
+ const mem = await ops.read(query);
51
+ if (!mem) {
52
+ return {
53
+ content: [
54
+ { type: 'text', text: `Memory not found: ${query}` },
55
+ ],
56
+ isError: true,
57
+ };
58
+ }
59
+ const tags = mem.tags.length > 0 ? `\nTags: ${mem.tags.join(', ')}` : '';
60
+ const text = `## ${mem.title}\nID: ${mem.id}\nFile: ${path.basename(mem.filePath)}${tags}\nType: ${mem.type}\nCreated: ${mem.created}\nUpdated: ${mem.updated}\n\n${mem.content}`;
61
+ return { content: [{ type: 'text', text }] };
62
+ });
63
+ server.registerTool('memory_add', {
64
+ description: 'Create a new memory with title, content, optional tags and type.',
65
+ inputSchema: {
66
+ title: z.string().describe('Memory title'),
67
+ content: z.string().describe('Memory content (markdown)'),
68
+ tags: z.array(z.string()).optional().describe('Tags'),
69
+ type: z
70
+ .enum([
71
+ 'user',
72
+ 'feedback',
73
+ 'project',
74
+ 'reference',
75
+ 'knowledge',
76
+ 'snippet',
77
+ 'file',
78
+ ])
79
+ .optional()
80
+ .describe('Memory type (default: knowledge)'),
81
+ },
82
+ }, async ({ title, content, tags, type }) => {
83
+ const mem = await ops.add({ title, content, tags, type });
84
+ return {
85
+ content: [
86
+ {
87
+ type: 'text',
88
+ text: `Created memory: ${mem.title}\nID: ${mem.id}\nFile: ${path.basename(mem.filePath)}`,
89
+ },
90
+ ],
91
+ };
92
+ });
93
+ server.registerTool('memory_remove', {
94
+ description: 'Delete a memory by UUID, UUID prefix, filename, or search query.',
95
+ inputSchema: {
96
+ query: z
97
+ .string()
98
+ .describe('UUID, UUID prefix, filename, or search query'),
99
+ },
100
+ }, async ({ query }) => {
101
+ try {
102
+ const result = await ops.remove(query);
103
+ return {
104
+ content: [
105
+ {
106
+ type: 'text',
107
+ text: `Removed: ${result.title} (${result.id})`,
108
+ },
109
+ ],
110
+ };
111
+ }
112
+ catch (e) {
113
+ return {
114
+ content: [
115
+ {
116
+ type: 'text',
117
+ text: e instanceof Error ? e.message : String(e),
118
+ },
119
+ ],
120
+ isError: true,
121
+ };
122
+ }
123
+ });
124
+ server.registerTool('memory_list', {
125
+ description: 'List all stored memories with their titles, IDs, and tags.',
126
+ }, async () => {
127
+ const memories = await ops.list();
128
+ if (memories.length === 0) {
129
+ return {
130
+ content: [{ type: 'text', text: 'No memories stored.' }],
131
+ };
132
+ }
133
+ const lines = memories.map((mem) => {
134
+ const tags = mem.tags.length > 0 ? ` [${mem.tags.join(', ')}]` : '';
135
+ return `- ${mem.id.slice(0, 8)} ${mem.title}${tags}`;
136
+ });
137
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
138
+ });
139
+ server.registerTool('memory_update', {
140
+ description: "Update an existing memory's title, content, tags, or type.",
141
+ inputSchema: {
142
+ query: z
143
+ .string()
144
+ .describe('UUID, UUID prefix, filename, or search query to find the memory'),
145
+ title: z.string().optional().describe('New title'),
146
+ content: z.string().optional().describe('New content'),
147
+ tags: z.array(z.string()).optional().describe('New tags'),
148
+ type: z
149
+ .enum([
150
+ 'user',
151
+ 'feedback',
152
+ 'project',
153
+ 'reference',
154
+ 'knowledge',
155
+ 'snippet',
156
+ 'file',
157
+ ])
158
+ .optional()
159
+ .describe('New type'),
160
+ },
161
+ }, async ({ query, title, content, tags, type }) => {
162
+ try {
163
+ const updated = await ops.update(query, { title, content, tags, type });
164
+ return {
165
+ content: [
166
+ {
167
+ type: 'text',
168
+ text: `Updated: ${updated.title}\nID: ${updated.id}\nFile: ${path.basename(updated.filePath)}`,
169
+ },
170
+ ],
171
+ };
172
+ }
173
+ catch (e) {
174
+ return {
175
+ content: [
176
+ {
177
+ type: 'text',
178
+ text: e instanceof Error ? e.message : String(e),
179
+ },
180
+ ],
181
+ isError: true,
182
+ };
183
+ }
184
+ });
185
+ const transport = new StdioServerTransport();
186
+ await server.connect(transport);
187
+ }
188
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { Config, Memory, MemoryType } from './types.js';
2
+ export declare function detectRepository(): string | undefined;
3
+ export declare function generateFilename(title: string, id: string): string;
4
+ export declare function createMemory(config: Config, opts: {
5
+ title: string;
6
+ content: string;
7
+ tags?: string[];
8
+ type?: MemoryType;
9
+ repository?: string;
10
+ }): Memory;
11
+ export declare function readMemory(filePath: string): Memory;
12
+ export declare function serializeMemory(mem: Memory): string;
13
+ export declare function updateMemory(filePath: string, updates: {
14
+ title?: string;
15
+ content?: string;
16
+ tags?: string[];
17
+ type?: MemoryType;
18
+ }): Memory;
19
+ export declare function deleteMemory(filePath: string): void;
20
+ export declare function listMemoryFiles(config: Config): string[];
package/dist/memory.js ADDED
@@ -0,0 +1,124 @@
1
+ import matter from 'gray-matter';
2
+ import { execSync } from 'node:child_process';
3
+ import crypto from 'node:crypto';
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ export function detectRepository() {
7
+ try {
8
+ const url = execSync('git remote get-url origin', {
9
+ encoding: 'utf-8',
10
+ stdio: ['pipe', 'pipe', 'pipe'],
11
+ }).trim();
12
+ // Normalize git URLs to domain/path format
13
+ return url
14
+ .replace(/^https?:\/\//, '')
15
+ .replace(/^git@/, '')
16
+ .replace(/\.git$/, '')
17
+ .replace(/:(\d+:)?/, '/');
18
+ }
19
+ catch {
20
+ return undefined;
21
+ }
22
+ }
23
+ export function generateFilename(title, id) {
24
+ const slug = title
25
+ .normalize('NFD')
26
+ .replace(/[\u0300-\u036f]/g, '')
27
+ .toLowerCase()
28
+ .replace(/[^a-z0-9]+/g, '-')
29
+ .replace(/^-|-$/g, '') || 'memory';
30
+ const hash = id.slice(0, 8).replace(/-/g, '').slice(0, 4);
31
+ return `${slug}-${hash}.md`;
32
+ }
33
+ export function createMemory(config, opts) {
34
+ const id = crypto.randomUUID();
35
+ const now = new Date().toISOString();
36
+ const repo = opts.repository ?? detectRepository();
37
+ const frontmatter = {
38
+ id,
39
+ title: opts.title,
40
+ tags: opts.tags ?? [],
41
+ type: opts.type ?? 'knowledge',
42
+ ...(repo ? { repository: repo } : {}),
43
+ created: now,
44
+ updated: now,
45
+ };
46
+ const filename = generateFilename(opts.title, id);
47
+ const filePath = path.join(config.memoryDir, filename);
48
+ const fileContent = matter.stringify(opts.content, frontmatter);
49
+ fs.writeFileSync(filePath, fileContent);
50
+ return {
51
+ ...frontmatter,
52
+ content: opts.content,
53
+ filePath,
54
+ };
55
+ }
56
+ export function readMemory(filePath) {
57
+ const raw = fs.readFileSync(filePath, 'utf-8');
58
+ const { data, content } = matter(raw);
59
+ const fm = data;
60
+ return {
61
+ id: fm.id,
62
+ title: fm.title,
63
+ tags: fm.tags ?? [],
64
+ type: fm.type ?? 'knowledge',
65
+ repository: fm.repository,
66
+ created: fm.created,
67
+ updated: fm.updated,
68
+ content: content.trim(),
69
+ filePath,
70
+ };
71
+ }
72
+ export function serializeMemory(mem) {
73
+ const frontmatter = {
74
+ id: mem.id,
75
+ title: mem.title,
76
+ tags: mem.tags,
77
+ type: mem.type,
78
+ ...(mem.repository ? { repository: mem.repository } : {}),
79
+ created: mem.created,
80
+ updated: mem.updated,
81
+ };
82
+ return matter.stringify(mem.content, frontmatter);
83
+ }
84
+ export function updateMemory(filePath, updates) {
85
+ const mem = readMemory(filePath);
86
+ const now = new Date().toISOString();
87
+ const frontmatter = {
88
+ id: mem.id,
89
+ title: updates.title ?? mem.title,
90
+ tags: updates.tags ?? mem.tags,
91
+ type: updates.type ?? mem.type,
92
+ ...(mem.repository ? { repository: mem.repository } : {}),
93
+ created: mem.created,
94
+ updated: now,
95
+ };
96
+ const content = updates.content ?? mem.content;
97
+ const fileContent = matter.stringify(content, frontmatter);
98
+ // If title changed, rename file (write new before deleting old to prevent data loss)
99
+ let newPath = filePath;
100
+ if (updates.title && updates.title !== mem.title) {
101
+ const newFilename = generateFilename(updates.title, mem.id);
102
+ newPath = path.join(path.dirname(filePath), newFilename);
103
+ }
104
+ fs.writeFileSync(newPath, fileContent);
105
+ if (newPath !== filePath)
106
+ fs.unlinkSync(filePath);
107
+ return {
108
+ ...frontmatter,
109
+ content,
110
+ filePath: newPath,
111
+ };
112
+ }
113
+ export function deleteMemory(filePath) {
114
+ fs.unlinkSync(filePath);
115
+ }
116
+ export function listMemoryFiles(config) {
117
+ if (!fs.existsSync(config.memoryDir))
118
+ return [];
119
+ return fs
120
+ .readdirSync(config.memoryDir)
121
+ .filter((f) => f.endsWith('.md'))
122
+ .map((f) => path.join(config.memoryDir, f));
123
+ }
124
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import type { Config, Memory, MemoryType, SearchResult } from './types.js';
2
+ export interface Operations {
3
+ search(query: string, limit?: number): Promise<SearchResult[]>;
4
+ read(query: string): Promise<Memory | undefined>;
5
+ add(opts: {
6
+ title: string;
7
+ content: string;
8
+ tags?: string[];
9
+ type?: MemoryType;
10
+ repository?: string;
11
+ }): Promise<Memory>;
12
+ update(query: string, updates: {
13
+ title?: string;
14
+ content?: string;
15
+ tags?: string[];
16
+ type?: MemoryType;
17
+ }): Promise<Memory>;
18
+ remove(query: string): Promise<{
19
+ title: string;
20
+ id: string;
21
+ }>;
22
+ grep(pattern: string, limit?: number, ignoreCase?: boolean): Promise<Memory[]>;
23
+ list(): Promise<Memory[]>;
24
+ push(): Promise<{
25
+ pushed: boolean;
26
+ message: string;
27
+ }>;
28
+ close(): void;
29
+ }
30
+ export declare class LocalOperations implements Operations {
31
+ private config;
32
+ private db;
33
+ private provider;
34
+ constructor(config: Config);
35
+ search(query: string, limit?: number): Promise<SearchResult[]>;
36
+ read(query: string): Promise<Memory | undefined>;
37
+ add(opts: {
38
+ title: string;
39
+ content: string;
40
+ tags?: string[];
41
+ type?: MemoryType;
42
+ repository?: string;
43
+ }): Promise<Memory>;
44
+ update(query: string, updates: {
45
+ title?: string;
46
+ content?: string;
47
+ tags?: string[];
48
+ type?: MemoryType;
49
+ }): Promise<Memory>;
50
+ remove(query: string): Promise<{
51
+ title: string;
52
+ id: string;
53
+ }>;
54
+ grep(pattern: string, limit?: number, ignoreCase?: boolean): Promise<Memory[]>;
55
+ list(): Promise<Memory[]>;
56
+ push(): Promise<{
57
+ pushed: boolean;
58
+ message: string;
59
+ }>;
60
+ close(): void;
61
+ }
@@ -0,0 +1,122 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import { deleteMemoryFromDb, grepMemories, openDb, upsertMemoryChecked, } from './db.js';
4
+ import { createProvider, } from './embeddings/provider.js';
5
+ import { hashContent, searchAsync, syncIndex } from './index.js';
6
+ import { createMemory, deleteMemory, listMemoryFiles, readMemory, updateMemory, } from './memory.js';
7
+ import { resolveQuery } from './query.js';
8
+ export class LocalOperations {
9
+ config;
10
+ db;
11
+ provider;
12
+ constructor(config) {
13
+ this.config = config;
14
+ this.db = openDb(config);
15
+ this.provider = createProvider(config.embedding);
16
+ }
17
+ async search(query, limit = 20) {
18
+ return searchAsync(this.config, this.db, query, limit, this.provider);
19
+ }
20
+ async read(query) {
21
+ return resolveQuery(this.config, this.db, query);
22
+ }
23
+ async add(opts) {
24
+ const mem = createMemory(this.config, opts);
25
+ const raw = fs.readFileSync(mem.filePath, 'utf-8');
26
+ upsertMemoryChecked(this.db, {
27
+ id: mem.id,
28
+ title: mem.title,
29
+ tags: mem.tags,
30
+ type: mem.type,
31
+ repository: mem.repository,
32
+ created: mem.created,
33
+ updated: mem.updated,
34
+ content: mem.content,
35
+ filePath: mem.filePath,
36
+ contentHash: hashContent(raw),
37
+ });
38
+ return mem;
39
+ }
40
+ async update(query, updates) {
41
+ const mem = resolveQuery(this.config, this.db, query);
42
+ if (!mem)
43
+ throw new Error(`Memory not found: ${query}`);
44
+ const updated = updateMemory(mem.filePath, updates);
45
+ const raw = fs.readFileSync(updated.filePath, 'utf-8');
46
+ upsertMemoryChecked(this.db, {
47
+ id: updated.id,
48
+ title: updated.title,
49
+ tags: updated.tags,
50
+ type: updated.type,
51
+ repository: updated.repository,
52
+ created: updated.created,
53
+ updated: updated.updated,
54
+ content: updated.content,
55
+ filePath: updated.filePath,
56
+ contentHash: hashContent(raw),
57
+ });
58
+ return updated;
59
+ }
60
+ async remove(query) {
61
+ const mem = resolveQuery(this.config, this.db, query);
62
+ if (!mem)
63
+ throw new Error(`Memory not found: ${query}`);
64
+ deleteMemory(mem.filePath);
65
+ deleteMemoryFromDb(this.db, mem.id);
66
+ return { title: mem.title, id: mem.id };
67
+ }
68
+ async grep(pattern, limit = 20, ignoreCase = false) {
69
+ syncIndex(this.config, this.db);
70
+ const rows = grepMemories(this.db, pattern, limit, ignoreCase);
71
+ const memories = [];
72
+ for (const row of rows) {
73
+ const mem = resolveQuery(this.config, this.db, row.id);
74
+ if (mem)
75
+ memories.push(mem);
76
+ }
77
+ return memories;
78
+ }
79
+ async list() {
80
+ syncIndex(this.config, this.db);
81
+ const files = listMemoryFiles(this.config);
82
+ const memories = [];
83
+ for (const filePath of files) {
84
+ try {
85
+ memories.push(readMemory(filePath));
86
+ }
87
+ catch {
88
+ // skip unparseable files
89
+ }
90
+ }
91
+ return memories;
92
+ }
93
+ async push() {
94
+ const dir = this.config.memoryDir;
95
+ const git = (args) => spawnSync('git', args, {
96
+ cwd: dir,
97
+ stdio: 'pipe',
98
+ encoding: 'utf-8',
99
+ });
100
+ const status = git(['status', '--porcelain']);
101
+ if (status.status !== 0) {
102
+ throw new Error('Memory folder is not a git repository');
103
+ }
104
+ if (!status.stdout.trim()) {
105
+ return { pushed: false, message: 'Nothing to push' };
106
+ }
107
+ const add = git(['add', '-A']);
108
+ if (add.status !== 0)
109
+ throw new Error(`git add failed: ${add.stderr.trim()}`);
110
+ const commit = git(['commit', '-m', 'update memory']);
111
+ if (commit.status !== 0)
112
+ throw new Error(`git commit failed: ${commit.stderr.trim()}`);
113
+ const push = git(['push']);
114
+ if (push.status !== 0)
115
+ throw new Error(`git push failed: ${push.stderr.trim()}`);
116
+ return { pushed: true, message: 'Pushed memory changes' };
117
+ }
118
+ close() {
119
+ this.db.close();
120
+ }
121
+ }
122
+ //# sourceMappingURL=operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations.js","sourceRoot":"","sources":["../src/operations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type DB } from './db.js';
2
+ import type { Config, Memory } from './types.js';
3
+ export declare function resolveQuery(config: Config, db: DB, query: string): Memory | undefined;
package/dist/query.js ADDED
@@ -0,0 +1,44 @@
1
+ import { getMemoryByFilename, getMemoryById, getMemoryByPrefix, searchFts, } from './db.js';
2
+ import { syncIndexIfNeeded } from './index.js';
3
+ import { readMemory } from './memory.js';
4
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
5
+ const UUID_PREFIX_RE = /^[0-9a-f]{4,}$/i;
6
+ export function resolveQuery(config, db, query) {
7
+ syncIndexIfNeeded(config, db);
8
+ // 1. Full UUID match
9
+ if (UUID_RE.test(query)) {
10
+ const row = getMemoryById(db, query);
11
+ if (row)
12
+ return readMemory(row.file_path);
13
+ }
14
+ // 2. UUID prefix match
15
+ if (UUID_PREFIX_RE.test(query) && query.length >= 4) {
16
+ const row = getMemoryByPrefix(db, query);
17
+ if (row)
18
+ return readMemory(row.file_path);
19
+ }
20
+ // 3. Exact filename match
21
+ const byFilename = getMemoryByFilename(db, query);
22
+ if (byFilename)
23
+ return readMemory(byFilename.file_path);
24
+ // Also try with .md extension
25
+ if (!query.endsWith('.md')) {
26
+ const byFilenameMd = getMemoryByFilename(db, query + '.md');
27
+ if (byFilenameMd)
28
+ return readMemory(byFilenameMd.file_path);
29
+ }
30
+ // 4. FTS search - return top result
31
+ try {
32
+ const results = searchFts(db, query, 1);
33
+ if (results.length > 0) {
34
+ const row = getMemoryById(db, results[0].id);
35
+ if (row)
36
+ return readMemory(row.file_path);
37
+ }
38
+ }
39
+ catch {
40
+ // FTS query syntax error - ignore
41
+ }
42
+ return undefined;
43
+ }
44
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,SAAS,GAEV,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,OAAO,GACX,iEAAiE,CAAC;AACpE,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAEzC,MAAM,UAAU,YAAY,CAC1B,MAAc,EACd,EAAM,EACN,KAAa;IAEb,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAE9B,qBAAqB;IACrB,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACrC,IAAI,GAAG;YAAE,OAAO,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED,uBAAuB;IACvB,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,iBAAiB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACzC,IAAI,GAAG;YAAE,OAAO,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED,0BAA0B;IAC1B,MAAM,UAAU,GAAG,mBAAmB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAClD,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAExD,8BAA8B;IAC9B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,YAAY,GAAG,mBAAmB,CAAC,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC;QAC5D,IAAI,YAAY;YAAE,OAAO,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAC9D,CAAC;IAED,oCAAoC;IACpC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACxC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC7C,IAAI,GAAG;gBAAE,OAAO,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { Operations } from './operations.js';
2
+ import type { Config, Memory, SearchResult } from './types.js';
3
+ export declare class RemoteOperations implements Operations {
4
+ private baseUrl;
5
+ private token?;
6
+ constructor(config: Config);
7
+ private headers;
8
+ private request;
9
+ search(query: string, limit?: number): Promise<SearchResult[]>;
10
+ read(query: string): Promise<Memory | undefined>;
11
+ add(opts: {
12
+ title: string;
13
+ content: string;
14
+ tags?: string[];
15
+ type?: string;
16
+ repository?: string;
17
+ }): Promise<Memory>;
18
+ update(query: string, updates: {
19
+ title?: string;
20
+ content?: string;
21
+ tags?: string[];
22
+ type?: string;
23
+ }): Promise<Memory>;
24
+ remove(query: string): Promise<{
25
+ title: string;
26
+ id: string;
27
+ }>;
28
+ grep(pattern: string, limit?: number, ignoreCase?: boolean): Promise<Memory[]>;
29
+ list(): Promise<Memory[]>;
30
+ push(): Promise<{
31
+ pushed: boolean;
32
+ message: string;
33
+ }>;
34
+ close(): void;
35
+ }