codymaster 4.1.3 → 4.1.4
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/index.js +471 -506
- package/dist/ui/box.js +49 -0
- package/package.json +1 -2
- package/skills/cm-tdd/SKILL.md +8 -8
package/dist/index.js
CHANGED
|
@@ -345,8 +345,7 @@ program
|
|
|
345
345
|
case 'start':
|
|
346
346
|
case undefined:
|
|
347
347
|
if (isDashboardRunning()) {
|
|
348
|
-
console.log(
|
|
349
|
-
console.log(chalk_1.default.gray(` URL: http://localhost:${port}`));
|
|
348
|
+
console.log((0, box_1.renderResult)('warning', 'Dashboard already running.', [`${(0, theme_1.dim)('URL:')} ${(0, theme_1.brand)(`http://localhost:${port}`)}`]));
|
|
350
349
|
return;
|
|
351
350
|
}
|
|
352
351
|
(0, dashboard_1.launchDashboard)(port);
|
|
@@ -358,15 +357,13 @@ program
|
|
|
358
357
|
dashboardStatus(port);
|
|
359
358
|
break;
|
|
360
359
|
case 'open':
|
|
361
|
-
console.log(
|
|
360
|
+
console.log((0, box_1.renderResult)('info', `Opening http://localhost:${port} ...`));
|
|
362
361
|
openUrl(`http://localhost:${port}`);
|
|
363
362
|
break;
|
|
364
363
|
case 'url':
|
|
365
364
|
console.log(`http://localhost:${port}`);
|
|
366
365
|
break;
|
|
367
|
-
default:
|
|
368
|
-
console.log(chalk_1.default.red(`Unknown: ${cmd}`));
|
|
369
|
-
console.log(chalk_1.default.gray('Available: start, stop, status, open, url'));
|
|
366
|
+
default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: start, stop, status, open, url')]));
|
|
370
367
|
}
|
|
371
368
|
});
|
|
372
369
|
function isDashboardRunning() {
|
|
@@ -388,7 +385,7 @@ function isDashboardRunning() {
|
|
|
388
385
|
function stopDashboard() {
|
|
389
386
|
try {
|
|
390
387
|
if (!fs_1.default.existsSync(data_1.PID_FILE)) {
|
|
391
|
-
console.log(
|
|
388
|
+
console.log((0, box_1.renderResult)('warning', 'No dashboard running.'));
|
|
392
389
|
return;
|
|
393
390
|
}
|
|
394
391
|
const pid = parseInt(fs_1.default.readFileSync(data_1.PID_FILE, 'utf-8').trim());
|
|
@@ -397,10 +394,10 @@ function stopDashboard() {
|
|
|
397
394
|
fs_1.default.unlinkSync(data_1.PID_FILE);
|
|
398
395
|
}
|
|
399
396
|
catch (_a) { }
|
|
400
|
-
console.log(
|
|
397
|
+
console.log((0, box_1.renderResult)('success', `Dashboard stopped (PID ${pid}).`));
|
|
401
398
|
}
|
|
402
399
|
catch (err) {
|
|
403
|
-
console.log(
|
|
400
|
+
console.log((0, box_1.renderResult)('error', `Failed to stop: ${err.message}`));
|
|
404
401
|
try {
|
|
405
402
|
fs_1.default.unlinkSync(data_1.PID_FILE);
|
|
406
403
|
}
|
|
@@ -410,13 +407,10 @@ function stopDashboard() {
|
|
|
410
407
|
function dashboardStatus(port) {
|
|
411
408
|
if (isDashboardRunning()) {
|
|
412
409
|
const pid = fs_1.default.readFileSync(data_1.PID_FILE, 'utf-8').trim();
|
|
413
|
-
console.log(
|
|
414
|
-
console.log(chalk_1.default.gray(` PID: ${pid}`));
|
|
415
|
-
console.log(chalk_1.default.gray(` URL: http://localhost:${port}`));
|
|
410
|
+
console.log((0, box_1.renderResult)('success', 'Dashboard RUNNING', [`${(0, theme_1.dim)('PID:')} ${(0, theme_1.brand)(pid)}`, `${(0, theme_1.dim)('URL:')} ${(0, theme_1.brand)(`http://localhost:${port}`)}`]));
|
|
416
411
|
}
|
|
417
412
|
else {
|
|
418
|
-
console.log(
|
|
419
|
-
console.log(chalk_1.default.gray(' Start with: cm dashboard start'));
|
|
413
|
+
console.log((0, box_1.renderResult)('warning', 'Dashboard NOT running', [(0, theme_1.dim)('Start with: cm dashboard start')]));
|
|
420
414
|
}
|
|
421
415
|
}
|
|
422
416
|
// ─── Task Command ───────────────────────────────────────────────────────────
|
|
@@ -456,14 +450,12 @@ program
|
|
|
456
450
|
case 'stuck':
|
|
457
451
|
taskStuck(opts);
|
|
458
452
|
break;
|
|
459
|
-
default:
|
|
460
|
-
console.log(chalk_1.default.red(`Unknown: ${cmd}`));
|
|
461
|
-
console.log(chalk_1.default.gray('Available: add, list, move, done, rm, dispatch, stuck'));
|
|
453
|
+
default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: add, list, move, done, rm, dispatch, stuck')]));
|
|
462
454
|
}
|
|
463
455
|
});
|
|
464
456
|
function taskAdd(title, opts) {
|
|
465
457
|
if (!title) {
|
|
466
|
-
console.log(
|
|
458
|
+
console.log((0, box_1.renderResult)('error', 'Title required. Usage: cm task add "My task"'));
|
|
467
459
|
return;
|
|
468
460
|
}
|
|
469
461
|
const data = (0, data_1.loadData)();
|
|
@@ -471,7 +463,7 @@ function taskAdd(title, opts) {
|
|
|
471
463
|
if (opts.project) {
|
|
472
464
|
const project = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
473
465
|
if (!project) {
|
|
474
|
-
console.log(
|
|
466
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
475
467
|
return;
|
|
476
468
|
}
|
|
477
469
|
projectId = project.id;
|
|
@@ -493,8 +485,9 @@ function taskAdd(title, opts) {
|
|
|
493
485
|
(0, data_1.logActivity)(data, 'task_created', `Task "${task.title}" created via CLI`, projectId, opts.agent || '');
|
|
494
486
|
(0, data_1.saveData)(data);
|
|
495
487
|
const project = data.projects.find(p => p.id === projectId);
|
|
496
|
-
console.log(
|
|
497
|
-
|
|
488
|
+
console.log((0, box_1.renderResult)('success', `Task created: ${title}`, [
|
|
489
|
+
`${(0, theme_1.dim)('ID:')} ${(0, theme_1.brand)((0, data_1.shortId)(task.id))} ${(0, theme_1.dim)('|')} ${(0, theme_1.dim)('Project:')} ${(0, theme_1.brand)((project === null || project === void 0 ? void 0 : project.name) || 'Default')} ${(0, theme_1.dim)('|')} ${(0, theme_1.dim)(column)} ${(0, theme_1.dim)('|')} ${(0, theme_1.dim)(opts.priority || 'medium')}`,
|
|
490
|
+
]));
|
|
498
491
|
}
|
|
499
492
|
function taskList(opts) {
|
|
500
493
|
const data = (0, data_1.loadData)();
|
|
@@ -502,45 +495,45 @@ function taskList(opts) {
|
|
|
502
495
|
if (opts.project && !opts.all) {
|
|
503
496
|
const project = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
504
497
|
if (!project) {
|
|
505
|
-
console.log(
|
|
498
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
506
499
|
return;
|
|
507
500
|
}
|
|
508
501
|
tasks = tasks.filter(t => t.projectId === project.id);
|
|
509
|
-
console.log(
|
|
502
|
+
console.log((0, box_1.renderCommandHeader)(`Tasks — ${project.name}`, '📋'));
|
|
510
503
|
}
|
|
511
504
|
else {
|
|
512
|
-
console.log(
|
|
505
|
+
console.log((0, box_1.renderCommandHeader)('All Tasks', '📋'));
|
|
513
506
|
}
|
|
514
507
|
if (tasks.length === 0) {
|
|
515
|
-
console.log(
|
|
508
|
+
console.log(` ${(0, theme_1.dim)('No tasks found.')}\n`);
|
|
516
509
|
return;
|
|
517
510
|
}
|
|
518
|
-
console.log(
|
|
519
|
-
console.log(
|
|
511
|
+
console.log((0, theme_1.dim)(' ' + padRight('ID', 10) + padRight('Title', 36) + padRight('Column', 14) + padRight('Priority', 10) + padRight('Agent', 14) + 'Project'));
|
|
512
|
+
console.log((0, theme_1.dim)(' ' + '─'.repeat(100)));
|
|
520
513
|
const co = ['backlog', 'in-progress', 'review', 'done'];
|
|
521
514
|
tasks.sort((a, b) => co.indexOf(a.column) - co.indexOf(b.column) || a.order - b.order);
|
|
522
515
|
for (const task of tasks) {
|
|
523
516
|
const cc = COL_COLORS[task.column] || chalk_1.default.white;
|
|
524
517
|
const pc = PRIORITY_COLORS[task.priority] || chalk_1.default.white;
|
|
525
518
|
const project = data.projects.find(p => p.id === task.projectId);
|
|
526
|
-
console.log(' ' +
|
|
519
|
+
console.log(' ' + (0, theme_1.dim)(padRight((0, data_1.shortId)(task.id), 10)) + padRight(task.title.substring(0, 34), 36) + cc(padRight(task.column, 14)) + pc(padRight(task.priority, 10)) + (0, theme_1.dim)(padRight(task.agent || '—', 14)) + (0, theme_1.dim)((project === null || project === void 0 ? void 0 : project.name) || '—'));
|
|
527
520
|
}
|
|
528
|
-
console.log(
|
|
521
|
+
console.log((0, theme_1.dim)(`\n Total: ${tasks.length} tasks\n`));
|
|
529
522
|
}
|
|
530
523
|
function taskMove(idPrefix, targetColumn) {
|
|
531
524
|
if (!idPrefix || !targetColumn) {
|
|
532
|
-
console.log(
|
|
525
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm task move <id> <column>'));
|
|
533
526
|
return;
|
|
534
527
|
}
|
|
535
528
|
const vc = ['backlog', 'in-progress', 'review', 'done'];
|
|
536
529
|
if (!vc.includes(targetColumn)) {
|
|
537
|
-
console.log(
|
|
530
|
+
console.log((0, box_1.renderResult)('error', `Invalid column: ${targetColumn}`, [(0, theme_1.dim)(`Valid: ${vc.join(', ')}`)]));
|
|
538
531
|
return;
|
|
539
532
|
}
|
|
540
533
|
const data = (0, data_1.loadData)();
|
|
541
534
|
const task = (0, data_1.findTaskByIdPrefix)(data, idPrefix);
|
|
542
535
|
if (!task) {
|
|
543
|
-
console.log(
|
|
536
|
+
console.log((0, box_1.renderResult)('error', `Task not found: ${idPrefix}`));
|
|
544
537
|
return;
|
|
545
538
|
}
|
|
546
539
|
const oldCol = task.column;
|
|
@@ -553,12 +546,11 @@ function taskMove(idPrefix, targetColumn) {
|
|
|
553
546
|
};
|
|
554
547
|
const allowed = VALID_TRANSITIONS[oldCol] || [];
|
|
555
548
|
if (oldCol !== targetColumn && !allowed.includes(targetColumn)) {
|
|
556
|
-
console.log(
|
|
557
|
-
console.log(chalk_1.default.gray(` Allowed transitions: ${allowed.join(', ')}`));
|
|
549
|
+
console.log((0, box_1.renderResult)('error', `Invalid transition: ${oldCol} → ${targetColumn}`, [(0, theme_1.dim)(`Allowed: ${allowed.join(', ')}`)]));
|
|
558
550
|
return;
|
|
559
551
|
}
|
|
560
552
|
if (oldCol === targetColumn) {
|
|
561
|
-
console.log(
|
|
553
|
+
console.log(` ${(0, theme_1.dim)(`Task already in ${targetColumn}.`)}`);
|
|
562
554
|
return;
|
|
563
555
|
}
|
|
564
556
|
task.column = targetColumn;
|
|
@@ -566,8 +558,9 @@ function taskMove(idPrefix, targetColumn) {
|
|
|
566
558
|
task.stuckSince = undefined;
|
|
567
559
|
(0, data_1.logActivity)(data, targetColumn === 'done' ? 'task_done' : 'task_transitioned', `Task "${task.title}" moved: ${oldCol} → ${targetColumn} (CLI)`, task.projectId, task.agent, { from: oldCol, to: targetColumn });
|
|
568
560
|
(0, data_1.saveData)(data);
|
|
569
|
-
console.log(
|
|
570
|
-
|
|
561
|
+
console.log((0, box_1.renderResult)('success', `Moved "${task.title}"`, [
|
|
562
|
+
`${(0, theme_1.dim)(oldCol)} ${(0, theme_1.brand)('→')} ${(COL_COLORS[targetColumn] || chalk_1.default.white)(targetColumn)}`,
|
|
563
|
+
]));
|
|
571
564
|
}
|
|
572
565
|
function taskStuck(opts) {
|
|
573
566
|
const data = (0, data_1.loadData)();
|
|
@@ -577,7 +570,7 @@ function taskStuck(opts) {
|
|
|
577
570
|
if (opts.project) {
|
|
578
571
|
const project = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
579
572
|
if (!project) {
|
|
580
|
-
console.log(
|
|
573
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
581
574
|
return;
|
|
582
575
|
}
|
|
583
576
|
tasks = tasks.filter(t => t.projectId === project.id);
|
|
@@ -587,56 +580,56 @@ function taskStuck(opts) {
|
|
|
587
580
|
return elapsed > thresholdMin * 60 * 1000;
|
|
588
581
|
}).sort((a, b) => new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime());
|
|
589
582
|
if (stuck.length === 0) {
|
|
590
|
-
console.log(
|
|
583
|
+
console.log((0, box_1.renderResult)('success', `No stuck tasks! All in-progress tasks updated within ${thresholdMin}m.`));
|
|
591
584
|
return;
|
|
592
585
|
}
|
|
593
|
-
console.log(
|
|
594
|
-
console.log(
|
|
595
|
-
console.log(
|
|
586
|
+
console.log((0, box_1.renderCommandHeader)(`${stuck.length} Stuck Tasks (>${thresholdMin}m in progress)`, '⚠️'));
|
|
587
|
+
console.log((0, theme_1.dim)(' ' + padRight('ID', 10) + padRight('Title', 36) + padRight('Stuck For', 12) + padRight('Agent', 14) + 'Priority'));
|
|
588
|
+
console.log((0, theme_1.dim)(' ' + '─'.repeat(86)));
|
|
596
589
|
for (const task of stuck) {
|
|
597
590
|
const elapsed = now - new Date(task.updatedAt).getTime();
|
|
598
591
|
const minutes = Math.round(elapsed / 60000);
|
|
599
592
|
const timeStr = minutes < 60 ? `${minutes}m` : `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
|
|
600
593
|
const project = data.projects.find(p => p.id === task.projectId);
|
|
601
594
|
const pc = PRIORITY_COLORS[task.priority] || chalk_1.default.white;
|
|
602
|
-
console.log(' ' +
|
|
595
|
+
console.log(' ' + (0, theme_1.dim)(padRight((0, data_1.shortId)(task.id), 10)) + padRight(task.title.substring(0, 34), 36) + (0, theme_1.warning)(padRight(timeStr, 12)) + (0, theme_1.dim)(padRight(task.agent || '—', 14)) + pc(task.priority));
|
|
603
596
|
}
|
|
604
597
|
console.log();
|
|
605
|
-
console.log(
|
|
598
|
+
console.log((0, theme_1.dim)(' Tip: Move tasks with: cm task move <id> review|done|backlog'));
|
|
606
599
|
console.log();
|
|
607
600
|
}
|
|
608
601
|
function taskDone(idPrefix) {
|
|
609
602
|
if (!idPrefix) {
|
|
610
|
-
console.log(
|
|
603
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm task done <id>'));
|
|
611
604
|
return;
|
|
612
605
|
}
|
|
613
606
|
taskMove(idPrefix, 'done');
|
|
614
607
|
}
|
|
615
608
|
function taskRemove(idPrefix) {
|
|
616
609
|
if (!idPrefix) {
|
|
617
|
-
console.log(
|
|
610
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm task rm <id>'));
|
|
618
611
|
return;
|
|
619
612
|
}
|
|
620
613
|
const data = (0, data_1.loadData)();
|
|
621
614
|
const idx = data.tasks.findIndex(t => t.id === idPrefix || t.id.startsWith(idPrefix));
|
|
622
615
|
if (idx === -1) {
|
|
623
|
-
console.log(
|
|
616
|
+
console.log((0, box_1.renderResult)('error', `Task not found: ${idPrefix}`));
|
|
624
617
|
return;
|
|
625
618
|
}
|
|
626
619
|
const [removed] = data.tasks.splice(idx, 1);
|
|
627
620
|
(0, data_1.logActivity)(data, 'task_deleted', `Task "${removed.title}" deleted via CLI`, removed.projectId, removed.agent);
|
|
628
621
|
(0, data_1.saveData)(data);
|
|
629
|
-
console.log(
|
|
622
|
+
console.log((0, box_1.renderResult)('success', `Deleted: "${removed.title}" (${(0, data_1.shortId)(removed.id)})`));
|
|
630
623
|
}
|
|
631
624
|
function taskDispatch(idPrefix, opts) {
|
|
632
625
|
if (!idPrefix) {
|
|
633
|
-
console.log(
|
|
626
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm task dispatch <id> [--force]'));
|
|
634
627
|
return;
|
|
635
628
|
}
|
|
636
629
|
const data = (0, data_1.loadData)();
|
|
637
630
|
const task = (0, data_1.findTaskByIdPrefix)(data, idPrefix);
|
|
638
631
|
if (!task) {
|
|
639
|
-
console.log(
|
|
632
|
+
console.log((0, box_1.renderResult)('error', `Task not found: ${idPrefix}`));
|
|
640
633
|
return;
|
|
641
634
|
}
|
|
642
635
|
const project = data.projects.find(p => p.id === task.projectId);
|
|
@@ -650,20 +643,21 @@ function taskDispatch(idPrefix, opts) {
|
|
|
650
643
|
taskId: task.id, filePath: result.filePath, force: opts.force || false,
|
|
651
644
|
});
|
|
652
645
|
(0, data_1.saveData)(data);
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
646
|
+
const details = [
|
|
647
|
+
`${(0, theme_1.dim)('Task:')} ${(0, theme_1.brand)(task.title)}`,
|
|
648
|
+
`${(0, theme_1.dim)('Agent:')} ${(0, theme_1.brand)(task.agent)}`,
|
|
649
|
+
];
|
|
656
650
|
if (task.skill)
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
console.log();
|
|
651
|
+
details.push(`${(0, theme_1.dim)('Skill:')} ${(0, theme_1.brand)(task.skill)}`);
|
|
652
|
+
details.push(`${(0, theme_1.dim)('File:')} ${(0, theme_1.brand)(result.filePath)}`);
|
|
653
|
+
console.log((0, box_1.renderResult)('success', `Task dispatched to ${task.agent}!`, details));
|
|
660
654
|
}
|
|
661
655
|
else {
|
|
662
656
|
task.dispatchStatus = 'failed';
|
|
663
657
|
task.dispatchError = result.error;
|
|
664
658
|
task.updatedAt = new Date().toISOString();
|
|
665
659
|
(0, data_1.saveData)(data);
|
|
666
|
-
console.log(
|
|
660
|
+
console.log((0, box_1.renderResult)('error', `Dispatch failed: ${result.error}`));
|
|
667
661
|
}
|
|
668
662
|
}
|
|
669
663
|
// ─── Project Command ────────────────────────────────────────────────────────
|
|
@@ -685,14 +679,12 @@ program
|
|
|
685
679
|
case 'delete':
|
|
686
680
|
projectRemove(args[0]);
|
|
687
681
|
break;
|
|
688
|
-
default:
|
|
689
|
-
console.log(chalk_1.default.red(`Unknown: ${cmd}`));
|
|
690
|
-
console.log(chalk_1.default.gray('Available: add, list, rm'));
|
|
682
|
+
default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: add, list, rm')]));
|
|
691
683
|
}
|
|
692
684
|
});
|
|
693
685
|
function projectAdd(name, opts) {
|
|
694
686
|
if (!name) {
|
|
695
|
-
console.log(
|
|
687
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm project add "my-project"'));
|
|
696
688
|
return;
|
|
697
689
|
}
|
|
698
690
|
const data = (0, data_1.loadData)();
|
|
@@ -700,35 +692,36 @@ function projectAdd(name, opts) {
|
|
|
700
692
|
data.projects.push(project);
|
|
701
693
|
(0, data_1.logActivity)(data, 'project_created', `Project "${project.name}" created via CLI`, project.id);
|
|
702
694
|
(0, data_1.saveData)(data);
|
|
703
|
-
console.log(
|
|
704
|
-
|
|
695
|
+
console.log((0, box_1.renderResult)('success', `Project created: ${name}`, [
|
|
696
|
+
`${(0, theme_1.dim)('ID:')} ${(0, theme_1.brand)((0, data_1.shortId)(project.id))} ${(0, theme_1.dim)('|')} ${(0, theme_1.dim)('Path:')} ${(0, theme_1.brand)(project.path)}`,
|
|
697
|
+
]));
|
|
705
698
|
}
|
|
706
699
|
function projectList() {
|
|
707
700
|
const data = (0, data_1.loadData)();
|
|
708
701
|
if (data.projects.length === 0) {
|
|
709
|
-
console.log(
|
|
702
|
+
console.log(`\n ${(0, theme_1.dim)('No projects.')}\n`);
|
|
710
703
|
return;
|
|
711
704
|
}
|
|
712
|
-
console.log(
|
|
713
|
-
console.log(
|
|
714
|
-
console.log(
|
|
705
|
+
console.log((0, box_1.renderCommandHeader)('Projects', '📦'));
|
|
706
|
+
console.log((0, theme_1.dim)(' ' + padRight('ID', 10) + padRight('Name', 24) + padRight('Tasks', 8) + padRight('Agents', 20) + 'Path'));
|
|
707
|
+
console.log((0, theme_1.dim)(' ' + '─'.repeat(90)));
|
|
715
708
|
for (const project of data.projects) {
|
|
716
709
|
const pt = data.tasks.filter(t => t.projectId === project.id);
|
|
717
710
|
const agents = [...new Set(pt.map(t => t.agent).filter(Boolean))];
|
|
718
711
|
const done = pt.filter(t => t.column === 'done').length;
|
|
719
|
-
console.log(' ' +
|
|
712
|
+
console.log(' ' + (0, theme_1.dim)(padRight((0, data_1.shortId)(project.id), 10)) + (0, theme_1.brand)(padRight(project.name, 24)) + (0, theme_1.dim)(padRight(`${done}/${pt.length}`, 8)) + (0, theme_1.dim)(padRight(agents.join(', ') || '—', 20)) + (0, theme_1.dim)(project.path || '—'));
|
|
720
713
|
}
|
|
721
714
|
console.log();
|
|
722
715
|
}
|
|
723
716
|
function projectRemove(query) {
|
|
724
717
|
if (!query) {
|
|
725
|
-
console.log(
|
|
718
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm project rm <name-or-id>'));
|
|
726
719
|
return;
|
|
727
720
|
}
|
|
728
721
|
const data = (0, data_1.loadData)();
|
|
729
722
|
const project = (0, data_1.findProjectByNameOrId)(data, query);
|
|
730
723
|
if (!project) {
|
|
731
|
-
console.log(
|
|
724
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${query}`));
|
|
732
725
|
return;
|
|
733
726
|
}
|
|
734
727
|
const tc = data.tasks.filter(t => t.projectId === project.id).length;
|
|
@@ -736,7 +729,7 @@ function projectRemove(query) {
|
|
|
736
729
|
data.tasks = data.tasks.filter(t => t.projectId !== project.id);
|
|
737
730
|
(0, data_1.logActivity)(data, 'project_deleted', `Project "${project.name}" deleted via CLI`, project.id);
|
|
738
731
|
(0, data_1.saveData)(data);
|
|
739
|
-
console.log(
|
|
732
|
+
console.log((0, box_1.renderResult)('success', `Deleted project "${project.name}" and ${tc} tasks.`));
|
|
740
733
|
}
|
|
741
734
|
// ─── Deploy Command ─────────────────────────────────────────────────────────
|
|
742
735
|
program
|
|
@@ -761,9 +754,7 @@ program
|
|
|
761
754
|
case 'ls':
|
|
762
755
|
deployList(opts);
|
|
763
756
|
break;
|
|
764
|
-
default:
|
|
765
|
-
console.log(chalk_1.default.red(`Unknown: ${cmd}`));
|
|
766
|
-
console.log(chalk_1.default.gray('Available: staging, production, list'));
|
|
757
|
+
default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: staging, production, list')]));
|
|
767
758
|
}
|
|
768
759
|
});
|
|
769
760
|
function deployRecord(env, opts) {
|
|
@@ -772,7 +763,7 @@ function deployRecord(env, opts) {
|
|
|
772
763
|
if (opts.project) {
|
|
773
764
|
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
774
765
|
if (!p) {
|
|
775
|
-
console.log(
|
|
766
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
776
767
|
return;
|
|
777
768
|
}
|
|
778
769
|
projectId = p.id;
|
|
@@ -781,7 +772,7 @@ function deployRecord(env, opts) {
|
|
|
781
772
|
projectId = data.projects[0].id;
|
|
782
773
|
}
|
|
783
774
|
else {
|
|
784
|
-
console.log(
|
|
775
|
+
console.log((0, box_1.renderResult)('error', 'No projects. Create one first: cm project add "my-project"'));
|
|
785
776
|
return;
|
|
786
777
|
}
|
|
787
778
|
const now = new Date().toISOString();
|
|
@@ -794,17 +785,18 @@ function deployRecord(env, opts) {
|
|
|
794
785
|
data.deployments.unshift(dep);
|
|
795
786
|
(0, data_1.logActivity)(data, env === 'staging' ? 'deploy_staging' : 'deploy_production', `Deployed to ${env}: ${dep.message}`, projectId, opts.agent || '', { deploymentId: dep.id });
|
|
796
787
|
(0, data_1.saveData)(data);
|
|
797
|
-
const envColor = env === 'production' ?
|
|
788
|
+
const envColor = env === 'production' ? theme_1.success : theme_1.warning;
|
|
798
789
|
const project = data.projects.find(p => p.id === projectId);
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
790
|
+
const details = [
|
|
791
|
+
`${(0, theme_1.dim)('ID:')} ${(0, theme_1.brand)((0, data_1.shortId)(dep.id))}`,
|
|
792
|
+
`${(0, theme_1.dim)('Env:')} ${envColor(env)}`,
|
|
793
|
+
`${(0, theme_1.dim)('Project:')} ${(0, theme_1.brand)((project === null || project === void 0 ? void 0 : project.name) || '—')}`,
|
|
794
|
+
`${(0, theme_1.dim)('Message:')} ${dep.message}`,
|
|
795
|
+
];
|
|
804
796
|
if (dep.commit)
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
console.log();
|
|
797
|
+
details.push(`${(0, theme_1.dim)('Commit:')} ${(0, theme_1.brand)(dep.commit)}`);
|
|
798
|
+
details.push(`${(0, theme_1.dim)('Branch:')} ${(0, theme_1.brand)(dep.branch)}`);
|
|
799
|
+
console.log((0, box_1.renderResult)('success', 'Deployment recorded!', details));
|
|
808
800
|
}
|
|
809
801
|
function deployList(opts) {
|
|
810
802
|
const data = (0, data_1.loadData)();
|
|
@@ -812,26 +804,26 @@ function deployList(opts) {
|
|
|
812
804
|
if (opts.project) {
|
|
813
805
|
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
814
806
|
if (!p) {
|
|
815
|
-
console.log(
|
|
807
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
816
808
|
return;
|
|
817
809
|
}
|
|
818
810
|
deps = deps.filter(d => d.projectId === p.id);
|
|
819
811
|
}
|
|
820
812
|
if (deps.length === 0) {
|
|
821
|
-
console.log(
|
|
813
|
+
console.log(`\n ${(0, theme_1.dim)('No deployments yet.')}\n`);
|
|
822
814
|
return;
|
|
823
815
|
}
|
|
824
|
-
console.log(
|
|
825
|
-
console.log(
|
|
826
|
-
console.log(
|
|
816
|
+
console.log((0, box_1.renderCommandHeader)('Deployment History', '🚀'));
|
|
817
|
+
console.log((0, theme_1.dim)(' ' + padRight('ID', 10) + padRight('Env', 12) + padRight('Status', 14) + padRight('Message', 32) + padRight('Branch', 12) + 'Time'));
|
|
818
|
+
console.log((0, theme_1.dim)(' ' + '─'.repeat(100)));
|
|
827
819
|
for (const dep of deps.slice(0, 20)) {
|
|
828
820
|
const sc = STATUS_COLORS[dep.status] || chalk_1.default.white;
|
|
829
|
-
const ec = dep.env === 'production' ?
|
|
821
|
+
const ec = dep.env === 'production' ? theme_1.success : theme_1.warning;
|
|
830
822
|
const timeAgo = formatTimeAgoCli(dep.startedAt);
|
|
831
823
|
const rollbackFlag = dep.rollbackOf ? ' ⏪' : '';
|
|
832
|
-
console.log(' ' +
|
|
824
|
+
console.log(' ' + (0, theme_1.dim)(padRight((0, data_1.shortId)(dep.id), 10)) + ec(padRight(dep.env, 12)) + sc(padRight(dep.status.replace('_', ' ') + rollbackFlag, 14)) + padRight(dep.message.substring(0, 30), 32) + (0, theme_1.dim)(padRight(dep.branch || '—', 12)) + (0, theme_1.dim)(timeAgo));
|
|
833
825
|
}
|
|
834
|
-
console.log(
|
|
826
|
+
console.log((0, theme_1.dim)(`\n Total: ${deps.length} deployments\n`));
|
|
835
827
|
}
|
|
836
828
|
// ─── Rollback Command ───────────────────────────────────────────────────────
|
|
837
829
|
program
|
|
@@ -843,11 +835,11 @@ program
|
|
|
843
835
|
const data = (0, data_1.loadData)();
|
|
844
836
|
const dep = data.deployments.find(d => d.id === deployId || d.id.startsWith(deployId));
|
|
845
837
|
if (!dep) {
|
|
846
|
-
console.log(
|
|
838
|
+
console.log((0, box_1.renderResult)('error', `Deployment not found: ${deployId}`));
|
|
847
839
|
return;
|
|
848
840
|
}
|
|
849
841
|
if (dep.status === 'rolled_back') {
|
|
850
|
-
console.log(
|
|
842
|
+
console.log((0, box_1.renderResult)('warning', 'Already rolled back.'));
|
|
851
843
|
return;
|
|
852
844
|
}
|
|
853
845
|
dep.status = 'rolled_back';
|
|
@@ -860,10 +852,11 @@ program
|
|
|
860
852
|
data.deployments.unshift(rollback);
|
|
861
853
|
(0, data_1.logActivity)(data, 'rollback', `Rolled back ${dep.env} deploy: ${dep.message}`, dep.projectId, opts.agent || '', { originalDeployId: dep.id, rollbackId: rollback.id });
|
|
862
854
|
(0, data_1.saveData)(data);
|
|
863
|
-
console.log(
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
855
|
+
console.log((0, box_1.renderResult)('success', 'Rollback complete!', [
|
|
856
|
+
`${(0, theme_1.dim)('Original:')} ${(0, theme_1.brand)((0, data_1.shortId)(dep.id))} ${(0, theme_1.dim)(`(${dep.env})`)}`,
|
|
857
|
+
`${(0, theme_1.dim)('Rollback ID:')} ${(0, theme_1.brand)((0, data_1.shortId)(rollback.id))}`,
|
|
858
|
+
`${(0, theme_1.dim)('Status:')} ${dep.message} → rolled back`,
|
|
859
|
+
]));
|
|
867
860
|
});
|
|
868
861
|
// ─── History Command ────────────────────────────────────────────────────────
|
|
869
862
|
program
|
|
@@ -878,7 +871,7 @@ program
|
|
|
878
871
|
if (opts.project) {
|
|
879
872
|
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
880
873
|
if (!p) {
|
|
881
|
-
console.log(
|
|
874
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
882
875
|
return;
|
|
883
876
|
}
|
|
884
877
|
acts = acts.filter(a => a.projectId === p.id);
|
|
@@ -886,23 +879,23 @@ program
|
|
|
886
879
|
const limit = parseInt(opts.limit) || 20;
|
|
887
880
|
acts = acts.slice(0, limit);
|
|
888
881
|
if (acts.length === 0) {
|
|
889
|
-
console.log(
|
|
882
|
+
console.log(`\n ${(0, theme_1.dim)('No activity yet.')}\n`);
|
|
890
883
|
return;
|
|
891
884
|
}
|
|
892
|
-
const
|
|
885
|
+
const ACT_ICONS = {
|
|
893
886
|
'task_created': '✨', 'task_moved': '↔️', 'task_done': '✅', 'task_deleted': '🗑️', 'task_updated': '✏️',
|
|
894
887
|
'project_created': '📦', 'project_deleted': '🗑️',
|
|
895
888
|
'deploy_staging': '🟡', 'deploy_production': '🚀', 'deploy_failed': '❌', 'rollback': '⏪',
|
|
896
889
|
'git_push': '📤', 'changelog_added': '📝',
|
|
897
890
|
};
|
|
898
|
-
console.log(
|
|
891
|
+
console.log((0, box_1.renderCommandHeader)(`Activity History (latest ${acts.length})`, '📜'));
|
|
899
892
|
for (const a of acts) {
|
|
900
|
-
const icon =
|
|
893
|
+
const icon = ACT_ICONS[a.type] || '📌';
|
|
901
894
|
const proj = data.projects.find(p => p.id === a.projectId);
|
|
902
|
-
const projTag = proj ?
|
|
903
|
-
const agentTag = a.agent ?
|
|
895
|
+
const projTag = proj ? (0, theme_1.dim)(` [${proj.name}]`) : '';
|
|
896
|
+
const agentTag = a.agent ? (0, theme_1.dim)(` @${a.agent}`) : '';
|
|
904
897
|
const time = formatTimeAgoCli(a.createdAt);
|
|
905
|
-
console.log(` ${icon} ${a.message}${projTag}${agentTag} ${
|
|
898
|
+
console.log(` ${icon} ${a.message}${projTag}${agentTag} ${(0, theme_1.dim)(`← ${time}`)}`);
|
|
906
899
|
}
|
|
907
900
|
console.log();
|
|
908
901
|
});
|
|
@@ -922,14 +915,12 @@ program
|
|
|
922
915
|
case 'ls':
|
|
923
916
|
changelogList(opts);
|
|
924
917
|
break;
|
|
925
|
-
default:
|
|
926
|
-
console.log(chalk_1.default.red(`Unknown: ${cmd}`));
|
|
927
|
-
console.log(chalk_1.default.gray('Available: add, list'));
|
|
918
|
+
default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: add, list')]));
|
|
928
919
|
}
|
|
929
920
|
});
|
|
930
921
|
function changelogAdd(args, opts) {
|
|
931
922
|
if (args.length < 2) {
|
|
932
|
-
console.log(
|
|
923
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm changelog add <version> "<title>" [changes...]'));
|
|
933
924
|
return;
|
|
934
925
|
}
|
|
935
926
|
const data = (0, data_1.loadData)();
|
|
@@ -937,7 +928,7 @@ function changelogAdd(args, opts) {
|
|
|
937
928
|
if (opts.project) {
|
|
938
929
|
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
939
930
|
if (!p) {
|
|
940
|
-
console.log(
|
|
931
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
941
932
|
return;
|
|
942
933
|
}
|
|
943
934
|
projectId = p.id;
|
|
@@ -955,13 +946,11 @@ function changelogAdd(args, opts) {
|
|
|
955
946
|
data.changelog.unshift(entry);
|
|
956
947
|
(0, data_1.logActivity)(data, 'changelog_added', `Changelog ${version}: ${title}`, projectId, opts.agent || '');
|
|
957
948
|
(0, data_1.saveData)(data);
|
|
958
|
-
|
|
959
|
-
console.log(chalk_1.default.gray(` Version: ${version}`));
|
|
960
|
-
console.log(chalk_1.default.gray(` Title: ${title}`));
|
|
949
|
+
const details = [`${(0, theme_1.dim)('Version:')} ${(0, theme_1.brand)(version)}`, `${(0, theme_1.dim)('Title:')} ${title}`];
|
|
961
950
|
if (changes.length > 0) {
|
|
962
|
-
changes.forEach(c =>
|
|
951
|
+
changes.forEach(c => details.push(`${(0, theme_1.dim)('•')} ${c}`));
|
|
963
952
|
}
|
|
964
|
-
console.log();
|
|
953
|
+
console.log((0, box_1.renderResult)('success', 'Changelog entry added!', details));
|
|
965
954
|
}
|
|
966
955
|
function changelogList(opts) {
|
|
967
956
|
const data = (0, data_1.loadData)();
|
|
@@ -969,21 +958,21 @@ function changelogList(opts) {
|
|
|
969
958
|
if (opts.project) {
|
|
970
959
|
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
971
960
|
if (!p) {
|
|
972
|
-
console.log(
|
|
961
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
973
962
|
return;
|
|
974
963
|
}
|
|
975
964
|
entries = entries.filter(c => c.projectId === p.id);
|
|
976
965
|
}
|
|
977
966
|
if (entries.length === 0) {
|
|
978
|
-
console.log(
|
|
967
|
+
console.log(`\n ${(0, theme_1.dim)('No changelog entries.')}\n`);
|
|
979
968
|
return;
|
|
980
969
|
}
|
|
981
|
-
console.log(
|
|
970
|
+
console.log((0, box_1.renderCommandHeader)('Changelog', '📝'));
|
|
982
971
|
for (const entry of entries) {
|
|
983
972
|
const proj = data.projects.find(p => p.id === entry.projectId);
|
|
984
|
-
console.log(
|
|
973
|
+
console.log((0, theme_1.brand)(` ${entry.version}`) + ` — ${entry.title}` + (0, theme_1.dim)(` (${formatTimeAgoCli(entry.createdAt)})${proj ? ' [' + proj.name + ']' : ''}`));
|
|
985
974
|
if (entry.changes.length > 0) {
|
|
986
|
-
entry.changes.forEach(c => console.log(
|
|
975
|
+
entry.changes.forEach(c => console.log((0, theme_1.dim)(` • ${c}`)));
|
|
987
976
|
}
|
|
988
977
|
}
|
|
989
978
|
console.log();
|
|
@@ -996,32 +985,32 @@ program
|
|
|
996
985
|
.action(() => {
|
|
997
986
|
const data = (0, data_1.loadData)();
|
|
998
987
|
showBanner();
|
|
999
|
-
console.log(
|
|
988
|
+
console.log((0, box_1.renderCommandHeader)('Status Overview', '📊'));
|
|
1000
989
|
// Projects
|
|
1001
|
-
console.log(
|
|
990
|
+
console.log((0, theme_1.brand)(` Projects: ${data.projects.length}`));
|
|
1002
991
|
for (const p of data.projects) {
|
|
1003
992
|
const pt = data.tasks.filter(t => t.projectId === p.id);
|
|
1004
993
|
const done = pt.filter(t => t.column === 'done').length;
|
|
1005
994
|
const pct = pt.length > 0 ? Math.round((done / pt.length) * 100) : 0;
|
|
1006
|
-
console.log(
|
|
995
|
+
console.log((0, theme_1.dim)(` 📦 ${padRight(p.name, 20)} ${progressBar(pct)} ${done}/${pt.length} (${pct}%)`));
|
|
1007
996
|
}
|
|
1008
997
|
// Tasks
|
|
1009
998
|
const total = data.tasks.length;
|
|
1010
999
|
const byCol = { backlog: 0, 'in-progress': 0, review: 0, done: 0 };
|
|
1011
1000
|
data.tasks.forEach(t => { byCol[t.column] = (byCol[t.column] || 0) + 1; });
|
|
1012
1001
|
console.log();
|
|
1013
|
-
console.log(
|
|
1014
|
-
console.log(
|
|
1015
|
-
console.log(
|
|
1016
|
-
console.log(
|
|
1017
|
-
console.log(
|
|
1002
|
+
console.log((0, theme_1.brand)(` Tasks: ${total}`));
|
|
1003
|
+
console.log((0, theme_1.dim)(` ⚪ Backlog: ${byCol.backlog}`));
|
|
1004
|
+
console.log((0, theme_1.info)(` 🟢 In Progress: ${byCol['in-progress']}`));
|
|
1005
|
+
console.log((0, theme_1.warning)(` 🟡 Review: ${byCol.review}`));
|
|
1006
|
+
console.log((0, theme_1.success)(` 🟢 Done: ${byCol.done}`));
|
|
1018
1007
|
// Deploys
|
|
1019
1008
|
if (data.deployments.length > 0) {
|
|
1020
1009
|
console.log();
|
|
1021
|
-
console.log(
|
|
1010
|
+
console.log((0, theme_1.brand)(` Deployments: ${data.deployments.length}`));
|
|
1022
1011
|
const latest = data.deployments[0];
|
|
1023
1012
|
const sc = STATUS_COLORS[latest.status] || chalk_1.default.white;
|
|
1024
|
-
console.log(
|
|
1013
|
+
console.log((0, theme_1.dim)(` Latest: ${latest.env} — ${sc(latest.status)} — ${latest.message} (${formatTimeAgoCli(latest.startedAt)})`));
|
|
1025
1014
|
}
|
|
1026
1015
|
// Agents
|
|
1027
1016
|
const agentCounts = {};
|
|
@@ -1030,18 +1019,18 @@ program
|
|
|
1030
1019
|
const agentNames = Object.keys(agentCounts);
|
|
1031
1020
|
if (agentNames.length > 0) {
|
|
1032
1021
|
console.log();
|
|
1033
|
-
console.log(
|
|
1022
|
+
console.log((0, theme_1.brand)(` Active Agents: ${agentNames.length}`));
|
|
1034
1023
|
for (const agent of agentNames.sort()) {
|
|
1035
|
-
console.log(
|
|
1024
|
+
console.log((0, theme_1.dim)(` 🤖 ${padRight(agent, 16)} ${agentCounts[agent]} tasks`));
|
|
1036
1025
|
}
|
|
1037
1026
|
}
|
|
1038
1027
|
// Dashboard
|
|
1039
1028
|
console.log();
|
|
1040
1029
|
if (isDashboardRunning()) {
|
|
1041
|
-
console.log(
|
|
1030
|
+
console.log((0, theme_1.success)(` 🚀 Dashboard: RUNNING at http://codymaster.localhost:${data_1.DEFAULT_PORT}`));
|
|
1042
1031
|
}
|
|
1043
1032
|
else {
|
|
1044
|
-
console.log(
|
|
1033
|
+
console.log((0, theme_1.dim)(` ⚫ Dashboard: not running (start with: cm dashboard)`));
|
|
1045
1034
|
}
|
|
1046
1035
|
console.log();
|
|
1047
1036
|
});
|
|
@@ -1069,22 +1058,24 @@ program
|
|
|
1069
1058
|
.description('Install an agent skill')
|
|
1070
1059
|
.option('-p, --platform <platform>', 'Target platform (gemini|claude|cursor|windsurf|cline)')
|
|
1071
1060
|
.action((skill, opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1072
|
-
console.log(
|
|
1061
|
+
console.log((0, theme_1.brand)(` Installing skill: ${skill}...`));
|
|
1073
1062
|
if (!opts.platform) {
|
|
1074
|
-
const
|
|
1075
|
-
const
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
{
|
|
1079
|
-
{
|
|
1080
|
-
{
|
|
1081
|
-
{
|
|
1082
|
-
{
|
|
1083
|
-
]
|
|
1063
|
+
const p = yield Promise.resolve().then(() => __importStar(require('@clack/prompts')));
|
|
1064
|
+
const platform = yield p.select({
|
|
1065
|
+
message: 'Which platform?',
|
|
1066
|
+
options: [
|
|
1067
|
+
{ label: '🟢 Google Antigravity', value: 'gemini' },
|
|
1068
|
+
{ label: '🟣 Claude Code', value: 'claude' },
|
|
1069
|
+
{ label: '🔵 Cursor', value: 'cursor' },
|
|
1070
|
+
{ label: '🟠 Windsurf', value: 'windsurf' },
|
|
1071
|
+
{ label: '🟤 Cline / RooCode', value: 'cline' },
|
|
1072
|
+
],
|
|
1084
1073
|
});
|
|
1085
|
-
|
|
1074
|
+
if (p.isCancel(platform))
|
|
1075
|
+
return;
|
|
1076
|
+
opts.platform = platform;
|
|
1086
1077
|
}
|
|
1087
|
-
console.log(
|
|
1078
|
+
console.log((0, box_1.renderResult)('success', `Skill '${skill}' installed for ${opts.platform}!`));
|
|
1088
1079
|
}));
|
|
1089
1080
|
// ─── Add Command (npx codymaster add --skill cm-debugging) ───────────────────
|
|
1090
1081
|
const ALL_SKILLS = [
|
|
@@ -1162,12 +1153,11 @@ function doAddSkills(skills, platform) {
|
|
|
1162
1153
|
console.log();
|
|
1163
1154
|
const { execFileSync } = require('child_process');
|
|
1164
1155
|
if (platform === 'claude') {
|
|
1165
|
-
console.log(
|
|
1166
|
-
console.log(
|
|
1167
|
-
// Step 1: Register marketplace
|
|
1168
|
-
console.log(
|
|
1156
|
+
console.log((0, theme_1.brand)('🟣 Claude Code — Installing via plugin system'));
|
|
1157
|
+
console.log((0, theme_1.dim)(' (Claude installs all 34 skills as one bundle)\n'));
|
|
1158
|
+
// Step 1: Register marketplace
|
|
1159
|
+
console.log((0, theme_1.dim)(' $ claude plugin marketplace add tody-agent/codymaster'));
|
|
1169
1160
|
try {
|
|
1170
|
-
// Use 'pipe' so we can inspect output on failure; print stdout ourselves
|
|
1171
1161
|
const r1 = require('child_process').spawnSync('claude', ['plugin', 'marketplace', 'add', 'tody-agent/codymaster'], { encoding: 'utf8' });
|
|
1172
1162
|
if (r1.stdout)
|
|
1173
1163
|
process.stdout.write(r1.stdout);
|
|
@@ -1175,27 +1165,27 @@ function doAddSkills(skills, platform) {
|
|
|
1175
1165
|
process.stderr.write(r1.stderr);
|
|
1176
1166
|
const combined = String(r1.stdout || '') + String(r1.stderr || '');
|
|
1177
1167
|
if (r1.status !== 0 && !combined.includes('already installed') && !combined.includes('already exists')) {
|
|
1178
|
-
console.log(
|
|
1168
|
+
console.log((0, box_1.renderResult)('warning', 'Marketplace warning — continuing anyway'));
|
|
1179
1169
|
}
|
|
1180
1170
|
else if (combined.includes('already installed') || combined.includes('already exists')) {
|
|
1181
|
-
console.log(
|
|
1171
|
+
console.log((0, theme_1.dim)(' ℹ️ Marketplace already registered'));
|
|
1182
1172
|
}
|
|
1183
1173
|
}
|
|
1184
1174
|
catch (_a) {
|
|
1185
|
-
console.log(
|
|
1175
|
+
console.log((0, box_1.renderResult)('warning', 'Could not reach marketplace — continuing'));
|
|
1186
1176
|
}
|
|
1187
1177
|
// Step 2: Install / update the plugin
|
|
1188
|
-
console.log(
|
|
1178
|
+
console.log((0, theme_1.dim)(' $ claude plugin install codymaster@codymaster'));
|
|
1189
1179
|
try {
|
|
1190
1180
|
execFileSync('claude', ['plugin', 'install', 'codymaster@codymaster'], { stdio: 'inherit' });
|
|
1191
|
-
console.log(
|
|
1181
|
+
console.log((0, box_1.renderResult)('success', 'All 34 skills installed!'));
|
|
1192
1182
|
yield postInstallOnboarding('claude');
|
|
1193
1183
|
}
|
|
1194
1184
|
catch (_b) {
|
|
1195
|
-
console.log(
|
|
1196
|
-
console.log(
|
|
1197
|
-
console.log(
|
|
1198
|
-
console.log(
|
|
1185
|
+
console.log((0, box_1.renderResult)('warning', 'Plugin install failed. Run manually:'));
|
|
1186
|
+
console.log((0, theme_1.brand)(' claude plugin install codymaster@codymaster'));
|
|
1187
|
+
console.log((0, theme_1.dim)('\n Or one-liner:'));
|
|
1188
|
+
console.log((0, theme_1.brand)(' bash <(curl -fsSL https://raw.githubusercontent.com/tody-agent/codymaster/main/install.sh) --claude'));
|
|
1199
1189
|
}
|
|
1200
1190
|
return;
|
|
1201
1191
|
}
|
|
@@ -1203,8 +1193,7 @@ function doAddSkills(skills, platform) {
|
|
|
1203
1193
|
// Gemini now falls through to the standard file-cloning logic below.
|
|
1204
1194
|
const target = PLATFORM_TARGETS[platform];
|
|
1205
1195
|
if (!target) {
|
|
1206
|
-
console.log(
|
|
1207
|
-
console.log(chalk_1.default.gray(` Supported: claude, gemini, cursor, windsurf, cline, opencode, kiro, copilot`));
|
|
1196
|
+
console.log((0, box_1.renderResult)('error', `Unknown platform: ${platform}`, [(0, theme_1.dim)('Supported: claude, gemini, cursor, windsurf, cline, opencode, kiro, copilot')]));
|
|
1208
1197
|
return;
|
|
1209
1198
|
}
|
|
1210
1199
|
if (platform === 'copilot') {
|
|
@@ -1216,15 +1205,14 @@ function doAddSkills(skills, platform) {
|
|
|
1216
1205
|
if (!existing.includes('Cody Master Skills')) {
|
|
1217
1206
|
fs_1.default.appendFileSync(instrFile, header + lines + '\n');
|
|
1218
1207
|
}
|
|
1219
|
-
console.log(
|
|
1220
|
-
console.log(chalk_1.default.gray(' GitHub Copilot will use these as context automatically.'));
|
|
1208
|
+
console.log((0, box_1.renderResult)('success', `${skills.length} skills referenced in ${instrFile}`, [(0, theme_1.dim)('GitHub Copilot will use these as context automatically.')]));
|
|
1221
1209
|
return;
|
|
1222
1210
|
}
|
|
1223
1211
|
const icons = { cursor: '🔵', windsurf: '🟠', cline: '⚫', opencode: '📦', kiro: '🔶' };
|
|
1224
1212
|
const icon = icons[platform] || '📦';
|
|
1225
1213
|
const label = skills.length === ALL_SKILLS.length ? 'all 34 skills' : skills.join(', ');
|
|
1226
|
-
console.log(`${icon} ${platform} — Installing ${label}`);
|
|
1227
|
-
console.log(
|
|
1214
|
+
console.log(`${icon} ${(0, theme_1.brand)(`${platform} — Installing ${label}`)}`);
|
|
1215
|
+
console.log((0, theme_1.dim)(` Target: ./${target.dir}/\n`));
|
|
1228
1216
|
let ok = 0, fail = 0;
|
|
1229
1217
|
for (const skill of skills) {
|
|
1230
1218
|
const url = `${RAW_BASE}/skills/${skill}/SKILL.md`;
|
|
@@ -1236,9 +1224,9 @@ function doAddSkills(skills, platform) {
|
|
|
1236
1224
|
else if (platform === 'continue') {
|
|
1237
1225
|
dest = path_1.default.join(target.dir, `${skill}.md`);
|
|
1238
1226
|
}
|
|
1239
|
-
const
|
|
1227
|
+
const ok_result = yield downloadFile(url, dest);
|
|
1240
1228
|
// Prepend Cursor MDC glob formatting
|
|
1241
|
-
if (
|
|
1229
|
+
if (ok_result && platform === 'cursor') {
|
|
1242
1230
|
try {
|
|
1243
1231
|
const content = fs_1.default.readFileSync(dest, 'utf-8');
|
|
1244
1232
|
if (!content.startsWith('---')) {
|
|
@@ -1252,27 +1240,26 @@ function doAddSkills(skills, platform) {
|
|
|
1252
1240
|
}
|
|
1253
1241
|
catch (err) { }
|
|
1254
1242
|
}
|
|
1255
|
-
if (
|
|
1256
|
-
process.stdout.write(
|
|
1243
|
+
if (ok_result) {
|
|
1244
|
+
process.stdout.write((0, theme_1.success)(` ✅ ${skill}\n`));
|
|
1257
1245
|
ok++;
|
|
1258
1246
|
}
|
|
1259
1247
|
else {
|
|
1260
|
-
process.stdout.write(
|
|
1248
|
+
process.stdout.write((0, theme_1.error)(` ❌ ${skill}\n`));
|
|
1261
1249
|
fail++;
|
|
1262
1250
|
}
|
|
1263
1251
|
}
|
|
1264
1252
|
console.log();
|
|
1265
1253
|
if (ok > 0) {
|
|
1266
|
-
console.log(
|
|
1254
|
+
console.log((0, box_1.renderResult)('success', `${ok} skill${ok > 1 ? 's' : ''} installed → ./${target.dir}/`));
|
|
1267
1255
|
const invoke = target.invoke.replace('<skill>', skills[0]);
|
|
1268
|
-
console.log(
|
|
1256
|
+
console.log((0, theme_1.brand)(` 📖 Usage: ${invoke} Your prompt here`));
|
|
1269
1257
|
if (target.note)
|
|
1270
|
-
console.log(
|
|
1258
|
+
console.log((0, theme_1.dim)(` Note: ${target.note}`));
|
|
1271
1259
|
yield postInstallOnboarding(platform);
|
|
1272
1260
|
}
|
|
1273
1261
|
if (fail > 0) {
|
|
1274
|
-
console.log(
|
|
1275
|
-
console.log(chalk_1.default.gray(` git clone https://github.com/tody-agent/codymaster.git`));
|
|
1262
|
+
console.log((0, box_1.renderResult)('warning', `${fail} failed — check connection or clone manually:`, [(0, theme_1.dim)('git clone https://github.com/tody-agent/codymaster.git')]));
|
|
1276
1263
|
}
|
|
1277
1264
|
});
|
|
1278
1265
|
}
|
|
@@ -1296,8 +1283,8 @@ program
|
|
|
1296
1283
|
}
|
|
1297
1284
|
else if (opts.skill) {
|
|
1298
1285
|
if (!ALL_SKILLS.includes(opts.skill)) {
|
|
1299
|
-
console.log(
|
|
1300
|
-
|
|
1286
|
+
console.log((0, box_1.renderResult)('error', `Unknown skill: ${opts.skill}`, [(0, theme_1.dim)('Run: npx codymaster add --list')]));
|
|
1287
|
+
return;
|
|
1301
1288
|
return;
|
|
1302
1289
|
}
|
|
1303
1290
|
skills = [opts.skill];
|
|
@@ -1305,27 +1292,27 @@ program
|
|
|
1305
1292
|
// Detect or prompt platform
|
|
1306
1293
|
let platform = opts.platform || autoDetectPlatform();
|
|
1307
1294
|
if (platform === 'manual') {
|
|
1308
|
-
const
|
|
1309
|
-
const
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
{
|
|
1313
|
-
{
|
|
1314
|
-
{
|
|
1315
|
-
{
|
|
1316
|
-
{
|
|
1317
|
-
{
|
|
1318
|
-
{
|
|
1319
|
-
{
|
|
1320
|
-
{
|
|
1321
|
-
{
|
|
1322
|
-
{
|
|
1323
|
-
{
|
|
1295
|
+
const p = yield Promise.resolve().then(() => __importStar(require('@clack/prompts')));
|
|
1296
|
+
const platform_choice = yield p.select({
|
|
1297
|
+
message: 'Select your AI coding platform:',
|
|
1298
|
+
options: [
|
|
1299
|
+
{ label: '🟣 Claude Code (recommended)', value: 'claude' },
|
|
1300
|
+
{ label: '💻 Gemini CLI & Antigravity', value: 'gemini' },
|
|
1301
|
+
{ label: '🔵 Cursor', value: 'cursor' },
|
|
1302
|
+
{ label: '🟠 Windsurf', value: 'windsurf' },
|
|
1303
|
+
{ label: '⚫ Cline / RooCode', value: 'cline' },
|
|
1304
|
+
{ label: '📦 OpenCode', value: 'opencode' },
|
|
1305
|
+
{ label: '🔶 Kiro (AWS)', value: 'kiro' },
|
|
1306
|
+
{ label: '🐙 GitHub Copilot', value: 'copilot' },
|
|
1307
|
+
{ label: '🤖 Aider', value: 'aider' },
|
|
1308
|
+
{ label: '🔗 Continue.dev', value: 'continue' },
|
|
1309
|
+
{ label: '☁️ Amazon Q', value: 'amazonq' },
|
|
1310
|
+
{ label: '⚡ Amp', value: 'amp' },
|
|
1324
1311
|
],
|
|
1325
1312
|
});
|
|
1326
|
-
if (
|
|
1313
|
+
if (p.isCancel(platform_choice))
|
|
1327
1314
|
return;
|
|
1328
|
-
platform =
|
|
1315
|
+
platform = platform_choice;
|
|
1329
1316
|
}
|
|
1330
1317
|
// If no skills chosen yet, prompt
|
|
1331
1318
|
if (!skills) {
|
|
@@ -1333,25 +1320,27 @@ program
|
|
|
1333
1320
|
skills = ALL_SKILLS;
|
|
1334
1321
|
}
|
|
1335
1322
|
else {
|
|
1336
|
-
const
|
|
1337
|
-
const
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
{
|
|
1341
|
-
{
|
|
1323
|
+
const p = yield Promise.resolve().then(() => __importStar(require('@clack/prompts')));
|
|
1324
|
+
const mode = yield p.select({
|
|
1325
|
+
message: 'What to install?',
|
|
1326
|
+
options: [
|
|
1327
|
+
{ label: 'All 34 skills (full kit)', value: 'all' },
|
|
1328
|
+
{ label: 'Search & pick one skill', value: 'pick' },
|
|
1342
1329
|
],
|
|
1343
1330
|
});
|
|
1344
|
-
if (
|
|
1331
|
+
if (p.isCancel(mode))
|
|
1332
|
+
return;
|
|
1333
|
+
if (mode === 'all') {
|
|
1345
1334
|
skills = ALL_SKILLS;
|
|
1346
1335
|
}
|
|
1347
1336
|
else {
|
|
1348
|
-
const pick = yield
|
|
1349
|
-
|
|
1350
|
-
|
|
1337
|
+
const pick = yield p.select({
|
|
1338
|
+
message: 'Select a skill:',
|
|
1339
|
+
options: ALL_SKILLS.map(s => ({ label: s, value: s })),
|
|
1351
1340
|
});
|
|
1352
|
-
if (
|
|
1341
|
+
if (p.isCancel(pick))
|
|
1353
1342
|
return;
|
|
1354
|
-
skills = [pick
|
|
1343
|
+
skills = [pick];
|
|
1355
1344
|
}
|
|
1356
1345
|
}
|
|
1357
1346
|
}
|
|
@@ -1418,43 +1407,38 @@ program
|
|
|
1418
1407
|
});
|
|
1419
1408
|
function continuityInit(projectPath) {
|
|
1420
1409
|
if ((0, continuity_1.hasCmDir)(projectPath)) {
|
|
1421
|
-
console.log(
|
|
1422
|
-
console.log(chalk_1.default.gray(` Path: ${projectPath}/.cm/`));
|
|
1410
|
+
console.log((0, box_1.renderResult)('warning', '.cm/ directory already exists.', [(0, theme_1.dim)(`Path: ${projectPath}/.cm/`)]));
|
|
1423
1411
|
return;
|
|
1424
1412
|
}
|
|
1425
1413
|
(0, continuity_1.ensureCmDir)(projectPath);
|
|
1426
|
-
console.log(
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
console.log(
|
|
1414
|
+
console.log((0, box_1.renderResult)('success', 'Working memory initialized!', [
|
|
1415
|
+
(0, theme_1.dim)(`Created: ${projectPath}/.cm/`),
|
|
1416
|
+
(0, theme_1.dim)('├── CONTINUITY.md (working memory)'),
|
|
1417
|
+
(0, theme_1.dim)('├── config.yaml (RARV settings)'),
|
|
1418
|
+
(0, theme_1.dim)('└── memory/'),
|
|
1419
|
+
(0, theme_1.dim)(' ├── learnings.json (error patterns)'),
|
|
1420
|
+
(0, theme_1.dim)(' └── decisions.json (architecture decisions)'),
|
|
1421
|
+
]));
|
|
1422
|
+
console.log((0, theme_1.info)('💡 Protocol: Read CONTINUITY.md at session start, update at session end.'));
|
|
1435
1423
|
}
|
|
1436
1424
|
function continuityStatus(projectPath) {
|
|
1437
1425
|
const status = (0, continuity_1.getContinuityStatus)(projectPath);
|
|
1438
1426
|
if (!status.initialized) {
|
|
1439
|
-
console.log(
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
console.log(
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
}
|
|
1453
|
-
console.log();
|
|
1454
|
-
console.log(chalk_1.default.gray(` ✅ Completed: ${status.completedCount} | 🚧 Blockers: ${status.blockerCount}`));
|
|
1455
|
-
console.log(chalk_1.default.gray(` 📚 Learnings: ${status.learningCount} | 📋 Decisions: ${status.decisionCount}`));
|
|
1427
|
+
console.log((0, box_1.renderResult)('warning', 'Working memory not initialized.', [(0, theme_1.dim)('Run: cm continuity init')]));
|
|
1428
|
+
return;
|
|
1429
|
+
}
|
|
1430
|
+
console.log((0, box_1.renderCommandHeader)('Working Memory Status', '🧠'));
|
|
1431
|
+
console.log((0, box_1.renderKeyValue)([
|
|
1432
|
+
['Project', String(status.project)],
|
|
1433
|
+
['Phase', phaseColor(status.phase)(status.phase)],
|
|
1434
|
+
['Iteration', String(status.iteration)],
|
|
1435
|
+
...(status.activeGoal ? [['Goal', String(status.activeGoal)]] : []),
|
|
1436
|
+
...(status.currentTask ? [['Task', String(status.currentTask)]] : []),
|
|
1437
|
+
]));
|
|
1438
|
+
console.log((0, theme_1.dim)(` ✅ Completed: ${status.completedCount} | 🚧 Blockers: ${status.blockerCount}`));
|
|
1439
|
+
console.log((0, theme_1.dim)(` 📚 Learnings: ${status.learningCount} | 📋 Decisions: ${status.decisionCount}`));
|
|
1456
1440
|
if (status.lastUpdated) {
|
|
1457
|
-
console.log(
|
|
1441
|
+
console.log((0, theme_1.dim)(` 🕐 Updated: ${formatTimeAgoCli(status.lastUpdated)}`));
|
|
1458
1442
|
}
|
|
1459
1443
|
console.log();
|
|
1460
1444
|
}
|
|
@@ -1467,46 +1451,45 @@ function phaseColor(phase) {
|
|
|
1467
1451
|
}
|
|
1468
1452
|
function continuityReset(projectPath) {
|
|
1469
1453
|
if (!(0, continuity_1.hasCmDir)(projectPath)) {
|
|
1470
|
-
console.log(
|
|
1454
|
+
console.log((0, box_1.renderResult)('warning', 'No .cm/ directory found.'));
|
|
1471
1455
|
return;
|
|
1472
1456
|
}
|
|
1473
1457
|
(0, continuity_1.resetContinuity)(projectPath);
|
|
1474
|
-
console.log(
|
|
1475
|
-
console.log(chalk_1.default.gray(' CONTINUITY.md cleared. Learnings preserved.'));
|
|
1458
|
+
console.log((0, box_1.renderResult)('success', 'Working memory reset.', [(0, theme_1.dim)('CONTINUITY.md cleared. Learnings preserved.')]));
|
|
1476
1459
|
}
|
|
1477
1460
|
function continuityLearnings(projectPath) {
|
|
1478
1461
|
if (!(0, continuity_1.hasCmDir)(projectPath)) {
|
|
1479
|
-
console.log(
|
|
1462
|
+
console.log((0, box_1.renderResult)('warning', 'No .cm/ directory found. Run: cm continuity init'));
|
|
1480
1463
|
return;
|
|
1481
1464
|
}
|
|
1482
1465
|
const learnings = (0, continuity_1.getLearnings)(projectPath);
|
|
1483
1466
|
if (learnings.length === 0) {
|
|
1484
|
-
console.log(
|
|
1467
|
+
console.log(`\n ${(0, theme_1.dim)('No learnings captured yet. 🎉')}\n`);
|
|
1485
1468
|
return;
|
|
1486
1469
|
}
|
|
1487
|
-
console.log(
|
|
1470
|
+
console.log((0, box_1.renderCommandHeader)(`Mistakes & Learnings (${learnings.length})`, '📚'));
|
|
1488
1471
|
for (const l of learnings.slice(-10)) {
|
|
1489
|
-
console.log(
|
|
1490
|
-
console.log(
|
|
1491
|
-
console.log(
|
|
1492
|
-
console.log(
|
|
1472
|
+
console.log((0, theme_1.error)(` ❌ ${l.whatFailed}`));
|
|
1473
|
+
console.log((0, theme_1.dim)(` Why: ${l.whyFailed}`));
|
|
1474
|
+
console.log((0, theme_1.success)(` Fix: ${l.howToPrevent}`));
|
|
1475
|
+
console.log((0, theme_1.dim)(` ${formatTimeAgoCli(l.timestamp)} | ${l.agent || 'unknown'}\n`));
|
|
1493
1476
|
}
|
|
1494
1477
|
}
|
|
1495
1478
|
function continuityDecisions(projectPath) {
|
|
1496
1479
|
if (!(0, continuity_1.hasCmDir)(projectPath)) {
|
|
1497
|
-
console.log(
|
|
1480
|
+
console.log((0, box_1.renderResult)('warning', 'No .cm/ directory found. Run: cm continuity init'));
|
|
1498
1481
|
return;
|
|
1499
1482
|
}
|
|
1500
1483
|
const decisions = (0, continuity_1.getDecisions)(projectPath);
|
|
1501
1484
|
if (decisions.length === 0) {
|
|
1502
|
-
console.log(
|
|
1485
|
+
console.log(`\n ${(0, theme_1.dim)('No decisions recorded yet.')}\n`);
|
|
1503
1486
|
return;
|
|
1504
1487
|
}
|
|
1505
|
-
console.log(
|
|
1488
|
+
console.log((0, box_1.renderCommandHeader)(`Key Decisions (${decisions.length})`, '📋'));
|
|
1506
1489
|
for (const d of decisions.slice(-10)) {
|
|
1507
|
-
console.log(
|
|
1508
|
-
console.log(
|
|
1509
|
-
console.log(
|
|
1490
|
+
console.log((0, theme_1.brand)(` 📌 ${d.decision}`));
|
|
1491
|
+
console.log((0, theme_1.dim)(` Rationale: ${d.rationale}`));
|
|
1492
|
+
console.log((0, theme_1.dim)(` ${formatTimeAgoCli(d.timestamp)} | ${d.agent || 'unknown'}\n`));
|
|
1510
1493
|
}
|
|
1511
1494
|
}
|
|
1512
1495
|
// ─── Brain Command (Enhanced Memory Explorer) ────────────────────────────────
|
|
@@ -1549,13 +1532,11 @@ program
|
|
|
1549
1532
|
brainExport(projectPath, opts);
|
|
1550
1533
|
break;
|
|
1551
1534
|
default:
|
|
1552
|
-
// Try as delete: cm brain learning <id> or cm brain decision <id>
|
|
1553
1535
|
if (cmd === 'learning' || cmd === 'decision') {
|
|
1554
|
-
console.log(
|
|
1536
|
+
console.log((0, theme_1.dim)(`Did you mean: cm brain ${cmd}s ?`));
|
|
1555
1537
|
}
|
|
1556
1538
|
else {
|
|
1557
|
-
console.log(
|
|
1558
|
-
console.log(chalk_1.default.gray('Available: status, learnings, decisions, delete, stats, export'));
|
|
1539
|
+
console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: status, learnings, decisions, delete, stats, export')]));
|
|
1559
1540
|
}
|
|
1560
1541
|
}
|
|
1561
1542
|
});
|
|
@@ -1570,40 +1551,38 @@ program
|
|
|
1570
1551
|
function brainStatus(projectPath) {
|
|
1571
1552
|
const status = (0, continuity_1.getContinuityStatus)(projectPath);
|
|
1572
1553
|
if (!status.initialized) {
|
|
1573
|
-
console.log(
|
|
1574
|
-
console.log(chalk_1.default.gray(' Run: cm continuity init'));
|
|
1554
|
+
console.log((0, box_1.renderResult)('warning', 'Working memory not initialized.', [(0, theme_1.dim)('Run: cm continuity init')]));
|
|
1575
1555
|
return;
|
|
1576
1556
|
}
|
|
1577
1557
|
showBanner();
|
|
1578
|
-
console.log(
|
|
1558
|
+
console.log((0, box_1.renderCommandHeader)('Brain — Memory Status', '🧠'));
|
|
1579
1559
|
// Stats row
|
|
1580
|
-
console.log(
|
|
1581
|
-
console.log(
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
console.log(
|
|
1560
|
+
console.log((0, theme_1.brand)(' ┌──────────────┬──────────────┬──────────────┬──────────────┐'));
|
|
1561
|
+
console.log((0, theme_1.brand)(' │') + (0, theme_1.error)(` ❤ Learn: ${padRight(String(status.learningCount), 4)}`) +
|
|
1562
|
+
(0, theme_1.brand)(' │') + (0, theme_1.brand)(` 📋 Decide: ${padRight(String(status.decisionCount), 3)}`) +
|
|
1563
|
+
(0, theme_1.brand)(' │') + phaseColor(status.phase)(` ● ${padRight(status.phase, 9)}`) +
|
|
1564
|
+
(0, theme_1.brand)(' │') + (0, theme_1.dim)(` #${padRight(String(status.iteration), 10)}`) + (0, theme_1.brand)('│'));
|
|
1565
|
+
console.log((0, theme_1.brand)(' └──────────────┴──────────────┴──────────────┴──────────────┘'));
|
|
1586
1566
|
console.log();
|
|
1587
|
-
console.log(
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
console.log(` ${chalk_1.default.white('Updated:')} ${formatTimeAgoCli(status.lastUpdated)}`);
|
|
1567
|
+
console.log((0, box_1.renderKeyValue)([
|
|
1568
|
+
['Project', String(status.project)],
|
|
1569
|
+
...(status.activeGoal ? [['Goal', String(status.activeGoal)]] : []),
|
|
1570
|
+
...(status.currentTask ? [['Task', String(status.currentTask)]] : []),
|
|
1571
|
+
['Completed', `${status.completedCount} items`],
|
|
1572
|
+
['Blockers', status.blockerCount > 0 ? (0, theme_1.warning)(`🚧 ${status.blockerCount}`) : (0, theme_1.success)('✅ None')],
|
|
1573
|
+
...(status.lastUpdated ? [['Updated', formatTimeAgoCli(status.lastUpdated)]] : []),
|
|
1574
|
+
]));
|
|
1596
1575
|
console.log();
|
|
1597
|
-
console.log(
|
|
1598
|
-
console.log(
|
|
1599
|
-
console.log(
|
|
1600
|
-
console.log(
|
|
1601
|
-
console.log(
|
|
1576
|
+
console.log((0, theme_1.dim)(' Commands:'));
|
|
1577
|
+
console.log((0, theme_1.dim)(' cm brain learnings — View mistakes & lessons'));
|
|
1578
|
+
console.log((0, theme_1.dim)(' cm brain decisions — View architecture decisions'));
|
|
1579
|
+
console.log((0, theme_1.dim)(' cm brain stats — Memory statistics'));
|
|
1580
|
+
console.log((0, theme_1.dim)(' cm brain export — Export memory data'));
|
|
1602
1581
|
console.log();
|
|
1603
1582
|
}
|
|
1604
1583
|
function brainLearnings(projectPath, opts) {
|
|
1605
1584
|
if (!(0, continuity_1.hasCmDir)(projectPath)) {
|
|
1606
|
-
console.log(
|
|
1585
|
+
console.log((0, box_1.renderResult)('warning', 'No .cm/ directory found. Run: cm continuity init'));
|
|
1607
1586
|
return;
|
|
1608
1587
|
}
|
|
1609
1588
|
let learnings = (0, continuity_1.getLearnings)(projectPath);
|
|
@@ -1618,95 +1597,96 @@ function brainLearnings(projectPath, opts) {
|
|
|
1618
1597
|
const limit = opts.last ? parseInt(opts.last) : 15;
|
|
1619
1598
|
const display = learnings.slice(-limit);
|
|
1620
1599
|
if (display.length === 0) {
|
|
1621
|
-
console.log(
|
|
1600
|
+
console.log(`\n ${(0, theme_1.dim)(`No learnings ${opts.search ? 'matching "' + opts.search + '"' : 'captured yet'}. 🎉`)}\n`);
|
|
1622
1601
|
return;
|
|
1623
1602
|
}
|
|
1624
|
-
console.log(
|
|
1603
|
+
console.log((0, box_1.renderCommandHeader)(`Learnings (${display.length}${learnings.length > limit ? '/' + learnings.length : ''})`, '📚'));
|
|
1625
1604
|
for (const l of display) {
|
|
1626
1605
|
const shortId = l.id ? l.id.substring(0, 8) : '???';
|
|
1627
|
-
console.log(
|
|
1606
|
+
console.log((0, theme_1.error)(` ❌ ${l.whatFailed}`) + (0, theme_1.dim)(` [${shortId}]`));
|
|
1628
1607
|
if (l.whyFailed)
|
|
1629
|
-
console.log(
|
|
1608
|
+
console.log((0, theme_1.dim)(` Why: ${l.whyFailed}`));
|
|
1630
1609
|
if (l.howToPrevent)
|
|
1631
|
-
console.log(
|
|
1632
|
-
console.log(
|
|
1610
|
+
console.log((0, theme_1.success)(` Fix: ${l.howToPrevent}`));
|
|
1611
|
+
console.log((0, theme_1.dim)(` ${formatTimeAgoCli(l.timestamp)} | ${l.agent || 'unknown'}${l.module ? ' | 📦 ' + l.module : ''}\n`));
|
|
1633
1612
|
}
|
|
1634
1613
|
}
|
|
1635
1614
|
function brainDecisions(projectPath, opts) {
|
|
1636
1615
|
if (!(0, continuity_1.hasCmDir)(projectPath)) {
|
|
1637
|
-
console.log(
|
|
1616
|
+
console.log((0, box_1.renderResult)('warning', 'No .cm/ directory found. Run: cm continuity init'));
|
|
1638
1617
|
return;
|
|
1639
1618
|
}
|
|
1640
1619
|
const decisions = (0, continuity_1.getDecisions)(projectPath);
|
|
1641
1620
|
const limit = opts.last ? parseInt(opts.last) : 15;
|
|
1642
1621
|
const display = decisions.slice(-limit);
|
|
1643
1622
|
if (display.length === 0) {
|
|
1644
|
-
console.log(
|
|
1623
|
+
console.log(`\n ${(0, theme_1.dim)('No decisions recorded yet.')}\n`);
|
|
1645
1624
|
return;
|
|
1646
1625
|
}
|
|
1647
|
-
console.log(
|
|
1626
|
+
console.log((0, box_1.renderCommandHeader)(`Key Decisions (${display.length}${decisions.length > limit ? '/' + decisions.length : ''})`, '📋'));
|
|
1648
1627
|
for (const d of display) {
|
|
1649
1628
|
const shortId = d.id ? d.id.substring(0, 8) : '???';
|
|
1650
|
-
console.log(
|
|
1629
|
+
console.log((0, theme_1.brand)(` 📌 ${d.decision}`) + (0, theme_1.dim)(` [${shortId}]`));
|
|
1651
1630
|
if (d.rationale)
|
|
1652
|
-
console.log(
|
|
1653
|
-
console.log(
|
|
1631
|
+
console.log((0, theme_1.dim)(` Rationale: ${d.rationale}`));
|
|
1632
|
+
console.log((0, theme_1.dim)(` ${formatTimeAgoCli(d.timestamp)} | ${d.agent || 'unknown'}\n`));
|
|
1654
1633
|
}
|
|
1655
1634
|
}
|
|
1656
1635
|
function brainDelete(projectPath, type, id) {
|
|
1657
1636
|
if (!(0, continuity_1.hasCmDir)(projectPath)) {
|
|
1658
|
-
console.log(
|
|
1637
|
+
console.log((0, box_1.renderResult)('warning', 'No .cm/ directory found.'));
|
|
1659
1638
|
return;
|
|
1660
1639
|
}
|
|
1661
1640
|
if (type === 'learning' || type === 'l') {
|
|
1662
1641
|
const learnings = (0, continuity_1.getLearnings)(projectPath);
|
|
1663
1642
|
const target = learnings.find(l => l.id && l.id.startsWith(id));
|
|
1664
1643
|
if (!target) {
|
|
1665
|
-
console.log(
|
|
1644
|
+
console.log((0, box_1.renderResult)('error', `Learning not found with ID prefix: ${id}`));
|
|
1666
1645
|
return;
|
|
1667
1646
|
}
|
|
1668
|
-
const
|
|
1669
|
-
if (
|
|
1670
|
-
console.log(
|
|
1647
|
+
const del_success = (0, continuity_1.deleteLearning)(projectPath, target.id);
|
|
1648
|
+
if (del_success) {
|
|
1649
|
+
console.log((0, box_1.renderResult)('success', `Deleted learning: ${target.whatFailed}`));
|
|
1671
1650
|
}
|
|
1672
1651
|
else {
|
|
1673
|
-
console.log(
|
|
1652
|
+
console.log((0, box_1.renderResult)('error', 'Failed to delete'));
|
|
1674
1653
|
}
|
|
1675
1654
|
}
|
|
1676
1655
|
else if (type === 'decision' || type === 'd') {
|
|
1677
1656
|
const decisions = (0, continuity_1.getDecisions)(projectPath);
|
|
1678
1657
|
const target = decisions.find(d => d.id && d.id.startsWith(id));
|
|
1679
1658
|
if (!target) {
|
|
1680
|
-
console.log(
|
|
1659
|
+
console.log((0, box_1.renderResult)('error', `Decision not found with ID prefix: ${id}`));
|
|
1681
1660
|
return;
|
|
1682
1661
|
}
|
|
1683
|
-
const
|
|
1684
|
-
if (
|
|
1685
|
-
console.log(
|
|
1662
|
+
const del_success = (0, continuity_1.deleteDecision)(projectPath, target.id);
|
|
1663
|
+
if (del_success) {
|
|
1664
|
+
console.log((0, box_1.renderResult)('success', `Deleted decision: ${target.decision}`));
|
|
1686
1665
|
}
|
|
1687
1666
|
else {
|
|
1688
|
-
console.log(
|
|
1667
|
+
console.log((0, box_1.renderResult)('error', 'Failed to delete'));
|
|
1689
1668
|
}
|
|
1690
1669
|
}
|
|
1691
1670
|
else {
|
|
1692
|
-
console.log(
|
|
1693
|
-
console.log(chalk_1.default.gray(' Use: cm brain-delete learning <id> | cm brain-delete decision <id>'));
|
|
1671
|
+
console.log((0, box_1.renderResult)('error', `Unknown type: ${type}`, [(0, theme_1.dim)('Use: cm brain-delete learning <id> | cm brain-delete decision <id>')]));
|
|
1694
1672
|
}
|
|
1695
1673
|
}
|
|
1696
1674
|
function brainStats(projectPath) {
|
|
1697
1675
|
if (!(0, continuity_1.hasCmDir)(projectPath)) {
|
|
1698
|
-
console.log(
|
|
1676
|
+
console.log((0, box_1.renderResult)('warning', 'No .cm/ directory found. Run: cm continuity init'));
|
|
1699
1677
|
return;
|
|
1700
1678
|
}
|
|
1701
1679
|
const status = (0, continuity_1.getContinuityStatus)(projectPath);
|
|
1702
1680
|
const learnings = (0, continuity_1.getLearnings)(projectPath);
|
|
1703
1681
|
const decisions = (0, continuity_1.getDecisions)(projectPath);
|
|
1704
|
-
console.log(
|
|
1705
|
-
console.log(
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1682
|
+
console.log((0, box_1.renderCommandHeader)('Brain Statistics', '📊'));
|
|
1683
|
+
console.log((0, box_1.renderKeyValue)([
|
|
1684
|
+
['Learnings', String(learnings.length)],
|
|
1685
|
+
['Decisions', String(decisions.length)],
|
|
1686
|
+
['Completed', `${status.completedCount} items`],
|
|
1687
|
+
['Blockers', String(status.blockerCount)],
|
|
1688
|
+
['Iteration', `#${status.iteration}`],
|
|
1689
|
+
]));
|
|
1710
1690
|
// Agent breakdown
|
|
1711
1691
|
const agentMap = {};
|
|
1712
1692
|
learnings.forEach(l => { if (l.agent)
|
|
@@ -1716,9 +1696,9 @@ function brainStats(projectPath) {
|
|
|
1716
1696
|
const agents = Object.entries(agentMap).sort((a, b) => b[1] - a[1]);
|
|
1717
1697
|
if (agents.length > 0) {
|
|
1718
1698
|
console.log();
|
|
1719
|
-
console.log(
|
|
1699
|
+
console.log((0, theme_1.brand)(' Agents:'));
|
|
1720
1700
|
for (const [agent, count] of agents) {
|
|
1721
|
-
console.log(
|
|
1701
|
+
console.log((0, theme_1.dim)(` 🤖 ${padRight(agent, 20)} ${count} entries`));
|
|
1722
1702
|
}
|
|
1723
1703
|
}
|
|
1724
1704
|
// Module breakdown
|
|
@@ -1728,23 +1708,23 @@ function brainStats(projectPath) {
|
|
|
1728
1708
|
const modules = Object.entries(moduleMap).sort((a, b) => b[1] - a[1]);
|
|
1729
1709
|
if (modules.length > 0) {
|
|
1730
1710
|
console.log();
|
|
1731
|
-
console.log(
|
|
1711
|
+
console.log((0, theme_1.brand)(' Modules (most error-prone):'));
|
|
1732
1712
|
for (const [mod, count] of modules.slice(0, 5)) {
|
|
1733
|
-
console.log(
|
|
1713
|
+
console.log((0, theme_1.dim)(` 📦 ${padRight(mod, 20)} ${count} learnings`));
|
|
1734
1714
|
}
|
|
1735
1715
|
}
|
|
1736
1716
|
// Time range
|
|
1737
1717
|
const allTimestamps = [...learnings.map(l => l.timestamp), ...decisions.map(d => d.timestamp)].filter(Boolean).sort();
|
|
1738
1718
|
if (allTimestamps.length > 0) {
|
|
1739
1719
|
console.log();
|
|
1740
|
-
console.log(
|
|
1741
|
-
console.log(
|
|
1720
|
+
console.log((0, theme_1.dim)(` First entry: ${formatTimeAgoCli(allTimestamps[0])}`));
|
|
1721
|
+
console.log((0, theme_1.dim)(` Latest: ${formatTimeAgoCli(allTimestamps[allTimestamps.length - 1])}`));
|
|
1742
1722
|
}
|
|
1743
1723
|
console.log();
|
|
1744
1724
|
}
|
|
1745
1725
|
function brainExport(projectPath, opts) {
|
|
1746
1726
|
if (!(0, continuity_1.hasCmDir)(projectPath)) {
|
|
1747
|
-
console.log(
|
|
1727
|
+
console.log((0, box_1.renderResult)('warning', 'No .cm/ directory found.'));
|
|
1748
1728
|
return;
|
|
1749
1729
|
}
|
|
1750
1730
|
const learnings = (0, continuity_1.getLearnings)(projectPath);
|
|
@@ -1755,8 +1735,7 @@ function brainExport(projectPath, opts) {
|
|
|
1755
1735
|
const data = { status, learnings, decisions, exportedAt: new Date().toISOString() };
|
|
1756
1736
|
const outFile = `brain-export-${new Date().toISOString().slice(0, 10)}.json`;
|
|
1757
1737
|
fs_1.default.writeFileSync(outFile, JSON.stringify(data, null, 2));
|
|
1758
|
-
console.log(
|
|
1759
|
-
console.log(chalk_1.default.gray(` ${learnings.length} learnings, ${decisions.length} decisions`));
|
|
1738
|
+
console.log((0, box_1.renderResult)('success', `Exported to ${outFile}`, [(0, theme_1.dim)(`${learnings.length} learnings, ${decisions.length} decisions`)]));
|
|
1760
1739
|
}
|
|
1761
1740
|
else if (format === 'md') {
|
|
1762
1741
|
let md = `# Brain Export\n\n**Project:** ${status.project || 'Unknown'}\n**Exported:** ${new Date().toISOString()}\n\n`;
|
|
@@ -1770,12 +1749,10 @@ function brainExport(projectPath, opts) {
|
|
|
1770
1749
|
}
|
|
1771
1750
|
const outFile = `brain-export-${new Date().toISOString().slice(0, 10)}.md`;
|
|
1772
1751
|
fs_1.default.writeFileSync(outFile, md);
|
|
1773
|
-
console.log(
|
|
1774
|
-
console.log(chalk_1.default.gray(` ${learnings.length} learnings, ${decisions.length} decisions`));
|
|
1752
|
+
console.log((0, box_1.renderResult)('success', `Exported to ${outFile}`, [(0, theme_1.dim)(`${learnings.length} learnings, ${decisions.length} decisions`)]));
|
|
1775
1753
|
}
|
|
1776
1754
|
else {
|
|
1777
|
-
console.log(
|
|
1778
|
-
console.log(chalk_1.default.gray(' Use: --format json | --format md'));
|
|
1755
|
+
console.log((0, box_1.renderResult)('error', `Unknown format: ${format}`, [(0, theme_1.dim)('Use: --format json | --format md')]));
|
|
1779
1756
|
}
|
|
1780
1757
|
}
|
|
1781
1758
|
// ─── Skill Command ──────────────────────────────────────────────────────────
|
|
@@ -1857,7 +1834,7 @@ program
|
|
|
1857
1834
|
break;
|
|
1858
1835
|
case 'info':
|
|
1859
1836
|
if (!name) {
|
|
1860
|
-
console.log(
|
|
1837
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm skill info <skill-name>'));
|
|
1861
1838
|
return;
|
|
1862
1839
|
}
|
|
1863
1840
|
skillInfo(name);
|
|
@@ -1875,52 +1852,51 @@ function skillList(filterDomain) {
|
|
|
1875
1852
|
? Object.entries(SKILL_CATALOG).filter(([d]) => d.toLowerCase().startsWith(filterDomain.toLowerCase()))
|
|
1876
1853
|
: Object.entries(SKILL_CATALOG);
|
|
1877
1854
|
if (entries.length === 0) {
|
|
1878
|
-
console.log(
|
|
1879
|
-
console.log(chalk_1.default.gray(' Domains: engineering, operations, product, growth, orchestration, workflow'));
|
|
1855
|
+
console.log((0, box_1.renderResult)('error', `Domain not found: ${filterDomain}`, [(0, theme_1.dim)('Domains: engineering, operations, product, growth, orchestration, workflow')]));
|
|
1880
1856
|
return;
|
|
1881
1857
|
}
|
|
1882
|
-
console.log(
|
|
1858
|
+
console.log((0, box_1.renderCommandHeader)('Cody Master — 34 Skills', '🧩'));
|
|
1883
1859
|
let total = 0;
|
|
1884
1860
|
for (const [domain, data] of entries) {
|
|
1885
|
-
console.log(
|
|
1861
|
+
console.log((0, theme_1.brand)(` ${data.icon} ${domain.charAt(0).toUpperCase() + domain.slice(1)}`));
|
|
1886
1862
|
for (const skill of data.skills) {
|
|
1887
|
-
console.log(` ${
|
|
1863
|
+
console.log(` ${(0, theme_1.brand)(padRight(skill.name, 26))} ${(0, theme_1.dim)(skill.desc)}`);
|
|
1888
1864
|
total++;
|
|
1889
1865
|
}
|
|
1890
1866
|
console.log();
|
|
1891
1867
|
}
|
|
1892
|
-
console.log(
|
|
1893
|
-
console.log(
|
|
1894
|
-
console.log(
|
|
1868
|
+
console.log((0, theme_1.dim)(` ${total} skills across ${entries.length} domains`));
|
|
1869
|
+
console.log((0, theme_1.dim)(` Install: npx codymaster add --all`));
|
|
1870
|
+
console.log((0, theme_1.dim)(` Add one: npx codymaster add --skill <name>\n`));
|
|
1895
1871
|
}
|
|
1896
1872
|
function skillInfo(name) {
|
|
1897
1873
|
for (const [domain, data] of Object.entries(SKILL_CATALOG)) {
|
|
1898
1874
|
const skill = data.skills.find(s => s.name === name);
|
|
1899
1875
|
if (skill) {
|
|
1900
|
-
console.log(
|
|
1901
|
-
console.log(` ${chalk_1.default.white('Domain:')} ${domain}`);
|
|
1902
|
-
console.log(` ${chalk_1.default.white('Description:')} ${skill.desc}`);
|
|
1876
|
+
console.log((0, box_1.renderCommandHeader)(`Skill: ${skill.name}`, '🧩'));
|
|
1903
1877
|
const agents = (0, judge_1.suggestAgentsForSkill)(skill.name);
|
|
1904
|
-
console.log(
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1878
|
+
console.log((0, box_1.renderKeyValue)([
|
|
1879
|
+
['Domain', domain],
|
|
1880
|
+
['Description', skill.desc],
|
|
1881
|
+
['Best Agents', agents.join(', ')],
|
|
1882
|
+
['Invoke', `@[/${skill.name}] (Antigravity/Gemini)`],
|
|
1883
|
+
['', `/${skill.name} (Claude Code)`],
|
|
1884
|
+
['', `@${skill.name} (Cursor/Windsurf/Cline)`],
|
|
1885
|
+
]));
|
|
1908
1886
|
console.log();
|
|
1909
1887
|
return;
|
|
1910
1888
|
}
|
|
1911
1889
|
}
|
|
1912
|
-
console.log(
|
|
1913
|
-
console.log(chalk_1.default.gray(' Use "cm skill list" to see all available skills.'));
|
|
1890
|
+
console.log((0, box_1.renderResult)('error', `Skill not found: ${name}`, [(0, theme_1.dim)('Use "cm skill list" to see all available skills.')]));
|
|
1914
1891
|
}
|
|
1915
1892
|
function skillDomains() {
|
|
1916
|
-
console.log(
|
|
1893
|
+
console.log((0, box_1.renderCommandHeader)('Skill Domains', '🎯'));
|
|
1917
1894
|
let total = 0;
|
|
1918
1895
|
for (const [domain, data] of Object.entries(SKILL_CATALOG)) {
|
|
1919
|
-
console.log(` ${data.icon} ${
|
|
1896
|
+
console.log(` ${data.icon} ${(0, theme_1.brand)(padRight(domain.charAt(0).toUpperCase() + domain.slice(1), 16))} ${(0, theme_1.dim)(`${data.skills.length} skills`)}`);
|
|
1920
1897
|
total += data.skills.length;
|
|
1921
1898
|
}
|
|
1922
|
-
console.log(
|
|
1923
|
-
console.log();
|
|
1899
|
+
console.log((0, theme_1.dim)(`\n Total: ${total} skills across ${Object.keys(SKILL_CATALOG).length} domains\n`));
|
|
1924
1900
|
}
|
|
1925
1901
|
// ─── Judge Command ──────────────────────────────────────────────────────────
|
|
1926
1902
|
program
|
|
@@ -1934,7 +1910,7 @@ program
|
|
|
1934
1910
|
// Single task evaluation
|
|
1935
1911
|
const task = (0, data_1.findTaskByIdPrefix)(data, taskId);
|
|
1936
1912
|
if (!task) {
|
|
1937
|
-
console.log(
|
|
1913
|
+
console.log((0, box_1.renderResult)('error', `Task not found: ${taskId}`));
|
|
1938
1914
|
return;
|
|
1939
1915
|
}
|
|
1940
1916
|
const project = data.projects.find(p => p.id === task.projectId);
|
|
@@ -1943,15 +1919,17 @@ program
|
|
|
1943
1919
|
learnings = (0, continuity_1.getLearnings)(project.path);
|
|
1944
1920
|
}
|
|
1945
1921
|
const decision = (0, judge_1.evaluateTaskState)(task, data.tasks, learnings);
|
|
1946
|
-
console.log(
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1922
|
+
console.log((0, box_1.renderCommandHeader)('Judge Decision', '🤖'));
|
|
1923
|
+
const details = [
|
|
1924
|
+
['Task', task.title],
|
|
1925
|
+
['Column', task.column],
|
|
1926
|
+
['Action', `${decision.badge} ${decision.action}`],
|
|
1927
|
+
['Reason', decision.reason],
|
|
1928
|
+
['Confidence', `${Math.round(decision.confidence * 100)}%`],
|
|
1929
|
+
];
|
|
1930
|
+
if (decision.suggestedNextSkill)
|
|
1931
|
+
details.push(['Suggested', decision.suggestedNextSkill]);
|
|
1932
|
+
console.log((0, box_1.renderKeyValue)(details));
|
|
1955
1933
|
console.log();
|
|
1956
1934
|
}
|
|
1957
1935
|
else {
|
|
@@ -1960,7 +1938,7 @@ program
|
|
|
1960
1938
|
if (opts.project) {
|
|
1961
1939
|
const project = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
1962
1940
|
if (!project) {
|
|
1963
|
-
console.log(
|
|
1941
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
1964
1942
|
return;
|
|
1965
1943
|
}
|
|
1966
1944
|
tasks = tasks.filter(t => t.projectId === project.id);
|
|
@@ -1973,19 +1951,19 @@ program
|
|
|
1973
1951
|
}
|
|
1974
1952
|
const decisions = (0, judge_1.evaluateAllTasks)(tasks, allLearnings);
|
|
1975
1953
|
if (decisions.size === 0) {
|
|
1976
|
-
console.log(
|
|
1954
|
+
console.log(`\n ${(0, theme_1.dim)('No active tasks to evaluate.')}\n`);
|
|
1977
1955
|
return;
|
|
1978
1956
|
}
|
|
1979
|
-
console.log(
|
|
1980
|
-
console.log(
|
|
1981
|
-
console.log(
|
|
1957
|
+
console.log((0, box_1.renderCommandHeader)(`Judge Decisions (${decisions.size} active tasks)`, '🤖'));
|
|
1958
|
+
console.log((0, theme_1.dim)(' ' + padRight('Badge', 8) + padRight('Action', 12) + padRight('Confidence', 12) + 'Task'));
|
|
1959
|
+
console.log((0, theme_1.dim)(' ' + '─'.repeat(70)));
|
|
1982
1960
|
for (const [tid, dec] of decisions) {
|
|
1983
1961
|
const task = tasks.find(t => t.id === tid);
|
|
1984
|
-
const actionColor = dec.action === 'CONTINUE' ?
|
|
1985
|
-
: dec.action === 'COMPLETE' ?
|
|
1986
|
-
: dec.action === 'ESCALATE' ?
|
|
1987
|
-
:
|
|
1988
|
-
console.log(' ' + padRight(dec.badge, 8) + actionColor(padRight(dec.action, 12)) +
|
|
1962
|
+
const actionColor = dec.action === 'CONTINUE' ? theme_1.success
|
|
1963
|
+
: dec.action === 'COMPLETE' ? theme_1.brand
|
|
1964
|
+
: dec.action === 'ESCALATE' ? theme_1.warning
|
|
1965
|
+
: theme_1.brand;
|
|
1966
|
+
console.log(' ' + padRight(dec.badge, 8) + actionColor(padRight(dec.action, 12)) + (0, theme_1.dim)(padRight(`${Math.round(dec.confidence * 100)}%`, 12)) + ((task === null || task === void 0 ? void 0 : task.title) || tid.substring(0, 8)));
|
|
1989
1967
|
}
|
|
1990
1968
|
console.log();
|
|
1991
1969
|
}
|
|
@@ -2003,8 +1981,7 @@ program
|
|
|
2003
1981
|
// Check if already exists
|
|
2004
1982
|
const existing = data.projects.find(p => p.path === projectPath || p.name === projectName);
|
|
2005
1983
|
if (existing) {
|
|
2006
|
-
console.log(
|
|
2007
|
-
console.log(chalk_1.default.gray(` ID: ${(0, data_1.shortId)(existing.id)} | Path: ${existing.path}`));
|
|
1984
|
+
console.log((0, box_1.renderResult)('warning', `Project already exists: ${existing.name}`, [(0, theme_1.dim)(`ID: ${(0, data_1.shortId)(existing.id)} | Path: ${existing.path}`)]));
|
|
2008
1985
|
return;
|
|
2009
1986
|
}
|
|
2010
1987
|
const project = {
|
|
@@ -2019,19 +1996,19 @@ program
|
|
|
2019
1996
|
(0, data_1.saveData)(data);
|
|
2020
1997
|
// Also init working memory
|
|
2021
1998
|
(0, continuity_1.ensureCmDir)(projectPath);
|
|
2022
|
-
console.log(
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
1999
|
+
console.log((0, box_1.renderResult)('success', `Project initialized: ${projectName}`, [
|
|
2000
|
+
(0, theme_1.dim)(`ID: ${(0, data_1.shortId)(project.id)}`),
|
|
2001
|
+
(0, theme_1.dim)(`Path: ${projectPath}`),
|
|
2002
|
+
(0, theme_1.dim)(`.cm/ Working memory created`),
|
|
2003
|
+
]));
|
|
2026
2004
|
console.log();
|
|
2027
2005
|
if (!isDashboardRunning()) {
|
|
2028
2006
|
(0, dashboard_1.launchDashboard)(data_1.DEFAULT_PORT);
|
|
2029
|
-
console.log(
|
|
2007
|
+
console.log((0, theme_1.success)(` 🚀 Dashboard auto-started! You can track progress at http://codymaster.localhost:${data_1.DEFAULT_PORT}`));
|
|
2030
2008
|
}
|
|
2031
|
-
console.log(
|
|
2032
|
-
console.log(
|
|
2033
|
-
console.log(
|
|
2034
|
-
console.log();
|
|
2009
|
+
console.log((0, theme_1.info)('💡 Next steps:'));
|
|
2010
|
+
console.log((0, theme_1.dim)(' cm task add "My first task"'));
|
|
2011
|
+
console.log((0, theme_1.dim)(' cm open\n'));
|
|
2035
2012
|
});
|
|
2036
2013
|
// ─── Open Command ───────────────────────────────────────────────────────────
|
|
2037
2014
|
program
|
|
@@ -2042,12 +2019,12 @@ program
|
|
|
2042
2019
|
.action((opts) => {
|
|
2043
2020
|
const port = parseInt(opts.port) || data_1.DEFAULT_PORT;
|
|
2044
2021
|
if (!isDashboardRunning()) {
|
|
2045
|
-
console.log(
|
|
2022
|
+
console.log((0, box_1.renderResult)('warning', 'Dashboard not running. Starting it first...'));
|
|
2046
2023
|
(0, dashboard_1.launchDashboard)(port);
|
|
2047
2024
|
setTimeout(() => openUrl(`http://codymaster.localhost:${port}`), 1500);
|
|
2048
2025
|
}
|
|
2049
2026
|
else {
|
|
2050
|
-
console.log(
|
|
2027
|
+
console.log((0, theme_1.info)(`🌐 Opening http://codymaster.localhost:${port} ...`));
|
|
2051
2028
|
openUrl(`http://codymaster.localhost:${port}`);
|
|
2052
2029
|
}
|
|
2053
2030
|
});
|
|
@@ -2057,31 +2034,32 @@ program
|
|
|
2057
2034
|
.alias('cfg')
|
|
2058
2035
|
.description('Show configuration & data paths')
|
|
2059
2036
|
.action(() => {
|
|
2060
|
-
console.log(
|
|
2061
|
-
console.log(
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2037
|
+
console.log((0, box_1.renderCommandHeader)('Cody Configuration', '⚙️'));
|
|
2038
|
+
console.log((0, box_1.renderKeyValue)([
|
|
2039
|
+
['Version', VERSION],
|
|
2040
|
+
['Data Dir', data_1.DATA_DIR],
|
|
2041
|
+
['Data File', data_1.DATA_FILE],
|
|
2042
|
+
['PID File', data_1.PID_FILE],
|
|
2043
|
+
['Port', String(data_1.DEFAULT_PORT)],
|
|
2044
|
+
['CLI Names', 'cm | cm | codymaster'],
|
|
2045
|
+
]));
|
|
2067
2046
|
console.log();
|
|
2068
2047
|
// Show data stats
|
|
2069
2048
|
const data = (0, data_1.loadData)();
|
|
2070
|
-
console.log(
|
|
2071
|
-
console.log(
|
|
2072
|
-
console.log(
|
|
2073
|
-
console.log(
|
|
2074
|
-
console.log(
|
|
2075
|
-
console.log(
|
|
2049
|
+
console.log((0, theme_1.brand)(' Data Stats:'));
|
|
2050
|
+
console.log((0, theme_1.dim)(` Projects: ${data.projects.length}`));
|
|
2051
|
+
console.log((0, theme_1.dim)(` Tasks: ${data.tasks.length}`));
|
|
2052
|
+
console.log((0, theme_1.dim)(` Deploys: ${data.deployments.length}`));
|
|
2053
|
+
console.log((0, theme_1.dim)(` Activities: ${data.activities.length}`));
|
|
2054
|
+
console.log((0, theme_1.dim)(` Changelog: ${data.changelog.length}`));
|
|
2076
2055
|
console.log();
|
|
2077
2056
|
// Dashboard status
|
|
2078
2057
|
if (isDashboardRunning()) {
|
|
2079
|
-
console.log(
|
|
2058
|
+
console.log((0, theme_1.success)(` 🚀 Dashboard: RUNNING at http://codymaster.localhost:${data_1.DEFAULT_PORT}\n`));
|
|
2080
2059
|
}
|
|
2081
2060
|
else {
|
|
2082
|
-
console.log(
|
|
2061
|
+
console.log((0, theme_1.dim)(` ⚫ Dashboard: not running\n`));
|
|
2083
2062
|
}
|
|
2084
|
-
console.log();
|
|
2085
2063
|
});
|
|
2086
2064
|
// ─── Agents Command ─────────────────────────────────────────────────────────
|
|
2087
2065
|
const AGENT_LIST = [
|
|
@@ -2102,24 +2080,23 @@ program
|
|
|
2102
2080
|
// Suggest best agents for skill
|
|
2103
2081
|
const domain = (0, judge_1.getSkillDomain)(skill);
|
|
2104
2082
|
const agents = (0, judge_1.suggestAgentsForSkill)(skill);
|
|
2105
|
-
console.log(
|
|
2106
|
-
console.log(
|
|
2083
|
+
console.log((0, box_1.renderCommandHeader)(`Agent Suggestions for ${skill}`, '🤖'));
|
|
2084
|
+
console.log((0, theme_1.dim)(` Domain: ${domain}\n`));
|
|
2107
2085
|
agents.forEach((agentId, index) => {
|
|
2108
2086
|
const agent = AGENT_LIST.find(a => a.id === agentId);
|
|
2109
|
-
const affinity = index === 0 ?
|
|
2087
|
+
const affinity = index === 0 ? (0, theme_1.success)('★ BEST') : index === 1 ? (0, theme_1.warning)('● GOOD') : (0, theme_1.dim)('○ OK');
|
|
2110
2088
|
console.log(` ${(agent === null || agent === void 0 ? void 0 : agent.icon) || '🤖'} ${padRight((agent === null || agent === void 0 ? void 0 : agent.name) || agentId, 24)} ${affinity}`);
|
|
2111
2089
|
});
|
|
2112
2090
|
console.log();
|
|
2113
2091
|
}
|
|
2114
2092
|
else {
|
|
2115
2093
|
// List all agents
|
|
2116
|
-
console.log(
|
|
2094
|
+
console.log((0, box_1.renderCommandHeader)('Available Agents', '🤖'));
|
|
2117
2095
|
for (const agent of AGENT_LIST) {
|
|
2118
|
-
console.log(` ${agent.icon} ${
|
|
2096
|
+
console.log(` ${agent.icon} ${(0, theme_1.brand)(padRight(agent.name, 24))} ${(0, theme_1.dim)(agent.id)}`);
|
|
2119
2097
|
}
|
|
2120
2098
|
console.log();
|
|
2121
|
-
console.log(
|
|
2122
|
-
console.log();
|
|
2099
|
+
console.log((0, theme_1.dim)(' 💡 Tip: cm agents <skill-name> to see best agents for a skill\n'));
|
|
2123
2100
|
}
|
|
2124
2101
|
});
|
|
2125
2102
|
// ─── Sync Command ───────────────────────────────────────────────────────────
|
|
@@ -2132,7 +2109,7 @@ program
|
|
|
2132
2109
|
.action((file, opts) => {
|
|
2133
2110
|
const filePath = path_1.default.resolve(file);
|
|
2134
2111
|
if (!fs_1.default.existsSync(filePath)) {
|
|
2135
|
-
console.log(
|
|
2112
|
+
console.log((0, box_1.renderResult)('error', `File not found: ${filePath}`));
|
|
2136
2113
|
return;
|
|
2137
2114
|
}
|
|
2138
2115
|
let tasks;
|
|
@@ -2144,8 +2121,7 @@ program
|
|
|
2144
2121
|
throw new Error('Invalid format');
|
|
2145
2122
|
}
|
|
2146
2123
|
catch (err) {
|
|
2147
|
-
console.log(
|
|
2148
|
-
console.log(chalk_1.default.gray(' Expected format: [{"title": "...", "priority": "...", "column": "..."}]'));
|
|
2124
|
+
console.log((0, box_1.renderResult)('error', `Invalid JSON file: ${err.message}`, [(0, theme_1.dim)('Expected format: [{"title": "...", "priority": "...", "column": "..."}]')]));
|
|
2149
2125
|
return;
|
|
2150
2126
|
}
|
|
2151
2127
|
const data = (0, data_1.loadData)();
|
|
@@ -2153,7 +2129,7 @@ program
|
|
|
2153
2129
|
if (opts.project) {
|
|
2154
2130
|
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
2155
2131
|
if (!p) {
|
|
2156
|
-
console.log(
|
|
2132
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
2157
2133
|
return;
|
|
2158
2134
|
}
|
|
2159
2135
|
projectId = p.id;
|
|
@@ -2188,12 +2164,11 @@ program
|
|
|
2188
2164
|
(0, data_1.logActivity)(data, 'task_created', `Synced ${count} tasks from ${path_1.default.basename(filePath)}`, projectId, opts.agent || '', { count, file: filePath });
|
|
2189
2165
|
(0, data_1.saveData)(data);
|
|
2190
2166
|
const project = data.projects.find(p => p.id === projectId);
|
|
2191
|
-
console.log(
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
console.log();
|
|
2167
|
+
console.log((0, box_1.renderResult)('success', `Synced ${count} tasks!`, [
|
|
2168
|
+
(0, theme_1.dim)(`Project: ${(project === null || project === void 0 ? void 0 : project.name) || 'Default'}`),
|
|
2169
|
+
(0, theme_1.dim)(`Source: ${filePath}`),
|
|
2170
|
+
...(opts.agent ? [(0, theme_1.dim)(`Agent: ${opts.agent}`)] : []),
|
|
2171
|
+
]));
|
|
2197
2172
|
});
|
|
2198
2173
|
// ─── Chain Command ──────────────────────────────────────────────────────────
|
|
2199
2174
|
// TRIZ #40 Composite Materials — skills compose into pipelines
|
|
@@ -2237,67 +2212,66 @@ program
|
|
|
2237
2212
|
chainHistory();
|
|
2238
2213
|
break;
|
|
2239
2214
|
default:
|
|
2240
|
-
console.log(
|
|
2241
|
-
console.log(chalk_1.default.gray('Available: list, info, start, status, advance, skip, abort, auto, history'));
|
|
2215
|
+
console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: list, info, start, status, advance, skip, abort, auto, history')]));
|
|
2242
2216
|
}
|
|
2243
2217
|
});
|
|
2244
2218
|
function chainList() {
|
|
2245
2219
|
const chains = (0, skill_chain_1.listChains)();
|
|
2246
|
-
console.log(
|
|
2220
|
+
console.log((0, box_1.renderCommandHeader)('Available Skill Chains', '🔗'));
|
|
2247
2221
|
for (const chain of chains) {
|
|
2248
|
-
console.log(` ${chain.icon} ${
|
|
2249
|
-
console.log(
|
|
2222
|
+
console.log(` ${chain.icon} ${(0, theme_1.brand)(padRight(chain.name, 24))} ${(0, theme_1.dim)(chain.description)}`);
|
|
2223
|
+
console.log((0, theme_1.dim)(` ID: ${chain.id} | Steps: ${chain.steps.length} | Triggers: ${chain.triggers.slice(0, 4).join(', ')}...`));
|
|
2250
2224
|
console.log();
|
|
2251
2225
|
}
|
|
2252
|
-
console.log(
|
|
2253
|
-
console.log(
|
|
2254
|
-
console.log(
|
|
2255
|
-
console.log(
|
|
2256
|
-
console.log();
|
|
2226
|
+
console.log((0, theme_1.dim)(` Total: ${chains.length} chains\n`));
|
|
2227
|
+
console.log((0, theme_1.info)('💡 Quick start:'));
|
|
2228
|
+
console.log((0, theme_1.dim)(' cm chain auto "Build user authentication" # Auto-detect chain'));
|
|
2229
|
+
console.log((0, theme_1.dim)(' cm chain start feature-development "My task" # Start specific chain\n'));
|
|
2257
2230
|
}
|
|
2258
2231
|
function chainInfo(chainId) {
|
|
2259
2232
|
if (!chainId) {
|
|
2260
|
-
console.log(
|
|
2233
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm chain info <chain-id>'));
|
|
2261
2234
|
return;
|
|
2262
2235
|
}
|
|
2263
2236
|
const chain = (0, skill_chain_1.findChain)(chainId);
|
|
2264
2237
|
if (!chain) {
|
|
2265
|
-
console.log(
|
|
2266
|
-
console.log(chalk_1.default.gray(' Use "cm chain list" to see available chains.'));
|
|
2238
|
+
console.log((0, box_1.renderResult)('error', `Chain not found: ${chainId}`, [(0, theme_1.dim)('Use "cm chain list" to see available chains.')]));
|
|
2267
2239
|
return;
|
|
2268
2240
|
}
|
|
2269
|
-
console.log(
|
|
2270
|
-
console.log(
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2241
|
+
console.log((0, box_1.renderCommandHeader)(`Chain: ${chain.name}`, chain.icon));
|
|
2242
|
+
console.log((0, box_1.renderKeyValue)([
|
|
2243
|
+
['ID', chain.id],
|
|
2244
|
+
['Description', chain.description],
|
|
2245
|
+
['Steps', String(chain.steps.length)],
|
|
2246
|
+
['Triggers', chain.triggers.join(', ')],
|
|
2247
|
+
]));
|
|
2274
2248
|
console.log();
|
|
2275
|
-
console.log(
|
|
2249
|
+
console.log((0, theme_1.brand)(' Pipeline:'));
|
|
2276
2250
|
for (let i = 0; i < chain.steps.length; i++) {
|
|
2277
2251
|
const step = chain.steps[i];
|
|
2278
|
-
const condBadge = step.condition === 'always' ?
|
|
2279
|
-
const optBadge = step.optional ?
|
|
2252
|
+
const condBadge = step.condition === 'always' ? (0, theme_1.success)('ALWAYS') : step.condition === 'if-complex' ? (0, theme_1.warning)('IF-COMPLEX') : (0, theme_1.brand)('IF-READY');
|
|
2253
|
+
const optBadge = step.optional ? (0, theme_1.dim)(' (optional)') : '';
|
|
2280
2254
|
const connector = i < chain.steps.length - 1 ? ' │' : ' ';
|
|
2281
|
-
console.log(` ${
|
|
2282
|
-
console.log(
|
|
2255
|
+
console.log(` ${(0, theme_1.brand)(`${i + 1}.`)} ${padRight(step.skill, 24)} ${condBadge}${optBadge}`);
|
|
2256
|
+
console.log((0, theme_1.dim)(` ${connector} ${step.description}`));
|
|
2283
2257
|
if (i < chain.steps.length - 1)
|
|
2284
|
-
console.log(
|
|
2258
|
+
console.log((0, theme_1.dim)(' │'));
|
|
2285
2259
|
}
|
|
2286
2260
|
console.log();
|
|
2287
2261
|
}
|
|
2288
2262
|
function chainStart(chainId, taskTitle, opts) {
|
|
2289
2263
|
var _a, _b, _c;
|
|
2290
2264
|
if (!chainId) {
|
|
2291
|
-
console.log(
|
|
2265
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm chain start <chain-id> "Task title"'));
|
|
2292
2266
|
return;
|
|
2293
2267
|
}
|
|
2294
2268
|
if (!taskTitle) {
|
|
2295
|
-
console.log(
|
|
2269
|
+
console.log((0, box_1.renderResult)('error', 'Task title required. Usage: cm chain start <chain-id> "My task"'));
|
|
2296
2270
|
return;
|
|
2297
2271
|
}
|
|
2298
2272
|
const chain = (0, skill_chain_1.findChain)(chainId);
|
|
2299
2273
|
if (!chain) {
|
|
2300
|
-
console.log(
|
|
2274
|
+
console.log((0, box_1.renderResult)('error', `Chain not found: ${chainId}`));
|
|
2301
2275
|
return;
|
|
2302
2276
|
}
|
|
2303
2277
|
const data = (0, data_1.loadData)();
|
|
@@ -2305,7 +2279,7 @@ function chainStart(chainId, taskTitle, opts) {
|
|
|
2305
2279
|
if (opts.project) {
|
|
2306
2280
|
const project = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
2307
2281
|
if (!project) {
|
|
2308
|
-
console.log(
|
|
2282
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
2309
2283
|
return;
|
|
2310
2284
|
}
|
|
2311
2285
|
projectId = project.id;
|
|
@@ -2314,7 +2288,7 @@ function chainStart(chainId, taskTitle, opts) {
|
|
|
2314
2288
|
projectId = data.projects[0].id;
|
|
2315
2289
|
}
|
|
2316
2290
|
else {
|
|
2317
|
-
console.log(
|
|
2291
|
+
console.log((0, box_1.renderResult)('error', 'No projects. Create one first: cm init'));
|
|
2318
2292
|
return;
|
|
2319
2293
|
}
|
|
2320
2294
|
const agent = opts.agent || 'antigravity';
|
|
@@ -2333,18 +2307,16 @@ function chainStart(chainId, taskTitle, opts) {
|
|
|
2333
2307
|
});
|
|
2334
2308
|
(0, data_1.saveData)(data);
|
|
2335
2309
|
const project = data.projects.find(p => p.id === projectId);
|
|
2336
|
-
console.log(
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
console.log(
|
|
2345
|
-
console.log();
|
|
2346
|
-
console.log(chalk_1.default.gray(` Next: cm chain advance ${(0, data_1.shortId)(execution.id)} "output summary"`));
|
|
2347
|
-
console.log();
|
|
2310
|
+
console.log((0, box_1.renderResult)('success', 'Chain started!', [
|
|
2311
|
+
(0, theme_1.dim)(`Chain: ${chain.icon} ${chain.name}`),
|
|
2312
|
+
(0, theme_1.dim)(`Task: ${taskTitle}`),
|
|
2313
|
+
(0, theme_1.dim)(`Project: ${(project === null || project === void 0 ? void 0 : project.name) || '—'}`),
|
|
2314
|
+
(0, theme_1.dim)(`Agent: ${agent}`),
|
|
2315
|
+
(0, theme_1.dim)(`Steps: ${chain.steps.length}`),
|
|
2316
|
+
(0, theme_1.dim)(`Exec ID: ${(0, data_1.shortId)(execution.id)}`),
|
|
2317
|
+
]));
|
|
2318
|
+
console.log((0, theme_1.brand)(` ▶ Current step: ${(_b = execution.steps[0]) === null || _b === void 0 ? void 0 : _b.skill} — ${(_c = execution.steps[0]) === null || _c === void 0 ? void 0 : _c.description}`));
|
|
2319
|
+
console.log((0, theme_1.dim)(`\n Next: cm chain advance ${(0, data_1.shortId)(execution.id)} "output summary"\n`));
|
|
2348
2320
|
}
|
|
2349
2321
|
function chainStatus(execIdPrefix) {
|
|
2350
2322
|
const data = (0, data_1.loadData)();
|
|
@@ -2352,7 +2324,7 @@ function chainStatus(execIdPrefix) {
|
|
|
2352
2324
|
// Show specific execution
|
|
2353
2325
|
const exec = data.chainExecutions.find(e => e.id === execIdPrefix || e.id.startsWith(execIdPrefix));
|
|
2354
2326
|
if (!exec) {
|
|
2355
|
-
console.log(
|
|
2327
|
+
console.log((0, box_1.renderResult)('error', `Chain execution not found: ${execIdPrefix}`));
|
|
2356
2328
|
return;
|
|
2357
2329
|
}
|
|
2358
2330
|
console.log();
|
|
@@ -2363,34 +2335,33 @@ function chainStatus(execIdPrefix) {
|
|
|
2363
2335
|
// Show all active executions
|
|
2364
2336
|
const active = data.chainExecutions.filter(e => e.status === 'running' || e.status === 'paused');
|
|
2365
2337
|
if (active.length === 0) {
|
|
2366
|
-
console.log(
|
|
2367
|
-
console.log(
|
|
2338
|
+
console.log(`\n ${(0, theme_1.dim)('No active chain executions.')}`);
|
|
2339
|
+
console.log(` ${(0, theme_1.dim)('Start one with: cm chain auto "task description"')}\n`);
|
|
2368
2340
|
return;
|
|
2369
2341
|
}
|
|
2370
|
-
console.log(
|
|
2342
|
+
console.log((0, box_1.renderCommandHeader)(`Active Chains (${active.length})`, '🔗'));
|
|
2371
2343
|
for (const exec of active) {
|
|
2372
2344
|
const project = data.projects.find(p => p.id === exec.projectId);
|
|
2373
2345
|
const currentSkill = (0, skill_chain_1.getCurrentSkill)(exec);
|
|
2374
2346
|
const progressBar = (0, skill_chain_1.formatChainProgressBar)(exec);
|
|
2375
|
-
console.log(` ${
|
|
2376
|
-
console.log(
|
|
2377
|
-
console.log(
|
|
2378
|
-
console.log();
|
|
2347
|
+
console.log(` ${(0, theme_1.brand)(exec.chainName)} — "${exec.taskTitle}"`);
|
|
2348
|
+
console.log((0, theme_1.dim)(` ${progressBar} | Step ${exec.currentStepIndex + 1}/${exec.steps.length}: ${currentSkill || 'done'}`));
|
|
2349
|
+
console.log((0, theme_1.dim)(` ID: ${(0, data_1.shortId)(exec.id)} | Agent: ${exec.agent} | Project: ${(project === null || project === void 0 ? void 0 : project.name) || '—'}\n`));
|
|
2379
2350
|
}
|
|
2380
2351
|
}
|
|
2381
2352
|
function chainAdvance(execIdPrefix, output) {
|
|
2382
2353
|
if (!execIdPrefix) {
|
|
2383
|
-
console.log(
|
|
2354
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm chain advance <exec-id> ["output summary"]'));
|
|
2384
2355
|
return;
|
|
2385
2356
|
}
|
|
2386
2357
|
const data = (0, data_1.loadData)();
|
|
2387
2358
|
const exec = data.chainExecutions.find(e => e.id === execIdPrefix || e.id.startsWith(execIdPrefix));
|
|
2388
2359
|
if (!exec) {
|
|
2389
|
-
console.log(
|
|
2360
|
+
console.log((0, box_1.renderResult)('error', `Chain execution not found: ${execIdPrefix}`));
|
|
2390
2361
|
return;
|
|
2391
2362
|
}
|
|
2392
2363
|
if (exec.status !== 'running') {
|
|
2393
|
-
console.log(
|
|
2364
|
+
console.log((0, box_1.renderResult)('warning', `Chain is ${exec.status}, cannot advance.`));
|
|
2394
2365
|
return;
|
|
2395
2366
|
}
|
|
2396
2367
|
const completedStep = exec.steps[exec.currentStepIndex];
|
|
@@ -2410,10 +2381,10 @@ function chainAdvance(execIdPrefix, output) {
|
|
|
2410
2381
|
executionId: exec.id, totalSteps: exec.steps.length,
|
|
2411
2382
|
});
|
|
2412
2383
|
(0, data_1.saveData)(data);
|
|
2413
|
-
console.log(
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2384
|
+
console.log((0, box_1.renderResult)('success', `Chain completed! All ${exec.steps.length} steps done.`, [
|
|
2385
|
+
(0, theme_1.dim)(`Chain: ${exec.chainName}`),
|
|
2386
|
+
(0, theme_1.dim)(`Task: ${exec.taskTitle}`),
|
|
2387
|
+
]));
|
|
2417
2388
|
}
|
|
2418
2389
|
else {
|
|
2419
2390
|
(0, data_1.logActivity)(data, 'chain_step_completed', `Chain step completed: ${completedStep === null || completedStep === void 0 ? void 0 : completedStep.skill} → next: ${result.nextSkill}`, exec.projectId, exec.agent, {
|
|
@@ -2421,52 +2392,51 @@ function chainAdvance(execIdPrefix, output) {
|
|
|
2421
2392
|
});
|
|
2422
2393
|
(0, data_1.saveData)(data);
|
|
2423
2394
|
const nextStep = exec.steps[exec.currentStepIndex];
|
|
2424
|
-
console.log(
|
|
2425
|
-
console.log(
|
|
2426
|
-
console.log(
|
|
2427
|
-
console.log();
|
|
2395
|
+
console.log((0, box_1.renderResult)('success', `Step completed: ${completedStep === null || completedStep === void 0 ? void 0 : completedStep.skill}`));
|
|
2396
|
+
console.log((0, theme_1.brand)(` ▶ Next step: ${result.nextSkill} — ${nextStep === null || nextStep === void 0 ? void 0 : nextStep.description}`));
|
|
2397
|
+
console.log((0, theme_1.dim)(` Progress: ${(0, skill_chain_1.formatChainProgressBar)(exec)}\n`));
|
|
2428
2398
|
}
|
|
2429
2399
|
}
|
|
2430
2400
|
function chainSkip(execIdPrefix, reason) {
|
|
2431
2401
|
if (!execIdPrefix) {
|
|
2432
|
-
console.log(
|
|
2402
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm chain skip <exec-id> ["reason"]'));
|
|
2433
2403
|
return;
|
|
2434
2404
|
}
|
|
2435
2405
|
const data = (0, data_1.loadData)();
|
|
2436
2406
|
const exec = data.chainExecutions.find(e => e.id === execIdPrefix || e.id.startsWith(execIdPrefix));
|
|
2437
2407
|
if (!exec) {
|
|
2438
|
-
console.log(
|
|
2408
|
+
console.log((0, box_1.renderResult)('error', `Chain execution not found: ${execIdPrefix}`));
|
|
2439
2409
|
return;
|
|
2440
2410
|
}
|
|
2441
2411
|
if (exec.status !== 'running') {
|
|
2442
|
-
console.log(
|
|
2412
|
+
console.log((0, box_1.renderResult)('warning', `Chain is ${exec.status}, cannot skip.`));
|
|
2443
2413
|
return;
|
|
2444
2414
|
}
|
|
2445
2415
|
const skippedStep = exec.steps[exec.currentStepIndex];
|
|
2446
2416
|
const result = (0, skill_chain_1.skipChainStep)(exec, reason);
|
|
2447
2417
|
(0, data_1.saveData)(data);
|
|
2448
|
-
console.log(
|
|
2418
|
+
console.log((0, theme_1.warning)(` ⏭️ Skipped: ${skippedStep === null || skippedStep === void 0 ? void 0 : skippedStep.skill}`));
|
|
2449
2419
|
if (result.completed) {
|
|
2450
|
-
console.log(
|
|
2420
|
+
console.log((0, theme_1.success)(` ✅ Chain completed!`));
|
|
2451
2421
|
}
|
|
2452
2422
|
else {
|
|
2453
|
-
console.log(
|
|
2423
|
+
console.log((0, theme_1.brand)(` ▶ Next: ${result.nextSkill}`));
|
|
2454
2424
|
}
|
|
2455
2425
|
console.log();
|
|
2456
2426
|
}
|
|
2457
2427
|
function chainAbort(execIdPrefix, reason) {
|
|
2458
2428
|
if (!execIdPrefix) {
|
|
2459
|
-
console.log(
|
|
2429
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm chain abort <exec-id> ["reason"]'));
|
|
2460
2430
|
return;
|
|
2461
2431
|
}
|
|
2462
2432
|
const data = (0, data_1.loadData)();
|
|
2463
2433
|
const exec = data.chainExecutions.find(e => e.id === execIdPrefix || e.id.startsWith(execIdPrefix));
|
|
2464
2434
|
if (!exec) {
|
|
2465
|
-
console.log(
|
|
2435
|
+
console.log((0, box_1.renderResult)('error', `Chain execution not found: ${execIdPrefix}`));
|
|
2466
2436
|
return;
|
|
2467
2437
|
}
|
|
2468
2438
|
if (exec.status !== 'running' && exec.status !== 'paused') {
|
|
2469
|
-
console.log(
|
|
2439
|
+
console.log((0, box_1.renderResult)('warning', `Chain already ${exec.status}.`));
|
|
2470
2440
|
return;
|
|
2471
2441
|
}
|
|
2472
2442
|
(0, skill_chain_1.abortChain)(exec, reason);
|
|
@@ -2474,30 +2444,25 @@ function chainAbort(execIdPrefix, reason) {
|
|
|
2474
2444
|
executionId: exec.id,
|
|
2475
2445
|
});
|
|
2476
2446
|
(0, data_1.saveData)(data);
|
|
2477
|
-
console.log(
|
|
2478
|
-
if (reason)
|
|
2479
|
-
console.log(chalk_1.default.gray(` Reason: ${reason}`));
|
|
2480
|
-
console.log();
|
|
2447
|
+
console.log((0, box_1.renderResult)('error', `Chain aborted: ${exec.chainName}`, reason ? [(0, theme_1.dim)(`Reason: ${reason}`)] : []));
|
|
2481
2448
|
}
|
|
2482
2449
|
function chainAuto(taskTitle, opts) {
|
|
2483
2450
|
if (!taskTitle) {
|
|
2484
|
-
console.log(
|
|
2485
|
-
console.log(chalk_1.default.gray(' Example: cm chain auto "Build user authentication"'));
|
|
2451
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm chain auto "task description"', [(0, theme_1.dim)('Example: cm chain auto "Build user authentication"')]));
|
|
2486
2452
|
return;
|
|
2487
2453
|
}
|
|
2488
2454
|
const chain = (0, skill_chain_1.matchChain)(taskTitle);
|
|
2489
2455
|
if (!chain) {
|
|
2490
|
-
|
|
2491
|
-
console.log(
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2456
|
+
const listHint = (0, skill_chain_1.listChains)().map(c => ` ${c.icon} ${c.id}: ${c.triggers.slice(0, 3).join(', ')}...`);
|
|
2457
|
+
console.log((0, box_1.renderResult)('warning', `No matching chain found for: "${taskTitle}"`, [
|
|
2458
|
+
(0, theme_1.dim)('Available chains:'),
|
|
2459
|
+
...listHint.map(l => (0, theme_1.dim)(l)),
|
|
2460
|
+
(0, theme_1.dim)('\n Use "cm chain start <chain-id> <title>" to start manually.'),
|
|
2461
|
+
]));
|
|
2496
2462
|
return;
|
|
2497
2463
|
}
|
|
2498
|
-
console.log(
|
|
2499
|
-
console.log(
|
|
2500
|
-
console.log();
|
|
2464
|
+
console.log((0, box_1.renderCommandHeader)(`Auto-detected chain: ${chain.name}`, chain.icon));
|
|
2465
|
+
console.log((0, theme_1.dim)(` Matched from: "${taskTitle}"\n`));
|
|
2501
2466
|
// Delegate to chainStart
|
|
2502
2467
|
chainStart(chain.id, taskTitle, opts);
|
|
2503
2468
|
}
|
|
@@ -2505,21 +2470,21 @@ function chainHistory() {
|
|
|
2505
2470
|
const data = (0, data_1.loadData)();
|
|
2506
2471
|
const execs = data.chainExecutions;
|
|
2507
2472
|
if (execs.length === 0) {
|
|
2508
|
-
console.log(
|
|
2473
|
+
console.log(`\n ${(0, theme_1.dim)('No chain executions yet.')}\n`);
|
|
2509
2474
|
return;
|
|
2510
2475
|
}
|
|
2511
2476
|
const STATUS_ICONS = {
|
|
2512
2477
|
pending: '⚪', running: '🔵', paused: '⏸️', completed: '✅', failed: '❌', aborted: '🛑',
|
|
2513
2478
|
};
|
|
2514
|
-
console.log(
|
|
2515
|
-
console.log(
|
|
2516
|
-
console.log(
|
|
2479
|
+
console.log((0, box_1.renderCommandHeader)(`Chain History (${execs.length})`, '🔗'));
|
|
2480
|
+
console.log((0, theme_1.dim)(' ' + padRight('Status', 8) + padRight('Chain', 24) + padRight('Task', 30) + padRight('Progress', 14) + 'Time'));
|
|
2481
|
+
console.log((0, theme_1.dim)(' ' + '─'.repeat(86)));
|
|
2517
2482
|
for (const exec of execs.slice(0, 20)) {
|
|
2518
2483
|
const icon = STATUS_ICONS[exec.status] || '❓';
|
|
2519
2484
|
const completed = exec.steps.filter(s => s.status === 'completed' || s.status === 'skipped').length;
|
|
2520
2485
|
const progress = `${completed}/${exec.steps.length} steps`;
|
|
2521
2486
|
const time = formatTimeAgoCli(exec.startedAt);
|
|
2522
|
-
console.log(' ' + padRight(icon, 8) + padRight(exec.chainName.substring(0, 22), 24) + padRight(exec.taskTitle.substring(0, 28), 30) +
|
|
2487
|
+
console.log(' ' + padRight(icon, 8) + (0, theme_1.brand)(padRight(exec.chainName.substring(0, 22), 24)) + padRight(exec.taskTitle.substring(0, 28), 30) + (0, theme_1.dim)(padRight(progress, 14)) + (0, theme_1.dim)(time));
|
|
2523
2488
|
}
|
|
2524
2489
|
console.log();
|
|
2525
2490
|
}
|