agileflow 2.76.0 → 2.78.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 +3 -3
- package/package.json +6 -1
- package/scripts/agileflow-configure.js +185 -13
- package/scripts/agileflow-statusline.sh +266 -27
- package/scripts/agileflow-welcome.js +160 -52
- package/scripts/auto-self-improve.js +63 -20
- package/scripts/check-update.js +1 -4
- package/scripts/damage-control-bash.js +232 -0
- package/scripts/damage-control-edit.js +243 -0
- package/scripts/damage-control-write.js +243 -0
- package/scripts/get-env.js +15 -7
- package/scripts/lib/frontmatter-parser.js +4 -1
- package/scripts/obtain-context.js +59 -48
- package/scripts/ralph-loop.js +25 -13
- package/scripts/validate-expertise.sh +19 -15
- package/src/core/agents/accessibility.md +124 -53
- package/src/core/agents/adr-writer.md +192 -52
- package/src/core/agents/analytics.md +139 -60
- package/src/core/agents/api.md +173 -63
- package/src/core/agents/ci.md +139 -57
- package/src/core/agents/compliance.md +159 -68
- package/src/core/agents/configuration/damage-control.md +356 -0
- package/src/core/agents/database.md +162 -61
- package/src/core/agents/datamigration.md +179 -66
- package/src/core/agents/design.md +179 -57
- package/src/core/agents/devops.md +160 -3
- package/src/core/agents/documentation.md +204 -60
- package/src/core/agents/epic-planner.md +147 -55
- package/src/core/agents/integrations.md +197 -69
- package/src/core/agents/mentor.md +158 -57
- package/src/core/agents/mobile.md +159 -67
- package/src/core/agents/monitoring.md +154 -65
- package/src/core/agents/multi-expert.md +115 -43
- package/src/core/agents/orchestrator.md +77 -24
- package/src/core/agents/performance.md +130 -75
- package/src/core/agents/product.md +151 -55
- package/src/core/agents/qa.md +162 -74
- package/src/core/agents/readme-updater.md +178 -76
- package/src/core/agents/refactor.md +148 -95
- package/src/core/agents/research.md +143 -72
- package/src/core/agents/security.md +154 -65
- package/src/core/agents/testing.md +176 -97
- package/src/core/agents/ui.md +170 -79
- package/src/core/commands/adr/list.md +171 -0
- package/src/core/commands/adr/update.md +235 -0
- package/src/core/commands/adr/view.md +252 -0
- package/src/core/commands/adr.md +207 -50
- package/src/core/commands/agent.md +16 -0
- package/src/core/commands/assign.md +148 -44
- package/src/core/commands/auto.md +18 -1
- package/src/core/commands/babysit.md +361 -36
- package/src/core/commands/baseline.md +14 -0
- package/src/core/commands/blockers.md +170 -51
- package/src/core/commands/board.md +144 -66
- package/src/core/commands/changelog.md +15 -0
- package/src/core/commands/ci.md +179 -69
- package/src/core/commands/compress.md +18 -0
- package/src/core/commands/configure.md +16 -0
- package/src/core/commands/context/export.md +193 -4
- package/src/core/commands/context/full.md +191 -18
- package/src/core/commands/context/note.md +248 -4
- package/src/core/commands/debt.md +17 -0
- package/src/core/commands/deploy.md +208 -65
- package/src/core/commands/deps.md +15 -0
- package/src/core/commands/diagnose.md +16 -0
- package/src/core/commands/docs.md +196 -64
- package/src/core/commands/epic/list.md +170 -0
- package/src/core/commands/epic/view.md +242 -0
- package/src/core/commands/epic.md +192 -69
- package/src/core/commands/feedback.md +191 -71
- package/src/core/commands/handoff.md +162 -48
- package/src/core/commands/help.md +9 -0
- package/src/core/commands/ideate.md +446 -0
- package/src/core/commands/impact.md +16 -0
- package/src/core/commands/metrics.md +141 -37
- package/src/core/commands/multi-expert.md +77 -0
- package/src/core/commands/packages.md +16 -0
- package/src/core/commands/pr.md +161 -67
- package/src/core/commands/readme-sync.md +16 -0
- package/src/core/commands/research/analyze.md +568 -0
- package/src/core/commands/research/ask.md +345 -20
- package/src/core/commands/research/import.md +562 -19
- package/src/core/commands/research/list.md +173 -5
- package/src/core/commands/research/view.md +181 -8
- package/src/core/commands/retro.md +135 -48
- package/src/core/commands/review.md +219 -47
- package/src/core/commands/session/end.md +209 -0
- package/src/core/commands/session/history.md +210 -0
- package/src/core/commands/session/init.md +116 -0
- package/src/core/commands/session/new.md +296 -0
- package/src/core/commands/session/resume.md +166 -0
- package/src/core/commands/session/status.md +166 -0
- package/src/core/commands/skill/create.md +115 -17
- package/src/core/commands/skill/delete.md +117 -0
- package/src/core/commands/skill/edit.md +104 -0
- package/src/core/commands/skill/list.md +128 -0
- package/src/core/commands/skill/test.md +135 -0
- package/src/core/commands/skill/upgrade.md +542 -0
- package/src/core/commands/sprint.md +17 -1
- package/src/core/commands/status.md +133 -21
- package/src/core/commands/story/list.md +176 -0
- package/src/core/commands/story/view.md +265 -0
- package/src/core/commands/story-validate.md +101 -1
- package/src/core/commands/story.md +204 -51
- package/src/core/commands/template.md +16 -1
- package/src/core/commands/tests.md +226 -64
- package/src/core/commands/update.md +17 -1
- package/src/core/commands/validate-expertise.md +16 -0
- package/src/core/commands/velocity.md +140 -36
- package/src/core/commands/verify.md +14 -0
- package/src/core/commands/whats-new.md +30 -0
- package/src/core/skills/_learnings/README.md +91 -0
- package/src/core/skills/_learnings/_template.yaml +106 -0
- package/src/core/skills/_learnings/commit.yaml +69 -0
- package/src/core/templates/damage-control-patterns.yaml +234 -0
- package/src/core/templates/skill-template.md +53 -11
- package/tools/cli/commands/list.js +3 -1
- package/tools/cli/commands/start.js +180 -0
- package/tools/cli/commands/uninstall.js +4 -5
- package/tools/cli/commands/update.js +11 -3
- package/tools/cli/lib/content-injector.js +6 -1
- package/tools/cli/tui/Dashboard.js +66 -0
- package/tools/cli/tui/StoryList.js +69 -0
- package/tools/cli/tui/index.js +16 -0
|
@@ -32,6 +32,7 @@ const c = {
|
|
|
32
32
|
bold: '\x1b[1m',
|
|
33
33
|
dim: '\x1b[2m',
|
|
34
34
|
|
|
35
|
+
// Standard ANSI colors
|
|
35
36
|
red: '\x1b[31m',
|
|
36
37
|
green: '\x1b[32m',
|
|
37
38
|
yellow: '\x1b[33m',
|
|
@@ -44,6 +45,22 @@ const c = {
|
|
|
44
45
|
brightYellow: '\x1b[93m',
|
|
45
46
|
brightCyan: '\x1b[96m',
|
|
46
47
|
|
|
48
|
+
// Vibrant 256-color palette (modern, sleek look)
|
|
49
|
+
mintGreen: '\x1b[38;5;158m', // Healthy/success states
|
|
50
|
+
peach: '\x1b[38;5;215m', // Warning states
|
|
51
|
+
coral: '\x1b[38;5;203m', // Critical/error states
|
|
52
|
+
lightGreen: '\x1b[38;5;194m', // Session healthy
|
|
53
|
+
lightYellow: '\x1b[38;5;228m', // Session warning
|
|
54
|
+
lightPink: '\x1b[38;5;210m', // Session critical
|
|
55
|
+
skyBlue: '\x1b[38;5;117m', // Directories/paths
|
|
56
|
+
lavender: '\x1b[38;5;147m', // Model info, story IDs
|
|
57
|
+
softGold: '\x1b[38;5;222m', // Cost/money
|
|
58
|
+
teal: '\x1b[38;5;80m', // Ready/pending states
|
|
59
|
+
slate: '\x1b[38;5;103m', // Secondary info
|
|
60
|
+
rose: '\x1b[38;5;211m', // Blocked/critical accent
|
|
61
|
+
amber: '\x1b[38;5;214m', // WIP/in-progress accent
|
|
62
|
+
powder: '\x1b[38;5;153m', // Labels/headers
|
|
63
|
+
|
|
47
64
|
// Brand color (#e8683a)
|
|
48
65
|
brand: '\x1b[38;2;232;104;58m',
|
|
49
66
|
};
|
|
@@ -105,7 +122,9 @@ function getProjectInfo(rootDir) {
|
|
|
105
122
|
} catch (e) {
|
|
106
123
|
// Fallback: check .agileflow/package.json
|
|
107
124
|
try {
|
|
108
|
-
const pkg = JSON.parse(
|
|
125
|
+
const pkg = JSON.parse(
|
|
126
|
+
fs.readFileSync(path.join(rootDir, '.agileflow/package.json'), 'utf8')
|
|
127
|
+
);
|
|
109
128
|
info.version = pkg.version || info.version;
|
|
110
129
|
} catch (e2) {}
|
|
111
130
|
}
|
|
@@ -327,6 +346,67 @@ function checkPreCompact(rootDir) {
|
|
|
327
346
|
return result;
|
|
328
347
|
}
|
|
329
348
|
|
|
349
|
+
function checkDamageControl(rootDir) {
|
|
350
|
+
const result = { configured: false, level: null, patternCount: 0, scriptsOk: true };
|
|
351
|
+
|
|
352
|
+
try {
|
|
353
|
+
// Check if PreToolUse hooks are configured in settings
|
|
354
|
+
const settingsPath = path.join(rootDir, '.claude/settings.json');
|
|
355
|
+
if (fs.existsSync(settingsPath)) {
|
|
356
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
357
|
+
if (settings.hooks?.PreToolUse && Array.isArray(settings.hooks.PreToolUse)) {
|
|
358
|
+
// Check for damage-control hooks
|
|
359
|
+
const hasDamageControlHooks = settings.hooks.PreToolUse.some(
|
|
360
|
+
h => h.hooks?.some(hk => hk.command?.includes('damage-control'))
|
|
361
|
+
);
|
|
362
|
+
if (hasDamageControlHooks) {
|
|
363
|
+
result.configured = true;
|
|
364
|
+
|
|
365
|
+
// Count how many hooks are present (should be 3: Bash, Edit, Write)
|
|
366
|
+
const dcHooks = settings.hooks.PreToolUse.filter(h =>
|
|
367
|
+
h.hooks?.some(hk => hk.command?.includes('damage-control'))
|
|
368
|
+
);
|
|
369
|
+
result.hooksCount = dcHooks.length;
|
|
370
|
+
|
|
371
|
+
// Check if all required scripts exist
|
|
372
|
+
const scriptsDir = path.join(rootDir, '.agileflow', 'scripts');
|
|
373
|
+
const requiredScripts = [
|
|
374
|
+
'damage-control-bash.js',
|
|
375
|
+
'damage-control-edit.js',
|
|
376
|
+
'damage-control-write.js',
|
|
377
|
+
];
|
|
378
|
+
for (const script of requiredScripts) {
|
|
379
|
+
if (!fs.existsSync(path.join(scriptsDir, script))) {
|
|
380
|
+
result.scriptsOk = false;
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Get protection level and pattern count from metadata
|
|
389
|
+
const metadataPath = path.join(rootDir, 'docs/00-meta/agileflow-metadata.json');
|
|
390
|
+
if (fs.existsSync(metadataPath)) {
|
|
391
|
+
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
|
|
392
|
+
if (metadata.features?.damagecontrol) {
|
|
393
|
+
result.level = metadata.features.damagecontrol.protectionLevel || 'standard';
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Count patterns in config file
|
|
398
|
+
const patternsPath = path.join(rootDir, '.agileflow', 'config', 'damage-control-patterns.yaml');
|
|
399
|
+
if (fs.existsSync(patternsPath)) {
|
|
400
|
+
const content = fs.readFileSync(patternsPath, 'utf8');
|
|
401
|
+
// Count pattern entries (lines starting with " - pattern:")
|
|
402
|
+
const patternMatches = content.match(/^\s*-\s*pattern:/gm);
|
|
403
|
+
result.patternCount = patternMatches ? patternMatches.length : 0;
|
|
404
|
+
}
|
|
405
|
+
} catch (e) {}
|
|
406
|
+
|
|
407
|
+
return result;
|
|
408
|
+
}
|
|
409
|
+
|
|
330
410
|
// Compare semantic versions: returns -1 if a < b, 0 if equal, 1 if a > b
|
|
331
411
|
function compareVersions(a, b) {
|
|
332
412
|
if (!a || !b) return 0;
|
|
@@ -420,7 +500,7 @@ function getChangelogEntries(version) {
|
|
|
420
500
|
// Run auto-update if enabled
|
|
421
501
|
async function runAutoUpdate(rootDir) {
|
|
422
502
|
try {
|
|
423
|
-
console.log(`${c.
|
|
503
|
+
console.log(`${c.skyBlue}Updating AgileFlow...${c.reset}`);
|
|
424
504
|
execSync('npx agileflow update', {
|
|
425
505
|
cwd: rootDir,
|
|
426
506
|
encoding: 'utf8',
|
|
@@ -428,7 +508,7 @@ async function runAutoUpdate(rootDir) {
|
|
|
428
508
|
});
|
|
429
509
|
return true;
|
|
430
510
|
} catch (e) {
|
|
431
|
-
console.log(`${c.
|
|
511
|
+
console.log(`${c.peach}Auto-update failed. Run manually: npx agileflow update${c.reset}`);
|
|
432
512
|
return false;
|
|
433
513
|
}
|
|
434
514
|
}
|
|
@@ -449,7 +529,8 @@ function validateExpertise(rootDir) {
|
|
|
449
529
|
const MAX_LINES = 200;
|
|
450
530
|
|
|
451
531
|
try {
|
|
452
|
-
const domains = fs
|
|
532
|
+
const domains = fs
|
|
533
|
+
.readdirSync(expertsDir, { withFileTypes: true })
|
|
453
534
|
.filter(d => d.isDirectory() && d.name !== 'templates')
|
|
454
535
|
.map(d => d.name);
|
|
455
536
|
|
|
@@ -584,7 +665,16 @@ function truncate(str, maxLen, suffix = '..') {
|
|
|
584
665
|
return str.substring(0, cutIndex) + suffix;
|
|
585
666
|
}
|
|
586
667
|
|
|
587
|
-
function formatTable(
|
|
668
|
+
function formatTable(
|
|
669
|
+
info,
|
|
670
|
+
archival,
|
|
671
|
+
session,
|
|
672
|
+
precompact,
|
|
673
|
+
parallelSessions,
|
|
674
|
+
updateInfo = {},
|
|
675
|
+
expertise = {},
|
|
676
|
+
damageControl = {}
|
|
677
|
+
) {
|
|
588
678
|
const W = 58; // inner width
|
|
589
679
|
const R = W - 24; // right column width (34 chars)
|
|
590
680
|
const lines = [];
|
|
@@ -605,21 +695,21 @@ function formatTable(info, archival, session, precompact, parallelSessions, upda
|
|
|
605
695
|
|
|
606
696
|
const divider = () =>
|
|
607
697
|
`${c.dim}${box.lT}${box.h.repeat(22)}${box.cross}${box.h.repeat(W - 22)}${box.rT}${c.reset}`;
|
|
608
|
-
const fullDivider = () =>
|
|
609
|
-
`${c.dim}${box.lT}${box.h.repeat(W)}${box.rT}${c.reset}`;
|
|
698
|
+
const fullDivider = () => `${c.dim}${box.lT}${box.h.repeat(W)}${box.rT}${c.reset}`;
|
|
610
699
|
const topBorder = `${c.dim}${box.tl}${box.h.repeat(22)}${box.tT}${box.h.repeat(W - 22)}${box.tr}${c.reset}`;
|
|
611
700
|
const bottomBorder = `${c.dim}${box.bl}${box.h.repeat(22)}${box.bT}${box.h.repeat(W - 22)}${box.br}${c.reset}`;
|
|
612
701
|
|
|
613
702
|
// Header with version and optional update indicator
|
|
703
|
+
// Use vibrant colors for branch
|
|
614
704
|
const branchColor =
|
|
615
|
-
info.branch === 'main' ? c.
|
|
705
|
+
info.branch === 'main' ? c.mintGreen : info.branch.startsWith('fix') ? c.coral : c.skyBlue;
|
|
616
706
|
|
|
617
|
-
// Build version string with update status
|
|
707
|
+
// Build version string with update status (vibrant colors)
|
|
618
708
|
let versionStr = `v${info.version}`;
|
|
619
709
|
if (updateInfo.justUpdated && updateInfo.previousVersion) {
|
|
620
|
-
versionStr = `v${info.version} ${c.
|
|
710
|
+
versionStr = `v${info.version} ${c.mintGreen}✓${c.reset}${c.slate} (was v${updateInfo.previousVersion})`;
|
|
621
711
|
} else if (updateInfo.available && updateInfo.latest) {
|
|
622
|
-
versionStr = `v${info.version} ${c.
|
|
712
|
+
versionStr = `v${info.version} ${c.amber}↑${updateInfo.latest}${c.reset}`;
|
|
623
713
|
}
|
|
624
714
|
|
|
625
715
|
// Calculate remaining space for branch
|
|
@@ -640,138 +730,153 @@ function formatTable(info, archival, session, precompact, parallelSessions, upda
|
|
|
640
730
|
lines.push(topBorder);
|
|
641
731
|
lines.push(headerLine);
|
|
642
732
|
|
|
643
|
-
// Show update available notification
|
|
733
|
+
// Show update available notification (using vibrant colors)
|
|
644
734
|
if (updateInfo.available && updateInfo.latest && !updateInfo.justUpdated) {
|
|
645
735
|
lines.push(fullDivider());
|
|
646
|
-
lines.push(fullRow(
|
|
647
|
-
lines.push(fullRow(` Run: npx agileflow update`,
|
|
736
|
+
lines.push(fullRow(`${c.amber}↑${c.reset} Update available: ${c.softGold}v${updateInfo.latest}${c.reset}`, ''));
|
|
737
|
+
lines.push(fullRow(` Run: ${c.skyBlue}npx agileflow update${c.reset}`, ''));
|
|
648
738
|
}
|
|
649
739
|
|
|
650
740
|
// Show "just updated" changelog
|
|
651
741
|
if (updateInfo.justUpdated && updateInfo.changelog && updateInfo.changelog.length > 0) {
|
|
652
742
|
lines.push(fullDivider());
|
|
653
|
-
lines.push(fullRow(
|
|
743
|
+
lines.push(fullRow(`${c.mintGreen}✨${c.reset} What's new in ${c.softGold}v${info.version}${c.reset}:`, ''));
|
|
654
744
|
for (const entry of updateInfo.changelog.slice(0, 2)) {
|
|
655
|
-
lines.push(fullRow(
|
|
745
|
+
lines.push(fullRow(` ${c.teal}•${c.reset} ${truncate(entry, W - 6)}`, ''));
|
|
656
746
|
}
|
|
657
|
-
lines.push(fullRow(`Run /agileflow:whats-new for full changelog`,
|
|
747
|
+
lines.push(fullRow(` Run ${c.skyBlue}/agileflow:whats-new${c.reset} for full changelog`, ''));
|
|
658
748
|
}
|
|
659
749
|
|
|
660
750
|
lines.push(divider());
|
|
661
751
|
|
|
662
|
-
// Stories section
|
|
752
|
+
// Stories section (always colorful labels like obtain-context)
|
|
663
753
|
lines.push(
|
|
664
754
|
row(
|
|
665
755
|
'In Progress',
|
|
666
756
|
info.wipCount > 0 ? `${info.wipCount}` : '0',
|
|
667
|
-
c.
|
|
668
|
-
info.wipCount > 0 ? c.
|
|
757
|
+
c.peach,
|
|
758
|
+
info.wipCount > 0 ? c.peach : c.dim
|
|
669
759
|
)
|
|
670
760
|
);
|
|
671
761
|
lines.push(
|
|
672
762
|
row(
|
|
673
763
|
'Blocked',
|
|
674
764
|
info.blockedCount > 0 ? `${info.blockedCount}` : '0',
|
|
675
|
-
c.
|
|
676
|
-
info.blockedCount > 0 ? c.
|
|
765
|
+
c.coral,
|
|
766
|
+
info.blockedCount > 0 ? c.coral : c.dim
|
|
677
767
|
)
|
|
678
768
|
);
|
|
679
769
|
lines.push(
|
|
680
770
|
row(
|
|
681
771
|
'Ready',
|
|
682
772
|
info.readyCount > 0 ? `${info.readyCount}` : '0',
|
|
683
|
-
c.
|
|
684
|
-
info.readyCount > 0 ? c.
|
|
773
|
+
c.skyBlue,
|
|
774
|
+
info.readyCount > 0 ? c.skyBlue : c.dim
|
|
685
775
|
)
|
|
686
776
|
);
|
|
777
|
+
const completedColor = `${c.bold}${c.mintGreen}`;
|
|
687
778
|
lines.push(
|
|
688
779
|
row(
|
|
689
780
|
'Completed',
|
|
690
781
|
info.completedCount > 0 ? `${info.completedCount}` : '0',
|
|
691
|
-
|
|
692
|
-
info.completedCount > 0 ?
|
|
782
|
+
completedColor,
|
|
783
|
+
info.completedCount > 0 ? completedColor : c.dim
|
|
693
784
|
)
|
|
694
785
|
);
|
|
695
786
|
|
|
696
787
|
lines.push(divider());
|
|
697
788
|
|
|
698
|
-
//
|
|
789
|
+
// System section (colorful labels like obtain-context)
|
|
699
790
|
if (archival.disabled) {
|
|
700
|
-
lines.push(row('Auto-archival', 'disabled', c.
|
|
791
|
+
lines.push(row('Auto-archival', 'disabled', c.lavender, c.slate));
|
|
701
792
|
} else {
|
|
702
793
|
const archivalStatus =
|
|
703
794
|
archival.archived > 0 ? `archived ${archival.archived} stories` : `nothing to archive`;
|
|
704
795
|
lines.push(
|
|
705
|
-
row('Auto-archival', archivalStatus, c.
|
|
796
|
+
row('Auto-archival', archivalStatus, c.lavender, archival.archived > 0 ? c.mintGreen : c.dim)
|
|
706
797
|
);
|
|
707
798
|
}
|
|
708
799
|
|
|
709
800
|
// Session cleanup
|
|
710
801
|
const sessionStatus = session.cleared > 0 ? `cleared ${session.cleared} command(s)` : `clean`;
|
|
711
|
-
lines.push(row('Session state', sessionStatus, c.
|
|
802
|
+
lines.push(row('Session state', sessionStatus, c.lavender, session.cleared > 0 ? c.mintGreen : c.dim));
|
|
712
803
|
|
|
713
804
|
// PreCompact status with version check
|
|
714
805
|
if (precompact.configured && precompact.scriptExists) {
|
|
715
806
|
if (precompact.outdated) {
|
|
716
807
|
const verStr = precompact.version ? ` (v${precompact.version})` : '';
|
|
717
|
-
lines.push(row('Context preserve', `outdated${verStr}`, c.
|
|
808
|
+
lines.push(row('Context preserve', `outdated${verStr}`, c.peach, c.peach));
|
|
718
809
|
} else if (session.commandNames && session.commandNames.length > 0) {
|
|
719
810
|
// Show the preserved command names
|
|
720
811
|
const cmdDisplay = session.commandNames.map(n => `/agileflow:${n}`).join(', ');
|
|
721
|
-
lines.push(row('Context preserve', cmdDisplay, c.
|
|
812
|
+
lines.push(row('Context preserve', cmdDisplay, c.lavender, c.mintGreen));
|
|
722
813
|
} else {
|
|
723
|
-
lines.push(row('Context preserve', '
|
|
814
|
+
lines.push(row('Context preserve', 'ready', c.lavender, c.dim));
|
|
724
815
|
}
|
|
725
816
|
} else if (precompact.configured) {
|
|
726
|
-
lines.push(row('Context preserve', 'script missing', c.
|
|
817
|
+
lines.push(row('Context preserve', 'script missing', c.peach, c.peach));
|
|
727
818
|
} else {
|
|
728
|
-
lines.push(row('Context preserve', 'not configured', c.
|
|
819
|
+
lines.push(row('Context preserve', 'not configured', c.slate, c.slate));
|
|
729
820
|
}
|
|
730
821
|
|
|
731
822
|
// Parallel sessions status
|
|
732
823
|
if (parallelSessions && parallelSessions.available) {
|
|
733
824
|
if (parallelSessions.otherActive > 0) {
|
|
734
825
|
const sessionStr = `⚠️ ${parallelSessions.otherActive} other active`;
|
|
735
|
-
lines.push(row('Sessions', sessionStr, c.
|
|
826
|
+
lines.push(row('Sessions', sessionStr, c.peach, c.peach));
|
|
736
827
|
} else {
|
|
737
828
|
const sessionStr = parallelSessions.currentId
|
|
738
829
|
? `✓ Session ${parallelSessions.currentId} (only)`
|
|
739
830
|
: '✓ Only session';
|
|
740
|
-
lines.push(row('Sessions', sessionStr, c.
|
|
831
|
+
lines.push(row('Sessions', sessionStr, c.lavender, c.mintGreen));
|
|
741
832
|
}
|
|
742
833
|
}
|
|
743
834
|
|
|
744
|
-
// Agent expertise validation (
|
|
835
|
+
// Agent expertise validation (always show with color)
|
|
745
836
|
if (expertise && expertise.total > 0) {
|
|
746
837
|
if (expertise.failed > 0) {
|
|
747
838
|
const expertStr = `❌ ${expertise.failed} failed, ${expertise.warnings} warnings`;
|
|
748
|
-
lines.push(row('Expertise', expertStr, c.
|
|
839
|
+
lines.push(row('Expertise', expertStr, c.coral, c.coral));
|
|
749
840
|
} else if (expertise.warnings > 0) {
|
|
750
841
|
const expertStr = `⚠️ ${expertise.warnings} warnings (${expertise.passed} ok)`;
|
|
751
|
-
lines.push(row('Expertise', expertStr, c.
|
|
842
|
+
lines.push(row('Expertise', expertStr, c.peach, c.peach));
|
|
843
|
+
} else {
|
|
844
|
+
lines.push(row('Expertise', `✓ ${expertise.total} valid`, c.lavender, c.mintGreen));
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// Damage control status (PreToolUse hooks for dangerous command protection)
|
|
849
|
+
if (damageControl && damageControl.configured) {
|
|
850
|
+
if (!damageControl.scriptsOk) {
|
|
851
|
+
lines.push(row('Damage control', '⚠️ scripts missing', c.coral, c.coral));
|
|
752
852
|
} else {
|
|
753
|
-
|
|
853
|
+
const levelStr = damageControl.level || 'standard';
|
|
854
|
+
const patternStr = damageControl.patternCount > 0 ? `${damageControl.patternCount} patterns` : '';
|
|
855
|
+
const dcStatus = `🛡️ ${levelStr}${patternStr ? ` (${patternStr})` : ''}`;
|
|
856
|
+
lines.push(row('Damage control', dcStatus, c.lavender, c.mintGreen));
|
|
754
857
|
}
|
|
858
|
+
} else {
|
|
859
|
+
lines.push(row('Damage control', 'not configured', c.slate, c.slate));
|
|
755
860
|
}
|
|
756
861
|
|
|
757
862
|
lines.push(divider());
|
|
758
863
|
|
|
759
|
-
// Current story (
|
|
864
|
+
// Current story (colorful like obtain-context)
|
|
760
865
|
if (info.currentStory) {
|
|
761
866
|
lines.push(
|
|
762
867
|
row(
|
|
763
868
|
'Current',
|
|
764
|
-
`${c.
|
|
765
|
-
c.
|
|
869
|
+
`${c.lightYellow}${info.currentStory.id}${c.reset}: ${info.currentStory.title}`,
|
|
870
|
+
c.skyBlue,
|
|
766
871
|
''
|
|
767
872
|
)
|
|
768
873
|
);
|
|
769
874
|
} else {
|
|
770
|
-
lines.push(row('Current', 'No active story', c.
|
|
875
|
+
lines.push(row('Current', 'No active story', c.skyBlue, c.dim));
|
|
771
876
|
}
|
|
772
877
|
|
|
773
|
-
// Last commit
|
|
774
|
-
lines.push(row('Last commit', `${info.commit} ${info.lastCommit}`, c.
|
|
878
|
+
// Last commit (colorful like obtain-context)
|
|
879
|
+
lines.push(row('Last commit', `${c.peach}${info.commit}${c.reset} ${info.lastCommit}`, c.lavender, ''));
|
|
775
880
|
|
|
776
881
|
lines.push(bottomBorder);
|
|
777
882
|
|
|
@@ -787,6 +892,7 @@ async function main() {
|
|
|
787
892
|
const precompact = checkPreCompact(rootDir);
|
|
788
893
|
const parallelSessions = checkParallelSessions(rootDir);
|
|
789
894
|
const expertise = validateExpertise(rootDir);
|
|
895
|
+
const damageControl = checkDamageControl(rootDir);
|
|
790
896
|
|
|
791
897
|
// Check for updates (async, cached)
|
|
792
898
|
let updateInfo = {};
|
|
@@ -810,14 +916,16 @@ async function main() {
|
|
|
810
916
|
// Update check failed - continue without it
|
|
811
917
|
}
|
|
812
918
|
|
|
813
|
-
console.log(
|
|
919
|
+
console.log(
|
|
920
|
+
formatTable(info, archival, session, precompact, parallelSessions, updateInfo, expertise, damageControl)
|
|
921
|
+
);
|
|
814
922
|
|
|
815
|
-
// Show warning and tip if other sessions are active
|
|
923
|
+
// Show warning and tip if other sessions are active (vibrant colors)
|
|
816
924
|
if (parallelSessions.otherActive > 0) {
|
|
817
925
|
console.log('');
|
|
818
|
-
console.log(`${c.
|
|
819
|
-
console.log(`${c.
|
|
820
|
-
console.log(`${c.
|
|
926
|
+
console.log(`${c.amber}⚠️ Other Claude session(s) active in this repo.${c.reset}`);
|
|
927
|
+
console.log(`${c.slate} Run ${c.skyBlue}/agileflow:session:status${c.reset}${c.slate} to see all sessions.${c.reset}`);
|
|
928
|
+
console.log(`${c.slate} Run ${c.skyBlue}/agileflow:session:new${c.reset}${c.slate} to create isolated workspace.${c.reset}`);
|
|
821
929
|
}
|
|
822
930
|
}
|
|
823
931
|
|
|
@@ -36,24 +36,44 @@ const c = {
|
|
|
36
36
|
|
|
37
37
|
// Agents that have expertise files
|
|
38
38
|
const AGENTS_WITH_EXPERTISE = [
|
|
39
|
-
'accessibility',
|
|
40
|
-
'
|
|
41
|
-
'
|
|
42
|
-
'
|
|
43
|
-
'
|
|
39
|
+
'accessibility',
|
|
40
|
+
'adr-writer',
|
|
41
|
+
'analytics',
|
|
42
|
+
'api',
|
|
43
|
+
'ci',
|
|
44
|
+
'compliance',
|
|
45
|
+
'database',
|
|
46
|
+
'datamigration',
|
|
47
|
+
'design',
|
|
48
|
+
'devops',
|
|
49
|
+
'documentation',
|
|
50
|
+
'epic-planner',
|
|
51
|
+
'integrations',
|
|
52
|
+
'mentor',
|
|
53
|
+
'mobile',
|
|
54
|
+
'monitoring',
|
|
55
|
+
'performance',
|
|
56
|
+
'product',
|
|
57
|
+
'qa',
|
|
58
|
+
'readme-updater',
|
|
59
|
+
'refactor',
|
|
60
|
+
'research',
|
|
61
|
+
'security',
|
|
62
|
+
'testing',
|
|
63
|
+
'ui',
|
|
44
64
|
];
|
|
45
65
|
|
|
46
66
|
// File patterns that suggest domain expertise
|
|
47
67
|
const DOMAIN_PATTERNS = {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
68
|
+
database: [/schema/, /migration/, /\.sql$/, /prisma/, /drizzle/, /sequelize/],
|
|
69
|
+
api: [/\/api\//, /controller/, /route/, /endpoint/, /graphql/],
|
|
70
|
+
ui: [/component/, /\.tsx$/, /\.jsx$/, /styles/, /\.css$/, /\.scss$/],
|
|
71
|
+
testing: [/\.test\./, /\.spec\./, /__tests__/, /jest/, /vitest/],
|
|
72
|
+
security: [/auth/, /password/, /token/, /jwt/, /oauth/, /permission/],
|
|
73
|
+
ci: [/\.github\/workflows/, /\.gitlab-ci/, /dockerfile/i, /docker-compose/],
|
|
74
|
+
documentation: [/\.md$/, /readme/i, /docs\//, /jsdoc/],
|
|
75
|
+
performance: [/cache/, /optimize/, /performance/, /benchmark/],
|
|
76
|
+
devops: [/deploy/, /kubernetes/, /k8s/, /terraform/, /ansible/],
|
|
57
77
|
};
|
|
58
78
|
|
|
59
79
|
// Find project root
|
|
@@ -83,19 +103,28 @@ function getGitDiff(rootDir) {
|
|
|
83
103
|
const diffFiles = execSync('git diff --name-only HEAD 2>/dev/null || git diff --name-only', {
|
|
84
104
|
cwd: rootDir,
|
|
85
105
|
encoding: 'utf8',
|
|
86
|
-
})
|
|
106
|
+
})
|
|
107
|
+
.trim()
|
|
108
|
+
.split('\n')
|
|
109
|
+
.filter(Boolean);
|
|
87
110
|
|
|
88
111
|
// Get staged files
|
|
89
112
|
const stagedFiles = execSync('git diff --cached --name-only 2>/dev/null', {
|
|
90
113
|
cwd: rootDir,
|
|
91
114
|
encoding: 'utf8',
|
|
92
|
-
})
|
|
115
|
+
})
|
|
116
|
+
.trim()
|
|
117
|
+
.split('\n')
|
|
118
|
+
.filter(Boolean);
|
|
93
119
|
|
|
94
120
|
// Get untracked files
|
|
95
121
|
const untrackedFiles = execSync('git ls-files --others --exclude-standard 2>/dev/null', {
|
|
96
122
|
cwd: rootDir,
|
|
97
123
|
encoding: 'utf8',
|
|
98
|
-
})
|
|
124
|
+
})
|
|
125
|
+
.trim()
|
|
126
|
+
.split('\n')
|
|
127
|
+
.filter(Boolean);
|
|
99
128
|
|
|
100
129
|
// Combine all
|
|
101
130
|
const allFiles = [...new Set([...diffFiles, ...stagedFiles, ...untrackedFiles])];
|
|
@@ -186,7 +215,16 @@ function getExpertisePath(rootDir, agent) {
|
|
|
186
215
|
if (fs.existsSync(installedPath)) return installedPath;
|
|
187
216
|
|
|
188
217
|
// Try source location
|
|
189
|
-
const sourcePath = path.join(
|
|
218
|
+
const sourcePath = path.join(
|
|
219
|
+
rootDir,
|
|
220
|
+
'packages',
|
|
221
|
+
'cli',
|
|
222
|
+
'src',
|
|
223
|
+
'core',
|
|
224
|
+
'experts',
|
|
225
|
+
agent,
|
|
226
|
+
'expertise.yaml'
|
|
227
|
+
);
|
|
190
228
|
if (fs.existsSync(sourcePath)) return sourcePath;
|
|
191
229
|
|
|
192
230
|
return null;
|
|
@@ -219,7 +257,10 @@ function appendLearning(expertisePath, learning) {
|
|
|
219
257
|
// Format learning as YAML
|
|
220
258
|
function formatLearning(summary, files, detectedDomain) {
|
|
221
259
|
const date = new Date().toISOString().split('T')[0];
|
|
222
|
-
const topFiles = files
|
|
260
|
+
const topFiles = files
|
|
261
|
+
.slice(0, 5)
|
|
262
|
+
.map(f => ` - ${f}`)
|
|
263
|
+
.join('\n');
|
|
223
264
|
|
|
224
265
|
return ` - date: "${date}"
|
|
225
266
|
auto_generated: true
|
|
@@ -281,7 +322,9 @@ function main() {
|
|
|
281
322
|
console.log('');
|
|
282
323
|
console.log(`${c.green}✓ Auto-learned:${c.reset} ${c.dim}${activeAgent}${c.reset}`);
|
|
283
324
|
console.log(`${c.dim} ${summary}${c.reset}`);
|
|
284
|
-
console.log(
|
|
325
|
+
console.log(
|
|
326
|
+
`${c.dim} → Updated ${path.basename(path.dirname(expertisePath))}/expertise.yaml${c.reset}`
|
|
327
|
+
);
|
|
285
328
|
console.log('');
|
|
286
329
|
}
|
|
287
330
|
}
|
package/scripts/check-update.js
CHANGED
|
@@ -232,10 +232,7 @@ async function checkForUpdates(options = {}) {
|
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
// Check if we just updated (lastSeenVersion < installed)
|
|
235
|
-
if (
|
|
236
|
-
config.lastSeenVersion &&
|
|
237
|
-
compareVersions(config.lastSeenVersion, installedVersion) < 0
|
|
238
|
-
) {
|
|
235
|
+
if (config.lastSeenVersion && compareVersions(config.lastSeenVersion, installedVersion) < 0) {
|
|
239
236
|
result.justUpdated = true;
|
|
240
237
|
result.previousVersion = config.lastSeenVersion;
|
|
241
238
|
}
|