multi-agents-cli 1.0.6 → 1.0.7
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/init.js +80 -54
- package/package.json +4 -1
package/init.js
CHANGED
|
@@ -11,6 +11,45 @@
|
|
|
11
11
|
const readline = require('readline');
|
|
12
12
|
const fs = require('fs');
|
|
13
13
|
const path = require('path');
|
|
14
|
+
|
|
15
|
+
// ── Prompts (arrow-key navigation) ───────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
let prompts;
|
|
18
|
+
try { prompts = require('prompts'); } catch { prompts = null; }
|
|
19
|
+
|
|
20
|
+
const arrowSelect = async (message, choices, rl) => {
|
|
21
|
+
if (prompts && process.stdin.isTTY) {
|
|
22
|
+
const res = await prompts({
|
|
23
|
+
type: 'select',
|
|
24
|
+
name: 'value',
|
|
25
|
+
message,
|
|
26
|
+
choices: choices.map((c, i) => ({ title: typeof c === 'string' ? c : c.label, value: i })),
|
|
27
|
+
}, { onCancel: () => process.exit(0) });
|
|
28
|
+
return res.value ?? 0;
|
|
29
|
+
}
|
|
30
|
+
choices.forEach((c, i) => console.log(` ${dim(`${i + 1}.`)} ${typeof c === 'string' ? c : c.label}`));
|
|
31
|
+
return new Promise(resolve => {
|
|
32
|
+
rl.question(`\n Select (1-${choices.length}): `, ans => {
|
|
33
|
+
const n = parseInt(ans) - 1;
|
|
34
|
+
resolve(!isNaN(n) && n >= 0 && n < choices.length ? n : 0);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const arrowConfirm = async (message, rl) => {
|
|
40
|
+
if (prompts && process.stdin.isTTY) {
|
|
41
|
+
const res = await prompts({
|
|
42
|
+
type: 'confirm',
|
|
43
|
+
name: 'value',
|
|
44
|
+
message,
|
|
45
|
+
initial: true,
|
|
46
|
+
}, { onCancel: () => process.exit(0) });
|
|
47
|
+
return res.value ?? true;
|
|
48
|
+
}
|
|
49
|
+
return new Promise(resolve => {
|
|
50
|
+
rl.question(`${message} (y/n): `, ans => resolve(ans.toLowerCase() !== 'n'));
|
|
51
|
+
});
|
|
52
|
+
};
|
|
14
53
|
const os = require('os');
|
|
15
54
|
const { execSync, spawn } = require('child_process');
|
|
16
55
|
|
|
@@ -436,29 +475,21 @@ const showList = (items, showSkip = false) => {
|
|
|
436
475
|
};
|
|
437
476
|
|
|
438
477
|
const selectRequired = async (prompt, items) => {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
const input = await ask(`\n ${bold('Select')} ${dim(`(1-${items.length})`)}: `);
|
|
443
|
-
const index = parseInt(input) - 1;
|
|
444
|
-
if (!isNaN(index) && index >= 0 && index < items.length) return items[index];
|
|
445
|
-
console.log(yellow(` Please enter a number between 1 and ${items.length}.`));
|
|
446
|
-
}
|
|
478
|
+
console.log(`\n${bold(prompt)}`);
|
|
479
|
+
const idx = await arrowSelect(prompt, items.map(i => ({ label: typeof i === 'string' ? i : i.label })), rl);
|
|
480
|
+
return items[idx];
|
|
447
481
|
};
|
|
448
482
|
|
|
449
483
|
const selectOptional = async (prompt, items) => {
|
|
450
484
|
if (!items || items.length === 0) return null;
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
}
|
|
460
|
-
console.log(yellow(` Invalid selection. Please enter a number between 0 and ${items.length}.`));
|
|
461
|
-
}
|
|
485
|
+
console.log(`\n${bold(prompt)}`);
|
|
486
|
+
const choices = [
|
|
487
|
+
...items.map(i => ({ label: typeof i === 'string' ? i : i.label })),
|
|
488
|
+
{ label: dim('Skip (agent will propose when needed)') },
|
|
489
|
+
];
|
|
490
|
+
const idx = await arrowSelect(prompt, choices, rl);
|
|
491
|
+
if (idx === items.length) return null;
|
|
492
|
+
return typeof items[idx] === 'string' ? items[idx] : items[idx].value;
|
|
462
493
|
};
|
|
463
494
|
|
|
464
495
|
const separator = () => console.log(`\n${dim('─'.repeat(60))}`);
|
|
@@ -600,11 +631,11 @@ const main = async () => {
|
|
|
600
631
|
let backendOrm = null;
|
|
601
632
|
let backendAuth = null;
|
|
602
633
|
let backendType = null;
|
|
634
|
+
let backendFwObj = null;
|
|
603
635
|
|
|
604
636
|
if (clientFw.integratedBackend) {
|
|
605
637
|
console.log(dim(` ${clientFw.value} supports server-side rendering and API routes.\n`));
|
|
606
|
-
|
|
607
|
-
useIntegratedBackend = integratedAnswer.toLowerCase() === 'y';
|
|
638
|
+
useIntegratedBackend = await arrowConfirm(`Use integrated backend (${clientFw.value} API routes/SSR) instead of a separate backend?`, rl);
|
|
608
639
|
|
|
609
640
|
if (useIntegratedBackend) {
|
|
610
641
|
backendType = 'integrated';
|
|
@@ -615,22 +646,12 @@ const main = async () => {
|
|
|
615
646
|
if (!useIntegratedBackend) {
|
|
616
647
|
console.log(dim(' You can skip the backend framework and decide later.\n'));
|
|
617
648
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
backendFwObj = null;
|
|
625
|
-
} else {
|
|
626
|
-
const index = parseInt(input) - 1;
|
|
627
|
-
if (isNaN(index) || index < 0 || index >= BACKEND_FRAMEWORKS.length) {
|
|
628
|
-
console.log(yellow(` Please enter a number between 0 and ${BACKEND_FRAMEWORKS.length}.`));
|
|
629
|
-
} else {
|
|
630
|
-
backendFwObj = BACKEND_FRAMEWORKS[index];
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
}
|
|
649
|
+
const backendChoices = [
|
|
650
|
+
...BACKEND_FRAMEWORKS.map(f => ({ label: f.label || f.value })),
|
|
651
|
+
{ label: dim('Skip (decide later)') },
|
|
652
|
+
];
|
|
653
|
+
const backendIdx = await arrowSelect('Backend framework:', backendChoices, rl);
|
|
654
|
+
backendFwObj = backendIdx === BACKEND_FRAMEWORKS.length ? null : BACKEND_FRAMEWORKS[backendIdx];
|
|
634
655
|
|
|
635
656
|
backendFw = backendFwObj ? backendFwObj.value : null;
|
|
636
657
|
backendLang = backendFwObj ? backendFwObj.language : null;
|
|
@@ -675,8 +696,7 @@ const main = async () => {
|
|
|
675
696
|
if (ideChoice.cmd && !ideChoice.detected) {
|
|
676
697
|
console.log(yellow(` ⚠ ${ideChoice.name} was not detected on PATH. It may not open automatically.`));
|
|
677
698
|
}
|
|
678
|
-
|
|
679
|
-
if (confirmIde.toLowerCase() !== 'y') {
|
|
699
|
+
if (!await arrowConfirm('Confirm this selection?', rl)) {
|
|
680
700
|
console.log(dim(' Re-selecting...\n'));
|
|
681
701
|
continue;
|
|
682
702
|
}
|
|
@@ -698,8 +718,7 @@ const main = async () => {
|
|
|
698
718
|
}
|
|
699
719
|
|
|
700
720
|
console.log(` ${yellow('!')} Could not verify ${ideChoice.name}. The CLI may not be installed or accessible.`);
|
|
701
|
-
|
|
702
|
-
if (proceedAnyway.toLowerCase() === 'y') break;
|
|
721
|
+
if (await arrowConfirm('Continue with this IDE anyway?', rl)) break;
|
|
703
722
|
console.log(dim(' Re-selecting...\n'));
|
|
704
723
|
}
|
|
705
724
|
|
|
@@ -724,9 +743,13 @@ const main = async () => {
|
|
|
724
743
|
|
|
725
744
|
console.log('');
|
|
726
745
|
console.log(dim(' y = confirm | n = abort | e = edit (start over)\n'));
|
|
727
|
-
const
|
|
746
|
+
const confirmIdx = await arrowSelect('Confirm and write to config files?', [
|
|
747
|
+
{ label: `${green('✓')} Confirm — write config and set up project` },
|
|
748
|
+
{ label: `${yellow('↺')} Restart — redo configuration` },
|
|
749
|
+
{ label: `${red('✗')} Abort` },
|
|
750
|
+
], rl);
|
|
728
751
|
|
|
729
|
-
if (
|
|
752
|
+
if (confirmIdx === 1) {
|
|
730
753
|
console.log(yellow('\n Restarting configuration...\n'));
|
|
731
754
|
rl.close();
|
|
732
755
|
const { spawn } = require('child_process');
|
|
@@ -735,7 +758,7 @@ const main = async () => {
|
|
|
735
758
|
return;
|
|
736
759
|
}
|
|
737
760
|
|
|
738
|
-
if (
|
|
761
|
+
if (confirmIdx === 2) {
|
|
739
762
|
console.log(yellow('\n Aborted. No files were changed.\n'));
|
|
740
763
|
rl.close();
|
|
741
764
|
return;
|
|
@@ -1125,11 +1148,11 @@ fi
|
|
|
1125
1148
|
// Wrap in loop to support back navigation
|
|
1126
1149
|
let trajectory = null;
|
|
1127
1150
|
trajectoryLoop: while (true) {
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1151
|
+
const trajIdx = await arrowSelect('How do you want to build?', [
|
|
1152
|
+
{ label: bold('Multi-Agent Driven Orchestration') },
|
|
1153
|
+
{ label: bold('Shared Orchestration') },
|
|
1154
|
+
], rl);
|
|
1155
|
+
trajectory = String(trajIdx + 1);
|
|
1133
1156
|
|
|
1134
1157
|
const selected = TRAJECTORY_DETAILS[trajectory];
|
|
1135
1158
|
separator();
|
|
@@ -1137,9 +1160,12 @@ fi
|
|
|
1137
1160
|
renderTrajectoryLines(selected.full);
|
|
1138
1161
|
console.log('');
|
|
1139
1162
|
|
|
1140
|
-
const
|
|
1141
|
-
|
|
1142
|
-
|
|
1163
|
+
const confirmIdx = await arrowSelect('Confirm?', [
|
|
1164
|
+
{ label: `${green('✓')} Confirm` },
|
|
1165
|
+
{ label: `${yellow('←')} Back — pick differently` },
|
|
1166
|
+
], rl);
|
|
1167
|
+
if (confirmIdx === 0) break trajectoryLoop;
|
|
1168
|
+
trajectory = null;
|
|
1143
1169
|
separator();
|
|
1144
1170
|
console.log(`\n ${bold('How do you want to build?')}\n`);
|
|
1145
1171
|
console.log(` ${dim('1.')} ${bold('Multi-Agent Driven Orchestration')}`);
|
|
@@ -1168,8 +1194,8 @@ fi
|
|
|
1168
1194
|
} catch { /* best-effort */ }
|
|
1169
1195
|
|
|
1170
1196
|
if (selected.next === 'launch') {
|
|
1171
|
-
const
|
|
1172
|
-
if (
|
|
1197
|
+
const launchConfirm = await arrowConfirm('Ready to launch your first task?', rl);
|
|
1198
|
+
if (launchConfirm) {
|
|
1173
1199
|
rl.close();
|
|
1174
1200
|
console.log('');
|
|
1175
1201
|
const child = spawn('node', [path.join(ROOT, '.workflow', 'launch.js')], {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "multi-agents-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Multi-agent workflow orchestration for Claude Code — isolated git worktrees, structured state tracking, autonomous task chaining",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
"bin": {
|
|
17
17
|
"multi-agents": "init.js"
|
|
18
18
|
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"prompts": "^2.4.2"
|
|
21
|
+
},
|
|
19
22
|
"files": [
|
|
20
23
|
"init.js",
|
|
21
24
|
"README.md",
|