agileflow 2.51.0 → 2.55.0
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 +82 -460
- package/package.json +18 -3
- package/scripts/agileflow-configure.js +134 -63
- package/scripts/agileflow-welcome.js +161 -31
- package/scripts/generators/agent-registry.js +2 -2
- package/scripts/generators/command-registry.js +6 -6
- package/scripts/generators/index.js +2 -6
- package/scripts/generators/inject-babysit.js +9 -2
- package/scripts/generators/inject-help.js +3 -1
- package/scripts/generators/inject-readme.js +7 -3
- package/scripts/generators/skill-registry.js +5 -5
- package/scripts/get-env.js +13 -12
- package/scripts/obtain-context.js +79 -26
- package/scripts/session-coordinator.sh +232 -0
- package/scripts/session-manager.js +512 -0
- package/src/core/agents/orchestrator.md +275 -0
- package/src/core/commands/adr.md +38 -16
- package/src/core/commands/agent.md +39 -22
- package/src/core/commands/assign.md +17 -0
- package/src/core/commands/auto.md +60 -46
- package/src/core/commands/babysit.md +302 -637
- package/src/core/commands/baseline.md +20 -0
- package/src/core/commands/blockers.md +33 -48
- package/src/core/commands/board.md +19 -0
- package/src/core/commands/changelog.md +20 -0
- package/src/core/commands/ci.md +17 -0
- package/src/core/commands/context.md +43 -40
- package/src/core/commands/debt.md +76 -45
- package/src/core/commands/deploy.md +20 -0
- package/src/core/commands/deps.md +40 -46
- package/src/core/commands/diagnose.md +24 -18
- package/src/core/commands/docs.md +18 -0
- package/src/core/commands/epic.md +31 -0
- package/src/core/commands/feedback.md +33 -21
- package/src/core/commands/handoff.md +29 -0
- package/src/core/commands/help.md +16 -7
- package/src/core/commands/impact.md +31 -61
- package/src/core/commands/metrics.md +17 -35
- package/src/core/commands/packages.md +21 -0
- package/src/core/commands/pr.md +15 -0
- package/src/core/commands/readme-sync.md +42 -9
- package/src/core/commands/research.md +58 -11
- package/src/core/commands/retro.md +42 -50
- package/src/core/commands/review.md +22 -27
- package/src/core/commands/session/end.md +53 -297
- package/src/core/commands/session/history.md +38 -257
- package/src/core/commands/session/init.md +44 -446
- package/src/core/commands/session/new.md +152 -0
- package/src/core/commands/session/resume.md +51 -447
- package/src/core/commands/session/status.md +32 -244
- package/src/core/commands/sprint.md +33 -0
- package/src/core/commands/status.md +18 -0
- package/src/core/commands/story-validate.md +32 -0
- package/src/core/commands/story.md +21 -6
- package/src/core/commands/template.md +18 -0
- package/src/core/commands/tests.md +22 -0
- package/src/core/commands/update.md +72 -58
- package/src/core/commands/validate-expertise.md +25 -37
- package/src/core/commands/velocity.md +33 -74
- package/src/core/commands/verify.md +16 -0
- package/src/core/experts/documentation/expertise.yaml +16 -2
- package/src/core/skills/agileflow-retro-facilitator/SKILL.md +57 -219
- package/src/core/skills/agileflow-retro-facilitator/cookbook/4ls.md +86 -0
- package/src/core/skills/agileflow-retro-facilitator/cookbook/glad-sad-mad.md +79 -0
- package/src/core/skills/agileflow-retro-facilitator/cookbook/start-stop-continue.md +142 -0
- package/src/core/skills/agileflow-retro-facilitator/prompts/action-items.md +83 -0
- package/src/core/skills/writing-skills/SKILL.md +352 -0
- package/src/core/skills/writing-skills/testing-skills-with-subagents.md +232 -0
- package/tools/cli/agileflow-cli.js +4 -2
- package/tools/cli/commands/config.js +20 -13
- package/tools/cli/commands/doctor.js +25 -9
- package/tools/cli/commands/list.js +10 -6
- package/tools/cli/commands/setup.js +54 -3
- package/tools/cli/commands/status.js +6 -8
- package/tools/cli/commands/uninstall.js +5 -5
- package/tools/cli/commands/update.js +51 -7
- package/tools/cli/installers/core/installer.js +8 -4
- package/tools/cli/installers/ide/_base-ide.js +3 -1
- package/tools/cli/installers/ide/claude-code.js +3 -7
- package/tools/cli/installers/ide/codex.js +440 -0
- package/tools/cli/installers/ide/manager.js +2 -6
- package/tools/cli/lib/content-injector.js +3 -3
- package/tools/cli/lib/docs-setup.js +3 -2
- package/tools/cli/lib/npm-utils.js +3 -3
- package/tools/cli/lib/ui.js +7 -7
- package/tools/cli/lib/version-checker.js +3 -3
- package/tools/postinstall.js +2 -3
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
|
|
14
14
|
const fs = require('fs');
|
|
15
15
|
const path = require('path');
|
|
16
|
-
const { execSync } = require('child_process');
|
|
16
|
+
const { execSync, spawnSync } = require('child_process');
|
|
17
|
+
|
|
18
|
+
// Session manager path (relative to script location)
|
|
19
|
+
const SESSION_MANAGER_PATH = path.join(__dirname, 'session-manager.js');
|
|
17
20
|
|
|
18
21
|
// ANSI color codes
|
|
19
22
|
const c = {
|
|
@@ -39,9 +42,16 @@ const c = {
|
|
|
39
42
|
|
|
40
43
|
// Box drawing characters
|
|
41
44
|
const box = {
|
|
42
|
-
tl: '╭',
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
tl: '╭',
|
|
46
|
+
tr: '╮',
|
|
47
|
+
bl: '╰',
|
|
48
|
+
br: '╯',
|
|
49
|
+
h: '─',
|
|
50
|
+
v: '│',
|
|
51
|
+
lT: '├',
|
|
52
|
+
rT: '┤',
|
|
53
|
+
tT: '┬',
|
|
54
|
+
bT: '┴',
|
|
45
55
|
cross: '┼',
|
|
46
56
|
};
|
|
47
57
|
|
|
@@ -70,7 +80,9 @@ function getProjectInfo(rootDir) {
|
|
|
70
80
|
|
|
71
81
|
// Get package info
|
|
72
82
|
try {
|
|
73
|
-
const pkg = JSON.parse(
|
|
83
|
+
const pkg = JSON.parse(
|
|
84
|
+
fs.readFileSync(path.join(rootDir, 'packages/cli/package.json'), 'utf8')
|
|
85
|
+
);
|
|
74
86
|
info.version = pkg.version || info.version;
|
|
75
87
|
} catch (e) {
|
|
76
88
|
try {
|
|
@@ -83,7 +95,10 @@ function getProjectInfo(rootDir) {
|
|
|
83
95
|
try {
|
|
84
96
|
info.branch = execSync('git branch --show-current', { cwd: rootDir, encoding: 'utf8' }).trim();
|
|
85
97
|
info.commit = execSync('git rev-parse --short HEAD', { cwd: rootDir, encoding: 'utf8' }).trim();
|
|
86
|
-
info.lastCommit = execSync('git log -1 --format="%s"', {
|
|
98
|
+
info.lastCommit = execSync('git log -1 --format="%s"', {
|
|
99
|
+
cwd: rootDir,
|
|
100
|
+
encoding: 'utf8',
|
|
101
|
+
}).trim();
|
|
87
102
|
} catch (e) {}
|
|
88
103
|
|
|
89
104
|
// Get status info
|
|
@@ -155,7 +170,7 @@ function runArchival(rootDir) {
|
|
|
155
170
|
execSync('bash scripts/archive-completed-stories.sh', {
|
|
156
171
|
cwd: rootDir,
|
|
157
172
|
encoding: 'utf8',
|
|
158
|
-
stdio: 'pipe'
|
|
173
|
+
stdio: 'pipe',
|
|
159
174
|
});
|
|
160
175
|
result.archived = toArchiveCount;
|
|
161
176
|
result.remaining -= toArchiveCount;
|
|
@@ -201,6 +216,60 @@ function clearActiveCommands(rootDir) {
|
|
|
201
216
|
return result;
|
|
202
217
|
}
|
|
203
218
|
|
|
219
|
+
function checkParallelSessions(rootDir) {
|
|
220
|
+
const result = {
|
|
221
|
+
available: false,
|
|
222
|
+
registered: false,
|
|
223
|
+
otherActive: 0,
|
|
224
|
+
currentId: null,
|
|
225
|
+
cleaned: 0,
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
// Check if session manager exists
|
|
230
|
+
const managerPath = path.join(rootDir, '.agileflow', 'scripts', 'session-manager.js');
|
|
231
|
+
if (!fs.existsSync(managerPath) && !fs.existsSync(SESSION_MANAGER_PATH)) {
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
result.available = true;
|
|
236
|
+
|
|
237
|
+
// Try to register current session and get status
|
|
238
|
+
const scriptPath = fs.existsSync(managerPath) ? managerPath : SESSION_MANAGER_PATH;
|
|
239
|
+
|
|
240
|
+
// Register this session
|
|
241
|
+
try {
|
|
242
|
+
const registerOutput = execSync(`node "${scriptPath}" register`, {
|
|
243
|
+
cwd: rootDir,
|
|
244
|
+
encoding: 'utf8',
|
|
245
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
246
|
+
});
|
|
247
|
+
const registerData = JSON.parse(registerOutput);
|
|
248
|
+
result.registered = true;
|
|
249
|
+
result.currentId = registerData.id;
|
|
250
|
+
} catch (e) {
|
|
251
|
+
// Registration failed, continue anyway
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Get count of other active sessions
|
|
255
|
+
try {
|
|
256
|
+
const countOutput = execSync(`node "${scriptPath}" count`, {
|
|
257
|
+
cwd: rootDir,
|
|
258
|
+
encoding: 'utf8',
|
|
259
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
260
|
+
});
|
|
261
|
+
const countData = JSON.parse(countOutput);
|
|
262
|
+
result.otherActive = countData.count || 0;
|
|
263
|
+
} catch (e) {
|
|
264
|
+
// Count failed
|
|
265
|
+
}
|
|
266
|
+
} catch (e) {
|
|
267
|
+
// Session system not available
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
|
|
204
273
|
function checkPreCompact(rootDir) {
|
|
205
274
|
const result = { configured: false, scriptExists: false, version: null, outdated: false };
|
|
206
275
|
|
|
@@ -258,7 +327,7 @@ function getFeatureVersions(rootDir) {
|
|
|
258
327
|
hooks: { version: null, outdated: false },
|
|
259
328
|
archival: { version: null, outdated: false },
|
|
260
329
|
statusline: { version: null, outdated: false },
|
|
261
|
-
precompact: { version: null, outdated: false }
|
|
330
|
+
precompact: { version: null, outdated: false },
|
|
262
331
|
};
|
|
263
332
|
|
|
264
333
|
// Minimum compatible versions for each feature
|
|
@@ -266,7 +335,7 @@ function getFeatureVersions(rootDir) {
|
|
|
266
335
|
hooks: '2.35.0',
|
|
267
336
|
archival: '2.35.0',
|
|
268
337
|
statusline: '2.35.0',
|
|
269
|
-
precompact: '2.40.0'
|
|
338
|
+
precompact: '2.40.0', // Multi-command support
|
|
270
339
|
};
|
|
271
340
|
|
|
272
341
|
try {
|
|
@@ -277,7 +346,8 @@ function getFeatureVersions(rootDir) {
|
|
|
277
346
|
for (const feature of Object.keys(result)) {
|
|
278
347
|
if (metadata.features?.[feature]?.configured_version) {
|
|
279
348
|
result[feature].version = metadata.features[feature].configured_version;
|
|
280
|
-
result[feature].outdated =
|
|
349
|
+
result[feature].outdated =
|
|
350
|
+
compareVersions(result[feature].version, minVersions[feature]) < 0;
|
|
281
351
|
}
|
|
282
352
|
}
|
|
283
353
|
}
|
|
@@ -291,7 +361,8 @@ function pad(str, len, align = 'left') {
|
|
|
291
361
|
const diff = len - stripped.length;
|
|
292
362
|
if (diff <= 0) return str;
|
|
293
363
|
if (align === 'right') return ' '.repeat(diff) + str;
|
|
294
|
-
if (align === 'center')
|
|
364
|
+
if (align === 'center')
|
|
365
|
+
return ' '.repeat(Math.floor(diff / 2)) + str + ' '.repeat(Math.ceil(diff / 2));
|
|
295
366
|
return str + ' '.repeat(diff);
|
|
296
367
|
}
|
|
297
368
|
|
|
@@ -323,7 +394,7 @@ function truncate(str, maxLen, suffix = '..') {
|
|
|
323
394
|
return str.substring(0, cutIndex) + suffix;
|
|
324
395
|
}
|
|
325
396
|
|
|
326
|
-
function formatTable(info, archival, session, precompact) {
|
|
397
|
+
function formatTable(info, archival, session, precompact, parallelSessions) {
|
|
327
398
|
const W = 58; // inner width
|
|
328
399
|
const R = W - 24; // right column width (34 chars)
|
|
329
400
|
const lines = [];
|
|
@@ -336,17 +407,20 @@ function formatTable(info, archival, session, precompact) {
|
|
|
336
407
|
return `${c.dim}${box.v}${c.reset} ${pad(leftStr, 20)} ${c.dim}${box.v}${c.reset} ${pad(rightStr, R)} ${c.dim}${box.v}${c.reset}`;
|
|
337
408
|
};
|
|
338
409
|
|
|
339
|
-
const divider = () =>
|
|
410
|
+
const divider = () =>
|
|
411
|
+
`${c.dim}${box.lT}${box.h.repeat(22)}${box.cross}${box.h.repeat(W - 22)}${box.rT}${c.reset}`;
|
|
340
412
|
const topBorder = `${c.dim}${box.tl}${box.h.repeat(22)}${box.tT}${box.h.repeat(W - 22)}${box.tr}${c.reset}`;
|
|
341
413
|
const bottomBorder = `${c.dim}${box.bl}${box.h.repeat(22)}${box.bT}${box.h.repeat(W - 22)}${box.br}${c.reset}`;
|
|
342
414
|
|
|
343
415
|
// Header (truncate branch name if too long)
|
|
344
|
-
const branchColor =
|
|
416
|
+
const branchColor =
|
|
417
|
+
info.branch === 'main' ? c.green : info.branch.startsWith('fix') ? c.red : c.cyan;
|
|
345
418
|
// Fixed parts: "agileflow " (10) + "v" (1) + version + " " (2) + " (" (2) + commit (7) + ")" (1) = 23 + version.length
|
|
346
|
-
const maxBranchLen =
|
|
347
|
-
const branchDisplay =
|
|
348
|
-
|
|
349
|
-
|
|
419
|
+
const maxBranchLen = W - 1 - 23 - info.version.length;
|
|
420
|
+
const branchDisplay =
|
|
421
|
+
info.branch.length > maxBranchLen
|
|
422
|
+
? info.branch.substring(0, maxBranchLen - 2) + '..'
|
|
423
|
+
: info.branch;
|
|
350
424
|
const header = `${c.brand}${c.bold}agileflow${c.reset} ${c.dim}v${info.version}${c.reset} ${branchColor}${branchDisplay}${c.reset} ${c.dim}(${info.commit})${c.reset}`;
|
|
351
425
|
const headerLine = `${c.dim}${box.v}${c.reset} ${pad(header, W - 1)} ${c.dim}${box.v}${c.reset}`;
|
|
352
426
|
|
|
@@ -355,10 +429,38 @@ function formatTable(info, archival, session, precompact) {
|
|
|
355
429
|
lines.push(divider());
|
|
356
430
|
|
|
357
431
|
// Stories section
|
|
358
|
-
lines.push(
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
432
|
+
lines.push(
|
|
433
|
+
row(
|
|
434
|
+
'In Progress',
|
|
435
|
+
info.wipCount > 0 ? `${info.wipCount}` : '0',
|
|
436
|
+
c.dim,
|
|
437
|
+
info.wipCount > 0 ? c.yellow : c.dim
|
|
438
|
+
)
|
|
439
|
+
);
|
|
440
|
+
lines.push(
|
|
441
|
+
row(
|
|
442
|
+
'Blocked',
|
|
443
|
+
info.blockedCount > 0 ? `${info.blockedCount}` : '0',
|
|
444
|
+
c.dim,
|
|
445
|
+
info.blockedCount > 0 ? c.red : c.dim
|
|
446
|
+
)
|
|
447
|
+
);
|
|
448
|
+
lines.push(
|
|
449
|
+
row(
|
|
450
|
+
'Ready',
|
|
451
|
+
info.readyCount > 0 ? `${info.readyCount}` : '0',
|
|
452
|
+
c.dim,
|
|
453
|
+
info.readyCount > 0 ? c.cyan : c.dim
|
|
454
|
+
)
|
|
455
|
+
);
|
|
456
|
+
lines.push(
|
|
457
|
+
row(
|
|
458
|
+
'Completed',
|
|
459
|
+
info.completedCount > 0 ? `${info.completedCount}` : '0',
|
|
460
|
+
c.dim,
|
|
461
|
+
info.completedCount > 0 ? c.green : c.dim
|
|
462
|
+
)
|
|
463
|
+
);
|
|
362
464
|
|
|
363
465
|
lines.push(divider());
|
|
364
466
|
|
|
@@ -366,16 +468,15 @@ function formatTable(info, archival, session, precompact) {
|
|
|
366
468
|
if (archival.disabled) {
|
|
367
469
|
lines.push(row('Auto-archival', 'disabled', c.dim, c.dim));
|
|
368
470
|
} else {
|
|
369
|
-
const archivalStatus =
|
|
370
|
-
? `archived ${archival.archived} stories`
|
|
371
|
-
|
|
372
|
-
|
|
471
|
+
const archivalStatus =
|
|
472
|
+
archival.archived > 0 ? `archived ${archival.archived} stories` : `nothing to archive`;
|
|
473
|
+
lines.push(
|
|
474
|
+
row('Auto-archival', archivalStatus, c.dim, archival.archived > 0 ? c.green : c.dim)
|
|
475
|
+
);
|
|
373
476
|
}
|
|
374
477
|
|
|
375
478
|
// Session cleanup
|
|
376
|
-
const sessionStatus = session.cleared > 0
|
|
377
|
-
? `cleared ${session.cleared} command(s)`
|
|
378
|
-
: `clean`;
|
|
479
|
+
const sessionStatus = session.cleared > 0 ? `cleared ${session.cleared} command(s)` : `clean`;
|
|
379
480
|
lines.push(row('Session state', sessionStatus, c.dim, session.cleared > 0 ? c.green : c.dim));
|
|
380
481
|
|
|
381
482
|
// PreCompact status with version check
|
|
@@ -396,11 +497,31 @@ function formatTable(info, archival, session, precompact) {
|
|
|
396
497
|
lines.push(row('Context preserve', 'not configured', c.dim, c.dim));
|
|
397
498
|
}
|
|
398
499
|
|
|
500
|
+
// Parallel sessions status
|
|
501
|
+
if (parallelSessions && parallelSessions.available) {
|
|
502
|
+
if (parallelSessions.otherActive > 0) {
|
|
503
|
+
const sessionStr = `⚠️ ${parallelSessions.otherActive} other active`;
|
|
504
|
+
lines.push(row('Sessions', sessionStr, c.dim, c.yellow));
|
|
505
|
+
} else {
|
|
506
|
+
const sessionStr = parallelSessions.currentId
|
|
507
|
+
? `✓ Session ${parallelSessions.currentId} (only)`
|
|
508
|
+
: '✓ Only session';
|
|
509
|
+
lines.push(row('Sessions', sessionStr, c.dim, c.green));
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
399
513
|
lines.push(divider());
|
|
400
514
|
|
|
401
515
|
// Current story (if any) - row() auto-truncates
|
|
402
516
|
if (info.currentStory) {
|
|
403
|
-
lines.push(
|
|
517
|
+
lines.push(
|
|
518
|
+
row(
|
|
519
|
+
'Current',
|
|
520
|
+
`${c.blue}${info.currentStory.id}${c.reset}: ${info.currentStory.title}`,
|
|
521
|
+
c.dim,
|
|
522
|
+
''
|
|
523
|
+
)
|
|
524
|
+
);
|
|
404
525
|
} else {
|
|
405
526
|
lines.push(row('Current', 'No active story', c.dim, c.dim));
|
|
406
527
|
}
|
|
@@ -420,8 +541,17 @@ function main() {
|
|
|
420
541
|
const archival = runArchival(rootDir);
|
|
421
542
|
const session = clearActiveCommands(rootDir);
|
|
422
543
|
const precompact = checkPreCompact(rootDir);
|
|
544
|
+
const parallelSessions = checkParallelSessions(rootDir);
|
|
545
|
+
|
|
546
|
+
console.log(formatTable(info, archival, session, precompact, parallelSessions));
|
|
423
547
|
|
|
424
|
-
|
|
548
|
+
// Show warning and tip if other sessions are active
|
|
549
|
+
if (parallelSessions.otherActive > 0) {
|
|
550
|
+
console.log('');
|
|
551
|
+
console.log(`${c.yellow}⚠️ Other Claude session(s) active in this repo.${c.reset}`);
|
|
552
|
+
console.log(`${c.dim} Run /agileflow:session:status to see all sessions.${c.reset}`);
|
|
553
|
+
console.log(`${c.dim} Run /agileflow:session:new to create isolated workspace.${c.reset}`);
|
|
554
|
+
}
|
|
425
555
|
}
|
|
426
556
|
|
|
427
557
|
main();
|
|
@@ -74,7 +74,7 @@ function categorizeAgent(name, description) {
|
|
|
74
74
|
'Maintenance & Optimization': ['refactor', 'performance', 'monitoring'],
|
|
75
75
|
'Documentation & Knowledge': ['documentation', 'readme-updater', 'research'],
|
|
76
76
|
'Compliance & Governance': ['compliance', 'analytics'],
|
|
77
|
-
|
|
77
|
+
Mentorship: ['mentor'],
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
for (const [category, keywords] of Object.entries(categories)) {
|
|
@@ -121,7 +121,7 @@ function scanAgents(agentsDir) {
|
|
|
121
121
|
tools,
|
|
122
122
|
model: frontmatter.model || 'haiku',
|
|
123
123
|
color: frontmatter.color || 'blue',
|
|
124
|
-
category: categorizeAgent(name, frontmatter.description || '')
|
|
124
|
+
category: categorizeAgent(name, frontmatter.description || ''),
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
127
|
|
|
@@ -47,15 +47,15 @@ function extractFrontmatter(filePath) {
|
|
|
47
47
|
function categorizeCommand(name, description) {
|
|
48
48
|
const categories = {
|
|
49
49
|
'Story Management': ['story', 'epic', 'assign', 'status'],
|
|
50
|
-
|
|
50
|
+
Development: ['verify', 'baseline', 'resume', 'session-init', 'babysit'],
|
|
51
51
|
'Quality & Testing': ['tests', 'review', 'ci'],
|
|
52
|
-
|
|
52
|
+
Documentation: ['docs', 'adr', 'readme-sync'],
|
|
53
53
|
'Planning & Metrics': ['sprint', 'velocity', 'metrics', 'board', 'deps'],
|
|
54
54
|
'Research & Strategy': ['research', 'product'],
|
|
55
55
|
'Deployment & Operations': ['deploy', 'packages'],
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
Collaboration: ['update', 'handoff', 'feedback', 'retro'],
|
|
57
|
+
Maintenance: ['debt', 'compress', 'template'],
|
|
58
|
+
System: ['setup', 'help', 'diagnose', 'auto', 'agent'],
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
for (const [category, keywords] of Object.entries(categories)) {
|
|
@@ -89,7 +89,7 @@ function scanCommands(commandsDir) {
|
|
|
89
89
|
path: filePath,
|
|
90
90
|
description: frontmatter.description || '',
|
|
91
91
|
argumentHint: frontmatter['argument-hint'] || '',
|
|
92
|
-
category: categorizeCommand(name, frontmatter.description || '')
|
|
92
|
+
category: categorizeCommand(name, frontmatter.description || ''),
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -25,7 +25,7 @@ function runGenerator(scriptName) {
|
|
|
25
25
|
try {
|
|
26
26
|
execSync(`node "${scriptPath}"`, {
|
|
27
27
|
cwd: __dirname,
|
|
28
|
-
stdio: 'inherit'
|
|
28
|
+
stdio: 'inherit',
|
|
29
29
|
});
|
|
30
30
|
console.log(`✅ ${scriptName} completed successfully`);
|
|
31
31
|
return true;
|
|
@@ -42,11 +42,7 @@ function main() {
|
|
|
42
42
|
console.log('🚀 AgileFlow Content Generation System');
|
|
43
43
|
console.log('Generating content from metadata...\n');
|
|
44
44
|
|
|
45
|
-
const generators = [
|
|
46
|
-
'inject-help.js',
|
|
47
|
-
'inject-babysit.js',
|
|
48
|
-
'inject-readme.js'
|
|
49
|
-
];
|
|
45
|
+
const generators = ['inject-help.js', 'inject-babysit.js', 'inject-readme.js'];
|
|
50
46
|
|
|
51
47
|
const results = [];
|
|
52
48
|
|
|
@@ -83,7 +83,9 @@ function injectContentByMarker(content, markerName, generated) {
|
|
|
83
83
|
const timestamp = new Date().toISOString().split('T')[0];
|
|
84
84
|
const injectedContent = `${startMarker}\n<!-- Auto-generated on ${timestamp}. Do not edit manually. -->\n\n${generated}\n${endMarker}`;
|
|
85
85
|
|
|
86
|
-
return
|
|
86
|
+
return (
|
|
87
|
+
content.substring(0, startIdx) + injectedContent + content.substring(endIdx + endMarker.length)
|
|
88
|
+
);
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
/**
|
|
@@ -159,7 +161,12 @@ function main() {
|
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
// Export for use in orchestrator
|
|
162
|
-
module.exports = {
|
|
164
|
+
module.exports = {
|
|
165
|
+
generateAgentList,
|
|
166
|
+
generateCommandReference,
|
|
167
|
+
injectContentByMarker,
|
|
168
|
+
addMarkersIfMissing,
|
|
169
|
+
};
|
|
163
170
|
|
|
164
171
|
// Run if called directly
|
|
165
172
|
if (require.main === module) {
|
|
@@ -62,7 +62,9 @@ function injectContent(content, generated) {
|
|
|
62
62
|
const timestamp = new Date().toISOString().split('T')[0];
|
|
63
63
|
const injectedContent = `${startMarker}\n<!-- Auto-generated on ${timestamp}. Do not edit manually. -->\n\n${generated}\n${endMarker}`;
|
|
64
64
|
|
|
65
|
-
return
|
|
65
|
+
return (
|
|
66
|
+
content.substring(0, startIdx) + injectedContent + content.substring(endIdx + endMarker.length)
|
|
67
|
+
);
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
/**
|
|
@@ -91,7 +91,9 @@ function injectContentByMarker(content, markerName, generated) {
|
|
|
91
91
|
const timestamp = new Date().toISOString().split('T')[0];
|
|
92
92
|
const injectedContent = `${startMarker}\n<!-- Auto-generated on ${timestamp}. Do not edit manually. -->\n\n${generated}\n${endMarker}`;
|
|
93
93
|
|
|
94
|
-
return
|
|
94
|
+
return (
|
|
95
|
+
content.substring(0, startIdx) + injectedContent + content.substring(endIdx + endMarker.length)
|
|
96
|
+
);
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
/**
|
|
@@ -117,7 +119,9 @@ function main() {
|
|
|
117
119
|
const agents = scanAgents(agentsDir);
|
|
118
120
|
const skills = scanSkills(skillsDir);
|
|
119
121
|
|
|
120
|
-
console.log(
|
|
122
|
+
console.log(
|
|
123
|
+
`Found: ${commands.length} commands, ${agents.length} agents, ${skills.length} skills`
|
|
124
|
+
);
|
|
121
125
|
|
|
122
126
|
// Read README
|
|
123
127
|
let readmeContent = fs.readFileSync(readmeFile, 'utf-8');
|
|
@@ -127,7 +131,7 @@ function main() {
|
|
|
127
131
|
const stats = generateStats({
|
|
128
132
|
commands: commands.length,
|
|
129
133
|
agents: agents.length,
|
|
130
|
-
skills: skills.length
|
|
134
|
+
skills: skills.length,
|
|
131
135
|
});
|
|
132
136
|
|
|
133
137
|
console.log('Generating agent table...');
|
|
@@ -48,10 +48,10 @@ function categorizeSkill(name, description) {
|
|
|
48
48
|
const categories = {
|
|
49
49
|
'Story & Planning': ['story', 'epic', 'sprint', 'acceptance-criteria'],
|
|
50
50
|
'Code Generation': ['type-definitions', 'validation-schema', 'error-handler'],
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
Testing: ['test-case'],
|
|
52
|
+
Documentation: ['adr', 'api-documentation', 'changelog', 'pr-description'],
|
|
53
|
+
Architecture: ['sql-schema', 'diagram'],
|
|
54
|
+
Deployment: ['deployment-guide', 'migration-checklist'],
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
const lowerName = name.toLowerCase();
|
|
@@ -98,7 +98,7 @@ function scanSkills(skillsDir) {
|
|
|
98
98
|
file: 'SKILL.md',
|
|
99
99
|
path: skillFile,
|
|
100
100
|
description,
|
|
101
|
-
category: categorizeSkill(name, description)
|
|
101
|
+
category: categorizeSkill(name, description),
|
|
102
102
|
});
|
|
103
103
|
}
|
|
104
104
|
|
package/scripts/get-env.js
CHANGED
|
@@ -35,9 +35,7 @@ function getProjectInfo() {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
try {
|
|
38
|
-
rootPackage = JSON.parse(
|
|
39
|
-
fs.readFileSync(path.join(rootDir, 'package.json'), 'utf8')
|
|
40
|
-
);
|
|
38
|
+
rootPackage = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf8'));
|
|
41
39
|
} catch (err) {
|
|
42
40
|
// Ignore if not found
|
|
43
41
|
}
|
|
@@ -50,17 +48,17 @@ function getProjectInfo() {
|
|
|
50
48
|
try {
|
|
51
49
|
gitBranch = execSync('git branch --show-current', {
|
|
52
50
|
cwd: rootDir,
|
|
53
|
-
encoding: 'utf8'
|
|
51
|
+
encoding: 'utf8',
|
|
54
52
|
}).trim();
|
|
55
53
|
gitCommit = execSync('git rev-parse --short HEAD', {
|
|
56
54
|
cwd: rootDir,
|
|
57
|
-
encoding: 'utf8'
|
|
55
|
+
encoding: 'utf8',
|
|
58
56
|
}).trim();
|
|
59
57
|
|
|
60
58
|
// Get recent commits (last 5)
|
|
61
59
|
const commitLog = execSync('git log --oneline -5 2>/dev/null', {
|
|
62
60
|
cwd: rootDir,
|
|
63
|
-
encoding: 'utf8'
|
|
61
|
+
encoding: 'utf8',
|
|
64
62
|
}).trim();
|
|
65
63
|
recentCommits = commitLog.split('\n').filter(Boolean);
|
|
66
64
|
} catch (err) {
|
|
@@ -68,10 +66,10 @@ function getProjectInfo() {
|
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
// Get AgileFlow status info
|
|
71
|
-
|
|
69
|
+
const activeStories = [];
|
|
72
70
|
let wipCount = 0;
|
|
73
71
|
let blockedCount = 0;
|
|
74
|
-
|
|
72
|
+
const activeEpics = [];
|
|
75
73
|
|
|
76
74
|
try {
|
|
77
75
|
const statusPath = path.join(rootDir, 'docs/09-agents/status.json');
|
|
@@ -163,13 +161,16 @@ function formatOutput(info, asJson = false, compact = false) {
|
|
|
163
161
|
|
|
164
162
|
// Header line with project info (brand color name, dim version, colored branch)
|
|
165
163
|
const branchColor = info.git.branch === 'main' ? c.green : c.cyan;
|
|
166
|
-
lines.push(
|
|
164
|
+
lines.push(
|
|
165
|
+
`${c.brand}${c.bold}${info.project.name}${c.reset} ${c.dim}v${info.project.version}${c.reset} | ${branchColor}${info.git.branch}${c.reset} ${c.dim}(${info.git.commit})${c.reset}`
|
|
166
|
+
);
|
|
167
167
|
|
|
168
168
|
// Status line (yellow WIP, red blocked)
|
|
169
169
|
const wipColor = info.agileflow.wipCount > 0 ? c.yellow : c.dim;
|
|
170
|
-
let statusLine =
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
let statusLine =
|
|
171
|
+
info.agileflow.wipCount > 0
|
|
172
|
+
? `${wipColor}WIP: ${info.agileflow.wipCount}${c.reset}`
|
|
173
|
+
: `${c.dim}No active work${c.reset}`;
|
|
173
174
|
if (info.agileflow.blockedCount > 0) {
|
|
174
175
|
statusLine += ` | ${c.red}Blocked: ${info.agileflow.blockedCount}${c.reset}`;
|
|
175
176
|
}
|