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,302 @@
1
+ /**
2
+ * Analyze complexity and symbols subcommands
3
+ * Complexity analysis and symbol extraction from code files
4
+ */
5
+ import { output } from '../output.js';
6
+ import * as fs from 'fs/promises';
7
+ import { resolve } from 'path';
8
+ import { getASTAnalyzer, safeWriteOutputFile, scanSourceFiles, fallbackAnalyze } from './analyze.js';
9
+ import { truncatePathAst, formatComplexityValueAst, getTypeMarkerAst } from './analyze-ast.js';
10
+ /**
11
+ * Complexity analysis subcommand
12
+ */
13
+ export const complexityAstCommand = {
14
+ name: 'complexity',
15
+ aliases: ['cx'],
16
+ description: 'Analyze code complexity metrics',
17
+ options: [
18
+ {
19
+ name: 'threshold',
20
+ short: 't',
21
+ description: 'Complexity threshold to flag (default: 10)',
22
+ type: 'number',
23
+ default: 10,
24
+ },
25
+ {
26
+ name: 'format',
27
+ short: 'f',
28
+ description: 'Output format (text, json)',
29
+ type: 'string',
30
+ default: 'text',
31
+ choices: ['text', 'json'],
32
+ },
33
+ {
34
+ name: 'output',
35
+ short: 'o',
36
+ description: 'Output file path',
37
+ type: 'string',
38
+ },
39
+ ],
40
+ examples: [
41
+ { command: 'monomind analyze complexity src/', description: 'Analyze complexity' },
42
+ { command: 'monomind analyze complexity src/ --threshold 15', description: 'Flag high complexity' },
43
+ ],
44
+ action: async (ctx) => {
45
+ const targetPath = ctx.args[0] || ctx.cwd;
46
+ const threshold = ctx.flags.threshold || 10;
47
+ const formatType = ctx.flags.format || 'text';
48
+ const outputFile = ctx.flags.output;
49
+ output.printInfo(`Analyzing complexity: ${output.highlight(targetPath)}`);
50
+ output.writeln();
51
+ const spinner = output.createSpinner({ text: 'Calculating complexity...', spinner: 'dots' });
52
+ spinner.start();
53
+ try {
54
+ const astModule = await getASTAnalyzer();
55
+ const resolvedPath = resolve(targetPath);
56
+ const stat = await fs.stat(resolvedPath);
57
+ const files = stat.isDirectory() ? await scanSourceFiles(resolvedPath) : [resolvedPath];
58
+ const results = [];
59
+ for (const file of files.slice(0, 100)) {
60
+ try {
61
+ const content = await fs.readFile(file, 'utf-8');
62
+ let analysis;
63
+ if (astModule) {
64
+ const analyzer = astModule.createASTAnalyzer();
65
+ analysis = analyzer.analyze(content, file);
66
+ }
67
+ else {
68
+ analysis = fallbackAnalyze(content, file);
69
+ }
70
+ const flagged = analysis.complexity.cyclomatic > threshold;
71
+ const rating = analysis.complexity.cyclomatic <= 5 ? 'Simple' :
72
+ analysis.complexity.cyclomatic <= 10 ? 'Moderate' :
73
+ analysis.complexity.cyclomatic <= 20 ? 'Complex' : 'Very Complex';
74
+ results.push({
75
+ file: file,
76
+ cyclomatic: analysis.complexity.cyclomatic,
77
+ cognitive: analysis.complexity.cognitive,
78
+ loc: analysis.complexity.loc,
79
+ commentDensity: analysis.complexity.commentDensity,
80
+ rating,
81
+ flagged,
82
+ });
83
+ }
84
+ catch {
85
+ // Skip files that can't be analyzed
86
+ }
87
+ }
88
+ spinner.stop();
89
+ // Sort by complexity descending
90
+ results.sort((a, b) => b.cyclomatic - a.cyclomatic);
91
+ const flaggedCount = results.filter(r => r.flagged).length;
92
+ const avgComplexity = results.length > 0
93
+ ? results.reduce((sum, r) => sum + r.cyclomatic, 0) / results.length
94
+ : 0;
95
+ if (formatType === 'json') {
96
+ const jsonOutput = { files: results, summary: { total: results.length, flagged: flaggedCount, avgComplexity, threshold } };
97
+ if (outputFile) {
98
+ await safeWriteOutputFile(outputFile, JSON.stringify(jsonOutput, null, 2));
99
+ output.printSuccess(`Results written to ${outputFile}`);
100
+ }
101
+ else {
102
+ output.printJson(jsonOutput);
103
+ }
104
+ return { success: true, data: jsonOutput };
105
+ }
106
+ // Summary
107
+ output.printBox([
108
+ `Files analyzed: ${results.length}`,
109
+ `Threshold: ${threshold}`,
110
+ `Flagged files: ${flaggedCount > 0 ? output.error(String(flaggedCount)) : output.success('0')}`,
111
+ `Average complexity: ${formatComplexityValueAst(Math.round(avgComplexity))}`,
112
+ ].join('\n'), 'Complexity Analysis');
113
+ // Show flagged files first
114
+ if (flaggedCount > 0) {
115
+ output.writeln();
116
+ output.writeln(output.bold(output.warning(`High Complexity Files (>${threshold})`)));
117
+ output.writeln(output.dim('-'.repeat(60)));
118
+ const flaggedFiles = results.filter(r => r.flagged).slice(0, 10);
119
+ output.printTable({
120
+ columns: [
121
+ { key: 'file', header: 'File', width: 40, format: (v) => truncatePathAst(v) },
122
+ { key: 'cyclomatic', header: 'Cyclo', width: 8, align: 'right', format: (v) => output.error(String(v)) },
123
+ { key: 'cognitive', header: 'Cogni', width: 8, align: 'right' },
124
+ { key: 'loc', header: 'LOC', width: 8, align: 'right' },
125
+ { key: 'rating', header: 'Rating', width: 15 },
126
+ ],
127
+ data: flaggedFiles,
128
+ });
129
+ }
130
+ // Show all files in table format
131
+ output.writeln();
132
+ output.writeln(output.bold('All Files'));
133
+ output.writeln(output.dim('-'.repeat(60)));
134
+ const displayFiles = results.slice(0, 15);
135
+ output.printTable({
136
+ columns: [
137
+ { key: 'file', header: 'File', width: 40, format: (v) => truncatePathAst(v) },
138
+ { key: 'cyclomatic', header: 'Cyclo', width: 8, align: 'right', format: (v) => formatComplexityValueAst(v) },
139
+ { key: 'cognitive', header: 'Cogni', width: 8, align: 'right' },
140
+ { key: 'loc', header: 'LOC', width: 8, align: 'right' },
141
+ ],
142
+ data: displayFiles,
143
+ });
144
+ if (results.length > 15) {
145
+ output.writeln(output.dim(` ... and ${results.length - 15} more files`));
146
+ }
147
+ if (outputFile) {
148
+ await safeWriteOutputFile(outputFile, JSON.stringify({ files: results, summary: { total: results.length, flagged: flaggedCount, avgComplexity, threshold } }, null, 2));
149
+ output.printSuccess(`Results written to ${outputFile}`);
150
+ }
151
+ return { success: true, data: { files: results, flaggedCount } };
152
+ }
153
+ catch (error) {
154
+ spinner.stop();
155
+ const message = error instanceof Error ? error.message : String(error);
156
+ output.printError(`Complexity analysis failed: ${message}`);
157
+ return { success: false, exitCode: 1 };
158
+ }
159
+ },
160
+ };
161
+ /**
162
+ * Symbol extraction subcommand
163
+ */
164
+ export const symbolsCommand = {
165
+ name: 'symbols',
166
+ aliases: ['sym'],
167
+ description: 'Extract and list code symbols (functions, classes, types)',
168
+ options: [
169
+ {
170
+ name: 'type',
171
+ short: 't',
172
+ description: 'Filter by symbol type (function, class, all)',
173
+ type: 'string',
174
+ default: 'all',
175
+ choices: ['function', 'class', 'all'],
176
+ },
177
+ {
178
+ name: 'format',
179
+ short: 'f',
180
+ description: 'Output format (text, json)',
181
+ type: 'string',
182
+ default: 'text',
183
+ choices: ['text', 'json'],
184
+ },
185
+ {
186
+ name: 'output',
187
+ short: 'o',
188
+ description: 'Output file path',
189
+ type: 'string',
190
+ },
191
+ ],
192
+ examples: [
193
+ { command: 'monomind analyze symbols src/', description: 'Extract all symbols' },
194
+ { command: 'monomind analyze symbols src/ --type function', description: 'Only functions' },
195
+ { command: 'monomind analyze symbols src/ --format json', description: 'JSON output' },
196
+ ],
197
+ action: async (ctx) => {
198
+ const targetPath = ctx.args[0] || ctx.cwd;
199
+ const symbolType = ctx.flags.type || 'all';
200
+ const formatType = ctx.flags.format || 'text';
201
+ const outputFile = ctx.flags.output;
202
+ output.printInfo(`Extracting symbols: ${output.highlight(targetPath)}`);
203
+ output.writeln();
204
+ const spinner = output.createSpinner({ text: 'Parsing code...', spinner: 'dots' });
205
+ spinner.start();
206
+ try {
207
+ const astModule = await getASTAnalyzer();
208
+ const resolvedPath = resolve(targetPath);
209
+ const stat = await fs.stat(resolvedPath);
210
+ const files = stat.isDirectory() ? await scanSourceFiles(resolvedPath) : [resolvedPath];
211
+ const symbols = [];
212
+ for (const file of files.slice(0, 100)) {
213
+ try {
214
+ const content = await fs.readFile(file, 'utf-8');
215
+ let analysis;
216
+ if (astModule) {
217
+ const analyzer = astModule.createASTAnalyzer();
218
+ analysis = analyzer.analyze(content, file);
219
+ }
220
+ else {
221
+ analysis = fallbackAnalyze(content, file);
222
+ }
223
+ if (symbolType === 'all' || symbolType === 'function') {
224
+ for (const fn of analysis.functions) {
225
+ symbols.push({
226
+ name: fn.name,
227
+ type: 'function',
228
+ file,
229
+ startLine: fn.startLine,
230
+ endLine: fn.endLine,
231
+ });
232
+ }
233
+ }
234
+ if (symbolType === 'all' || symbolType === 'class') {
235
+ for (const cls of analysis.classes) {
236
+ symbols.push({
237
+ name: cls.name,
238
+ type: 'class',
239
+ file,
240
+ startLine: cls.startLine,
241
+ endLine: cls.endLine,
242
+ });
243
+ }
244
+ }
245
+ }
246
+ catch {
247
+ // Skip files that can't be parsed
248
+ }
249
+ }
250
+ spinner.stop();
251
+ // Sort by file then name
252
+ symbols.sort((a, b) => a.file.localeCompare(b.file) || a.name.localeCompare(b.name));
253
+ if (formatType === 'json') {
254
+ if (outputFile) {
255
+ await safeWriteOutputFile(outputFile, JSON.stringify(symbols, null, 2));
256
+ output.printSuccess(`Results written to ${outputFile}`);
257
+ }
258
+ else {
259
+ output.printJson(symbols);
260
+ }
261
+ return { success: true, data: symbols };
262
+ }
263
+ // Summary
264
+ const functionCount = symbols.filter(s => s.type === 'function').length;
265
+ const classCount = symbols.filter(s => s.type === 'class').length;
266
+ output.printBox([
267
+ `Total symbols: ${symbols.length}`,
268
+ `Functions: ${functionCount}`,
269
+ `Classes: ${classCount}`,
270
+ `Files: ${files.length}`,
271
+ ].join('\n'), 'Symbol Extraction');
272
+ output.writeln();
273
+ output.writeln(output.bold('Symbols'));
274
+ output.writeln(output.dim('-'.repeat(60)));
275
+ const displaySymbols = symbols.slice(0, 30);
276
+ output.printTable({
277
+ columns: [
278
+ { key: 'type', header: 'Type', width: 10, format: (v) => getTypeMarkerAst(v) },
279
+ { key: 'name', header: 'Name', width: 30 },
280
+ { key: 'file', header: 'File', width: 35, format: (v) => truncatePathAst(v, 33) },
281
+ { key: 'startLine', header: 'Line', width: 8, align: 'right' },
282
+ ],
283
+ data: displaySymbols,
284
+ });
285
+ if (symbols.length > 30) {
286
+ output.writeln(output.dim(` ... and ${symbols.length - 30} more symbols`));
287
+ }
288
+ if (outputFile) {
289
+ await safeWriteOutputFile(outputFile, JSON.stringify(symbols, null, 2));
290
+ output.printSuccess(`Results written to ${outputFile}`);
291
+ }
292
+ return { success: true, data: symbols };
293
+ }
294
+ catch (error) {
295
+ spinner.stop();
296
+ const message = error instanceof Error ? error.message : String(error);
297
+ output.printError(`Symbol extraction failed: ${message}`);
298
+ return { success: false, exitCode: 1 };
299
+ }
300
+ },
301
+ };
302
+ //# sourceMappingURL=analyze-symbols.js.map
@@ -14,6 +14,44 @@
14
14
  * github.com/monoes/monomind
15
15
  */
16
16
  import type { Command } from '../types.js';
17
+ type AnalyzerModule = any;
18
+ export declare function getASTAnalyzer(): Promise<AnalyzerModule | null>;
19
+ export declare function getGraphAnalyzer(): Promise<AnalyzerModule | null>;
20
+ /**
21
+ * Write analysis output to a file, constraining the path to the current working
22
+ * directory to prevent path traversal attacks via --output /etc/cron.d/x or
23
+ * similar. Throws if the resolved path escapes cwd.
24
+ */
25
+ export declare function safeWriteOutputFile(outputFile: string, data: string): Promise<void>;
26
+ /**
27
+ * Helper: Scan directory for source files
28
+ */
29
+ export declare function scanSourceFiles(dir: string, maxDepth?: number): Promise<string[]>;
30
+ /**
31
+ * Fallback analysis when monovector is not available
32
+ */
33
+ export declare function fallbackAnalyze(code: string, filePath: string): {
34
+ filePath: string;
35
+ language: string;
36
+ functions: {
37
+ name: string;
38
+ startLine: number;
39
+ endLine: number;
40
+ }[];
41
+ classes: {
42
+ name: string;
43
+ startLine: number;
44
+ endLine: number;
45
+ }[];
46
+ imports: string[];
47
+ exports: string[];
48
+ complexity: {
49
+ cyclomatic: number;
50
+ cognitive: number;
51
+ loc: number;
52
+ commentDensity: number;
53
+ };
54
+ };
17
55
  export declare const analyzeCommand: Command;
18
56
  export default analyzeCommand;
19
57
  //# sourceMappingURL=analyze.d.ts.map