monomind 1.17.0 → 1.17.1
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.
- package/.claude/agents/engineering/engineering-security-engineer.md +1 -1
- package/.claude/commands/mastermind/_repeat.md +4 -0
- package/.claude/commands/mastermind/master.md +52 -1
- package/.claude/scheduled_tasks.lock +1 -1
- package/.claude/skills/mastermind/_repeat.md +2 -0
- package/package.json +1 -1
- package/packages/@monomind/cli/.claude/agents/engineering/engineering-security-engineer.md +1 -1
- package/packages/@monomind/cli/.claude/commands/mastermind/_repeat.md +4 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/master.md +52 -1
- package/packages/@monomind/cli/.claude/skills/mastermind/_repeat.md +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-analyzer.test.js +42 -59
- package/packages/@monomind/cli/dist/src/browser/dashboard/server.js +18 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/ui.html +37 -125
- package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.d.ts +17 -0
- package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.js +320 -0
- package/packages/@monomind/cli/dist/src/commands/agent-ops.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/agent-ops.js +329 -0
- package/packages/@monomind/cli/dist/src/commands/agent.js +5 -907
- package/packages/@monomind/cli/dist/src/commands/analyze-ast.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-ast.js +284 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.js +295 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-diff.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-diff.js +395 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-graph.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-graph.js +304 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-imports.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-imports.js +287 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-symbols.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-symbols.js +302 -0
- package/packages/@monomind/cli/dist/src/commands/analyze.d.ts +38 -0
- package/packages/@monomind/cli/dist/src/commands/analyze.js +12 -1827
- package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.js +189 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +19 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +388 -0
- package/packages/@monomind/cli/dist/src/commands/doctor.js +51 -942
- package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.js +242 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.d.ts +35 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.js +203 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.js +233 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.js +274 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind.js +10 -1129
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +19 -819
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.js +334 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.js +399 -0
- package/packages/@monomind/cli/dist/src/commands/init-subcommands.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/init-subcommands.js +156 -0
- package/packages/@monomind/cli/dist/src/commands/init-upgrade.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/init-upgrade.js +203 -0
- package/packages/@monomind/cli/dist/src/commands/init-wizard.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/init-wizard.js +246 -0
- package/packages/@monomind/cli/dist/src/commands/init.js +6 -623
- package/packages/@monomind/cli/dist/src/commands/memory-admin.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/commands/memory-admin.js +433 -0
- package/packages/@monomind/cli/dist/src/commands/memory-crud.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/memory-crud.js +342 -0
- package/packages/@monomind/cli/dist/src/commands/memory-list.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/commands/memory-list.js +321 -0
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.js +372 -0
- package/packages/@monomind/cli/dist/src/commands/memory.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/memory.js +10 -1441
- package/packages/@monomind/cli/dist/src/commands/neural-core.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/neural-core.js +274 -0
- package/packages/@monomind/cli/dist/src/commands/neural-optimize.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/neural-optimize.js +332 -0
- package/packages/@monomind/cli/dist/src/commands/neural-registry.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/neural-registry.js +290 -0
- package/packages/@monomind/cli/dist/src/commands/neural.js +3 -974
- package/packages/@monomind/cli/dist/src/commands/platforms.js +327 -7
- package/packages/@monomind/cli/dist/src/commands/security-cve.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/security-cve.js +310 -0
- package/packages/@monomind/cli/dist/src/commands/security-misc.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/security-misc.js +293 -0
- package/packages/@monomind/cli/dist/src/commands/security-scan.d.ts +18 -0
- package/packages/@monomind/cli/dist/src/commands/security-scan.js +328 -0
- package/packages/@monomind/cli/dist/src/commands/security.js +3 -958
- package/packages/@monomind/cli/dist/src/commands/session.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/swarm.js +23 -17
- package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +77 -0
- package/packages/@monomind/cli/dist/src/parser.js +11 -6
- package/packages/@monomind/cli/dist/src/routing/llm-caller.js +1 -2
- package/packages/@monomind/cli/package.json +2 -3
- package/packages/@monomind/cli/scripts/understand-analyze.mjs +1 -1
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
* Comprehensive initialization for Monomind with Claude Code integration
|
|
4
4
|
*/
|
|
5
5
|
import { output } from '../output.js';
|
|
6
|
-
import { confirm
|
|
6
|
+
import { confirm } from '../prompt.js';
|
|
7
7
|
import * as fs from 'fs';
|
|
8
8
|
import * as path from 'path';
|
|
9
|
-
import { executeInit,
|
|
10
|
-
|
|
9
|
+
import { executeInit, DEFAULT_INIT_OPTIONS, MINIMAL_INIT_OPTIONS, FULL_INIT_OPTIONS, } from '../init/index.js';
|
|
10
|
+
import { wizardCommand } from './init-wizard.js';
|
|
11
|
+
import { upgradeCommand } from './init-upgrade.js';
|
|
12
|
+
import { checkCommand, skillsCommand, hooksCommand } from './init-subcommands.js';
|
|
11
13
|
function isInitialized(cwd) {
|
|
12
14
|
const claudePath = path.join(cwd, '.claude', 'settings.json');
|
|
13
15
|
const monomindPath = path.join(cwd, '.monomind', 'config.yaml');
|
|
@@ -16,7 +18,6 @@ function isInitialized(cwd) {
|
|
|
16
18
|
monomind: fs.existsSync(monomindPath),
|
|
17
19
|
};
|
|
18
20
|
}
|
|
19
|
-
// Init subcommand (default)
|
|
20
21
|
const initAction = async (ctx) => {
|
|
21
22
|
const force = ctx.flags.force;
|
|
22
23
|
const minimal = ctx.flags.minimal;
|
|
@@ -24,7 +25,6 @@ const initAction = async (ctx) => {
|
|
|
24
25
|
const skipClaude = ctx.flags['skip-claude'];
|
|
25
26
|
const onlyClaude = ctx.flags['only-claude'];
|
|
26
27
|
const cwd = ctx.cwd;
|
|
27
|
-
// Check if already initialized
|
|
28
28
|
const initialized = isInitialized(cwd);
|
|
29
29
|
const hasExisting = initialized.claude || initialized.monomind;
|
|
30
30
|
if (hasExisting && !force) {
|
|
@@ -51,7 +51,6 @@ const initAction = async (ctx) => {
|
|
|
51
51
|
output.writeln();
|
|
52
52
|
output.writeln(output.bold('Initializing Monomind'));
|
|
53
53
|
output.writeln();
|
|
54
|
-
// Build init options based on flags
|
|
55
54
|
let options;
|
|
56
55
|
if (minimal) {
|
|
57
56
|
options = { ...MINIMAL_INIT_OPTIONS, targetDir: cwd, force };
|
|
@@ -62,7 +61,6 @@ const initAction = async (ctx) => {
|
|
|
62
61
|
else {
|
|
63
62
|
options = { ...DEFAULT_INIT_OPTIONS, targetDir: cwd, force };
|
|
64
63
|
}
|
|
65
|
-
// Handle --skip-claude and --only-claude flags
|
|
66
64
|
if (skipClaude) {
|
|
67
65
|
options.components.settings = false;
|
|
68
66
|
options.components.skills = false;
|
|
@@ -76,11 +74,9 @@ const initAction = async (ctx) => {
|
|
|
76
74
|
if (onlyClaude) {
|
|
77
75
|
options.components.runtime = false;
|
|
78
76
|
}
|
|
79
|
-
// Create spinner
|
|
80
77
|
const spinner = output.createSpinner({ text: 'Initializing...' });
|
|
81
78
|
spinner.start();
|
|
82
79
|
try {
|
|
83
|
-
// Execute initialization
|
|
84
80
|
const result = await executeInit(options);
|
|
85
81
|
if (!result.success) {
|
|
86
82
|
spinner.fail('Initialization failed');
|
|
@@ -132,7 +128,6 @@ const initAction = async (ctx) => {
|
|
|
132
128
|
}
|
|
133
129
|
}
|
|
134
130
|
output.writeln();
|
|
135
|
-
// Display summary
|
|
136
131
|
const summary = [];
|
|
137
132
|
if (result.created.directories.length > 0) {
|
|
138
133
|
summary.push(`Directories: ${result.created.directories.length} created`);
|
|
@@ -145,7 +140,6 @@ const initAction = async (ctx) => {
|
|
|
145
140
|
}
|
|
146
141
|
output.printBox(summary.join('\n'), 'Summary');
|
|
147
142
|
output.writeln();
|
|
148
|
-
// Show what was created
|
|
149
143
|
if (options.components.claudeMd || options.components.settings || options.components.skills || options.components.commands || options.components.agents) {
|
|
150
144
|
output.printBox([
|
|
151
145
|
options.components.claudeMd ? `CLAUDE.md: Swarm guidance & configuration` : '',
|
|
@@ -167,19 +161,16 @@ const initAction = async (ctx) => {
|
|
|
167
161
|
].join('\n'), 'v1 Runtime');
|
|
168
162
|
output.writeln();
|
|
169
163
|
}
|
|
170
|
-
// Hooks summary
|
|
171
164
|
if (result.summary.hooksEnabled > 0) {
|
|
172
165
|
output.printInfo(`Hooks: ${result.summary.hooksEnabled} hook types enabled in settings.json`);
|
|
173
166
|
output.writeln();
|
|
174
167
|
}
|
|
175
|
-
// Handle --start-all or --start-daemon
|
|
176
168
|
const startAll = ctx.flags['start-all'] || ctx.flags.startAll;
|
|
177
169
|
const startDaemon = ctx.flags['start-daemon'] || ctx.flags.startDaemon || startAll;
|
|
178
170
|
if (startDaemon || startAll) {
|
|
179
171
|
output.writeln();
|
|
180
172
|
output.printInfo('Starting services...');
|
|
181
173
|
const { execSync, spawn: spawnChild } = await import('child_process');
|
|
182
|
-
// Initialize memory database
|
|
183
174
|
if (startAll) {
|
|
184
175
|
try {
|
|
185
176
|
output.writeln(output.dim(' Initializing memory database...'));
|
|
@@ -194,7 +185,6 @@ const initAction = async (ctx) => {
|
|
|
194
185
|
output.writeln(output.dim(' Memory database already exists'));
|
|
195
186
|
}
|
|
196
187
|
}
|
|
197
|
-
// Start daemon
|
|
198
188
|
if (startDaemon) {
|
|
199
189
|
try {
|
|
200
190
|
output.writeln(output.dim(' Starting daemon...'));
|
|
@@ -206,7 +196,6 @@ const initAction = async (ctx) => {
|
|
|
206
196
|
output.writeln(output.warning(' Daemon may already be running'));
|
|
207
197
|
}
|
|
208
198
|
}
|
|
209
|
-
// Initialize swarm
|
|
210
199
|
if (startAll) {
|
|
211
200
|
try {
|
|
212
201
|
output.writeln(output.dim(' Initializing swarm...'));
|
|
@@ -224,7 +213,6 @@ const initAction = async (ctx) => {
|
|
|
224
213
|
output.writeln();
|
|
225
214
|
output.printSuccess('All services started');
|
|
226
215
|
}
|
|
227
|
-
// Handle --with-embeddings
|
|
228
216
|
const withEmbeddings = ctx.flags['with-embeddings'] || ctx.flags.withEmbeddings;
|
|
229
217
|
const embeddingModel = (ctx.flags['embedding-model'] || ctx.flags.embeddingModel || 'Xenova/all-MiniLM-L6-v2');
|
|
230
218
|
if (withEmbeddings) {
|
|
@@ -247,12 +235,11 @@ const initAction = async (ctx) => {
|
|
|
247
235
|
output.writeln(output.success(' ✓ Embeddings initialized'));
|
|
248
236
|
output.writeln(output.dim(' Run "embeddings init --download" to download model'));
|
|
249
237
|
}
|
|
250
|
-
catch
|
|
238
|
+
catch {
|
|
251
239
|
output.writeln(output.warning(' Embedding initialization skipped (run manually)'));
|
|
252
240
|
}
|
|
253
241
|
}
|
|
254
242
|
if (!startDaemon && !startAll) {
|
|
255
|
-
// Next steps (only if not auto-starting)
|
|
256
243
|
output.writeln(output.bold('Next steps:'));
|
|
257
244
|
output.printList([
|
|
258
245
|
`Run ${output.highlight('monomind daemon start')} to start background workers`,
|
|
@@ -262,7 +249,6 @@ const initAction = async (ctx) => {
|
|
|
262
249
|
options.components.settings ? `Review ${output.highlight('.claude/settings.json')} for hook configurations` : '',
|
|
263
250
|
].filter(Boolean));
|
|
264
251
|
}
|
|
265
|
-
// Recommend semantic enrichment — prominent callout, not buried tip
|
|
266
252
|
output.writeln('');
|
|
267
253
|
output.writeln(output.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
268
254
|
output.writeln(output.bold(' Run /mastermind:understand next'));
|
|
@@ -285,609 +271,6 @@ const initAction = async (ctx) => {
|
|
|
285
271
|
return { success: false, exitCode: 1 };
|
|
286
272
|
}
|
|
287
273
|
};
|
|
288
|
-
// Wizard subcommand for interactive setup
|
|
289
|
-
const wizardCommand = {
|
|
290
|
-
name: 'wizard',
|
|
291
|
-
description: 'Interactive setup wizard for comprehensive configuration',
|
|
292
|
-
action: async (ctx) => {
|
|
293
|
-
output.writeln();
|
|
294
|
-
output.writeln(output.bold('Monomind Setup Wizard'));
|
|
295
|
-
output.writeln(output.dim('Answer questions to configure your project'));
|
|
296
|
-
output.writeln();
|
|
297
|
-
try {
|
|
298
|
-
// Start with base options
|
|
299
|
-
const options = { ...DEFAULT_INIT_OPTIONS, targetDir: ctx.cwd };
|
|
300
|
-
// Configuration preset
|
|
301
|
-
const preset = await select({
|
|
302
|
-
message: 'Select configuration preset:',
|
|
303
|
-
options: [
|
|
304
|
-
{ value: 'default', label: 'Default', hint: 'Recommended settings for most projects' },
|
|
305
|
-
{ value: 'minimal', label: 'Minimal', hint: 'Core features only' },
|
|
306
|
-
{ value: 'full', label: 'Full', hint: 'All features enabled' },
|
|
307
|
-
{ value: 'custom', label: 'Custom', hint: 'Choose each component' },
|
|
308
|
-
],
|
|
309
|
-
});
|
|
310
|
-
if (preset === 'minimal') {
|
|
311
|
-
Object.assign(options, MINIMAL_INIT_OPTIONS);
|
|
312
|
-
options.targetDir = ctx.cwd;
|
|
313
|
-
}
|
|
314
|
-
else if (preset === 'full') {
|
|
315
|
-
Object.assign(options, FULL_INIT_OPTIONS);
|
|
316
|
-
options.targetDir = ctx.cwd;
|
|
317
|
-
}
|
|
318
|
-
else if (preset === 'custom') {
|
|
319
|
-
// Component selection
|
|
320
|
-
const components = await multiSelect({
|
|
321
|
-
message: 'Select components to initialize:',
|
|
322
|
-
options: [
|
|
323
|
-
{ value: 'claudeMd', label: 'CLAUDE.md', hint: 'Swarm guidance and project configuration', selected: true },
|
|
324
|
-
{ value: 'settings', label: 'settings.json', hint: 'Claude Code hooks configuration', selected: true },
|
|
325
|
-
{ value: 'skills', label: 'Skills', hint: 'Claude Code skills in .claude/skills/', selected: true },
|
|
326
|
-
{ value: 'commands', label: 'Commands', hint: 'Claude Code commands in .claude/commands/', selected: true },
|
|
327
|
-
{ value: 'agents', label: 'Agents', hint: 'Agent definitions in .claude/agents/', selected: true },
|
|
328
|
-
{ value: 'helpers', label: 'Helpers', hint: 'Utility scripts in .claude/helpers/', selected: true },
|
|
329
|
-
{ value: 'statusline', label: 'Statusline', hint: 'Shell statusline integration', selected: false },
|
|
330
|
-
{ value: 'mcp', label: 'MCP', hint: '.mcp.json for MCP server configuration', selected: true },
|
|
331
|
-
{ value: 'runtime', label: 'Runtime', hint: '.monomind/ directory for v1 runtime', selected: true },
|
|
332
|
-
],
|
|
333
|
-
});
|
|
334
|
-
options.components.claudeMd = components.includes('claudeMd');
|
|
335
|
-
options.components.settings = components.includes('settings');
|
|
336
|
-
options.components.skills = components.includes('skills');
|
|
337
|
-
options.components.commands = components.includes('commands');
|
|
338
|
-
options.components.agents = components.includes('agents');
|
|
339
|
-
options.components.helpers = components.includes('helpers');
|
|
340
|
-
options.components.statusline = components.includes('statusline');
|
|
341
|
-
options.components.mcp = components.includes('mcp');
|
|
342
|
-
options.components.runtime = components.includes('runtime');
|
|
343
|
-
// Skills selection
|
|
344
|
-
if (options.components.skills) {
|
|
345
|
-
const skillSets = await multiSelect({
|
|
346
|
-
message: 'Select skill sets:',
|
|
347
|
-
options: [
|
|
348
|
-
{ value: 'core', label: 'Core', hint: 'Swarm, memory, SPARC skills', selected: true },
|
|
349
|
-
{ value: 'memory', label: 'Memory (LanceDB)', hint: 'Vector database skills', selected: true },
|
|
350
|
-
{ value: 'github', label: 'GitHub', hint: 'GitHub integration skills', selected: true },
|
|
351
|
-
],
|
|
352
|
-
});
|
|
353
|
-
options.skills.core = skillSets.includes('core');
|
|
354
|
-
options.skills.memory = skillSets.includes('memory');
|
|
355
|
-
options.skills.github = skillSets.includes('github');
|
|
356
|
-
}
|
|
357
|
-
// Hooks selection
|
|
358
|
-
if (options.components.settings) {
|
|
359
|
-
const hooks = await multiSelect({
|
|
360
|
-
message: 'Select hooks to enable:',
|
|
361
|
-
options: [
|
|
362
|
-
{ value: 'preToolUse', label: 'PreToolUse', hint: 'Before tool execution', selected: true },
|
|
363
|
-
{ value: 'postToolUse', label: 'PostToolUse', hint: 'After tool execution', selected: true },
|
|
364
|
-
{ value: 'userPromptSubmit', label: 'UserPromptSubmit', hint: 'Task routing', selected: true },
|
|
365
|
-
{ value: 'sessionStart', label: 'SessionStart', hint: 'Session initialization', selected: true },
|
|
366
|
-
{ value: 'stop', label: 'Stop', hint: 'Task completion evaluation', selected: true },
|
|
367
|
-
{ value: 'notification', label: 'Notification', hint: 'Swarm notifications', selected: true },
|
|
368
|
-
{ value: 'permissionRequest', label: 'PermissionRequest', hint: 'Auto-allow monomind tools', selected: true },
|
|
369
|
-
],
|
|
370
|
-
});
|
|
371
|
-
options.hooks.preToolUse = hooks.includes('preToolUse');
|
|
372
|
-
options.hooks.postToolUse = hooks.includes('postToolUse');
|
|
373
|
-
options.hooks.userPromptSubmit = hooks.includes('userPromptSubmit');
|
|
374
|
-
options.hooks.sessionStart = hooks.includes('sessionStart');
|
|
375
|
-
options.hooks.stop = hooks.includes('stop');
|
|
376
|
-
options.hooks.notification = hooks.includes('notification');
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
// Swarm topology (for all presets)
|
|
380
|
-
const topology = await select({
|
|
381
|
-
message: 'Select swarm topology:',
|
|
382
|
-
options: [
|
|
383
|
-
{ value: 'hierarchical-mesh', label: 'Hierarchical Mesh', hint: 'Best for complex projects (recommended)' },
|
|
384
|
-
{ value: 'mesh', label: 'Mesh', hint: 'Peer-to-peer coordination' },
|
|
385
|
-
{ value: 'hierarchical', label: 'Hierarchical', hint: 'Tree-based coordination' },
|
|
386
|
-
{ value: 'adaptive', label: 'Adaptive', hint: 'Dynamic topology switching' },
|
|
387
|
-
],
|
|
388
|
-
});
|
|
389
|
-
options.runtime.topology = topology;
|
|
390
|
-
// Max agents
|
|
391
|
-
const maxAgents = await input({
|
|
392
|
-
message: 'Maximum concurrent agents:',
|
|
393
|
-
default: String(options.runtime.maxAgents),
|
|
394
|
-
validate: (v) => {
|
|
395
|
-
const n = parseInt(v);
|
|
396
|
-
return (!isNaN(n) && n > 0 && n <= 50) || 'Enter a number between 1 and 50';
|
|
397
|
-
},
|
|
398
|
-
});
|
|
399
|
-
options.runtime.maxAgents = parseInt(maxAgents);
|
|
400
|
-
// Memory backend
|
|
401
|
-
const memoryBackend = await select({
|
|
402
|
-
message: 'Select memory backend:',
|
|
403
|
-
options: [
|
|
404
|
-
{ value: 'hybrid', label: 'Hybrid', hint: 'SQLite + LanceDB (recommended)' },
|
|
405
|
-
{ value: 'lancedb', label: 'LanceDB', hint: '150x faster vector search' },
|
|
406
|
-
{ value: 'sqlite', label: 'SQLite', hint: 'Standard SQL storage' },
|
|
407
|
-
{ value: 'memory', label: 'In-Memory', hint: 'Fast but non-persistent' },
|
|
408
|
-
],
|
|
409
|
-
});
|
|
410
|
-
options.runtime.memoryBackend = memoryBackend;
|
|
411
|
-
// HNSW indexing
|
|
412
|
-
if (memoryBackend === 'lancedb' || memoryBackend === 'hybrid') {
|
|
413
|
-
const enableHNSW = await confirm({
|
|
414
|
-
message: 'Enable HNSW indexing for faster vector search?',
|
|
415
|
-
default: true,
|
|
416
|
-
});
|
|
417
|
-
options.runtime.enableHNSW = enableHNSW;
|
|
418
|
-
}
|
|
419
|
-
// Neural learning
|
|
420
|
-
const enableNeural = await confirm({
|
|
421
|
-
message: 'Enable neural pattern learning?',
|
|
422
|
-
default: options.runtime.enableNeural,
|
|
423
|
-
});
|
|
424
|
-
options.runtime.enableNeural = enableNeural;
|
|
425
|
-
// ADR-049: Self-Learning Memory capabilities
|
|
426
|
-
if (memoryBackend === 'lancedb' || memoryBackend === 'hybrid') {
|
|
427
|
-
const enableSelfLearning = await confirm({
|
|
428
|
-
message: 'Enable self-learning memory? (LearningBridge + Knowledge Graph + Agent Scopes)',
|
|
429
|
-
default: true,
|
|
430
|
-
});
|
|
431
|
-
options.runtime.enableLearningBridge = enableSelfLearning && enableNeural;
|
|
432
|
-
options.runtime.enableMemoryGraph = enableSelfLearning;
|
|
433
|
-
options.runtime.enableAgentScopes = enableSelfLearning;
|
|
434
|
-
}
|
|
435
|
-
else {
|
|
436
|
-
options.runtime.enableLearningBridge = false;
|
|
437
|
-
options.runtime.enableMemoryGraph = false;
|
|
438
|
-
options.runtime.enableAgentScopes = false;
|
|
439
|
-
}
|
|
440
|
-
// Embeddings configuration
|
|
441
|
-
const enableEmbeddings = await confirm({
|
|
442
|
-
message: 'Enable ONNX embedding system with hyperbolic support?',
|
|
443
|
-
default: true,
|
|
444
|
-
});
|
|
445
|
-
let embeddingModel = 'Xenova/all-MiniLM-L6-v2';
|
|
446
|
-
if (enableEmbeddings) {
|
|
447
|
-
embeddingModel = await select({
|
|
448
|
-
message: 'Select embedding model:',
|
|
449
|
-
options: [
|
|
450
|
-
{ value: 'Xenova/all-MiniLM-L6-v2', label: 'MiniLM L6 (384d)', hint: 'Fast, good quality (recommended)' },
|
|
451
|
-
{ value: 'Xenova/all-mpnet-base-v2', label: 'MPNet Base (768d)', hint: 'Higher quality, more memory' },
|
|
452
|
-
],
|
|
453
|
-
});
|
|
454
|
-
}
|
|
455
|
-
// Execute initialization
|
|
456
|
-
output.writeln();
|
|
457
|
-
const spinner = output.createSpinner({ text: 'Initializing...' });
|
|
458
|
-
spinner.start();
|
|
459
|
-
const result = await executeInit(options);
|
|
460
|
-
if (!result.success) {
|
|
461
|
-
spinner.fail('Initialization failed');
|
|
462
|
-
for (const error of result.errors) {
|
|
463
|
-
output.printError(error);
|
|
464
|
-
}
|
|
465
|
-
return { success: false, exitCode: 1 };
|
|
466
|
-
}
|
|
467
|
-
spinner.succeed('Setup complete!');
|
|
468
|
-
// Initialize embeddings if enabled
|
|
469
|
-
let embeddingsInitialized = false;
|
|
470
|
-
if (enableEmbeddings) {
|
|
471
|
-
output.writeln();
|
|
472
|
-
output.printInfo('Initializing ONNX embedding subsystem...');
|
|
473
|
-
const ALLOWED_MODELS = /^[\w\-./]+$/;
|
|
474
|
-
if (!ALLOWED_MODELS.test(embeddingModel)) {
|
|
475
|
-
output.writeln(output.error('Invalid model identifier. Only alphanumeric characters, hyphens, dots, and slashes are allowed.'));
|
|
476
|
-
return { success: false, exitCode: 1 };
|
|
477
|
-
}
|
|
478
|
-
const { execFileSync } = await import('child_process');
|
|
479
|
-
try {
|
|
480
|
-
execFileSync(process.platform === 'win32' ? 'npx.cmd' : 'npx', ['@monomind/cli@latest', 'embeddings', 'init', '--model', embeddingModel, '--no-download', '--force'], {
|
|
481
|
-
stdio: 'pipe',
|
|
482
|
-
cwd: ctx.cwd,
|
|
483
|
-
timeout: 30000
|
|
484
|
-
});
|
|
485
|
-
output.writeln(output.success(' ✓ Embeddings configured'));
|
|
486
|
-
embeddingsInitialized = true;
|
|
487
|
-
}
|
|
488
|
-
catch {
|
|
489
|
-
output.writeln(output.dim(' Embeddings will be configured on first use'));
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
// Enforcement gates opt-in
|
|
493
|
-
const enableGates = await confirm({
|
|
494
|
-
message: 'Enable enforcement gates? (blocks destructive commands + secrets in writes)',
|
|
495
|
-
default: true,
|
|
496
|
-
});
|
|
497
|
-
let gatesEnabled = false;
|
|
498
|
-
if (enableGates) {
|
|
499
|
-
try {
|
|
500
|
-
const { execFileSync } = await import('child_process');
|
|
501
|
-
execFileSync(process.platform === 'win32' ? 'npx.cmd' : 'npx', ['@monomind/cli@latest', 'guidance', 'setup', '--project-dir', ctx.cwd], { stdio: 'pipe', cwd: ctx.cwd, timeout: 10000 });
|
|
502
|
-
gatesEnabled = true;
|
|
503
|
-
output.writeln(output.success(' ✓ Enforcement gates wired'));
|
|
504
|
-
}
|
|
505
|
-
catch {
|
|
506
|
-
output.writeln(output.dim(' Gates setup skipped (run `monomind guidance setup` manually)'));
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
output.writeln();
|
|
510
|
-
// Summary table
|
|
511
|
-
output.printTable({
|
|
512
|
-
columns: [
|
|
513
|
-
{ key: 'setting', header: 'Setting', width: 20 },
|
|
514
|
-
{ key: 'value', header: 'Value', width: 40 },
|
|
515
|
-
],
|
|
516
|
-
data: [
|
|
517
|
-
{ setting: 'Preset', value: preset },
|
|
518
|
-
{ setting: 'Topology', value: options.runtime.topology },
|
|
519
|
-
{ setting: 'Max Agents', value: String(options.runtime.maxAgents) },
|
|
520
|
-
{ setting: 'Memory Backend', value: options.runtime.memoryBackend },
|
|
521
|
-
{ setting: 'HNSW Indexing', value: options.runtime.enableHNSW ? 'Enabled' : 'Disabled' },
|
|
522
|
-
{ setting: 'Neural Learning', value: options.runtime.enableNeural ? 'Enabled' : 'Disabled' },
|
|
523
|
-
{ setting: 'Self-Learning', value: options.runtime.enableLearningBridge ? 'LearningBridge + Graph + Scopes' : 'Disabled' },
|
|
524
|
-
{ setting: 'Embeddings', value: enableEmbeddings ? `${embeddingModel} (hyperbolic)` : 'Disabled' },
|
|
525
|
-
{ setting: 'Skills', value: `${result.summary.skillsCount} installed` },
|
|
526
|
-
{ setting: 'Commands', value: `${result.summary.commandsCount} installed` },
|
|
527
|
-
{ setting: 'Agents', value: `${result.summary.agentsCount} installed` },
|
|
528
|
-
{ setting: 'Hooks', value: `${result.summary.hooksEnabled} enabled` },
|
|
529
|
-
{ setting: 'Enforcement Gates', value: gatesEnabled ? 'Enabled' : 'Disabled' },
|
|
530
|
-
],
|
|
531
|
-
});
|
|
532
|
-
return { success: true, data: result };
|
|
533
|
-
}
|
|
534
|
-
catch (error) {
|
|
535
|
-
if (error instanceof Error && error.message === 'User cancelled') {
|
|
536
|
-
output.printInfo('Setup cancelled');
|
|
537
|
-
return { success: true };
|
|
538
|
-
}
|
|
539
|
-
throw error;
|
|
540
|
-
}
|
|
541
|
-
},
|
|
542
|
-
};
|
|
543
|
-
// Check subcommand
|
|
544
|
-
const checkCommand = {
|
|
545
|
-
name: 'check',
|
|
546
|
-
description: 'Check if MonoMind is initialized',
|
|
547
|
-
action: async (ctx) => {
|
|
548
|
-
const initialized = isInitialized(ctx.cwd);
|
|
549
|
-
const result = {
|
|
550
|
-
initialized: initialized.claude || initialized.monomind,
|
|
551
|
-
claude: initialized.claude,
|
|
552
|
-
monomind: initialized.monomind,
|
|
553
|
-
paths: {
|
|
554
|
-
claudeSettings: initialized.claude ? path.join(ctx.cwd, '.claude', 'settings.json') : null,
|
|
555
|
-
monomindConfig: initialized.monomind ? path.join(ctx.cwd, '.monomind', 'config.yaml') : null,
|
|
556
|
-
},
|
|
557
|
-
};
|
|
558
|
-
if (ctx.flags.format === 'json') {
|
|
559
|
-
output.printJson(result);
|
|
560
|
-
return { success: true, data: result };
|
|
561
|
-
}
|
|
562
|
-
if (result.initialized) {
|
|
563
|
-
output.printSuccess('MonoMind is initialized');
|
|
564
|
-
if (initialized.claude) {
|
|
565
|
-
output.printInfo(` Claude Code: .claude/settings.json`);
|
|
566
|
-
}
|
|
567
|
-
if (initialized.monomind) {
|
|
568
|
-
output.printInfo(` Runtime: .monomind/config.yaml`);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
else {
|
|
572
|
-
output.printWarning('MonoMind is not initialized in this directory');
|
|
573
|
-
output.printInfo('Run "monomind init" to initialize');
|
|
574
|
-
}
|
|
575
|
-
return { success: true, data: result };
|
|
576
|
-
},
|
|
577
|
-
};
|
|
578
|
-
// Skills subcommand
|
|
579
|
-
const skillsCommand = {
|
|
580
|
-
name: 'skills',
|
|
581
|
-
description: 'Initialize only skills',
|
|
582
|
-
options: [
|
|
583
|
-
{ name: 'all', description: 'Install all skills', type: 'boolean', default: false },
|
|
584
|
-
{ name: 'core', description: 'Install core skills', type: 'boolean', default: true },
|
|
585
|
-
{ name: 'memory', description: 'Install memory skills', type: 'boolean', default: false },
|
|
586
|
-
{ name: 'github', description: 'Install GitHub skills', type: 'boolean', default: false },
|
|
587
|
-
],
|
|
588
|
-
action: async (ctx) => {
|
|
589
|
-
const options = {
|
|
590
|
-
...MINIMAL_INIT_OPTIONS,
|
|
591
|
-
targetDir: ctx.cwd,
|
|
592
|
-
force: ctx.flags.force,
|
|
593
|
-
components: {
|
|
594
|
-
settings: false,
|
|
595
|
-
skills: true,
|
|
596
|
-
commands: false,
|
|
597
|
-
agents: false,
|
|
598
|
-
helpers: false,
|
|
599
|
-
statusline: false,
|
|
600
|
-
mcp: false,
|
|
601
|
-
runtime: false,
|
|
602
|
-
claudeMd: false,
|
|
603
|
-
graphify: false,
|
|
604
|
-
},
|
|
605
|
-
skills: {
|
|
606
|
-
all: ctx.flags.all,
|
|
607
|
-
core: ctx.flags.core,
|
|
608
|
-
memory: ctx.flags.memory,
|
|
609
|
-
github: ctx.flags.github,
|
|
610
|
-
browser: false,
|
|
611
|
-
advanced: false,
|
|
612
|
-
},
|
|
613
|
-
};
|
|
614
|
-
const spinner = output.createSpinner({ text: 'Installing skills...' });
|
|
615
|
-
spinner.start();
|
|
616
|
-
const result = await executeInit(options);
|
|
617
|
-
if (result.success) {
|
|
618
|
-
spinner.succeed(`Installed ${result.summary.skillsCount} skills`);
|
|
619
|
-
}
|
|
620
|
-
else {
|
|
621
|
-
spinner.fail('Failed to install skills');
|
|
622
|
-
for (const error of result.errors) {
|
|
623
|
-
output.printError(error);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
return { success: result.success, data: result };
|
|
627
|
-
},
|
|
628
|
-
};
|
|
629
|
-
// Hooks subcommand
|
|
630
|
-
const hooksCommand = {
|
|
631
|
-
name: 'hooks',
|
|
632
|
-
description: 'Initialize only hooks configuration',
|
|
633
|
-
options: [
|
|
634
|
-
{ name: 'all', description: 'Enable all hooks', type: 'boolean', default: true },
|
|
635
|
-
{ name: 'minimal', description: 'Enable only essential hooks', type: 'boolean', default: false },
|
|
636
|
-
],
|
|
637
|
-
action: async (ctx) => {
|
|
638
|
-
const minimal = ctx.flags.minimal;
|
|
639
|
-
const options = {
|
|
640
|
-
...DEFAULT_INIT_OPTIONS,
|
|
641
|
-
targetDir: ctx.cwd,
|
|
642
|
-
force: ctx.flags.force,
|
|
643
|
-
components: {
|
|
644
|
-
settings: true,
|
|
645
|
-
skills: false,
|
|
646
|
-
commands: false,
|
|
647
|
-
agents: false,
|
|
648
|
-
helpers: false,
|
|
649
|
-
statusline: false,
|
|
650
|
-
mcp: false,
|
|
651
|
-
runtime: false,
|
|
652
|
-
claudeMd: false,
|
|
653
|
-
graphify: false,
|
|
654
|
-
},
|
|
655
|
-
hooks: minimal
|
|
656
|
-
? {
|
|
657
|
-
preToolUse: true,
|
|
658
|
-
postToolUse: true,
|
|
659
|
-
userPromptSubmit: false,
|
|
660
|
-
sessionStart: false,
|
|
661
|
-
stop: false,
|
|
662
|
-
preCompact: false,
|
|
663
|
-
notification: false,
|
|
664
|
-
teammateIdle: false,
|
|
665
|
-
taskCompleted: false,
|
|
666
|
-
timeout: 5000,
|
|
667
|
-
continueOnError: true,
|
|
668
|
-
}
|
|
669
|
-
: DEFAULT_INIT_OPTIONS.hooks,
|
|
670
|
-
};
|
|
671
|
-
const spinner = output.createSpinner({ text: 'Creating hooks configuration...' });
|
|
672
|
-
spinner.start();
|
|
673
|
-
const result = await executeInit(options);
|
|
674
|
-
if (result.success) {
|
|
675
|
-
spinner.succeed(`Created settings.json with ${result.summary.hooksEnabled} hooks enabled`);
|
|
676
|
-
}
|
|
677
|
-
else {
|
|
678
|
-
spinner.fail('Failed to create hooks configuration');
|
|
679
|
-
for (const error of result.errors) {
|
|
680
|
-
output.printError(error);
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
return { success: result.success, data: result };
|
|
684
|
-
},
|
|
685
|
-
};
|
|
686
|
-
// Upgrade subcommand - updates helpers without losing user data
|
|
687
|
-
const upgradeCommand = {
|
|
688
|
-
name: 'upgrade',
|
|
689
|
-
description: 'Update statusline and helpers while preserving existing data',
|
|
690
|
-
options: [
|
|
691
|
-
{
|
|
692
|
-
name: 'verbose',
|
|
693
|
-
short: 'v',
|
|
694
|
-
description: 'Show detailed output',
|
|
695
|
-
type: 'boolean',
|
|
696
|
-
default: false,
|
|
697
|
-
},
|
|
698
|
-
{
|
|
699
|
-
name: 'add-missing',
|
|
700
|
-
short: 'a',
|
|
701
|
-
description: 'Add any new skills, agents, and commands that are missing',
|
|
702
|
-
type: 'boolean',
|
|
703
|
-
default: false,
|
|
704
|
-
},
|
|
705
|
-
{
|
|
706
|
-
name: 'settings',
|
|
707
|
-
short: 's',
|
|
708
|
-
description: 'Merge new settings (Agent Teams, hooks) into existing settings.json',
|
|
709
|
-
type: 'boolean',
|
|
710
|
-
default: false,
|
|
711
|
-
},
|
|
712
|
-
{
|
|
713
|
-
name: 'all',
|
|
714
|
-
description: 'Upgrade all known monomind projects on this machine (scans ~/Desktop, ~/projects, etc.)',
|
|
715
|
-
type: 'boolean',
|
|
716
|
-
default: false,
|
|
717
|
-
},
|
|
718
|
-
],
|
|
719
|
-
action: async (ctx) => {
|
|
720
|
-
const addMissing = (ctx.flags['add-missing'] || ctx.flags.addMissing);
|
|
721
|
-
const upgradeSettings = (ctx.flags.settings);
|
|
722
|
-
const upgradeAll = (ctx.flags.all);
|
|
723
|
-
// ── --all: scan for every monomind project and upgrade each ──────────────
|
|
724
|
-
if (upgradeAll) {
|
|
725
|
-
output.writeln();
|
|
726
|
-
output.writeln(output.bold('Upgrading all monomind projects'));
|
|
727
|
-
output.writeln(output.dim('Scanning ~/Desktop, ~/projects, ~/code… (this may take a moment)'));
|
|
728
|
-
output.writeln();
|
|
729
|
-
const projects = findMonomindProjects();
|
|
730
|
-
if (projects.length === 0) {
|
|
731
|
-
output.printInfo('No monomind projects found. Install monomind in a project first: npx monomind init');
|
|
732
|
-
return { success: true, exitCode: 0 };
|
|
733
|
-
}
|
|
734
|
-
output.printInfo(`Found ${projects.length} project(s). Upgrading…`);
|
|
735
|
-
output.writeln();
|
|
736
|
-
let succeeded = 0;
|
|
737
|
-
let failed = 0;
|
|
738
|
-
// Try to read control URL for dashboard progress events (best-effort)
|
|
739
|
-
let controlUrl = 'http://localhost:4242';
|
|
740
|
-
try {
|
|
741
|
-
const ctrlPath = path.join(process.cwd(), '.monomind', 'control.json');
|
|
742
|
-
if (fs.existsSync(ctrlPath) && fs.statSync(ctrlPath).size <= 4096) {
|
|
743
|
-
const ctrlCfg = JSON.parse(fs.readFileSync(ctrlPath, 'utf-8'));
|
|
744
|
-
// Only allow localhost/127.0.0.1 URLs to prevent SSRF via attacker-controlled control.json
|
|
745
|
-
if (typeof ctrlCfg.url === 'string' && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?(\/|$)/.test(ctrlCfg.url)) {
|
|
746
|
-
controlUrl = ctrlCfg.url;
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
catch { }
|
|
751
|
-
const emitUpgradeProgress = async (projDir, status, current, total) => {
|
|
752
|
-
try {
|
|
753
|
-
const { default: http } = await import('http');
|
|
754
|
-
const payload = JSON.stringify({ type: 'upgrade:progress', project: projDir, status, current, total, ts: Date.now() });
|
|
755
|
-
const url = new URL(controlUrl + '/api/mastermind/event');
|
|
756
|
-
const req = http.request({ hostname: url.hostname, port: parseInt(url.port || '4242'), path: url.pathname, method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) } });
|
|
757
|
-
req.write(payload);
|
|
758
|
-
req.end();
|
|
759
|
-
req.on('error', () => { });
|
|
760
|
-
}
|
|
761
|
-
catch { }
|
|
762
|
-
};
|
|
763
|
-
for (const projDir of projects) {
|
|
764
|
-
const projIdx = projects.indexOf(projDir) + 1;
|
|
765
|
-
const spinner = output.createSpinner({ text: `[${projIdx}/${projects.length}] ${projDir}` });
|
|
766
|
-
spinner.start();
|
|
767
|
-
try {
|
|
768
|
-
const res = addMissing
|
|
769
|
-
? await executeUpgradeWithMissing(projDir, upgradeSettings)
|
|
770
|
-
: await executeUpgrade(projDir, upgradeSettings);
|
|
771
|
-
if (res.success) {
|
|
772
|
-
spinner.succeed(projDir + ' (' + res.updated.length + ' updated)');
|
|
773
|
-
succeeded++;
|
|
774
|
-
emitUpgradeProgress(projDir, 'success', projIdx, projects.length);
|
|
775
|
-
}
|
|
776
|
-
else {
|
|
777
|
-
spinner.fail(projDir + ' — ' + (res.errors[0] || 'unknown error'));
|
|
778
|
-
failed++;
|
|
779
|
-
emitUpgradeProgress(projDir, 'failed', projIdx, projects.length);
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
catch (e) {
|
|
783
|
-
spinner.fail(projDir + ' — ' + (e instanceof Error ? e.message : String(e)));
|
|
784
|
-
failed++;
|
|
785
|
-
emitUpgradeProgress(projDir, 'failed', projIdx, projects.length);
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
output.writeln();
|
|
789
|
-
output.printInfo(`Done: ${succeeded} upgraded, ${failed} failed out of ${projects.length} projects.`);
|
|
790
|
-
return { success: failed === 0, exitCode: failed > 0 ? 1 : 0 };
|
|
791
|
-
}
|
|
792
|
-
output.writeln();
|
|
793
|
-
output.writeln(output.bold('Upgrading MonoMind'));
|
|
794
|
-
if (addMissing && upgradeSettings) {
|
|
795
|
-
output.writeln(output.dim('Updates helpers, settings, and adds any missing skills/agents/commands'));
|
|
796
|
-
}
|
|
797
|
-
else if (addMissing) {
|
|
798
|
-
output.writeln(output.dim('Updates helpers and adds any missing skills/agents/commands'));
|
|
799
|
-
}
|
|
800
|
-
else if (upgradeSettings) {
|
|
801
|
-
output.writeln(output.dim('Updates helpers and merges new settings (Agent Teams, hooks)'));
|
|
802
|
-
}
|
|
803
|
-
else {
|
|
804
|
-
output.writeln(output.dim('Updates helpers while preserving your existing data'));
|
|
805
|
-
}
|
|
806
|
-
output.writeln();
|
|
807
|
-
const spinnerText = upgradeSettings
|
|
808
|
-
? 'Upgrading helpers and settings...'
|
|
809
|
-
: (addMissing ? 'Upgrading and adding missing assets...' : 'Upgrading...');
|
|
810
|
-
const spinner = output.createSpinner({ text: spinnerText });
|
|
811
|
-
spinner.start();
|
|
812
|
-
try {
|
|
813
|
-
const result = addMissing
|
|
814
|
-
? await executeUpgradeWithMissing(ctx.cwd, upgradeSettings)
|
|
815
|
-
: await executeUpgrade(ctx.cwd, upgradeSettings);
|
|
816
|
-
if (!result.success) {
|
|
817
|
-
spinner.fail('Upgrade failed');
|
|
818
|
-
for (const error of result.errors) {
|
|
819
|
-
output.printError(error);
|
|
820
|
-
}
|
|
821
|
-
return { success: false, exitCode: 1 };
|
|
822
|
-
}
|
|
823
|
-
spinner.succeed('Upgrade complete!');
|
|
824
|
-
output.writeln();
|
|
825
|
-
// Show what was updated
|
|
826
|
-
if (result.updated.length > 0) {
|
|
827
|
-
output.printBox(result.updated.map(f => `✓ ${f}`).join('\n'), 'Updated (latest version)');
|
|
828
|
-
output.writeln();
|
|
829
|
-
}
|
|
830
|
-
// Show what was created
|
|
831
|
-
if (result.created.length > 0) {
|
|
832
|
-
output.printBox(result.created.map(f => `+ ${f}`).join('\n'), 'Created (new files)');
|
|
833
|
-
output.writeln();
|
|
834
|
-
}
|
|
835
|
-
// Show what was preserved
|
|
836
|
-
if (result.preserved.length > 0 && ctx.flags.verbose) {
|
|
837
|
-
output.printBox(result.preserved.map(f => `• ${f}`).join('\n'), 'Preserved (existing data kept)');
|
|
838
|
-
output.writeln();
|
|
839
|
-
}
|
|
840
|
-
else if (result.preserved.length > 0) {
|
|
841
|
-
output.printInfo(`Preserved ${result.preserved.length} existing data files`);
|
|
842
|
-
output.writeln();
|
|
843
|
-
}
|
|
844
|
-
// Show added assets (when --add-missing flag is used)
|
|
845
|
-
if (result.addedSkills && result.addedSkills.length > 0) {
|
|
846
|
-
output.printBox(result.addedSkills.map(s => `+ ${s}`).join('\n'), `Added Skills (${result.addedSkills.length} new)`);
|
|
847
|
-
output.writeln();
|
|
848
|
-
}
|
|
849
|
-
if (result.addedAgents && result.addedAgents.length > 0) {
|
|
850
|
-
output.printBox(result.addedAgents.map(a => `+ ${a}`).join('\n'), `Added Agents (${result.addedAgents.length} new)`);
|
|
851
|
-
output.writeln();
|
|
852
|
-
}
|
|
853
|
-
if (result.addedCommands && result.addedCommands.length > 0) {
|
|
854
|
-
output.printBox(result.addedCommands.map(c => `+ ${c}`).join('\n'), `Added Commands (${result.addedCommands.length} new)`);
|
|
855
|
-
output.writeln();
|
|
856
|
-
}
|
|
857
|
-
// Show settings updates
|
|
858
|
-
if (result.settingsUpdated && result.settingsUpdated.length > 0) {
|
|
859
|
-
output.printBox(result.settingsUpdated.map(s => `+ ${s}`).join('\n'), 'Settings Updated');
|
|
860
|
-
output.writeln();
|
|
861
|
-
}
|
|
862
|
-
output.printSuccess('Your statusline helper has been updated to the latest version');
|
|
863
|
-
output.printInfo('Existing metrics and learning data were preserved');
|
|
864
|
-
// Show settings summary
|
|
865
|
-
if (upgradeSettings && result.settingsUpdated && result.settingsUpdated.length > 0) {
|
|
866
|
-
output.printSuccess('Settings.json updated with new Agent Teams configuration');
|
|
867
|
-
}
|
|
868
|
-
// Show summary for --add-missing
|
|
869
|
-
if (addMissing) {
|
|
870
|
-
const totalAdded = (result.addedSkills?.length || 0) + (result.addedAgents?.length || 0) + (result.addedCommands?.length || 0);
|
|
871
|
-
if (totalAdded > 0) {
|
|
872
|
-
output.printSuccess(`Added ${totalAdded} missing assets to your project`);
|
|
873
|
-
}
|
|
874
|
-
else {
|
|
875
|
-
output.printInfo('All skills, agents, and commands are already up to date');
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
if (ctx.flags.format === 'json') {
|
|
879
|
-
output.printJson(result);
|
|
880
|
-
}
|
|
881
|
-
return { success: true, data: result };
|
|
882
|
-
}
|
|
883
|
-
catch (error) {
|
|
884
|
-
spinner.fail('Upgrade failed');
|
|
885
|
-
output.printError(`Failed to upgrade: ${error instanceof Error ? error.message : String(error)}`);
|
|
886
|
-
return { success: false, exitCode: 1 };
|
|
887
|
-
}
|
|
888
|
-
},
|
|
889
|
-
};
|
|
890
|
-
// Main init command
|
|
891
274
|
export const initCommand = {
|
|
892
275
|
name: 'init',
|
|
893
276
|
description: 'Initialize MonoMind in the current directory',
|