monomind 1.17.0 → 1.17.2

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 (94) hide show
  1. package/.claude/agents/engineering/engineering-security-engineer.md +1 -1
  2. package/.claude/commands/mastermind/_repeat.md +4 -0
  3. package/.claude/commands/mastermind/master.md +52 -1
  4. package/.claude/scheduled_tasks.lock +1 -1
  5. package/.claude/skills/mastermind/_repeat.md +2 -0
  6. package/package.json +1 -1
  7. package/packages/@monomind/cli/.claude/agents/engineering/engineering-security-engineer.md +1 -1
  8. package/packages/@monomind/cli/.claude/commands/mastermind/_repeat.md +4 -0
  9. package/packages/@monomind/cli/.claude/commands/mastermind/master.md +52 -1
  10. package/packages/@monomind/cli/.claude/skills/mastermind/_repeat.md +2 -0
  11. package/packages/@monomind/cli/dist/src/__tests__/browse-analyzer.test.js +42 -59
  12. package/packages/@monomind/cli/dist/src/agents/registry-builder.d.ts +8 -0
  13. package/packages/@monomind/cli/dist/src/agents/registry-builder.js +22 -0
  14. package/packages/@monomind/cli/dist/src/browser/dashboard/server.js +18 -0
  15. package/packages/@monomind/cli/dist/src/browser/dashboard/ui.html +37 -125
  16. package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.d.ts +17 -0
  17. package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.js +320 -0
  18. package/packages/@monomind/cli/dist/src/commands/agent-ops.d.ts +9 -0
  19. package/packages/@monomind/cli/dist/src/commands/agent-ops.js +329 -0
  20. package/packages/@monomind/cli/dist/src/commands/agent.js +5 -907
  21. package/packages/@monomind/cli/dist/src/commands/analyze-ast.d.ts +26 -0
  22. package/packages/@monomind/cli/dist/src/commands/analyze-ast.js +284 -0
  23. package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.d.ts +14 -0
  24. package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.js +295 -0
  25. package/packages/@monomind/cli/dist/src/commands/analyze-diff.d.ts +8 -0
  26. package/packages/@monomind/cli/dist/src/commands/analyze-diff.js +395 -0
  27. package/packages/@monomind/cli/dist/src/commands/analyze-graph.d.ts +14 -0
  28. package/packages/@monomind/cli/dist/src/commands/analyze-graph.js +304 -0
  29. package/packages/@monomind/cli/dist/src/commands/analyze-imports.d.ts +11 -0
  30. package/packages/@monomind/cli/dist/src/commands/analyze-imports.js +287 -0
  31. package/packages/@monomind/cli/dist/src/commands/analyze-symbols.d.ts +14 -0
  32. package/packages/@monomind/cli/dist/src/commands/analyze-symbols.js +302 -0
  33. package/packages/@monomind/cli/dist/src/commands/analyze.d.ts +38 -0
  34. package/packages/@monomind/cli/dist/src/commands/analyze.js +12 -1827
  35. package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.d.ts +26 -0
  36. package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.js +189 -0
  37. package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +20 -0
  38. package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +432 -0
  39. package/packages/@monomind/cli/dist/src/commands/doctor.js +54 -943
  40. package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.d.ts +11 -0
  41. package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.js +242 -0
  42. package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.d.ts +35 -0
  43. package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.js +203 -0
  44. package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.d.ts +8 -0
  45. package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.js +233 -0
  46. package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.d.ts +12 -0
  47. package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.js +274 -0
  48. package/packages/@monomind/cli/dist/src/commands/hive-mind.js +10 -1129
  49. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.d.ts +4 -4
  50. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +19 -819
  51. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.d.ts +7 -0
  52. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.js +334 -0
  53. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.d.ts +7 -0
  54. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.js +399 -0
  55. package/packages/@monomind/cli/dist/src/commands/init-subcommands.d.ts +8 -0
  56. package/packages/@monomind/cli/dist/src/commands/init-subcommands.js +156 -0
  57. package/packages/@monomind/cli/dist/src/commands/init-upgrade.d.ts +6 -0
  58. package/packages/@monomind/cli/dist/src/commands/init-upgrade.js +203 -0
  59. package/packages/@monomind/cli/dist/src/commands/init-wizard.d.ts +6 -0
  60. package/packages/@monomind/cli/dist/src/commands/init-wizard.js +246 -0
  61. package/packages/@monomind/cli/dist/src/commands/init.js +6 -623
  62. package/packages/@monomind/cli/dist/src/commands/memory-admin.d.ts +10 -0
  63. package/packages/@monomind/cli/dist/src/commands/memory-admin.js +433 -0
  64. package/packages/@monomind/cli/dist/src/commands/memory-crud.d.ts +9 -0
  65. package/packages/@monomind/cli/dist/src/commands/memory-crud.js +342 -0
  66. package/packages/@monomind/cli/dist/src/commands/memory-list.d.ts +10 -0
  67. package/packages/@monomind/cli/dist/src/commands/memory-list.js +321 -0
  68. package/packages/@monomind/cli/dist/src/commands/memory-transfer.d.ts +9 -0
  69. package/packages/@monomind/cli/dist/src/commands/memory-transfer.js +372 -0
  70. package/packages/@monomind/cli/dist/src/commands/memory.d.ts +6 -0
  71. package/packages/@monomind/cli/dist/src/commands/memory.js +10 -1441
  72. package/packages/@monomind/cli/dist/src/commands/neural-core.d.ts +8 -0
  73. package/packages/@monomind/cli/dist/src/commands/neural-core.js +274 -0
  74. package/packages/@monomind/cli/dist/src/commands/neural-optimize.d.ts +7 -0
  75. package/packages/@monomind/cli/dist/src/commands/neural-optimize.js +332 -0
  76. package/packages/@monomind/cli/dist/src/commands/neural-registry.d.ts +7 -0
  77. package/packages/@monomind/cli/dist/src/commands/neural-registry.js +290 -0
  78. package/packages/@monomind/cli/dist/src/commands/neural.js +3 -974
  79. package/packages/@monomind/cli/dist/src/commands/platforms.js +327 -7
  80. package/packages/@monomind/cli/dist/src/commands/security-cve.d.ts +6 -0
  81. package/packages/@monomind/cli/dist/src/commands/security-cve.js +310 -0
  82. package/packages/@monomind/cli/dist/src/commands/security-misc.d.ts +9 -0
  83. package/packages/@monomind/cli/dist/src/commands/security-misc.js +293 -0
  84. package/packages/@monomind/cli/dist/src/commands/security-scan.d.ts +18 -0
  85. package/packages/@monomind/cli/dist/src/commands/security-scan.js +328 -0
  86. package/packages/@monomind/cli/dist/src/commands/security.js +3 -958
  87. package/packages/@monomind/cli/dist/src/commands/session.js +1 -1
  88. package/packages/@monomind/cli/dist/src/commands/swarm.js +23 -17
  89. package/packages/@monomind/cli/dist/src/index.js +8 -37
  90. package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +77 -0
  91. package/packages/@monomind/cli/dist/src/parser.js +11 -6
  92. package/packages/@monomind/cli/dist/src/routing/llm-caller.js +1 -2
  93. package/packages/@monomind/cli/package.json +2 -3
  94. package/packages/@monomind/cli/scripts/understand-analyze.mjs +1 -1
@@ -0,0 +1,342 @@
1
+ /**
2
+ * Memory CRUD Commands
3
+ * store, retrieve, search
4
+ */
5
+ import { output } from '../output.js';
6
+ import { input } from '../prompt.js';
7
+ // Store command
8
+ export const storeCommand = {
9
+ name: 'store',
10
+ description: 'Store data in memory',
11
+ options: [
12
+ {
13
+ name: 'key',
14
+ short: 'k',
15
+ description: 'Storage key/namespace',
16
+ type: 'string',
17
+ required: true
18
+ },
19
+ {
20
+ name: 'value',
21
+ // Note: No short flag - global -v is reserved for verbose
22
+ description: 'Value to store (use --value)',
23
+ type: 'string'
24
+ },
25
+ {
26
+ name: 'namespace',
27
+ short: 'n',
28
+ description: 'Memory namespace',
29
+ type: 'string',
30
+ default: 'default'
31
+ },
32
+ {
33
+ name: 'ttl',
34
+ description: 'Time to live in seconds',
35
+ type: 'number'
36
+ },
37
+ {
38
+ name: 'tags',
39
+ description: 'Comma-separated tags',
40
+ type: 'string'
41
+ },
42
+ {
43
+ name: 'vector',
44
+ description: 'Store as vector embedding',
45
+ type: 'boolean',
46
+ default: false
47
+ },
48
+ {
49
+ name: 'upsert',
50
+ short: 'u',
51
+ description: 'Update if key exists (insert or replace)',
52
+ type: 'boolean',
53
+ default: false
54
+ }
55
+ ],
56
+ examples: [
57
+ { command: 'monomind memory store -k "api/auth" -v "JWT implementation"', description: 'Store text' },
58
+ { command: 'monomind memory store -k "pattern/singleton" --vector', description: 'Store vector' },
59
+ { command: 'monomind memory store -k "pattern" -v "updated" --upsert', description: 'Update existing' }
60
+ ],
61
+ action: async (ctx) => {
62
+ const key = ctx.flags.key;
63
+ let value = ctx.flags.value || ctx.args[0];
64
+ const namespace = ctx.flags.namespace;
65
+ const ttl = ctx.flags.ttl;
66
+ const tags = ctx.flags.tags ? ctx.flags.tags.split(',') : [];
67
+ const asVector = ctx.flags.vector;
68
+ const upsert = ctx.flags.upsert;
69
+ if (!key) {
70
+ output.printError('Key is required. Use --key or -k');
71
+ return { success: false, exitCode: 1 };
72
+ }
73
+ if (!value && ctx.interactive) {
74
+ value = await input({
75
+ message: 'Enter value to store:',
76
+ validate: (v) => v.length > 0 || 'Value is required'
77
+ });
78
+ }
79
+ if (!value) {
80
+ output.printError('Value is required. Use --value');
81
+ return { success: false, exitCode: 1 };
82
+ }
83
+ const storeData = {
84
+ key,
85
+ namespace,
86
+ value,
87
+ ttl,
88
+ tags,
89
+ asVector,
90
+ storedAt: new Date().toISOString(),
91
+ size: Buffer.byteLength(value, 'utf8')
92
+ };
93
+ output.printInfo(`Storing in ${namespace}/${key}...`);
94
+ // Use direct sql.js storage with automatic embedding generation
95
+ try {
96
+ const { storeEntry } = await import('../memory/memory-initializer.js');
97
+ if (asVector) {
98
+ output.writeln(output.dim(' Generating embedding vector...'));
99
+ }
100
+ const result = await storeEntry({
101
+ key,
102
+ value,
103
+ namespace,
104
+ generateEmbeddingFlag: true, // Always generate embeddings for semantic search
105
+ tags,
106
+ ttl,
107
+ upsert
108
+ });
109
+ if (!result.success) {
110
+ output.printError(result.error || 'Failed to store');
111
+ return { success: false, exitCode: 1 };
112
+ }
113
+ output.writeln();
114
+ output.printTable({
115
+ columns: [
116
+ { key: 'property', header: 'Property', width: 15 },
117
+ { key: 'val', header: 'Value', width: 40 }
118
+ ],
119
+ data: [
120
+ { property: 'Key', val: key },
121
+ { property: 'Namespace', val: namespace },
122
+ { property: 'Size', val: `${storeData.size} bytes` },
123
+ { property: 'TTL', val: ttl ? `${ttl}s` : 'None' },
124
+ { property: 'Tags', val: tags.length > 0 ? tags.join(', ') : 'None' },
125
+ { property: 'Vector', val: result.embedding ? `Yes (${result.embedding.dimensions}-dim)` : 'No' },
126
+ { property: 'ID', val: result.id.substring(0, 20) }
127
+ ]
128
+ });
129
+ output.writeln();
130
+ output.printSuccess('Data stored successfully');
131
+ return { success: true, data: { ...storeData, id: result.id, embedding: result.embedding } };
132
+ }
133
+ catch (error) {
134
+ output.printError(`Failed to store: ${error instanceof Error ? error.message : 'Unknown error'}`);
135
+ return { success: false, exitCode: 1 };
136
+ }
137
+ }
138
+ };
139
+ // Retrieve command
140
+ export const retrieveCommand = {
141
+ name: 'retrieve',
142
+ aliases: ['get'],
143
+ description: 'Retrieve data from memory',
144
+ options: [
145
+ {
146
+ name: 'key',
147
+ short: 'k',
148
+ description: 'Storage key',
149
+ type: 'string'
150
+ },
151
+ {
152
+ name: 'namespace',
153
+ short: 'n',
154
+ description: 'Memory namespace',
155
+ type: 'string',
156
+ default: 'default'
157
+ }
158
+ ],
159
+ action: async (ctx) => {
160
+ const key = ctx.flags.key || ctx.args[0];
161
+ const namespace = ctx.flags.namespace;
162
+ if (!key) {
163
+ output.printError('Key is required');
164
+ return { success: false, exitCode: 1 };
165
+ }
166
+ // Use sql.js directly for consistent data access
167
+ try {
168
+ const { getEntry } = await import('../memory/memory-initializer.js');
169
+ const result = await getEntry({ key, namespace });
170
+ if (!result.success) {
171
+ output.printError(`Failed to retrieve: ${result.error}`);
172
+ return { success: false, exitCode: 1 };
173
+ }
174
+ if (!result.found || !result.entry) {
175
+ output.printWarning(`Key not found: ${key}`);
176
+ return { success: false, exitCode: 1, data: { key, found: false } };
177
+ }
178
+ const entry = result.entry;
179
+ if (ctx.flags.format === 'json') {
180
+ output.printJson(entry);
181
+ return { success: true, data: entry };
182
+ }
183
+ output.writeln();
184
+ output.printBox([
185
+ `Namespace: ${entry.namespace}`,
186
+ `Key: ${entry.key}`,
187
+ `Size: ${entry.content.length} bytes`,
188
+ `Access Count: ${entry.accessCount}`,
189
+ `Tags: ${entry.tags.length > 0 ? entry.tags.join(', ') : 'None'}`,
190
+ `Vector: ${entry.hasEmbedding ? 'Yes' : 'No'}`,
191
+ '',
192
+ output.bold('Value:'),
193
+ entry.content
194
+ ].join('\n'), 'Memory Entry');
195
+ return { success: true, data: entry };
196
+ }
197
+ catch (error) {
198
+ output.printError(`Failed to retrieve: ${error instanceof Error ? error.message : 'Unknown error'}`);
199
+ return { success: false, exitCode: 1 };
200
+ }
201
+ }
202
+ };
203
+ // Search command
204
+ export const searchCommand = {
205
+ name: 'search',
206
+ description: 'Search memory with semantic/vector search',
207
+ options: [
208
+ {
209
+ name: 'query',
210
+ short: 'q',
211
+ description: 'Search query',
212
+ type: 'string',
213
+ required: true
214
+ },
215
+ {
216
+ name: 'namespace',
217
+ short: 'n',
218
+ description: 'Memory namespace',
219
+ type: 'string'
220
+ },
221
+ {
222
+ name: 'limit',
223
+ short: 'l',
224
+ description: 'Maximum results',
225
+ type: 'number',
226
+ default: 10
227
+ },
228
+ {
229
+ name: 'threshold',
230
+ description: 'Similarity threshold (0-1)',
231
+ type: 'number',
232
+ default: 0.7
233
+ },
234
+ {
235
+ name: 'type',
236
+ short: 't',
237
+ description: 'Search type (semantic, keyword, hybrid)',
238
+ type: 'string',
239
+ default: 'semantic',
240
+ choices: ['semantic', 'keyword', 'hybrid']
241
+ },
242
+ {
243
+ name: 'build-hnsw',
244
+ description: 'Build/rebuild pure-JS HNSW index before searching',
245
+ type: 'boolean',
246
+ default: false
247
+ }
248
+ ],
249
+ examples: [
250
+ { command: 'monomind memory search -q "authentication patterns"', description: 'Semantic search' },
251
+ { command: 'monomind memory search -q "JWT" -t keyword', description: 'Keyword search' },
252
+ { command: 'monomind memory search -q "test" --build-hnsw', description: 'Build HNSW index and search' }
253
+ ],
254
+ action: async (ctx) => {
255
+ const query = ctx.flags.query || ctx.args[0];
256
+ const namespace = ctx.flags.namespace || 'all';
257
+ const limit = ctx.flags.limit || 10;
258
+ const threshold = ctx.flags.threshold || 0.3;
259
+ const searchType = ctx.flags.type || 'semantic';
260
+ const buildHnsw = (ctx.flags['build-hnsw'] || ctx.flags.buildHnsw);
261
+ if (!query) {
262
+ output.printError('Query is required. Use --query or -q');
263
+ return { success: false, exitCode: 1 };
264
+ }
265
+ // Build/rebuild HNSW index if requested
266
+ if (buildHnsw) {
267
+ output.printInfo('Building HNSW index...');
268
+ try {
269
+ const { getHNSWIndex, getHNSWStatus } = await import('../memory/memory-initializer.js');
270
+ const startTime = Date.now();
271
+ const index = await getHNSWIndex({ forceRebuild: true });
272
+ const buildTime = Date.now() - startTime;
273
+ if (index) {
274
+ const status = getHNSWStatus();
275
+ output.printSuccess(`HNSW index built (${status.entryCount} vectors, ${buildTime}ms)`);
276
+ output.writeln(output.dim(` Dimensions: ${status.dimensions}, Metric: cosine`));
277
+ output.writeln(output.dim(` Complexity: O(log n) vs O(n) linear scan`));
278
+ }
279
+ else {
280
+ output.printWarning('HNSW index not available');
281
+ }
282
+ output.writeln();
283
+ }
284
+ catch (error) {
285
+ output.printWarning(`HNSW build failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
286
+ output.writeln(output.dim(' Falling back to brute-force search'));
287
+ output.writeln();
288
+ }
289
+ }
290
+ output.printInfo(`Searching: "${query}" (${searchType})`);
291
+ output.writeln();
292
+ // Use direct sql.js search with vector similarity
293
+ try {
294
+ const { searchEntries } = await import('../memory/memory-initializer.js');
295
+ const searchResult = await searchEntries({
296
+ query,
297
+ namespace,
298
+ limit,
299
+ threshold
300
+ });
301
+ if (!searchResult.success) {
302
+ output.printError(searchResult.error || 'Search failed');
303
+ return { success: false, exitCode: 1 };
304
+ }
305
+ const results = searchResult.results.map(r => ({
306
+ key: r.key,
307
+ score: r.score,
308
+ namespace: r.namespace,
309
+ preview: r.content
310
+ }));
311
+ if (ctx.flags.format === 'json') {
312
+ output.printJson({ query, searchType, results, searchTime: `${searchResult.searchTime}ms` });
313
+ return { success: true, data: results };
314
+ }
315
+ // Performance stats
316
+ output.writeln(output.dim(` Search time: ${searchResult.searchTime}ms`));
317
+ output.writeln();
318
+ if (results.length === 0) {
319
+ output.printWarning('No results found');
320
+ output.writeln(output.dim('Try: monomind memory store -k "key" --value "data"'));
321
+ return { success: true, data: [] };
322
+ }
323
+ output.printTable({
324
+ columns: [
325
+ { key: 'key', header: 'Key', width: 20 },
326
+ { key: 'score', header: 'Score', width: 8, align: 'right', format: (v) => Number(v).toFixed(2) },
327
+ { key: 'namespace', header: 'Namespace', width: 12 },
328
+ { key: 'preview', header: 'Preview', width: 35 }
329
+ ],
330
+ data: results
331
+ });
332
+ output.writeln();
333
+ output.printInfo(`Found ${results.length} results`);
334
+ return { success: true, data: results };
335
+ }
336
+ catch (error) {
337
+ output.printError(`Search failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
338
+ return { success: false, exitCode: 1 };
339
+ }
340
+ }
341
+ };
342
+ //# sourceMappingURL=memory-crud.js.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Memory List Commands
3
+ * formatRelativeTime, listCommand, editCommand, templatesCommand
4
+ */
5
+ import type { Command } from '../types.js';
6
+ export declare function formatRelativeTime(isoDate: string): string;
7
+ export declare const listCommand: Command;
8
+ export declare const editCommand: Command;
9
+ export declare const templatesCommand: Command;
10
+ //# sourceMappingURL=memory-list.d.ts.map
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Memory List Commands
3
+ * formatRelativeTime, listCommand, editCommand, templatesCommand
4
+ */
5
+ import { output } from '../output.js';
6
+ import { input } from '../prompt.js';
7
+ // Helper function to format relative time
8
+ export function formatRelativeTime(isoDate) {
9
+ const now = Date.now();
10
+ const date = new Date(isoDate).getTime();
11
+ const diff = now - date;
12
+ const seconds = Math.floor(diff / 1000);
13
+ const minutes = Math.floor(seconds / 60);
14
+ const hours = Math.floor(minutes / 60);
15
+ const days = Math.floor(hours / 24);
16
+ if (days > 0)
17
+ return `${days}d ago`;
18
+ if (hours > 0)
19
+ return `${hours}h ago`;
20
+ if (minutes > 0)
21
+ return `${minutes}m ago`;
22
+ return 'just now';
23
+ }
24
+ // List command
25
+ export const listCommand = {
26
+ name: 'list',
27
+ aliases: ['ls'],
28
+ description: 'List memory entries',
29
+ options: [
30
+ {
31
+ name: 'namespace',
32
+ short: 'n',
33
+ description: 'Filter by namespace',
34
+ type: 'string'
35
+ },
36
+ {
37
+ name: 'tags',
38
+ short: 't',
39
+ description: 'Filter by tags (comma-separated)',
40
+ type: 'string'
41
+ },
42
+ {
43
+ name: 'limit',
44
+ short: 'l',
45
+ description: 'Maximum entries',
46
+ type: 'number',
47
+ default: 20
48
+ }
49
+ ],
50
+ action: async (ctx) => {
51
+ const namespace = ctx.flags.namespace;
52
+ const limit = ctx.flags.limit;
53
+ // Use sql.js directly for consistent data access
54
+ try {
55
+ const { listEntries } = await import('../memory/memory-initializer.js');
56
+ const listResult = await listEntries({ namespace, limit, offset: 0 });
57
+ if (!listResult.success) {
58
+ output.printError(`Failed to list: ${listResult.error}`);
59
+ return { success: false, exitCode: 1 };
60
+ }
61
+ // Format entries for display
62
+ const entries = listResult.entries.map(e => ({
63
+ key: e.key,
64
+ namespace: e.namespace,
65
+ size: e.size + ' B',
66
+ vector: e.hasEmbedding ? '✓' : '-',
67
+ accessCount: e.accessCount,
68
+ updated: formatRelativeTime(e.updatedAt)
69
+ }));
70
+ if (ctx.flags.format === 'json') {
71
+ output.printJson(listResult.entries);
72
+ return { success: true, data: listResult.entries };
73
+ }
74
+ output.writeln();
75
+ output.writeln(output.bold('Memory Entries'));
76
+ output.writeln();
77
+ if (entries.length === 0) {
78
+ output.printWarning('No entries found');
79
+ output.printInfo('Store data: monomind memory store -k "key" --value "data"');
80
+ return { success: true, data: [] };
81
+ }
82
+ output.printTable({
83
+ columns: [
84
+ { key: 'key', header: 'Key', width: 25 },
85
+ { key: 'namespace', header: 'Namespace', width: 12 },
86
+ { key: 'size', header: 'Size', width: 10, align: 'right' },
87
+ { key: 'vector', header: 'Vector', width: 8, align: 'center' },
88
+ { key: 'accessCount', header: 'Accessed', width: 10, align: 'right' },
89
+ { key: 'updated', header: 'Updated', width: 12 }
90
+ ],
91
+ data: entries
92
+ });
93
+ output.writeln();
94
+ output.printInfo(`Showing ${entries.length} of ${listResult.total} entries`);
95
+ return { success: true, data: listResult.entries };
96
+ }
97
+ catch (error) {
98
+ output.printError(`Failed to list: ${error instanceof Error ? error.message : 'Unknown error'}`);
99
+ return { success: false, exitCode: 1 };
100
+ }
101
+ }
102
+ };
103
+ // Edit command
104
+ export const editCommand = {
105
+ name: 'edit',
106
+ description: 'Edit a memory entry (LanceDB, Memory Palace, or knowledge chunk)',
107
+ options: [
108
+ { name: 'key', short: 'k', description: 'Storage key', type: 'string' },
109
+ { name: 'namespace', short: 'n', description: 'Memory namespace', type: 'string', default: 'default' },
110
+ { name: 'value', description: 'New value/content', type: 'string' },
111
+ { name: 'source', short: 's', description: 'Source to edit: lancedb, palace, knowledge', type: 'string', default: 'lancedb', choices: ['lancedb', 'palace', 'knowledge'] },
112
+ { name: 'id', description: 'Entry ID (palace/knowledge)', type: 'string' }
113
+ ],
114
+ examples: [
115
+ { command: 'monomind memory edit -k "pattern/auth" --value "updated content"', description: 'Edit LanceDB entry' },
116
+ { command: 'monomind memory edit --source palace --id "abc123" --value "new content"', description: 'Edit Memory Palace drawer' },
117
+ { command: 'monomind memory edit --source knowledge --id "chunk-42" --value "updated"', description: 'Edit knowledge chunk' }
118
+ ],
119
+ action: async (ctx) => {
120
+ const source = ctx.flags.source || 'lancedb';
121
+ let value = ctx.flags.value || ctx.args[0];
122
+ const fs = await import('fs');
123
+ const path = await import('path');
124
+ if (source === 'lancedb') {
125
+ const key = ctx.flags.key;
126
+ const namespace = ctx.flags.namespace || 'default';
127
+ if (!key) {
128
+ output.printError('Key is required for lancedb edit. Use --key or -k');
129
+ return { success: false, exitCode: 1 };
130
+ }
131
+ if (!value && ctx.interactive) {
132
+ value = await input({ message: 'Enter new value:', validate: v => v.length > 0 || 'Value required' });
133
+ }
134
+ if (!value) {
135
+ output.printError('Value is required. Use --value');
136
+ return { success: false, exitCode: 1 };
137
+ }
138
+ try {
139
+ const { storeEntry } = await import('../memory/memory-initializer.js');
140
+ const result = await storeEntry({ key, value, namespace, generateEmbeddingFlag: true, upsert: true });
141
+ if (!result.success) {
142
+ output.printError(result.error || 'Failed to update');
143
+ return { success: false, exitCode: 1 };
144
+ }
145
+ output.printSuccess(`Updated "${key}" in namespace "${namespace}"`);
146
+ return { success: true, data: result };
147
+ }
148
+ catch (error) {
149
+ output.printError(`Failed to edit: ${error instanceof Error ? error.message : 'Unknown error'}`);
150
+ return { success: false, exitCode: 1 };
151
+ }
152
+ }
153
+ // palace or knowledge — JSONL file edit
154
+ const id = ctx.flags.id;
155
+ if (!id) {
156
+ output.printError('Entry ID is required for palace/knowledge edit. Use --id');
157
+ return { success: false, exitCode: 1 };
158
+ }
159
+ if (!/^[a-zA-Z0-9_\-]{1,128}$/.test(id)) {
160
+ output.printError('ID must be 1-128 chars: alphanumeric, underscore, or hyphen only');
161
+ return { success: false, exitCode: 1 };
162
+ }
163
+ const filePath = source === 'palace'
164
+ ? path.join(process.cwd(), '.monomind', 'palace', 'drawers.jsonl')
165
+ : path.join(process.cwd(), '.monomind', 'knowledge', 'chunks.jsonl');
166
+ if (!fs.existsSync(filePath)) {
167
+ output.printError(`File not found: ${filePath}`);
168
+ return { success: false, exitCode: 1 };
169
+ }
170
+ const MAX_MEMORY_FILE_BYTES = 50 * 1024 * 1024; // 50 MB
171
+ if (fs.statSync(filePath).size > MAX_MEMORY_FILE_BYTES) {
172
+ output.printError(`Memory file too large (> 50 MB): ${filePath}`);
173
+ return { success: false, exitCode: 1 };
174
+ }
175
+ let entries;
176
+ try {
177
+ const raw = fs.readFileSync(filePath, 'utf8');
178
+ entries = [];
179
+ for (const line of raw.split('\n').filter(Boolean)) {
180
+ try {
181
+ entries.push(JSON.parse(line));
182
+ }
183
+ catch {
184
+ output.printError(`Malformed JSONL entry in ${source} file`);
185
+ return { success: false, exitCode: 1 };
186
+ }
187
+ }
188
+ }
189
+ catch (err) {
190
+ output.printError(`Failed to read ${source} file: ${err instanceof Error ? err.message : 'Unknown error'}`);
191
+ return { success: false, exitCode: 1 };
192
+ }
193
+ const idx = entries.findIndex(e => e.id === id);
194
+ if (idx === -1) {
195
+ output.printWarning(`Entry not found with id "${id}"`);
196
+ return { success: false, exitCode: 1 };
197
+ }
198
+ if (!value && ctx.interactive) {
199
+ output.writeln(output.dim('Current content:'));
200
+ output.writeln(entries[idx].content || '(empty)');
201
+ output.writeln();
202
+ value = await input({ message: 'Enter new content:', validate: v => v.length > 0 || 'Content required' });
203
+ }
204
+ if (!value) {
205
+ output.printError('Value is required. Use --value');
206
+ return { success: false, exitCode: 1 };
207
+ }
208
+ entries[idx] = { ...entries[idx], content: value, ts: new Date().toISOString() };
209
+ try {
210
+ const tmpPath = filePath + '.tmp';
211
+ fs.writeFileSync(tmpPath, entries.map(e => JSON.stringify(e)).join('\n') + '\n');
212
+ fs.renameSync(tmpPath, filePath);
213
+ output.printSuccess(`Updated ${source} entry "${id}"`);
214
+ return { success: true, data: entries[idx] };
215
+ }
216
+ catch (err) {
217
+ output.printError(`Failed to write ${source} file: ${err instanceof Error ? err.message : 'Unknown error'}`);
218
+ return { success: false, exitCode: 1 };
219
+ }
220
+ }
221
+ };
222
+ // Templates command
223
+ export const templatesCommand = {
224
+ name: 'templates',
225
+ description: 'Show best-practice templates for memory entries',
226
+ options: [
227
+ { name: 'type', short: 't', description: 'Template type: user, feedback, project, reference', type: 'string', choices: ['user', 'feedback', 'project', 'reference'] }
228
+ ],
229
+ examples: [
230
+ { command: 'monomind memory templates', description: 'Show all templates' },
231
+ { command: 'monomind memory templates -t feedback', description: 'Show feedback template only' }
232
+ ],
233
+ action: async (ctx) => {
234
+ const filter = ctx.flags.type;
235
+ const templates = {
236
+ user: {
237
+ label: 'User Memory',
238
+ description: 'Role, goals, preferences, knowledge level',
239
+ example: [
240
+ '---',
241
+ 'name: user_role',
242
+ 'description: <one-line summary of user role and context>',
243
+ 'type: user',
244
+ '---',
245
+ '',
246
+ '<Role and experience description. What does the user know well? What are they new to?>',
247
+ 'Frame explanations accordingly.'
248
+ ].join('\n')
249
+ },
250
+ feedback: {
251
+ label: 'Feedback Memory',
252
+ description: 'How to approach work — corrections and validated choices',
253
+ example: [
254
+ '---',
255
+ 'name: feedback_<topic>',
256
+ 'description: <one-line rule that triggers on lookup>',
257
+ 'type: feedback',
258
+ '---',
259
+ '',
260
+ '<The rule itself — what to do or avoid.>',
261
+ '',
262
+ '**Why:** <Reason the user gave — past incident, strong preference, etc.>',
263
+ '',
264
+ '**How to apply:** <When does this kick in? What edge cases does it cover?>'
265
+ ].join('\n')
266
+ },
267
+ project: {
268
+ label: 'Project Memory',
269
+ description: 'Ongoing work context, goals, decisions, deadlines',
270
+ example: [
271
+ '---',
272
+ 'name: project_<initiative>',
273
+ 'description: <one-line fact about the project decision or constraint>',
274
+ 'type: project',
275
+ '---',
276
+ '',
277
+ '<The fact or decision — what is happening and what was decided.>',
278
+ '',
279
+ '**Why:** <Motivation — constraint, deadline, stakeholder ask, compliance issue.>',
280
+ '',
281
+ '**How to apply:** <How should this shape future suggestions and decisions?>'
282
+ ].join('\n')
283
+ },
284
+ reference: {
285
+ label: 'Reference Memory',
286
+ description: 'Pointers to external resources and where to find information',
287
+ example: [
288
+ '---',
289
+ 'name: reference_<resource>',
290
+ 'description: <what this resource contains and when to use it>',
291
+ 'type: reference',
292
+ '---',
293
+ '',
294
+ '<Resource name and location (URL, project name, channel, etc.)>',
295
+ '',
296
+ 'Use this when: <specific scenarios where this reference is relevant>.'
297
+ ].join('\n')
298
+ }
299
+ };
300
+ output.writeln();
301
+ output.writeln(output.bold('Memory Entry Templates'));
302
+ output.writeln(output.dim('Best-practice scaffolds for .claude/projects/.../memory/ entries'));
303
+ output.writeln();
304
+ const keys = filter ? [filter] : Object.keys(templates);
305
+ for (const key of keys) {
306
+ const t = templates[key];
307
+ if (!t) {
308
+ output.printError(`Unknown type: "${key}". Valid types: user, feedback, project, reference`);
309
+ return { success: false, exitCode: 1 };
310
+ }
311
+ output.writeln(output.bold(`── ${t.label} (--type ${key})`));
312
+ output.writeln(output.dim(` ${t.description}`));
313
+ output.writeln();
314
+ output.writeln(t.example);
315
+ output.writeln();
316
+ }
317
+ output.writeln(output.dim('Save with: monomind memory store -k "<name>" --value "<content>" --namespace auto-memory'));
318
+ return { success: true };
319
+ }
320
+ };
321
+ //# sourceMappingURL=memory-list.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Memory Transfer Commands
3
+ * compressCommand, exportCommand, importCommand
4
+ */
5
+ import type { Command } from '../types.js';
6
+ export declare const compressCommand: Command;
7
+ export declare const exportCommand: Command;
8
+ export declare const importCommand: Command;
9
+ //# sourceMappingURL=memory-transfer.d.ts.map