agileflow 2.42.0 → 2.44.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.
Files changed (75) hide show
  1. package/package.json +2 -1
  2. package/scripts/generate-all.sh +77 -0
  3. package/scripts/generators/agent-registry.js +167 -0
  4. package/scripts/generators/command-registry.js +135 -0
  5. package/scripts/generators/index.js +87 -0
  6. package/scripts/generators/inject-babysit.js +167 -0
  7. package/scripts/generators/inject-help.js +109 -0
  8. package/scripts/generators/inject-readme.js +156 -0
  9. package/scripts/generators/skill-registry.js +144 -0
  10. package/src/core/agents/accessibility.md +8 -0
  11. package/src/core/agents/adr-writer.md +8 -0
  12. package/src/core/agents/analytics.md +8 -0
  13. package/src/core/agents/api.md +8 -2
  14. package/src/core/agents/ci.md +8 -0
  15. package/src/core/agents/compliance.md +8 -0
  16. package/src/core/agents/configuration/archival.md +23 -1
  17. package/src/core/agents/configuration/attribution.md +22 -1
  18. package/src/core/agents/configuration/ci.md +23 -1
  19. package/src/core/agents/configuration/git-config.md +23 -1
  20. package/src/core/agents/configuration/hooks.md +22 -1
  21. package/src/core/agents/configuration/precompact.md +8 -0
  22. package/src/core/agents/configuration/status-line.md +93 -13
  23. package/src/core/agents/configuration/verify.md +23 -1
  24. package/src/core/agents/database.md +8 -2
  25. package/src/core/agents/datamigration.md +8 -0
  26. package/src/core/agents/design.md +8 -0
  27. package/src/core/agents/devops.md +8 -2
  28. package/src/core/agents/documentation.md +8 -0
  29. package/src/core/agents/epic-planner.md +8 -0
  30. package/src/core/agents/integrations.md +8 -0
  31. package/src/core/agents/mentor.md +8 -3
  32. package/src/core/agents/mobile.md +8 -0
  33. package/src/core/agents/monitoring.md +8 -0
  34. package/src/core/agents/multi-expert.md +8 -0
  35. package/src/core/agents/performance.md +8 -2
  36. package/src/core/agents/product.md +8 -0
  37. package/src/core/agents/qa.md +8 -0
  38. package/src/core/agents/readme-updater.md +8 -0
  39. package/src/core/agents/refactor.md +8 -2
  40. package/src/core/agents/research.md +8 -0
  41. package/src/core/agents/security.md +8 -2
  42. package/src/core/agents/testing.md +8 -0
  43. package/src/core/agents/ui.md +8 -2
  44. package/src/core/commands/adr.md +2 -13
  45. package/src/core/commands/agent.md +2 -13
  46. package/src/core/commands/assign.md +2 -13
  47. package/src/core/commands/auto.md +2 -13
  48. package/src/core/commands/babysit.md +94 -88
  49. package/src/core/commands/baseline.md +2 -13
  50. package/src/core/commands/blockers.md +4 -13
  51. package/src/core/commands/board.md +4 -13
  52. package/src/core/commands/context.md +141 -5
  53. package/src/core/commands/deps.md +4 -15
  54. package/src/core/commands/docs.md +2 -15
  55. package/src/core/commands/epic.md +4 -15
  56. package/src/core/commands/help.md +3 -14
  57. package/src/core/commands/metrics.md +4 -15
  58. package/src/core/commands/packages.md +3 -14
  59. package/src/core/commands/pr.md +4 -13
  60. package/src/core/commands/readme-sync.md +7 -24
  61. package/src/core/commands/research.md +3 -14
  62. package/src/core/commands/retro.md +4 -15
  63. package/src/core/commands/sprint.md +8 -0
  64. package/src/core/commands/status.md +5 -14
  65. package/src/core/commands/story-validate.md +3 -14
  66. package/src/core/commands/story.md +17 -17
  67. package/src/core/commands/template.md +2 -15
  68. package/src/core/commands/tests.md +2 -15
  69. package/src/core/commands/update.md +2 -15
  70. package/src/core/commands/validate-expertise.md +2 -15
  71. package/src/core/commands/velocity.md +4 -15
  72. package/src/core/commands/verify.md +4 -15
  73. package/src/core/templates/agileflow-configure.js +123 -2
  74. package/src/core/templates/agileflow-metadata.json +12 -0
  75. package/src/core/templates/agileflow-statusline.sh +238 -44
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agileflow",
3
- "version": "2.42.0",
3
+ "version": "2.44.0",
4
4
  "description": "AI-driven agile development system for Claude Code, Cursor, Windsurf, and more",
5
5
  "keywords": [
6
6
  "agile",
@@ -31,6 +31,7 @@
31
31
  "files": [
32
32
  "tools/",
33
33
  "src/",
34
+ "scripts/",
34
35
  "LICENSE",
35
36
  "README.md"
36
37
  ],
@@ -0,0 +1,77 @@
1
+ #!/bin/bash
2
+
3
+ ###############################################################################
4
+ # AgileFlow Content Generation Script
5
+ #
6
+ # Regenerates all dynamic content in AgileFlow plugin files.
7
+ # Run this after:
8
+ # - Adding/removing/renaming commands
9
+ # - Adding/removing/renaming agents
10
+ # - Adding/removing/renaming skills
11
+ # - Changing command/agent/skill descriptions or metadata
12
+ #
13
+ # Usage:
14
+ # bash scripts/generate-all.sh
15
+ # npm run generate (if added to package.json)
16
+ ###############################################################################
17
+
18
+ set -e # Exit on error
19
+
20
+ # Get script directory
21
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+ GENERATORS_DIR="$SCRIPT_DIR/generators"
23
+
24
+ # Colors for output
25
+ GREEN='\033[0;32m'
26
+ BLUE='\033[0;34m'
27
+ YELLOW='\033[1;33m'
28
+ RED='\033[0;31m'
29
+ NC='\033[0m' # No Color
30
+
31
+ echo -e "${BLUE}============================================================${NC}"
32
+ echo -e "${BLUE} AgileFlow Content Generation System${NC}"
33
+ echo -e "${BLUE}============================================================${NC}"
34
+ echo ""
35
+
36
+ # Check if Node.js is available
37
+ if ! command -v node &> /dev/null; then
38
+ echo -e "${RED}❌ Error: Node.js is not installed or not in PATH${NC}"
39
+ exit 1
40
+ fi
41
+
42
+ # Check if generators directory exists
43
+ if [ ! -d "$GENERATORS_DIR" ]; then
44
+ echo -e "${RED}❌ Error: Generators directory not found: $GENERATORS_DIR${NC}"
45
+ exit 1
46
+ fi
47
+
48
+ # Run the orchestrator
49
+ echo -e "${YELLOW}Running content generators...${NC}"
50
+ echo ""
51
+
52
+ cd "$GENERATORS_DIR"
53
+ node index.js
54
+
55
+ EXIT_CODE=$?
56
+
57
+ if [ $EXIT_CODE -eq 0 ]; then
58
+ echo ""
59
+ echo -e "${GREEN}============================================================${NC}"
60
+ echo -e "${GREEN}✅ Content generation completed successfully!${NC}"
61
+ echo -e "${GREEN}============================================================${NC}"
62
+ echo ""
63
+ echo -e "${YELLOW}Next steps:${NC}"
64
+ echo "1. Review the changes: git diff"
65
+ echo "2. Test the plugin to ensure everything works"
66
+ echo "3. Commit the generated content: git add -A && git commit -m 'chore: regenerate plugin content'"
67
+ echo ""
68
+ else
69
+ echo ""
70
+ echo -e "${RED}============================================================${NC}"
71
+ echo -e "${RED}❌ Content generation failed${NC}"
72
+ echo -e "${RED}============================================================${NC}"
73
+ echo ""
74
+ echo -e "${YELLOW}Please check the errors above and fix any issues.${NC}"
75
+ echo ""
76
+ exit 1
77
+ fi
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Agent Registry Scanner
5
+ *
6
+ * Scans agents/ directory and extracts metadata from frontmatter.
7
+ * Returns structured agent registry for use in generators.
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+
13
+ /**
14
+ * Extract YAML frontmatter from markdown file
15
+ * Handles multi-line values like tools arrays
16
+ * @param {string} filePath - Path to markdown file
17
+ * @returns {object} Frontmatter object
18
+ */
19
+ function extractFrontmatter(filePath) {
20
+ const content = fs.readFileSync(filePath, 'utf-8');
21
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
22
+
23
+ if (!frontmatterMatch) {
24
+ return {};
25
+ }
26
+
27
+ const frontmatter = {};
28
+ const lines = frontmatterMatch[1].split('\n');
29
+ let currentKey = null;
30
+ let currentArray = null;
31
+
32
+ for (const line of lines) {
33
+ // Handle array items (lines starting with -)
34
+ if (line.trim().startsWith('-')) {
35
+ if (currentArray) {
36
+ currentArray.push(line.trim().substring(1).trim());
37
+ }
38
+ continue;
39
+ }
40
+
41
+ // Handle key-value pairs
42
+ const match = line.match(/^(\w+):\s*(.*)$/);
43
+ if (match) {
44
+ const [, key, value] = match;
45
+ currentKey = key;
46
+
47
+ // If value is empty, it's likely an array
48
+ if (!value) {
49
+ currentArray = [];
50
+ frontmatter[key] = currentArray;
51
+ } else {
52
+ // Remove quotes if present
53
+ frontmatter[key] = value.replace(/^["']|["']$/g, '');
54
+ currentArray = null;
55
+ }
56
+ }
57
+ }
58
+
59
+ return frontmatter;
60
+ }
61
+
62
+ /**
63
+ * Categorize agent based on its role
64
+ * @param {string} name - Agent name
65
+ * @param {string} description - Agent description
66
+ * @returns {string} Category name
67
+ */
68
+ function categorizeAgent(name, description) {
69
+ const categories = {
70
+ 'Core Development': ['ui', 'api', 'database', 'devops', 'ci'],
71
+ 'Specialized Development': ['mobile', 'integrations', 'datamigration'],
72
+ 'Quality & Testing': ['qa', 'testing', 'security', 'accessibility'],
73
+ 'Architecture & Design': ['design', 'adr-writer', 'epic-planner', 'product'],
74
+ 'Maintenance & Optimization': ['refactor', 'performance', 'monitoring'],
75
+ 'Documentation & Knowledge': ['documentation', 'readme-updater', 'research'],
76
+ 'Compliance & Governance': ['compliance', 'analytics'],
77
+ 'Mentorship': ['mentor']
78
+ };
79
+
80
+ for (const [category, keywords] of Object.entries(categories)) {
81
+ if (keywords.some(kw => name.includes(kw))) {
82
+ return category;
83
+ }
84
+ }
85
+
86
+ return 'Other';
87
+ }
88
+
89
+ /**
90
+ * Scan agents directory and build registry
91
+ * @param {string} agentsDir - Path to agents directory
92
+ * @returns {Array} Array of agent metadata objects
93
+ */
94
+ function scanAgents(agentsDir) {
95
+ const agents = [];
96
+ const files = fs.readdirSync(agentsDir);
97
+
98
+ for (const file of files) {
99
+ if (!file.endsWith('.md')) continue;
100
+
101
+ const filePath = path.join(agentsDir, file);
102
+ const frontmatter = extractFrontmatter(filePath);
103
+ const name = file.replace('.md', '');
104
+
105
+ // Parse tools array if it exists
106
+ let tools = [];
107
+ if (frontmatter.tools) {
108
+ if (Array.isArray(frontmatter.tools)) {
109
+ tools = frontmatter.tools;
110
+ } else if (typeof frontmatter.tools === 'string') {
111
+ tools = frontmatter.tools.split(',').map(t => t.trim());
112
+ }
113
+ }
114
+
115
+ agents.push({
116
+ name,
117
+ file,
118
+ path: filePath,
119
+ displayName: frontmatter.name || name,
120
+ description: frontmatter.description || '',
121
+ tools,
122
+ model: frontmatter.model || 'haiku',
123
+ color: frontmatter.color || 'blue',
124
+ category: categorizeAgent(name, frontmatter.description || '')
125
+ });
126
+ }
127
+
128
+ // Sort by category, then by name
129
+ agents.sort((a, b) => {
130
+ if (a.category !== b.category) {
131
+ return a.category.localeCompare(b.category);
132
+ }
133
+ return a.name.localeCompare(b.name);
134
+ });
135
+
136
+ return agents;
137
+ }
138
+
139
+ /**
140
+ * Main function
141
+ */
142
+ function main() {
143
+ const rootDir = path.resolve(__dirname, '../..');
144
+ const agentsDir = path.join(rootDir, 'src/core/agents');
145
+
146
+ if (!fs.existsSync(agentsDir)) {
147
+ console.error(`Agents directory not found: ${agentsDir}`);
148
+ process.exit(1);
149
+ }
150
+
151
+ const agents = scanAgents(agentsDir);
152
+
153
+ // If called directly, output JSON
154
+ if (require.main === module) {
155
+ console.log(JSON.stringify(agents, null, 2));
156
+ }
157
+
158
+ return agents;
159
+ }
160
+
161
+ // Export for use in other scripts
162
+ module.exports = { scanAgents, extractFrontmatter, categorizeAgent };
163
+
164
+ // Run if called directly
165
+ if (require.main === module) {
166
+ main();
167
+ }
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Command Registry Scanner
5
+ *
6
+ * Scans commands/ directory and extracts metadata from frontmatter.
7
+ * Returns structured command registry for use in generators.
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+
13
+ /**
14
+ * Extract frontmatter from markdown file
15
+ * @param {string} filePath - Path to markdown file
16
+ * @returns {object} Frontmatter object
17
+ */
18
+ function extractFrontmatter(filePath) {
19
+ const content = fs.readFileSync(filePath, 'utf-8');
20
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
21
+
22
+ if (!frontmatterMatch) {
23
+ return {};
24
+ }
25
+
26
+ const frontmatter = {};
27
+ const lines = frontmatterMatch[1].split('\n');
28
+
29
+ for (const line of lines) {
30
+ const match = line.match(/^(\w+):\s*(.+)$/);
31
+ if (match) {
32
+ const [, key, value] = match;
33
+ // Remove quotes if present
34
+ frontmatter[key] = value.replace(/^["']|["']$/g, '');
35
+ }
36
+ }
37
+
38
+ return frontmatter;
39
+ }
40
+
41
+ /**
42
+ * Categorize command based on its name/description
43
+ * @param {string} name - Command name
44
+ * @param {string} description - Command description
45
+ * @returns {string} Category name
46
+ */
47
+ function categorizeCommand(name, description) {
48
+ const categories = {
49
+ 'Story Management': ['story', 'epic', 'assign', 'status'],
50
+ 'Development': ['verify', 'baseline', 'resume', 'session-init', 'babysit'],
51
+ 'Quality & Testing': ['tests', 'review', 'ci'],
52
+ 'Documentation': ['docs', 'adr', 'readme-sync'],
53
+ 'Planning & Metrics': ['sprint', 'velocity', 'metrics', 'board', 'deps'],
54
+ 'Research & Strategy': ['research', 'product'],
55
+ 'Deployment & Operations': ['deploy', 'packages'],
56
+ 'Collaboration': ['update', 'handoff', 'feedback', 'retro'],
57
+ 'Maintenance': ['debt', 'compress', 'template'],
58
+ 'System': ['setup', 'help', 'diagnose', 'auto', 'agent']
59
+ };
60
+
61
+ for (const [category, keywords] of Object.entries(categories)) {
62
+ if (keywords.some(kw => name.includes(kw))) {
63
+ return category;
64
+ }
65
+ }
66
+
67
+ return 'Other';
68
+ }
69
+
70
+ /**
71
+ * Scan commands directory and build registry
72
+ * @param {string} commandsDir - Path to commands directory
73
+ * @returns {Array} Array of command metadata objects
74
+ */
75
+ function scanCommands(commandsDir) {
76
+ const commands = [];
77
+ const files = fs.readdirSync(commandsDir);
78
+
79
+ for (const file of files) {
80
+ if (!file.endsWith('.md')) continue;
81
+
82
+ const filePath = path.join(commandsDir, file);
83
+ const frontmatter = extractFrontmatter(filePath);
84
+ const name = file.replace('.md', '');
85
+
86
+ commands.push({
87
+ name,
88
+ file,
89
+ path: filePath,
90
+ description: frontmatter.description || '',
91
+ argumentHint: frontmatter['argument-hint'] || '',
92
+ category: categorizeCommand(name, frontmatter.description || '')
93
+ });
94
+ }
95
+
96
+ // Sort by category, then by name
97
+ commands.sort((a, b) => {
98
+ if (a.category !== b.category) {
99
+ return a.category.localeCompare(b.category);
100
+ }
101
+ return a.name.localeCompare(b.name);
102
+ });
103
+
104
+ return commands;
105
+ }
106
+
107
+ /**
108
+ * Main function
109
+ */
110
+ function main() {
111
+ const rootDir = path.resolve(__dirname, '../..');
112
+ const commandsDir = path.join(rootDir, 'src/core/commands');
113
+
114
+ if (!fs.existsSync(commandsDir)) {
115
+ console.error(`Commands directory not found: ${commandsDir}`);
116
+ process.exit(1);
117
+ }
118
+
119
+ const commands = scanCommands(commandsDir);
120
+
121
+ // If called directly, output JSON
122
+ if (require.main === module) {
123
+ console.log(JSON.stringify(commands, null, 2));
124
+ }
125
+
126
+ return commands;
127
+ }
128
+
129
+ // Export for use in other scripts
130
+ module.exports = { scanCommands, extractFrontmatter, categorizeCommand };
131
+
132
+ // Run if called directly
133
+ if (require.main === module) {
134
+ main();
135
+ }
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Content Generation Orchestrator
5
+ *
6
+ * Runs all content generators to update AgileFlow plugin files.
7
+ * Single source of truth: frontmatter and directory structure.
8
+ */
9
+
10
+ const path = require('path');
11
+ const { execSync } = require('child_process');
12
+
13
+ /**
14
+ * Run a generator script
15
+ * @param {string} scriptName - Name of the generator script
16
+ * @returns {boolean} Success status
17
+ */
18
+ function runGenerator(scriptName) {
19
+ const scriptPath = path.join(__dirname, scriptName);
20
+
21
+ console.log(`\n${'='.repeat(60)}`);
22
+ console.log(`Running: ${scriptName}`);
23
+ console.log('='.repeat(60));
24
+
25
+ try {
26
+ execSync(`node "${scriptPath}"`, {
27
+ cwd: __dirname,
28
+ stdio: 'inherit'
29
+ });
30
+ console.log(`✅ ${scriptName} completed successfully`);
31
+ return true;
32
+ } catch (error) {
33
+ console.error(`❌ ${scriptName} failed:`, error.message);
34
+ return false;
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Main orchestrator
40
+ */
41
+ function main() {
42
+ console.log('🚀 AgileFlow Content Generation System');
43
+ console.log('Generating content from metadata...\n');
44
+
45
+ const generators = [
46
+ 'inject-help.js',
47
+ 'inject-babysit.js',
48
+ 'inject-readme.js'
49
+ ];
50
+
51
+ const results = [];
52
+
53
+ for (const generator of generators) {
54
+ const success = runGenerator(generator);
55
+ results.push({ generator, success });
56
+ }
57
+
58
+ // Summary
59
+ console.log(`\n${'='.repeat(60)}`);
60
+ console.log('GENERATION SUMMARY');
61
+ console.log('='.repeat(60));
62
+
63
+ let allSuccess = true;
64
+ for (const { generator, success } of results) {
65
+ const status = success ? '✅' : '❌';
66
+ console.log(`${status} ${generator}`);
67
+ if (!success) allSuccess = false;
68
+ }
69
+
70
+ console.log('');
71
+
72
+ if (allSuccess) {
73
+ console.log('🎉 All generators completed successfully!');
74
+ console.log('📝 Generated content is ready for commit.');
75
+ process.exit(0);
76
+ } else {
77
+ console.log('⚠️ Some generators failed. Please check errors above.');
78
+ process.exit(1);
79
+ }
80
+ }
81
+
82
+ // Run if called directly
83
+ if (require.main === module) {
84
+ main();
85
+ }
86
+
87
+ module.exports = { runGenerator };
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Babysit Command Content Injector
5
+ *
6
+ * Injects agent list and command references into /agileflow:babysit command file.
7
+ * Handles multiple AUTOGEN sections.
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const { scanAgents } = require('./agent-registry');
13
+ const { scanCommands } = require('./command-registry');
14
+
15
+ /**
16
+ * Generate agent list content with details
17
+ * @param {Array} agents - Array of agent metadata
18
+ * @returns {string} Formatted agent list
19
+ */
20
+ function generateAgentList(agents) {
21
+ const lines = [];
22
+
23
+ lines.push(`**AVAILABLE AGENTS** (${agents.length} total):`);
24
+ lines.push('');
25
+
26
+ let count = 1;
27
+ for (const agent of agents) {
28
+ lines.push(`${count}. **${agent.name}** (model: ${agent.model})`);
29
+ lines.push(` - **Purpose**: ${agent.description}`);
30
+ lines.push(` - **Tools**: ${agent.tools.join(', ')}`);
31
+ lines.push(` - **Category**: ${agent.category}`);
32
+ lines.push('');
33
+ count++;
34
+ }
35
+
36
+ return lines.join('\n');
37
+ }
38
+
39
+ /**
40
+ * Generate command reference list (compact format for babysit)
41
+ * @param {Array} commands - Array of command metadata
42
+ * @returns {string} Formatted command list
43
+ */
44
+ function generateCommandReference(commands) {
45
+ const lines = [];
46
+
47
+ // Group by category
48
+ const categories = {};
49
+ for (const cmd of commands) {
50
+ if (!categories[cmd.category]) {
51
+ categories[cmd.category] = [];
52
+ }
53
+ categories[cmd.category].push(cmd);
54
+ }
55
+
56
+ for (const [category, cmds] of Object.entries(categories)) {
57
+ const cmdNames = cmds.map(c => c.name).join(', ');
58
+ lines.push(`- **${category}**: ${cmdNames}`);
59
+ }
60
+
61
+ return lines.join('\n');
62
+ }
63
+
64
+ /**
65
+ * Inject content between specified AUTOGEN markers
66
+ * @param {string} content - Original file content
67
+ * @param {string} markerName - Name of the marker (e.g., AGENT_LIST, COMMAND_REF)
68
+ * @param {string} generated - Generated content to inject
69
+ * @returns {string} Updated file content
70
+ */
71
+ function injectContentByMarker(content, markerName, generated) {
72
+ const startMarker = `<!-- AUTOGEN:${markerName}:START -->`;
73
+ const endMarker = `<!-- AUTOGEN:${markerName}:END -->`;
74
+
75
+ const startIdx = content.indexOf(startMarker);
76
+ const endIdx = content.indexOf(endMarker);
77
+
78
+ if (startIdx === -1 || endIdx === -1) {
79
+ console.warn(`AUTOGEN:${markerName} markers not found - skipping`);
80
+ return content;
81
+ }
82
+
83
+ const timestamp = new Date().toISOString().split('T')[0];
84
+ const injectedContent = `${startMarker}\n<!-- Auto-generated on ${timestamp}. Do not edit manually. -->\n\n${generated}\n${endMarker}`;
85
+
86
+ return content.substring(0, startIdx) + injectedContent + content.substring(endIdx + endMarker.length);
87
+ }
88
+
89
+ /**
90
+ * Add AUTOGEN markers to babysit file if they don't exist
91
+ * @param {string} content - Original file content
92
+ * @returns {string} Updated content with markers
93
+ */
94
+ function addMarkersIfMissing(content) {
95
+ let updated = content;
96
+
97
+ // Add AGENT_LIST markers around the agent list section
98
+ if (!content.includes('<!-- AUTOGEN:AGENT_LIST:START -->')) {
99
+ // Find "**AVAILABLE AGENTS**" and wrap it
100
+ const agentSectionStart = content.indexOf('**AVAILABLE AGENTS**');
101
+ if (agentSectionStart !== -1) {
102
+ // Find the end of the agent list (before "**WHEN TO SPAWN AGENTS**")
103
+ const agentSectionEnd = content.indexOf('**WHEN TO SPAWN AGENTS**', agentSectionStart);
104
+ if (agentSectionEnd !== -1) {
105
+ const before = content.substring(0, agentSectionStart);
106
+ const agentSection = content.substring(agentSectionStart, agentSectionEnd);
107
+ const after = content.substring(agentSectionEnd);
108
+
109
+ updated = `${before}<!-- AUTOGEN:AGENT_LIST:START -->\n${agentSection}<!-- AUTOGEN:AGENT_LIST:END -->\n\n${after}`;
110
+ console.log('✅ Added AGENT_LIST markers to babysit.md');
111
+ }
112
+ }
113
+ }
114
+
115
+ return updated;
116
+ }
117
+
118
+ /**
119
+ * Main function
120
+ */
121
+ function main() {
122
+ const rootDir = path.resolve(__dirname, '../..');
123
+ const babysitFile = path.join(rootDir, 'src/core/commands/babysit.md');
124
+ const agentsDir = path.join(rootDir, 'src/core/agents');
125
+ const commandsDir = path.join(rootDir, 'src/core/commands');
126
+
127
+ // Check if babysit file exists
128
+ if (!fs.existsSync(babysitFile)) {
129
+ console.error(`Babysit file not found: ${babysitFile}`);
130
+ process.exit(1);
131
+ }
132
+
133
+ // Scan agents and commands
134
+ console.log('Scanning agents...');
135
+ const agents = scanAgents(agentsDir);
136
+ console.log(`Found ${agents.length} agents`);
137
+
138
+ console.log('Scanning commands...');
139
+ const commands = scanCommands(commandsDir);
140
+ console.log(`Found ${commands.length} commands`);
141
+
142
+ // Read babysit file
143
+ let babysitContent = fs.readFileSync(babysitFile, 'utf-8');
144
+
145
+ // Add markers if missing
146
+ babysitContent = addMarkersIfMissing(babysitContent);
147
+
148
+ // Generate content
149
+ console.log('Generating agent list...');
150
+ const agentList = generateAgentList(agents);
151
+
152
+ // Inject content
153
+ console.log('Injecting content into babysit.md...');
154
+ babysitContent = injectContentByMarker(babysitContent, 'AGENT_LIST', agentList);
155
+
156
+ // Write back
157
+ fs.writeFileSync(babysitFile, babysitContent, 'utf-8');
158
+ console.log('✅ Successfully updated babysit.md');
159
+ }
160
+
161
+ // Export for use in orchestrator
162
+ module.exports = { generateAgentList, generateCommandReference, injectContentByMarker, addMarkersIfMissing };
163
+
164
+ // Run if called directly
165
+ if (require.main === module) {
166
+ main();
167
+ }