UNPKG

agentic-data-stack-community

Version:

AI Agentic Data Stack Framework - Community Edition. Open source data engineering framework with 4 core agents, essential templates, and 3-dimensional quality validation.

1,483 lines (1,246 loc) • 42.1 kB
/** * Expansion Pack Manager - Modular Domain Extension System * * Implements sophisticated expansion pack architecture with: * - Dynamic pack discovery and loading * - Agent team composition and integration * - Domain-specific resource management * - Pack dependency resolution * - Version compatibility checking * - Interactive pack creation wizard * - Pack validation and quality control * - Marketplace integration readiness */ const chalk = require('chalk'); const inquirer = require('inquirer'); const fs = require('fs-extra'); const path = require('path'); const yaml = require('yaml'); class ExpansionPackManager { constructor(options = {}) { this.rootDir = options.rootDir || process.cwd(); this.dataCore = path.join(this.rootDir, 'data-core'); this.expansionPacksDir = path.join(this.rootDir, 'expansion-packs'); this.installedPacks = new Map(); this.packRegistry = new Map(); this.packDependencies = new Map(); this.agentOrchestrator = options.agentOrchestrator; this.knowledgeBase = options.knowledgeBase; this.templateEngine = options.templateEngine; } /** * Initialize expansion pack system */ async initialize() { console.log(chalk.blue('šŸ“¦ Initializing Expansion Pack System...')); try { // Ensure expansion packs directory exists await fs.ensureDir(this.expansionPacksDir); // Discover available packs await this.discoverPacks(); // Load pack configurations await this.loadPackConfigurations(); // Validate pack compatibility await this.validateCompatibility(); console.log(chalk.green(`āœ… Expansion Pack System initialized`)); console.log(chalk.dim(` Found ${this.packRegistry.size} available packs`)); console.log(chalk.dim(` ${this.installedPacks.size} packs installed`)); return { success: true, available: this.packRegistry.size, installed: this.installedPacks.size }; } catch (error) { console.error(chalk.red(`āŒ Initialization failed: ${error.message}`)); return { success: false, error: error.message }; } } /** * Discover available expansion packs */ async discoverPacks() { if (!await fs.pathExists(this.expansionPacksDir)) { return; } const entries = await fs.readdir(this.expansionPacksDir, { withFileTypes: true }); for (const entry of entries) { if (entry.isDirectory() && !entry.name.startsWith('.')) { const packPath = path.join(this.expansionPacksDir, entry.name); const configPath = path.join(packPath, 'config.yaml'); if (await fs.pathExists(configPath)) { try { const config = await this.loadPackConfig(configPath); this.packRegistry.set(entry.name, { ...config, path: packPath, installed: true }); } catch (error) { console.warn(chalk.yellow(`Warning: Invalid pack config in ${entry.name}`)); } } } } // Discover example packs from reference await this.discoverReferencePacks(); } /** * Discover reference/example packs */ async discoverReferencePacks() { const referencePacksDir = path.join(this.rootDir, 'reference', 'expansion-packs'); if (!await fs.pathExists(referencePacksDir)) { return; } const entries = await fs.readdir(referencePacksDir, { withFileTypes: true }); for (const entry of entries) { if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'README.md') { const packPath = path.join(referencePacksDir, entry.name); const configPath = path.join(packPath, 'config.yaml'); if (await fs.pathExists(configPath)) { try { const config = await this.loadPackConfig(configPath); if (!this.packRegistry.has(entry.name)) { this.packRegistry.set(entry.name, { ...config, path: packPath, installed: false, reference: true }); } } catch (error) { console.warn(chalk.yellow(`Warning: Invalid reference pack config in ${entry.name}`)); } } } } } /** * Load pack configuration */ async loadPackConfig(configPath) { const content = await fs.readFile(configPath, 'utf8'); const config = yaml.parse(content); return { name: config.name, version: config.version, title: config['short-title'] || config.title || config.name, description: config.description, author: config.author || 'Unknown', slashPrefix: config.slashPrefix, dependencies: config.dependencies || [], agents: config.agents || [], category: config.category || 'general' }; } /** * Load detailed pack configurations */ async loadPackConfigurations() { for (const [packName, packInfo] of this.packRegistry.entries()) { if (packInfo.installed) { try { const pack = await this.loadPackDetails(packInfo.path); this.installedPacks.set(packName, pack); } catch (error) { console.warn(chalk.yellow(`Warning: Could not load pack ${packName}: ${error.message}`)); } } } } /** * Load complete pack details */ async loadPackDetails(packPath) { const pack = { path: packPath, agents: new Map(), tasks: new Map(), templates: new Map(), workflows: new Map(), checklists: new Map(), data: new Map() }; // Load agents const agentsDir = path.join(packPath, 'agents'); if (await fs.pathExists(agentsDir)) { const agentFiles = await fs.readdir(agentsDir); for (const file of agentFiles) { if (file.endsWith('.md')) { const agentPath = path.join(agentsDir, file); const content = await fs.readFile(agentPath, 'utf8'); const agentId = path.basename(file, '.md'); pack.agents.set(agentId, { path: agentPath, content, id: agentId }); } } } // Load tasks const tasksDir = path.join(packPath, 'tasks'); if (await fs.pathExists(tasksDir)) { const taskFiles = await fs.readdir(tasksDir); for (const file of taskFiles) { if (file.endsWith('.md')) { const taskPath = path.join(tasksDir, file); const content = await fs.readFile(taskPath, 'utf8'); const taskId = path.basename(file, '.md'); pack.tasks.set(taskId, { path: taskPath, content, id: taskId }); } } } // Load templates const templatesDir = path.join(packPath, 'templates'); if (await fs.pathExists(templatesDir)) { const templateFiles = await fs.readdir(templatesDir); for (const file of templateFiles) { if (file.endsWith('.yaml') || file.endsWith('.yml')) { const templatePath = path.join(templatesDir, file); const content = await fs.readFile(templatePath, 'utf8'); const templateId = path.basename(file).replace(/\.(yaml|yml)$/, ''); pack.templates.set(templateId, { path: templatePath, content, id: templateId }); } } } // Load workflows const workflowsDir = path.join(packPath, 'workflows'); if (await fs.pathExists(workflowsDir)) { const workflowFiles = await fs.readdir(workflowsDir); for (const file of workflowFiles) { if (file.endsWith('.yaml') || file.endsWith('.yml')) { const workflowPath = path.join(workflowsDir, file); const content = await fs.readFile(workflowPath, 'utf8'); const workflowId = path.basename(file).replace(/\.(yaml|yml)$/, ''); pack.workflows.set(workflowId, { path: workflowPath, content, id: workflowId }); } } } // Load data files const dataDir = path.join(packPath, 'data'); if (await fs.pathExists(dataDir)) { const dataFiles = await fs.readdir(dataDir); for (const file of dataFiles) { if (file.endsWith('.md')) { const dataPath = path.join(dataDir, file); const content = await fs.readFile(dataPath, 'utf8'); const dataId = path.basename(file, '.md'); pack.data.set(dataId, { path: dataPath, content, id: dataId }); } } } return pack; } /** * Validate pack compatibility */ async validateCompatibility() { for (const [packName, packInfo] of this.packRegistry.entries()) { if (packInfo.dependencies && packInfo.dependencies.length > 0) { for (const dep of packInfo.dependencies) { if (!this.packRegistry.has(dep)) { console.warn(chalk.yellow(`Warning: Pack ${packName} requires missing dependency: ${dep}`)); } } } } } /** * Interactive pack management interface */ async managePacks() { console.log(chalk.bold.blue('\nšŸ“¦ Expansion Pack Manager')); const actions = [ 'Browse available packs', 'Install expansion pack', 'Create new expansion pack', 'Manage installed packs', 'Validate pack integrity', 'Exit' ]; const { action } = await inquirer.prompt([{ type: 'list', name: 'action', message: 'What would you like to do?', choices: actions }]); switch (action) { case 'Browse available packs': return await this.browseAvailablePacks(); case 'Install expansion pack': return await this.installPack(); case 'Create new expansion pack': return await this.createNewPack(); case 'Manage installed packs': return await this.manageInstalledPacks(); case 'Validate pack integrity': return await this.validatePacks(); default: return { success: true, action: 'exit' }; } } /** * Browse available expansion packs */ async browseAvailablePacks() { console.log(chalk.bold.blue('\nšŸ“š Available Expansion Packs\n')); const categories = new Map(); // Group packs by category this.packRegistry.forEach((pack, packName) => { const category = pack.category || 'general'; if (!categories.has(category)) { categories.set(category, []); } categories.get(category).push({ packName, ...pack }); }); // Display by category categories.forEach((packs, category) => { console.log(chalk.bold.yellow(`${category.charAt(0).toUpperCase() + category.slice(1)}:`)); packs.forEach(pack => { const status = pack.installed ? chalk.green('āœ“ Installed') : pack.reference ? chalk.blue('⬇ Available') : chalk.gray('ā—‹ Not Installed'); console.log(` ${status} ${chalk.bold(pack.title || pack.name)} v${pack.version}`); console.log(chalk.dim(` ${pack.description || 'No description'}`)); if (pack.author) { console.log(chalk.dim(` Author: ${pack.author}`)); } console.log(''); }); }); const { viewDetails } = await inquirer.prompt([{ type: 'confirm', name: 'viewDetails', message: 'Would you like to view details of a specific pack?', default: true }]); if (viewDetails) { const packChoices = Array.from(this.packRegistry.entries()) .map(([name, pack]) => ({ name: `${pack.title || name} (${pack.installed ? 'Installed' : 'Available'})`, value: name })); const { selectedPack } = await inquirer.prompt([{ type: 'list', name: 'selectedPack', message: 'Select a pack to view details:', choices: packChoices }]); await this.viewPackDetails(selectedPack); } return { success: true }; } /** * View detailed pack information */ async viewPackDetails(packName) { const packInfo = this.packRegistry.get(packName); if (!packInfo) { console.log(chalk.red('Pack not found')); return; } console.log(chalk.bold.blue(`\nšŸ“¦ ${packInfo.title || packName}`)); console.log(chalk.dim('═'.repeat(50))); console.log(chalk.bold('Version:'), packInfo.version); console.log(chalk.bold('Author:'), packInfo.author || 'Unknown'); console.log(chalk.bold('Category:'), packInfo.category || 'general'); console.log(chalk.bold('Status:'), packInfo.installed ? 'Installed' : 'Not Installed'); if (packInfo.slashPrefix) { console.log(chalk.bold('Command Prefix:'), `/${packInfo.slashPrefix}`); } console.log(chalk.bold('\nDescription:')); console.log(chalk.dim(packInfo.description || 'No description available')); if (packInfo.installed) { const pack = this.installedPacks.get(packName); if (pack) { console.log(chalk.bold('\nContents:')); console.log(chalk.green(` • ${pack.agents.size} Agents`)); console.log(chalk.green(` • ${pack.tasks.size} Tasks`)); console.log(chalk.green(` • ${pack.templates.size} Templates`)); console.log(chalk.green(` • ${pack.workflows.size} Workflows`)); console.log(chalk.green(` • ${pack.data.size} Data Files`)); if (pack.agents.size > 0) { console.log(chalk.bold('\nAgents:')); pack.agents.forEach((agent, agentId) => { console.log(chalk.dim(` • ${agentId}`)); }); } } } if (packInfo.dependencies && packInfo.dependencies.length > 0) { console.log(chalk.bold('\nDependencies:')); packInfo.dependencies.forEach(dep => { const installed = this.packRegistry.has(dep) && this.packRegistry.get(dep).installed; console.log(` ${installed ? chalk.green('āœ“') : chalk.red('āœ—')} ${dep}`); }); } } /** * Install an expansion pack */ async installPack() { console.log(chalk.bold.blue('\nšŸ“„ Install Expansion Pack\n')); // Filter available packs (not installed) const availablePacks = Array.from(this.packRegistry.entries()) .filter(([_, pack]) => !pack.installed) .map(([name, pack]) => ({ name: `${pack.title || name} - ${pack.description || 'No description'}`, value: name })); if (availablePacks.length === 0) { console.log(chalk.yellow('No available packs to install')); console.log(chalk.dim('All discovered packs are already installed')); return { success: false }; } const { packToInstall } = await inquirer.prompt([{ type: 'list', name: 'packToInstall', message: 'Select pack to install:', choices: availablePacks }]); const packInfo = this.packRegistry.get(packToInstall); // Check dependencies if (packInfo.dependencies && packInfo.dependencies.length > 0) { console.log(chalk.yellow('\nChecking dependencies...')); const missingDeps = packInfo.dependencies.filter(dep => !this.packRegistry.has(dep) || !this.packRegistry.get(dep).installed ); if (missingDeps.length > 0) { console.log(chalk.red('Missing dependencies:'), missingDeps.join(', ')); const { installDeps } = await inquirer.prompt([{ type: 'confirm', name: 'installDeps', message: 'Install missing dependencies?', default: true }]); if (installDeps) { for (const dep of missingDeps) { await this.installPackByName(dep); } } else { return { success: false, error: 'Missing dependencies' }; } } } // Install the pack return await this.installPackByName(packToInstall); } /** * Install a pack by name */ async installPackByName(packName) { const packInfo = this.packRegistry.get(packName); if (!packInfo) { console.log(chalk.red(`Pack not found: ${packName}`)); return { success: false, error: 'Pack not found' }; } if (packInfo.installed) { console.log(chalk.yellow(`Pack already installed: ${packName}`)); return { success: true, alreadyInstalled: true }; } console.log(chalk.blue(`Installing ${packInfo.title || packName}...`)); try { const targetPath = path.join(this.expansionPacksDir, packName); // Copy from reference location if (packInfo.reference && packInfo.path) { await fs.copy(packInfo.path, targetPath); // Update registry packInfo.installed = true; packInfo.path = targetPath; // Load pack details const pack = await this.loadPackDetails(targetPath); this.installedPacks.set(packName, pack); // Register with agent orchestrator if available if (this.agentOrchestrator) { await this.registerPackAgents(packName, pack); } // Add to knowledge base if available if (this.knowledgeBase) { await this.registerPackKnowledge(packName, pack); } console.log(chalk.green(`āœ… Successfully installed ${packInfo.title || packName}`)); return { success: true, packName }; } else { console.log(chalk.red('Pack source not found')); return { success: false, error: 'Pack source not found' }; } } catch (error) { console.error(chalk.red(`Installation failed: ${error.message}`)); return { success: false, error: error.message }; } } /** * Create a new expansion pack */ async createNewPack() { console.log(chalk.bold.blue('\nšŸŽØ Create New Expansion Pack\n')); console.log(chalk.dim('Let\'s create a custom expansion pack for your domain\n')); // Gather basic information const packInfo = await inquirer.prompt([ { type: 'input', name: 'name', message: 'Pack name (lowercase, hyphens):', validate: input => /^[a-z0-9-]+$/.test(input) || 'Use lowercase letters, numbers, and hyphens only', filter: input => input.toLowerCase().replace(/\s+/g, '-') }, { type: 'input', name: 'title', message: 'Display title:', validate: input => input.trim().length > 0 || 'Title is required' }, { type: 'input', name: 'description', message: 'Pack description:', validate: input => input.trim().length > 0 || 'Description is required' }, { type: 'input', name: 'author', message: 'Author name:', default: 'Unknown' }, { type: 'list', name: 'category', message: 'Pack category:', choices: [ 'technical', 'business', 'creative', 'health', 'education', 'gaming', 'productivity', 'general' ] }, { type: 'input', name: 'slashPrefix', message: 'Command prefix (optional, e.g., "game" for /game):', filter: input => input.replace(/^\//, '').trim() } ]); // Domain-specific questions const domainInfo = await inquirer.prompt([ { type: 'input', name: 'domain', message: 'What domain/industry does this pack serve?', validate: input => input.trim().length > 0 || 'Domain is required' }, { type: 'input', name: 'problems', message: 'What problems will this pack solve? (comma-separated):', filter: input => input.split(',').map(s => s.trim()).filter(s => s) }, { type: 'input', name: 'targetUsers', message: 'Who are the target users?', validate: input => input.trim().length > 0 || 'Target users required' } ]); // Agent design console.log(chalk.bold('\nšŸ¤– Let\'s design your agents:\n')); const agents = await this.designPackAgents(packInfo.name); // Create pack structure console.log(chalk.blue('\nšŸ“ Creating pack structure...')); const packPath = path.join(this.expansionPacksDir, packInfo.name); try { // Create directories await fs.ensureDir(packPath); await fs.ensureDir(path.join(packPath, 'agents')); await fs.ensureDir(path.join(packPath, 'tasks')); await fs.ensureDir(path.join(packPath, 'templates')); await fs.ensureDir(path.join(packPath, 'workflows')); await fs.ensureDir(path.join(packPath, 'checklists')); await fs.ensureDir(path.join(packPath, 'data')); await fs.ensureDir(path.join(packPath, 'agent-teams')); // Create config.yaml const config = { name: packInfo.name, version: '1.0.0', 'short-title': packInfo.title, description: packInfo.description, author: packInfo.author, category: packInfo.category, slashPrefix: packInfo.slashPrefix || undefined, domain: domainInfo.domain, problems: domainInfo.problems, targetUsers: domainInfo.targetUsers, agents: agents.map(a => a.id), dependencies: [] }; await fs.writeFile( path.join(packPath, 'config.yaml'), yaml.stringify(config), 'utf8' ); // Create agent files for (const agent of agents) { await this.createAgentFile(packPath, agent); } // Create sample task await this.createSampleTask(packPath, packInfo.name); // Create sample template await this.createSampleTemplate(packPath, packInfo.name); // Create knowledge base file await this.createPackKnowledgeBase(packPath, packInfo, domainInfo, agents); // Create README await this.createPackReadme(packPath, packInfo, domainInfo, agents); console.log(chalk.green(`\nāœ… Expansion pack created successfully!`)); console.log(chalk.dim(`Location: ${packPath}`)); // Register the new pack this.packRegistry.set(packInfo.name, { ...config, path: packPath, installed: true }); // Load pack details const pack = await this.loadPackDetails(packPath); this.installedPacks.set(packInfo.name, pack); console.log(chalk.bold('\nNext steps:')); console.log('1. Add more agents to the agents/ directory'); console.log('2. Create tasks in the tasks/ directory'); console.log('3. Design templates in the templates/ directory'); console.log('4. Define workflows in the workflows/ directory'); console.log('5. Test with your target users'); return { success: true, packName: packInfo.name, path: packPath }; } catch (error) { console.error(chalk.red(`Failed to create pack: ${error.message}`)); return { success: false, error: error.message }; } } /** * Design agents for a new pack */ async designPackAgents(packName) { const agents = []; let addMore = true; console.log(chalk.dim('Design specialized agents for your domain (minimum 2)\n')); while (addMore || agents.length < 2) { const agentNum = agents.length + 1; console.log(chalk.bold(`\nAgent ${agentNum}:`)); const agentInfo = await inquirer.prompt([ { type: 'input', name: 'id', message: 'Agent ID (lowercase, hyphens):', validate: input => /^[a-z0-9-]+$/.test(input) || 'Use lowercase letters, numbers, and hyphens only', filter: input => input.toLowerCase().replace(/\s+/g, '-') }, { type: 'input', name: 'name', message: 'Agent name:', validate: input => input.trim().length > 0 || 'Name is required' }, { type: 'input', name: 'title', message: 'Agent title/role:', validate: input => input.trim().length > 0 || 'Title is required' }, { type: 'input', name: 'icon', message: 'Agent icon (emoji):', default: 'šŸ¤–' }, { type: 'input', name: 'expertise', message: 'Areas of expertise (comma-separated):', filter: input => input.split(',').map(s => s.trim()).filter(s => s) }, { type: 'input', name: 'personality', message: 'Personality traits (comma-separated):', filter: input => input.split(',').map(s => s.trim()).filter(s => s), default: 'professional, helpful, knowledgeable' } ]); agents.push(agentInfo); if (agents.length >= 2) { const { continue: shouldContinue } = await inquirer.prompt([{ type: 'confirm', name: 'continue', message: 'Add another agent?', default: false }]); addMore = shouldContinue; } } return agents; } /** * Create agent file */ async createAgentFile(packPath, agentInfo) { const agentContent = `# ${agentInfo.name} ## Agent Configuration \`\`\`yaml agent: id: ${agentInfo.id} name: ${agentInfo.name} title: ${agentInfo.title} icon: ${agentInfo.icon} persona: role: ${agentInfo.title} expertise: ${agentInfo.expertise.map(e => `\n - ${e}`).join('')} personality: ${agentInfo.personality.map(p => `\n - ${p}`).join('')} communication_style: Clear, professional, domain-specific capabilities: primary: - ${agentInfo.expertise[0] || 'Domain expertise'} - Task execution and guidance - Knowledge synthesis secondary: - Cross-functional collaboration - Best practice recommendations - Quality assurance commands: - help: Show available commands and capabilities - task: Execute a specific task - analyze: Analyze current context - recommend: Provide recommendations - create-doc: Create documentation from templates dependencies: tasks: - analyze-context.md - provide-recommendations.md templates: - analysis-report-tmpl.yaml - recommendation-tmpl.yaml data: - ${agentInfo.id}-kb.md \`\`\` ## Operational Guidelines ### Primary Responsibilities 1. **${agentInfo.expertise[0] || 'Domain Expertise'}** - Provide expert guidance and recommendations - Ensure best practices are followed - Validate approaches and solutions 2. **Task Execution** - Guide users through complex tasks - Break down problems into manageable steps - Ensure quality outcomes 3. **Knowledge Management** - Synthesize information effectively - Provide context-aware insights - Document decisions and rationale ### Interaction Patterns - Always maintain professional demeanor - Ask clarifying questions when needed - Provide actionable recommendations - Validate understanding before proceeding ### Quality Standards - Ensure all outputs meet domain standards - Validate recommendations against best practices - Document assumptions and constraints - Provide clear success criteria `; await fs.writeFile( path.join(packPath, 'agents', `${agentInfo.id}.md`), agentContent, 'utf8' ); } /** * Create sample task */ async createSampleTask(packPath, packName) { const taskContent = `# Analyze Context Task ## Purpose Analyze the current context and provide domain-specific insights and recommendations. ## Task Steps 1. **Gather Context** - Understand the current situation - Identify key stakeholders - Document constraints and requirements 2. **Analyze Domain Factors** - Apply domain expertise - Identify patterns and trends - Assess risks and opportunities 3. **Generate Insights** - Synthesize findings - Identify key insights - Prioritize by impact 4. **Provide Recommendations** - Develop actionable recommendations - Consider implementation feasibility - Define success metrics ## Expected Outputs - Context analysis document - Key insights summary - Prioritized recommendations - Implementation roadmap ## Quality Criteria - Comprehensive analysis - Clear and actionable insights - Evidence-based recommendations - Practical implementation guidance `; await fs.writeFile( path.join(packPath, 'tasks', 'analyze-context.md'), taskContent, 'utf8' ); } /** * Create sample template */ async createSampleTemplate(packPath, packName) { const templateContent = { template: { name: 'Analysis Report Template', version: '1.0', description: 'Template for domain-specific analysis reports', sections: [ { id: 'executive-summary', title: 'Executive Summary', type: 'paragraph', instruction: 'Provide a high-level summary of the analysis and key findings', elicit: true }, { id: 'context', title: 'Context and Background', type: 'structured', fields: [ { field: 'Situation', description: 'Current situation overview' }, { field: 'Stakeholders', description: 'Key stakeholders involved' }, { field: 'Constraints', description: 'Known constraints and limitations' } ] }, { id: 'analysis', title: 'Detailed Analysis', type: 'paragraphs', instruction: 'Provide comprehensive analysis of the domain-specific factors', elicit: true }, { id: 'recommendations', title: 'Recommendations', type: 'numbered-list', instruction: 'List prioritized recommendations with rationale', elicit: true }, { id: 'next-steps', title: 'Next Steps', type: 'bullet-list', instruction: 'Define clear next steps and action items' } ] } }; await fs.writeFile( path.join(packPath, 'templates', 'analysis-report-tmpl.yaml'), yaml.stringify(templateContent), 'utf8' ); } /** * Create pack knowledge base */ async createPackKnowledgeBase(packPath, packInfo, domainInfo, agents) { const kbContent = `# ${packInfo.title} Knowledge Base ## Overview ${packInfo.description} ### Domain Focus **Industry/Domain**: ${domainInfo.domain} **Target Users**: ${domainInfo.targetUsers} **Problems Solved**: ${domainInfo.problems.map(p => `- ${p}`).join('\n')} ## Agent Capabilities ${agents.map(agent => `### ${agent.name} (${agent.id}) **Role**: ${agent.title} **Expertise Areas**: ${agent.expertise.map(e => `- ${e}`).join('\n')} **Key Responsibilities**: - Provide expert guidance in ${agent.expertise[0] || 'domain area'} - Execute specialized tasks - Collaborate with other agents - Ensure quality outcomes `).join('\n')} ## Best Practices ### Domain-Specific Guidelines 1. **Understand Context First** - Always gather comprehensive context - Identify stakeholder needs - Document constraints clearly 2. **Apply Domain Expertise** - Use established best practices - Consider industry standards - Validate against real-world scenarios 3. **Deliver Value** - Focus on actionable outcomes - Provide clear recommendations - Enable implementation success ### Quality Standards - All outputs must be practical and implementable - Recommendations should be evidence-based - Documentation must be clear and comprehensive - Solutions should consider long-term sustainability ## Common Workflows ### Initial Analysis 1. Activate relevant agent 2. Execute context analysis task 3. Review findings 4. Generate recommendations ### Implementation Planning 1. Define objectives clearly 2. Break down into manageable tasks 3. Assign to appropriate agents 4. Track progress systematically ## Glossary Define domain-specific terms here to ensure consistent understanding. ## Resources List additional resources, references, and tools relevant to this domain. `; await fs.writeFile( path.join(packPath, 'data', `${packInfo.name}-kb.md`), kbContent, 'utf8' ); } /** * Create pack README */ async createPackReadme(packPath, packInfo, domainInfo, agents) { const readmeContent = `# ${packInfo.title} ${packInfo.description} ## Overview This expansion pack provides specialized AI agents for ${domainInfo.domain}, designed to help ${domainInfo.targetUsers}. ### Problems Solved ${domainInfo.problems.map(p => `- ${p}`).join('\n')} ## Agents ${agents.map(agent => `### ${agent.icon} ${agent.name} - **ID**: \`${agent.id}\` - **Role**: ${agent.title} - **Expertise**: ${agent.expertise.join(', ')}`).join('\n\n')} ## Quick Start 1. **Activate an agent**: \`\`\` @${agents[0].id} \`\`\` 2. **View available commands**: \`\`\` *help \`\`\` 3. **Execute a task**: \`\`\` *task analyze-context \`\`\` ## Installation This pack is installed in your expansion-packs directory. To use it: 1. Ensure the pack is loaded in your configuration 2. Activate agents using their IDs 3. Use the provided tasks and templates ## Structure \`\`\` ${packInfo.name}/ ā”œā”€ā”€ agents/ # Agent definitions ā”œā”€ā”€ tasks/ # Reusable task definitions ā”œā”€ā”€ templates/ # Document templates ā”œā”€ā”€ workflows/ # Multi-step workflows ā”œā”€ā”€ checklists/ # Quality checklists ā”œā”€ā”€ data/ # Knowledge base files └── config.yaml # Pack configuration \`\`\` ## Customization Feel free to: - Add new agents to the agents/ directory - Create domain-specific tasks - Design custom templates - Define workflows for common processes ## Version History - v1.0.0 - Initial release ## Author ${packInfo.author} ## License [Specify your license here] `; await fs.writeFile( path.join(packPath, 'README.md'), readmeContent, 'utf8' ); } /** * Manage installed packs */ async manageInstalledPacks() { console.log(chalk.bold.blue('\nšŸ“¦ Installed Expansion Packs\n')); if (this.installedPacks.size === 0) { console.log(chalk.yellow('No expansion packs installed')); return { success: true }; } const packChoices = Array.from(this.installedPacks.entries()) .map(([name, _]) => { const info = this.packRegistry.get(name); return { name: `${info.title || name} v${info.version}`, value: name }; }); const { selectedPack } = await inquirer.prompt([{ type: 'list', name: 'selectedPack', message: 'Select a pack to manage:', choices: [...packChoices, { name: 'Back', value: null }] }]); if (!selectedPack) { return { success: true }; } const { action } = await inquirer.prompt([{ type: 'list', name: 'action', message: `Manage ${selectedPack}:`, choices: [ 'View details', 'Update pack', 'Export pack', 'Uninstall pack', 'Back' ] }]); switch (action) { case 'View details': await this.viewPackDetails(selectedPack); break; case 'Update pack': await this.updatePack(selectedPack); break; case 'Export pack': await this.exportPack(selectedPack); break; case 'Uninstall pack': await this.uninstallPack(selectedPack); break; } return { success: true }; } /** * Validate pack integrity */ async validatePacks() { console.log(chalk.bold.blue('\nšŸ” Validating Expansion Packs\n')); const results = []; for (const [packName, pack] of this.installedPacks.entries()) { console.log(chalk.blue(`Validating ${packName}...`)); const issues = []; // Check required directories const requiredDirs = ['agents', 'tasks', 'templates']; for (const dir of requiredDirs) { const dirPath = path.join(pack.path, dir); if (!await fs.pathExists(dirPath)) { issues.push(`Missing required directory: ${dir}/`); } } // Check config file const configPath = path.join(pack.path, 'config.yaml'); if (!await fs.pathExists(configPath)) { issues.push('Missing config.yaml'); } // Check agent definitions if (pack.agents.size === 0) { issues.push('No agents defined'); } // Validate agent files for (const [agentId, agent] of pack.agents.entries()) { const agentIssues = this.validateAgentDefinition(agent.content); if (agentIssues.length > 0) { issues.push(`Agent ${agentId}: ${agentIssues.join(', ')}`); } } results.push({ packName, valid: issues.length === 0, issues }); } // Display results console.log(chalk.bold('\nValidation Results:\n')); results.forEach(result => { if (result.valid) { console.log(chalk.green(`āœ… ${result.packName}: Valid`)); } else { console.log(chalk.red(`āŒ ${result.packName}: ${result.issues.length} issues found`)); result.issues.forEach(issue => { console.log(chalk.dim(` - ${issue}`)); }); } }); return { success: true, results }; } /** * Validate agent definition */ validateAgentDefinition(content) { const issues = []; // Check for required YAML block if (!content.includes('```yaml')) { issues.push('Missing YAML configuration block'); } // Check for required sections const requiredSections = ['agent:', 'persona:', 'commands:']; requiredSections.forEach(section => { if (!content.includes(section)) { issues.push(`Missing required section: ${section}`); } }); return issues; } /** * Register pack agents with orchestrator */ async registerPackAgents(packName, pack) { if (!this.agentOrchestrator) return; console.log(chalk.dim(`Registering agents from ${packName}...`)); for (const [agentId, agent] of pack.agents.entries()) { try { // Add pack prefix to avoid conflicts const fullAgentId = `${packName}-${agentId}`; await this.agentOrchestrator.loadAgent(agent.path); console.log(chalk.dim(` āœ“ Registered ${agentId}`)); } catch (error) { console.warn(chalk.yellow(` Warning: Could not register ${agentId}`)); } } } /** * Register pack knowledge with KB */ async registerPackKnowledge(packName, pack) { if (!this.knowledgeBase) return; console.log(chalk.dim(`Adding knowledge from ${packName}...`)); for (const [dataId, data] of pack.data.entries()) { try { await this.knowledgeBase.updateKnowledge( `${packName}-${dataId}.md`, data.content, { source: 'expansion-pack', pack: packName } ); console.log(chalk.dim(` āœ“ Added ${dataId}`)); } catch (error) { console.warn(chalk.yellow(` Warning: Could not add ${dataId}`)); } } } /** * Export pack for sharing */ async exportPack(packName) { const pack = this.installedPacks.get(packName); if (!pack) { console.log(chalk.red('Pack not found')); return { success: false }; } console.log(chalk.blue(`\nšŸ“¤ Exporting ${packName}...`)); const exportPath = path.join(this.rootDir, 'exports', `${packName}-export.zip`); // TODO: Implement zip export functionality console.log(chalk.yellow('Export functionality coming soon!')); console.log(chalk.dim(`Pack location: ${pack.path}`)); return { success: true }; } /** * Update pack (placeholder) */ async updatePack(packName) { console.log(chalk.yellow('Update functionality coming soon!')); console.log(chalk.dim('Check for updates manually or submit PRs to improve packs')); return { success: true }; } /** * Uninstall pack */ async uninstallPack(packName) { const pack = this.installedPacks.get(packName); if (!pack) { console.log(chalk.red('Pack not found')); return { success: false }; } const { confirm } = await inquirer.prompt([{ type: 'confirm', name: 'confirm', message: `Are you sure you want to uninstall ${packName}?`, default: false }]); if (!confirm) { return { success: false, cancelled: true }; } try { console.log(chalk.blue(`Uninstalling ${packName}...`)); // Remove from disk await fs.remove(pack.path); // Remove from registries this.installedPacks.delete(packName); const packInfo = this.packRegistry.get(packName); if (packInfo) { packInfo.installed = false; } console.log(chalk.green(`āœ… Successfully uninstalled ${packName}`)); return { success: true }; } catch (error) { console.error(chalk.red(`Failed to uninstall: ${error.message}`)); return { success: false, error: error.message }; } } /** * Get pack by name */ getPack(packName) { return this.installedPacks.get(packName); } /** * List all installed packs */ listInstalledPacks() { return Array.from(this.installedPacks.keys()); } /** * Get pack agents */ getPackAgents(packName) { const pack = this.installedPacks.get(packName); return pack ? Array.from(pack.agents.keys()) : []; } /** * Get pack templates */ getPackTemplates(packName) { const pack = this.installedPacks.get(packName); return pack ? Array.from(pack.templates.keys()) : []; } } module.exports = ExpansionPackManager;