multi-agents-cli 1.1.10 → 1.1.12

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.
@@ -1184,11 +1184,10 @@ const main = async () => {
1184
1184
  type: 'text',
1185
1185
  name: 'value',
1186
1186
  message: '* What are you building?',
1187
- initial: 'e.g. A stock market prediction app with AI insights and portfolio tracking',
1187
+ hint: '(e.g. A stock market prediction app with AI insights)',
1188
1188
  }, { onCancel: () => process.exit(0) });
1189
1189
  const rawCtx = (ctxRes.value || '').trim();
1190
- const isPlaceholderCtx = rawCtx.startsWith('e.g. ');
1191
- projectContext = isPlaceholderCtx ? '' : rawCtx;
1190
+ projectContext = rawCtx;
1192
1191
  } else {
1193
1192
  console.log(dim(' (optional — helps the agent make better decisions)'));
1194
1193
  const input = await ask(`\n${bold('* What are you building?')}: `);
@@ -1207,12 +1206,13 @@ const main = async () => {
1207
1206
  type: 'text',
1208
1207
  name: 'value',
1209
1208
  message: `* Task description (${agent} agent)`,
1210
- initial: defaultTask ? `e.g. ${defaultTask}` : '',
1209
+ initial: defaultTask || '',
1210
+ hint: defaultTask ? '(Enter to use default, or type your own)' : '(describe what this agent should build or fix)',
1211
1211
  }, { onCancel: () => process.exit(0) });
1212
1212
 
1213
1213
  if (res.value === undefined) continue flowLoop; // Esc = back
1214
1214
  const rawValue = (res.value || '').trim();
1215
- const isPlaceholder = rawValue.startsWith('e.g. ') && rawValue === `e.g. ${defaultTask}`;
1215
+ const isPlaceholder = rawValue === defaultTask || rawValue === '';
1216
1216
  task = isPlaceholder ? defaultTask : (rawValue || defaultTask);
1217
1217
  if (!task) task = defaultTask;
1218
1218
  } else {
@@ -1721,6 +1721,19 @@ ${excludedUrls}
1721
1721
  ], rl);
1722
1722
 
1723
1723
  if (sessionIdx === 0) {
1724
+ separator();
1725
+ console.log(`\n ${bold('What happens next:')}
1726
+ `);
1727
+ console.log(` ${dim('→')} ${bold(config.ide.name || 'Your IDE')} will open at your agent workspace`);
1728
+ console.log(` ${dim('→')} A new terminal window will open with Claude Code\n`);
1729
+ console.log(` ${bold('Once open:')}
1730
+ `);
1731
+ console.log(` ${bold('1.')} Approve the workspace trust prompt in Claude Code`);
1732
+ console.log(` ${bold('2.')} Type anything to start ${dim("(e.g. 'go', 'start', 'begin')")}`);
1733
+ console.log(` ${bold('3.')} Let the agent run autonomously — don't interrupt mid-task`);
1734
+ console.log(` ${bold('4.')} When done, run: ${cyan('npm run complete')}\n`);
1735
+ const goIdx = await arrowSelect('Ready?', [{ label: `${green('✓')} Open workspace` }, { label: `${dim('←')} Back` }], rl);
1736
+ if (goIdx === 1) { continue sessionLoop; }
1724
1737
  const openedIDE = openIDE(worktreePath);
1725
1738
  if (openedIDE) console.log(` ${green('✓')} ${openedIDE} opened`);
1726
1739
  else console.log(` ${yellow('!')} Could not open IDE - open manually at: ${dim(worktreePath)}`);
@@ -1732,15 +1745,38 @@ ${excludedUrls}
1732
1745
  process.exit(0);
1733
1746
 
1734
1747
  } else if (sessionIdx === 1) {
1748
+ separator();
1749
+ console.log(`\n ${bold('What happens next:')}
1750
+ `);
1751
+ console.log(` ${dim('→')} ${bold(config.ide.name || 'Your IDE')} will open at your agent workspace\n`);
1752
+ console.log(` ${bold('Once open:')}
1753
+ `);
1754
+ console.log(` ${bold('1.')} Open a new Claude Code session inside the IDE`);
1755
+ console.log(` ${bold('2.')} Approve the workspace trust prompt`);
1756
+ console.log(` ${bold('3.')} Type anything to start ${dim("(e.g. 'go', 'start', 'begin')")}`);
1757
+ console.log(` ${bold('4.')} Let the agent run autonomously — don't interrupt mid-task`);
1758
+ console.log(` ${bold('5.')} When done, run: ${cyan('npm run complete')}\n`);
1759
+ const goIdx = await arrowSelect('Ready?', [{ label: `${green('✓')} Open workspace` }, { label: `${dim('←')} Back` }], rl);
1760
+ if (goIdx === 1) { continue sessionLoop; }
1735
1761
  const openedIDE = openIDE(worktreePath);
1736
1762
  if (openedIDE) console.log(` ${green("✓")} ${openedIDE} opened`);
1737
1763
  else console.log(` ${yellow("!")} Could not open IDE - open manually at: ${dim(worktreePath)}`);
1738
- console.log(`\n ${dim('Open a NEW Claude Code session and type')} ${cyan('go')} ${dim('to start.')}\n`);
1739
- console.log(` ${dim('When done, run:')} ${cyan('npm run complete')}\n`);
1740
1764
  rl.close();
1741
1765
  process.exit(0);
1742
1766
 
1743
1767
  } else if (sessionIdx === 2) {
1768
+ separator();
1769
+ console.log(`\n ${bold('What happens next:')}
1770
+ `);
1771
+ console.log(` ${dim('→')} A new terminal window will open with Claude Code\n`);
1772
+ console.log(` ${bold('Once open:')}
1773
+ `);
1774
+ console.log(` ${bold('1.')} Approve the workspace trust prompt in Claude Code`);
1775
+ console.log(` ${bold('2.')} Type anything to start ${dim("(e.g. 'go', 'start', 'begin')")}`);
1776
+ console.log(` ${bold('3.')} Let the agent run autonomously — don't interrupt mid-task`);
1777
+ console.log(` ${bold('4.')} When done, run: ${cyan('npm run complete')}\n`);
1778
+ const goIdx = await arrowSelect('Ready?', [{ label: `${green('✓')} Open workspace` }, { label: `${dim('←')} Back` }], rl);
1779
+ if (goIdx === 1) { continue sessionLoop; }
1744
1780
  const termOpened = openTerminal(worktreePath, skipPermissions);
1745
1781
  if (termOpened) console.log(` ${green('✓')} New terminal opened with Claude Code CLI`);
1746
1782
  console.log(`\n ${dim("This window can be closed.")}`);
@@ -9,7 +9,7 @@
9
9
  * Run from the repo root after a task is complete.
10
10
  */
11
11
 
12
- const readline = require('readline');
12
+ let prompts; try { prompts = require('prompts'); } catch { prompts = null; }
13
13
  const fs = require('fs');
14
14
  const path = require('path');
15
15
  const { execSync, spawn } = require('child_process');
@@ -51,15 +51,23 @@ if (!fs.existsSync(LOCK_PATH)) {
51
51
 
52
52
  const config = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
53
53
 
54
- // ── Readline ──────────────────────────────────────────────────────────────────
54
+ // ── Arrow confirm helper ──────────────────────────────────────────────────────
55
55
 
56
- const rl = readline.createInterface({
57
- input: process.stdin,
58
- output: process.stdout,
59
- });
56
+ const arrowConfirm = async (message, initial = true) => {
57
+ if (prompts && process.stdin.isTTY) {
58
+ const res = await prompts({ type: 'confirm', name: 'value', message, initial }, { onCancel: () => process.exit(0) });
59
+ return res.value ?? initial;
60
+ }
61
+ return initial;
62
+ };
60
63
 
61
- const ask = (question) =>
62
- new Promise((resolve) => rl.question(question, (a) => resolve(a.trim())));
64
+ const arrowSelect = async (message, choices) => {
65
+ if (prompts && process.stdin.isTTY) {
66
+ const res = await prompts({ type: 'select', name: 'value', message, choices: choices.map((c, i) => ({ title: c, value: i })) }, { onCancel: () => process.exit(0) });
67
+ return res.value ?? 0;
68
+ }
69
+ return 0;
70
+ };
63
71
 
64
72
  const separator = () => console.log(`\n${dim('─'.repeat(60))}`);
65
73
 
@@ -143,7 +151,6 @@ const main = async () => {
143
151
  if (worktrees.length === 0) {
144
152
  console.log(`\n${yellow(' No active task worktrees found.')}`);
145
153
  console.log(dim(' Run npm run agent to start a task.\n'));
146
- rl.close();
147
154
  return;
148
155
  }
149
156
 
@@ -163,15 +170,8 @@ const main = async () => {
163
170
  selectedWorktree = worktrees[0];
164
171
  console.log(dim(`\n Auto-selected: ${selectedWorktree.branch}\n`));
165
172
  } else {
166
- while (!selectedWorktree) {
167
- const input = await ask(`\n ${bold('Select task to complete')} ${dim(`(1-${worktrees.length})`)}: `);
168
- const index = parseInt(input) - 1;
169
- if (!isNaN(index) && index >= 0 && index < worktrees.length) {
170
- selectedWorktree = worktrees[index];
171
- } else {
172
- console.log(yellow(` Please enter a number between 1 and ${worktrees.length}.`));
173
- }
174
- }
173
+ const idx = await arrowSelect('Select task to complete:', worktrees.map(wt => wt.branch));
174
+ selectedWorktree = worktrees[idx];
175
175
  }
176
176
 
177
177
  const { path: worktreePath, branch: branchName } = selectedWorktree;
@@ -219,7 +219,6 @@ const main = async () => {
219
219
  console.log(dim(' The following files are outside the allowed scope for ' + scopeMeta.agent + ' (' + scopeMeta.scope + '):\n'));
220
220
  violations.forEach(f => console.log(' ' + red('✗') + ' ' + f));
221
221
  console.log('\n' + dim(' Fix the violations, then re-run npm run complete.\n'));
222
- rl.close();
223
222
  return;
224
223
  }
225
224
 
@@ -238,10 +237,9 @@ const main = async () => {
238
237
  if (!isCompleted && !isNonTTY) {
239
238
  console.log(`\n${yellow(' TASK.md is not marked as COMPLETED.')}`);
240
239
  console.log(dim(' The agent may still be working on this task.\n'));
241
- const proceed = await ask(` ${bold('Proceed with merge anyway?')} ${dim('(y/n)')}: `);
242
- if (proceed.toLowerCase() !== 'y') {
240
+ const proceed = await arrowConfirm('Proceed with merge anyway?', false);
241
+ if (!proceed) {
243
242
  console.log(yellow('\n Aborted. Complete the task first.\n'));
244
- rl.close();
245
243
  return;
246
244
  }
247
245
  } else if (!isCompleted && isNonTTY) {
@@ -258,10 +256,9 @@ const main = async () => {
258
256
  console.log(` ${dim('Into')} : ${green('main')}`);
259
257
  console.log(` ${dim('Worktree')} : ${dim(worktreePath)}\n`);
260
258
 
261
- const confirm = isNonTTY ? 'y' : await ask(`${bold('Confirm merge into main?')} ${dim('(y/n)')}: `);
262
- if (confirm.toLowerCase() !== 'y') {
259
+ const confirmMerge = isNonTTY ? true : await arrowConfirm('Confirm merge into main?');
260
+ if (!confirmMerge) {
263
261
  console.log(yellow('\n Aborted.\n'));
264
- rl.close();
265
262
  return;
266
263
  }
267
264
 
@@ -328,10 +325,9 @@ const main = async () => {
328
325
  } catch (err) {
329
326
  console.log(` ${yellow('!')} Could not pull latest main.`);
330
327
  if (!isNonTTY) {
331
- const proceedAnyway = await ask(` ${bold('Proceed with merge anyway?')} ${dim('(y/n)')}: `);
332
- if (proceedAnyway.toLowerCase() !== 'y') {
328
+ const proceedAnyway = await arrowConfirm('Proceed with merge anyway?');
329
+ if (!proceedAnyway) {
333
330
  console.log(yellow('\n Aborted.\n'));
334
- rl.close();
335
331
  return;
336
332
  }
337
333
  } else {
@@ -362,12 +358,10 @@ const main = async () => {
362
358
  } else {
363
359
  console.log(`\n${red(' ✗ Merge conflict in:')} ${conflicts.join(', ')}`);
364
360
  console.log(dim(' Resolve conflicts manually, then run: git commit\n'));
365
- rl.close();
366
361
  return;
367
362
  }
368
363
  } catch {
369
364
  console.log(`\n${red(' ✗ Merge failed.')} Resolve manually.\n`);
370
- rl.close();
371
365
  return;
372
366
  }
373
367
  }
@@ -560,22 +554,13 @@ const main = async () => {
560
554
  console.log(` client/LOGIC is merged. This is the ideal moment to launch backend/INIT.\n`);
561
555
 
562
556
  const { spawn: _spawn } = require('child_process');
563
- const launchIdx = await new Promise(resolve => {
564
- rl2 = readline.createInterface({ input: process.stdin, output: process.stdout });
565
- const choices = [
566
- '1. Launch backend/INIT now ← recommended',
567
- '2. Skip — I will handle it manually',
568
- ];
569
- choices.forEach(c => console.log(` ${c}`));
570
- rl2.question('\n Select (1-2): ', ans => {
571
- rl2.close();
572
- resolve(parseInt(ans));
573
- });
574
- });
557
+ const launchIdx = await arrowSelect('Launch backend/INIT?', [
558
+ 'Launch backend/INIT now ← recommended',
559
+ 'Skip I will handle it manually',
560
+ ]);
575
561
 
576
562
  if (launchIdx === 1) {
577
563
  console.log(`\n ${green('✓')} Launching backend/INIT...\n`);
578
- rl.close();
579
564
  _spawn('node', [path.join(ROOT, '.workflow', 'agent.js'), '--scope=backend', '--agent=INIT'], {
580
565
  cwd: ROOT, stdio: 'inherit',
581
566
  });
@@ -583,8 +568,6 @@ const main = async () => {
583
568
  }
584
569
  }
585
570
  } catch { /* best-effort */ }
586
-
587
- rl.close();
588
571
  };
589
572
 
590
573
  main().catch((err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multi-agents-cli",
3
- "version": "1.1.10",
3
+ "version": "1.1.12",
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",