@claude-flow/cli 3.0.0-alpha.13 → 3.0.0-alpha.14

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 (102) hide show
  1. package/package.json +12 -4
  2. package/.agentic-flow/intelligence.json +0 -17
  3. package/.claude-flow/agents/store.json +0 -16
  4. package/.claude-flow/daemon-state.json +0 -123
  5. package/.claude-flow/daemon-test.log +0 -0
  6. package/.claude-flow/daemon.log +0 -0
  7. package/.claude-flow/daemon2.log +0 -0
  8. package/.claude-flow/daemon3.log +0 -0
  9. package/.claude-flow/hive-mind/state.json +0 -51
  10. package/.claude-flow/metrics/agent-metrics.json +0 -1
  11. package/.claude-flow/metrics/codebase-map.json +0 -11
  12. package/.claude-flow/metrics/consolidation.json +0 -6
  13. package/.claude-flow/metrics/performance.json +0 -87
  14. package/.claude-flow/metrics/security-audit.json +0 -10
  15. package/.claude-flow/metrics/task-metrics.json +0 -10
  16. package/.claude-flow/metrics/test-gaps.json +0 -6
  17. package/__tests__/README.md +0 -140
  18. package/__tests__/TEST_SUMMARY.md +0 -144
  19. package/__tests__/cli.test.ts +0 -558
  20. package/__tests__/commands.test.ts +0 -726
  21. package/__tests__/config-adapter.test.ts +0 -362
  22. package/__tests__/config-loading.test.ts +0 -106
  23. package/__tests__/coverage/.tmp/coverage-0.json +0 -1
  24. package/__tests__/coverage/.tmp/coverage-1.json +0 -1
  25. package/__tests__/coverage/.tmp/coverage-2.json +0 -1
  26. package/__tests__/coverage/.tmp/coverage-3.json +0 -1
  27. package/__tests__/coverage/.tmp/coverage-4.json +0 -1
  28. package/__tests__/coverage/.tmp/coverage-5.json +0 -1
  29. package/__tests__/mcp-client.test.ts +0 -480
  30. package/__tests__/p1-commands.test.ts +0 -1064
  31. package/agents/architect.yaml +0 -11
  32. package/agents/coder.yaml +0 -11
  33. package/agents/reviewer.yaml +0 -10
  34. package/agents/security-architect.yaml +0 -10
  35. package/agents/tester.yaml +0 -10
  36. package/docs/CONFIG_LOADING.md +0 -236
  37. package/docs/IMPLEMENTATION_COMPLETE.md +0 -421
  38. package/docs/MCP_CLIENT_GUIDE.md +0 -620
  39. package/docs/REFACTORING_SUMMARY.md +0 -247
  40. package/scripts/publish.sh +0 -46
  41. package/src/commands/agent.ts +0 -955
  42. package/src/commands/claims.ts +0 -317
  43. package/src/commands/completions.ts +0 -558
  44. package/src/commands/config.ts +0 -452
  45. package/src/commands/daemon.ts +0 -621
  46. package/src/commands/deployment.ts +0 -323
  47. package/src/commands/doctor.ts +0 -382
  48. package/src/commands/embeddings.ts +0 -686
  49. package/src/commands/hive-mind.ts +0 -928
  50. package/src/commands/hooks.ts +0 -2603
  51. package/src/commands/index.ts +0 -154
  52. package/src/commands/init.ts +0 -597
  53. package/src/commands/mcp.ts +0 -753
  54. package/src/commands/memory.ts +0 -1161
  55. package/src/commands/migrate.ts +0 -447
  56. package/src/commands/neural.ts +0 -253
  57. package/src/commands/performance.ts +0 -292
  58. package/src/commands/plugins.ts +0 -316
  59. package/src/commands/process.ts +0 -695
  60. package/src/commands/providers.ts +0 -259
  61. package/src/commands/security.ts +0 -288
  62. package/src/commands/session.ts +0 -891
  63. package/src/commands/start.ts +0 -457
  64. package/src/commands/status.ts +0 -736
  65. package/src/commands/swarm.ts +0 -648
  66. package/src/commands/task.ts +0 -792
  67. package/src/commands/workflow.ts +0 -742
  68. package/src/config-adapter.ts +0 -210
  69. package/src/index.ts +0 -443
  70. package/src/infrastructure/in-memory-repositories.ts +0 -310
  71. package/src/init/claudemd-generator.ts +0 -631
  72. package/src/init/executor.ts +0 -762
  73. package/src/init/helpers-generator.ts +0 -628
  74. package/src/init/index.ts +0 -60
  75. package/src/init/mcp-generator.ts +0 -83
  76. package/src/init/settings-generator.ts +0 -284
  77. package/src/init/statusline-generator.ts +0 -211
  78. package/src/init/types.ts +0 -447
  79. package/src/mcp-client.ts +0 -241
  80. package/src/mcp-server.ts +0 -577
  81. package/src/mcp-tools/agent-tools.ts +0 -466
  82. package/src/mcp-tools/config-tools.ts +0 -370
  83. package/src/mcp-tools/hive-mind-tools.ts +0 -521
  84. package/src/mcp-tools/hooks-tools.ts +0 -1888
  85. package/src/mcp-tools/index.ts +0 -16
  86. package/src/mcp-tools/memory-tools.ts +0 -270
  87. package/src/mcp-tools/session-tools.ts +0 -359
  88. package/src/mcp-tools/swarm-tools.ts +0 -105
  89. package/src/mcp-tools/task-tools.ts +0 -347
  90. package/src/mcp-tools/types.ts +0 -33
  91. package/src/mcp-tools/workflow-tools.ts +0 -573
  92. package/src/output.ts +0 -639
  93. package/src/parser.ts +0 -417
  94. package/src/prompt.ts +0 -619
  95. package/src/services/index.ts +0 -15
  96. package/src/services/worker-daemon.ts +0 -726
  97. package/src/suggest.ts +0 -245
  98. package/src/types.ts +0 -287
  99. package/tmp.json +0 -0
  100. package/tsconfig.json +0 -16
  101. package/tsconfig.tsbuildinfo +0 -1
  102. package/vitest.config.ts +0 -13
@@ -1,792 +0,0 @@
1
- /**
2
- * V3 CLI Task Command
3
- * Task management for Claude Flow
4
- */
5
-
6
- import type { Command, CommandContext, CommandResult } from '../types.js';
7
- import { output } from '../output.js';
8
- import { select, confirm, input, multiSelect } from '../prompt.js';
9
- import { callMCPTool, MCPClientError } from '../mcp-client.js';
10
-
11
- // Task types
12
- const TASK_TYPES = [
13
- { value: 'implementation', label: 'Implementation', hint: 'Feature implementation' },
14
- { value: 'bug-fix', label: 'Bug Fix', hint: 'Fix a bug or issue' },
15
- { value: 'refactoring', label: 'Refactoring', hint: 'Code refactoring' },
16
- { value: 'testing', label: 'Testing', hint: 'Write or update tests' },
17
- { value: 'documentation', label: 'Documentation', hint: 'Documentation updates' },
18
- { value: 'research', label: 'Research', hint: 'Research and analysis' },
19
- { value: 'review', label: 'Review', hint: 'Code review' },
20
- { value: 'optimization', label: 'Optimization', hint: 'Performance optimization' },
21
- { value: 'security', label: 'Security', hint: 'Security audit or fix' },
22
- { value: 'custom', label: 'Custom', hint: 'Custom task type' }
23
- ];
24
-
25
- // Task priorities
26
- const TASK_PRIORITIES = [
27
- { value: 'critical', label: 'Critical', hint: 'Highest priority' },
28
- { value: 'high', label: 'High', hint: 'Important task' },
29
- { value: 'normal', label: 'Normal', hint: 'Standard priority' },
30
- { value: 'low', label: 'Low', hint: 'Lower priority' }
31
- ];
32
-
33
- // Format task status with color
34
- function formatStatus(status: string): string {
35
- switch (status) {
36
- case 'completed':
37
- return output.success(status);
38
- case 'running':
39
- case 'in_progress':
40
- return output.info(status);
41
- case 'pending':
42
- case 'queued':
43
- return output.warning(status);
44
- case 'failed':
45
- case 'cancelled':
46
- return output.error(status);
47
- default:
48
- return status;
49
- }
50
- }
51
-
52
- // Format priority with color
53
- function formatPriority(priority: string): string {
54
- switch (priority) {
55
- case 'critical':
56
- return output.error(priority);
57
- case 'high':
58
- return output.warning(priority);
59
- case 'normal':
60
- return priority;
61
- case 'low':
62
- return output.dim(priority);
63
- default:
64
- return priority;
65
- }
66
- }
67
-
68
- // Create subcommand
69
- const createCommand: Command = {
70
- name: 'create',
71
- aliases: ['new', 'add'],
72
- description: 'Create a new task',
73
- options: [
74
- {
75
- name: 'type',
76
- short: 't',
77
- description: 'Task type',
78
- type: 'string',
79
- choices: TASK_TYPES.map(t => t.value)
80
- },
81
- {
82
- name: 'description',
83
- short: 'd',
84
- description: 'Task description',
85
- type: 'string'
86
- },
87
- {
88
- name: 'priority',
89
- short: 'p',
90
- description: 'Task priority',
91
- type: 'string',
92
- choices: TASK_PRIORITIES.map(p => p.value),
93
- default: 'normal'
94
- },
95
- {
96
- name: 'assign',
97
- short: 'a',
98
- description: 'Assign to agent(s)',
99
- type: 'string'
100
- },
101
- {
102
- name: 'tags',
103
- description: 'Comma-separated tags',
104
- type: 'string'
105
- },
106
- {
107
- name: 'parent',
108
- description: 'Parent task ID',
109
- type: 'string'
110
- },
111
- {
112
- name: 'dependencies',
113
- description: 'Comma-separated task IDs that must complete first',
114
- type: 'string'
115
- },
116
- {
117
- name: 'timeout',
118
- description: 'Task timeout in seconds',
119
- type: 'number',
120
- default: 300
121
- }
122
- ],
123
- action: async (ctx: CommandContext): Promise<CommandResult> => {
124
- let taskType = ctx.flags.type as string;
125
- let description = ctx.flags.description as string;
126
- let priority = ctx.flags.priority as string;
127
-
128
- // Interactive mode
129
- if (!taskType && ctx.interactive) {
130
- taskType = await select({
131
- message: 'Select task type:',
132
- options: TASK_TYPES
133
- });
134
- }
135
-
136
- if (!description && ctx.interactive) {
137
- description = await input({
138
- message: 'Task description:',
139
- validate: (v) => v.length > 0 || 'Description is required'
140
- });
141
- }
142
-
143
- if (!taskType || !description) {
144
- output.printError('Task type and description are required');
145
- output.printInfo('Use --type and --description flags, or run in interactive mode');
146
- return { success: false, exitCode: 1 };
147
- }
148
-
149
- if (!priority && ctx.interactive) {
150
- priority = await select({
151
- message: 'Select priority:',
152
- options: TASK_PRIORITIES,
153
- default: 'normal'
154
- });
155
- }
156
-
157
- // Parse tags and dependencies
158
- const tags = ctx.flags.tags ? (ctx.flags.tags as string).split(',').map(t => t.trim()) : [];
159
- const dependencies = ctx.flags.dependencies
160
- ? (ctx.flags.dependencies as string).split(',').map(d => d.trim())
161
- : [];
162
-
163
- output.writeln();
164
- output.printInfo(`Creating ${taskType} task...`);
165
-
166
- try {
167
- const result = await callMCPTool<{
168
- taskId: string;
169
- type: string;
170
- description: string;
171
- priority: string;
172
- status: string;
173
- createdAt: string;
174
- assignedTo?: string[];
175
- tags: string[];
176
- }>('task/create', {
177
- type: taskType,
178
- description,
179
- priority: priority || 'normal',
180
- assignedTo: ctx.flags.assign ? [ctx.flags.assign] : undefined,
181
- parentId: ctx.flags.parent,
182
- dependencies,
183
- tags,
184
- timeout: ctx.flags.timeout,
185
- metadata: {
186
- source: 'cli',
187
- createdBy: 'user'
188
- }
189
- });
190
-
191
- output.writeln();
192
- output.printSuccess(`Task created: ${result.taskId}`);
193
- output.writeln();
194
-
195
- output.printTable({
196
- columns: [
197
- { key: 'property', header: 'Property', width: 15 },
198
- { key: 'value', header: 'Value', width: 40 }
199
- ],
200
- data: [
201
- { property: 'ID', value: result.taskId },
202
- { property: 'Type', value: result.type },
203
- { property: 'Description', value: result.description },
204
- { property: 'Priority', value: formatPriority(result.priority) },
205
- { property: 'Status', value: formatStatus(result.status) },
206
- { property: 'Assigned To', value: result.assignedTo?.join(', ') || 'Unassigned' },
207
- { property: 'Tags', value: result.tags.join(', ') || 'None' },
208
- { property: 'Created', value: new Date(result.createdAt).toLocaleString() }
209
- ]
210
- });
211
-
212
- if (ctx.flags.format === 'json') {
213
- output.printJson(result);
214
- }
215
-
216
- return { success: true, data: result };
217
- } catch (error) {
218
- if (error instanceof MCPClientError) {
219
- output.printError(`Failed to create task: ${error.message}`);
220
- } else {
221
- output.printError(`Unexpected error: ${String(error)}`);
222
- }
223
- return { success: false, exitCode: 1 };
224
- }
225
- }
226
- };
227
-
228
- // List subcommand
229
- const listCommand: Command = {
230
- name: 'list',
231
- aliases: ['ls'],
232
- description: 'List tasks',
233
- options: [
234
- {
235
- name: 'status',
236
- short: 's',
237
- description: 'Filter by status',
238
- type: 'string',
239
- choices: ['pending', 'running', 'completed', 'failed', 'cancelled', 'all']
240
- },
241
- {
242
- name: 'type',
243
- short: 't',
244
- description: 'Filter by task type',
245
- type: 'string'
246
- },
247
- {
248
- name: 'priority',
249
- short: 'p',
250
- description: 'Filter by priority',
251
- type: 'string'
252
- },
253
- {
254
- name: 'agent',
255
- short: 'a',
256
- description: 'Filter by assigned agent',
257
- type: 'string'
258
- },
259
- {
260
- name: 'limit',
261
- short: 'l',
262
- description: 'Maximum number of tasks to show',
263
- type: 'number',
264
- default: 20
265
- },
266
- {
267
- name: 'all',
268
- description: 'Show all tasks including completed',
269
- type: 'boolean',
270
- default: false
271
- }
272
- ],
273
- action: async (ctx: CommandContext): Promise<CommandResult> => {
274
- const status = ctx.flags.all ? 'all' : (ctx.flags.status as string) || 'pending,running';
275
- const limit = ctx.flags.limit as number;
276
-
277
- try {
278
- const result = await callMCPTool<{
279
- tasks: Array<{
280
- id: string;
281
- type: string;
282
- description: string;
283
- priority: string;
284
- status: string;
285
- assignedTo?: string[];
286
- progress: number;
287
- createdAt: string;
288
- }>;
289
- total: number;
290
- }>('task/list', {
291
- status,
292
- type: ctx.flags.type,
293
- priority: ctx.flags.priority,
294
- agentId: ctx.flags.agent,
295
- limit,
296
- offset: 0
297
- });
298
-
299
- if (ctx.flags.format === 'json') {
300
- output.printJson(result);
301
- return { success: true, data: result };
302
- }
303
-
304
- output.writeln();
305
- output.writeln(output.bold('Tasks'));
306
- output.writeln();
307
-
308
- if (result.tasks.length === 0) {
309
- output.printInfo('No tasks found matching criteria');
310
- return { success: true, data: result };
311
- }
312
-
313
- output.printTable({
314
- columns: [
315
- { key: 'id', header: 'ID', width: 15 },
316
- { key: 'type', header: 'Type', width: 15 },
317
- { key: 'description', header: 'Description', width: 30 },
318
- { key: 'priority', header: 'Priority', width: 10 },
319
- { key: 'status', header: 'Status', width: 12 },
320
- { key: 'progress', header: 'Progress', width: 10 }
321
- ],
322
- data: result.tasks.map(t => ({
323
- id: t.id,
324
- type: t.type,
325
- description: t.description.length > 27
326
- ? t.description.slice(0, 27) + '...'
327
- : t.description,
328
- priority: formatPriority(t.priority),
329
- status: formatStatus(t.status),
330
- progress: `${t.progress}%`
331
- }))
332
- });
333
-
334
- output.writeln();
335
- output.printInfo(`Showing ${result.tasks.length} of ${result.total} tasks`);
336
-
337
- return { success: true, data: result };
338
- } catch (error) {
339
- if (error instanceof MCPClientError) {
340
- output.printError(`Failed to list tasks: ${error.message}`);
341
- } else {
342
- output.printError(`Unexpected error: ${String(error)}`);
343
- }
344
- return { success: false, exitCode: 1 };
345
- }
346
- }
347
- };
348
-
349
- // Status subcommand (get task details)
350
- const statusCommand: Command = {
351
- name: 'status',
352
- aliases: ['info', 'get'],
353
- description: 'Get task status and details',
354
- options: [
355
- {
356
- name: 'id',
357
- description: 'Task ID',
358
- type: 'string'
359
- },
360
- {
361
- name: 'logs',
362
- description: 'Include execution logs',
363
- type: 'boolean',
364
- default: false
365
- }
366
- ],
367
- action: async (ctx: CommandContext): Promise<CommandResult> => {
368
- let taskId = ctx.args[0] || ctx.flags.id as string;
369
-
370
- if (!taskId && ctx.interactive) {
371
- taskId = await input({
372
- message: 'Enter task ID:',
373
- validate: (v) => v.length > 0 || 'Task ID is required'
374
- });
375
- }
376
-
377
- if (!taskId) {
378
- output.printError('Task ID is required');
379
- return { success: false, exitCode: 1 };
380
- }
381
-
382
- try {
383
- const result = await callMCPTool<{
384
- id: string;
385
- type: string;
386
- description: string;
387
- priority: string;
388
- status: string;
389
- progress: number;
390
- assignedTo?: string[];
391
- parentId?: string;
392
- dependencies: string[];
393
- dependents: string[];
394
- tags: string[];
395
- createdAt: string;
396
- startedAt?: string;
397
- completedAt?: string;
398
- result?: unknown;
399
- error?: string;
400
- logs?: Array<{ timestamp: string; level: string; message: string }>;
401
- metrics?: {
402
- executionTime: number;
403
- retries: number;
404
- tokensUsed: number;
405
- };
406
- }>('task/status', {
407
- taskId,
408
- includeLogs: ctx.flags.logs,
409
- includeMetrics: true
410
- });
411
-
412
- if (ctx.flags.format === 'json') {
413
- output.printJson(result);
414
- return { success: true, data: result };
415
- }
416
-
417
- output.writeln();
418
- output.printBox(
419
- [
420
- `Type: ${result.type}`,
421
- `Status: ${formatStatus(result.status)}`,
422
- `Priority: ${formatPriority(result.priority)}`,
423
- `Progress: ${result.progress}%`,
424
- '',
425
- `Description: ${result.description}`
426
- ].join('\n'),
427
- `Task: ${result.id}`
428
- );
429
-
430
- // Assignment info
431
- output.writeln();
432
- output.writeln(output.bold('Assignment'));
433
- output.printTable({
434
- columns: [
435
- { key: 'property', header: 'Property', width: 15 },
436
- { key: 'value', header: 'Value', width: 40 }
437
- ],
438
- data: [
439
- { property: 'Assigned To', value: result.assignedTo?.join(', ') || 'Unassigned' },
440
- { property: 'Parent Task', value: result.parentId || 'None' },
441
- { property: 'Dependencies', value: result.dependencies.join(', ') || 'None' },
442
- { property: 'Dependents', value: result.dependents.join(', ') || 'None' },
443
- { property: 'Tags', value: result.tags.join(', ') || 'None' }
444
- ]
445
- });
446
-
447
- // Timeline
448
- output.writeln();
449
- output.writeln(output.bold('Timeline'));
450
- output.printTable({
451
- columns: [
452
- { key: 'event', header: 'Event', width: 15 },
453
- { key: 'time', header: 'Time', width: 30 }
454
- ],
455
- data: [
456
- { event: 'Created', time: new Date(result.createdAt).toLocaleString() },
457
- { event: 'Started', time: result.startedAt ? new Date(result.startedAt).toLocaleString() : '-' },
458
- { event: 'Completed', time: result.completedAt ? new Date(result.completedAt).toLocaleString() : '-' }
459
- ]
460
- });
461
-
462
- // Metrics
463
- if (result.metrics) {
464
- output.writeln();
465
- output.writeln(output.bold('Metrics'));
466
- output.printTable({
467
- columns: [
468
- { key: 'metric', header: 'Metric', width: 20 },
469
- { key: 'value', header: 'Value', width: 20, align: 'right' }
470
- ],
471
- data: [
472
- { metric: 'Execution Time', value: `${(result.metrics.executionTime / 1000).toFixed(2)}s` },
473
- { metric: 'Retries', value: result.metrics.retries },
474
- { metric: 'Tokens Used', value: result.metrics.tokensUsed.toLocaleString() }
475
- ]
476
- });
477
- }
478
-
479
- // Error if failed
480
- if (result.status === 'failed' && result.error) {
481
- output.writeln();
482
- output.printError(`Error: ${result.error}`);
483
- }
484
-
485
- // Logs if requested
486
- if (ctx.flags.logs && result.logs && result.logs.length > 0) {
487
- output.writeln();
488
- output.writeln(output.bold('Execution Logs'));
489
- for (const log of result.logs.slice(-20)) {
490
- const time = new Date(log.timestamp).toLocaleTimeString();
491
- const level = log.level === 'error' ? output.error(`[${log.level}]`) :
492
- log.level === 'warn' ? output.warning(`[${log.level}]`) :
493
- output.dim(`[${log.level}]`);
494
- output.writeln(` ${output.dim(time)} ${level} ${log.message}`);
495
- }
496
- }
497
-
498
- return { success: true, data: result };
499
- } catch (error) {
500
- if (error instanceof MCPClientError) {
501
- output.printError(`Failed to get task status: ${error.message}`);
502
- } else {
503
- output.printError(`Unexpected error: ${String(error)}`);
504
- }
505
- return { success: false, exitCode: 1 };
506
- }
507
- }
508
- };
509
-
510
- // Cancel subcommand
511
- const cancelCommand: Command = {
512
- name: 'cancel',
513
- aliases: ['abort', 'stop'],
514
- description: 'Cancel a running task',
515
- options: [
516
- {
517
- name: 'force',
518
- short: 'f',
519
- description: 'Force cancel without confirmation',
520
- type: 'boolean',
521
- default: false
522
- },
523
- {
524
- name: 'reason',
525
- short: 'r',
526
- description: 'Cancellation reason',
527
- type: 'string'
528
- }
529
- ],
530
- action: async (ctx: CommandContext): Promise<CommandResult> => {
531
- const taskId = ctx.args[0];
532
- const force = ctx.flags.force as boolean;
533
- const reason = ctx.flags.reason as string;
534
-
535
- if (!taskId) {
536
- output.printError('Task ID is required');
537
- return { success: false, exitCode: 1 };
538
- }
539
-
540
- if (!force && ctx.interactive) {
541
- const confirmed = await confirm({
542
- message: `Are you sure you want to cancel task ${taskId}?`,
543
- default: false
544
- });
545
-
546
- if (!confirmed) {
547
- output.printInfo('Operation cancelled');
548
- return { success: true };
549
- }
550
- }
551
-
552
- try {
553
- const result = await callMCPTool<{
554
- taskId: string;
555
- cancelled: boolean;
556
- previousStatus: string;
557
- cancelledAt: string;
558
- }>('task/cancel', {
559
- taskId,
560
- reason: reason || 'Cancelled by user via CLI'
561
- });
562
-
563
- output.writeln();
564
- output.printSuccess(`Task ${taskId} cancelled`);
565
- output.printInfo(`Previous status: ${result.previousStatus}`);
566
-
567
- if (ctx.flags.format === 'json') {
568
- output.printJson(result);
569
- }
570
-
571
- return { success: true, data: result };
572
- } catch (error) {
573
- if (error instanceof MCPClientError) {
574
- output.printError(`Failed to cancel task: ${error.message}`);
575
- } else {
576
- output.printError(`Unexpected error: ${String(error)}`);
577
- }
578
- return { success: false, exitCode: 1 };
579
- }
580
- }
581
- };
582
-
583
- // Assign subcommand
584
- const assignCommand: Command = {
585
- name: 'assign',
586
- description: 'Assign a task to agent(s)',
587
- options: [
588
- {
589
- name: 'agent',
590
- short: 'a',
591
- description: 'Agent ID(s) to assign (comma-separated)',
592
- type: 'string'
593
- },
594
- {
595
- name: 'unassign',
596
- description: 'Remove current assignment',
597
- type: 'boolean',
598
- default: false
599
- }
600
- ],
601
- action: async (ctx: CommandContext): Promise<CommandResult> => {
602
- const taskId = ctx.args[0];
603
- const agentIds = ctx.flags.agent as string;
604
- const unassign = ctx.flags.unassign as boolean;
605
-
606
- if (!taskId) {
607
- output.printError('Task ID is required');
608
- return { success: false, exitCode: 1 };
609
- }
610
-
611
- if (!agentIds && !unassign) {
612
- // Interactive agent selection
613
- if (ctx.interactive) {
614
- try {
615
- const agents = await callMCPTool<{
616
- agents: Array<{ id: string; type: string; status: string }>;
617
- }>('agent/list', { status: 'active,idle' });
618
-
619
- if (agents.agents.length === 0) {
620
- output.printWarning('No available agents');
621
- return { success: false, exitCode: 1 };
622
- }
623
-
624
- const selectedAgents = await multiSelect({
625
- message: 'Select agent(s) to assign:',
626
- options: agents.agents.map(a => ({
627
- value: a.id,
628
- label: a.id,
629
- hint: `${a.type} - ${a.status}`
630
- })),
631
- required: true
632
- });
633
-
634
- if (selectedAgents.length === 0) {
635
- output.printInfo('No agents selected');
636
- return { success: true };
637
- }
638
-
639
- // Continue with assignment
640
- const result = await callMCPTool<{
641
- taskId: string;
642
- assignedTo: string[];
643
- previouslyAssigned: string[];
644
- }>('task/assign', {
645
- taskId,
646
- agentIds: selectedAgents
647
- });
648
-
649
- output.writeln();
650
- output.printSuccess(`Task ${taskId} assigned to ${result.assignedTo.join(', ')}`);
651
-
652
- return { success: true, data: result };
653
- } catch (error) {
654
- if (error instanceof Error && error.message === 'User cancelled') {
655
- output.printInfo('Operation cancelled');
656
- return { success: true };
657
- }
658
- throw error;
659
- }
660
- }
661
-
662
- output.printError('Agent ID is required. Use --agent flag or run in interactive mode');
663
- return { success: false, exitCode: 1 };
664
- }
665
-
666
- try {
667
- const result = await callMCPTool<{
668
- taskId: string;
669
- assignedTo: string[];
670
- previouslyAssigned: string[];
671
- }>('task/assign', {
672
- taskId,
673
- agentIds: unassign ? [] : agentIds.split(',').map(id => id.trim()),
674
- unassign
675
- });
676
-
677
- output.writeln();
678
- if (unassign) {
679
- output.printSuccess(`Task ${taskId} unassigned`);
680
- } else {
681
- output.printSuccess(`Task ${taskId} assigned to ${result.assignedTo.join(', ')}`);
682
- }
683
-
684
- if (ctx.flags.format === 'json') {
685
- output.printJson(result);
686
- }
687
-
688
- return { success: true, data: result };
689
- } catch (error) {
690
- if (error instanceof MCPClientError) {
691
- output.printError(`Failed to assign task: ${error.message}`);
692
- } else {
693
- output.printError(`Unexpected error: ${String(error)}`);
694
- }
695
- return { success: false, exitCode: 1 };
696
- }
697
- }
698
- };
699
-
700
- // Retry subcommand
701
- const retryCommand: Command = {
702
- name: 'retry',
703
- aliases: ['rerun'],
704
- description: 'Retry a failed task',
705
- options: [
706
- {
707
- name: 'reset-state',
708
- description: 'Reset task state completely',
709
- type: 'boolean',
710
- default: false
711
- }
712
- ],
713
- action: async (ctx: CommandContext): Promise<CommandResult> => {
714
- const taskId = ctx.args[0];
715
- const resetState = ctx.flags['reset-state'] as boolean;
716
-
717
- if (!taskId) {
718
- output.printError('Task ID is required');
719
- return { success: false, exitCode: 1 };
720
- }
721
-
722
- try {
723
- const result = await callMCPTool<{
724
- taskId: string;
725
- newTaskId: string;
726
- previousStatus: string;
727
- status: string;
728
- }>('task/retry', {
729
- taskId,
730
- resetState
731
- });
732
-
733
- output.writeln();
734
- output.printSuccess(`Task ${taskId} retried`);
735
- output.printInfo(`New task ID: ${result.newTaskId}`);
736
- output.printInfo(`Status: ${formatStatus(result.status)}`);
737
-
738
- if (ctx.flags.format === 'json') {
739
- output.printJson(result);
740
- }
741
-
742
- return { success: true, data: result };
743
- } catch (error) {
744
- if (error instanceof MCPClientError) {
745
- output.printError(`Failed to retry task: ${error.message}`);
746
- } else {
747
- output.printError(`Unexpected error: ${String(error)}`);
748
- }
749
- return { success: false, exitCode: 1 };
750
- }
751
- }
752
- };
753
-
754
- // Main task command
755
- export const taskCommand: Command = {
756
- name: 'task',
757
- description: 'Task management commands',
758
- subcommands: [createCommand, listCommand, statusCommand, cancelCommand, assignCommand, retryCommand],
759
- options: [],
760
- examples: [
761
- { command: 'claude-flow task create -t implementation -d "Add user auth"', description: 'Create a task' },
762
- { command: 'claude-flow task list', description: 'List pending/running tasks' },
763
- { command: 'claude-flow task list --all', description: 'List all tasks' },
764
- { command: 'claude-flow task status task-123', description: 'Get task details' },
765
- { command: 'claude-flow task cancel task-123', description: 'Cancel a task' },
766
- { command: 'claude-flow task assign task-123 --agent coder-1', description: 'Assign task to agent' },
767
- { command: 'claude-flow task retry task-123', description: 'Retry a failed task' }
768
- ],
769
- action: async (ctx: CommandContext): Promise<CommandResult> => {
770
- // Show help if no subcommand
771
- output.writeln();
772
- output.writeln(output.bold('Task Management Commands'));
773
- output.writeln();
774
- output.writeln('Usage: claude-flow task <subcommand> [options]');
775
- output.writeln();
776
- output.writeln('Subcommands:');
777
- output.printList([
778
- `${output.highlight('create')} - Create a new task`,
779
- `${output.highlight('list')} - List tasks`,
780
- `${output.highlight('status')} - Get task details`,
781
- `${output.highlight('cancel')} - Cancel a running task`,
782
- `${output.highlight('assign')} - Assign task to agent(s)`,
783
- `${output.highlight('retry')} - Retry a failed task`
784
- ]);
785
- output.writeln();
786
- output.writeln('Run "claude-flow task <subcommand> --help" for subcommand help');
787
-
788
- return { success: true };
789
- }
790
- };
791
-
792
- export default taskCommand;