@patricio0312rev/agentkit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +491 -0
- package/LICENSE +21 -0
- package/README.md +442 -0
- package/bin/cli.js +41 -0
- package/package.json +54 -0
- package/src/commands/init.js +312 -0
- package/src/index.js +220 -0
- package/src/lib/config.js +157 -0
- package/src/lib/generator.js +193 -0
- package/src/utils/display.js +95 -0
- package/src/utils/readme.js +191 -0
- package/src/utils/tool-specific.js +408 -0
- package/templates/departments/design/brand-guardian.md +133 -0
- package/templates/departments/design/ui-designer.md +154 -0
- package/templates/departments/design/ux-researcher.md +285 -0
- package/templates/departments/design/visual-storyteller.md +296 -0
- package/templates/departments/design/whimsy-injector.md +318 -0
- package/templates/departments/engineering/ai-engineer.md +386 -0
- package/templates/departments/engineering/backend-architect.md +425 -0
- package/templates/departments/engineering/devops-automator.md +393 -0
- package/templates/departments/engineering/frontend-developer.md +411 -0
- package/templates/departments/engineering/mobile-app-builder.md +412 -0
- package/templates/departments/engineering/rapid-prototyper.md +415 -0
- package/templates/departments/engineering/test-writer-fixer.md +462 -0
- package/templates/departments/marketing/app-store-optimizer.md +176 -0
- package/templates/departments/marketing/content-creator.md +206 -0
- package/templates/departments/marketing/growth-hacker.md +219 -0
- package/templates/departments/marketing/instagram-curator.md +166 -0
- package/templates/departments/marketing/reddit-community-builder.md +192 -0
- package/templates/departments/marketing/tiktok-strategist.md +158 -0
- package/templates/departments/marketing/twitter-engager.md +184 -0
- package/templates/departments/product/feedback-synthesizer.md +143 -0
- package/templates/departments/product/sprint-prioritizer.md +169 -0
- package/templates/departments/product/trend-researcher.md +176 -0
- package/templates/departments/project-management/experiment-tracker.md +128 -0
- package/templates/departments/project-management/project-shipper.md +151 -0
- package/templates/departments/project-management/studio-producer.md +156 -0
- package/templates/departments/studio-operations/analytics-reporter.md +191 -0
- package/templates/departments/studio-operations/finance-tracker.md +242 -0
- package/templates/departments/studio-operations/infrastructure-maintainer.md +202 -0
- package/templates/departments/studio-operations/legal-compliance-checker.md +208 -0
- package/templates/departments/studio-operations/support-responder.md +181 -0
- package/templates/departments/testing/api-tester.md +207 -0
- package/templates/departments/testing/performance-benchmarker.md +262 -0
- package/templates/departments/testing/test-results-analyzer.md +251 -0
- package/templates/departments/testing/tool-evaluator.md +206 -0
- package/templates/departments/testing/workflow-optimizer.md +235 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { TOOLS, DEPARTMENTS } = require('./config');
|
|
4
|
+
const { generateReadme } = require('../utils/readme');
|
|
5
|
+
const { generateToolSpecificFiles } = require('../utils/tool-specific');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Main generator function that creates AI agent configuration
|
|
9
|
+
* @param {Object} config - Configuration object
|
|
10
|
+
* @returns {Promise<Object>} Generation result
|
|
11
|
+
*/
|
|
12
|
+
async function generateAgents(config) {
|
|
13
|
+
const targetDir = path.join(process.cwd(), config.folder);
|
|
14
|
+
const result = {
|
|
15
|
+
success: false,
|
|
16
|
+
targetDir,
|
|
17
|
+
agentsGenerated: 0,
|
|
18
|
+
filesCreated: [],
|
|
19
|
+
errors: []
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
// Ensure target directory exists
|
|
24
|
+
await fs.ensureDir(targetDir);
|
|
25
|
+
|
|
26
|
+
// Generate department folders and agent files
|
|
27
|
+
const agentResult = await generateDepartmentAgents(config, targetDir);
|
|
28
|
+
result.agentsGenerated = agentResult.count;
|
|
29
|
+
result.filesCreated.push(...agentResult.files);
|
|
30
|
+
|
|
31
|
+
// Generate README
|
|
32
|
+
const readmePath = path.join(targetDir, 'README.md');
|
|
33
|
+
const readmeContent = generateReadme(config, result);
|
|
34
|
+
await fs.writeFile(readmePath, readmeContent);
|
|
35
|
+
result.filesCreated.push(readmePath);
|
|
36
|
+
|
|
37
|
+
// Generate tool-specific files (e.g., .cursorrules, copilot-instructions.md)
|
|
38
|
+
const toolFiles = await generateToolSpecificFiles(config, targetDir, agentResult.agentsList);
|
|
39
|
+
result.filesCreated.push(...toolFiles);
|
|
40
|
+
|
|
41
|
+
result.success = true;
|
|
42
|
+
return result;
|
|
43
|
+
|
|
44
|
+
} catch (error) {
|
|
45
|
+
result.errors.push(error.message);
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Generate department folders and copy agent files
|
|
52
|
+
* @param {Object} config - Configuration object
|
|
53
|
+
* @param {string} targetDir - Target directory path
|
|
54
|
+
* @returns {Promise<Object>} Result with count and file list
|
|
55
|
+
*/
|
|
56
|
+
async function generateDepartmentAgents(config, targetDir) {
|
|
57
|
+
let count = 0;
|
|
58
|
+
const files = [];
|
|
59
|
+
const agentsList = [];
|
|
60
|
+
|
|
61
|
+
for (const dept of config.departments) {
|
|
62
|
+
const deptInfo = DEPARTMENTS[dept];
|
|
63
|
+
if (!deptInfo) continue;
|
|
64
|
+
|
|
65
|
+
const deptDir = path.join(targetDir, dept);
|
|
66
|
+
await fs.ensureDir(deptDir);
|
|
67
|
+
|
|
68
|
+
// Determine which agents to generate
|
|
69
|
+
let agentsToGenerate = deptInfo.agents;
|
|
70
|
+
|
|
71
|
+
// Filter if specific agents were selected
|
|
72
|
+
if (config.agents && config.agents.length > 0) {
|
|
73
|
+
agentsToGenerate = agentsToGenerate.filter(agent => {
|
|
74
|
+
// Support both "agent-name" and "dept/agent-name" formats
|
|
75
|
+
return config.agents.includes(agent) ||
|
|
76
|
+
config.agents.includes(`${dept}/${agent}`);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Copy/generate each agent file
|
|
81
|
+
for (const agent of agentsToGenerate) {
|
|
82
|
+
const agentFile = await generateAgentFile(dept, agent, deptDir, config);
|
|
83
|
+
if (agentFile) {
|
|
84
|
+
files.push(agentFile);
|
|
85
|
+
agentsList.push({ dept, agent, file: agentFile });
|
|
86
|
+
count++;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { count, files, agentsList };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Generate or copy an individual agent file
|
|
96
|
+
* @param {string} dept - Department name
|
|
97
|
+
* @param {string} agent - Agent name
|
|
98
|
+
* @param {string} deptDir - Department directory path
|
|
99
|
+
* @param {Object} config - Configuration object
|
|
100
|
+
* @returns {Promise<string|null>} Path to created file or null
|
|
101
|
+
*/
|
|
102
|
+
async function generateAgentFile(dept, agent, deptDir, config) {
|
|
103
|
+
const sourceFile = path.join(__dirname, '../../templates/departments', dept, `${agent}.md`);
|
|
104
|
+
const targetFile = path.join(deptDir, `${agent}.md`);
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
// Check if template exists
|
|
108
|
+
if (await fs.pathExists(sourceFile)) {
|
|
109
|
+
let content = await fs.readFile(sourceFile, 'utf8');
|
|
110
|
+
|
|
111
|
+
// Process content based on config
|
|
112
|
+
content = processAgentContent(content, config);
|
|
113
|
+
|
|
114
|
+
await fs.writeFile(targetFile, content);
|
|
115
|
+
return targetFile;
|
|
116
|
+
} else {
|
|
117
|
+
// Generate basic template if source doesn't exist
|
|
118
|
+
const basicTemplate = generateBasicAgentTemplate(dept, agent);
|
|
119
|
+
await fs.writeFile(targetFile, basicTemplate);
|
|
120
|
+
return targetFile;
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.error(`Error generating agent ${agent}:`, error.message);
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Process agent content based on configuration
|
|
130
|
+
* @param {string} content - Original content
|
|
131
|
+
* @param {Object} config - Configuration object
|
|
132
|
+
* @returns {string} Processed content
|
|
133
|
+
*/
|
|
134
|
+
function processAgentContent(content, config) {
|
|
135
|
+
let processed = content;
|
|
136
|
+
|
|
137
|
+
// Remove examples if requested
|
|
138
|
+
if (config.skipExamples) {
|
|
139
|
+
// Remove content between <example> tags
|
|
140
|
+
processed = processed.replace(/<example>[\s\S]*?<\/example>/g, '');
|
|
141
|
+
// Clean up extra whitespace
|
|
142
|
+
processed = processed.replace(/\n{3,}/g, '\n\n');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Add tech stack information if provided
|
|
146
|
+
if (config.stack && config.stack.length > 0) {
|
|
147
|
+
const stackSection = `\n\n## Tech Stack Context\n\nThis project uses: ${config.stack.join(', ')}\n`;
|
|
148
|
+
// Insert before the main content or at the end
|
|
149
|
+
processed += stackSection;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return processed;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Generate a basic agent template when source file doesn't exist
|
|
157
|
+
* @param {string} dept - Department name
|
|
158
|
+
* @param {string} agent - Agent name
|
|
159
|
+
* @returns {string} Basic template content
|
|
160
|
+
*/
|
|
161
|
+
function generateBasicAgentTemplate(dept, agent) {
|
|
162
|
+
const deptInfo = DEPARTMENTS[dept];
|
|
163
|
+
return `<!-- ${dept}/${agent}.md -->
|
|
164
|
+
---
|
|
165
|
+
name: ${agent}
|
|
166
|
+
description: AI agent for ${deptInfo.name}
|
|
167
|
+
color: blue
|
|
168
|
+
tools: Read, Write, MultiEdit
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
# ${agent.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')}
|
|
172
|
+
|
|
173
|
+
This is a placeholder agent file. Please add specific instructions and responsibilities.
|
|
174
|
+
|
|
175
|
+
## Responsibilities
|
|
176
|
+
|
|
177
|
+
- [Add specific responsibilities]
|
|
178
|
+
|
|
179
|
+
## Best Practices
|
|
180
|
+
|
|
181
|
+
- [Add best practices]
|
|
182
|
+
|
|
183
|
+
## Examples
|
|
184
|
+
|
|
185
|
+
- [Add usage examples]
|
|
186
|
+
`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
module.exports = {
|
|
190
|
+
generateAgents,
|
|
191
|
+
generateDepartmentAgents,
|
|
192
|
+
generateAgentFile
|
|
193
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const chalk = require("chalk");
|
|
2
|
+
|
|
3
|
+
function displayBanner() {
|
|
4
|
+
const version = require("../../package.json").version;
|
|
5
|
+
console.log(
|
|
6
|
+
chalk.cyan(
|
|
7
|
+
"\n" +
|
|
8
|
+
" ╔═══════════════════════════════════════════╗\n" +
|
|
9
|
+
" ║ ║\n" +
|
|
10
|
+
" ║ 🤖 AgentKit CLI v" +
|
|
11
|
+
version.padEnd(19) +
|
|
12
|
+
"║\n" +
|
|
13
|
+
" ║ ║\n" +
|
|
14
|
+
" ║ Scaffold AI agent configurations ║\n" +
|
|
15
|
+
" ║ for Claude Code, Cursor & more ║\n" +
|
|
16
|
+
" ║ ║\n" +
|
|
17
|
+
" ╚═══════════════════════════════════════════╝\n"
|
|
18
|
+
)
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function displaySuccess(message) {
|
|
23
|
+
console.log(chalk.green(`\n✓ ${message}\n`));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function displayError(message) {
|
|
27
|
+
console.log(chalk.red(`\n✗ ${message}\n`));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function displayWarning(message) {
|
|
31
|
+
console.log(chalk.yellow(`\n⚠ ${message}\n`));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function displayInfo(message) {
|
|
35
|
+
console.log(chalk.blue(`\nℹ ${message}\n`));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Display content in a nice box with consistent formatting
|
|
40
|
+
* @param {string} title - Box title
|
|
41
|
+
* @param {string} content - Box content
|
|
42
|
+
*/
|
|
43
|
+
function displayBox(title, content) {
|
|
44
|
+
const lines = content.split("\n");
|
|
45
|
+
|
|
46
|
+
// Calculate max width needed
|
|
47
|
+
const contentWidth = Math.max(
|
|
48
|
+
...lines.map((line) => stripAnsi(line).length),
|
|
49
|
+
stripAnsi(title).length
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// Set minimum and maximum width
|
|
53
|
+
const minWidth = 50;
|
|
54
|
+
const maxWidth = 80;
|
|
55
|
+
const width = Math.min(Math.max(contentWidth, minWidth), maxWidth);
|
|
56
|
+
|
|
57
|
+
// Top border
|
|
58
|
+
console.log(chalk.cyan("┌" + "─".repeat(width + 2) + "┐"));
|
|
59
|
+
|
|
60
|
+
// Title
|
|
61
|
+
const titlePadded = title + " ".repeat(width - stripAnsi(title).length);
|
|
62
|
+
console.log(chalk.cyan("│ ") + chalk.bold(titlePadded) + chalk.cyan(" │"));
|
|
63
|
+
|
|
64
|
+
// Separator
|
|
65
|
+
console.log(chalk.cyan("├" + "─".repeat(width + 2) + "┤"));
|
|
66
|
+
|
|
67
|
+
// Content lines
|
|
68
|
+
lines.forEach((line) => {
|
|
69
|
+
const lineLength = stripAnsi(line).length;
|
|
70
|
+
const padding = " ".repeat(width - lineLength);
|
|
71
|
+
console.log(chalk.cyan("│ ") + line + padding + chalk.cyan(" │"));
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Bottom border
|
|
75
|
+
console.log(chalk.cyan("└" + "─".repeat(width + 2) + "┘\n"));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Strip ANSI color codes to get actual string length
|
|
80
|
+
* @param {string} str - String with potential ANSI codes
|
|
81
|
+
* @returns {string} Clean string
|
|
82
|
+
*/
|
|
83
|
+
function stripAnsi(str) {
|
|
84
|
+
// eslint-disable-next-line no-control-regex
|
|
85
|
+
return str.replace(/\x1B\[\d+m/g, "");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
displayBanner,
|
|
90
|
+
displaySuccess,
|
|
91
|
+
displayError,
|
|
92
|
+
displayWarning,
|
|
93
|
+
displayInfo,
|
|
94
|
+
displayBox,
|
|
95
|
+
};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
const { TOOLS, DEPARTMENTS } = require('../lib/config');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate README.md content for the generated configuration
|
|
5
|
+
* @param {Object} config - Configuration object
|
|
6
|
+
* @param {Object} result - Generation result
|
|
7
|
+
* @returns {string} README content
|
|
8
|
+
*/
|
|
9
|
+
function generateReadme(config, result) {
|
|
10
|
+
const tool = TOOLS[config.tool];
|
|
11
|
+
const timestamp = new Date().toISOString();
|
|
12
|
+
|
|
13
|
+
return `# AI Agents Configuration
|
|
14
|
+
|
|
15
|
+
> Generated with [AgentKit](https://github.com/patricio0312rev/agentkit) 🤖
|
|
16
|
+
|
|
17
|
+
## 📋 Overview
|
|
18
|
+
|
|
19
|
+
- **Tool**: ${tool.name}
|
|
20
|
+
- **Location**: \`${config.folder}/\`
|
|
21
|
+
- **Departments**: ${config.departments.length}
|
|
22
|
+
- **Agents**: ${result.agentsGenerated}
|
|
23
|
+
- **Generated**: ${new Date().toLocaleString()}
|
|
24
|
+
|
|
25
|
+
## 🚀 Usage
|
|
26
|
+
|
|
27
|
+
${getDetailedUsageInstructions(config.tool)}
|
|
28
|
+
|
|
29
|
+
## 📁 Structure
|
|
30
|
+
|
|
31
|
+
\`\`\`
|
|
32
|
+
${config.folder}/
|
|
33
|
+
${generateStructureTree(config)}
|
|
34
|
+
\`\`\`
|
|
35
|
+
|
|
36
|
+
## 🏢 Departments Included
|
|
37
|
+
|
|
38
|
+
${generateDepartmentsList(config)}
|
|
39
|
+
|
|
40
|
+
${config.stack.length > 0 ? generateStackSection(config.stack) : ''}
|
|
41
|
+
|
|
42
|
+
## 🔄 Updating
|
|
43
|
+
|
|
44
|
+
To regenerate or update your configuration:
|
|
45
|
+
|
|
46
|
+
\`\`\`bash
|
|
47
|
+
npx agentkit init
|
|
48
|
+
\`\`\`
|
|
49
|
+
|
|
50
|
+
Or if installed globally:
|
|
51
|
+
|
|
52
|
+
\`\`\`bash
|
|
53
|
+
agentkit init
|
|
54
|
+
\`\`\`
|
|
55
|
+
|
|
56
|
+
## 📚 Resources
|
|
57
|
+
|
|
58
|
+
- [AgentKit Documentation](https://github.com/patricio0312rev/agentkit)
|
|
59
|
+
- [Claude Code Documentation](https://code.claude.com/docs)
|
|
60
|
+
- [Cursor Documentation](https://cursor.sh/docs)
|
|
61
|
+
|
|
62
|
+
## 💡 Tips
|
|
63
|
+
|
|
64
|
+
- Commit these files to version control
|
|
65
|
+
- Share with your team for consistent AI assistance
|
|
66
|
+
- Update regularly as your project evolves
|
|
67
|
+
- Customize agent instructions for your specific needs
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
*Generated by AgentKit v${require('../../package.json').version}*
|
|
72
|
+
`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function getDetailedUsageInstructions(tool) {
|
|
76
|
+
const instructions = {
|
|
77
|
+
'claude-code': `### With Claude Code CLI
|
|
78
|
+
|
|
79
|
+
The agents in this folder are automatically loaded by Claude Code.
|
|
80
|
+
|
|
81
|
+
\`\`\`bash
|
|
82
|
+
# Use agents in your prompts naturally
|
|
83
|
+
claude-code "Build a login page using the frontend-developer patterns"
|
|
84
|
+
|
|
85
|
+
# Reference specific agents
|
|
86
|
+
claude-code "Review this API design with the backend-architect agent"
|
|
87
|
+
\`\`\`
|
|
88
|
+
|
|
89
|
+
### Sub-Agent System
|
|
90
|
+
|
|
91
|
+
Claude Code's sub-agent system allows multiple specialized agents to work together on complex tasks.`,
|
|
92
|
+
|
|
93
|
+
'cursor': `### With Cursor
|
|
94
|
+
|
|
95
|
+
**Method 1: @-mentions**
|
|
96
|
+
|
|
97
|
+
\`\`\`
|
|
98
|
+
In Cursor chat, use @-mentions:
|
|
99
|
+
@engineering/backend-architect.md Design a REST API for user management
|
|
100
|
+
\`\`\`
|
|
101
|
+
|
|
102
|
+
**Method 2: Natural References**
|
|
103
|
+
|
|
104
|
+
Just reference the agent naturally in your prompts:
|
|
105
|
+
\`\`\`
|
|
106
|
+
"Using the backend-architect guidelines, design an API..."
|
|
107
|
+
\`\`\`
|
|
108
|
+
|
|
109
|
+
### Settings
|
|
110
|
+
|
|
111
|
+
1. Cursor automatically detects agent files in common folders
|
|
112
|
+
2. You can also configure custom folders in Cursor settings`,
|
|
113
|
+
|
|
114
|
+
'copilot': `### With GitHub Copilot
|
|
115
|
+
|
|
116
|
+
The configuration file is located at:
|
|
117
|
+
\`\`\`
|
|
118
|
+
.github/copilot-instructions.md
|
|
119
|
+
\`\`\`
|
|
120
|
+
|
|
121
|
+
GitHub Copilot will automatically use these instructions when:
|
|
122
|
+
- Writing code
|
|
123
|
+
- Suggesting completions
|
|
124
|
+
- Answering questions in chat
|
|
125
|
+
|
|
126
|
+
No additional setup required!`,
|
|
127
|
+
|
|
128
|
+
'universal': `### With Any AI Tool
|
|
129
|
+
|
|
130
|
+
1. **Upload Method**: Upload relevant agent .md files to your AI chat
|
|
131
|
+
2. **Reference**: Reference them in your prompts
|
|
132
|
+
3. **Copy-Paste**: Or copy agent content directly into context
|
|
133
|
+
|
|
134
|
+
Example:
|
|
135
|
+
\`\`\`
|
|
136
|
+
[Upload: engineering/backend-architect.md]
|
|
137
|
+
|
|
138
|
+
"Following the backend-architect guidelines, help me design..."
|
|
139
|
+
\`\`\``
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
return instructions[tool] || instructions.universal;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function generateStructureTree(config) {
|
|
146
|
+
const lines = ['├── README.md'];
|
|
147
|
+
|
|
148
|
+
config.departments.forEach((dept, index) => {
|
|
149
|
+
const isLast = index === config.departments.length - 1;
|
|
150
|
+
const prefix = isLast ? '└──' : '├──';
|
|
151
|
+
lines.push(`${prefix} ${dept}/`);
|
|
152
|
+
|
|
153
|
+
const agents = DEPARTMENTS[dept].agents;
|
|
154
|
+
agents.forEach((agent, agentIndex) => {
|
|
155
|
+
const agentIsLast = agentIndex === agents.length - 1;
|
|
156
|
+
const agentPrefix = isLast ? ' ' : '│ ';
|
|
157
|
+
const agentMarker = agentIsLast ? '└──' : '├──';
|
|
158
|
+
lines.push(`${agentPrefix}${agentMarker} ${agent}.md`);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
return lines.join('\n');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function generateDepartmentsList(config) {
|
|
166
|
+
return config.departments.map(dept => {
|
|
167
|
+
const deptInfo = DEPARTMENTS[dept];
|
|
168
|
+
return `### ${deptInfo.name}
|
|
169
|
+
|
|
170
|
+
${deptInfo.description}
|
|
171
|
+
|
|
172
|
+
**Agents** (${deptInfo.agents.length}):
|
|
173
|
+
${deptInfo.agents.map(agent => `- \`${agent}\``).join('\n')}
|
|
174
|
+
`;
|
|
175
|
+
}).join('\n');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function generateStackSection(stack) {
|
|
179
|
+
return `## 🛠️ Tech Stack
|
|
180
|
+
|
|
181
|
+
This configuration is optimized for:
|
|
182
|
+
|
|
183
|
+
${stack.map(tech => `- ${tech}`).join('\n')}
|
|
184
|
+
|
|
185
|
+
Agents are aware of this stack and will provide relevant guidance.
|
|
186
|
+
`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
module.exports = {
|
|
190
|
+
generateReadme
|
|
191
|
+
};
|