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
|
@@ -71,7 +71,8 @@
|
|
|
71
71
|
"wip": true,
|
|
72
72
|
"context": true,
|
|
73
73
|
"cost": true,
|
|
74
|
-
"git": true
|
|
74
|
+
"git": true,
|
|
75
|
+
"ultradeep": true
|
|
75
76
|
}
|
|
76
77
|
},
|
|
77
78
|
"mcp": {
|
|
@@ -127,5 +128,23 @@
|
|
|
127
128
|
"security": {
|
|
128
129
|
"mcpJsonGitignored": false,
|
|
129
130
|
"envGitignored": false
|
|
131
|
+
},
|
|
132
|
+
"models": {
|
|
133
|
+
"default_audit_model": null,
|
|
134
|
+
"description": "Override via MODEL=haiku|sonnet|opus in audit command arguments. null = use agent defaults."
|
|
135
|
+
},
|
|
136
|
+
"ci_feedback_loops": {
|
|
137
|
+
"enabled": true,
|
|
138
|
+
"max_rounds": 3,
|
|
139
|
+
"description": "Auto-retry agent work when CI/tests fail, up to max_rounds before escalating to human"
|
|
140
|
+
},
|
|
141
|
+
"ultradeep": {
|
|
142
|
+
"tab_naming": "prefix:name",
|
|
143
|
+
"custom_colors": null,
|
|
144
|
+
"auto_attach": true,
|
|
145
|
+
"completion_timeout_minutes": 30,
|
|
146
|
+
"max_sessions_per_audit": 20,
|
|
147
|
+
"stagger_seconds": 3,
|
|
148
|
+
"max_concurrent": 0
|
|
130
149
|
}
|
|
131
150
|
}
|
|
@@ -89,7 +89,14 @@ module.exports = {
|
|
|
89
89
|
config = await promptInstall();
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
const totalSteps = 5;
|
|
93
|
+
let currentStep = 0;
|
|
94
|
+
const step = label => {
|
|
95
|
+
currentStep++;
|
|
96
|
+
return `[${currentStep}/${totalSteps}] ${label}`;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
displaySection(step('Installing Core Content'), `Target: ${config.directory}`);
|
|
93
100
|
|
|
94
101
|
// Run core installation
|
|
95
102
|
const coreResult = await installer.install(config);
|
|
@@ -104,17 +111,81 @@ module.exports = {
|
|
|
104
111
|
success(`Installed ${coreResult.counts.skills} skills`);
|
|
105
112
|
|
|
106
113
|
// Setup IDE configurations
|
|
107
|
-
displaySection('Configuring IDEs');
|
|
114
|
+
displaySection(step('Configuring IDEs'));
|
|
108
115
|
|
|
109
116
|
ideManager.setAgileflowFolder(config.agileflowFolder);
|
|
110
117
|
ideManager.setDocsFolder(config.docsFolder);
|
|
111
118
|
|
|
119
|
+
// Check for existing IDE configs before overwriting
|
|
120
|
+
if (!options.yes) {
|
|
121
|
+
const existingConfigs = [];
|
|
122
|
+
const ideConfigDirs = {
|
|
123
|
+
'claude-code': '.claude',
|
|
124
|
+
cursor: '.cursor',
|
|
125
|
+
windsurf: '.windsurf',
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
for (const ide of config.ides) {
|
|
129
|
+
const configDir = ideConfigDirs[ide];
|
|
130
|
+
if (configDir) {
|
|
131
|
+
const fullPath = path.join(config.directory, configDir);
|
|
132
|
+
if (fs.existsSync(fullPath)) {
|
|
133
|
+
existingConfigs.push({ ide, dir: configDir });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (existingConfigs.length > 0) {
|
|
139
|
+
const { confirmOverwrite } = require('inquirer');
|
|
140
|
+
const configList = existingConfigs.map(c => ` ${c.dir}/`).join('\n');
|
|
141
|
+
console.log(chalk.yellow(`\n Existing IDE configs detected:\n${configList}\n`));
|
|
142
|
+
console.log(
|
|
143
|
+
chalk.dim(
|
|
144
|
+
' AgileFlow will add commands and hooks to these directories.\n' +
|
|
145
|
+
' Existing settings will be merged (not replaced).\n'
|
|
146
|
+
)
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
let proceed = true;
|
|
150
|
+
try {
|
|
151
|
+
const inquirer = require('inquirer');
|
|
152
|
+
const answer = await inquirer.prompt([
|
|
153
|
+
{
|
|
154
|
+
type: 'confirm',
|
|
155
|
+
name: 'proceed',
|
|
156
|
+
message: 'Continue with IDE configuration?',
|
|
157
|
+
default: true,
|
|
158
|
+
},
|
|
159
|
+
]);
|
|
160
|
+
proceed = answer.proceed;
|
|
161
|
+
} catch {
|
|
162
|
+
// If inquirer not available or stdin not interactive, proceed
|
|
163
|
+
proceed = true;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!proceed) {
|
|
167
|
+
info('Skipping IDE configuration. Core installation is complete.');
|
|
168
|
+
console.log(chalk.dim(' Run setup again to configure IDEs later.\n'));
|
|
169
|
+
// Skip to docs structure
|
|
170
|
+
displaySection('Creating Documentation Structure', `Folder: ${config.docsFolder}/`);
|
|
171
|
+
const docsResult = await createDocsStructure(config.directory, config.docsFolder, {
|
|
172
|
+
updateGitignore: config.updateGitignore,
|
|
173
|
+
});
|
|
174
|
+
if (!docsResult.success) {
|
|
175
|
+
error('Failed to create docs structure');
|
|
176
|
+
}
|
|
177
|
+
console.log(chalk.green('\n✨ Setup complete (without IDE configs)!\n'));
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
112
183
|
for (const ide of config.ides) {
|
|
113
184
|
await ideManager.setup(ide, config.directory, coreResult.path);
|
|
114
185
|
}
|
|
115
186
|
|
|
116
187
|
// Create docs structure
|
|
117
|
-
displaySection('Creating Documentation Structure', `Folder: ${config.docsFolder}/`);
|
|
188
|
+
displaySection(step('Creating Documentation Structure'), `Folder: ${config.docsFolder}/`);
|
|
118
189
|
const docsResult = await createDocsStructure(config.directory, config.docsFolder, {
|
|
119
190
|
updateGitignore: config.updateGitignore,
|
|
120
191
|
});
|
|
@@ -127,6 +198,7 @@ module.exports = {
|
|
|
127
198
|
}
|
|
128
199
|
|
|
129
200
|
// Update metadata with config tracking
|
|
201
|
+
displaySection(step('Updating Configuration'));
|
|
130
202
|
try {
|
|
131
203
|
const metadataPath = path.join(
|
|
132
204
|
config.directory,
|
|
@@ -149,6 +221,16 @@ module.exports = {
|
|
|
149
221
|
}
|
|
150
222
|
|
|
151
223
|
// Final summary
|
|
224
|
+
displaySection(step('Verifying Installation'));
|
|
225
|
+
const { counts } = coreResult;
|
|
226
|
+
const totalItems = (counts.commands || 0) + (counts.agents || 0) + (counts.skills || 0);
|
|
227
|
+
console.log(
|
|
228
|
+
chalk.green(
|
|
229
|
+
` Setup complete: ${counts.commands} commands, ${counts.agents} agents, ${counts.skills} skills installed`
|
|
230
|
+
)
|
|
231
|
+
);
|
|
232
|
+
console.log(chalk.dim(` IDEs configured: ${config.ides.join(', ')}`));
|
|
233
|
+
|
|
152
234
|
console.log(chalk.green('\n✨ Setup complete!\n'));
|
|
153
235
|
|
|
154
236
|
console.log(chalk.bold('Get started:'));
|
|
@@ -230,6 +230,48 @@ module.exports = {
|
|
|
230
230
|
|
|
231
231
|
console.log(chalk.green(`\n✨ Update complete! (${status.version} → ${latestVersion})\n`));
|
|
232
232
|
|
|
233
|
+
// Show changelog diff between old and new version
|
|
234
|
+
try {
|
|
235
|
+
const fs = require('node:fs');
|
|
236
|
+
const changelogPath = path.join(status.path, 'CHANGELOG.md');
|
|
237
|
+
if (fs.existsSync(changelogPath)) {
|
|
238
|
+
const changelog = fs.readFileSync(changelogPath, 'utf8');
|
|
239
|
+
const oldVer = status.version.replace(/^v/, '');
|
|
240
|
+
const newVer = latestVersion.replace(/^v/, '');
|
|
241
|
+
|
|
242
|
+
// Extract sections between old and new version headers
|
|
243
|
+
const versionPattern = /^##\s+\[?\d+\.\d+\.\d+\]?/m;
|
|
244
|
+
const lines = changelog.split('\n');
|
|
245
|
+
const relevantLines = [];
|
|
246
|
+
let capturing = false;
|
|
247
|
+
|
|
248
|
+
for (const line of lines) {
|
|
249
|
+
if (versionPattern.test(line)) {
|
|
250
|
+
if (line.includes(oldVer)) {
|
|
251
|
+
break; // Stop at old version
|
|
252
|
+
}
|
|
253
|
+
capturing = true;
|
|
254
|
+
}
|
|
255
|
+
if (capturing) {
|
|
256
|
+
relevantLines.push(line);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (relevantLines.length > 0) {
|
|
261
|
+
const maxLines = 20;
|
|
262
|
+
const display = relevantLines.slice(0, maxLines);
|
|
263
|
+
console.log(chalk.hex('#e8683a').bold(` What's New in v${newVer}:\n`));
|
|
264
|
+
display.forEach(l => console.log(chalk.dim(` ${l}`)));
|
|
265
|
+
if (relevantLines.length > maxLines) {
|
|
266
|
+
console.log(chalk.dim(` ... and ${relevantLines.length - maxLines} more lines`));
|
|
267
|
+
}
|
|
268
|
+
console.log(chalk.dim(`\n Run /agileflow:whats-new for full changelog\n`));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
} catch {
|
|
272
|
+
// Changelog display is non-critical
|
|
273
|
+
}
|
|
274
|
+
|
|
233
275
|
// If running from outdated global installation, remind user to update it
|
|
234
276
|
if (
|
|
235
277
|
npmLatestVersion &&
|
|
@@ -82,15 +82,18 @@ class BaseIdeSetup {
|
|
|
82
82
|
* Uses content-transformer module for consistent injection
|
|
83
83
|
* @param {string} content - Template file content
|
|
84
84
|
* @param {string} agileflowDir - AgileFlow installation directory
|
|
85
|
+
* @param {Object} [options] - Additional injection options
|
|
86
|
+
* @param {boolean} [options.minimal] - When true, skip full list injection (use discovery pointers)
|
|
85
87
|
* @returns {string} Content with placeholders replaced
|
|
86
88
|
*/
|
|
87
|
-
injectDynamicContent(content, agileflowDir) {
|
|
89
|
+
injectDynamicContent(content, agileflowDir, options = {}) {
|
|
88
90
|
// agileflowDir is the user's .agileflow installation directory
|
|
89
91
|
// which has agents/, commands/, skills/ at the root level
|
|
90
92
|
return injectDynamicContentHelper(content, {
|
|
91
93
|
coreDir: agileflowDir,
|
|
92
94
|
agileflowFolder: this.agileflowFolder,
|
|
93
95
|
version: this.getVersion(),
|
|
96
|
+
minimal: options.minimal || false,
|
|
94
97
|
});
|
|
95
98
|
}
|
|
96
99
|
|
|
@@ -107,6 +110,30 @@ class BaseIdeSetup {
|
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Detect minimal context mode from project metadata.
|
|
115
|
+
* Reads the contextVerbosity setting from /configure.
|
|
116
|
+
* @param {string} projectDir - Project directory
|
|
117
|
+
* @returns {boolean} True if minimal mode should be used
|
|
118
|
+
*/
|
|
119
|
+
_detectMinimalMode(projectDir) {
|
|
120
|
+
try {
|
|
121
|
+
const metadataPath = path.join(
|
|
122
|
+
projectDir,
|
|
123
|
+
this.docsFolder,
|
|
124
|
+
'00-meta',
|
|
125
|
+
'agileflow-metadata.json'
|
|
126
|
+
);
|
|
127
|
+
if (!fs.existsSync(metadataPath)) return false;
|
|
128
|
+
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
|
|
129
|
+
const mode = metadata?.features?.contextVerbosity?.mode;
|
|
130
|
+
if (mode === 'minimal') return true;
|
|
131
|
+
return false;
|
|
132
|
+
} catch {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
110
137
|
/**
|
|
111
138
|
* Main setup method - must be implemented by subclasses
|
|
112
139
|
* @param {string} projectDir - Project directory
|
|
@@ -128,6 +155,7 @@ class BaseIdeSetup {
|
|
|
128
155
|
* @param {string} config.agileflowFolder - AgileFlow folder name (e.g., 'agileflow', 'AgileFlow')
|
|
129
156
|
* @param {string} [config.commandLabel='commands'] - Label for commands in output (e.g., 'workflows')
|
|
130
157
|
* @param {string} [config.agentLabel='agents'] - Label for agents in output
|
|
158
|
+
* @param {boolean} [config.minimal=false] - When true, skip full agent/command list injection. Auto-detected from metadata if not set.
|
|
131
159
|
* @returns {Promise<{success: boolean, commands: number, agents: number}>}
|
|
132
160
|
*/
|
|
133
161
|
async setupStandard(projectDir, agileflowDir, config) {
|
|
@@ -136,8 +164,12 @@ class BaseIdeSetup {
|
|
|
136
164
|
agileflowFolder,
|
|
137
165
|
commandLabel = 'commands',
|
|
138
166
|
agentLabel = 'agents',
|
|
167
|
+
minimal: explicitMinimal,
|
|
139
168
|
} = config;
|
|
140
169
|
|
|
170
|
+
// Auto-detect minimal mode from /configure context verbosity setting
|
|
171
|
+
const minimal = explicitMinimal ?? this._detectMinimalMode(projectDir);
|
|
172
|
+
|
|
141
173
|
console.log(chalk.hex('#e8683a')(` Setting up ${this.displayName}...`));
|
|
142
174
|
|
|
143
175
|
// Clean up old installation first
|
|
@@ -154,7 +186,9 @@ class BaseIdeSetup {
|
|
|
154
186
|
commandsSource,
|
|
155
187
|
agileflowTargetDir,
|
|
156
188
|
agileflowDir,
|
|
157
|
-
true // Inject dynamic content
|
|
189
|
+
true, // Inject dynamic content
|
|
190
|
+
null, // No IDE transform
|
|
191
|
+
{ minimal } // Pass minimal flag for content injection
|
|
158
192
|
);
|
|
159
193
|
|
|
160
194
|
// Install agents as subdirectory
|
|
@@ -379,6 +413,7 @@ class BaseIdeSetup {
|
|
|
379
413
|
* @param {string} agileflowDir - AgileFlow installation directory (for dynamic content)
|
|
380
414
|
* @param {boolean} injectDynamic - Whether to inject dynamic content (only for top-level commands)
|
|
381
415
|
* @param {Function} [ideTransform] - Optional IDE transformation function: (content, filename) => string
|
|
416
|
+
* @param {Object} [injectionOptions] - Options passed to injectDynamicContent (e.g., { minimal: true })
|
|
382
417
|
* @returns {Promise<{commands: number, subdirs: number}>} Count of installed items
|
|
383
418
|
* @throws {CommandInstallationError} If command installation fails
|
|
384
419
|
* @throws {FilePermissionError} If permission denied
|
|
@@ -402,7 +437,8 @@ class BaseIdeSetup {
|
|
|
402
437
|
targetDir,
|
|
403
438
|
agileflowDir,
|
|
404
439
|
injectDynamic = false,
|
|
405
|
-
ideTransform = null
|
|
440
|
+
ideTransform = null,
|
|
441
|
+
injectionOptions = {}
|
|
406
442
|
) {
|
|
407
443
|
let commandCount = 0;
|
|
408
444
|
let subdirCount = 0;
|
|
@@ -434,7 +470,7 @@ class BaseIdeSetup {
|
|
|
434
470
|
// Inject dynamic content if enabled (for top-level commands)
|
|
435
471
|
if (injectDynamic) {
|
|
436
472
|
try {
|
|
437
|
-
content = this.injectDynamicContent(content, agileflowDir);
|
|
473
|
+
content = this.injectDynamicContent(content, agileflowDir, injectionOptions);
|
|
438
474
|
} catch (injectionError) {
|
|
439
475
|
throw new ContentInjectionError(this.displayName, sourcePath, injectionError.message);
|
|
440
476
|
}
|
|
@@ -467,7 +503,8 @@ class BaseIdeSetup {
|
|
|
467
503
|
targetPath,
|
|
468
504
|
agileflowDir,
|
|
469
505
|
false, // Don't inject dynamic content in subdirectories
|
|
470
|
-
ideTransform // Pass ideTransform to recursive calls
|
|
506
|
+
ideTransform, // Pass ideTransform to recursive calls
|
|
507
|
+
injectionOptions // Pass injection options to recursive calls
|
|
471
508
|
);
|
|
472
509
|
commandCount += subResult.commands;
|
|
473
510
|
subdirCount += 1 + subResult.subdirs;
|
|
@@ -52,11 +52,11 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
|
|
52
52
|
await this.installCommandsRecursive(agentsSource, spawnableAgentsDir, agileflowDir, false);
|
|
53
53
|
console.log(chalk.dim(` - Spawnable agents: .claude/agents/agileflow/`));
|
|
54
54
|
|
|
55
|
-
// Claude Code specific: Create skills directory for
|
|
56
|
-
//
|
|
55
|
+
// Claude Code specific: Create skills directory for marketplace skills
|
|
56
|
+
// Users browse and install skills via /agileflow:skill:recommend or npx skills add
|
|
57
57
|
const skillsTargetDir = path.join(ideDir, 'skills');
|
|
58
58
|
await this.ensureDir(skillsTargetDir);
|
|
59
|
-
console.log(chalk.dim(` - Skills directory: .claude/skills/ (for
|
|
59
|
+
console.log(chalk.dim(` - Skills directory: .claude/skills/ (for marketplace skills)`));
|
|
60
60
|
|
|
61
61
|
// Claude Code specific: Setup damage control hooks
|
|
62
62
|
await this.setupDamageControl(projectDir, agileflowDir, ideDir, options);
|
|
@@ -64,6 +64,9 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
|
|
64
64
|
// Claude Code specific: Setup SessionStart hooks (welcome, archive, context-loader)
|
|
65
65
|
await this.setupSessionStartHooks(projectDir, agileflowDir, ideDir, options);
|
|
66
66
|
|
|
67
|
+
// Claude Code specific: Setup PostToolUse hooks (native team observer)
|
|
68
|
+
await this.setupPostToolUseHooks(projectDir, agileflowDir, ideDir, options);
|
|
69
|
+
|
|
67
70
|
return result;
|
|
68
71
|
}
|
|
69
72
|
|
|
@@ -297,6 +300,71 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
|
|
297
300
|
);
|
|
298
301
|
}
|
|
299
302
|
|
|
303
|
+
/**
|
|
304
|
+
* Setup PostToolUse hooks for native Agent Teams observability.
|
|
305
|
+
* Registers native-team-observer.js for TeamCreate, SendMessage, ListTeams.
|
|
306
|
+
* @param {string} projectDir - Project directory
|
|
307
|
+
* @param {string} agileflowDir - AgileFlow installation directory
|
|
308
|
+
* @param {string} claudeDir - .claude directory path
|
|
309
|
+
* @param {Object} options - Setup options
|
|
310
|
+
*/
|
|
311
|
+
async setupPostToolUseHooks(projectDir, agileflowDir, claudeDir, options = {}) {
|
|
312
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
313
|
+
let settings = {};
|
|
314
|
+
|
|
315
|
+
if (fs.existsSync(settingsPath)) {
|
|
316
|
+
try {
|
|
317
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
318
|
+
} catch (e) {
|
|
319
|
+
settings = {};
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (!settings.hooks) settings.hooks = {};
|
|
324
|
+
if (!settings.hooks.PostToolUse) settings.hooks.PostToolUse = [];
|
|
325
|
+
|
|
326
|
+
const observerCommand = 'node $CLAUDE_PROJECT_DIR/.agileflow/scripts/native-team-observer.js';
|
|
327
|
+
|
|
328
|
+
const postToolUseHooks = [
|
|
329
|
+
{
|
|
330
|
+
matcher: 'TeamCreate',
|
|
331
|
+
hooks: [{ type: 'command', command: observerCommand, timeout: 5000 }],
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
matcher: 'SendMessage',
|
|
335
|
+
hooks: [{ type: 'command', command: observerCommand, timeout: 5000 }],
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
matcher: 'ListTeams',
|
|
339
|
+
hooks: [{ type: 'command', command: observerCommand, timeout: 5000 }],
|
|
340
|
+
},
|
|
341
|
+
];
|
|
342
|
+
|
|
343
|
+
// Merge with existing hooks (don't duplicate)
|
|
344
|
+
for (const newHook of postToolUseHooks) {
|
|
345
|
+
const existingIdx = settings.hooks.PostToolUse.findIndex(h => h.matcher === newHook.matcher);
|
|
346
|
+
if (existingIdx === -1) {
|
|
347
|
+
settings.hooks.PostToolUse.push(newHook);
|
|
348
|
+
} else {
|
|
349
|
+
const existing = settings.hooks.PostToolUse[existingIdx];
|
|
350
|
+
if (!existing.hooks) existing.hooks = [];
|
|
351
|
+
const hasObserver = existing.hooks.some(
|
|
352
|
+
h => h.type === 'command' && h.command && h.command.includes('native-team-observer')
|
|
353
|
+
);
|
|
354
|
+
if (!hasObserver) {
|
|
355
|
+
existing.hooks.push(newHook.hooks[0]);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
361
|
+
console.log(
|
|
362
|
+
chalk.dim(
|
|
363
|
+
` - PostToolUse hooks: native team observer (TeamCreate, SendMessage, ListTeams)`
|
|
364
|
+
)
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
|
|
300
368
|
/**
|
|
301
369
|
* Remove AgileFlow command duplicates from user-level ~/.claude/commands/
|
|
302
370
|
* When the same command exists in both ~/.claude/commands/ and
|
|
@@ -70,9 +70,46 @@ function isPathSafe(filePath, baseDir) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
|
-
*
|
|
73
|
+
* Derive agent category from name for compact grouping.
|
|
74
|
+
* @param {string} name - Agent name
|
|
75
|
+
* @returns {string} Category name
|
|
76
|
+
*/
|
|
77
|
+
function categorizeAgent(name) {
|
|
78
|
+
// Audit analyzer families
|
|
79
|
+
const analyzerMatch = name.match(/^(logic|security|perf|test|completeness|legal)-analyzer-/);
|
|
80
|
+
if (analyzerMatch) {
|
|
81
|
+
const familyNames = {
|
|
82
|
+
logic: 'Logic',
|
|
83
|
+
security: 'Security',
|
|
84
|
+
perf: 'Performance',
|
|
85
|
+
test: 'Tests',
|
|
86
|
+
completeness: 'Completeness',
|
|
87
|
+
legal: 'Legal',
|
|
88
|
+
};
|
|
89
|
+
return `Audit - ${familyNames[analyzerMatch[1]] || analyzerMatch[1]}`;
|
|
90
|
+
}
|
|
91
|
+
// Consensus coordinators for audit families
|
|
92
|
+
const consensusMatch = name.match(/^(logic|security|perf|test|completeness|legal)-consensus$/);
|
|
93
|
+
if (consensusMatch) {
|
|
94
|
+
const familyNames = {
|
|
95
|
+
logic: 'Logic',
|
|
96
|
+
security: 'Security',
|
|
97
|
+
perf: 'Performance',
|
|
98
|
+
test: 'Tests',
|
|
99
|
+
completeness: 'Completeness',
|
|
100
|
+
legal: 'Legal',
|
|
101
|
+
};
|
|
102
|
+
return `Audit - ${familyNames[consensusMatch[1]] || consensusMatch[1]}`;
|
|
103
|
+
}
|
|
104
|
+
if (name.startsWith('council-')) return 'Council';
|
|
105
|
+
if (name.endsWith('-validator')) return 'Validation';
|
|
106
|
+
return 'Domain';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Scan agents directory and generate compact category-grouped agent list
|
|
74
111
|
* @param {string} agentsDir - Path to agents directory
|
|
75
|
-
* @returns {string} Formatted agent list
|
|
112
|
+
* @returns {string} Formatted agent list grouped by category
|
|
76
113
|
*/
|
|
77
114
|
function generateAgentList(agentsDir) {
|
|
78
115
|
if (!fs.existsSync(agentsDir)) return '';
|
|
@@ -117,16 +154,20 @@ function generateAgentList(agentsDir) {
|
|
|
117
154
|
|
|
118
155
|
// Sanitize the count value
|
|
119
156
|
const safeCount = sanitize.count(agents.length);
|
|
157
|
+
|
|
158
|
+
// Group by category for compact output
|
|
159
|
+
const categories = {};
|
|
160
|
+
for (const agent of agents) {
|
|
161
|
+
const cat = categorizeAgent(agent.name);
|
|
162
|
+
if (!categories[cat]) categories[cat] = [];
|
|
163
|
+
categories[cat].push(agent.name);
|
|
164
|
+
}
|
|
165
|
+
|
|
120
166
|
let output = `**AVAILABLE AGENTS (${safeCount} total)**:\n\n`;
|
|
121
167
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
output += ` - **Purpose**: ${agent.description}\n`;
|
|
126
|
-
output += ` - **Tools**: ${agent.tools.join(', ')}\n`;
|
|
127
|
-
output += ` - **Usage**: \`subagent_type: "agileflow-${agent.name}"\`\n`;
|
|
128
|
-
output += `\n`;
|
|
129
|
-
});
|
|
168
|
+
for (const [category, names] of Object.entries(categories)) {
|
|
169
|
+
output += `**${category}**: ${names.join(', ')}\n`;
|
|
170
|
+
}
|
|
130
171
|
|
|
131
172
|
return output;
|
|
132
173
|
}
|
|
@@ -235,6 +276,94 @@ function generateCommandList(commandsDir) {
|
|
|
235
276
|
return output;
|
|
236
277
|
}
|
|
237
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Generate a compact category summary for agents (no individual names).
|
|
281
|
+
* Used by minimal mode and generators that want a discovery-oriented summary.
|
|
282
|
+
* @param {string} agentsDir - Path to agents directory
|
|
283
|
+
* @returns {string} Compact category summary with counts
|
|
284
|
+
*/
|
|
285
|
+
function generateAgentSummary(agentsDir) {
|
|
286
|
+
if (!fs.existsSync(agentsDir)) return '';
|
|
287
|
+
|
|
288
|
+
const files = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
|
|
289
|
+
const agents = [];
|
|
290
|
+
|
|
291
|
+
for (const file of files) {
|
|
292
|
+
const filePath = path.join(agentsDir, file);
|
|
293
|
+
if (!isPathSafe(filePath, agentsDir)) continue;
|
|
294
|
+
|
|
295
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
296
|
+
const frontmatter = parseFrontmatter(content);
|
|
297
|
+
if (!frontmatter || Object.keys(frontmatter).length === 0) continue;
|
|
298
|
+
|
|
299
|
+
const name = frontmatter.name || path.basename(file, '.md');
|
|
300
|
+
agents.push(name);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Group by category, count per category
|
|
304
|
+
const categories = {};
|
|
305
|
+
for (const name of agents) {
|
|
306
|
+
const cat = categorizeAgent(name);
|
|
307
|
+
if (!categories[cat]) categories[cat] = 0;
|
|
308
|
+
categories[cat]++;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const safeCount = sanitize.count(agents.length);
|
|
312
|
+
let output = `**${safeCount} agents** across ${Object.keys(categories).length} categories:\n`;
|
|
313
|
+
for (const [category, count] of Object.entries(categories)) {
|
|
314
|
+
output += `- **${category}**: ${count} agents\n`;
|
|
315
|
+
}
|
|
316
|
+
output += `\nRun \`/agileflow:help agents\` or browse \`.agileflow/agents/\` for the full list.`;
|
|
317
|
+
return output;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Generate a compact category summary for commands (no individual names).
|
|
322
|
+
* Used by minimal mode and generators that want a discovery-oriented summary.
|
|
323
|
+
* @param {string} commandsDir - Path to commands directory
|
|
324
|
+
* @returns {string} Compact category summary with counts
|
|
325
|
+
*/
|
|
326
|
+
function generateCommandSummary(commandsDir) {
|
|
327
|
+
if (!fs.existsSync(commandsDir)) return '';
|
|
328
|
+
|
|
329
|
+
const commands = [];
|
|
330
|
+
|
|
331
|
+
// Count main command files
|
|
332
|
+
const mainFiles = fs.readdirSync(commandsDir).filter(f => f.endsWith('.md'));
|
|
333
|
+
for (const file of mainFiles) {
|
|
334
|
+
const filePath = path.join(commandsDir, file);
|
|
335
|
+
if (!isPathSafe(filePath, commandsDir)) continue;
|
|
336
|
+
|
|
337
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
338
|
+
const frontmatter = parseFrontmatter(content);
|
|
339
|
+
if (!frontmatter || Object.keys(frontmatter).length === 0) continue;
|
|
340
|
+
commands.push(path.basename(file, '.md'));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Count subdirectory command files
|
|
344
|
+
const entries = fs.readdirSync(commandsDir, { withFileTypes: true });
|
|
345
|
+
for (const entry of entries) {
|
|
346
|
+
if (entry.isDirectory()) {
|
|
347
|
+
const subDir = path.join(commandsDir, entry.name);
|
|
348
|
+
if (!isPathSafe(subDir, commandsDir)) continue;
|
|
349
|
+
|
|
350
|
+
const subFiles = fs.readdirSync(subDir).filter(f => f.endsWith('.md'));
|
|
351
|
+
for (const file of subFiles) {
|
|
352
|
+
const filePath = path.join(subDir, file);
|
|
353
|
+
if (!isPathSafe(filePath, commandsDir)) continue;
|
|
354
|
+
|
|
355
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
356
|
+
const frontmatter = parseFrontmatter(content);
|
|
357
|
+
if (!frontmatter || Object.keys(frontmatter).length === 0) continue;
|
|
358
|
+
commands.push(`${entry.name}:${path.basename(file, '.md')}`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const safeCount = sanitize.count(commands.length);
|
|
364
|
+
return `**${safeCount} commands** available. Run \`/agileflow:help\` for the full list with descriptions.`;
|
|
365
|
+
}
|
|
366
|
+
|
|
238
367
|
// =============================================================================
|
|
239
368
|
// Template Generation Functions
|
|
240
369
|
// =============================================================================
|
|
@@ -480,6 +609,8 @@ function clearPreserveRulesCache() {
|
|
|
480
609
|
* @param {string} context.agileflowFolder - AgileFlow folder name
|
|
481
610
|
* @param {string} context.docsFolder - Docs folder name (default: 'docs')
|
|
482
611
|
* @param {string} context.version - AgileFlow version
|
|
612
|
+
* @param {boolean} context.minimal - When true, skip AGENT_LIST and COMMAND_LIST injection
|
|
613
|
+
* (replaces with discovery pointers). Keeps session harness, quality gates, preserve_rules.
|
|
483
614
|
* @returns {string} Content with all placeholders replaced
|
|
484
615
|
*/
|
|
485
616
|
function injectContent(content, context = {}) {
|
|
@@ -488,6 +619,7 @@ function injectContent(content, context = {}) {
|
|
|
488
619
|
agileflowFolder = '.agileflow',
|
|
489
620
|
docsFolder = 'docs',
|
|
490
621
|
version = 'unknown',
|
|
622
|
+
minimal = false,
|
|
491
623
|
} = context;
|
|
492
624
|
|
|
493
625
|
let result = content;
|
|
@@ -541,7 +673,13 @@ function injectContent(content, context = {}) {
|
|
|
541
673
|
// List generation already includes sanitization via sanitizeAgentData/sanitizeCommandData
|
|
542
674
|
if (coreDir && fs.existsSync(coreDir)) {
|
|
543
675
|
if (result.includes('{{AGENT_LIST}}')) {
|
|
544
|
-
|
|
676
|
+
let agentList;
|
|
677
|
+
if (minimal) {
|
|
678
|
+
// Minimal mode: replace with compact discovery pointer
|
|
679
|
+
agentList = `**Agents**: ${safeAgentCount} available. Run \`/agileflow:help agents\` or \`ls .agileflow/agents/\` to browse.`;
|
|
680
|
+
} else {
|
|
681
|
+
agentList = generateAgentList(path.join(coreDir, 'agents'));
|
|
682
|
+
}
|
|
545
683
|
result = replaceInBodyOnly(result, body => {
|
|
546
684
|
let updated = body.replace(/<!-- \{\{AGENT_LIST\}\} -->/g, agentList);
|
|
547
685
|
updated = updated.replace(/\{\{AGENT_LIST\}\}/g, agentList);
|
|
@@ -550,7 +688,13 @@ function injectContent(content, context = {}) {
|
|
|
550
688
|
}
|
|
551
689
|
|
|
552
690
|
if (result.includes('{{COMMAND_LIST}}')) {
|
|
553
|
-
|
|
691
|
+
let commandList;
|
|
692
|
+
if (minimal) {
|
|
693
|
+
// Minimal mode: replace with compact discovery pointer
|
|
694
|
+
commandList = `**Commands**: ${safeCommandCount} available. Run \`/agileflow:help\` or \`ls .agileflow/commands/\` to browse.`;
|
|
695
|
+
} else {
|
|
696
|
+
commandList = generateCommandList(path.join(coreDir, 'commands'));
|
|
697
|
+
}
|
|
554
698
|
result = replaceInBodyOnly(result, body => {
|
|
555
699
|
let updated = body.replace(/<!-- \{\{COMMAND_LIST\}\} -->/g, commandList);
|
|
556
700
|
updated = updated.replace(/\{\{COMMAND_LIST\}\}/g, commandList);
|
|
@@ -798,6 +942,10 @@ module.exports = {
|
|
|
798
942
|
generateAgentList,
|
|
799
943
|
generateCommandList,
|
|
800
944
|
|
|
945
|
+
// Summary generation (compact, for minimal mode)
|
|
946
|
+
generateAgentSummary,
|
|
947
|
+
generateCommandSummary,
|
|
948
|
+
|
|
801
949
|
// Template generation
|
|
802
950
|
generateSessionHarnessContent,
|
|
803
951
|
clearSessionHarnessCache,
|
|
@@ -190,7 +190,7 @@ Project-level planning and tracking.
|
|
|
190
190
|
- **milestones.md**: Release milestones
|
|
191
191
|
- **risks.md**: Project risks and mitigation strategies
|
|
192
192
|
- **ideation/**: Ideation reports from \`/agileflow:ideate:new\`
|
|
193
|
-
- **
|
|
193
|
+
- **code-audits/**: Code audit reports from \`/agileflow:code:logic\`
|
|
194
194
|
`,
|
|
195
195
|
|
|
196
196
|
[`${docsFolder}/09-agents/README.md`]: `# Agent Status Tracking
|