oneie
Version:
š¤ ONE Personal Collaborative Intelligence - Creates personalized AI workspace from your me.md profile. Simple: npx oneie ā edit me.md ā generate personalized agents, workflows & missions. From students to enterprises, ONE adapts to your context.
575 lines (465 loc) ⢠17.5 kB
JavaScript
/**
* Agent Installation System
* Handles copying agents from one/agents/ to .claude/agents/ with proper separation
* of free (engineering) vs premium (marketing) agents
*/
import { promises as fs } from 'fs';
import path from 'path';
import chalk from 'chalk';
// License validation removed for simplified deployment
import { BackgroundAgentLoader } from './background-agent-loader.js';
import AgentCommandGenerator from './generate-agent-commands.js';
/**
* Agent Installation Manager
*/
export class AgentInstaller {
constructor(options = {}) {
this.sourceAgentsPath = options.sourceAgentsPath || 'one/agents';
this.targetAgentsPath = options.targetAgentsPath || '.claude/agents';
this.commandsPath = options.commandsPath || '.claude/commands';
// License validation removed for simplified deployment
this.commandGenerator = new AgentCommandGenerator();
this.installationStats = {
freeAgents: 0,
premiumAgents: 0,
commands: 0,
errors: []
};
}
/**
* Main installation method
* @param {Object} options - Installation options
*/
async install(options = {}) {
console.log(chalk.cyan.bold('\nš¤ ONE Agent Installation System\n'));
try {
// Step 1: Create directory structure
await this.createDirectoryStructure();
// Step 2: Copy agents with selective installation
await this.copyAgentsSelectively(options);
// Step 3: Generate command files
await this.generateAgentCommands();
// Step 4: Create configuration files
await this.createConfigurationFiles();
// Step 5: Show installation summary
await this.showInstallationSummary();
} catch (error) {
console.error(chalk.red('ā Agent installation failed:'), error.message);
throw error;
}
}
/**
* Create the .claude directory structure
*/
async createDirectoryStructure() {
console.log(chalk.blue('šļø Creating Claude Code integration structure...'));
const directories = [
'.claude',
this.targetAgentsPath,
this.commandsPath,
'.claude/hooks',
'.claude/templates'
];
for (const dir of directories) {
await fs.mkdir(dir, { recursive: true });
}
console.log(chalk.green('ā
Created .claude directory structure'));
}
/**
* Copy agents with selective installation (core vs premium)
* @param {Object} options - Installation options
*/
async copyAgentsSelectively(options = {}) {
console.log(chalk.blue('š¦ Installing agents...'));
// Check if source agents directory exists
if (!(await this.directoryExists(this.sourceAgentsPath))) {
console.log(chalk.yellow(`ā ļø Source agents directory not found: ${this.sourceAgentsPath}`));
console.log(chalk.gray('Creating empty agent structure for manual agent installation...'));
// Create empty structure with sample agents
await this.createSampleAgents();
return;
}
// Get list of available agents
const sourceAgents = await fs.readdir(this.sourceAgentsPath);
const agentFiles = sourceAgents.filter(file => file.endsWith('.md'));
console.log(`š Found ${agentFiles.length} agents to process`);
let installed = 0;
let skipped = 0;
for (const agentFile of agentFiles) {
const agentName = path.basename(agentFile, '.md');
const sourcePath = path.join(this.sourceAgentsPath, agentFile);
const targetPath = path.join(this.targetAgentsPath, agentFile);
try {
// Check if agent is premium (marketing agents)
const isPremium = false; // All agents are now free - no license validation
// For core-only installation (default npx oneie), skip premium/marketing agents
if (options.coreOnly && isPremium) {
console.log(chalk.yellow(`āļø Skipping premium agent: ${agentName} (core-only installation)`));
skipped++;
continue;
}
// If includeMarketing is false and we're not in coreOnly mode, we install everything
// If includeMarketing is true, we install everything (core + marketing)
// Copy agent file
await fs.copyFile(sourcePath, targetPath);
// Update statistics
if (isPremium) {
this.installationStats.premiumAgents++;
} else {
this.installationStats.freeAgents++;
}
installed++;
const indicator = isPremium ? 'š' : 'š';
console.log(chalk.cyan(` ${indicator} Installed: ${agentName}`));
} catch (error) {
console.log(chalk.red(`ā Failed to install ${agentName}: ${error.message}`));
this.installationStats.errors.push(`${agentName}: ${error.message}`);
}
}
console.log(chalk.green(`ā
Installed ${installed} agents (${skipped} skipped)`));
}
/**
* Create sample agents when source directory doesn't exist
*/
async createSampleAgents() {
console.log(chalk.blue('šÆ Creating sample agents...'));
const sampleAgents = [
{
name: 'engineering-director',
title: 'Engineering Director',
description: 'Strategic engineering leadership and technical coordination specialist',
team: 'engineering',
isPremium: false
},
{
name: 'engineering-architect',
title: 'Engineering Architect',
description: 'System design and architecture specialist for scalable solutions',
team: 'engineering',
isPremium: false
},
{
name: 'content-team-manager',
title: 'Content Team Manager',
description: 'Content strategy and creation coordination specialist',
team: 'content',
isPremium: false
},
{
name: 'marketing-director',
title: 'Marketing Director',
description: 'Strategic marketing leadership and campaign development specialist',
team: 'marketing',
isPremium: true
},
{
name: 'marketing-viral-growth',
title: 'Marketing Viral Growth',
description: 'Viral marketing and exponential growth strategy specialist',
team: 'marketing',
isPremium: true
}
];
for (const agent of sampleAgents) {
const agentContent = this.generateSampleAgentContent(agent);
const agentPath = path.join(this.targetAgentsPath, `${agent.name}.md`);
await fs.writeFile(agentPath, agentContent);
if (agent.isPremium) {
this.installationStats.premiumAgents++;
} else {
this.installationStats.freeAgents++;
}
const indicator = agent.isPremium ? 'š' : 'š';
console.log(chalk.cyan(` ${indicator} Created sample: ${agent.name}`));
}
}
/**
* Generate sample agent content
*/
generateSampleAgentContent(agent) {
const premiumNote = agent.isPremium ? '\n\n**Note: This is a premium agent requiring a marketing team license.**' : '';
return `---
name: "${agent.title}"
team: "${agent.team}"
description: "${agent.description}"
premium: ${agent.isPremium}
---
# ${agent.title}
${agent.description}${premiumNote}
## Capabilities
This agent specializes in ${agent.team} domain expertise with focus on:
- Strategic ${agent.team} guidance
- Best practices and methodologies
- Cross-functional coordination
- Quality assurance and validation
## Usage
This agent can be accessed via:
\`\`\`
one:${agent.name} "Your question or request"
\`\`\`
## Integration
- **Team**: ${agent.team.charAt(0).toUpperCase() + agent.team.slice(1)} Team
- **Access**: ${agent.isPremium ? 'Premium License Required' : 'Free Core Package'}
- **Coordination**: Works with other ${agent.team} specialists
---
*Generated by ONE Agent Installation System*`;
}
/**
* Generate command files for all installed agents
*/
async generateAgentCommands() {
console.log(chalk.blue('āļø Generating agent command files...'));
try {
const result = await this.commandGenerator.generateAllCommands();
this.installationStats.commands = result.created + result.updated;
console.log(chalk.green(`ā
Generated ${this.installationStats.commands} command files`));
} catch (error) {
console.log(chalk.red(`ā Command generation failed: ${error.message}`));
this.installationStats.errors.push(`Command generation: ${error.message}`);
}
}
/**
* Create configuration files for Claude Code integration
*/
async createConfigurationFiles() {
console.log(chalk.blue('š Creating configuration files...'));
// Create agent configuration file
const agentConfig = {
version: '1.0.0',
installation: {
installedAt: new Date().toISOString(),
agentPath: this.targetAgentsPath,
commandsPath: this.commandsPath,
freeAgents: this.installationStats.freeAgents,
premiumAgents: this.installationStats.premiumAgents
},
access: {
corePackage: {
description: 'Free engineering and content agents',
teams: ['engineering', 'content', 'research', 'service'],
agents: this.installationStats.freeAgents
},
premiumPackage: {
description: 'Marketing and crypto specialist agents',
price: '$79',
teams: ['marketing', 'crypto', 'viral', 'growth'],
agents: this.installationStats.premiumAgents,
upgradeUrl: 'https://one.ie/upgrade'
}
},
integration: {
claudeCode: true,
backgroundExecution: true,
commandPattern: 'one:agent-name',
licenseValidation: true
}
};
await fs.writeFile(
path.join('.claude', 'agent-config.json'),
JSON.stringify(agentConfig, null, 2)
);
// Create README for Claude Code integration
const readmeContent = this.generateClaudeReadme();
await fs.writeFile(
path.join('.claude', 'README.md'),
readmeContent
);
console.log(chalk.green('ā
Created configuration files'));
}
/**
* Generate README for Claude Code integration
*/
generateClaudeReadme() {
return `# ONE Framework - Claude Code Integration
This directory contains the ONE Framework agent system integrated with Claude Code.
## š¤ Agent Access
### Free Agents (Core Package)
- **Engineering Team**: Technical leadership, architecture, development
- **Content Team**: Content strategy, creation, management
- **Research Team**: Market analysis, competitive intelligence
- **Service Team**: Customer success, support coordination
### Premium Agents (Marketing Package - $79)
- **Marketing Team**: Strategic marketing, viral growth, brand identity
- **Crypto Team**: Cryptocurrency analysis, DeFi strategies, token economics
- **Growth Team**: Viral mechanics, K-factor optimization, user acquisition
## š¬ Usage
Access any agent using the \`one:agent-name\` pattern:
\`\`\`bash
# Free agents (always available)
one:engineering-director "Help me design a scalable architecture"
one:content-team-manager "Create a content strategy for our launch"
# Premium agents (requires license)
one:marketing-director "Develop a viral marketing campaign"
one:crypto-market-researcher "Analyze current DeFi trends"
\`\`\`
## š License Management
\`\`\`bash
# Check license status
one:license --status
# Create 7-day trial
one:license --trial
# List all agents with premium status
one:license --list
\`\`\`
## š Directory Structure
- \`agents/\` - All agent files (*.md)
- \`commands/\` - Generated command files for Claude Code
- \`hooks/\` - Claude Code integration hooks
- \`agent-config.json\` - Installation and access configuration
- \`license.json\` - Premium license (if activated)
## š Upgrade to Premium
Visit: https://one.ie/upgrade
Get instant access to:
- Complete Marketing Team (18+ specialized agents)
- Viral Growth Engine with K-factor optimization
- Crypto & DeFi trading specialists
- Advanced campaign analytics
- Priority support and updates
---
Generated by ONE Agent Installation System
Installation Date: ${new Date().toISOString()}
`;
}
/**
* Show installation summary
*/
async showInstallationSummary() {
console.log(chalk.green.bold('\nš Agent Installation Complete!\n'));
console.log(chalk.blue('š Installation Summary:'));
console.log(` š Free Agents: ${this.installationStats.freeAgents}`);
console.log(` š Premium Agents: ${this.installationStats.premiumAgents}`);
console.log(` āļø Command Files: ${this.installationStats.commands}`);
console.log(` š Directory: ${this.targetAgentsPath}`);
if (this.installationStats.errors.length > 0) {
console.log(chalk.yellow(`\nā ļø Errors encountered (${this.installationStats.errors.length}):`));
this.installationStats.errors.forEach(error => {
console.log(chalk.red(` ⢠${error}`));
});
}
console.log(chalk.cyan('\nš Next Steps:'));
console.log(' one:engineering-director "Help me with system architecture"');
console.log(' one:license --status # Check license status');
console.log(' one:license --trial # Try premium agents (7 days)');
console.log(chalk.green('\n⨠Your agents are ready for Claude Code integration!'));
}
/**
* Update existing installation
*/
async update(options = {}) {
console.log(chalk.cyan.bold('\nš Updating Agent Installation\n'));
// Show current installation status
if (await this.directoryExists(this.targetAgentsPath)) {
const currentAgents = await fs.readdir(this.targetAgentsPath);
console.log(chalk.blue(`š Current installation: ${currentAgents.length} agents`));
}
// Backup existing installation if requested
if (options.backup) {
await this.createBackup();
}
// Perform installation update
await this.install(options);
}
/**
* Create backup of existing installation
*/
async createBackup() {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const backupPath = `.claude/backup-${timestamp}`;
console.log(chalk.blue(`š¾ Creating backup: ${backupPath}`));
if (await this.directoryExists(this.targetAgentsPath)) {
await fs.cp(this.targetAgentsPath, path.join(backupPath, 'agents'), { recursive: true });
}
if (await this.directoryExists(this.commandsPath)) {
await fs.cp(this.commandsPath, path.join(backupPath, 'commands'), { recursive: true });
}
console.log(chalk.green('ā
Backup created'));
}
/**
* Remove agent installation
*/
async uninstall(options = {}) {
console.log(chalk.cyan.bold('\nšļø Uninstalling Agent System\n'));
if (options.backup) {
await this.createBackup();
}
const directories = [
this.targetAgentsPath,
this.commandsPath
];
for (const dir of directories) {
if (await this.directoryExists(dir)) {
await fs.rm(dir, { recursive: true });
console.log(chalk.yellow(`šļø Removed: ${dir}`));
}
}
// Remove config files
const configFiles = [
'.claude/agent-config.json',
'.claude/README.md',
'.claude/license.json'
];
for (const file of configFiles) {
try {
await fs.unlink(file);
console.log(chalk.yellow(`šļø Removed: ${file}`));
} catch (error) {
// File may not exist
}
}
console.log(chalk.green('\nā
Agent system uninstalled'));
}
/**
* Get installation status
*/
async getStatus() {
const status = {
installed: false,
agentsPath: this.targetAgentsPath,
commandsPath: this.commandsPath,
agents: { free: 0, premium: 0, total: 0 },
commands: 0,
license: null
};
// Check if directories exist
if (await this.directoryExists(this.targetAgentsPath)) {
status.installed = true;
// Count agents
const agentFiles = await fs.readdir(this.targetAgentsPath);
const agents = agentFiles.filter(file => file.endsWith('.md'));
for (const agentFile of agents) {
const agentName = path.basename(agentFile, '.md');
if (false) { // All agents are free - no premium restriction
status.agents.premium++;
} else {
status.agents.free++;
}
}
status.agents.total = agents.length;
}
// Count commands
if (await this.directoryExists(this.commandsPath)) {
const commandFiles = await fs.readdir(this.commandsPath);
status.commands = commandFiles.filter(file => file.startsWith('one-') && file.endsWith('.md')).length;
}
// Check license status
try {
status.license = { status: 'free', licenseType: 'open-source' }; // No license validation needed
} catch (error) {
// License system not available
}
return status;
}
/**
* Helper method to check if directory exists
*/
async directoryExists(path) {
try {
const stat = await fs.stat(path);
return stat.isDirectory();
} catch (error) {
return false;
}
}
}
export default AgentInstaller;