memextend 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 (53) hide show
  1. package/dist/commands/edit.d.ts +2 -0
  2. package/dist/commands/edit.d.ts.map +1 -0
  3. package/dist/commands/edit.js +84 -0
  4. package/dist/commands/edit.js.map +1 -0
  5. package/dist/commands/export.d.ts +8 -0
  6. package/dist/commands/export.d.ts.map +1 -0
  7. package/dist/commands/export.js +88 -0
  8. package/dist/commands/export.js.map +1 -0
  9. package/dist/commands/forget.d.ts +10 -0
  10. package/dist/commands/forget.d.ts.map +1 -0
  11. package/dist/commands/forget.js +199 -0
  12. package/dist/commands/forget.js.map +1 -0
  13. package/dist/commands/help.d.ts +2 -0
  14. package/dist/commands/help.d.ts.map +1 -0
  15. package/dist/commands/help.js +437 -0
  16. package/dist/commands/help.js.map +1 -0
  17. package/dist/commands/import.d.ts +7 -0
  18. package/dist/commands/import.d.ts.map +1 -0
  19. package/dist/commands/import.js +138 -0
  20. package/dist/commands/import.js.map +1 -0
  21. package/dist/commands/init.d.ts +6 -0
  22. package/dist/commands/init.d.ts.map +1 -0
  23. package/dist/commands/init.js +258 -0
  24. package/dist/commands/init.js.map +1 -0
  25. package/dist/commands/list.d.ts +7 -0
  26. package/dist/commands/list.d.ts.map +1 -0
  27. package/dist/commands/list.js +67 -0
  28. package/dist/commands/list.js.map +1 -0
  29. package/dist/commands/save.d.ts +8 -0
  30. package/dist/commands/save.d.ts.map +1 -0
  31. package/dist/commands/save.js +95 -0
  32. package/dist/commands/save.js.map +1 -0
  33. package/dist/commands/search.d.ts +8 -0
  34. package/dist/commands/search.d.ts.map +1 -0
  35. package/dist/commands/search.js +82 -0
  36. package/dist/commands/search.js.map +1 -0
  37. package/dist/commands/status.d.ts +7 -0
  38. package/dist/commands/status.d.ts.map +1 -0
  39. package/dist/commands/status.js +231 -0
  40. package/dist/commands/status.js.map +1 -0
  41. package/dist/commands/uninstall.d.ts +7 -0
  42. package/dist/commands/uninstall.d.ts.map +1 -0
  43. package/dist/commands/uninstall.js +188 -0
  44. package/dist/commands/uninstall.js.map +1 -0
  45. package/dist/commands/webui.d.ts +7 -0
  46. package/dist/commands/webui.d.ts.map +1 -0
  47. package/dist/commands/webui.js +314 -0
  48. package/dist/commands/webui.js.map +1 -0
  49. package/dist/index.d.ts +3 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +97 -0
  52. package/dist/index.js.map +1 -0
  53. package/package.json +51 -0
@@ -0,0 +1,258 @@
1
+ // apps/cli/src/commands/init.ts
2
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
3
+ import { existsSync } from 'fs';
4
+ import { mkdir, writeFile, readFile } from 'fs/promises';
5
+ import { join } from 'path';
6
+ import { homedir } from 'os';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ const MEMEXTEND_DIR = join(homedir(), '.memextend');
10
+ const CONFIG_PATH = join(MEMEXTEND_DIR, 'config.json');
11
+ const DB_PATH = join(MEMEXTEND_DIR, 'memextend.db');
12
+ const VECTORS_PATH = join(MEMEXTEND_DIR, 'vectors');
13
+ const MODELS_PATH = join(MEMEXTEND_DIR, 'models');
14
+ const CLAUDE_DIR = join(homedir(), '.claude');
15
+ const CLAUDE_SETTINGS_PATH = join(CLAUDE_DIR, 'settings.json');
16
+ const CLAUDE_MD_PATH = join(CLAUDE_DIR, 'CLAUDE.md');
17
+ const CLAUDE_MD_TEMPLATE = `# memextend - AI Memory Extension
18
+
19
+ You have persistent memory across sessions via memextend.
20
+
21
+ ## Available MCP Tools
22
+
23
+ - **memextend_search** - Search your memories for past decisions, patterns, or context
24
+ Example: "How did we implement caching?" → Use memextend_search to find relevant memories
25
+
26
+ - **memextend_save** - Save important decisions or context for this project
27
+ Example: After making an architectural decision, save it for future reference
28
+
29
+ - **memextend_save_global** - Save cross-project preferences (coding style, preferred tools)
30
+ Example: "User prefers TypeScript strict mode" → Save as global preference
31
+
32
+ - **memextend_forget** - Delete a specific memory by ID
33
+
34
+ - **memextend_status** - Check memory statistics and system status
35
+
36
+ ## When to Use Memory
37
+
38
+ **Search memories when:**
39
+ - Starting work on a project you've worked on before
40
+ - The user references past decisions ("like we did before", "as discussed")
41
+ - You need context about project architecture or conventions
42
+
43
+ **Save memories when:**
44
+ - Making significant architectural decisions
45
+ - Establishing project conventions or patterns
46
+ - The user shares important preferences
47
+ - Completing a major feature or fix
48
+
49
+ ## Memory is Automatic
50
+
51
+ Memories are automatically captured from your sessions and injected at startup.
52
+ Use the tools above to actively search for more detail or save important context.
53
+ `;
54
+ const DEFAULT_CONFIG = {
55
+ version: 1,
56
+ storage: {
57
+ path: MEMEXTEND_DIR,
58
+ sqlite: 'memextend.db',
59
+ vectors: 'vectors',
60
+ },
61
+ embedding: {
62
+ model: 'nomic-embed-text-v1.5-GGUF',
63
+ dimensions: 384,
64
+ },
65
+ capture: {
66
+ tools: ['Edit', 'Write', 'Bash', 'Task'],
67
+ skipTools: ['Read', 'Glob', 'Grep', 'TodoWrite', 'AskUserQuestion'],
68
+ maxContentLength: 2000,
69
+ },
70
+ retrieval: {
71
+ autoInject: true,
72
+ maxMemories: 0,
73
+ recentDays: 0,
74
+ includeGlobal: true,
75
+ },
76
+ adapters: {
77
+ 'claude-code': {
78
+ enabled: true,
79
+ hooksRegistered: false,
80
+ mcpRegistered: false,
81
+ },
82
+ },
83
+ };
84
+ export async function initCommand(options) {
85
+ console.log(chalk.bold('\n memextend v0.1.0\n'));
86
+ if (options.manual) {
87
+ printManualInstructions();
88
+ return;
89
+ }
90
+ const spinner = ora();
91
+ try {
92
+ // Step 1: Create directories
93
+ spinner.start('Creating memextend directory...');
94
+ await mkdir(MEMEXTEND_DIR, { recursive: true });
95
+ await mkdir(VECTORS_PATH, { recursive: true });
96
+ await mkdir(MODELS_PATH, { recursive: true });
97
+ spinner.succeed('Created ~/.memextend/');
98
+ // Step 2: Initialize SQLite database
99
+ spinner.start('Initializing SQLite database...');
100
+ const { SQLiteStorage } = await import('@memextend/core');
101
+ const sqlite = new SQLiteStorage(DB_PATH);
102
+ sqlite.close();
103
+ spinner.succeed('Initialized SQLite database');
104
+ // Step 3: Initialize LanceDB
105
+ spinner.start('Initializing LanceDB vectors...');
106
+ const { LanceDBStorage } = await import('@memextend/core');
107
+ const lancedb = await LanceDBStorage.create(VECTORS_PATH);
108
+ await lancedb.close();
109
+ spinner.succeed('Initialized LanceDB vectors');
110
+ // Step 4: Write config
111
+ spinner.start('Writing configuration...');
112
+ await writeFile(CONFIG_PATH, JSON.stringify(DEFAULT_CONFIG, null, 2));
113
+ spinner.succeed('Configuration saved');
114
+ // Step 5: Register with Claude Code
115
+ spinner.start('Registering with Claude Code...');
116
+ const registered = await registerWithClaudeCode();
117
+ if (registered) {
118
+ spinner.succeed('Registered hooks and MCP server with Claude Code');
119
+ }
120
+ else {
121
+ spinner.warn('Could not auto-register with Claude Code (see manual instructions)');
122
+ }
123
+ // Step 6: Create CLAUDE.md template
124
+ spinner.start('Creating CLAUDE.md template...');
125
+ const claudeMdCreated = await createClaudeMd();
126
+ if (claudeMdCreated) {
127
+ spinner.succeed('Created ~/.claude/CLAUDE.md with memory tool guidance');
128
+ }
129
+ else {
130
+ spinner.warn('CLAUDE.md already exists (skipped)');
131
+ }
132
+ // Done!
133
+ console.log(chalk.green('\n ✅ memextend is ready!\n'));
134
+ console.log(' Start a new Claude Code session to begin building memory.\n');
135
+ if (!registered) {
136
+ console.log(chalk.yellow(' Note: Run `memextend init --manual` for manual setup instructions.\n'));
137
+ }
138
+ }
139
+ catch (error) {
140
+ spinner.fail('Initialization failed');
141
+ console.error(chalk.red(`\n Error: ${error instanceof Error ? error.message : error}\n`));
142
+ process.exit(1);
143
+ }
144
+ }
145
+ async function registerWithClaudeCode() {
146
+ try {
147
+ // Check if Claude Code settings exist
148
+ if (!existsSync(CLAUDE_SETTINGS_PATH)) {
149
+ return false;
150
+ }
151
+ const settingsContent = await readFile(CLAUDE_SETTINGS_PATH, 'utf-8');
152
+ const settings = JSON.parse(settingsContent);
153
+ // Add hooks configuration
154
+ if (!settings.hooks) {
155
+ settings.hooks = {};
156
+ }
157
+ // Find the installed package location
158
+ const packagePath = findPackagePath();
159
+ if (!packagePath) {
160
+ return false;
161
+ }
162
+ const hooksPath = join(packagePath, 'packages', 'adapters', 'claude-code', 'dist', 'hooks');
163
+ const mcpPath = join(packagePath, 'packages', 'adapters', 'claude-code', 'dist', 'mcp');
164
+ // Register SessionStart hook
165
+ settings.hooks.SessionStart = {
166
+ command: 'node',
167
+ args: [join(hooksPath, 'session-start.cjs')],
168
+ timeout: 30000,
169
+ };
170
+ // Register Stop hook
171
+ settings.hooks.Stop = {
172
+ command: 'node',
173
+ args: [join(hooksPath, 'stop.cjs')],
174
+ timeout: 30000,
175
+ };
176
+ // Register MCP server
177
+ if (!settings.mcpServers) {
178
+ settings.mcpServers = {};
179
+ }
180
+ settings.mcpServers.memextend = {
181
+ command: 'node',
182
+ args: [join(mcpPath, 'server.cjs')],
183
+ };
184
+ // Write updated settings
185
+ await writeFile(CLAUDE_SETTINGS_PATH, JSON.stringify(settings, null, 2));
186
+ // Update our config to reflect registration
187
+ const config = { ...DEFAULT_CONFIG };
188
+ config.adapters['claude-code'].hooksRegistered = true;
189
+ config.adapters['claude-code'].mcpRegistered = true;
190
+ await writeFile(CONFIG_PATH, JSON.stringify(config, null, 2));
191
+ return true;
192
+ }
193
+ catch {
194
+ return false;
195
+ }
196
+ }
197
+ function findPackagePath() {
198
+ // Try to find the installed package
199
+ // For now, return null and rely on manual setup
200
+ // In production, this would resolve the npm package location
201
+ return null;
202
+ }
203
+ async function createClaudeMd() {
204
+ try {
205
+ // Create .claude directory if it doesn't exist
206
+ await mkdir(CLAUDE_DIR, { recursive: true });
207
+ // Check if CLAUDE.md already exists
208
+ if (existsSync(CLAUDE_MD_PATH)) {
209
+ // Check if it already contains memextend section
210
+ const existing = await readFile(CLAUDE_MD_PATH, 'utf-8');
211
+ if (existing.includes('memextend')) {
212
+ return false; // Already has memextend content
213
+ }
214
+ // Append to existing file
215
+ await writeFile(CLAUDE_MD_PATH, existing + '\n\n' + CLAUDE_MD_TEMPLATE);
216
+ }
217
+ else {
218
+ // Create new file
219
+ await writeFile(CLAUDE_MD_PATH, CLAUDE_MD_TEMPLATE);
220
+ }
221
+ return true;
222
+ }
223
+ catch {
224
+ return false;
225
+ }
226
+ }
227
+ function printManualInstructions() {
228
+ console.log(chalk.bold('Manual Configuration Instructions\n'));
229
+ console.log('1. Create the memextend directory:');
230
+ console.log(chalk.cyan(' mkdir -p ~/.memextend\n'));
231
+ console.log('2. Add the following to your Claude Code settings (~/.claude/settings.json):');
232
+ console.log(chalk.cyan(`
233
+ {
234
+ "hooks": {
235
+ "SessionStart": {
236
+ "command": "node",
237
+ "args": ["/path/to/memextend/dist/hooks/session-start.cjs"],
238
+ "timeout": 30000
239
+ },
240
+ "Stop": {
241
+ "command": "node",
242
+ "args": ["/path/to/memextend/dist/hooks/stop.cjs"],
243
+ "timeout": 30000
244
+ }
245
+ },
246
+ "mcpServers": {
247
+ "memextend": {
248
+ "command": "node",
249
+ "args": ["/path/to/memextend/dist/mcp/server.cjs"]
250
+ }
251
+ }
252
+ }
253
+ `));
254
+ console.log('3. Replace /path/to/memextend with the actual installation path.');
255
+ console.log(' You can find it by running: npm root -g\n');
256
+ console.log('4. Restart Claude Code to apply changes.\n');
257
+ }
258
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface ListOptions {
2
+ project?: boolean;
3
+ limit?: string;
4
+ }
5
+ export declare function listCommand(options: ListOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAaA,UAAU,WAAW;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CrE"}
@@ -0,0 +1,67 @@
1
+ // apps/cli/src/commands/list.ts
2
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
3
+ import { existsSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { homedir } from 'os';
6
+ import { execSync } from 'child_process';
7
+ import { createHash } from 'crypto';
8
+ import chalk from 'chalk';
9
+ const MEMEXTEND_DIR = join(homedir(), '.memextend');
10
+ const DB_PATH = join(MEMEXTEND_DIR, 'memextend.db');
11
+ export async function listCommand(options) {
12
+ if (!existsSync(DB_PATH)) {
13
+ console.log(chalk.yellow('\n ⚠ memextend not initialized. Run `memextend init` first.\n'));
14
+ return;
15
+ }
16
+ try {
17
+ const { SQLiteStorage } = await import('@memextend/core');
18
+ const sqlite = new SQLiteStorage(DB_PATH);
19
+ const limit = parseInt(options.limit ?? '20', 10);
20
+ let projectId;
21
+ if (options.project) {
22
+ projectId = getProjectId(process.cwd());
23
+ }
24
+ const memories = sqlite.getAllMemories(projectId, limit);
25
+ console.log(chalk.bold(`\n Recent Memories${options.project ? ' (current project)' : ''}\n`));
26
+ if (memories.length === 0) {
27
+ console.log(chalk.yellow(' No memories found.\n'));
28
+ }
29
+ else {
30
+ memories.forEach((memory, i) => {
31
+ const preview = memory.content.split('\n')[0].slice(0, 70);
32
+ const date = formatDate(memory.createdAt);
33
+ const type = memory.sourceTool ? `[${memory.sourceTool}]` : '[manual]';
34
+ console.log(` ${chalk.cyan(`${i + 1}.`)} ${chalk.dim(type)} ${preview}`);
35
+ console.log(chalk.dim(` Date: ${date} | ID: ${memory.id}\n`));
36
+ });
37
+ console.log(chalk.dim(` Showing ${memories.length} of ${sqlite.getMemoryCount()} total memories.\n`));
38
+ }
39
+ sqlite.close();
40
+ }
41
+ catch (error) {
42
+ console.error(chalk.red(`\n Error: ${error instanceof Error ? error.message : error}\n`));
43
+ process.exit(1);
44
+ }
45
+ }
46
+ function getProjectId(cwd) {
47
+ try {
48
+ const gitRoot = execSync('git rev-parse --show-toplevel', {
49
+ cwd,
50
+ encoding: 'utf-8',
51
+ stdio: ['pipe', 'pipe', 'pipe']
52
+ }).trim();
53
+ return createHash('sha256').update(gitRoot).digest('hex').slice(0, 16);
54
+ }
55
+ catch {
56
+ return createHash('sha256').update(cwd).digest('hex').slice(0, 16);
57
+ }
58
+ }
59
+ function formatDate(isoDate) {
60
+ const date = new Date(isoDate);
61
+ return date.toLocaleDateString('en-US', {
62
+ year: 'numeric',
63
+ month: 'short',
64
+ day: 'numeric',
65
+ });
66
+ }
67
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ interface SaveOptions {
2
+ global?: boolean;
3
+ project?: string;
4
+ message?: string;
5
+ }
6
+ export declare function saveCommand(options: SaveOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=save.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../src/commands/save.ts"],"names":[],"mappings":"AAcA,UAAU,WAAW;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA+FrE"}
@@ -0,0 +1,95 @@
1
+ // apps/cli/src/commands/save.ts
2
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
3
+ import { existsSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { homedir } from 'os';
6
+ import chalk from 'chalk';
7
+ import { createInterface } from 'readline';
8
+ import { randomUUID } from 'crypto';
9
+ const MEMEXTEND_DIR = join(homedir(), '.memextend');
10
+ const DB_PATH = join(MEMEXTEND_DIR, 'memextend.db');
11
+ const VECTORS_PATH = join(MEMEXTEND_DIR, 'vectors');
12
+ export async function saveCommand(options) {
13
+ if (!existsSync(DB_PATH)) {
14
+ console.log(chalk.yellow('\n memextend not initialized. Run `memextend init` first.\n'));
15
+ return;
16
+ }
17
+ try {
18
+ const { SQLiteStorage, LanceDBStorage, LocalEmbedding, getCurrentProjectId } = await import('@memextend/core');
19
+ let content = options.message;
20
+ // If no message provided, prompt for content interactively
21
+ if (!content) {
22
+ console.log(chalk.cyan('\n Enter memory content (press Enter twice to finish, or Ctrl+C to cancel):\n'));
23
+ const rl = createInterface({
24
+ input: process.stdin,
25
+ output: process.stdout,
26
+ });
27
+ const lines = [];
28
+ let emptyLineCount = 0;
29
+ content = await new Promise((resolve) => {
30
+ const askLine = () => {
31
+ rl.question(' > ', (line) => {
32
+ if (line === '') {
33
+ emptyLineCount++;
34
+ if (emptyLineCount >= 2) {
35
+ rl.close();
36
+ resolve(lines.join('\n').trim());
37
+ return;
38
+ }
39
+ }
40
+ else {
41
+ emptyLineCount = 0;
42
+ }
43
+ lines.push(line);
44
+ askLine();
45
+ });
46
+ };
47
+ askLine();
48
+ });
49
+ }
50
+ if (!content) {
51
+ console.log(chalk.yellow('\n No content provided. Memory not saved.\n'));
52
+ return;
53
+ }
54
+ // Determine project ID
55
+ let projectId = null;
56
+ if (!options.global) {
57
+ projectId = options.project || getCurrentProjectId();
58
+ if (!projectId) {
59
+ console.log(chalk.yellow('\n Could not determine project. Use --global for global memory or --project <id>.\n'));
60
+ return;
61
+ }
62
+ }
63
+ // Initialize storage
64
+ const sqlite = new SQLiteStorage(DB_PATH);
65
+ const lancedb = await LanceDBStorage.create(VECTORS_PATH);
66
+ const embedder = await LocalEmbedding.create(MEMEXTEND_DIR);
67
+ // Create memory
68
+ const memoryId = randomUUID();
69
+ const memory = {
70
+ id: memoryId,
71
+ projectId,
72
+ content,
73
+ type: 'manual',
74
+ sourceTool: null,
75
+ createdAt: new Date().toISOString(),
76
+ sessionId: null,
77
+ metadata: null
78
+ };
79
+ // Save to SQLite
80
+ sqlite.insertMemory(memory);
81
+ // Generate and save embedding
82
+ const embedding = await embedder.embed(content);
83
+ await lancedb.insertVector(memoryId, embedding);
84
+ sqlite.close();
85
+ await lancedb.close();
86
+ const scope = projectId ? `project: ${projectId.slice(0, 8)}...` : 'global';
87
+ console.log(chalk.green(`\n Memory saved (${scope})`));
88
+ console.log(chalk.dim(` ID: ${memoryId}\n`));
89
+ }
90
+ catch (error) {
91
+ console.error(chalk.red(`\n Error: ${error instanceof Error ? error.message : error}\n`));
92
+ process.exit(1);
93
+ }
94
+ }
95
+ //# sourceMappingURL=save.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.js","sourceRoot":"","sources":["../../src/commands/save.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,8CAA8C;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AACpD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AACpD,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AAQpD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB;IACpD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,8DAA8D,CAAC,CAAC,CAAC;QAC1F,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAE/G,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAE9B,2DAA2D;QAC3D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC,CAAC;YAE1G,MAAM,EAAE,GAAG,eAAe,CAAC;gBACzB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,CAAC;YAEH,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,IAAI,cAAc,GAAG,CAAC,CAAC;YAEvB,OAAO,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;gBAC9C,MAAM,OAAO,GAAG,GAAG,EAAE;oBACnB,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;wBAC3B,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;4BAChB,cAAc,EAAE,CAAC;4BACjB,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;gCACxB,EAAE,CAAC,KAAK,EAAE,CAAC;gCACX,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gCACjC,OAAO;4BACT,CAAC;wBACH,CAAC;6BAAM,CAAC;4BACN,cAAc,GAAG,CAAC,CAAC;wBACrB,CAAC;wBACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACjB,OAAO,EAAE,CAAC;oBACZ,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC;gBACF,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,8CAA8C,CAAC,CAAC,CAAC;YAC1E,OAAO;QACT,CAAC;QAED,uBAAuB;QACvB,IAAI,SAAS,GAAkB,IAAI,CAAC;QACpC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,SAAS,GAAG,OAAO,CAAC,OAAO,IAAI,mBAAmB,EAAE,CAAC;YACrD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sFAAsF,CAAC,CAAC,CAAC;gBAClH,OAAO;YACT,CAAC;QACH,CAAC;QAED,qBAAqB;QACrB,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAE5D,gBAAgB;QAChB,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG;YACb,EAAE,EAAE,QAAQ;YACZ,SAAS;YACT,OAAO;YACP,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,IAAI;SACf,CAAC;QAEF,iBAAiB;QACjB,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAE5B,8BAA8B;QAC9B,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,OAAO,CAAC,YAAY,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QAEtB,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,YAAY,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,KAAK,GAAG,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,QAAQ,IAAI,CAAC,CAAC,CAAC;IAEhD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ interface SearchOptions {
2
+ project?: boolean;
3
+ global?: boolean;
4
+ limit?: string;
5
+ }
6
+ export declare function searchCommand(query: string, options: SearchOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAaA,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA0ExF"}
@@ -0,0 +1,82 @@
1
+ // apps/cli/src/commands/search.ts
2
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
3
+ import { existsSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { homedir } from 'os';
6
+ import chalk from 'chalk';
7
+ const MEMEXTEND_DIR = join(homedir(), '.memextend');
8
+ const DB_PATH = join(MEMEXTEND_DIR, 'memextend.db');
9
+ const VECTORS_PATH = join(MEMEXTEND_DIR, 'vectors');
10
+ const MODELS_PATH = join(MEMEXTEND_DIR, 'models');
11
+ export async function searchCommand(query, options) {
12
+ if (!existsSync(DB_PATH)) {
13
+ console.log(chalk.yellow('\n ⚠ memextend not initialized. Run `memextend init` first.\n'));
14
+ return;
15
+ }
16
+ try {
17
+ const { SQLiteStorage, LanceDBStorage, MemoryRetriever, createEmbedFunction, getProjectId } = await import('@memextend/core');
18
+ const sqlite = new SQLiteStorage(DB_PATH);
19
+ const lancedb = await LanceDBStorage.create(VECTORS_PATH);
20
+ // Create embedding function (uses real model if available)
21
+ const embedder = await createEmbedFunction(MODELS_PATH);
22
+ const retriever = new MemoryRetriever(sqlite, lancedb, embedder.embedQuery);
23
+ const limit = parseInt(options.limit ?? '10', 10);
24
+ let projectId;
25
+ if (options.project) {
26
+ projectId = getProjectId(process.cwd());
27
+ }
28
+ // Perform search
29
+ console.log(chalk.bold(`\n Searching for: "${query}"`));
30
+ if (!embedder.isReal) {
31
+ console.log(chalk.dim(' (Using fallback embeddings - run `memextend init` to download model)\n'));
32
+ }
33
+ else {
34
+ console.log('');
35
+ }
36
+ let results;
37
+ if (options.global) {
38
+ // Search global profile only
39
+ const profiles = sqlite.getGlobalProfiles(limit);
40
+ console.log(chalk.dim(` Found ${profiles.length} global profile entries:\n`));
41
+ profiles.forEach((profile, i) => {
42
+ console.log(` ${i + 1}. [${profile.key}] ${profile.content}`);
43
+ console.log(chalk.dim(` Created: ${formatDate(profile.createdAt)}\n`));
44
+ });
45
+ sqlite.close();
46
+ await lancedb.close();
47
+ await embedder.close();
48
+ return;
49
+ }
50
+ results = await retriever.hybridSearch(query, { limit, projectId });
51
+ if (results.length === 0) {
52
+ console.log(chalk.yellow(' No memories found matching your query.\n'));
53
+ }
54
+ else {
55
+ console.log(chalk.dim(` Found ${results.length} memories:\n`));
56
+ results.forEach((result, i) => {
57
+ const { memory, score, source } = result;
58
+ const preview = memory.content.split('\n')[0].slice(0, 80);
59
+ const date = formatDate(memory.createdAt);
60
+ console.log(` ${chalk.cyan(`${i + 1}.`)} ${preview}`);
61
+ console.log(chalk.dim(` Score: ${score.toFixed(3)} | Source: ${source} | Date: ${date}`));
62
+ console.log(chalk.dim(` ID: ${memory.id}\n`));
63
+ });
64
+ }
65
+ sqlite.close();
66
+ await lancedb.close();
67
+ await embedder.close();
68
+ }
69
+ catch (error) {
70
+ console.error(chalk.red(`\n Error: ${error instanceof Error ? error.message : error}\n`));
71
+ process.exit(1);
72
+ }
73
+ }
74
+ function formatDate(isoDate) {
75
+ const date = new Date(isoDate);
76
+ return date.toLocaleDateString('en-US', {
77
+ year: 'numeric',
78
+ month: 'short',
79
+ day: 'numeric',
80
+ });
81
+ }
82
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface StatusOptions {
2
+ project?: boolean;
3
+ checkEmbeddings?: boolean;
4
+ }
5
+ export declare function statusCommand(options: StatusOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAgBA,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EzE"}