multi-agents-cli 1.0.7 → 1.0.9
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/README.md +87 -55
- package/init.js +32 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,39 +1,33 @@
|
|
|
1
|
-
# Multi
|
|
1
|
+
# Multi Agents
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Claude Code agents working simultaneously in isolated git worktrees — each
|
|
5
|
-
agent owning a specific domain, all coordinating through shared state.
|
|
3
|
+
Multi-agent workflow orchestration for Claude Code — isolated git worktrees, structured state tracking, autonomous task chaining.
|
|
6
4
|
|
|
7
5
|
---
|
|
8
6
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
Three commands drive the entire workflow:
|
|
7
|
+
## Install
|
|
12
8
|
|
|
13
9
|
```bash
|
|
14
|
-
npm
|
|
15
|
-
npm run launch # create a new agent workspace
|
|
16
|
-
npm run complete # merge finished work, start next task
|
|
10
|
+
npm install -g multi-agents-cli
|
|
17
11
|
```
|
|
18
12
|
|
|
19
|
-
No manual worktree management. No manual branch creation. No repeated context.
|
|
20
|
-
|
|
21
13
|
---
|
|
22
14
|
|
|
23
15
|
## Quickstart
|
|
24
16
|
|
|
25
17
|
```bash
|
|
26
|
-
|
|
18
|
+
multi-agents init my-project
|
|
27
19
|
cd my-project
|
|
28
|
-
npm run
|
|
20
|
+
npm run launch
|
|
29
21
|
```
|
|
30
22
|
|
|
31
|
-
`
|
|
32
|
-
-
|
|
23
|
+
`multi-agents init` will:
|
|
24
|
+
- Guide you through project name, stack, IDE, and build trajectory using arrow-key selection
|
|
33
25
|
- Fetch all templates and workflow scripts from multi-agents-core
|
|
34
26
|
- Generate `BUILD_STATE.md`, `CONTRACTS.md`, `CLAUDE.md`
|
|
27
|
+
- Generate `.scaffold/.paths.json` with expected framework paths
|
|
35
28
|
- Initialize agent tracking (`.scaffold/.tracking.json`)
|
|
36
|
-
-
|
|
29
|
+
- Install `prompts` dependency for arrow-key navigation
|
|
30
|
+
- Set up git remote handling (first agent session handles this automatically)
|
|
37
31
|
|
|
38
32
|
---
|
|
39
33
|
|
|
@@ -63,6 +57,39 @@ and continue building.
|
|
|
63
57
|
|
|
64
58
|
---
|
|
65
59
|
|
|
60
|
+
## Build Trajectories
|
|
61
|
+
|
|
62
|
+
Choose during `multi-agents init`:
|
|
63
|
+
|
|
64
|
+
**Multi-Agent Driven Orchestration** *(recommended)*
|
|
65
|
+
Every task should start with `npm run launch`. Each agent works in its own
|
|
66
|
+
git worktree — an isolated branch and folder that merges back into main via
|
|
67
|
+
`npm run complete`. Faster builds and lower token spend than a single long session.
|
|
68
|
+
⚠ If you commit directly to main yourself, you bypass the framework and break
|
|
69
|
+
task tracking for any active agent branches.
|
|
70
|
+
|
|
71
|
+
**Shared Orchestration**
|
|
72
|
+
You and agents co-build — each owning a defined part of the codebase. Agent
|
|
73
|
+
tasks run in git worktrees; your work happens directly in the project. Define
|
|
74
|
+
boundaries before work begins.
|
|
75
|
+
⚠ If you and an agent touch the same file, expect merge conflicts.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Supported Frameworks
|
|
80
|
+
|
|
81
|
+
### Client
|
|
82
|
+
Next.js · Angular · Vue/Nuxt · SvelteKit · Vite+React · Remix
|
|
83
|
+
|
|
84
|
+
### Backend (separate)
|
|
85
|
+
Express · NestJS · Fastify · FastAPI · Django
|
|
86
|
+
|
|
87
|
+
Each framework has a dedicated scaffold instruction file in
|
|
88
|
+
`client/frameworks/` and `backend/frameworks/` — agents read these
|
|
89
|
+
before scaffolding to ensure files land in the correct location.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
66
93
|
## Agent Roster
|
|
67
94
|
|
|
68
95
|
### Client
|
|
@@ -101,8 +128,7 @@ and continue building.
|
|
|
101
128
|
|
|
102
129
|
## Running the App
|
|
103
130
|
|
|
104
|
-
After agents complete their tasks and merge into main
|
|
105
|
-
in `client/` (and `backend/` if configured separately):
|
|
131
|
+
After agents complete their tasks and merge into main:
|
|
106
132
|
|
|
107
133
|
```bash
|
|
108
134
|
cd client
|
|
@@ -117,15 +143,13 @@ For deployment (Vercel, Netlify etc.) set the **root directory** to
|
|
|
117
143
|
|
|
118
144
|
## Remote Setup
|
|
119
145
|
|
|
120
|
-
`
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
**Your first agent session handles remote setup automatically:**
|
|
146
|
+
`multi-agents init` does NOT configure a GitHub remote. Your first agent
|
|
147
|
+
session handles remote setup automatically:
|
|
124
148
|
|
|
125
149
|
1. Checks SSH, gh CLI, and HTTPS credentials in order
|
|
126
|
-
2. If a remote
|
|
127
|
-
3.
|
|
128
|
-
|
|
150
|
+
2. If a remote repo exists — evaluates its state (orphaned branches, completion status, age)
|
|
151
|
+
3. Auto-clears old sessions or surfaces a decision when unfinished work is detected
|
|
152
|
+
4. If no remote — opens your browser to `github.com/new` with the repo name pre-filled
|
|
129
153
|
|
|
130
154
|
No manual `git remote add` needed.
|
|
131
155
|
|
|
@@ -141,6 +165,7 @@ No manual `git remote add` needed.
|
|
|
141
165
|
| `TASK.md` | Per-task instructions — lives in the agent's worktree |
|
|
142
166
|
| `.scaffold/.config.json` | Project config written at init time |
|
|
143
167
|
| `.scaffold/.tracking.json` | Active agent state — managed by workflow scripts |
|
|
168
|
+
| `.scaffold/.paths.json` | Expected and actual framework paths — updated by agents after scaffolding |
|
|
144
169
|
|
|
145
170
|
> **Never edit `BUILD_STATE.md` directly.** `npm run complete` owns all
|
|
146
171
|
> updates to it. Editing it in a worktree causes merge conflicts.
|
|
@@ -152,13 +177,15 @@ No manual `git remote add` needed.
|
|
|
152
177
|
Context loads in this order for every agent:
|
|
153
178
|
|
|
154
179
|
```
|
|
155
|
-
Root CLAUDE.md
|
|
180
|
+
Root CLAUDE.md ← global rules, protocols, tracking schema
|
|
181
|
+
↓
|
|
182
|
+
client/CLAUDE.md ← stack config, framework scaffold instructions
|
|
156
183
|
↓
|
|
157
|
-
client/
|
|
184
|
+
client/frameworks/{fw}.md ← exact scaffold commands and path conventions
|
|
158
185
|
↓
|
|
159
|
-
agents/UI.md
|
|
186
|
+
agents/UI.md ← agent-specific behavior and constraints
|
|
160
187
|
↓
|
|
161
|
-
TASK.md
|
|
188
|
+
TASK.md ← the specific task to execute
|
|
162
189
|
```
|
|
163
190
|
|
|
164
191
|
Each layer narrows scope. Agents never need to be told what framework
|
|
@@ -180,8 +207,7 @@ The launcher enforces structural rules before any worktree is created:
|
|
|
180
207
|
|
|
181
208
|
## Tracking
|
|
182
209
|
|
|
183
|
-
`.scaffold/.tracking.json` is the runtime state ledger
|
|
184
|
-
is pre-defined at init time:
|
|
210
|
+
`.scaffold/.tracking.json` is the runtime state ledger:
|
|
185
211
|
|
|
186
212
|
```json
|
|
187
213
|
{
|
|
@@ -203,29 +229,33 @@ Managed entirely by `launch.js` and `complete.js`. Never edit manually.
|
|
|
203
229
|
|
|
204
230
|
---
|
|
205
231
|
|
|
206
|
-
##
|
|
232
|
+
## Path Tracking
|
|
207
233
|
|
|
208
|
-
`
|
|
209
|
-
via `git rev-parse --git-common-dir`. Run them from the worktree terminal,
|
|
210
|
-
the repo root, or anywhere inside the git tree — they always work.
|
|
234
|
+
`.scaffold/.paths.json` maps expected and actual framework paths:
|
|
211
235
|
|
|
212
|
-
|
|
236
|
+
```json
|
|
237
|
+
{
|
|
238
|
+
"client": {
|
|
239
|
+
"typesDir": {
|
|
240
|
+
"expected": "client/src/types",
|
|
241
|
+
"current": null,
|
|
242
|
+
"status": "pending"
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
213
247
|
|
|
214
|
-
|
|
248
|
+
**Status values:** `pending` (not yet scaffolded) · `verified` (agent confirmed path) · `diverged` (actual path differs from expected)
|
|
215
249
|
|
|
216
|
-
|
|
250
|
+
Written at init time. Updated by agents after scaffolding their framework.
|
|
217
251
|
|
|
218
|
-
|
|
219
|
-
```bash
|
|
220
|
-
git clone https://github.com/JDev-il/multi-agents-template.git my-project
|
|
221
|
-
cd my-project
|
|
222
|
-
npm run init
|
|
223
|
-
```
|
|
224
|
-
The template remote is automatically removed. Remote setup happens on first agent session.
|
|
252
|
+
---
|
|
225
253
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
254
|
+
## Running Commands From Anywhere
|
|
255
|
+
|
|
256
|
+
`npm run launch` and `npm run complete` self-relocate to the repo root
|
|
257
|
+
via `git rev-parse --git-common-dir`. Run them from the worktree terminal,
|
|
258
|
+
the repo root, or anywhere inside the git tree — they always work.
|
|
229
259
|
|
|
230
260
|
---
|
|
231
261
|
|
|
@@ -233,19 +263,21 @@ with a clean history. Then clone your new repo and run `npm run init`.
|
|
|
233
263
|
|
|
234
264
|
```
|
|
235
265
|
my-project/
|
|
236
|
-
├── client/
|
|
237
|
-
│ ├──
|
|
266
|
+
├── client/ ← built by client agents, merges into main
|
|
267
|
+
│ ├── frameworks/ ← scaffold instruction files per framework
|
|
238
268
|
│ └── src/
|
|
239
|
-
├── backend/
|
|
240
|
-
|
|
241
|
-
├──
|
|
242
|
-
|
|
269
|
+
├── backend/ ← built by backend agents (if separate)
|
|
270
|
+
│ └── frameworks/ ← scaffold instruction files per framework
|
|
271
|
+
├── shared/
|
|
272
|
+
├── worktrees/ ← local only, gitignored
|
|
273
|
+
│ └── client-my-project-ui-1780403456467/
|
|
243
274
|
├── CLAUDE.md
|
|
244
275
|
├── BUILD_STATE.md
|
|
245
276
|
├── CONTRACTS.md
|
|
246
277
|
├── .scaffold/
|
|
247
278
|
│ ├── .config.json
|
|
248
279
|
│ ├── .tracking.json
|
|
280
|
+
│ ├── .paths.json
|
|
249
281
|
│ └── .initialized
|
|
250
282
|
└── .workflow/
|
|
251
283
|
├── launch.js
|
package/init.js
CHANGED
|
@@ -17,21 +17,25 @@ const path = require('path');
|
|
|
17
17
|
let prompts;
|
|
18
18
|
try { prompts = require('prompts'); } catch { prompts = null; }
|
|
19
19
|
|
|
20
|
-
const arrowSelect = async (message, choices, rl) => {
|
|
20
|
+
const arrowSelect = async (message, choices, rl, showBack = false) => {
|
|
21
|
+
const allChoices = showBack
|
|
22
|
+
? [...choices, { label: dim('← Restart configuration') }]
|
|
23
|
+
: choices;
|
|
24
|
+
|
|
21
25
|
if (prompts && process.stdin.isTTY) {
|
|
22
26
|
const res = await prompts({
|
|
23
27
|
type: 'select',
|
|
24
28
|
name: 'value',
|
|
25
29
|
message,
|
|
26
|
-
choices:
|
|
30
|
+
choices: allChoices.map((c, i) => ({ title: typeof c === 'string' ? c : c.label, value: i })),
|
|
27
31
|
}, { onCancel: () => process.exit(0) });
|
|
28
32
|
return res.value ?? 0;
|
|
29
33
|
}
|
|
30
|
-
|
|
34
|
+
allChoices.forEach((c, i) => console.log(` ${dim(`${i + 1}.`)} ${typeof c === 'string' ? c : c.label}`));
|
|
31
35
|
return new Promise(resolve => {
|
|
32
|
-
rl.question(`\n Select (1-${
|
|
36
|
+
rl.question(`\n Select (1-${allChoices.length}): `, ans => {
|
|
33
37
|
const n = parseInt(ans) - 1;
|
|
34
|
-
resolve(!isNaN(n) && n >= 0 && n <
|
|
38
|
+
resolve(!isNaN(n) && n >= 0 && n < allChoices.length ? n : 0);
|
|
35
39
|
});
|
|
36
40
|
});
|
|
37
41
|
};
|
|
@@ -474,20 +478,23 @@ const showList = (items, showSkip = false) => {
|
|
|
474
478
|
if (showSkip) console.log(` ${dim('0.')} Skip ${dim('(agent will propose when needed)')}`);
|
|
475
479
|
};
|
|
476
480
|
|
|
481
|
+
// Sentinel value returned when user picks ← Restart
|
|
482
|
+
const BACK = Symbol('BACK');
|
|
483
|
+
|
|
477
484
|
const selectRequired = async (prompt, items) => {
|
|
478
|
-
|
|
479
|
-
|
|
485
|
+
const idx = await arrowSelect(prompt, items.map(i => ({ label: typeof i === 'string' ? i : i.label })), rl, true);
|
|
486
|
+
if (idx === items.length) return BACK;
|
|
480
487
|
return items[idx];
|
|
481
488
|
};
|
|
482
489
|
|
|
483
490
|
const selectOptional = async (prompt, items) => {
|
|
484
491
|
if (!items || items.length === 0) return null;
|
|
485
|
-
console.log(`\n${bold(prompt)}`);
|
|
486
492
|
const choices = [
|
|
487
493
|
...items.map(i => ({ label: typeof i === 'string' ? i : i.label })),
|
|
488
494
|
{ label: dim('Skip (agent will propose when needed)') },
|
|
489
495
|
];
|
|
490
|
-
const idx = await arrowSelect(prompt, choices, rl);
|
|
496
|
+
const idx = await arrowSelect(prompt, choices, rl, true);
|
|
497
|
+
if (idx === choices.length) return BACK;
|
|
491
498
|
if (idx === items.length) return null;
|
|
492
499
|
return typeof items[idx] === 'string' ? items[idx] : items[idx].value;
|
|
493
500
|
};
|
|
@@ -595,7 +602,7 @@ const main = async () => {
|
|
|
595
602
|
separator();
|
|
596
603
|
|
|
597
604
|
console.log(`\n${bold('Let\'s configure your project.')}`);
|
|
598
|
-
console.log(dim('
|
|
605
|
+
console.log(dim(' Use arrow keys to select. Optional fields can be skipped.\n'));
|
|
599
606
|
console.log(dim(' Skipped fields will be resolved by the agent when first needed.\n'));
|
|
600
607
|
|
|
601
608
|
// ── Project name ────────────────────────────────────────────────────────────
|
|
@@ -606,6 +613,14 @@ const main = async () => {
|
|
|
606
613
|
if (!projectName) console.log(yellow(' Project name is required. Please enter a name.'));
|
|
607
614
|
}
|
|
608
615
|
|
|
616
|
+
const restartIfBack = (val) => {
|
|
617
|
+
if (val !== BACK) return false;
|
|
618
|
+
rl.close();
|
|
619
|
+
const { spawn } = require('child_process');
|
|
620
|
+
spawn('node', [__filename], { stdio: 'inherit', cwd: ROOT }).on('exit', c => process.exit(c));
|
|
621
|
+
return true;
|
|
622
|
+
};
|
|
623
|
+
|
|
609
624
|
separator();
|
|
610
625
|
|
|
611
626
|
// ── Client ──────────────────────────────────────────────────────────────────
|
|
@@ -613,10 +628,14 @@ const main = async () => {
|
|
|
613
628
|
console.log(`\n${bold(blue('Client configuration'))}`);
|
|
614
629
|
|
|
615
630
|
const clientFw = await selectRequired('* Client framework (required):', CLIENT_FRAMEWORKS);
|
|
631
|
+
if (restartIfBack(clientFw)) return;
|
|
616
632
|
const clientLang = clientFw.language;
|
|
617
633
|
const clientState = await selectOptional('State management:', STATE_OPTIONS[clientFw.value] || []);
|
|
634
|
+
if (restartIfBack(clientState)) return;
|
|
618
635
|
const clientUi = await selectOptional('UI library:', UI_OPTIONS[clientFw.value] || []);
|
|
636
|
+
if (restartIfBack(clientUi)) return;
|
|
619
637
|
const clientStyle = await selectOptional('Styling:', STYLING_OPTIONS);
|
|
638
|
+
if (restartIfBack(clientStyle)) return;
|
|
620
639
|
|
|
621
640
|
separator();
|
|
622
641
|
|
|
@@ -656,7 +675,9 @@ const main = async () => {
|
|
|
656
675
|
backendFw = backendFwObj ? backendFwObj.value : null;
|
|
657
676
|
backendLang = backendFwObj ? backendFwObj.language : null;
|
|
658
677
|
backendOrm = backendFw ? await selectOptional('ORM / database layer:', ORM_OPTIONS[backendFw] || []) : null;
|
|
678
|
+
if (restartIfBack(backendOrm)) return;
|
|
659
679
|
backendAuth = backendFw ? await selectOptional('Auth strategy:', AUTH_OPTIONS[backendFw] || []) : null;
|
|
680
|
+
if (restartIfBack(backendAuth)) return;
|
|
660
681
|
backendType = backendFw ? 'separate' : null;
|
|
661
682
|
}
|
|
662
683
|
|
|
@@ -690,6 +711,7 @@ const main = async () => {
|
|
|
690
711
|
let ideChoice;
|
|
691
712
|
while (true) {
|
|
692
713
|
ideChoice = await selectRequired('* IDE / editor (required):', sortedIdeOptions);
|
|
714
|
+
if (restartIfBack(ideChoice)) return;
|
|
693
715
|
|
|
694
716
|
// ── Confirmation ──────────────────────────────────────────────────────────
|
|
695
717
|
console.log(`\n Selected: ${bold(ideChoice.name)}`);
|
package/package.json
CHANGED