multi-agents-cli 1.0.99 → 1.1.1
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 +18 -2
- package/core/templates/.agents/backend/API.md +12 -1
- package/core/templates/.agents/backend/AUTH.md +12 -1
- package/core/templates/.agents/backend/DB.md +12 -1
- package/core/templates/.agents/backend/EVENTS.md +12 -1
- package/core/templates/.agents/backend/INIT.md +11 -0
- package/core/templates/.agents/backend/JOBS.md +12 -1
- package/core/templates/.agents/backend/LOGIC.md +12 -1
- package/core/templates/.agents/backend/TESTING.md +12 -1
- package/core/templates/.agents/client/ACCESSIBILITY.md +12 -1
- package/core/templates/.agents/client/FORMS.md +12 -1
- package/core/templates/.agents/client/LOGIC.md +12 -1
- package/core/templates/.agents/client/ROUTING.md +12 -1
- package/core/templates/.agents/client/TESTING.md +12 -1
- package/core/templates/.agents/client/UI.md +12 -1
- package/core/templates/.agents/shared/SECURITY.md +12 -1
- package/core/workflow/complete.js +99 -5
- package/lib/questions-flow.js +13 -1
- package/lib/steps.js +13 -1
- package/lib/ui.js +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,7 +93,7 @@ You and agents co-build - each owning a defined part of the codebase. Agent task
|
|
|
93
93
|
Next.js - Angular - Vue/Nuxt - SvelteKit - Vite+React - Remix
|
|
94
94
|
|
|
95
95
|
### Backend (separate)
|
|
96
|
-
Express - NestJS - Fastify - FastAPI - Django
|
|
96
|
+
Express - NestJS - Fastify - FastAPI - Django - Laravel - Rails
|
|
97
97
|
|
|
98
98
|
Each framework has a dedicated scaffold instruction file in `.frameworks/client/` and `.frameworks/backend/` - agents read these before scaffolding to ensure files land in the correct location.
|
|
99
99
|
|
|
@@ -281,6 +281,22 @@ On completion, scope is validated and work merges into `main`. The final `main`
|
|
|
281
281
|
}
|
|
282
282
|
```
|
|
283
283
|
|
|
284
|
-
**Status values:** `null` (never launched) - `ACTIVE` (running) - `MISSING` (worktree deleted without completing)
|
|
284
|
+
**Status values:** `null` (never launched) - `ACTIVE` (running) - `COMPLETED` (merged into main) - `MISSING` (worktree deleted without completing)
|
|
285
285
|
|
|
286
286
|
Managed entirely by `agent.js` and `complete.js`. Never edit manually.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## What's new in v1.1.0
|
|
291
|
+
|
|
292
|
+
**Init flow**
|
|
293
|
+
- Step counter (`Step N of 12`) shown throughout the configuration flow
|
|
294
|
+
- Back-navigation fully wired — go back to any previous step and resume without re-answering everything
|
|
295
|
+
|
|
296
|
+
**After merge**
|
|
297
|
+
- `npm run complete` now surfaces the next recommended agent explicitly based on tracking state
|
|
298
|
+
- `start:client` script written into `package.json` after `client/UI` merges
|
|
299
|
+
- `start:backend` script written into `package.json` after `backend/INIT` merges
|
|
300
|
+
|
|
301
|
+
**Agent templates**
|
|
302
|
+
- Every agent now includes a `Session Close` block — explicit next-step instructions after Definition of Done
|
|
@@ -256,4 +256,15 @@ An API task is complete when:
|
|
|
256
256
|
- [ ] No business logic exists inside controllers
|
|
257
257
|
- [ ] No existing endpoints outside task scope are affected
|
|
258
258
|
- [ ] Code follows `{{FRAMEWORK}}` idiomatic controller patterns
|
|
259
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
259
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Session Close
|
|
264
|
+
|
|
265
|
+
When all Definition of Done items are checked:
|
|
266
|
+
|
|
267
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
268
|
+
2. Run: `npm run complete`
|
|
269
|
+
|
|
270
|
+
**Next recommended agent:** backend/AUTH
|
|
@@ -243,4 +243,15 @@ An auth task is complete when:
|
|
|
243
243
|
- [ ] Authentication and authorization are implemented as distinct units
|
|
244
244
|
- [ ] No auth logic outside task scope is affected
|
|
245
245
|
- [ ] Code follows `{{FRAMEWORK}}` and `{{AUTH}}` idiomatic patterns
|
|
246
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
246
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Session Close
|
|
251
|
+
|
|
252
|
+
When all Definition of Done items are checked:
|
|
253
|
+
|
|
254
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
255
|
+
2. Run: `npm run complete`
|
|
256
|
+
|
|
257
|
+
**Next recommended agent:** backend/DB
|
|
@@ -254,4 +254,15 @@ A DB task is complete when:
|
|
|
254
254
|
- [ ] Shared entity types exist in `CONTRACTS.md` - none defined locally
|
|
255
255
|
- [ ] Soft deletes are explicitly declared if used
|
|
256
256
|
- [ ] Code follows `{{ORM}}` idiomatic patterns
|
|
257
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
257
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Session Close
|
|
262
|
+
|
|
263
|
+
When all Definition of Done items are checked:
|
|
264
|
+
|
|
265
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
266
|
+
2. Run: `npm run complete`
|
|
267
|
+
|
|
268
|
+
**Next recommended agent:** backend/LOGIC
|
|
@@ -250,4 +250,15 @@ An events task is complete when:
|
|
|
250
250
|
- [ ] Webhook token validation is delegated to AUTH.md - not implemented here
|
|
251
251
|
- [ ] No event logic outside task scope is affected
|
|
252
252
|
- [ ] Code follows `{{FRAMEWORK}}` idiomatic event patterns
|
|
253
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
253
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Session Close
|
|
258
|
+
|
|
259
|
+
When all Definition of Done items are checked:
|
|
260
|
+
|
|
261
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
262
|
+
2. Run: `npm run complete`
|
|
263
|
+
|
|
264
|
+
**Next recommended agent:** backend/JOBS
|
|
@@ -237,3 +237,14 @@ An INIT task is complete when:
|
|
|
237
237
|
- [ ] No actual environment variable values exist anywhere in the codebase
|
|
238
238
|
- [ ] No implementation exists in any shell file
|
|
239
239
|
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Session Close
|
|
244
|
+
|
|
245
|
+
When all Definition of Done items are checked:
|
|
246
|
+
|
|
247
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
248
|
+
2. Run: `npm run complete`
|
|
249
|
+
|
|
250
|
+
**Next recommended agent:** backend/API
|
|
@@ -253,4 +253,15 @@ A jobs task is complete when:
|
|
|
253
253
|
- [ ] No job is triggered synchronously inside the request/response cycle
|
|
254
254
|
- [ ] Job payload types exist in `CONTRACTS.md` - none defined locally
|
|
255
255
|
- [ ] Code follows `{{FRAMEWORK}}` idiomatic scheduling and queue patterns
|
|
256
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
256
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Session Close
|
|
261
|
+
|
|
262
|
+
When all Definition of Done items are checked:
|
|
263
|
+
|
|
264
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
265
|
+
2. Run: `npm run complete`
|
|
266
|
+
|
|
267
|
+
**Next recommended agent:** backend/TESTING
|
|
@@ -288,4 +288,15 @@ A backend logic task is complete when:
|
|
|
288
288
|
- [ ] No unrelated domain rules bundled into the same service
|
|
289
289
|
- [ ] No service logic outside task scope is affected
|
|
290
290
|
- [ ] Code follows `{{FRAMEWORK}}` idiomatic service patterns
|
|
291
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
291
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Session Close
|
|
296
|
+
|
|
297
|
+
When all Definition of Done items are checked:
|
|
298
|
+
|
|
299
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
300
|
+
2. Run: `npm run complete`
|
|
301
|
+
|
|
302
|
+
**Next recommended agent:** backend/EVENTS
|
|
@@ -263,4 +263,15 @@ A backend testing task is complete when:
|
|
|
263
263
|
- [ ] No existing passing tests are broken
|
|
264
264
|
- [ ] No implementation changes were made as part of this task
|
|
265
265
|
- [ ] Code follows `{{FRAMEWORK}}` idiomatic test patterns
|
|
266
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
266
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Session Close
|
|
271
|
+
|
|
272
|
+
When all Definition of Done items are checked:
|
|
273
|
+
|
|
274
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
275
|
+
2. Run: `npm run complete`
|
|
276
|
+
|
|
277
|
+
**Next recommended agent:** shared/SECURITY
|
|
@@ -263,4 +263,15 @@ An accessibility task is complete when:
|
|
|
263
263
|
- [ ] Semantic HTML is used correctly - ARIA supplements, not replaces
|
|
264
264
|
- [ ] No visual or behavioral regressions introduced
|
|
265
265
|
- [ ] Code follows `{{FRAMEWORK}}` idiomatic accessibility patterns
|
|
266
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
266
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Session Close
|
|
271
|
+
|
|
272
|
+
When all Definition of Done items are checked:
|
|
273
|
+
|
|
274
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
275
|
+
2. Run: `npm run complete`
|
|
276
|
+
|
|
277
|
+
**Next recommended agent:** shared/SECURITY (or backend agents if not started)
|
|
@@ -231,4 +231,15 @@ A form task is complete when:
|
|
|
231
231
|
- [ ] Form state is local unless explicitly justified otherwise
|
|
232
232
|
- [ ] No payload types redeclared locally
|
|
233
233
|
- [ ] Code follows `{{FRAMEWORK}}` idiomatic form patterns
|
|
234
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
234
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Session Close
|
|
239
|
+
|
|
240
|
+
When all Definition of Done items are checked:
|
|
241
|
+
|
|
242
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
243
|
+
2. Run: `npm run complete`
|
|
244
|
+
|
|
245
|
+
**Next recommended agent:** client/ROUTING
|
|
@@ -274,4 +274,15 @@ A client logic task is complete when:
|
|
|
274
274
|
- [ ] State and data fetching concerns are properly separated
|
|
275
275
|
- [ ] Environment-specific values derive from config - nothing hardcoded
|
|
276
276
|
- [ ] Code follows `{{FRAMEWORK}}` and `{{STATE}}` idiomatic patterns
|
|
277
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
277
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Session Close
|
|
282
|
+
|
|
283
|
+
When all Definition of Done items are checked:
|
|
284
|
+
|
|
285
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
286
|
+
2. Run: `npm run complete`
|
|
287
|
+
|
|
288
|
+
**Next recommended agent:** client/FORMS (or backend/INIT if backend not yet started)
|
|
@@ -232,4 +232,15 @@ A routing task is complete when:
|
|
|
232
232
|
- [ ] No navigation logic exists inside components
|
|
233
233
|
- [ ] No existing routes outside task scope are affected
|
|
234
234
|
- [ ] Code follows `{{FRAMEWORK}}` idiomatic routing patterns
|
|
235
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
235
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Session Close
|
|
240
|
+
|
|
241
|
+
When all Definition of Done items are checked:
|
|
242
|
+
|
|
243
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
244
|
+
2. Run: `npm run complete`
|
|
245
|
+
|
|
246
|
+
**Next recommended agent:** client/TESTING
|
|
@@ -238,4 +238,15 @@ A testing task is complete when:
|
|
|
238
238
|
- [ ] No existing passing tests are broken
|
|
239
239
|
- [ ] No implementation changes were made as part of this task
|
|
240
240
|
- [ ] Code follows `{{FRAMEWORK}}` idiomatic test patterns
|
|
241
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
241
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Session Close
|
|
246
|
+
|
|
247
|
+
When all Definition of Done items are checked:
|
|
248
|
+
|
|
249
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
250
|
+
2. Run: `npm run complete`
|
|
251
|
+
|
|
252
|
+
**Next recommended agent:** client/ACCESSIBILITY
|
|
@@ -223,4 +223,15 @@ A UI task is complete when:
|
|
|
223
223
|
- [ ] Shared types consumed from `CONTRACTS.md` - none redeclared locally
|
|
224
224
|
- [ ] Existing components outside task scope are unaffected
|
|
225
225
|
- [ ] Code follows `{{FRAMEWORK}}` and `{{UI_LIBRARY}}` idiomatic patterns
|
|
226
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
226
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Session Close
|
|
231
|
+
|
|
232
|
+
When all Definition of Done items are checked:
|
|
233
|
+
|
|
234
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
235
|
+
2. Run: `npm run complete`
|
|
236
|
+
|
|
237
|
+
**Next recommended agent:** client/LOGIC
|
|
@@ -283,4 +283,15 @@ A security task is complete when:
|
|
|
283
283
|
- [ ] No sensitive data is exposed unnecessarily across boundaries
|
|
284
284
|
- [ ] No secrets, tokens, or keys found in source code
|
|
285
285
|
- [ ] No fixes were implemented directly by this agent
|
|
286
|
-
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
286
|
+
- [ ] Pre-flight checks all passed and documented if any flags were raised
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Session Close
|
|
291
|
+
|
|
292
|
+
When all Definition of Done items are checked:
|
|
293
|
+
|
|
294
|
+
1. Mark TASK.md complete: change `[ ] COMPLETED` to `[x] COMPLETED` at the top of TASK.md
|
|
295
|
+
2. Run: `npm run complete`
|
|
296
|
+
|
|
297
|
+
**Next recommended agent:** npm run complete — project is secured. Consider backend or deploy when ready.
|
|
@@ -391,6 +391,58 @@ const main = async () => {
|
|
|
391
391
|
}
|
|
392
392
|
} catch { /* best-effort */ }
|
|
393
393
|
|
|
394
|
+
// ── Write start:client / start:backend into root package.json ───────────────
|
|
395
|
+
|
|
396
|
+
try {
|
|
397
|
+
const CLIENT_START = {
|
|
398
|
+
'Next.js': 'npm run dev',
|
|
399
|
+
'Nuxt': 'npm run dev',
|
|
400
|
+
'SvelteKit': 'npm run dev',
|
|
401
|
+
'Remix': 'npm run dev',
|
|
402
|
+
'Vite+React': 'npm run dev',
|
|
403
|
+
'Angular': 'npx ng serve',
|
|
404
|
+
};
|
|
405
|
+
const BACKEND_START = {
|
|
406
|
+
'NestJS': 'npm run start:dev',
|
|
407
|
+
'Express': 'npm run dev',
|
|
408
|
+
'Fastify': 'npm run dev',
|
|
409
|
+
'Django': 'python manage.py runserver',
|
|
410
|
+
'FastAPI': 'uvicorn main:app --reload',
|
|
411
|
+
'Laravel': 'php artisan serve',
|
|
412
|
+
'Rails': 'bin/rails server',
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
const pkgPath = path.join(ROOT, 'package.json');
|
|
416
|
+
if (fs.existsSync(pkgPath)) {
|
|
417
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
418
|
+
if (!pkg.scripts) pkg.scripts = {};
|
|
419
|
+
|
|
420
|
+
const parts = branchName.split('/');
|
|
421
|
+
const mergedScope = parts.length >= 4 ? parts[1] : null;
|
|
422
|
+
const mergedAgent = parts.length >= 4 ? parts[2].toUpperCase() : null;
|
|
423
|
+
|
|
424
|
+
if (mergedScope === 'client' && mergedAgent === 'UI') {
|
|
425
|
+
const fw = config.client && config.client.framework;
|
|
426
|
+
const cmd = CLIENT_START[fw];
|
|
427
|
+
if (cmd && !pkg.scripts['start:client']) {
|
|
428
|
+
pkg.scripts['start:client'] = cmd;
|
|
429
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
430
|
+
console.log(` ${green('✓')} start:client added to package.json (${cmd})`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (mergedScope === 'backend' && mergedAgent === 'INIT') {
|
|
435
|
+
const fw = config.backend && config.backend.framework;
|
|
436
|
+
const cmd = BACKEND_START[fw];
|
|
437
|
+
if (cmd && !pkg.scripts['start:backend']) {
|
|
438
|
+
pkg.scripts['start:backend'] = cmd;
|
|
439
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
440
|
+
console.log(` ${green('✓')} start:backend added to package.json (${cmd})`);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
} catch { /* best-effort */ }
|
|
445
|
+
|
|
394
446
|
// ── Update scaffold flags ──────────────────────────────────────────────────
|
|
395
447
|
|
|
396
448
|
try {
|
|
@@ -442,11 +494,53 @@ const main = async () => {
|
|
|
442
494
|
if (_agent) console.log(` ${dim('Agent')} : ${green(_agent)} ${dim('(' + _scope + ')')}`);
|
|
443
495
|
if (_task) console.log(` ${dim('Task')} : ${dim(_task)}`);
|
|
444
496
|
console.log(` ${dim('Branch')} : ${green(branchName)} merged into ${green('main')}\n`);
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
497
|
+
|
|
498
|
+
// ── Derive next step from tracking ──────────────────────────────────────────
|
|
499
|
+
const AGENT_ORDER = {
|
|
500
|
+
client: ['UI', 'LOGIC', 'FORMS', 'ROUTING', 'TESTING', 'ACCESSIBILITY'],
|
|
501
|
+
backend: ['INIT', 'API', 'LOGIC', 'AUTH', 'DB', 'TESTING', 'EVENTS', 'JOBS'],
|
|
502
|
+
shared: ['SECURITY'],
|
|
503
|
+
};
|
|
504
|
+
const SCOPE_ORDER = ['client', 'backend', 'shared'];
|
|
505
|
+
|
|
506
|
+
try {
|
|
507
|
+
const _tracking = guards.loadTracking(ROOT, config);
|
|
508
|
+
|
|
509
|
+
const findNextInScope = (scope) => {
|
|
510
|
+
const order = AGENT_ORDER[scope] || [];
|
|
511
|
+
for (const a of order) {
|
|
512
|
+
const slot = (_tracking[scope] || {})[a];
|
|
513
|
+
if (!slot || (slot.status !== 'COMPLETED' && slot.status !== 'ACTIVE')) return a;
|
|
514
|
+
}
|
|
515
|
+
return null;
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
let nextScope = null;
|
|
519
|
+
let nextAgent = null;
|
|
520
|
+
|
|
521
|
+
const scopesToCheck = [_scope, ...SCOPE_ORDER.filter(s => s !== _scope)];
|
|
522
|
+
for (const s of scopesToCheck) {
|
|
523
|
+
const n = findNextInScope(s);
|
|
524
|
+
if (n) { nextScope = s; nextAgent = n; break; }
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
separator();
|
|
528
|
+
console.log(`\n ${bold('What to do next:')}`);
|
|
529
|
+
|
|
530
|
+
if (nextAgent) {
|
|
531
|
+
console.log(`\n ${green('→')} ${bold(nextAgent)} ${dim('(' + nextScope + ')')}`);
|
|
532
|
+
console.log(`\n ${cyan('npm run agent')}`);
|
|
533
|
+
console.log(` ${dim('Select: ' + nextScope + ' → ' + nextAgent)}`);
|
|
534
|
+
} else {
|
|
535
|
+
console.log(`\n ${cyan('npm run agent')}`);
|
|
536
|
+
}
|
|
537
|
+
} catch {
|
|
538
|
+
separator();
|
|
539
|
+
console.log(`\n ${bold('What to do next:')}\n`);
|
|
540
|
+
console.log(` ${cyan('npm run agent')}`);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
console.log('\n');
|
|
450
544
|
|
|
451
545
|
|
|
452
546
|
// ── Backend/INIT launch prompt (if user chose 'after' during LOGIC session) ──
|
package/lib/questions-flow.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// ── Imports ───────────────────────────────────────────────────────────────────
|
|
4
4
|
|
|
5
|
-
const { dim, bold, blue, green, cyan, separator, arrowSelect, arrowConfirm, selectRequired, selectOptional } = require('./ui');
|
|
5
|
+
const { dim, bold, blue, green, cyan, separator, arrowSelect, arrowConfirm, selectRequired, selectOptional, stepHeader } = require('./ui');
|
|
6
6
|
const { BACK, RESTART } = require('./steps');
|
|
7
7
|
const {
|
|
8
8
|
CLIENT_FRAMEWORKS, BACKEND_FRAMEWORKS, FRAMEWORK_VERSION_FALLBACK,
|
|
@@ -21,6 +21,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
21
21
|
{
|
|
22
22
|
name: 'clientFw',
|
|
23
23
|
run: async (machine, answers) => {
|
|
24
|
+
stepHeader(1, 12);
|
|
24
25
|
console.log(`\n${bold(blue('Client configuration'))}`);
|
|
25
26
|
return await selectRequired('* Client framework (required):', CLIENT_FRAMEWORKS, machine, 0);
|
|
26
27
|
},
|
|
@@ -30,6 +31,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
30
31
|
{
|
|
31
32
|
name: 'clientFwVersion',
|
|
32
33
|
run: async (machine, answers) => {
|
|
34
|
+
stepHeader(2, 12);
|
|
33
35
|
const fw = answers.clientFw;
|
|
34
36
|
const versions = await fetchLatestVersions(fw.value) || FRAMEWORK_VERSION_FALLBACK[fw.value] || [];
|
|
35
37
|
if (!versions.length) return null; // skip silently
|
|
@@ -56,6 +58,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
56
58
|
{
|
|
57
59
|
name: 'clientState',
|
|
58
60
|
run: async (machine, answers) => {
|
|
61
|
+
stepHeader(3, 12);
|
|
59
62
|
const opts = STATE_OPTIONS[answers.clientFw.value] || [];
|
|
60
63
|
return await selectOptional('State management:', opts, machine, 2);
|
|
61
64
|
},
|
|
@@ -65,6 +68,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
65
68
|
{
|
|
66
69
|
name: 'clientUi',
|
|
67
70
|
run: async (machine, answers) => {
|
|
71
|
+
stepHeader(4, 12);
|
|
68
72
|
const opts = UI_OPTIONS[answers.clientFw.value] || [];
|
|
69
73
|
return await selectOptional('UI library:', opts, machine, 3);
|
|
70
74
|
},
|
|
@@ -74,6 +78,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
74
78
|
{
|
|
75
79
|
name: 'clientStyle',
|
|
76
80
|
run: async (machine, answers) => {
|
|
81
|
+
stepHeader(5, 12);
|
|
77
82
|
return await selectOptional('Styling:', STYLING_OPTIONS, machine, 4);
|
|
78
83
|
},
|
|
79
84
|
},
|
|
@@ -82,6 +87,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
82
87
|
{
|
|
83
88
|
name: 'useIntegratedBackend',
|
|
84
89
|
run: async (machine, answers) => {
|
|
90
|
+
stepHeader(6, 12);
|
|
85
91
|
const fw = answers.clientFw;
|
|
86
92
|
if (!fw.integratedBackend) return false; // skip — not applicable
|
|
87
93
|
|
|
@@ -98,6 +104,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
98
104
|
{
|
|
99
105
|
name: 'backendFwObj',
|
|
100
106
|
run: async (machine, answers) => {
|
|
107
|
+
stepHeader(7, 12);
|
|
101
108
|
if (answers.useIntegratedBackend) return null; // skip
|
|
102
109
|
|
|
103
110
|
separator();
|
|
@@ -121,6 +128,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
121
128
|
{
|
|
122
129
|
name: 'backendFwVersion',
|
|
123
130
|
run: async (machine, answers) => {
|
|
131
|
+
stepHeader(8, 12);
|
|
124
132
|
const fwObj = answers.backendFwObj;
|
|
125
133
|
if (!fwObj) return null; // skip — no backend selected
|
|
126
134
|
|
|
@@ -147,6 +155,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
147
155
|
{
|
|
148
156
|
name: 'backendDb',
|
|
149
157
|
run: async (machine, answers) => {
|
|
158
|
+
stepHeader(9, 12);
|
|
150
159
|
if (!answers.backendFwObj) return null;
|
|
151
160
|
return await selectOptional('Database type:', DB_OPTIONS, machine, 8);
|
|
152
161
|
},
|
|
@@ -156,6 +165,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
156
165
|
{
|
|
157
166
|
name: 'backendOrm',
|
|
158
167
|
run: async (machine, answers) => {
|
|
168
|
+
stepHeader(10, 12);
|
|
159
169
|
const { backendFwObj, backendDb } = answers;
|
|
160
170
|
if (!backendFwObj || !backendDb) return null;
|
|
161
171
|
const ormChoices = ORM_OPTIONS_BY_DB[backendDb] || ORM_OPTIONS[backendFwObj.value] || [];
|
|
@@ -167,6 +177,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
167
177
|
{
|
|
168
178
|
name: 'backendAuth',
|
|
169
179
|
run: async (machine, answers) => {
|
|
180
|
+
stepHeader(11, 12);
|
|
170
181
|
const { backendFwObj } = answers;
|
|
171
182
|
if (!backendFwObj) return null;
|
|
172
183
|
return await selectOptional('Auth strategy:', AUTH_OPTIONS[backendFwObj.value] || [], machine, 10);
|
|
@@ -177,6 +188,7 @@ const buildStepDefs = (IDE_CANDIDATES) => [
|
|
|
177
188
|
{
|
|
178
189
|
name: 'ideChoice',
|
|
179
190
|
run: async (machine, answers) => {
|
|
191
|
+
stepHeader(12, 12);
|
|
180
192
|
separator();
|
|
181
193
|
console.log(`\n${bold(blue('Environment'))}`);
|
|
182
194
|
|
package/lib/steps.js
CHANGED
|
@@ -103,13 +103,25 @@ const runQuestions = async (stepDefs, machine) => {
|
|
|
103
103
|
if (result === RESTART) return RESTART;
|
|
104
104
|
|
|
105
105
|
if (result === BACK) {
|
|
106
|
-
if (i === 0) return RESTART; // nowhere to go back
|
|
106
|
+
if (i === 0) return RESTART; // nowhere to go back from step 0
|
|
107
|
+
machine.enterBackNav(i); // record where back-nav started
|
|
107
108
|
const popped = machine.pop();
|
|
108
109
|
if (popped) delete answers[popped.stepName];
|
|
109
110
|
i--;
|
|
110
111
|
continue;
|
|
111
112
|
}
|
|
112
113
|
|
|
114
|
+
if (result === CONTINUE) {
|
|
115
|
+
// User chose to resume — skip forward to where they first pressed Back
|
|
116
|
+
const resumeTarget = machine.resumeIndex ?? i + 1;
|
|
117
|
+
machine.exitBackNav();
|
|
118
|
+
i = resumeTarget;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Normal answer — if re-answering during back-nav, exit back-nav mode
|
|
123
|
+
if (machine.inBackNav) machine.exitBackNav();
|
|
124
|
+
|
|
113
125
|
machine.push(i, def.name, result);
|
|
114
126
|
answers[def.name] = result;
|
|
115
127
|
i++;
|
package/lib/ui.js
CHANGED
|
@@ -109,6 +109,13 @@ const renderTrajectoryLines = (lines) => {
|
|
|
109
109
|
});
|
|
110
110
|
};
|
|
111
111
|
|
|
112
|
+
// ── Step progress header ─────────────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
const stepHeader = (stepIndex, totalSteps) => {
|
|
115
|
+
console.log(`
|
|
116
|
+
${dim(`Step ${stepIndex} of ${totalSteps}`)}`);
|
|
117
|
+
};
|
|
118
|
+
|
|
112
119
|
// ── Step selection helpers ────────────────────────────────────────────────────
|
|
113
120
|
|
|
114
121
|
const { BACK, RESTART } = require('./steps');
|
|
@@ -150,6 +157,7 @@ const selectOptional = async (prompt, items, stepMachine, stepIndex) => {
|
|
|
150
157
|
// ── Exports ───────────────────────────────────────────────────────────────────
|
|
151
158
|
|
|
152
159
|
module.exports = {
|
|
160
|
+
stepHeader,
|
|
153
161
|
c, bold, green, yellow, dim, cyan, blue, red,
|
|
154
162
|
rl, ask,
|
|
155
163
|
arrowSelect, arrowConfirm,
|
package/package.json
CHANGED