agileflow 3.3.0 → 3.4.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/CHANGELOG.md +10 -0
- package/README.md +6 -6
- package/lib/skill-loader.js +0 -1
- package/package.json +1 -1
- package/scripts/agileflow-statusline.sh +81 -0
- package/scripts/agileflow-welcome.js +79 -0
- package/scripts/claude-tmux.sh +90 -23
- package/scripts/claude-watchdog.sh +225 -0
- package/scripts/generators/agent-registry.js +14 -1
- package/scripts/generators/inject-babysit.js +22 -9
- package/scripts/generators/inject-help.js +19 -9
- package/scripts/lib/ac-test-matcher.js +452 -0
- package/scripts/lib/audit-cleanup.js +250 -0
- package/scripts/lib/audit-registry.js +304 -0
- package/scripts/lib/configure-features.js +35 -0
- package/scripts/lib/feature-catalog.js +3 -3
- package/scripts/lib/gate-enforcer.js +295 -0
- package/scripts/lib/model-profiles.js +118 -0
- package/scripts/lib/quality-gates.js +163 -0
- package/scripts/lib/signal-detectors.js +44 -1
- package/scripts/lib/skill-catalog.js +557 -0
- package/scripts/lib/skill-recommender.js +311 -0
- package/scripts/lib/status-writer.js +255 -0
- package/scripts/lib/story-claiming.js +128 -45
- package/scripts/lib/task-sync.js +32 -38
- package/scripts/lib/tdd-phase-manager.js +455 -0
- package/scripts/lib/team-events.js +34 -3
- package/scripts/lib/tmux-audit-monitor.js +611 -0
- package/scripts/lib/tmux-group-colors.js +113 -0
- package/scripts/lib/tool-registry.yaml +241 -0
- package/scripts/lib/tool-shed.js +441 -0
- package/scripts/messaging-bridge.js +209 -1
- package/scripts/native-team-observer.js +219 -0
- package/scripts/obtain-context.js +14 -0
- package/scripts/ralph-loop.js +30 -5
- package/scripts/smart-detect.js +21 -0
- package/scripts/spawn-audit-sessions.js +877 -0
- package/scripts/team-manager.js +56 -16
- package/scripts/tmux-close-windows.sh +180 -0
- package/src/core/agents/a11y-analyzer-aria.md +155 -0
- package/src/core/agents/a11y-analyzer-forms.md +162 -0
- package/src/core/agents/a11y-analyzer-keyboard.md +175 -0
- package/src/core/agents/a11y-analyzer-semantic.md +153 -0
- package/src/core/agents/a11y-analyzer-visual.md +158 -0
- package/src/core/agents/a11y-consensus.md +248 -0
- package/src/core/agents/ads-audit-budget.md +181 -0
- package/src/core/agents/ads-audit-compliance.md +169 -0
- package/src/core/agents/ads-audit-creative.md +164 -0
- package/src/core/agents/ads-audit-google.md +226 -0
- package/src/core/agents/ads-audit-meta.md +183 -0
- package/src/core/agents/ads-audit-tracking.md +197 -0
- package/src/core/agents/ads-consensus.md +396 -0
- package/src/core/agents/ads-generate.md +145 -0
- package/src/core/agents/ads-performance-tracker.md +197 -0
- package/src/core/agents/api-quality-analyzer-conventions.md +148 -0
- package/src/core/agents/api-quality-analyzer-docs.md +176 -0
- package/src/core/agents/api-quality-analyzer-errors.md +183 -0
- package/src/core/agents/api-quality-analyzer-pagination.md +171 -0
- package/src/core/agents/api-quality-analyzer-versioning.md +143 -0
- package/src/core/agents/api-quality-consensus.md +214 -0
- package/src/core/agents/arch-analyzer-circular.md +148 -0
- package/src/core/agents/arch-analyzer-complexity.md +171 -0
- package/src/core/agents/arch-analyzer-coupling.md +146 -0
- package/src/core/agents/arch-analyzer-layering.md +151 -0
- package/src/core/agents/arch-analyzer-patterns.md +162 -0
- package/src/core/agents/arch-consensus.md +227 -0
- package/src/core/agents/brainstorm-analyzer-features.md +169 -0
- package/src/core/agents/brainstorm-analyzer-growth.md +161 -0
- package/src/core/agents/brainstorm-analyzer-integration.md +172 -0
- package/src/core/agents/brainstorm-analyzer-market.md +147 -0
- package/src/core/agents/brainstorm-analyzer-ux.md +167 -0
- package/src/core/agents/brainstorm-consensus.md +237 -0
- package/src/core/agents/completeness-consensus.md +5 -5
- package/src/core/agents/perf-consensus.md +2 -2
- package/src/core/agents/security-consensus.md +2 -2
- package/src/core/agents/seo-analyzer-content.md +167 -0
- package/src/core/agents/seo-analyzer-images.md +187 -0
- package/src/core/agents/seo-analyzer-performance.md +206 -0
- package/src/core/agents/seo-analyzer-schema.md +176 -0
- package/src/core/agents/seo-analyzer-sitemap.md +172 -0
- package/src/core/agents/seo-analyzer-technical.md +144 -0
- package/src/core/agents/seo-consensus.md +289 -0
- package/src/core/agents/test-consensus.md +2 -2
- package/src/core/commands/adr.md +1 -0
- package/src/core/commands/ads/audit.md +375 -0
- package/src/core/commands/ads/budget.md +97 -0
- package/src/core/commands/ads/competitor.md +112 -0
- package/src/core/commands/ads/creative.md +85 -0
- package/src/core/commands/ads/generate.md +238 -0
- package/src/core/commands/ads/google.md +112 -0
- package/src/core/commands/ads/health.md +327 -0
- package/src/core/commands/ads/landing.md +119 -0
- package/src/core/commands/ads/linkedin.md +112 -0
- package/src/core/commands/ads/meta.md +91 -0
- package/src/core/commands/ads/microsoft.md +115 -0
- package/src/core/commands/ads/plan.md +321 -0
- package/src/core/commands/ads/test-plan.md +317 -0
- package/src/core/commands/ads/tiktok.md +129 -0
- package/src/core/commands/ads/track.md +288 -0
- package/src/core/commands/ads/youtube.md +124 -0
- package/src/core/commands/ads.md +140 -0
- package/src/core/commands/assign.md +1 -0
- package/src/core/commands/audit.md +43 -6
- package/src/core/commands/babysit.md +315 -1266
- package/src/core/commands/baseline.md +1 -0
- package/src/core/commands/blockers.md +1 -0
- package/src/core/commands/board.md +1 -0
- package/src/core/commands/changelog.md +1 -0
- package/src/core/commands/choose.md +1 -0
- package/src/core/commands/ci.md +1 -0
- package/src/core/commands/code/accessibility.md +347 -0
- package/src/core/commands/code/api.md +297 -0
- package/src/core/commands/code/architecture.md +297 -0
- package/src/core/commands/{audit → code}/completeness.md +72 -25
- package/src/core/commands/{audit → code}/legal.md +63 -16
- package/src/core/commands/{audit → code}/logic.md +64 -16
- package/src/core/commands/{audit → code}/performance.md +67 -20
- package/src/core/commands/{audit → code}/security.md +69 -19
- package/src/core/commands/{audit → code}/test.md +67 -20
- package/src/core/commands/configure.md +1 -0
- package/src/core/commands/council.md +1 -0
- package/src/core/commands/deploy.md +1 -0
- package/src/core/commands/diagnose.md +1 -0
- package/src/core/commands/docs.md +1 -0
- package/src/core/commands/epic/edit.md +213 -0
- package/src/core/commands/epic.md +1 -0
- package/src/core/commands/export.md +238 -0
- package/src/core/commands/help.md +16 -1
- package/src/core/commands/{discovery → ideate}/brief.md +12 -12
- package/src/core/commands/{discovery/new.md → ideate/discover.md} +20 -16
- package/src/core/commands/ideate/features.md +496 -0
- package/src/core/commands/ideate/new.md +158 -124
- package/src/core/commands/impact.md +1 -0
- package/src/core/commands/learn/explain.md +118 -0
- package/src/core/commands/learn/glossary.md +135 -0
- package/src/core/commands/learn/patterns.md +138 -0
- package/src/core/commands/learn/tour.md +126 -0
- package/src/core/commands/migrate/codemods.md +151 -0
- package/src/core/commands/migrate/plan.md +131 -0
- package/src/core/commands/migrate/scan.md +114 -0
- package/src/core/commands/migrate/validate.md +119 -0
- package/src/core/commands/multi-expert.md +1 -0
- package/src/core/commands/pr.md +1 -0
- package/src/core/commands/review.md +1 -0
- package/src/core/commands/seo/audit.md +373 -0
- package/src/core/commands/seo/competitor.md +174 -0
- package/src/core/commands/seo/content.md +107 -0
- package/src/core/commands/seo/geo.md +229 -0
- package/src/core/commands/seo/hreflang.md +140 -0
- package/src/core/commands/seo/images.md +96 -0
- package/src/core/commands/seo/page.md +198 -0
- package/src/core/commands/seo/plan.md +163 -0
- package/src/core/commands/seo/programmatic.md +131 -0
- package/src/core/commands/seo/references/cwv-thresholds.md +64 -0
- package/src/core/commands/seo/references/eeat-framework.md +110 -0
- package/src/core/commands/seo/references/quality-gates.md +91 -0
- package/src/core/commands/seo/references/schema-types.md +102 -0
- package/src/core/commands/seo/schema.md +183 -0
- package/src/core/commands/seo/sitemap.md +97 -0
- package/src/core/commands/seo/technical.md +100 -0
- package/src/core/commands/seo.md +107 -0
- package/src/core/commands/skill/list.md +68 -212
- package/src/core/commands/skill/recommend.md +216 -0
- package/src/core/commands/sprint.md +1 -0
- package/src/core/commands/status/undo.md +191 -0
- package/src/core/commands/status.md +1 -0
- package/src/core/commands/story/edit.md +204 -0
- package/src/core/commands/story/view.md +29 -7
- package/src/core/commands/story-validate.md +1 -0
- package/src/core/commands/story.md +1 -0
- package/src/core/commands/tdd-next.md +238 -0
- package/src/core/commands/tdd.md +211 -0
- package/src/core/commands/team/start.md +10 -6
- package/src/core/commands/tests.md +1 -0
- package/src/core/commands/verify.md +27 -1
- package/src/core/commands/workflow.md +2 -0
- package/src/core/experts/_core-expertise.yaml +105 -0
- package/src/core/experts/analytics/expertise.yaml +5 -99
- package/src/core/experts/codebase-query/expertise.yaml +3 -72
- package/src/core/experts/compliance/expertise.yaml +6 -72
- package/src/core/experts/database/expertise.yaml +9 -52
- package/src/core/experts/documentation/expertise.yaml +7 -140
- package/src/core/experts/integrations/expertise.yaml +7 -127
- package/src/core/experts/mentor/expertise.yaml +8 -35
- package/src/core/experts/monitoring/expertise.yaml +7 -49
- package/src/core/experts/performance/expertise.yaml +1 -26
- package/src/core/experts/security/expertise.yaml +9 -34
- package/src/core/experts/ui/expertise.yaml +6 -36
- package/src/core/knowledge/ads/ad-audit-checklist-scoring.md +424 -0
- package/src/core/knowledge/ads/ad-optimization-logic.md +590 -0
- package/src/core/knowledge/ads/ad-technical-specifications.md +385 -0
- package/src/core/knowledge/ads/definitive-advertising-reference-2026.md +506 -0
- package/src/core/knowledge/ads/paid-advertising-research-2026.md +445 -0
- package/src/core/teams/backend.json +41 -0
- package/src/core/teams/frontend.json +41 -0
- package/src/core/teams/qa.json +41 -0
- package/src/core/teams/solo.json +35 -0
- package/src/core/templates/agileflow-metadata.json +20 -1
- package/tools/cli/commands/setup.js +85 -3
- package/tools/cli/commands/update.js +42 -0
- package/tools/cli/installers/ide/_base-ide.js +42 -5
- package/tools/cli/installers/ide/claude-code.js +71 -3
- package/tools/cli/lib/content-injector.js +160 -12
- package/tools/cli/lib/docs-setup.js +1 -1
- package/src/core/commands/skill/create.md +0 -698
- package/src/core/commands/skill/delete.md +0 -316
- package/src/core/commands/skill/edit.md +0 -359
- package/src/core/commands/skill/test.md +0 -394
- package/src/core/commands/skill/upgrade.md +0 -552
- package/src/core/templates/skill-template.md +0 -117
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* model-profiles.js - Model resolution for audit subagents
|
|
3
|
+
*
|
|
4
|
+
* Resolves which model (haiku/sonnet/opus) to use for agent subagents.
|
|
5
|
+
* Models are specified inline via command arguments (MODEL=opus).
|
|
6
|
+
*
|
|
7
|
+
* Resolution order:
|
|
8
|
+
* 1. Explicit MODEL= argument (highest priority)
|
|
9
|
+
* 2. Agent frontmatter model (from .md file)
|
|
10
|
+
* 3. Fallback: 'haiku'
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* const { resolveModel, estimateCost } = require('./model-profiles');
|
|
14
|
+
* const model = resolveModel('opus', 'haiku'); // returns 'opus'
|
|
15
|
+
* const model2 = resolveModel(null, 'sonnet'); // returns 'sonnet'
|
|
16
|
+
* const model3 = resolveModel(null, null); // returns 'haiku'
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const VALID_MODELS = ['haiku', 'sonnet', 'opus'];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Resolve which model to use for a given agent.
|
|
23
|
+
*
|
|
24
|
+
* Resolution order:
|
|
25
|
+
* 1. Explicit model argument (MODEL= from command)
|
|
26
|
+
* 2. Agent frontmatter model
|
|
27
|
+
* 3. Fallback: 'haiku'
|
|
28
|
+
*
|
|
29
|
+
* @param {string} [explicitModel] - MODEL= argument value
|
|
30
|
+
* @param {string} [frontmatterModel] - Model from agent .md frontmatter
|
|
31
|
+
* @returns {string} Model name: 'haiku', 'sonnet', or 'opus'
|
|
32
|
+
*/
|
|
33
|
+
function resolveModel(explicitModel, frontmatterModel) {
|
|
34
|
+
// 1. Explicit MODEL= argument
|
|
35
|
+
if (explicitModel && VALID_MODELS.includes(explicitModel.toLowerCase())) {
|
|
36
|
+
return explicitModel.toLowerCase();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 2. Frontmatter model
|
|
40
|
+
if (frontmatterModel && VALID_MODELS.includes(frontmatterModel.toLowerCase())) {
|
|
41
|
+
return frontmatterModel.toLowerCase();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 3. Fallback
|
|
45
|
+
return 'haiku';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Validate a model name.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} model - Model name to validate
|
|
52
|
+
* @returns {boolean} True if valid
|
|
53
|
+
*/
|
|
54
|
+
function isValidModel(model) {
|
|
55
|
+
return !!model && VALID_MODELS.includes(model.toLowerCase());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Estimate cost multiplier for a model relative to haiku baseline.
|
|
60
|
+
*
|
|
61
|
+
* @param {string} model - Model name
|
|
62
|
+
* @param {number} [analyzerCount=5] - Number of analyzers
|
|
63
|
+
* @param {number} [partitions=1] - Number of partitions (extreme mode)
|
|
64
|
+
* @returns {{ multiplier: number, model: string, perAnalyzerCost: string, totalEstimate: string, partitions?: number, totalSessions?: number }}
|
|
65
|
+
*/
|
|
66
|
+
function estimateCost(model, analyzerCount, partitions) {
|
|
67
|
+
let MODEL_PRICING;
|
|
68
|
+
try {
|
|
69
|
+
MODEL_PRICING = require('./team-events').MODEL_PRICING;
|
|
70
|
+
} catch (_) {
|
|
71
|
+
MODEL_PRICING = {
|
|
72
|
+
haiku: { input: 0.8, output: 4.0 },
|
|
73
|
+
sonnet: { input: 3.0, output: 15.0 },
|
|
74
|
+
opus: { input: 15.0, output: 75.0 },
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const count = analyzerCount || 5;
|
|
79
|
+
const partCount = typeof partitions === 'number' && partitions > 1 ? partitions : 1;
|
|
80
|
+
const resolved = resolveModel(model);
|
|
81
|
+
const pricing = MODEL_PRICING[resolved] || MODEL_PRICING.haiku;
|
|
82
|
+
const haikuPricing = MODEL_PRICING.haiku;
|
|
83
|
+
|
|
84
|
+
const multiplier = pricing.output / haikuPricing.output;
|
|
85
|
+
const perAnalyzerCostNum =
|
|
86
|
+
(pricing.input * 50000) / 1_000_000 + (pricing.output * 10000) / 1_000_000;
|
|
87
|
+
const perAnalyzer = `$${perAnalyzerCostNum.toFixed(3)}`;
|
|
88
|
+
|
|
89
|
+
// For extreme mode: each partition has a coordinator + all analyzers as sub-agents
|
|
90
|
+
// Estimated cost per partition coordinator session in USD (~10k input + 2k output at haiku rates)
|
|
91
|
+
const coordinatorCostUSD = 0.05;
|
|
92
|
+
const totalSessions = partCount * count;
|
|
93
|
+
const totalCost =
|
|
94
|
+
partCount > 1
|
|
95
|
+
? partCount * coordinatorCostUSD + totalSessions * perAnalyzerCostNum
|
|
96
|
+
: count * perAnalyzerCostNum;
|
|
97
|
+
|
|
98
|
+
const result = {
|
|
99
|
+
multiplier: Math.round(multiplier * 100) / 100,
|
|
100
|
+
model: resolved,
|
|
101
|
+
perAnalyzerCost: perAnalyzer,
|
|
102
|
+
totalEstimate: `~$${totalCost.toFixed(2)}`,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
if (partCount > 1) {
|
|
106
|
+
result.partitions = partCount;
|
|
107
|
+
result.totalSessions = totalSessions;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = {
|
|
114
|
+
VALID_MODELS,
|
|
115
|
+
resolveModel,
|
|
116
|
+
isValidModel,
|
|
117
|
+
estimateCost,
|
|
118
|
+
};
|
|
@@ -561,6 +561,164 @@ function createValidationReport(gateResults, options = {}) {
|
|
|
561
561
|
return lines.join('\n');
|
|
562
562
|
}
|
|
563
563
|
|
|
564
|
+
// ============================================================================
|
|
565
|
+
// CI Feedback Loop
|
|
566
|
+
// ============================================================================
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Default CI feedback loop configuration
|
|
570
|
+
*/
|
|
571
|
+
const CI_FEEDBACK_DEFAULTS = {
|
|
572
|
+
enabled: true,
|
|
573
|
+
max_rounds: 3,
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Load CI feedback loop config from agileflow-metadata.json
|
|
578
|
+
* @param {string} projectRoot - Project root directory
|
|
579
|
+
* @returns {Object} CI feedback loop config
|
|
580
|
+
*/
|
|
581
|
+
function loadCIFeedbackConfig(projectRoot) {
|
|
582
|
+
const metadataPath = path.join(projectRoot, 'docs', '00-meta', 'agileflow-metadata.json');
|
|
583
|
+
try {
|
|
584
|
+
if (fs.existsSync(metadataPath)) {
|
|
585
|
+
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
|
|
586
|
+
if (metadata.ci_feedback_loops) {
|
|
587
|
+
return {
|
|
588
|
+
...CI_FEEDBACK_DEFAULTS,
|
|
589
|
+
...metadata.ci_feedback_loops,
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
} catch {
|
|
594
|
+
// Fall through to defaults
|
|
595
|
+
}
|
|
596
|
+
return { ...CI_FEEDBACK_DEFAULTS };
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Execute a CI feedback loop - runs gates, and if they fail, returns
|
|
601
|
+
* structured feedback for the agent to retry (up to max_rounds).
|
|
602
|
+
*
|
|
603
|
+
* This implements the Stripe "Minions" pattern: deterministic CI check
|
|
604
|
+
* followed by agent retry, with a hard iteration limit.
|
|
605
|
+
*
|
|
606
|
+
* @param {Object[]} gates - Quality gate definitions to check
|
|
607
|
+
* @param {Object} options - Loop options
|
|
608
|
+
* @param {string} [options.projectRoot] - Project root directory
|
|
609
|
+
* @param {number} [options.maxRounds] - Override max retry rounds (default: from config)
|
|
610
|
+
* @param {number} [options.currentRound] - Current round number (1-based, default: 1)
|
|
611
|
+
* @param {string} [options.cwd] - Working directory for gate execution
|
|
612
|
+
* @returns {Object} Loop result with status and agent feedback
|
|
613
|
+
*/
|
|
614
|
+
function executeCIFeedbackLoop(gates, options = {}) {
|
|
615
|
+
const { projectRoot = process.cwd(), maxRounds, currentRound = 1, cwd } = options;
|
|
616
|
+
|
|
617
|
+
const config = loadCIFeedbackConfig(projectRoot);
|
|
618
|
+
|
|
619
|
+
if (!config.enabled) {
|
|
620
|
+
return {
|
|
621
|
+
status: 'disabled',
|
|
622
|
+
message: 'CI feedback loops are disabled in agileflow-metadata.json',
|
|
623
|
+
should_retry: false,
|
|
624
|
+
round: currentRound,
|
|
625
|
+
max_rounds: 0,
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
const effectiveMaxRounds = maxRounds || config.max_rounds || CI_FEEDBACK_DEFAULTS.max_rounds;
|
|
630
|
+
|
|
631
|
+
// Execute all gates
|
|
632
|
+
const gateResults = executeGates(gates, { cwd, stopOnFailure: false });
|
|
633
|
+
|
|
634
|
+
if (gateResults.passed) {
|
|
635
|
+
return {
|
|
636
|
+
status: 'passed',
|
|
637
|
+
message: `All ${gateResults.passed_count} gates passed on round ${currentRound}`,
|
|
638
|
+
should_retry: false,
|
|
639
|
+
round: currentRound,
|
|
640
|
+
max_rounds: effectiveMaxRounds,
|
|
641
|
+
gate_results: gateResults,
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// Gates failed - determine if we should retry
|
|
646
|
+
const hasRoundsLeft = currentRound < effectiveMaxRounds;
|
|
647
|
+
|
|
648
|
+
if (!hasRoundsLeft) {
|
|
649
|
+
return {
|
|
650
|
+
status: 'exhausted',
|
|
651
|
+
message: `Gates failed after ${currentRound}/${effectiveMaxRounds} rounds. Escalating to human.`,
|
|
652
|
+
should_retry: false,
|
|
653
|
+
round: currentRound,
|
|
654
|
+
max_rounds: effectiveMaxRounds,
|
|
655
|
+
gate_results: gateResults,
|
|
656
|
+
failures: gateResults.results
|
|
657
|
+
.filter(r => r.status === GATE_STATUS.FAILED || r.status === GATE_STATUS.ERROR)
|
|
658
|
+
.map(r => ({
|
|
659
|
+
gate: r.gate,
|
|
660
|
+
message: r.message,
|
|
661
|
+
output: r.output,
|
|
662
|
+
error: r.error,
|
|
663
|
+
})),
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Build structured feedback for agent retry
|
|
668
|
+
const failures = gateResults.results.filter(
|
|
669
|
+
r => r.status === GATE_STATUS.FAILED || r.status === GATE_STATUS.ERROR
|
|
670
|
+
);
|
|
671
|
+
|
|
672
|
+
const feedbackLines = [
|
|
673
|
+
`## CI Feedback Loop - Round ${currentRound}/${effectiveMaxRounds}`,
|
|
674
|
+
'',
|
|
675
|
+
`**${failures.length} gate(s) failed.** ${effectiveMaxRounds - currentRound} retry round(s) remaining.`,
|
|
676
|
+
'',
|
|
677
|
+
'### Failures',
|
|
678
|
+
'',
|
|
679
|
+
];
|
|
680
|
+
|
|
681
|
+
for (const failure of failures) {
|
|
682
|
+
feedbackLines.push(`#### ${failure.gate} (${failure.type})`);
|
|
683
|
+
feedbackLines.push(`- **Status**: ${failure.status}`);
|
|
684
|
+
feedbackLines.push(`- **Message**: ${failure.message}`);
|
|
685
|
+
if (failure.output) {
|
|
686
|
+
feedbackLines.push('- **Output**:');
|
|
687
|
+
feedbackLines.push('```');
|
|
688
|
+
feedbackLines.push(failure.output);
|
|
689
|
+
feedbackLines.push('```');
|
|
690
|
+
}
|
|
691
|
+
if (failure.error) {
|
|
692
|
+
feedbackLines.push('- **Error**:');
|
|
693
|
+
feedbackLines.push('```');
|
|
694
|
+
feedbackLines.push(failure.error);
|
|
695
|
+
feedbackLines.push('```');
|
|
696
|
+
}
|
|
697
|
+
feedbackLines.push('');
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
feedbackLines.push('### Action Required');
|
|
701
|
+
feedbackLines.push('');
|
|
702
|
+
feedbackLines.push('Fix the failing gates above, then re-run verification.');
|
|
703
|
+
|
|
704
|
+
return {
|
|
705
|
+
status: 'retry',
|
|
706
|
+
message: `Round ${currentRound}/${effectiveMaxRounds} failed. Agent should fix and retry.`,
|
|
707
|
+
should_retry: true,
|
|
708
|
+
round: currentRound,
|
|
709
|
+
max_rounds: effectiveMaxRounds,
|
|
710
|
+
next_round: currentRound + 1,
|
|
711
|
+
gate_results: gateResults,
|
|
712
|
+
agent_feedback: feedbackLines.join('\n'),
|
|
713
|
+
failures: failures.map(r => ({
|
|
714
|
+
gate: r.gate,
|
|
715
|
+
message: r.message,
|
|
716
|
+
output: r.output,
|
|
717
|
+
error: r.error,
|
|
718
|
+
})),
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
|
|
564
722
|
// ============================================================================
|
|
565
723
|
// Exports
|
|
566
724
|
// ============================================================================
|
|
@@ -595,4 +753,9 @@ module.exports = {
|
|
|
595
753
|
|
|
596
754
|
// Reporting
|
|
597
755
|
createValidationReport,
|
|
756
|
+
|
|
757
|
+
// CI Feedback Loop
|
|
758
|
+
CI_FEEDBACK_DEFAULTS,
|
|
759
|
+
loadCIFeedbackConfig,
|
|
760
|
+
executeCIFeedbackLoop,
|
|
598
761
|
};
|
|
@@ -233,6 +233,24 @@ const FEATURE_DETECTORS = {
|
|
|
233
233
|
});
|
|
234
234
|
},
|
|
235
235
|
|
|
236
|
+
'scale-adaptive': signals => {
|
|
237
|
+
const { scale } = signals;
|
|
238
|
+
if (!scale || !scale.tier) return null;
|
|
239
|
+
// Only trigger when scale info provides actionable guidance
|
|
240
|
+
const rec = scale.recommendations;
|
|
241
|
+
if (!rec) return null;
|
|
242
|
+
// Suggest scale-adaptive workflow when project is not medium (the default)
|
|
243
|
+
if (scale.tier === 'medium') return null;
|
|
244
|
+
const label = scale.tier.charAt(0).toUpperCase() + scale.tier.slice(1);
|
|
245
|
+
return recommend('scale-adaptive', {
|
|
246
|
+
priority: scale.tier === 'enterprise' || scale.tier === 'large' ? 'medium' : 'low',
|
|
247
|
+
trigger: `${label} project detected (${scale.metrics.files} files, ${scale.metrics.stories} stories) — ${rec.description}`,
|
|
248
|
+
action: 'suggest',
|
|
249
|
+
command: '/agileflow:workflow',
|
|
250
|
+
phase: 'pre-story',
|
|
251
|
+
});
|
|
252
|
+
},
|
|
253
|
+
|
|
236
254
|
// =========================================================================
|
|
237
255
|
// PLANNING PHASE
|
|
238
256
|
// =========================================================================
|
|
@@ -517,6 +535,29 @@ const FEATURE_DETECTORS = {
|
|
|
517
535
|
});
|
|
518
536
|
},
|
|
519
537
|
|
|
538
|
+
'ac-verify': signals => {
|
|
539
|
+
const { story, tests } = signals;
|
|
540
|
+
if (!story || story.status !== 'in-progress') return null;
|
|
541
|
+
if (!tests || tests.passing !== true) return null; // Only after tests pass
|
|
542
|
+
if (!storyHasAC(story)) return null;
|
|
543
|
+
// Check if AC already verified (count by index to avoid extra keys)
|
|
544
|
+
const acStatus = story.ac_status || {};
|
|
545
|
+
const acList = story.acceptance_criteria || story.ac || [];
|
|
546
|
+
const verifiedCount = acList.filter(
|
|
547
|
+
(_, i) =>
|
|
548
|
+
acStatus[i] === 'verified' || acStatus[i] === 'auto-verified' || acStatus[i] === true
|
|
549
|
+
).length;
|
|
550
|
+
if (verifiedCount === acList.length) return null;
|
|
551
|
+
const unverifiedCount = acList.length - verifiedCount;
|
|
552
|
+
return recommend('ac-verify', {
|
|
553
|
+
priority: 'high',
|
|
554
|
+
trigger: `Tests pass but ${unverifiedCount}/${acList.length} AC unverified`,
|
|
555
|
+
action: 'suggest',
|
|
556
|
+
command: '/agileflow:audit',
|
|
557
|
+
phase: 'post-impl',
|
|
558
|
+
});
|
|
559
|
+
},
|
|
560
|
+
|
|
520
561
|
// =========================================================================
|
|
521
562
|
// POST-IMPLEMENTATION PHASE
|
|
522
563
|
// =========================================================================
|
|
@@ -546,7 +587,7 @@ const FEATURE_DETECTORS = {
|
|
|
546
587
|
priority: 'medium',
|
|
547
588
|
trigger: `${coreFiles} source files modified - logic audit available`,
|
|
548
589
|
action: 'offer',
|
|
549
|
-
command: '/agileflow:
|
|
590
|
+
command: '/agileflow:code:logic',
|
|
550
591
|
phase: 'post-impl',
|
|
551
592
|
});
|
|
552
593
|
},
|
|
@@ -704,6 +745,7 @@ const PHASE_MAP = {
|
|
|
704
745
|
'workflow',
|
|
705
746
|
'template',
|
|
706
747
|
'configure',
|
|
748
|
+
'scale-adaptive',
|
|
707
749
|
],
|
|
708
750
|
planning: [
|
|
709
751
|
'impact',
|
|
@@ -728,6 +770,7 @@ const PHASE_MAP = {
|
|
|
728
770
|
'serve',
|
|
729
771
|
],
|
|
730
772
|
'post-impl': [
|
|
773
|
+
'ac-verify',
|
|
731
774
|
'review',
|
|
732
775
|
'logic-audit',
|
|
733
776
|
'docs',
|