@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.
Files changed (47) hide show
  1. package/CONTRIBUTING.md +491 -0
  2. package/LICENSE +21 -0
  3. package/README.md +442 -0
  4. package/bin/cli.js +41 -0
  5. package/package.json +54 -0
  6. package/src/commands/init.js +312 -0
  7. package/src/index.js +220 -0
  8. package/src/lib/config.js +157 -0
  9. package/src/lib/generator.js +193 -0
  10. package/src/utils/display.js +95 -0
  11. package/src/utils/readme.js +191 -0
  12. package/src/utils/tool-specific.js +408 -0
  13. package/templates/departments/design/brand-guardian.md +133 -0
  14. package/templates/departments/design/ui-designer.md +154 -0
  15. package/templates/departments/design/ux-researcher.md +285 -0
  16. package/templates/departments/design/visual-storyteller.md +296 -0
  17. package/templates/departments/design/whimsy-injector.md +318 -0
  18. package/templates/departments/engineering/ai-engineer.md +386 -0
  19. package/templates/departments/engineering/backend-architect.md +425 -0
  20. package/templates/departments/engineering/devops-automator.md +393 -0
  21. package/templates/departments/engineering/frontend-developer.md +411 -0
  22. package/templates/departments/engineering/mobile-app-builder.md +412 -0
  23. package/templates/departments/engineering/rapid-prototyper.md +415 -0
  24. package/templates/departments/engineering/test-writer-fixer.md +462 -0
  25. package/templates/departments/marketing/app-store-optimizer.md +176 -0
  26. package/templates/departments/marketing/content-creator.md +206 -0
  27. package/templates/departments/marketing/growth-hacker.md +219 -0
  28. package/templates/departments/marketing/instagram-curator.md +166 -0
  29. package/templates/departments/marketing/reddit-community-builder.md +192 -0
  30. package/templates/departments/marketing/tiktok-strategist.md +158 -0
  31. package/templates/departments/marketing/twitter-engager.md +184 -0
  32. package/templates/departments/product/feedback-synthesizer.md +143 -0
  33. package/templates/departments/product/sprint-prioritizer.md +169 -0
  34. package/templates/departments/product/trend-researcher.md +176 -0
  35. package/templates/departments/project-management/experiment-tracker.md +128 -0
  36. package/templates/departments/project-management/project-shipper.md +151 -0
  37. package/templates/departments/project-management/studio-producer.md +156 -0
  38. package/templates/departments/studio-operations/analytics-reporter.md +191 -0
  39. package/templates/departments/studio-operations/finance-tracker.md +242 -0
  40. package/templates/departments/studio-operations/infrastructure-maintainer.md +202 -0
  41. package/templates/departments/studio-operations/legal-compliance-checker.md +208 -0
  42. package/templates/departments/studio-operations/support-responder.md +181 -0
  43. package/templates/departments/testing/api-tester.md +207 -0
  44. package/templates/departments/testing/performance-benchmarker.md +262 -0
  45. package/templates/departments/testing/test-results-analyzer.md +251 -0
  46. package/templates/departments/testing/tool-evaluator.md +206 -0
  47. 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
+ };