@mrpatronz/nexusflow 2.5.0 → 2.5.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/dist/commands/finish.d.ts.map +1 -1
- package/dist/commands/finish.js +7 -0
- package/dist/commands/finish.js.map +1 -1
- package/dist/commands/list.d.ts +3 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +5 -1
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/schedule.d.ts.map +1 -1
- package/dist/commands/schedule.js +6 -0
- package/dist/commands/schedule.js.map +1 -1
- package/dist/commands/ui.d.ts +1 -0
- package/dist/commands/ui.d.ts.map +1 -1
- package/dist/commands/ui.js +1 -1
- package/dist/commands/ui.js.map +1 -1
- package/dist/core/doctor.d.ts.map +1 -1
- package/dist/core/doctor.js +24 -0
- package/dist/core/doctor.js.map +1 -1
- package/dist/gui/assets/{AgentsPage-BNHR9qux.js → AgentsPage-gHbRof2y.js} +1 -1
- package/dist/gui/assets/{DashboardPage-BScH3Cxp.js → DashboardPage-CkXIpoFX.js} +1 -1
- package/dist/gui/assets/{GettingStartedPage-AWlI-176.js → GettingStartedPage-DRL_nbb6.js} +1 -1
- package/dist/gui/assets/{ProjectsPage-Bojj7gxI.js → ProjectsPage-C8XQ9dRr.js} +1 -1
- package/dist/gui/assets/{ScaffoldRepoInline-DJMbeHVM.js → ScaffoldRepoInline-ys4l8ho4.js} +1 -1
- package/dist/gui/assets/{SettingsPage-BAdXO8X0.js → SettingsPage-CRVDsRwi.js} +1 -1
- package/dist/gui/assets/{SkillsPage-CF6Db1FA.js → SkillsPage-BfQu6PT3.js} +1 -1
- package/dist/gui/assets/StartWorkPage-BNzeMcFc.js +1 -0
- package/dist/gui/assets/{StrategiesPage-nGbR9TAc.js → StrategiesPage-Bh6x7zhl.js} +1 -1
- package/dist/gui/assets/{WorkspacesPage-7XRtVJNF.js → WorkspacesPage-DYQt7CQ8.js} +1 -1
- package/dist/gui/assets/{alert-dialog-67uzXJi4.js → alert-dialog-D7jNzvYQ.js} +1 -1
- package/dist/gui/assets/{index-V1dDX1O_.js → index-C6qbn9Zq.js} +3 -3
- package/dist/gui/assets/{vsc-Di05BTNr.js → vsc-CvlJSs-5.js} +1 -1
- package/dist/gui/index.html +1 -1
- package/dist/index.js +115 -502
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +48 -11
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +1 -0
- package/dist/server.test.js.map +1 -1
- package/package.json +3 -3
- package/dist/gui/assets/StartWorkPage-BQid3uIw.js +0 -1
package/dist/index.js
CHANGED
|
@@ -54,136 +54,83 @@ program.hook('preAction', (thisCommand) => {
|
|
|
54
54
|
process.env.NEXUSFLOW_DEBUG = '1';
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
|
+
function isDebugMode() {
|
|
58
|
+
return process.argv.includes('--debug') || Boolean(process.env.NEXUSFLOW_DEBUG);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Wraps a command action: clean exit on prompt cancellation (Ctrl+C inside an
|
|
62
|
+
* inquirer prompt), clean red error message by default, and exit code 1.
|
|
63
|
+
* When --debug is provided, prints the full error stack.
|
|
64
|
+
*/
|
|
65
|
+
function runAction(fn) {
|
|
66
|
+
return async (...args) => {
|
|
67
|
+
try {
|
|
68
|
+
await fn(...args);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
72
|
+
console.log('\nCancelled.');
|
|
73
|
+
process.exit(0);
|
|
74
|
+
}
|
|
75
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
76
|
+
console.error(chalk.red(`\n✖ ${message}`));
|
|
77
|
+
if (isDebugMode() && error instanceof Error && error.stack) {
|
|
78
|
+
console.error(chalk.dim(error.stack));
|
|
79
|
+
}
|
|
80
|
+
else if (!isDebugMode()) {
|
|
81
|
+
console.error(chalk.dim(' (Run with --debug for details)\n'));
|
|
82
|
+
}
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
57
87
|
program
|
|
58
88
|
.command('create')
|
|
59
89
|
.description('Create a new feature workspace — pick repos, pick AI assistants, generate context')
|
|
60
|
-
.action(
|
|
61
|
-
try {
|
|
62
|
-
await createCommand();
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
66
|
-
console.log('\nCancelled.');
|
|
67
|
-
process.exit(0);
|
|
68
|
-
}
|
|
69
|
-
console.error(error);
|
|
70
|
-
process.exit(1);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
90
|
+
.action(runAction(createCommand));
|
|
73
91
|
program
|
|
74
92
|
.command('list')
|
|
75
93
|
.alias('ls')
|
|
76
94
|
.description('List all existing workspaces')
|
|
77
|
-
.
|
|
78
|
-
|
|
79
|
-
await listCommand();
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
console.error(error);
|
|
83
|
-
process.exit(1);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
95
|
+
.option('--json', 'Output as JSON')
|
|
96
|
+
.action(runAction(listCommand));
|
|
86
97
|
program
|
|
87
98
|
.command('open')
|
|
88
99
|
.description('Re-open an existing workspace in an editor')
|
|
89
|
-
.action(
|
|
90
|
-
try {
|
|
91
|
-
await openCommand();
|
|
92
|
-
}
|
|
93
|
-
catch (error) {
|
|
94
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
95
|
-
console.log('\nCancelled.');
|
|
96
|
-
process.exit(0);
|
|
97
|
-
}
|
|
98
|
-
console.error(error);
|
|
99
|
-
process.exit(1);
|
|
100
|
-
}
|
|
101
|
-
});
|
|
100
|
+
.action(runAction(openCommand));
|
|
102
101
|
program
|
|
103
102
|
.command('init')
|
|
104
103
|
.description('Initialize NexusFlow configuration')
|
|
105
|
-
.action(
|
|
106
|
-
try {
|
|
107
|
-
await initCommand();
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
111
|
-
console.log('\nCancelled.');
|
|
112
|
-
process.exit(0);
|
|
113
|
-
}
|
|
114
|
-
console.error(error);
|
|
115
|
-
process.exit(1);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
104
|
+
.action(runAction(initCommand));
|
|
118
105
|
program
|
|
119
106
|
.command('start')
|
|
120
107
|
.description('Start all services in a workspace')
|
|
121
108
|
.argument('[workspace]', 'Path to workspace (auto-detects from CWD)')
|
|
122
|
-
.action(async (workspace) => {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
128
|
-
console.log('\nCancelled.');
|
|
129
|
-
process.exit(0);
|
|
130
|
-
}
|
|
131
|
-
console.error(error);
|
|
132
|
-
process.exit(1);
|
|
133
|
-
}
|
|
134
|
-
});
|
|
109
|
+
.action(runAction(async (workspace) => {
|
|
110
|
+
await startCommand(workspace);
|
|
111
|
+
}));
|
|
135
112
|
program
|
|
136
113
|
.command('stop')
|
|
137
114
|
.description('Stop all running services in a workspace')
|
|
138
115
|
.argument('[workspace]', 'Path to workspace (auto-detects from CWD)')
|
|
139
|
-
.action(async (workspace) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
145
|
-
console.log('\nCancelled.');
|
|
146
|
-
process.exit(0);
|
|
147
|
-
}
|
|
148
|
-
console.error(error);
|
|
149
|
-
process.exit(1);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
116
|
+
.action(runAction(async (workspace) => {
|
|
117
|
+
await stopCommand(workspace);
|
|
118
|
+
}));
|
|
152
119
|
program
|
|
153
120
|
.command('logs')
|
|
154
121
|
.description('Show logs from running services')
|
|
155
122
|
.argument('[workspace]', 'Path to workspace (auto-detects from CWD)')
|
|
156
123
|
.option('-n, --lines <number>', 'Number of lines per service', '30')
|
|
157
|
-
.action(async (workspace, options) => {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
catch (error) {
|
|
162
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
163
|
-
console.log('\nCancelled.');
|
|
164
|
-
process.exit(0);
|
|
165
|
-
}
|
|
166
|
-
console.error(error);
|
|
167
|
-
process.exit(1);
|
|
168
|
-
}
|
|
169
|
-
});
|
|
124
|
+
.action(runAction(async (workspace, options) => {
|
|
125
|
+
await logsCommand(workspace, parseInt(options.lines, 10));
|
|
126
|
+
}));
|
|
170
127
|
program
|
|
171
128
|
.command('status')
|
|
172
129
|
.description('Show status of running services')
|
|
173
130
|
.argument('[workspace]', 'Path to workspace (auto-detects from CWD)')
|
|
174
|
-
.action(async (workspace) => {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
catch (error) {
|
|
179
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
180
|
-
console.log('\nCancelled.');
|
|
181
|
-
process.exit(0);
|
|
182
|
-
}
|
|
183
|
-
console.error(error);
|
|
184
|
-
process.exit(1);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
131
|
+
.action(runAction(async (workspace) => {
|
|
132
|
+
await statusCommand(workspace);
|
|
133
|
+
}));
|
|
187
134
|
program
|
|
188
135
|
.command('ui')
|
|
189
136
|
.description('Start the NexusFlow dashboard server (the backend the desktop app embeds)')
|
|
@@ -192,15 +139,9 @@ program
|
|
|
192
139
|
.option('--open', 'Also open the dashboard in your default browser')
|
|
193
140
|
.option('--server-only', '(deprecated — server-only is now the default)')
|
|
194
141
|
.option('--strict-port', 'Fail instead of auto-incrementing when the port is in use')
|
|
195
|
-
.action(async (options) => {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
catch (error) {
|
|
200
|
-
console.error(error);
|
|
201
|
-
process.exit(1);
|
|
202
|
-
}
|
|
203
|
-
});
|
|
142
|
+
.action(runAction(async (options) => {
|
|
143
|
+
await uiCommand(options);
|
|
144
|
+
}));
|
|
204
145
|
program
|
|
205
146
|
.command('dashboard')
|
|
206
147
|
.alias('dash')
|
|
@@ -271,57 +212,27 @@ program
|
|
|
271
212
|
.description('Display a unified summary of changes across all repositories (including unpushed commits)')
|
|
272
213
|
.argument('[workspace]', 'Path to workspace (auto-detects from CWD)')
|
|
273
214
|
.option('-r, --repo <repos...>', 'Only show the given repositories (by name)')
|
|
274
|
-
.action(async (workspace, options) => {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
catch (error) {
|
|
279
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
280
|
-
console.log('\nCancelled.');
|
|
281
|
-
process.exit(0);
|
|
282
|
-
}
|
|
283
|
-
console.error(error);
|
|
284
|
-
process.exit(1);
|
|
285
|
-
}
|
|
286
|
-
});
|
|
215
|
+
.action(runAction(async (workspace, options) => {
|
|
216
|
+
await diffCommand(workspace, options);
|
|
217
|
+
}));
|
|
287
218
|
// Pack command removed.
|
|
288
219
|
program
|
|
289
220
|
.command('remove')
|
|
290
221
|
.alias('rm')
|
|
291
222
|
.description('Delete a workspace and cleanly prune/remove its git worktrees')
|
|
292
223
|
.argument('[workspace]', 'Workspace name or path')
|
|
293
|
-
.action(async (workspace) => {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
catch (error) {
|
|
298
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
299
|
-
console.log('\nCancelled.');
|
|
300
|
-
process.exit(0);
|
|
301
|
-
}
|
|
302
|
-
console.error(error);
|
|
303
|
-
process.exit(1);
|
|
304
|
-
}
|
|
305
|
-
});
|
|
224
|
+
.action(runAction(async (workspace) => {
|
|
225
|
+
await removeCommand(workspace);
|
|
226
|
+
}));
|
|
306
227
|
program
|
|
307
228
|
.command('add-repo')
|
|
308
229
|
.alias('add')
|
|
309
230
|
.description('Add a repository to an existing workspace and update configurations')
|
|
310
231
|
.argument('[repo-path]', 'Path to the repository to add')
|
|
311
232
|
.argument('[workspace]', 'Workspace name or path')
|
|
312
|
-
.action(async (repoPath, workspace) => {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
catch (error) {
|
|
317
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
318
|
-
console.log('\nCancelled.');
|
|
319
|
-
process.exit(0);
|
|
320
|
-
}
|
|
321
|
-
console.error(error);
|
|
322
|
-
process.exit(1);
|
|
323
|
-
}
|
|
324
|
-
});
|
|
233
|
+
.action(runAction(async (repoPath, workspace) => {
|
|
234
|
+
await addRepoCommand(repoPath, workspace);
|
|
235
|
+
}));
|
|
325
236
|
program
|
|
326
237
|
.command('isolate')
|
|
327
238
|
.description('Dynamically isolate a repository in an in-place workspace into a dedicated worktree on demand')
|
|
@@ -330,60 +241,32 @@ program
|
|
|
330
241
|
.option('-b, --branch <branch>', 'Target feature branch name')
|
|
331
242
|
.option('--base <base>', 'Base branch to branch off')
|
|
332
243
|
.option('-w, --workspace <workspace>', 'Workspace name or path')
|
|
333
|
-
.action(async (repo, branchArg, options) => {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
catch (error) {
|
|
338
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
339
|
-
console.log('\nCancelled.');
|
|
340
|
-
process.exit(0);
|
|
341
|
-
}
|
|
342
|
-
console.error(error);
|
|
343
|
-
process.exit(1);
|
|
344
|
-
}
|
|
345
|
-
});
|
|
244
|
+
.action(runAction(async (repo, branchArg, options) => {
|
|
245
|
+
await isolateCommand(repo, branchArg, options);
|
|
246
|
+
}));
|
|
346
247
|
program
|
|
347
248
|
.command('handoff')
|
|
348
249
|
.description('Generate a compact handoff bundle (nexusflow-handoff.md) for session resumption')
|
|
349
250
|
.argument('[workspace]', 'Path to the workspace')
|
|
350
|
-
.action(async (workspace) => {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
}
|
|
354
|
-
catch (error) {
|
|
355
|
-
console.error(error);
|
|
356
|
-
process.exit(1);
|
|
357
|
-
}
|
|
358
|
-
});
|
|
251
|
+
.action(runAction(async (workspace) => {
|
|
252
|
+
await handoffCommand(workspace);
|
|
253
|
+
}));
|
|
359
254
|
program
|
|
360
255
|
.command('refresh')
|
|
361
256
|
.description('Refresh workspace context, plan and handoff files (re-analyzes only changed repos)')
|
|
362
257
|
.argument('[workspace]', 'Path to workspace (auto-detects from CWD)')
|
|
363
258
|
.option('-f, --force', 'Ignore the analysis cache and re-analyze every repository')
|
|
364
259
|
.option('-s, --strategy <id>', 'Update the teamwork strategy (use template ID, or "auto" for AI suggestion)')
|
|
365
|
-
.action(async (workspace, options) => {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
catch (error) {
|
|
370
|
-
console.error(error);
|
|
371
|
-
process.exit(1);
|
|
372
|
-
}
|
|
373
|
-
});
|
|
260
|
+
.action(runAction(async (workspace, options) => {
|
|
261
|
+
await refreshCommand(options, workspace);
|
|
262
|
+
}));
|
|
374
263
|
program
|
|
375
264
|
.command('doctor')
|
|
376
265
|
.description('Run diagnostics to verify workspace health and check for local loop issues')
|
|
377
266
|
.argument('[workspace]', 'Path to workspace (auto-detects from CWD)')
|
|
378
|
-
.action(async (workspace) => {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
catch (error) {
|
|
383
|
-
console.error(error);
|
|
384
|
-
process.exit(1);
|
|
385
|
-
}
|
|
386
|
-
});
|
|
267
|
+
.action(runAction(async (workspace) => {
|
|
268
|
+
await doctorCommand(workspace);
|
|
269
|
+
}));
|
|
387
270
|
program
|
|
388
271
|
.command('finish')
|
|
389
272
|
.description('Finish a feature — commit & push everything, open PRs, promote learnings, optionally remove the workspace')
|
|
@@ -394,19 +277,9 @@ program
|
|
|
394
277
|
.option('--cleanup', 'Remove the workspace after everything is confirmed pushed (still asks for confirmation)')
|
|
395
278
|
.option('-y, --yes', 'Accept defaults for non-destructive prompts')
|
|
396
279
|
.option('--dry-run', 'Show what finish would do without changing anything')
|
|
397
|
-
.action(async (workspace, options) => {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
}
|
|
401
|
-
catch (error) {
|
|
402
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
403
|
-
console.log('\nCancelled.');
|
|
404
|
-
process.exit(0);
|
|
405
|
-
}
|
|
406
|
-
console.error(error);
|
|
407
|
-
process.exit(1);
|
|
408
|
-
}
|
|
409
|
-
});
|
|
280
|
+
.action(runAction(async (workspace, options) => {
|
|
281
|
+
await finishCommand(workspace, options);
|
|
282
|
+
}));
|
|
410
283
|
// Knowledge command group
|
|
411
284
|
const knowledgeCmd = program
|
|
412
285
|
.command('knowledge')
|
|
@@ -420,38 +293,18 @@ knowledgeCmd
|
|
|
420
293
|
.requiredOption('-m, --message <msg>', 'The learning to record, as a rule plus its reason (max 300 chars)')
|
|
421
294
|
.option('--title <title>', 'Short title (used for decision headings)')
|
|
422
295
|
.option('-r, --repo <repo>', "Write to this repo's persistent base knowledge instead")
|
|
423
|
-
.action(async (workspace, options) => {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
}
|
|
427
|
-
catch (error) {
|
|
428
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
429
|
-
console.log('\nCancelled.');
|
|
430
|
-
process.exit(0);
|
|
431
|
-
}
|
|
432
|
-
console.error(error);
|
|
433
|
-
process.exit(1);
|
|
434
|
-
}
|
|
435
|
-
});
|
|
296
|
+
.action(runAction(async (workspace, options) => {
|
|
297
|
+
await knowledgeAddCommand(workspace, options);
|
|
298
|
+
}));
|
|
436
299
|
knowledgeCmd
|
|
437
300
|
.command('show')
|
|
438
301
|
.description("Print the workspace knowledge file (or a repo's base knowledge)")
|
|
439
302
|
.argument('[workspace]', 'Path to workspace (auto-detects from CWD)')
|
|
440
303
|
.option('-s, --section <name>', 'Only show one section')
|
|
441
304
|
.option('-r, --repo <repo>', "Show the repo's base knowledge file instead")
|
|
442
|
-
.action(async (workspace, options) => {
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
446
|
-
catch (error) {
|
|
447
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
448
|
-
console.log('\nCancelled.');
|
|
449
|
-
process.exit(0);
|
|
450
|
-
}
|
|
451
|
-
console.error(error);
|
|
452
|
-
process.exit(1);
|
|
453
|
-
}
|
|
454
|
-
});
|
|
305
|
+
.action(runAction(async (workspace, options) => {
|
|
306
|
+
await knowledgeShowCommand(workspace, options);
|
|
307
|
+
}));
|
|
455
308
|
knowledgeCmd
|
|
456
309
|
.command('promote')
|
|
457
310
|
.description('Copy workspace learnings into per-repo base knowledge so they persist across features')
|
|
@@ -461,39 +314,9 @@ knowledgeCmd
|
|
|
461
314
|
.option('-m, --message <msg>', 'Promote this text directly (non-interactive)')
|
|
462
315
|
.option('--move', 'Remove the entry from the workspace file after promoting (default: copy)')
|
|
463
316
|
.option('--all', 'Promote all decisions, gotchas and assumptions without prompting')
|
|
464
|
-
.action(async (workspace, options) => {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
}
|
|
468
|
-
catch (error) {
|
|
469
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
470
|
-
console.log('\nCancelled.');
|
|
471
|
-
process.exit(0);
|
|
472
|
-
}
|
|
473
|
-
console.error(error);
|
|
474
|
-
process.exit(1);
|
|
475
|
-
}
|
|
476
|
-
});
|
|
477
|
-
/**
|
|
478
|
-
* Wraps a command action: clean exit on prompt cancellation (Ctrl+C inside an
|
|
479
|
-
* inquirer prompt), exit code 1 with the error otherwise. New command
|
|
480
|
-
* registrations should use this instead of copy-pasting the try/catch.
|
|
481
|
-
*/
|
|
482
|
-
function runAction(fn) {
|
|
483
|
-
return async (...args) => {
|
|
484
|
-
try {
|
|
485
|
-
await fn(...args);
|
|
486
|
-
}
|
|
487
|
-
catch (error) {
|
|
488
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
489
|
-
console.log('\nCancelled.');
|
|
490
|
-
process.exit(0);
|
|
491
|
-
}
|
|
492
|
-
console.error(error);
|
|
493
|
-
process.exit(1);
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
}
|
|
317
|
+
.action(runAction(async (workspace, options) => {
|
|
318
|
+
await knowledgePromoteCommand(workspace, options);
|
|
319
|
+
}));
|
|
497
320
|
// Project command group
|
|
498
321
|
const projectCmd = program
|
|
499
322
|
.command('project')
|
|
@@ -532,216 +355,76 @@ strategyCmd
|
|
|
532
355
|
.command('list')
|
|
533
356
|
.alias('ls')
|
|
534
357
|
.description('List all available strategy templates (built-in and custom)')
|
|
535
|
-
.action(
|
|
536
|
-
try {
|
|
537
|
-
await strategyListCommand();
|
|
538
|
-
}
|
|
539
|
-
catch (error) {
|
|
540
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
541
|
-
console.log('\nCancelled.');
|
|
542
|
-
process.exit(0);
|
|
543
|
-
}
|
|
544
|
-
console.error(error);
|
|
545
|
-
process.exit(1);
|
|
546
|
-
}
|
|
547
|
-
});
|
|
358
|
+
.action(runAction(strategyListCommand));
|
|
548
359
|
strategyCmd
|
|
549
360
|
.command('create')
|
|
550
361
|
.description('Create a new custom strategy template')
|
|
551
362
|
.option('-n, --name <name>', 'Strategy name')
|
|
552
363
|
.option('-f, --file <path>', 'Load content from a .md or .txt file')
|
|
553
|
-
.action(
|
|
554
|
-
try {
|
|
555
|
-
await strategyCreateCommand(options);
|
|
556
|
-
}
|
|
557
|
-
catch (error) {
|
|
558
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
559
|
-
console.log('\nCancelled.');
|
|
560
|
-
process.exit(0);
|
|
561
|
-
}
|
|
562
|
-
console.error(error);
|
|
563
|
-
process.exit(1);
|
|
564
|
-
}
|
|
565
|
-
});
|
|
364
|
+
.action(runAction(strategyCreateCommand));
|
|
566
365
|
strategyCmd
|
|
567
366
|
.command('edit')
|
|
568
367
|
.description('Edit an existing custom strategy template')
|
|
569
368
|
.option('--id <id>', 'Template ID to edit (skips the selection prompt)')
|
|
570
|
-
.action(
|
|
571
|
-
try {
|
|
572
|
-
await strategyEditCommand(options);
|
|
573
|
-
}
|
|
574
|
-
catch (error) {
|
|
575
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
576
|
-
console.log('\nCancelled.');
|
|
577
|
-
process.exit(0);
|
|
578
|
-
}
|
|
579
|
-
console.error(error);
|
|
580
|
-
process.exit(1);
|
|
581
|
-
}
|
|
582
|
-
});
|
|
369
|
+
.action(runAction(strategyEditCommand));
|
|
583
370
|
strategyCmd
|
|
584
371
|
.command('delete')
|
|
585
372
|
.alias('rm')
|
|
586
373
|
.description('Delete a custom strategy template')
|
|
587
374
|
.option('--id <id>', 'Template ID to delete (skips the selection prompt)')
|
|
588
375
|
.option('-y, --yes', 'Skip confirmation prompt')
|
|
589
|
-
.action(
|
|
590
|
-
try {
|
|
591
|
-
await strategyDeleteCommand(options);
|
|
592
|
-
}
|
|
593
|
-
catch (error) {
|
|
594
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
595
|
-
console.log('\nCancelled.');
|
|
596
|
-
process.exit(0);
|
|
597
|
-
}
|
|
598
|
-
console.error(error);
|
|
599
|
-
process.exit(1);
|
|
600
|
-
}
|
|
601
|
-
});
|
|
376
|
+
.action(runAction(strategyDeleteCommand));
|
|
602
377
|
strategyCmd
|
|
603
378
|
.command('show')
|
|
604
379
|
.description('Display the full content of a strategy template')
|
|
605
380
|
.option('--id <id>', 'Template ID to show (skips the selection prompt)')
|
|
606
|
-
.action(
|
|
607
|
-
try {
|
|
608
|
-
await strategyShowCommand(options);
|
|
609
|
-
}
|
|
610
|
-
catch (error) {
|
|
611
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
612
|
-
console.log('\nCancelled.');
|
|
613
|
-
process.exit(0);
|
|
614
|
-
}
|
|
615
|
-
console.error(error);
|
|
616
|
-
process.exit(1);
|
|
617
|
-
}
|
|
618
|
-
});
|
|
381
|
+
.action(runAction(strategyShowCommand));
|
|
619
382
|
program
|
|
620
383
|
.command('desktop')
|
|
621
384
|
.description('Launch the NexusFlow desktop application')
|
|
622
|
-
.action(
|
|
623
|
-
try {
|
|
624
|
-
await desktopCommand();
|
|
625
|
-
}
|
|
626
|
-
catch (error) {
|
|
627
|
-
console.error(error);
|
|
628
|
-
process.exit(1);
|
|
629
|
-
}
|
|
630
|
-
});
|
|
385
|
+
.action(runAction(desktopCommand));
|
|
631
386
|
// Config command group
|
|
632
387
|
const configCmd = program.command('config').description('View and update NexusFlow configuration');
|
|
633
388
|
configCmd
|
|
634
389
|
.command('show')
|
|
635
390
|
.description('Display the current configuration')
|
|
636
|
-
.action(
|
|
637
|
-
try {
|
|
638
|
-
await configShowCommand();
|
|
639
|
-
}
|
|
640
|
-
catch (error) {
|
|
641
|
-
console.error(error);
|
|
642
|
-
process.exit(1);
|
|
643
|
-
}
|
|
644
|
-
});
|
|
391
|
+
.action(runAction(configShowCommand));
|
|
645
392
|
configCmd
|
|
646
393
|
.command('get')
|
|
647
394
|
.description('Get a specific configuration key')
|
|
648
395
|
.argument('<key>', 'Configuration key to read')
|
|
649
|
-
.action(
|
|
650
|
-
try {
|
|
651
|
-
await configGetCommand(key);
|
|
652
|
-
}
|
|
653
|
-
catch (error) {
|
|
654
|
-
console.error(error);
|
|
655
|
-
process.exit(1);
|
|
656
|
-
}
|
|
657
|
-
});
|
|
396
|
+
.action(runAction(configGetCommand));
|
|
658
397
|
configCmd
|
|
659
398
|
.command('set')
|
|
660
399
|
.description('Set a configuration key to a value')
|
|
661
400
|
.argument('<key>', 'Configuration key to set')
|
|
662
401
|
.argument('<value>', 'Value to assign')
|
|
663
|
-
.action(
|
|
664
|
-
try {
|
|
665
|
-
await configSetCommand(key, value);
|
|
666
|
-
}
|
|
667
|
-
catch (error) {
|
|
668
|
-
console.error(error);
|
|
669
|
-
process.exit(1);
|
|
670
|
-
}
|
|
671
|
-
});
|
|
402
|
+
.action(runAction(configSetCommand));
|
|
672
403
|
// Default action when 'nexusflow config' is run without a subcommand
|
|
673
|
-
configCmd.action(
|
|
674
|
-
try {
|
|
675
|
-
await configShowCommand();
|
|
676
|
-
}
|
|
677
|
-
catch (error) {
|
|
678
|
-
console.error(error);
|
|
679
|
-
process.exit(1);
|
|
680
|
-
}
|
|
681
|
-
});
|
|
404
|
+
configCmd.action(runAction(configShowCommand));
|
|
682
405
|
// Adapter command group
|
|
683
406
|
const adapterCmd = program.command('adapter').description('Manage storage adapters — list, switch, configure, or create new ones');
|
|
684
407
|
adapterCmd
|
|
685
408
|
.command('list')
|
|
686
409
|
.description('List all available storage adapters')
|
|
687
|
-
.action(
|
|
688
|
-
try {
|
|
689
|
-
await adapterListCommand();
|
|
690
|
-
}
|
|
691
|
-
catch (error) {
|
|
692
|
-
console.error(error);
|
|
693
|
-
process.exit(1);
|
|
694
|
-
}
|
|
695
|
-
});
|
|
410
|
+
.action(runAction(adapterListCommand));
|
|
696
411
|
adapterCmd
|
|
697
412
|
.command('use')
|
|
698
413
|
.description('Switch to a different storage adapter (prompts for config if needed)')
|
|
699
414
|
.argument('<name>', 'Adapter name to activate')
|
|
700
|
-
.action(
|
|
701
|
-
try {
|
|
702
|
-
await adapterUseCommand(name);
|
|
703
|
-
}
|
|
704
|
-
catch (error) {
|
|
705
|
-
console.error(error);
|
|
706
|
-
process.exit(1);
|
|
707
|
-
}
|
|
708
|
-
});
|
|
415
|
+
.action(runAction(adapterUseCommand));
|
|
709
416
|
adapterCmd
|
|
710
417
|
.command('info')
|
|
711
418
|
.description('Show detailed information about an adapter')
|
|
712
419
|
.argument('<name>', 'Adapter name to inspect')
|
|
713
|
-
.action(
|
|
714
|
-
try {
|
|
715
|
-
await adapterInfoCommand(name);
|
|
716
|
-
}
|
|
717
|
-
catch (error) {
|
|
718
|
-
console.error(error);
|
|
719
|
-
process.exit(1);
|
|
720
|
-
}
|
|
721
|
-
});
|
|
420
|
+
.action(runAction(adapterInfoCommand));
|
|
722
421
|
adapterCmd
|
|
723
422
|
.command('init')
|
|
724
423
|
.description('Scaffold a new adapter plugin project')
|
|
725
424
|
.argument('<name>', 'Name for the new adapter')
|
|
726
|
-
.action(
|
|
727
|
-
try {
|
|
728
|
-
await adapterInitCommand(name);
|
|
729
|
-
}
|
|
730
|
-
catch (error) {
|
|
731
|
-
console.error(error);
|
|
732
|
-
process.exit(1);
|
|
733
|
-
}
|
|
734
|
-
});
|
|
425
|
+
.action(runAction(adapterInitCommand));
|
|
735
426
|
// Default action when 'nexusflow adapter' is run without a subcommand
|
|
736
|
-
adapterCmd.action(
|
|
737
|
-
try {
|
|
738
|
-
await adapterListCommand();
|
|
739
|
-
}
|
|
740
|
-
catch (error) {
|
|
741
|
-
console.error(error);
|
|
742
|
-
process.exit(1);
|
|
743
|
-
}
|
|
744
|
-
});
|
|
427
|
+
adapterCmd.action(runAction(adapterListCommand));
|
|
745
428
|
// Schedule command group
|
|
746
429
|
const scheduleCmd = program
|
|
747
430
|
.command('schedule')
|
|
@@ -752,124 +435,54 @@ scheduleCmd
|
|
|
752
435
|
.argument('[workspace]', 'Path to workspace (auto-detects from CWD)')
|
|
753
436
|
.option('-t, --task <task>', 'Job to run: "sync" or "refresh"', 'sync')
|
|
754
437
|
.requiredOption('-e, --every <interval>', 'How often to run, e.g. 30m, 2h, 1d')
|
|
755
|
-
.action(async (workspace, options) => {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
}
|
|
759
|
-
catch (error) {
|
|
760
|
-
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
761
|
-
console.log('\nCancelled.');
|
|
762
|
-
process.exit(0);
|
|
763
|
-
}
|
|
764
|
-
console.error(error);
|
|
765
|
-
process.exit(1);
|
|
766
|
-
}
|
|
767
|
-
});
|
|
438
|
+
.action(runAction(async (workspace, options) => {
|
|
439
|
+
await scheduleAddCommand(workspace, options);
|
|
440
|
+
}));
|
|
768
441
|
scheduleCmd
|
|
769
442
|
.command('list')
|
|
770
443
|
.alias('ls')
|
|
771
444
|
.description('List all scheduled jobs')
|
|
772
|
-
.action(
|
|
773
|
-
try {
|
|
774
|
-
await scheduleListCommand();
|
|
775
|
-
}
|
|
776
|
-
catch (error) {
|
|
777
|
-
console.error(error);
|
|
778
|
-
process.exit(1);
|
|
779
|
-
}
|
|
780
|
-
});
|
|
445
|
+
.action(runAction(scheduleListCommand));
|
|
781
446
|
scheduleCmd
|
|
782
447
|
.command('remove')
|
|
783
448
|
.alias('rm')
|
|
784
449
|
.description('Remove a scheduled job')
|
|
785
450
|
.argument('<id>', 'Job id (see "nexusflow schedule list")')
|
|
786
|
-
.action(
|
|
787
|
-
try {
|
|
788
|
-
await scheduleRemoveCommand(id);
|
|
789
|
-
}
|
|
790
|
-
catch (error) {
|
|
791
|
-
console.error(error);
|
|
792
|
-
process.exit(1);
|
|
793
|
-
}
|
|
794
|
-
});
|
|
451
|
+
.action(runAction(scheduleRemoveCommand));
|
|
795
452
|
scheduleCmd
|
|
796
453
|
.command('enable')
|
|
797
454
|
.description('Enable a scheduled job')
|
|
798
455
|
.argument('<id>', 'Job id (see "nexusflow schedule list")')
|
|
799
|
-
.action(async (id) => {
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
}
|
|
803
|
-
catch (error) {
|
|
804
|
-
console.error(error);
|
|
805
|
-
process.exit(1);
|
|
806
|
-
}
|
|
807
|
-
});
|
|
456
|
+
.action(runAction(async (id) => {
|
|
457
|
+
await scheduleToggleCommand(id, true);
|
|
458
|
+
}));
|
|
808
459
|
scheduleCmd
|
|
809
460
|
.command('disable')
|
|
810
461
|
.description('Disable a scheduled job without removing it')
|
|
811
462
|
.argument('<id>', 'Job id (see "nexusflow schedule list")')
|
|
812
|
-
.action(async (id) => {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
}
|
|
816
|
-
catch (error) {
|
|
817
|
-
console.error(error);
|
|
818
|
-
process.exit(1);
|
|
819
|
-
}
|
|
820
|
-
});
|
|
463
|
+
.action(runAction(async (id) => {
|
|
464
|
+
await scheduleToggleCommand(id, false);
|
|
465
|
+
}));
|
|
821
466
|
scheduleCmd
|
|
822
467
|
.command('run')
|
|
823
468
|
.description('Run a scheduled job immediately')
|
|
824
469
|
.argument('<id>', 'Job id (see "nexusflow schedule list")')
|
|
825
|
-
.action(
|
|
826
|
-
try {
|
|
827
|
-
await scheduleRunCommand(id);
|
|
828
|
-
}
|
|
829
|
-
catch (error) {
|
|
830
|
-
console.error(error);
|
|
831
|
-
process.exit(1);
|
|
832
|
-
}
|
|
833
|
-
});
|
|
470
|
+
.action(runAction(scheduleRunCommand));
|
|
834
471
|
// Default action when 'nexusflow schedule' is run without a subcommand
|
|
835
|
-
scheduleCmd.action(
|
|
836
|
-
try {
|
|
837
|
-
await scheduleListCommand();
|
|
838
|
-
}
|
|
839
|
-
catch (error) {
|
|
840
|
-
console.error(error);
|
|
841
|
-
process.exit(1);
|
|
842
|
-
}
|
|
843
|
-
});
|
|
472
|
+
scheduleCmd.action(runAction(scheduleListCommand));
|
|
844
473
|
const mcp = program.command('mcp').description('Manage the NexusFlow MCP Server for AI assistants');
|
|
845
474
|
mcp
|
|
846
475
|
.command('run')
|
|
847
476
|
.description('Start the NexusFlow MCP Server (typically called automatically by AI assistants)')
|
|
848
477
|
.argument('[workspace]', 'Path to workspace (auto-detects from CWD)')
|
|
849
|
-
.action(
|
|
850
|
-
try {
|
|
851
|
-
await mcpRunCommand(workspace);
|
|
852
|
-
}
|
|
853
|
-
catch (error) {
|
|
854
|
-
console.error(error);
|
|
855
|
-
process.exit(1);
|
|
856
|
-
}
|
|
857
|
-
});
|
|
478
|
+
.action(runAction(mcpRunCommand));
|
|
858
479
|
mcp
|
|
859
480
|
.command('setup')
|
|
860
481
|
.description('Automatically configure your AI environments (Claude Desktop, Cursor, VS Code) to use the NexusFlow MCP Server')
|
|
861
|
-
.action(
|
|
862
|
-
try {
|
|
863
|
-
await mcpSetupCommand();
|
|
864
|
-
}
|
|
865
|
-
catch (error) {
|
|
866
|
-
console.error(error);
|
|
867
|
-
process.exit(1);
|
|
868
|
-
}
|
|
869
|
-
});
|
|
482
|
+
.action(runAction(mcpSetupCommand));
|
|
870
483
|
program.hook('postAction', async (thisCommand, actionCommand) => {
|
|
871
|
-
// Skip update check for MCP
|
|
872
|
-
if (actionCommand.name() === 'run' && actionCommand.parent?.name() === 'mcp') {
|
|
484
|
+
// Skip update check for non-TTY streams and MCP runs to prevent contaminating stdout stream
|
|
485
|
+
if (!process.stdout.isTTY || (actionCommand.name() === 'run' && actionCommand.parent?.name() === 'mcp')) {
|
|
873
486
|
return;
|
|
874
487
|
}
|
|
875
488
|
try {
|