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,290 @@
1
+ /**
2
+ * Neural registry commands — list and import models from IPFS
3
+ */
4
+ import { output } from '../output.js';
5
+ // ─── list subcommand ─────────────────────────────────────────────────────────
6
+ export const listCommand = {
7
+ name: 'list',
8
+ description: 'List available pre-trained models from the official registry',
9
+ options: [
10
+ { name: 'category', type: 'string', description: 'Filter by category (security, quality, performance, etc.)' },
11
+ { name: 'format', short: 'f', type: 'string', description: 'Output format: table, json, simple', default: 'table' },
12
+ { name: 'cid', type: 'string', description: 'Custom registry CID (default: official registry)' },
13
+ ],
14
+ examples: [
15
+ { command: 'monomind neural list', description: 'List all available models' },
16
+ { command: 'monomind neural list --category security', description: 'List only security models' },
17
+ { command: 'monomind neural list -f json', description: 'Output as JSON' },
18
+ ],
19
+ action: async (ctx) => {
20
+ const category = ctx.flags.category;
21
+ const format = ctx.flags.format || 'table';
22
+ const customCid = ctx.flags.cid;
23
+ const registryCid = customCid || 'QmNr1yYMKi7YBaL8JSztQyuB5ZUaTdRMLxJC1pBpGbjsTc';
24
+ output.writeln();
25
+ output.writeln(output.bold('Pre-trained Model Registry'));
26
+ output.writeln(output.dim('─'.repeat(60)));
27
+ const spinner = output.createSpinner({ text: 'Fetching model registry...', spinner: 'dots' });
28
+ spinner.start();
29
+ try {
30
+ const gateways = ['https://gateway.pinata.cloud', 'https://ipfs.io', 'https://dweb.link'];
31
+ let registry = null;
32
+ for (const gateway of gateways) {
33
+ try {
34
+ const response = await fetch(`${gateway}/ipfs/${registryCid}`, {
35
+ signal: AbortSignal.timeout(15000),
36
+ headers: { 'Accept': 'application/json' },
37
+ });
38
+ if (response.ok) {
39
+ const MAX_REGISTRY_BYTES = 50 * 1024 * 1024;
40
+ const buf = await response.arrayBuffer();
41
+ if (buf.byteLength > MAX_REGISTRY_BYTES)
42
+ throw new Error(`Registry response too large: ${buf.byteLength} bytes`);
43
+ registry = JSON.parse(new TextDecoder().decode(buf));
44
+ break;
45
+ }
46
+ }
47
+ catch {
48
+ continue;
49
+ }
50
+ }
51
+ if (!registry || !registry.models) {
52
+ spinner.fail('Could not fetch model registry');
53
+ return { success: false, exitCode: 1 };
54
+ }
55
+ let models = registry.models;
56
+ if (category) {
57
+ models = models.filter(m => m.category === category ||
58
+ m.id.includes(category) ||
59
+ m.name.toLowerCase().includes(category.toLowerCase()));
60
+ spinner.succeed(`Found ${models.length} models matching "${category}"`);
61
+ }
62
+ else {
63
+ spinner.succeed(`Found ${registry.models.length} models`);
64
+ }
65
+ if (models.length === 0) {
66
+ output.writeln(output.warning(`No models found for category: ${category}`));
67
+ output.writeln(output.dim('Available categories: security, quality, performance, testing, api, debugging, refactoring, documentation'));
68
+ return { success: false, exitCode: 1 };
69
+ }
70
+ output.writeln();
71
+ if (format === 'json') {
72
+ output.writeln(JSON.stringify(models, null, 2));
73
+ }
74
+ else if (format === 'simple') {
75
+ for (const model of models) {
76
+ output.writeln(`${model.id} (${model.category}) - ${model.patterns.length} patterns, ${(model.metadata.accuracy * 100).toFixed(0)}% accuracy`);
77
+ }
78
+ }
79
+ else {
80
+ output.printTable({
81
+ columns: [
82
+ { key: 'id', header: 'Model ID', width: 35 },
83
+ { key: 'category', header: 'Category', width: 14 },
84
+ { key: 'patterns', header: 'Patterns', width: 10 },
85
+ { key: 'accuracy', header: 'Accuracy', width: 10 },
86
+ { key: 'usage', header: 'Usage', width: 10 },
87
+ ],
88
+ data: models.map(m => ({
89
+ id: m.id, category: m.category,
90
+ patterns: String(m.patterns.length),
91
+ accuracy: `${(m.metadata.accuracy * 100).toFixed(0)}%`,
92
+ usage: m.metadata.totalUsage.toLocaleString(),
93
+ })),
94
+ });
95
+ output.writeln();
96
+ output.writeln(output.dim('Registry CID: ' + registryCid));
97
+ output.writeln();
98
+ output.writeln(output.bold('Import Commands:'));
99
+ output.writeln(output.dim(' All models: ') + `monomind neural import --cid ${registryCid}`);
100
+ if (category) {
101
+ output.writeln(output.dim(` ${category} only: `) + `monomind neural import --cid ${registryCid} --category ${category}`);
102
+ }
103
+ else {
104
+ output.writeln(output.dim(' By category: ') + `monomind neural import --cid ${registryCid} --category <category>`);
105
+ }
106
+ }
107
+ return { success: true };
108
+ }
109
+ catch (error) {
110
+ spinner.fail(`Failed to list models: ${error instanceof Error ? error.message : String(error)}`);
111
+ return { success: false, exitCode: 1 };
112
+ }
113
+ },
114
+ };
115
+ // ─── import subcommand ───────────────────────────────────────────────────────
116
+ export const importCommand = {
117
+ name: 'import',
118
+ description: 'Import trained models from IPFS with signature verification',
119
+ options: [
120
+ { name: 'cid', short: 'c', type: 'string', description: 'IPFS CID to import from' },
121
+ { name: 'file', short: 'f', type: 'string', description: 'Local file to import' },
122
+ { name: 'verify', short: 'v', type: 'boolean', description: 'Verify Ed25519 signature', default: 'true' },
123
+ { name: 'merge', type: 'boolean', description: 'Merge with existing patterns (vs replace)', default: 'true' },
124
+ { name: 'category', type: 'string', description: 'Only import patterns from specific category' },
125
+ ],
126
+ examples: [
127
+ { command: 'monomind neural import --cid QmXxx...', description: 'Import from IPFS' },
128
+ { command: 'monomind neural import -f ./patterns.json --verify', description: 'Import from file' },
129
+ { command: 'monomind neural import --cid QmNr1yYMK... --category security', description: 'Import only security patterns' },
130
+ ],
131
+ action: async (ctx) => {
132
+ const cid = ctx.flags.cid;
133
+ const file = ctx.flags.file;
134
+ const verifySignature = ctx.flags.verify !== false;
135
+ const merge = ctx.flags.merge !== false;
136
+ const categoryFilter = ctx.flags.category;
137
+ if (!cid && !file) {
138
+ output.writeln(output.error('Either --cid or --file is required'));
139
+ return { success: false, exitCode: 1 };
140
+ }
141
+ output.writeln();
142
+ output.writeln(output.bold('Secure Model Import'));
143
+ output.writeln(output.dim('─'.repeat(50)));
144
+ const spinner = output.createSpinner({ text: 'Fetching model...', spinner: 'dots' });
145
+ spinner.start();
146
+ try {
147
+ const fs = await import('fs');
148
+ const path = await import('path');
149
+ const crypto = await import('crypto');
150
+ let importData = null;
151
+ if (cid) {
152
+ const gateways = ['https://gateway.pinata.cloud', 'https://ipfs.io', 'https://dweb.link'];
153
+ for (const gateway of gateways) {
154
+ try {
155
+ spinner.setText(`Fetching from ${gateway}...`);
156
+ const response = await fetch(`${gateway}/ipfs/${cid}`, {
157
+ signal: AbortSignal.timeout(30000),
158
+ headers: { 'Accept': 'application/json' },
159
+ });
160
+ if (response.ok) {
161
+ const MAX_IMPORT_BYTES = 50 * 1024 * 1024;
162
+ const importBuf = await response.arrayBuffer();
163
+ if (importBuf.byteLength > MAX_IMPORT_BYTES)
164
+ throw new Error(`Import response too large: ${importBuf.byteLength} bytes`);
165
+ importData = JSON.parse(new TextDecoder().decode(importBuf));
166
+ break;
167
+ }
168
+ }
169
+ catch {
170
+ continue;
171
+ }
172
+ }
173
+ if (!importData) {
174
+ spinner.fail('Could not fetch from any IPFS gateway');
175
+ return { success: false, exitCode: 1 };
176
+ }
177
+ }
178
+ else {
179
+ if (!fs.existsSync(file)) {
180
+ spinner.fail(`File not found: ${file}`);
181
+ return { success: false, exitCode: 1 };
182
+ }
183
+ const stat = fs.statSync(file);
184
+ const MAX_IMPORT_BYTES = 50 * 1024 * 1024;
185
+ if (stat.size > MAX_IMPORT_BYTES) {
186
+ spinner.fail(`Import file too large: ${stat.size} bytes (max ${MAX_IMPORT_BYTES})`);
187
+ return { success: false, exitCode: 1 };
188
+ }
189
+ importData = JSON.parse(fs.readFileSync(file, 'utf8'));
190
+ }
191
+ if (!importData) {
192
+ spinner.fail('No import data available');
193
+ return { success: false, exitCode: 1 };
194
+ }
195
+ // SECURITY: Verify signature — fail-CLOSED (no bypass if missing or malformed)
196
+ if (verifySignature) {
197
+ if (!importData.signature || !importData.publicKey) {
198
+ spinner.fail('SECURITY: --verify requested but payload is unsigned. Aborting (use --no-verify to override).');
199
+ return { success: false, exitCode: 1 };
200
+ }
201
+ spinner.setText('Verifying Ed25519 signature...');
202
+ try {
203
+ const { webcrypto } = crypto;
204
+ const publicKeyHex = importData.publicKey.replace('ed25519:', '');
205
+ const publicKeyBytes = Buffer.from(publicKeyHex, 'hex');
206
+ const signatureBytes = Buffer.from(importData.signature, 'hex');
207
+ const publicKey = await webcrypto.subtle.importKey('raw', publicKeyBytes, { name: 'Ed25519' }, false, ['verify']);
208
+ const dataBytes = new TextEncoder().encode(JSON.stringify(importData.pinataContent));
209
+ const valid = await webcrypto.subtle.verify('Ed25519', publicKey, signatureBytes, dataBytes);
210
+ if (!valid) {
211
+ spinner.fail('Signature verification FAILED - data may be tampered');
212
+ return { success: false, exitCode: 1 };
213
+ }
214
+ output.writeln(output.success('Signature verified'));
215
+ }
216
+ catch (err) {
217
+ // FAIL-CLOSED: any error during verification must reject the import
218
+ spinner.fail(`SECURITY: Signature verification error: ${err instanceof Error ? err.message : String(err)}. Aborting.`);
219
+ return { success: false, exitCode: 1 };
220
+ }
221
+ }
222
+ spinner.setText('Importing patterns...');
223
+ const content = importData.pinataContent || importData;
224
+ let patterns = [];
225
+ const registry = content;
226
+ if (registry.models && Array.isArray(registry.models)) {
227
+ for (const model of registry.models) {
228
+ if (!categoryFilter || model.category === categoryFilter || model.id.includes(categoryFilter)) {
229
+ for (const pattern of model.patterns || []) {
230
+ patterns.push({ ...pattern, category: model.category });
231
+ }
232
+ }
233
+ }
234
+ }
235
+ else {
236
+ patterns = content.patterns || [];
237
+ }
238
+ if (categoryFilter && patterns.length > 0) {
239
+ patterns = patterns.filter(p => p.category === categoryFilter || p.trigger.includes(categoryFilter));
240
+ }
241
+ // Validate patterns (security check)
242
+ const suspicious = ['eval(', 'Function(', 'exec(', 'spawn(', 'child_process', 'rm -rf', 'sudo', '<script>', 'javascript:', 'data:'];
243
+ const validPatterns = patterns.filter(p => {
244
+ const c = JSON.stringify(p);
245
+ return !suspicious.some(s => c.includes(s));
246
+ });
247
+ if (validPatterns.length < patterns.length) {
248
+ output.writeln(output.warning(`Filtered ${patterns.length - validPatterns.length} suspicious patterns`));
249
+ }
250
+ const memoryDir = path.join(process.cwd(), '.monomind', 'neural');
251
+ if (!fs.existsSync(memoryDir))
252
+ fs.mkdirSync(memoryDir, { recursive: true });
253
+ const patternsFile = path.join(memoryDir, 'patterns.json');
254
+ let existingPatterns = [];
255
+ if (merge && fs.existsSync(patternsFile) && fs.statSync(patternsFile).size <= 50 * 1024 * 1024) {
256
+ existingPatterns = JSON.parse(fs.readFileSync(patternsFile, 'utf8'));
257
+ }
258
+ const existingIds = new Set(existingPatterns.map(p => p.id));
259
+ const newPatterns = validPatterns.filter(p => !existingIds.has(p.id));
260
+ const finalPatterns = merge ? [...existingPatterns, ...newPatterns] : validPatterns;
261
+ const tmpPatterns = `${patternsFile}.${process.pid}.${Date.now()}.tmp`;
262
+ fs.writeFileSync(tmpPatterns, JSON.stringify(finalPatterns, null, 2), { flag: 'wx' });
263
+ fs.renameSync(tmpPatterns, patternsFile);
264
+ spinner.succeed('Import complete');
265
+ output.writeln();
266
+ output.printTable({
267
+ columns: [
268
+ { key: 'metric', header: 'Metric', width: 25 },
269
+ { key: 'value', header: 'Value', width: 20 },
270
+ ],
271
+ data: [
272
+ { metric: 'Patterns Imported', value: String(validPatterns.length) },
273
+ { metric: 'New Patterns', value: String(newPatterns.length) },
274
+ { metric: 'Total Patterns', value: String(finalPatterns.length) },
275
+ { metric: 'Signature Verified', value: importData.signature ? 'Yes' : 'N/A' },
276
+ { metric: 'Merge Mode', value: merge ? 'Yes' : 'Replace' },
277
+ ],
278
+ });
279
+ output.writeln();
280
+ output.writeln(output.success('Patterns imported and ready to use'));
281
+ output.writeln(output.dim('Run "monomind neural patterns --action list" to see imported patterns'));
282
+ return { success: true };
283
+ }
284
+ catch (error) {
285
+ spinner.fail(`Import failed: ${error instanceof Error ? error.message : String(error)}`);
286
+ return { success: false, exitCode: 1 };
287
+ }
288
+ },
289
+ };
290
+ //# sourceMappingURL=neural-registry.js.map