@agentforge-ai/cli 0.7.0 → 0.7.1
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/dist/index.js +877 -73
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/create.ts","../src/commands/run.ts","../src/commands/deploy.ts","../src/lib/credentials.ts","../src/lib/cloud-client.ts","../src/lib/convex-client.ts","../src/lib/display.ts","../src/commands/agents.ts","../src/commands/chat.ts","../src/commands/sessions.ts","../src/commands/skills.ts","../src/commands/cron.ts","../src/commands/mcp.ts","../src/commands/files.ts","../src/commands/projects.ts","../src/commands/config.ts","../src/commands/vault.ts","../src/commands/keys.ts","../src/commands/status.ts","../src/commands/login.ts","../src/commands/channel-telegram.ts","../src/commands/channel-whatsapp.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createProject } from './commands/create.js';\nimport { runProject } from './commands/run.js';\nimport { deployProject } from './commands/deploy.js';\nimport { registerAgentsCommand } from './commands/agents.js';\nimport { registerChatCommand } from './commands/chat.js';\nimport { registerSessionsCommand, registerThreadsCommand } from './commands/sessions.js';\nimport { registerSkillsCommand } from './commands/skills.js';\nimport { registerCronCommand } from './commands/cron.js';\nimport { registerMcpCommand } from './commands/mcp.js';\nimport { registerFilesCommand } from './commands/files.js';\nimport { registerProjectsCommand } from './commands/projects.js';\nimport { registerConfigCommand } from './commands/config.js';\nimport { registerVaultCommand } from './commands/vault.js';\nimport { registerKeysCommand } from './commands/keys.js';\nimport { registerStatusCommand } from './commands/status.js';\nimport { registerLoginCommand } from './commands/login.js';\nimport { registerChannelTelegramCommand } from './commands/channel-telegram.js';\nimport { registerChannelWhatsAppCommand } from './commands/channel-whatsapp.js';\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, resolve } from 'node:path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('agentforge')\n .description('AgentForge — NanoClaw: A minimalist agent framework powered by Mastra + Convex')\n .version(pkg.version);\n\n// ─── Project Lifecycle ───────────────────────────────────────────\nprogram\n .command('create')\n .argument('<project-name>', 'Name of the project to create')\n .description('Create a new AgentForge project')\n .option('-t, --template <template>', 'Project template to use', 'default')\n .action(async (projectName: string, options: { template: string }) => {\n await createProject(projectName, options);\n });\n\nprogram\n .command('run')\n .description('Start the local development environment')\n .option('-p, --port <port>', 'Port for the dev server', '3000')\n .option('-s, --sandbox <type>', 'Sandbox provider for agent execution (local, docker, e2b, none)', 'local')\n .action(async (options: { port: string; sandbox: string }) => {\n await runProject(options as import('./commands/run.js').RunOptions);\n });\n\nprogram\n .command('deploy')\n .description('Deploy the project to production')\n .option('--env <path>', 'Path to environment file', '.env.production')\n .option('--dry-run', 'Preview deployment without executing', false)\n .option('--rollback', 'Rollback to previous deployment', false)\n .option('--force', 'Skip confirmation prompts', false)\n .option('--provider <provider>', 'Deployment provider (convex or cloud)', 'convex')\n .option('--project <projectId>', 'Project ID for cloud deployments')\n .option('--version <tag>', 'Version tag for the deployment')\n .action(async (options: { \n env: string; \n dryRun: boolean; \n rollback: boolean; \n force: boolean;\n provider: 'convex' | 'cloud';\n project?: string;\n version?: string;\n }) => {\n await deployProject(options);\n });\n\n// ─── Cloud Authentication ────────────────────────────────────────\nregisterLoginCommand(program);\n\n// ─── Agent Management ────────────────────────────────────────────\nregisterAgentsCommand(program);\n\n// ─── Chat ────────────────────────────────────────────────────────\nregisterChatCommand(program);\n\n// ─── Sessions & Threads ──────────────────────────────────────────\nregisterSessionsCommand(program);\nregisterThreadsCommand(program);\n\n// ─── Skills ──────────────────────────────────────────────────────\nregisterSkillsCommand(program);\n\n// ─── Cron Jobs ───────────────────────────────────────────────────\nregisterCronCommand(program);\n\n// ─── MCP Connections ─────────────────────────────────────────────\nregisterMcpCommand(program);\n\n// ─── Files & Folders ─────────────────────────────────────────────\nregisterFilesCommand(program);\n\n// ─── Projects / Workspaces ───────────────────────────────────────\nregisterProjectsCommand(program);\n\n// ─── Configuration ───────────────────────────────────────────────\nregisterConfigCommand(program);\n\n// ─── Vault (Secrets) ─────────────────────────────────────────────\nregisterVaultCommand(program);\n\n// ─── AI Provider Keys ────────────────────────────────────────────\nregisterKeysCommand(program);\n\n// ─── Channels ───────────────────────────────────────────────────\nregisterChannelTelegramCommand(program);\nregisterChannelWhatsAppCommand(program);\n\n// ─── Status, Dashboard, Logs, Heartbeat ──────────────────────────\nregisterStatusCommand(program);\n\nprogram.parse();\n","import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport fs from 'fs-extra';\nimport { execSync } from 'node:child_process';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Options for the create command.\n */\nexport interface CreateOptions {\n /** The project template to use. */\n template: string;\n}\n\n/**\n * Creates a new AgentForge project from a template.\n *\n * @param projectName - The name of the project to create.\n * @param options - Options for the create command.\n */\nexport async function createProject(\n projectName: string,\n options: CreateOptions\n): Promise<void> {\n const targetDir = path.resolve(process.cwd(), projectName);\n\n // Check if directory already exists\n if (await fs.pathExists(targetDir)) {\n console.error(`Error: Directory \"${projectName}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n🔨 Creating AgentForge project: ${projectName}\\n`);\n\n // Resolve template directory\n // tsup publicDir copies templates/ contents into dist/, so dist/default/ exists\n // When running from dist/index.js, __dirname is dist/, so we check:\n // 1. dist/<template> (built bundle — tsup publicDir)\n // 2. ../templates/<template> (development — running from src/)\n // 3. ../../templates/<template> (fallback)\n const searchDirs = [\n path.resolve(__dirname, options.template), // dist/default (built)\n path.resolve(__dirname, '..', 'templates', options.template), // packages/cli/templates/default (dev)\n path.resolve(__dirname, '..', '..', 'templates', options.template), // fallback\n ];\n\n let templateDir = '';\n for (const dir of searchDirs) {\n if (await fs.pathExists(dir)) {\n templateDir = dir;\n break;\n }\n }\n\n if (!templateDir) {\n console.error(`Error: Template \"${options.template}\" not found.`);\n console.error(`Searched in:`);\n searchDirs.forEach(d => console.error(` - ${d}`));\n process.exit(1);\n }\n\n // Copy template to target directory\n await fs.copy(templateDir, targetDir);\n\n // Update package.json with project name\n const pkgPath = path.join(targetDir, 'package.json');\n if (await fs.pathExists(pkgPath)) {\n const pkg = await fs.readJson(pkgPath);\n pkg.name = projectName;\n await fs.writeJson(pkgPath, pkg, { spaces: 2 });\n }\n\n // Update dashboard package.json name\n const dashPkgPath = path.join(targetDir, 'dashboard', 'package.json');\n if (await fs.pathExists(dashPkgPath)) {\n const dashPkg = await fs.readJson(dashPkgPath);\n dashPkg.name = `${projectName}-dashboard`;\n await fs.writeJson(dashPkgPath, dashPkg, { spaces: 2 });\n }\n\n console.log(` ✅ Project scaffolded at ./${projectName}`);\n\n // Install root dependencies\n console.log(`\\n📦 Installing dependencies...\\n`);\n try {\n execSync('pnpm install', {\n cwd: targetDir,\n stdio: 'inherit',\n });\n console.log(`\\n ✅ Dependencies installed`);\n } catch {\n console.warn(\n `\\n ⚠️ Could not install dependencies. Run \"cd ${projectName} && pnpm install\" manually.`\n );\n }\n\n // Install dashboard dependencies\n const dashDir = path.join(targetDir, 'dashboard');\n if (await fs.pathExists(dashDir)) {\n console.log(`\\n📦 Installing dashboard dependencies...\\n`);\n try {\n execSync('pnpm install', {\n cwd: dashDir,\n stdio: 'inherit',\n });\n console.log(`\\n ✅ Dashboard dependencies installed`);\n } catch {\n console.warn(\n `\\n ⚠️ Could not install dashboard dependencies. Run \"cd ${projectName}/dashboard && pnpm install\" manually.`\n );\n }\n }\n\n // Initialize Convex\n console.log(`\\n⚡ Initializing Convex...\\n`);\n try {\n execSync('npx convex dev --once', {\n cwd: targetDir,\n stdio: 'inherit',\n });\n console.log(`\\n ✅ Convex initialized`);\n } catch {\n console.warn(\n `\\n ⚠️ Convex initialization skipped. Run \"npx convex dev\" to set up your backend.`\n );\n }\n\n console.log(`\n🎉 AgentForge project \"${projectName}\" created successfully!\n\nNext steps:\n cd ${projectName}\n\n # Start the Convex backend\n npx convex dev\n\n # In another terminal, launch the dashboard\n agentforge dashboard\n\n # Or chat with your agent from the CLI\n agentforge chat\n\n # Install skills to extend agent capabilities\n agentforge skills list --registry\n agentforge skills install web-search\n\n # Check system status\n agentforge status\n\nDocumentation: https://github.com/Agentic-Engineering-Agency/agentforge\n`);\n}\n","import { spawn } from 'node:child_process';\nimport path from 'node:path';\nimport fs from 'fs-extra';\n\n/**\n * Supported sandbox providers for agent tool execution.\n */\nexport type SandboxType = 'local' | 'docker' | 'e2b' | 'none';\n\n/**\n * Options for the run command.\n */\nexport interface RunOptions {\n /** The port for the dev server. */\n port: string;\n /** The sandbox provider to use for agent tool execution. */\n sandbox: SandboxType;\n}\n\n/**\n * Starts the local development environment for an AgentForge project.\n *\n * This command starts the Convex development server and watches for file changes.\n * When `--sandbox docker` is specified, agent tool execution will use Docker\n * containers for isolation instead of the default local sandbox.\n *\n * @param options - Options for the run command.\n */\nexport async function runProject(options: RunOptions): Promise<void> {\n const projectDir = process.cwd();\n\n // Verify we're in an AgentForge project\n const pkgPath = path.join(projectDir, 'package.json');\n if (!(await fs.pathExists(pkgPath))) {\n console.error(\n 'Error: No package.json found. Are you in an AgentForge project directory?'\n );\n process.exit(1);\n }\n\n const convexDir = path.join(projectDir, 'convex');\n if (!(await fs.pathExists(convexDir))) {\n console.error(\n 'Error: No convex/ directory found. Are you in an AgentForge project directory?'\n );\n process.exit(1);\n }\n\n console.log(`\\n🚀 Starting AgentForge development server...\\n`);\n console.log(` Convex dev server starting on port ${options.port}...`);\n\n // Log sandbox configuration\n if (options.sandbox === 'docker') {\n console.log(` 🐳 Docker sandbox enabled — agent tools will execute in isolated containers`);\n console.log(` Image: ${process.env['DOCKER_IMAGE'] ?? 'node:22-slim (default)'}`);\n console.log(` Host: ${process.env['DOCKER_HOST'] ?? '/var/run/docker.sock (default)'}`);\n } else if (options.sandbox === 'e2b') {\n console.log(` ☁️ E2B sandbox enabled — agent tools will execute in cloud sandboxes`);\n } else if (options.sandbox === 'none') {\n console.log(` ⚠️ No sandbox — agent tools will execute directly on the host (unsafe)`);\n } else {\n console.log(` 📦 Local sandbox enabled (default)`);\n }\n\n // Set sandbox environment variable for downstream consumers\n const sandboxEnv = {\n ...process.env,\n AGENTFORGE_SANDBOX_PROVIDER: options.sandbox,\n };\n\n // Start the Convex dev server\n const convexProcess = spawn('npx', ['convex', 'dev'], {\n cwd: projectDir,\n stdio: 'inherit',\n shell: true,\n env: sandboxEnv,\n });\n\n convexProcess.on('error', (err) => {\n console.error(`Failed to start Convex dev server: ${err.message}`);\n process.exit(1);\n });\n\n convexProcess.on('close', (code) => {\n if (code !== 0) {\n console.error(`Convex dev server exited with code ${code}`);\n }\n });\n\n // Handle graceful shutdown\n const shutdown = () => {\n console.log('\\n\\n👋 Shutting down AgentForge dev server...');\n convexProcess.kill('SIGTERM');\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n","import path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport prompts from 'prompts';\nimport { CloudClient, CloudClientError, type AgentConfig } from '../lib/cloud-client.js';\nimport { readCredentials, getCloudUrl } from '../lib/credentials.js';\n\n/**\n * Options for the deploy command.\n */\nexport interface DeployOptions {\n /** Path to the environment file. */\n env: string;\n /** Preview deployment without executing. */\n dryRun: boolean;\n /** Rollback to previous deployment. */\n rollback: boolean;\n /** Skip confirmation prompts. */\n force: boolean;\n /** Deployment provider: convex (default) or cloud. */\n provider: 'convex' | 'cloud';\n /** Project ID for cloud deployments. */\n project?: string;\n /** Version tag for the deployment. */\n version?: string;\n}\n\n/**\n * Configuration file format for agentforge.config.ts or agentforge.json\n */\nexport interface AgentForgeConfig {\n projectId?: string;\n agents?: AgentConfig[];\n cloudUrl?: string;\n}\n\n/**\n * Parses a .env file and returns key-value pairs.\n *\n * @param filePath - Absolute path to the .env file.\n * @returns A record of environment variable key-value pairs.\n */\nexport function parseEnvFile(filePath: string): Record<string, string> {\n const content = fs.readFileSync(filePath, 'utf-8');\n const vars: Record<string, string> = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n // Remove surrounding quotes\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n if (key) {\n vars[key] = value;\n }\n }\n\n return vars;\n}\n\n/**\n * Read agentforge configuration from agentforge.config.ts or agentforge.json\n */\nexport async function readAgentForgeConfig(projectDir: string): Promise<AgentForgeConfig | null> {\n // Try agentforge.config.ts first\n const tsConfigPath = path.join(projectDir, 'agentforge.config.ts');\n if (await fs.pathExists(tsConfigPath)) {\n try {\n // For now, we'll read it as a simple module that exports default\n // In production, this might need a dynamic import or esbuild\n const content = await fs.readFile(tsConfigPath, 'utf-8');\n return parseConfigFromContent(content, projectDir);\n } catch {\n // Fall through to JSON\n }\n }\n\n // Try agentforge.json\n const jsonConfigPath = path.join(projectDir, 'agentforge.json');\n if (await fs.pathExists(jsonConfigPath)) {\n try {\n const content = await fs.readFile(jsonConfigPath, 'utf-8');\n return JSON.parse(content) as AgentForgeConfig;\n } catch {\n return null;\n }\n }\n\n return null;\n}\n\n/**\n * Parse config from TypeScript file content\n * This is a simplified parser - in production you might use ts-node or esbuild\n */\nfunction parseConfigFromContent(content: string, projectDir: string): AgentForgeConfig | null {\n const config: AgentForgeConfig = {};\n\n // Extract projectId\n const projectIdMatch = content.match(/projectId\\s*:\\s*[\"']([^\"']+)[\"']/);\n if (projectIdMatch) {\n config.projectId = projectIdMatch[1];\n }\n\n // Try to read agents from the convex/agents.ts file if present\n const agentsPath = path.join(projectDir, 'convex', 'agents.ts');\n if (fs.existsSync(agentsPath)) {\n try {\n const agentsContent = fs.readFileSync(agentsPath, 'utf-8');\n config.agents = parseAgentsFromConvex(agentsContent);\n } catch {\n // Ignore\n }\n }\n\n // Extract cloudUrl\n const cloudUrlMatch = content.match(/cloudUrl\\s*:\\s*[\"']([^\"']+)[\"']/);\n if (cloudUrlMatch) {\n config.cloudUrl = cloudUrlMatch[1];\n }\n\n return Object.keys(config).length > 0 ? config : null;\n}\n\n/**\n * Parse agent definitions from convex/agents.ts\n * This is a simplified parser for common patterns\n */\nfunction parseAgentsFromConvex(content: string): AgentConfig[] {\n const agents: AgentConfig[] = [];\n\n // Look for agent objects in the content\n // Pattern: { id: \"...\", name: \"...\", instructions: \"...\", model: \"...\" }\n const agentPattern = /\\{\\s*id:\\s*[\"']([^\"']+)[\"']\\s*,\\s*name:\\s*[\"']([^\"']+)[\"']([\\s\\S]*?)\\}/g;\n \n let match;\n while ((match = agentPattern.exec(content)) !== null) {\n const id = match[1];\n const name = match[2];\n const rest = match[3];\n\n const agent: AgentConfig = { id, name, instructions: '', model: 'gpt-4o-mini' };\n\n const instructionsMatch = rest.match(/instructions:\\s*[\"']([^\"']+)[\"']/);\n if (instructionsMatch) agent.instructions = instructionsMatch[1];\n\n const modelMatch = rest.match(/model:\\s*[\"']([^\"']+)[\"']/);\n if (modelMatch) agent.model = modelMatch[1];\n\n const providerMatch = rest.match(/provider:\\s*[\"']([^\"']+)[\"']/);\n if (providerMatch) agent.provider = providerMatch[1];\n\n const descriptionMatch = rest.match(/description:\\s*[\"']([^\"']+)[\"']/);\n if (descriptionMatch) agent.description = descriptionMatch[1];\n\n agents.push(agent);\n }\n\n return agents;\n}\n\n/**\n * Deploy to AgentForge Cloud\n */\nasync function deployToCloud(\n options: DeployOptions,\n projectDir: string\n): Promise<void> {\n console.log('\\n☁️ Deploying to AgentForge Cloud...\\n');\n\n // 1. Read credentials\n const credentials = await readCredentials();\n if (!credentials?.apiKey) {\n console.error(chalk.red('✖'), 'Not authenticated with AgentForge Cloud.');\n console.error(' Run \"agentforge login\" to authenticate.\\n');\n process.exit(1);\n }\n\n // 2. Read local configuration\n const spinner = ora('Reading agent configuration...').start();\n const config = await readAgentForgeConfig(projectDir);\n\n // 3. Resolve project ID\n let projectId = options.project || config?.projectId;\n \n if (!projectId) {\n spinner.stop();\n console.error(chalk.red('✖'), 'No project ID specified.');\n console.error(' Use --project flag or set projectId in agentforge.config.ts\\n');\n process.exit(1);\n }\n\n // 4. Extract agents from config\n let agents = config?.agents || [];\n \n if (agents.length === 0) {\n spinner.stop();\n console.error(chalk.red('✖'), 'No agents found in configuration.');\n console.error(' Define agents in agentforge.config.ts or convex/agents.ts\\n');\n process.exit(1);\n }\n\n spinner.succeed(`Found ${agents.length} agent(s) to deploy`);\n\n // 5. Handle dry-run mode\n if (options.dryRun) {\n console.log('\\n' + chalk.blue('ℹ'), 'Dry run - no changes will be made\\n');\n console.log(' Project ID:', chalk.cyan(projectId));\n console.log(' Cloud URL:', chalk.cyan(credentials.cloudUrl || 'https://cloud.agentforge.ai'));\n console.log(' Agents:');\n for (const agent of agents) {\n console.log(` • ${chalk.bold(agent.name)} (${agent.model})`);\n }\n console.log();\n return;\n }\n\n // 6. Create Cloud client\n const cloudSpinner = ora('Connecting to AgentForge Cloud...').start();\n const client = new CloudClient(\n credentials.cloudUrl || process.env.AGENTFORGE_CLOUD_URL,\n credentials.apiKey\n );\n\n // Verify authentication\n try {\n await client.authenticate();\n cloudSpinner.succeed('Connected to AgentForge Cloud');\n } catch (err: any) {\n cloudSpinner.fail('Failed to connect to AgentForge Cloud');\n if (err instanceof CloudClientError) {\n console.error(chalk.red('✖'), err.message);\n } else {\n console.error(chalk.red('✖'), err.message || err);\n }\n process.exit(1);\n }\n\n // 7. Verify project exists\n const projectSpinner = ora('Verifying project...').start();\n try {\n await client.getProject(projectId);\n projectSpinner.succeed(`Project verified: ${chalk.cyan(projectId)}`);\n } catch (err: any) {\n projectSpinner.fail('Project verification failed');\n if (err.status === 404) {\n console.error(chalk.red('✖'), `Project \"${projectId}\" not found.`);\n console.error(' Check the project ID or create the project in the dashboard.\\n');\n } else {\n console.error(chalk.red('✖'), err.message || err);\n }\n process.exit(1);\n }\n\n // 8. Create deployment\n const version = options.version || `v${Date.now()}`;\n const deploySpinner = ora('Creating deployment...').start();\n\n let deploymentId: string;\n try {\n const response = await client.createDeployment({\n projectId,\n agents,\n version,\n });\n deploymentId = response.deploymentId;\n deploySpinner.succeed(`Deployment created: ${chalk.cyan(deploymentId)}`);\n } catch (err: any) {\n deploySpinner.fail('Failed to create deployment');\n if (err instanceof CloudClientError) {\n console.error(chalk.red('✖'), err.message);\n } else {\n console.error(chalk.red('✖'), err.message || err);\n }\n process.exit(1);\n }\n\n // 9. Poll deployment status\n console.log('\\n📦 Deploying agents...\\n');\n const pollSpinner = ora('Waiting for deployment to complete...').start();\n\n const maxAttempts = 60; // 3 minutes max (3s * 60)\n let attempts = 0;\n\n while (attempts < maxAttempts) {\n let status;\n try {\n status = await client.getDeploymentStatus(deploymentId);\n attempts++;\n } catch (err: any) {\n // Continue polling on network errors, but track failures\n attempts++;\n if (attempts >= maxAttempts) {\n pollSpinner.fail('Deployment status check timed out');\n console.error();\n console.error(chalk.yellow('⚠'), 'The deployment may still be in progress.');\n console.error(` Check status at: https://cloud.agentforge.ai/projects/${projectId}/deployments/${deploymentId}`);\n console.error();\n process.exit(1);\n }\n await new Promise((resolve) => setTimeout(resolve, 3000));\n continue;\n }\n\n if (status.status === 'completed') {\n pollSpinner.succeed('Deployment completed successfully!');\n console.log();\n console.log(chalk.green('✔'), `Deployed to ${chalk.bold(`https://cloud.agentforge.ai/projects/${projectId}`)}`);\n if (status.url) {\n console.log(chalk.green('✔'), `Deployment URL: ${chalk.cyan(status.url)}`);\n }\n console.log();\n return;\n } else if (status.status === 'failed') {\n pollSpinner.fail('Deployment failed');\n console.error();\n console.error(chalk.red('✖'), 'Error:', status.errorMessage || 'Unknown error');\n console.error();\n process.exit(1);\n } else if (status.progress !== undefined) {\n pollSpinner.text = `Deploying... ${status.progress}%`;\n } else {\n const statuses: Record<string, string> = {\n pending: 'Waiting to start...',\n building: 'Building...',\n deploying: 'Deploying...',\n };\n pollSpinner.text = statuses[status.status] || `Status: ${status.status}`;\n }\n\n // Wait 3 seconds before polling again\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n\n pollSpinner.fail('Deployment timed out');\n process.exit(1);\n}\n\n/**\n * Deploy to Convex (original behavior)\n */\nasync function deployToConvex(options: DeployOptions): Promise<void> {\n const projectDir = process.cwd();\n\n // Validate project structure\n const pkgPath = path.join(projectDir, 'package.json');\n if (!(await fs.pathExists(pkgPath))) {\n console.error(\n 'Error: No package.json found. Are you in an AgentForge project directory?'\n );\n process.exit(1);\n }\n\n const convexDir = path.join(projectDir, 'convex');\n if (!(await fs.pathExists(convexDir))) {\n console.error(\n 'Error: No convex/ directory found. Are you in an AgentForge project directory?'\n );\n process.exit(1);\n }\n\n // Handle rollback mode\n if (options.rollback) {\n console.log('\\n🔄 Rolling back to previous Convex deployment...\\n');\n try {\n execSync('npx convex deploy --rollback', {\n cwd: projectDir,\n stdio: 'inherit',\n });\n console.log('\\n ✅ Rollback completed successfully.');\n } catch {\n console.error('\\n ❌ Rollback failed.');\n process.exit(1);\n }\n return;\n }\n\n // Resolve and validate env file\n const envPath = path.resolve(projectDir, options.env);\n const envExists = await fs.pathExists(envPath);\n\n // Parse env vars if file exists\n let envVars: Record<string, string> = {};\n if (envExists) {\n envVars = parseEnvFile(envPath);\n }\n\n // Handle dry-run mode\n if (options.dryRun) {\n console.log('\\n🔍 Dry run — previewing deployment plan:\\n');\n console.log(` Project directory: ${projectDir}`);\n console.log(` Convex directory: ${convexDir}`);\n console.log(` Environment file: ${envExists ? envPath : '(not found, skipping env vars)'}`);\n\n if (Object.keys(envVars).length > 0) {\n console.log(`\\n Environment variables to set (${Object.keys(envVars).length}):`);\n for (const key of Object.keys(envVars)) {\n console.log(` • ${key}=${envVars[key].slice(0, 4)}${'*'.repeat(Math.max(0, envVars[key].length - 4))}`);\n }\n } else {\n console.log('\\n No environment variables to set.');\n }\n\n console.log('\\n ℹ️ No changes were made (dry run).\\n');\n return;\n }\n\n // Require env file for actual deployment\n if (!envExists) {\n console.error(\n `Error: Environment file \"${options.env}\" not found. Create it or use --env to specify a different path.`\n );\n process.exit(1);\n }\n\n // Confirmation prompt (unless --force)\n if (!options.force) {\n console.log('\\n🚀 Deployment plan:\\n');\n console.log(` Project: ${projectDir}`);\n console.log(` Env file: ${envPath}`);\n console.log(` Env vars: ${Object.keys(envVars).length} variable(s)`);\n console.log('\\n Use --force to skip this confirmation.\\n');\n\n // In a real CLI, we'd use prompts here. For now, auto-proceed.\n // The --force flag is the recommended path for CI/CD.\n }\n\n console.log('\\n📦 Deploying AgentForge project to production...\\n');\n\n // Step 1: Push environment variables\n if (Object.keys(envVars).length > 0) {\n console.log(' Setting environment variables...');\n for (const [key, value] of Object.entries(envVars)) {\n try {\n execSync(`npx convex env set ${key} \"${value}\"`, {\n cwd: projectDir,\n stdio: 'pipe',\n });\n console.log(` ✅ ${key}`);\n } catch {\n console.error(` ❌ Failed to set ${key}`);\n }\n }\n console.log('');\n }\n\n // Step 2: Deploy\n console.log(' Deploying Convex backend...');\n try {\n execSync('npx convex deploy', {\n cwd: projectDir,\n stdio: 'inherit',\n });\n console.log('\\n ✅ Deployment completed successfully!');\n console.log(' Use \"agentforge deploy --rollback\" to revert if needed.\\n');\n } catch {\n console.error('\\n ❌ Deployment failed.');\n console.error(' Check the Convex dashboard for details.');\n process.exit(1);\n }\n}\n\n/**\n * Deploys an AgentForge project to production.\n *\n * Handles environment variable configuration, provides deployment status\n * feedback, and supports rollback capabilities.\n *\n * @param options - Options for the deploy command.\n */\nexport async function deployProject(options: DeployOptions): Promise<void> {\n const projectDir = process.cwd();\n\n // Route to appropriate provider\n if (options.provider === 'cloud') {\n await deployToCloud(options, projectDir);\n } else {\n await deployToConvex(options);\n }\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\nimport os from 'node:os';\n\n/**\n * AgentForge Cloud credentials storage\n * Stored in ~/.agentforge/credentials.json\n */\n\nexport interface Credentials {\n /** API key for AgentForge Cloud */\n apiKey: string;\n /** Cloud URL (defaults to https://cloud.agentforge.ai) */\n cloudUrl: string;\n /** User email or identifier */\n userEmail?: string;\n /** User display name */\n userName?: string;\n /** Token expiration timestamp */\n expiresAt?: number;\n /** Last refreshed timestamp */\n refreshedAt?: number;\n}\n\nconst CREDENTIALS_DIR = path.join(os.homedir(), '.agentforge');\nconst CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, 'credentials.json');\nconst DEFAULT_CLOUD_URL = 'https://cloud.agentforge.ai';\n\n/**\n * Ensure the credentials directory exists\n */\nasync function ensureCredentialsDir(): Promise<void> {\n await fs.ensureDir(CREDENTIALS_DIR);\n // Set restrictive permissions (owner read/write only)\n try {\n await fs.chmod(CREDENTIALS_DIR, 0o700);\n } catch {\n // Ignore permission errors on Windows\n }\n}\n\n/**\n * Read credentials from the secure storage\n */\nexport async function readCredentials(): Promise<Credentials | null> {\n try {\n if (!(await fs.pathExists(CREDENTIALS_FILE))) {\n return null;\n }\n const content = await fs.readFile(CREDENTIALS_FILE, 'utf-8');\n const creds = JSON.parse(content) as Credentials;\n // Ensure cloudUrl has a default\n if (!creds.cloudUrl) {\n creds.cloudUrl = DEFAULT_CLOUD_URL;\n }\n return creds;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Write credentials to secure storage\n */\nexport async function writeCredentials(credentials: Credentials): Promise<void> {\n await ensureCredentialsDir();\n const data: Credentials = {\n ...credentials,\n cloudUrl: credentials.cloudUrl || DEFAULT_CLOUD_URL,\n refreshedAt: Date.now(),\n };\n await fs.writeFile(CREDENTIALS_FILE, JSON.stringify(data, null, 2), 'utf-8');\n // Set restrictive permissions (owner read/write only)\n try {\n await fs.chmod(CREDENTIALS_FILE, 0o600);\n } catch {\n // Ignore permission errors on Windows\n }\n}\n\n/**\n * Delete credentials (logout)\n */\nexport async function deleteCredentials(): Promise<boolean> {\n try {\n if (await fs.pathExists(CREDENTIALS_FILE)) {\n await fs.remove(CREDENTIALS_FILE);\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if user is authenticated\n */\nexport async function isAuthenticated(): Promise<boolean> {\n const creds = await readCredentials();\n return creds !== null && creds.apiKey !== undefined;\n}\n\n/**\n * Get the cloud URL (from credentials or default)\n */\nexport async function getCloudUrl(): Promise<string> {\n const creds = await readCredentials();\n return creds?.cloudUrl || process.env.AGENTFORGE_CLOUD_URL || DEFAULT_CLOUD_URL;\n}\n\n/**\n * Get API key (returns null if not authenticated)\n */\nexport async function getApiKey(): Promise<string | null> {\n const creds = await readCredentials();\n return creds?.apiKey || null;\n}\n\n/**\n * Get the credentials file path\n */\nexport function getCredentialsPath(): string {\n return CREDENTIALS_FILE;\n}\n\n/**\n * Check if credentials are expired\n */\nexport function isExpired(credentials: Credentials): boolean {\n if (!credentials.expiresAt) return false;\n return Date.now() >= credentials.expiresAt;\n}\n\n/**\n * Update credentials with new data\n */\nexport async function updateCredentials(updates: Partial<Credentials>): Promise<Credentials | null> {\n const current = await readCredentials();\n if (!current) return null;\n const updated = { ...current, ...updates, refreshedAt: Date.now() };\n await writeCredentials(updated);\n return updated;\n}\n","import type { Credentials } from './credentials.js';\nimport { getCloudUrl, getApiKey, readCredentials } from './credentials.js';\n\n/**\n * AgentForge Cloud API Client\n * \n * Handles all HTTP communication with the AgentForge Cloud API.\n * Supports both REST API endpoints and Convex HTTP actions.\n */\n\nexport interface Project {\n id: string;\n name: string;\n description?: string;\n createdAt: number;\n updatedAt: number;\n}\n\nexport interface AgentConfig {\n id?: string;\n name: string;\n description?: string;\n instructions: string;\n model: string;\n provider?: string;\n tools?: any;\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n config?: Record<string, any>;\n}\n\nexport interface Deployment {\n id: string;\n projectId: string;\n status: 'pending' | 'building' | 'deploying' | 'completed' | 'failed' | 'rolled_back';\n version: string;\n agents: AgentConfig[];\n url?: string;\n createdAt: number;\n updatedAt: number;\n errorMessage?: string;\n}\n\nexport interface CreateDeploymentRequest {\n projectId: string;\n agents: AgentConfig[];\n version: string;\n}\n\nexport interface CreateDeploymentResponse {\n deploymentId: string;\n status: string;\n url?: string;\n}\n\nexport interface DeploymentStatusResponse {\n id: string;\n status: string;\n url?: string;\n errorMessage?: string;\n progress?: number;\n}\n\nexport interface UserInfo {\n id: string;\n email: string;\n name?: string;\n}\n\nexport interface CloudApiError {\n message: string;\n code?: string;\n status?: number;\n}\n\n/**\n * Cloud API Error class for typed error handling\n */\nexport class CloudClientError extends Error {\n constructor(\n message: string,\n public code?: string,\n public status?: number\n ) {\n super(message);\n this.name = 'CloudClientError';\n }\n}\n\n/**\n * AgentForge Cloud API Client\n */\nexport class CloudClient {\n private baseUrl: string;\n private apiKey: string | null = null;\n\n constructor(baseUrl?: string, apiKey?: string) {\n this.baseUrl = baseUrl || 'https://cloud.agentforge.ai';\n this.apiKey = apiKey || null;\n }\n\n /**\n * Initialize the client with stored credentials\n */\n async initialize(): Promise<void> {\n this.baseUrl = await getCloudUrl();\n this.apiKey = await getApiKey();\n }\n\n /**\n * Set the API key directly\n */\n setApiKey(apiKey: string): void {\n this.apiKey = apiKey;\n }\n\n /**\n * Set the base URL directly\n */\n setBaseUrl(baseUrl: string): void {\n this.baseUrl = baseUrl;\n }\n\n /**\n * Get the full API URL for an endpoint\n */\n private getUrl(endpoint: string): string {\n const base = this.baseUrl.replace(/\\/$/, '');\n const path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;\n return `${base}${path}`;\n }\n\n /**\n * Get request headers with authentication\n */\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'X-Client-Version': '0.5.1',\n };\n\n if (this.apiKey) {\n headers['Authorization'] = `Bearer ${this.apiKey}`;\n }\n\n return headers;\n }\n\n /**\n * Make an HTTP request to the Cloud API\n */\n private async request<T>(\n method: string,\n endpoint: string,\n body?: unknown\n ): Promise<T> {\n const url = this.getUrl(endpoint);\n const options: RequestInit = {\n method,\n headers: this.getHeaders(),\n };\n\n if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {\n options.body = JSON.stringify(body);\n }\n\n let response: Response;\n try {\n response = await fetch(url, options);\n } catch (error: any) {\n throw new CloudClientError(\n `Network error: ${error.message || 'Failed to connect to AgentForge Cloud'}`,\n 'NETWORK_ERROR'\n );\n }\n\n // Handle non-JSON responses\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n if (!response.ok) {\n const errorBody: CloudApiError | null = isJson ? (await response.json()) as CloudApiError : null;\n const message = errorBody?.message || `HTTP ${response.status}: ${response.statusText}`;\n throw new CloudClientError(\n message,\n errorBody?.code || `HTTP_${response.status}`,\n response.status\n );\n }\n\n if (response.status === 204) {\n return {} as T;\n }\n\n if (!isJson) {\n const text = await response.text();\n return { text } as T;\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Check if credentials are valid\n */\n async authenticate(): Promise<UserInfo> {\n if (!this.apiKey) {\n throw new CloudClientError(\n 'No API key configured. Run \"agentforge login\" to authenticate.',\n 'NO_CREDENTIALS',\n 401\n );\n }\n\n try {\n const user = await this.request<UserInfo>('GET', '/api/auth/me');\n return user;\n } catch (error: any) {\n if (error.status === 401) {\n throw new CloudClientError(\n 'Invalid API key. Run \"agentforge login\" to re-authenticate.',\n 'UNAUTHORIZED',\n 401\n );\n }\n throw error;\n }\n }\n\n /**\n * List all projects for the authenticated user\n */\n async listProjects(): Promise<Project[]> {\n return this.request<Project[]>('GET', '/api/projects');\n }\n\n /**\n * Get a specific project by ID\n */\n async getProject(projectId: string): Promise<Project> {\n return this.request<Project>('GET', `/api/projects/${projectId}`);\n }\n\n /**\n * Upload agent configuration to Cloud\n */\n async uploadAgentConfig(\n projectId: string,\n agentConfig: AgentConfig\n ): Promise<{ agentId: string }> {\n return this.request<{ agentId: string }>(\n 'POST',\n `/api/projects/${projectId}/agents`,\n agentConfig\n );\n }\n\n /**\n * Create a new deployment\n */\n async createDeployment(\n request: CreateDeploymentRequest\n ): Promise<CreateDeploymentResponse> {\n return this.request<CreateDeploymentResponse>(\n 'POST',\n '/api/deployments/create',\n request\n );\n }\n\n /**\n * Get deployment status\n */\n async getDeploymentStatus(\n deploymentId: string\n ): Promise<DeploymentStatusResponse> {\n return this.request<DeploymentStatusResponse>(\n 'GET',\n `/api/deployments/${deploymentId}/status`\n );\n }\n\n /**\n * Get deployment details\n */\n async getDeployment(deploymentId: string): Promise<Deployment> {\n return this.request<Deployment>('GET', `/api/deployments/${deploymentId}`);\n }\n\n /**\n * Rollback a deployment\n */\n async rollbackDeployment(deploymentId: string): Promise<{ success: boolean }> {\n return this.request<{ success: boolean }>(\n 'POST',\n `/api/deployments/${deploymentId}/rollback`\n );\n }\n\n /**\n * List deployments for a project\n */\n async listDeployments(projectId: string): Promise<Deployment[]> {\n return this.request<Deployment[]>('GET', `/api/projects/${projectId}/deployments`);\n }\n}\n\n/**\n * Create a CloudClient with credentials from storage\n */\nexport async function createCloudClient(): Promise<CloudClient> {\n const client = new CloudClient();\n await client.initialize();\n return client;\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\n\n/**\n * Safely get the current working directory.\n * Returns null if the CWD has been deleted or is inaccessible.\n */\nfunction safeCwd(): string | null {\n try {\n return process.cwd();\n } catch {\n return null;\n }\n}\n\n/**\n * Get the Convex deployment URL from the project's .env files.\n * Called lazily — only when a command actually needs Convex.\n */\nfunction getConvexUrl(): string {\n const cwd = safeCwd();\n if (!cwd) {\n throw new Error(\n 'Current directory does not exist or is not accessible.\\n' +\n 'Please navigate to a valid AgentForge project directory and try again.'\n );\n }\n const envFiles = ['.env.local', '.env', '.env.production'];\n\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(/CONVEX_URL\\s*=\\s*(.+)/);\n if (match) {\n return match[1].trim().replace(/[\"']/g, '');\n }\n }\n }\n\n // Also check .convex/deployment.json\n const convexEnv = path.join(cwd, '.convex', 'deployment.json');\n if (fs.existsSync(convexEnv)) {\n try {\n const data = JSON.parse(fs.readFileSync(convexEnv, 'utf-8'));\n if (data.url) return data.url;\n } catch {\n // ignore\n }\n }\n\n throw new Error(\n 'CONVEX_URL not found. Run `npx convex dev` first, or set CONVEX_URL in your .env file.'\n );\n}\n\n/**\n * Create a Convex HTTP client connected to the project's deployment.\n * The ConvexHttpClient import is deferred to avoid triggering\n * process.cwd() at module load time (which crashes if CWD is gone).\n */\nexport async function createClient(): Promise<import('convex/browser').ConvexHttpClient> {\n const { ConvexHttpClient } = await import('convex/browser');\n const url = getConvexUrl();\n return new ConvexHttpClient(url);\n}\n\n/**\n * Safely call a Convex query/mutation and handle errors gracefully.\n */\nexport async function safeCall<T>(\n fn: () => Promise<T>,\n errorMessage: string\n): Promise<T> {\n try {\n return await fn();\n } catch (error: any) {\n if (error.message?.includes('CONVEX_URL not found')) {\n console.error('\\n❌ Not connected to Convex.');\n console.error(' Run `npx convex dev` in your project directory first.\\n');\n } else if (error.message?.includes('Current directory does not exist')) {\n console.error(`\\n❌ ${error.message}\\n`);\n } else if (error.message?.includes('fetch failed') || error.message?.includes('ECONNREFUSED')) {\n console.error('\\n❌ Cannot reach Convex deployment.');\n console.error(' Make sure `npx convex dev` is running.\\n');\n } else {\n console.error(`\\n❌ ${errorMessage}`);\n console.error(` ${error.message}\\n`);\n }\n process.exit(1);\n }\n}\n","/**\n * CLI Display Helpers — Consistent formatting for all commands\n */\n\nexport const colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n gray: '\\x1b[90m',\n};\n\nexport function success(msg: string) {\n console.log(`${colors.green}✔${colors.reset} ${msg}`);\n}\n\nexport function error(msg: string) {\n console.error(`${colors.red}✖${colors.reset} ${msg}`);\n}\n\nexport function warn(msg: string) {\n console.log(`${colors.yellow}⚠${colors.reset} ${msg}`);\n}\n\nexport function info(msg: string) {\n console.log(`${colors.blue}ℹ${colors.reset} ${msg}`);\n}\n\nexport function header(title: string) {\n console.log(`\\n${colors.bold}${colors.cyan}${title}${colors.reset}\\n`);\n}\n\nexport function dim(msg: string) {\n console.log(`${colors.dim}${msg}${colors.reset}`);\n}\n\n/**\n * Print a table from an array of objects\n */\nexport function table(data: Record<string, any>[], columns?: string[]) {\n if (data.length === 0) {\n dim(' (no items)');\n return;\n }\n\n const cols = columns ?? Object.keys(data[0]);\n const widths: Record<string, number> = {};\n\n for (const col of cols) {\n widths[col] = Math.max(\n col.length,\n ...data.map((row) => String(row[col] ?? '').length)\n );\n }\n\n // Header\n const headerRow = cols.map((c) => c.toUpperCase().padEnd(widths[c])).join(' ');\n console.log(` ${colors.bold}${headerRow}${colors.reset}`);\n console.log(` ${cols.map((c) => '─'.repeat(widths[c])).join('──')}`);\n\n // Rows\n for (const row of data) {\n const line = cols.map((c) => String(row[c] ?? '').padEnd(widths[c])).join(' ');\n console.log(` ${line}`);\n }\n console.log();\n}\n\n/**\n * Print key-value details\n */\nexport function details(data: Record<string, any>) {\n const maxKey = Math.max(...Object.keys(data).map((k) => k.length));\n for (const [key, value] of Object.entries(data)) {\n const label = `${colors.dim}${key.padEnd(maxKey)}${colors.reset}`;\n console.log(` ${label} ${value}`);\n }\n console.log();\n}\n\n/**\n * Format a timestamp to a readable date string\n */\nexport function formatDate(ts: number): string {\n return new Date(ts).toLocaleString();\n}\n\n/**\n * Truncate a string to a max length\n */\nexport function truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + '…';\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, details, success, error, info, formatDate } from '../lib/display.js';\nimport readline from 'node:readline';\n\nfunction prompt(question: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => rl.question(question, (ans) => { rl.close(); resolve(ans.trim()); }));\n}\n\nexport function registerAgentsCommand(program: Command) {\n const agents = program.command('agents').description('Manage agents');\n\n agents\n .command('list')\n .description('List all agents')\n .option('--active', 'Show only active agents')\n .option('--json', 'Output as JSON')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(\n () => client.query('agents:list' as any, {}),\n 'Failed to list agents'\n );\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n header('Agents');\n if (!result || (result as any[]).length === 0) {\n info('No agents found. Create one with: agentforge agents create');\n return;\n }\n const filtered = opts.active ? (result as any[]).filter((a: any) => a.isActive) : result;\n table(\n (filtered as any[]).map((a: any) => ({\n ID: a.id,\n Name: a.name,\n Model: a.model,\n Provider: a.provider || 'openai',\n Active: a.isActive ? '✔' : '✖',\n Created: formatDate(a.createdAt),\n }))\n );\n });\n\n agents\n .command('create')\n .description('Create a new agent (interactive)')\n .option('--name <name>', 'Agent name')\n .option('--model <model>', 'Model identifier (e.g., openai:gpt-4o-mini)')\n .option('--instructions <text>', 'System instructions')\n .action(async (opts) => {\n const name = opts.name || await prompt('Agent name: ');\n const model = opts.model || await prompt('Model (e.g., openai:gpt-4o-mini): ');\n const instructions = opts.instructions || await prompt('Instructions: ');\n\n if (!name || !model || !instructions) {\n error('Name, model, and instructions are required.');\n process.exit(1);\n }\n\n const provider = model.includes(':') ? model.split(':')[0] : 'openai';\n const agentId = name.toLowerCase().replace(/[^a-z0-9]+/g, '-');\n\n const client = await createClient();\n await safeCall(\n () => client.mutation('agents:create' as any, {\n id: agentId,\n name,\n instructions,\n model,\n provider,\n }),\n 'Failed to create agent'\n );\n success(`Agent \"${name}\" created with ID: ${agentId}`);\n });\n\n agents\n .command('inspect')\n .argument('<id>', 'Agent ID')\n .description('Show detailed agent information')\n .action(async (id) => {\n const client = await createClient();\n const agent = await safeCall(\n () => client.query('agents:get' as any, { id }),\n 'Failed to fetch agent'\n );\n if (!agent) {\n error(`Agent \"${id}\" not found.`);\n process.exit(1);\n }\n header(`Agent: ${(agent as any).name}`);\n const a = agent as any;\n details({\n 'ID': a.id,\n 'Name': a.name,\n 'Model': a.model,\n 'Provider': a.provider || 'openai',\n 'Active': a.isActive ? 'Yes' : 'No',\n 'Temperature': a.temperature ?? 'default',\n 'Max Tokens': a.maxTokens ?? 'default',\n 'Created': formatDate(a.createdAt),\n 'Updated': formatDate(a.updatedAt),\n });\n if (a.description) info(`Description: ${a.description}`);\n console.log(` Instructions:\\n ${a.instructions.split('\\n').join('\\n ')}\\n`);\n });\n\n agents\n .command('edit')\n .argument('<id>', 'Agent ID')\n .option('--name <name>', 'New name')\n .option('--model <model>', 'New model')\n .option('--instructions <text>', 'New instructions')\n .description('Edit an agent')\n .action(async (id, opts) => {\n const client = await createClient();\n const agent = await safeCall(\n () => client.query('agents:get' as any, { id }),\n 'Failed to fetch agent'\n );\n if (!agent) { error(`Agent \"${id}\" not found.`); process.exit(1); }\n\n const updates: Record<string, any> = {};\n if (opts.name) updates.name = opts.name;\n if (opts.model) {\n updates.model = opts.model;\n updates.provider = opts.model.includes(':') ? opts.model.split(':')[0] : 'openai';\n }\n if (opts.instructions) updates.instructions = opts.instructions;\n\n if (Object.keys(updates).length === 0) {\n const a = agent as any;\n const name = await prompt(`Name [${a.name}]: `);\n const model = await prompt(`Model [${a.model}]: `);\n const instr = await prompt(`Instructions [keep current]: `);\n if (name) updates.name = name;\n if (model) { updates.model = model; updates.provider = model.includes(':') ? model.split(':')[0] : 'openai'; }\n if (instr) updates.instructions = instr;\n }\n\n if (Object.keys(updates).length === 0) { info('No changes made.'); return; }\n\n await safeCall(\n () => client.mutation('agents:update' as any, { id, ...updates }),\n 'Failed to update agent'\n );\n success(`Agent \"${id}\" updated.`);\n });\n\n agents\n .command('delete')\n .argument('<id>', 'Agent ID')\n .option('-f, --force', 'Skip confirmation')\n .description('Delete an agent')\n .action(async (id, opts) => {\n if (!opts.force) {\n const confirm = await prompt(`Delete agent \"${id}\"? (y/N): `);\n if (confirm.toLowerCase() !== 'y') { info('Cancelled.'); return; }\n }\n const client = await createClient();\n const agent = await safeCall(\n () => client.query('agents:get' as any, { id }),\n 'Failed to fetch agent'\n );\n if (!agent) { error(`Agent \"${id}\" not found.`); process.exit(1); }\n await safeCall(\n () => client.mutation('agents:remove' as any, { id }),\n 'Failed to delete agent'\n );\n success(`Agent \"${id}\" deleted.`);\n });\n\n agents\n .command('enable')\n .argument('<id>', 'Agent ID')\n .description('Enable an agent')\n .action(async (id) => {\n const client = await createClient();\n const agent = await safeCall(() => client.query('agents:get' as any, { id }), 'Failed to fetch agent');\n if (!agent) { error(`Agent \"${id}\" not found.`); process.exit(1); }\n await safeCall(() => client.mutation('agents:update' as any, { id, isActive: true }), 'Failed');\n success(`Agent \"${id}\" enabled.`);\n });\n\n agents\n .command('disable')\n .argument('<id>', 'Agent ID')\n .description('Disable an agent')\n .action(async (id) => {\n const client = await createClient();\n const agent = await safeCall(() => client.query('agents:get' as any, { id }), 'Failed to fetch agent');\n if (!agent) { error(`Agent \"${id}\" not found.`); process.exit(1); }\n await safeCall(() => client.mutation('agents:update' as any, { id, isActive: false }), 'Failed');\n success(`Agent \"${id}\" disabled.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, success, error, info, dim, colors } from '../lib/display.js';\nimport readline from 'node:readline';\n\nexport function registerChatCommand(program: Command) {\n program\n .command('chat')\n .argument('[agent-id]', 'Agent ID to chat with')\n .option('-s, --session <id>', 'Resume an existing session')\n .description('Start an interactive chat session with an agent')\n .action(async (agentId, opts) => {\n const client = await createClient();\n\n if (!agentId && !opts.session) {\n const agents = await safeCall(() => client.query('agents:list' as any, {}), 'Failed to list agents');\n if (!agents || (agents as any[]).length === 0) {\n error('No agents found. Create one first: agentforge agents create');\n process.exit(1);\n }\n header('Available Agents');\n (agents as any[]).forEach((a: any, i: number) => {\n console.log(` ${colors.cyan}${i + 1}.${colors.reset} ${a.name} ${colors.dim}(${a.id})${colors.reset}`);\n });\n console.log();\n const rl2 = readline.createInterface({ input: process.stdin, output: process.stdout });\n const choice = await new Promise<string>((r) => rl2.question('Select agent (number or ID): ', (a) => { rl2.close(); r(a.trim()); }));\n const idx = parseInt(choice) - 1;\n agentId = idx >= 0 && idx < (agents as any[]).length ? (agents as any[])[idx].id : choice;\n }\n\n const agent = await safeCall(() => client.query('agents:get' as any, { id: agentId }), 'Failed to fetch agent');\n if (!agent) { error(`Agent \"${agentId}\" not found.`); process.exit(1); }\n\n const a = agent as any;\n header(`Chat with ${a.name}`);\n dim(` Model: ${a.model} | Provider: ${a.provider || 'openai'}`);\n dim(` Type \"exit\" or \"quit\" to end. \"/new\" for new thread. \"/history\" for messages.`);\n console.log();\n\n let threadId = await safeCall(\n () => client.mutation('threads:create' as any, { agentId: a.id }),\n 'Failed to create thread'\n );\n\n const history: Array<{ role: string; content: string }> = [];\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: `${colors.green}You${colors.reset} > ` });\n rl.prompt();\n\n rl.on('line', async (line) => {\n const input = line.trim();\n if (!input) { rl.prompt(); return; }\n if (input === 'exit' || input === 'quit') { success('Session ended. Goodbye!'); process.exit(0); }\n if (input === '/new') {\n threadId = await safeCall(() => client.mutation('threads:create' as any, { agentId: a.id }), 'Failed');\n history.length = 0;\n info('New thread started.');\n rl.prompt();\n return;\n }\n if (input === '/history') {\n history.forEach((m) => {\n const prefix = m.role === 'user' ? `${colors.green}You${colors.reset}` : `${colors.cyan}${a.name}${colors.reset}`;\n console.log(` ${prefix}: ${m.content}`);\n });\n if (history.length === 0) dim(' (no messages yet)');\n console.log();\n rl.prompt();\n return;\n }\n\n history.push({ role: 'user', content: input });\n await safeCall(() => client.mutation('messages:add' as any, { threadId, role: 'user', content: input }), 'Failed to send');\n\n process.stdout.write(`${colors.cyan}${a.name}${colors.reset} > `);\n try {\n const response = await safeCall(\n () => client.action('mastraIntegration:executeAgent' as any, { agentId: a.id, prompt: input, threadId }),\n 'Failed to get response'\n );\n const text = (response as any)?.response || (response as any)?.text || (response as any)?.content || String(response);\n console.log(text);\n history.push({ role: 'assistant', content: text });\n } catch {\n console.log(`${colors.yellow}[Configure your LLM API key in .env to get responses]${colors.reset}`);\n }\n console.log();\n rl.prompt();\n });\n\n rl.on('close', () => { console.log(); info('Session ended.'); process.exit(0); });\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, details, success, error, info, formatDate } from '../lib/display.js';\n\nexport function registerSessionsCommand(program: Command) {\n const sessions = program.command('sessions').description('Manage sessions');\n\n sessions\n .command('list')\n .option('--status <status>', 'Filter by status (active, ended)')\n .option('--json', 'Output as JSON')\n .description('List all sessions')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('sessions:list' as any, {}), 'Failed to list sessions');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Sessions');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No sessions found.'); return; }\n const filtered = opts.status ? items.filter((s: any) => s.status === opts.status) : items;\n table(filtered.map((s: any) => ({\n ID: s._id?.slice(-8) || 'N/A',\n Session: s.sessionId,\n Agent: s.agentId,\n Status: s.status,\n Started: formatDate(s.startedAt),\n 'Last Activity': formatDate(s.lastActivityAt),\n })));\n });\n\n sessions\n .command('inspect')\n .argument('<id>', 'Session ID')\n .description('Show session details')\n .action(async (id) => {\n const client = await createClient();\n const session = await safeCall(() => client.query('sessions:get' as any, { sessionId: id }), 'Failed to fetch session');\n if (!session) { error(`Session \"${id}\" not found.`); process.exit(1); }\n const s = session as any;\n header(`Session: ${s.sessionId}`);\n details({ ID: s._id, 'Session ID': s.sessionId, Agent: s.agentId, Status: s.status, Started: formatDate(s.startedAt), 'Last Activity': formatDate(s.lastActivityAt) });\n });\n\n sessions\n .command('end')\n .argument('<id>', 'Session ID')\n .description('End an active session')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('sessions:updateStatus' as any, { sessionId: id, status: 'completed' }), 'Failed to end session');\n success(`Session \"${id}\" ended.`);\n });\n}\n\nexport function registerThreadsCommand(program: Command) {\n const threads = program.command('threads').description('Manage conversation threads');\n\n threads\n .command('list')\n .option('--agent <id>', 'Filter by agent ID')\n .option('--json', 'Output as JSON')\n .description('List all threads')\n .action(async (opts) => {\n const client = await createClient();\n const args = opts.agent ? { agentId: opts.agent } : {};\n const result = await safeCall(() => client.query('threads:list' as any, args), 'Failed to list threads');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Threads');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No threads found.'); return; }\n table(items.map((t: any) => ({\n ID: t._id?.slice(-8) || 'N/A',\n Name: t.name || 'Unnamed',\n Agent: t.agentId,\n Messages: t.metadata?.messageCount || '-',\n Created: formatDate(t.createdAt),\n })));\n });\n\n threads\n .command('inspect')\n .argument('<id>', 'Thread ID')\n .description('Show thread messages')\n .action(async (id) => {\n const client = await createClient();\n const messages = await safeCall(() => client.query('messages:list' as any, { threadId: id }), 'Failed to fetch messages');\n header(`Thread: ${id}`);\n const items = (messages as any[]) || [];\n if (items.length === 0) { info('No messages in this thread.'); return; }\n items.forEach((m: any) => {\n const role = m.role === 'user' ? '\\x1b[32mUser\\x1b[0m' : m.role === 'assistant' ? '\\x1b[36mAssistant\\x1b[0m' : `\\x1b[33m${m.role}\\x1b[0m`;\n console.log(` ${role}: ${m.content}`);\n });\n console.log();\n });\n\n threads\n .command('delete')\n .argument('<id>', 'Thread ID')\n .description('Delete a thread and its messages')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('threads:remove' as any, { id }), 'Failed to delete thread');\n success(`Thread \"${id}\" deleted.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, success, error, info, dim, warn, colors, formatDate, details, truncate } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\nimport { execSync } from 'node:child_process';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ninterface SkillManifest {\n name: string;\n description: string;\n version: string;\n tags?: string[];\n author?: string;\n repository?: string;\n}\n\ninterface RegistryEntry {\n name: string;\n description: string;\n version: string;\n tags: string[];\n author: string;\n source: 'builtin' | 'github' | 'local' | 'url';\n repository?: string;\n path?: string;\n}\n\ninterface SkillLockEntry {\n name: string;\n version: string;\n source: string;\n installedAt: string;\n repository?: string;\n}\n\ninterface SkillsLock {\n version: 1;\n skills: Record<string, SkillLockEntry>;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst SKILLS_DIR_NAME = 'skills';\nconst SKILLS_LOCK_FILE = 'skills.lock.json';\nconst WORKSPACE_DIR_NAME = 'workspace';\n\n// ─── Built-in Skills Registry ─────────────────────────────────────────────────\n// These are the skills that ship with AgentForge and can be installed via CLI.\n// They follow the Mastra Agent Skills Specification (SKILL.md frontmatter format).\n\nconst BUILTIN_REGISTRY: RegistryEntry[] = [\n {\n name: 'web-search',\n description: 'Search the web for information using DuckDuckGo. Provides structured search results with titles, URLs, and snippets.',\n version: '1.0.0',\n tags: ['web', 'search', 'research'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'file-manager',\n description: 'Advanced file management operations including batch rename, find-and-replace across files, directory comparison, and file organization.',\n version: '1.0.0',\n tags: ['files', 'utility', 'management'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'code-review',\n description: 'Systematic code review following best practices. Checks for bugs, security vulnerabilities, style issues, and suggests improvements.',\n version: '1.0.0',\n tags: ['development', 'review', 'quality'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'data-analyst',\n description: 'Analyze CSV, JSON, and tabular data. Generate summaries, statistics, and insights from structured datasets.',\n version: '1.0.0',\n tags: ['data', 'analysis', 'csv', 'json'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'api-tester',\n description: 'Test REST APIs with structured request/response validation. Supports GET, POST, PUT, DELETE with headers and body.',\n version: '1.0.0',\n tags: ['api', 'testing', 'http', 'rest'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'git-workflow',\n description: 'Git workflow automation including conventional commits, branch management, PR descriptions, and changelog generation.',\n version: '1.0.0',\n tags: ['git', 'workflow', 'development'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'browser-automation',\n description: 'Browser automation using Playwright. Navigate web pages, click elements, type text, extract content, take screenshots, and run JavaScript. Supports Docker sandbox mode for secure execution.',\n version: '1.0.0',\n tags: ['web', 'browser', 'automation', 'scraping'],\n author: 'AgentForge',\n source: 'builtin',\n },\n];\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\n/**\n * Resolve the project's skills directory.\n * Checks for workspace/skills/ first (Mastra Workspace pattern), then falls back to skills/.\n */\nfunction resolveSkillsDir(): string {\n const cwd = process.cwd();\n\n // Mastra Workspace pattern: workspace/skills/\n const workspaceSkillsDir = path.join(cwd, WORKSPACE_DIR_NAME, SKILLS_DIR_NAME);\n if (fs.existsSync(path.join(cwd, WORKSPACE_DIR_NAME))) {\n return workspaceSkillsDir;\n }\n\n // Fallback: skills/ at project root\n return path.join(cwd, SKILLS_DIR_NAME);\n}\n\n/**\n * Read the skills lockfile for tracking installed skills.\n */\nfunction readSkillsLock(skillsDir: string): SkillsLock {\n const lockPath = path.join(path.dirname(skillsDir), SKILLS_LOCK_FILE);\n if (fs.existsSync(lockPath)) {\n try {\n return JSON.parse(fs.readFileSync(lockPath, 'utf-8'));\n } catch {\n // Corrupted lock file, start fresh\n }\n }\n return { version: 1, skills: {} };\n}\n\n/**\n * Write the skills lockfile.\n */\nfunction writeSkillsLock(skillsDir: string, lock: SkillsLock): void {\n const lockPath = path.join(path.dirname(skillsDir), SKILLS_LOCK_FILE);\n fs.writeFileSync(lockPath, JSON.stringify(lock, null, 2) + '\\n');\n}\n\n/**\n * Parse SKILL.md frontmatter to extract metadata.\n * Uses a simple YAML frontmatter parser to avoid heavy dependencies.\n */\nfunction parseSkillMd(content: string): { data: SkillManifest; content: string } {\n // Dynamic import of gray-matter for YAML frontmatter parsing\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const matter = require('gray-matter');\n const parsed = matter(content);\n return {\n data: parsed.data as SkillManifest,\n content: parsed.content,\n };\n } catch {\n // Fallback: simple regex-based frontmatter parsing\n const fmMatch = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n if (!fmMatch) {\n return { data: { name: '', description: '', version: '1.0.0' }, content };\n }\n\n const frontmatter = fmMatch[1];\n const body = fmMatch[2];\n const data: Record<string, unknown> = {};\n\n for (const line of frontmatter.split('\\n')) {\n const match = line.match(/^(\\w+):\\s*(.+)$/);\n if (match) {\n const value = match[2].trim();\n data[match[1]] = value;\n }\n }\n\n return {\n data: data as unknown as SkillManifest,\n content: body,\n };\n }\n}\n\n/**\n * Read a local skill's metadata from its SKILL.md.\n */\nfunction readSkillMetadata(skillDir: string): SkillManifest | null {\n const skillMdPath = path.join(skillDir, 'SKILL.md');\n if (!fs.existsSync(skillMdPath)) return null;\n\n const content = fs.readFileSync(skillMdPath, 'utf-8');\n const { data } = parseSkillMd(content);\n return {\n name: data.name || path.basename(skillDir),\n description: data.description || '',\n version: data.version || '1.0.0',\n tags: data.tags || [],\n author: data.author || 'Unknown',\n };\n}\n\n/**\n * Find a skill in the built-in registry by name.\n */\nfunction findInRegistry(name: string): RegistryEntry | undefined {\n return BUILTIN_REGISTRY.find((s) => s.name === name);\n}\n\n// ─── Built-in Skill Content Generators ────────────────────────────────────────\n// These generate the full SKILL.md + supporting files for each built-in skill.\n\nfunction generateBuiltinSkill(name: string): Map<string, string> | null {\n const generators: Record<string, () => Map<string, string>> = {\n 'web-search': generateWebSearchSkill,\n 'file-manager': generateFileManagerSkill,\n 'code-review': generateCodeReviewSkill,\n 'data-analyst': generateDataAnalystSkill,\n 'api-tester': generateApiTesterSkill,\n 'git-workflow': generateGitWorkflowSkill,\n 'browser-automation': generateBrowserAutomationSkill,\n };\n\n const generator = generators[name];\n return generator ? generator() : null;\n}\n\nfunction generateWebSearchSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: web-search\ndescription: Search the web for information using DuckDuckGo and return structured results\nversion: 1.0.0\ntags:\n - web\n - search\n - research\n---\n\n# Web Search\n\nYou are a web research assistant. When the user asks you to search for information:\n\n1. Use the workspace sandbox to execute the search script at \\`scripts/search.ts\\`\n2. Parse the results and present them in a clear, organized format\n3. Include source URLs for all information\n4. Summarize key findings at the top\n\n## How to Search\n\nRun the search script with the user's query:\n\n\\`\\`\\`bash\nnpx tsx scripts/search.ts \"user query here\"\n\\`\\`\\`\n\nThe script returns JSON with structured results including title, URL, and snippet.\n\n## Result Format\n\nPresent results as:\n- **Title** — Brief description ([Source](url))\n- Group related results together\n- Highlight the most relevant findings first\n\n## Guidelines\n\n- Always cite sources with URLs\n- If results are insufficient, suggest refined queries\n- Cross-reference multiple results for accuracy\n- Note when information may be outdated\n`);\n\n files.set('scripts/search.ts', `#!/usr/bin/env npx tsx\n/**\n * Web Search Script — Uses DuckDuckGo Instant Answer API\n *\n * Usage: npx tsx scripts/search.ts \"your query\"\n */\n\nconst query = process.argv[2];\nif (!query) {\n console.error('Usage: npx tsx scripts/search.ts \"query\"');\n process.exit(1);\n}\n\ninterface SearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\nasync function search(q: string): Promise<SearchResult[]> {\n const url = \\`https://api.duckduckgo.com/?q=\\${encodeURIComponent(q)}&format=json&no_redirect=1&no_html=1\\`;\n const res = await fetch(url);\n const data = await res.json();\n\n const results: SearchResult[] = [];\n\n // Abstract (main answer)\n if (data.Abstract) {\n results.push({\n title: data.Heading || q,\n url: data.AbstractURL || '',\n snippet: data.Abstract,\n });\n }\n\n // Related topics\n if (data.RelatedTopics) {\n for (const topic of data.RelatedTopics) {\n if (topic.Text && topic.FirstURL) {\n results.push({\n title: topic.Text.split(' - ')[0] || topic.Text.slice(0, 80),\n url: topic.FirstURL,\n snippet: topic.Text,\n });\n }\n // Subtopics\n if (topic.Topics) {\n for (const sub of topic.Topics) {\n if (sub.Text && sub.FirstURL) {\n results.push({\n title: sub.Text.split(' - ')[0] || sub.Text.slice(0, 80),\n url: sub.FirstURL,\n snippet: sub.Text,\n });\n }\n }\n }\n }\n }\n\n return results.slice(0, 10);\n}\n\nsearch(query)\n .then((results) => console.log(JSON.stringify({ query, results, count: results.length }, null, 2)))\n .catch((err) => {\n console.error(JSON.stringify({ error: err.message }));\n process.exit(1);\n });\n`);\n\n files.set('references/search-tips.md', `# Search Tips\n\n## Effective Queries\n- Use specific keywords rather than full sentences\n- Include domain-specific terms for technical searches\n- Use quotes for exact phrase matching (in the query string)\n- Add \"site:example.com\" to limit to specific domains\n\n## Result Evaluation\n- Check the date of sources when available\n- Cross-reference claims across multiple results\n- Prefer authoritative sources (.edu, .gov, established publications)\n- Note when results are from forums vs. official documentation\n`);\n\n return files;\n}\n\nfunction generateFileManagerSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: file-manager\ndescription: Advanced file management operations including batch rename, find-and-replace, and directory organization\nversion: 1.0.0\ntags:\n - files\n - utility\n - management\n---\n\n# File Manager\n\nYou are a file management assistant. Help users organize, search, and manipulate files in the workspace.\n\n## Capabilities\n\n1. **List & Search** — Find files by name, extension, or content\n2. **Batch Rename** — Rename multiple files using patterns\n3. **Find & Replace** — Search and replace text across files\n4. **Organize** — Sort files into directories by type, date, or custom rules\n5. **Compare** — Show differences between files or directories\n\n## How to Use\n\nUse the workspace filesystem tools to perform operations:\n\n- \\`mastra_workspace_list_files\\` — List directory contents as a tree\n- \\`mastra_workspace_read_file\\` — Read file contents\n- \\`mastra_workspace_write_file\\` — Create or overwrite files\n- \\`mastra_workspace_edit_file\\` — Find and replace in files\n- \\`mastra_workspace_delete\\` — Remove files or directories\n- \\`mastra_workspace_file_stat\\` — Get file metadata (size, dates)\n- \\`mastra_workspace_mkdir\\` — Create directories\n\nFor complex operations, use \\`mastra_workspace_execute_command\\` with the scripts in this skill.\n\n## Scripts\n\n- \\`scripts/batch-rename.ts\\` — Batch rename files with pattern support\n- \\`scripts/find-replace.ts\\` — Find and replace across multiple files\n- \\`scripts/organize.ts\\` — Organize files by extension into directories\n\n## Guidelines\n\n- Always confirm destructive operations (delete, overwrite) with the user\n- Show a preview of changes before executing batch operations\n- Create backups when performing bulk modifications\n- Report the number of files affected after each operation\n`);\n\n files.set('scripts/batch-rename.ts', `#!/usr/bin/env npx tsx\n/**\n * Batch Rename Script\n *\n * Usage: npx tsx scripts/batch-rename.ts <directory> <find-pattern> <replace-pattern>\n * Example: npx tsx scripts/batch-rename.ts ./docs \"report-\" \"2026-report-\"\n */\n\nimport { readdirSync, renameSync } from 'fs';\nimport { join, basename } from 'path';\n\nconst [dir, findPattern, replacePattern] = process.argv.slice(2);\nif (!dir || !findPattern || !replacePattern) {\n console.error('Usage: npx tsx scripts/batch-rename.ts <dir> <find> <replace>');\n process.exit(1);\n}\n\nconst files = readdirSync(dir);\nconst renames: Array<{ from: string; to: string }> = [];\n\nfor (const file of files) {\n if (file.includes(findPattern)) {\n const newName = file.replace(findPattern, replacePattern);\n renames.push({ from: file, to: newName });\n }\n}\n\nif (renames.length === 0) {\n console.log(JSON.stringify({ message: 'No files matched the pattern', count: 0 }));\n process.exit(0);\n}\n\nfor (const { from, to } of renames) {\n renameSync(join(dir, from), join(dir, to));\n}\n\nconsole.log(JSON.stringify({ renames, count: renames.length }));\n`);\n\n files.set('scripts/find-replace.ts', `#!/usr/bin/env npx tsx\n/**\n * Find and Replace Script\n *\n * Usage: npx tsx scripts/find-replace.ts <directory> <find-text> <replace-text> [--ext .ts,.js]\n */\n\nimport { readdirSync, readFileSync, writeFileSync, statSync } from 'fs';\nimport { join, extname } from 'path';\n\nconst args = process.argv.slice(2);\nconst dir = args[0];\nconst findText = args[1];\nconst replaceText = args[2];\nconst extFilter = args.includes('--ext') ? args[args.indexOf('--ext') + 1]?.split(',') : null;\n\nif (!dir || !findText || replaceText === undefined) {\n console.error('Usage: npx tsx scripts/find-replace.ts <dir> <find> <replace> [--ext .ts,.js]');\n process.exit(1);\n}\n\ninterface Change { file: string; count: number; }\nconst changes: Change[] = [];\n\nfunction processDir(dirPath: string) {\n for (const entry of readdirSync(dirPath)) {\n const fullPath = join(dirPath, entry);\n const stat = statSync(fullPath);\n if (stat.isDirectory() && !entry.startsWith('.') && entry !== 'node_modules') {\n processDir(fullPath);\n } else if (stat.isFile()) {\n if (extFilter && !extFilter.includes(extname(entry))) continue;\n const content = readFileSync(fullPath, 'utf-8');\n const count = (content.match(new RegExp(findText.replace(/[.*+?^\\${}()|[\\\\]\\\\\\\\]/g, '\\\\\\\\$&'), 'g')) || []).length;\n if (count > 0) {\n const newContent = content.replaceAll(findText, replaceText);\n writeFileSync(fullPath, newContent);\n changes.push({ file: fullPath, count });\n }\n }\n }\n}\n\nprocessDir(dir);\nconsole.log(JSON.stringify({ changes, totalFiles: changes.length, totalReplacements: changes.reduce((s, c) => s + c.count, 0) }));\n`);\n\n return files;\n}\n\nfunction generateCodeReviewSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: code-review\ndescription: Systematic code review following best practices for quality, security, and style\nversion: 1.0.0\ntags:\n - development\n - review\n - quality\n---\n\n# Code Review\n\nYou are a code reviewer. When reviewing code, follow this systematic process:\n\n## Review Process\n\n1. **Critical Issues** — Security vulnerabilities, memory leaks, logic bugs, missing error handling\n2. **Code Quality** — Functions over 50 lines, code duplication, confusing names, missing types\n3. **Style Guide** — Check references/style-guide.md for naming and organization conventions\n4. **Performance** — Unnecessary re-renders, N+1 queries, missing memoization, large bundle imports\n5. **Testing** — Missing test coverage, edge cases not handled, brittle assertions\n\n## Feedback Format\n\nProvide feedback in this structure:\n\n**Summary**: One sentence overview of the code quality\n\n**Critical Issues**: List with file paths and line numbers\n- \\`file.ts:42\\` — Description of the issue\n\n**Suggestions**: Improvements that would help\n- Description of suggestion with code example\n\n**Positive Notes**: What the code does well\n\n## What to Look Out For\n\n- Unused variables and imports\n- Missing error handling (try/catch, null checks)\n- Security vulnerabilities (SQL injection, XSS, secrets in code)\n- Performance issues (unnecessary loops, missing indexes)\n- TypeScript: any types, missing return types, loose generics\n- React: missing keys, stale closures, missing deps in useEffect\n\n## Scripts\n\n- \\`scripts/lint.ts\\` — Run linting checks on a file or directory\n`);\n\n files.set('references/style-guide.md', `# Code Style Guide\n\n## TypeScript Conventions\n- Use \\`const\\` by default, \\`let\\` only when reassignment is needed\n- Prefer \\`interface\\` over \\`type\\` for object shapes\n- Always specify return types for exported functions\n- Use \\`unknown\\` instead of \\`any\\` where possible\n- Prefer \\`readonly\\` for properties that shouldn't change\n\n## Naming Conventions\n- **Files**: kebab-case (\\`my-component.tsx\\`)\n- **Components**: PascalCase (\\`MyComponent\\`)\n- **Functions**: camelCase (\\`getUserById\\`)\n- **Constants**: UPPER_SNAKE_CASE (\\`MAX_RETRIES\\`)\n- **Types/Interfaces**: PascalCase (\\`UserProfile\\`)\n\n## File Organization\n- One component per file\n- Co-locate tests with source files (\\`*.test.ts\\`)\n- Group by feature, not by type\n- Keep files under 300 lines\n\n## Error Handling\n- Always handle promise rejections\n- Use typed errors with error codes\n- Log errors with context (user ID, request ID)\n- Never swallow errors silently\n`);\n\n files.set('scripts/lint.ts', `#!/usr/bin/env npx tsx\n/**\n * Simple Lint Script — Checks for common issues\n *\n * Usage: npx tsx scripts/lint.ts <file-or-directory>\n */\n\nimport { readFileSync, readdirSync, statSync } from 'fs';\nimport { join, extname } from 'path';\n\nconst target = process.argv[2];\nif (!target) {\n console.error('Usage: npx tsx scripts/lint.ts <file-or-directory>');\n process.exit(1);\n}\n\ninterface LintIssue {\n file: string;\n line: number;\n severity: 'error' | 'warning';\n message: string;\n}\n\nconst issues: LintIssue[] = [];\n\nfunction lintFile(filePath: string) {\n const content = readFileSync(filePath, 'utf-8');\n const lines = content.split('\\\\n');\n\n lines.forEach((line, i) => {\n const lineNum = i + 1;\n // Check for console.log\n if (line.includes('console.log') && !filePath.includes('test')) {\n issues.push({ file: filePath, line: lineNum, severity: 'warning', message: 'console.log found — remove before production' });\n }\n // Check for debugger\n if (line.trim() === 'debugger' || line.trim() === 'debugger;') {\n issues.push({ file: filePath, line: lineNum, severity: 'error', message: 'debugger statement found' });\n }\n // Check for any type\n if (line.includes(': any') || line.includes('<any>')) {\n issues.push({ file: filePath, line: lineNum, severity: 'warning', message: 'Use of \"any\" type — prefer \"unknown\" or specific type' });\n }\n // Check for var usage\n if (/\\\\bvar\\\\s+/.test(line)) {\n issues.push({ file: filePath, line: lineNum, severity: 'error', message: 'Use \"const\" or \"let\" instead of \"var\"' });\n }\n // Check for TODO/FIXME\n if (/\\\\/\\\\/\\\\s*(TODO|FIXME|HACK|XXX)/.test(line)) {\n issues.push({ file: filePath, line: lineNum, severity: 'warning', message: 'Unresolved TODO/FIXME comment' });\n }\n });\n}\n\nfunction processPath(p: string) {\n const stat = statSync(p);\n if (stat.isFile() && ['.ts', '.tsx', '.js', '.jsx'].includes(extname(p))) {\n lintFile(p);\n } else if (stat.isDirectory()) {\n for (const entry of readdirSync(p)) {\n if (!entry.startsWith('.') && entry !== 'node_modules' && entry !== 'dist') {\n processPath(join(p, entry));\n }\n }\n }\n}\n\nprocessPath(target);\nconsole.log(JSON.stringify({ issues, total: issues.length, errors: issues.filter(i => i.severity === 'error').length, warnings: issues.filter(i => i.severity === 'warning').length }));\n`);\n\n return files;\n}\n\nfunction generateDataAnalystSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: data-analyst\ndescription: Analyze CSV, JSON, and tabular data to generate summaries, statistics, and insights\nversion: 1.0.0\ntags:\n - data\n - analysis\n - csv\n - json\n---\n\n# Data Analyst\n\nYou are a data analysis assistant. Help users understand and extract insights from structured data.\n\n## Capabilities\n\n1. **Load Data** — Read CSV, JSON, and TSV files from the workspace\n2. **Summarize** — Generate column statistics (min, max, mean, median, mode)\n3. **Filter & Query** — Filter rows by conditions, select columns\n4. **Aggregate** — Group by columns and compute aggregates\n5. **Detect Anomalies** — Find outliers and missing values\n\n## How to Analyze\n\n1. First, read the data file using workspace filesystem tools\n2. Use \\`scripts/analyze.ts\\` for statistical analysis\n3. Present findings in a clear table format\n4. Suggest follow-up analyses based on initial findings\n\n## Scripts\n\n- \\`scripts/analyze.ts\\` — Compute statistics on CSV/JSON data\n\n## Output Format\n\nPresent analysis results as:\n- **Dataset Overview**: Row count, column count, column types\n- **Key Statistics**: Per-column min, max, mean, median\n- **Missing Data**: Columns with null/empty values and their percentages\n- **Insights**: Notable patterns, correlations, or anomalies\n\n## Guidelines\n\n- Always show a sample of the data (first 5 rows) before analysis\n- Handle missing values gracefully — report them, don't crash\n- Use appropriate precision for numbers (2 decimal places for percentages)\n- Suggest visualizations when patterns would be clearer in chart form\n`);\n\n files.set('scripts/analyze.ts', `#!/usr/bin/env npx tsx\n/**\n * Data Analysis Script — Basic statistics for CSV/JSON data\n *\n * Usage: npx tsx scripts/analyze.ts <file.csv|file.json>\n */\n\nimport { readFileSync } from 'fs';\nimport { extname } from 'path';\n\nconst filePath = process.argv[2];\nif (!filePath) {\n console.error('Usage: npx tsx scripts/analyze.ts <file.csv|file.json>');\n process.exit(1);\n}\n\nfunction parseCSV(content: string): Record<string, string>[] {\n const lines = content.trim().split('\\\\n');\n const headers = lines[0].split(',').map(h => h.trim().replace(/^\"|\"$/g, ''));\n return lines.slice(1).map(line => {\n const values = line.split(',').map(v => v.trim().replace(/^\"|\"$/g, ''));\n return Object.fromEntries(headers.map((h, i) => [h, values[i] ?? '']));\n });\n}\n\nconst content = readFileSync(filePath, 'utf-8');\nconst ext = extname(filePath).toLowerCase();\nlet data: Record<string, string>[];\n\nif (ext === '.json') {\n const parsed = JSON.parse(content);\n data = Array.isArray(parsed) ? parsed : [parsed];\n} else {\n data = parseCSV(content);\n}\n\nconst columns = Object.keys(data[0] || {});\nconst stats: Record<string, any> = {};\n\nfor (const col of columns) {\n const values = data.map(row => row[col]).filter(v => v !== '' && v !== null && v !== undefined);\n const numValues = values.map(Number).filter(n => !isNaN(n));\n\n stats[col] = {\n total: data.length,\n nonNull: values.length,\n missing: data.length - values.length,\n missingPct: ((data.length - values.length) / data.length * 100).toFixed(1) + '%',\n unique: new Set(values).size,\n };\n\n if (numValues.length > 0) {\n numValues.sort((a, b) => a - b);\n stats[col].type = 'numeric';\n stats[col].min = Math.min(...numValues);\n stats[col].max = Math.max(...numValues);\n stats[col].mean = +(numValues.reduce((s, n) => s + n, 0) / numValues.length).toFixed(2);\n stats[col].median = numValues.length % 2 === 0\n ? +((numValues[numValues.length / 2 - 1] + numValues[numValues.length / 2]) / 2).toFixed(2)\n : numValues[Math.floor(numValues.length / 2)];\n } else {\n stats[col].type = 'string';\n stats[col].sample = values.slice(0, 3);\n }\n}\n\nconsole.log(JSON.stringify({\n rows: data.length,\n columns: columns.length,\n columnNames: columns,\n stats,\n sample: data.slice(0, 5),\n}, null, 2));\n`);\n\n return files;\n}\n\nfunction generateApiTesterSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: api-tester\ndescription: Test REST APIs with structured request/response validation\nversion: 1.0.0\ntags:\n - api\n - testing\n - http\n - rest\n---\n\n# API Tester\n\nYou are an API testing assistant. Help users test and validate REST API endpoints.\n\n## Capabilities\n\n1. **Send Requests** — GET, POST, PUT, PATCH, DELETE with headers and body\n2. **Validate Responses** — Check status codes, response structure, and timing\n3. **Chain Requests** — Use output from one request as input to another\n4. **Generate Reports** — Summarize test results with pass/fail status\n\n## How to Test\n\nUse \\`scripts/request.ts\\` to make HTTP requests:\n\n\\`\\`\\`bash\nnpx tsx scripts/request.ts GET https://api.example.com/users\nnpx tsx scripts/request.ts POST https://api.example.com/users --body '{\"name\":\"test\"}'\n\\`\\`\\`\n\n## Report Format\n\nFor each API test, report:\n- **Endpoint**: METHOD URL\n- **Status**: HTTP status code (with pass/fail indicator)\n- **Response Time**: Duration in milliseconds\n- **Response Body**: Formatted JSON (truncated if large)\n- **Headers**: Key response headers\n\n## Guidelines\n\n- Always show the full request details (method, URL, headers, body)\n- Time every request and flag slow responses (>2s)\n- Validate JSON response structure when a schema is provided\n- Never send real credentials — use placeholders and warn the user\n- Group related tests together (e.g., CRUD operations on one resource)\n`);\n\n files.set('scripts/request.ts', `#!/usr/bin/env npx tsx\n/**\n * HTTP Request Script — Make API requests from the command line\n *\n * Usage: npx tsx scripts/request.ts <METHOD> <URL> [--header \"Key: Value\"] [--body '{\"key\":\"value\"}']\n */\n\nconst args = process.argv.slice(2);\nconst method = args[0]?.toUpperCase() || 'GET';\nconst url = args[1];\n\nif (!url) {\n console.error('Usage: npx tsx scripts/request.ts <METHOD> <URL> [--header \"K: V\"] [--body JSON]');\n process.exit(1);\n}\n\nconst headers: Record<string, string> = { 'Content-Type': 'application/json' };\nlet body: string | undefined;\n\nfor (let i = 2; i < args.length; i++) {\n if (args[i] === '--header' && args[i + 1]) {\n const [key, ...valueParts] = args[++i].split(':');\n headers[key.trim()] = valueParts.join(':').trim();\n }\n if (args[i] === '--body' && args[i + 1]) {\n body = args[++i];\n }\n}\n\nasync function makeRequest() {\n const start = Date.now();\n const res = await fetch(url, {\n method,\n headers,\n ...(body && method !== 'GET' ? { body } : {}),\n });\n const elapsed = Date.now() - start;\n const responseHeaders: Record<string, string> = {};\n res.headers.forEach((v, k) => { responseHeaders[k] = v; });\n\n let responseBody: any;\n const contentType = res.headers.get('content-type') || '';\n if (contentType.includes('json')) {\n responseBody = await res.json();\n } else {\n responseBody = await res.text();\n }\n\n console.log(JSON.stringify({\n request: { method, url, headers, body: body ? JSON.parse(body) : undefined },\n response: {\n status: res.status,\n statusText: res.statusText,\n headers: responseHeaders,\n body: responseBody,\n timeMs: elapsed,\n },\n }, null, 2));\n}\n\nmakeRequest().catch((err) => {\n console.error(JSON.stringify({ error: err.message }));\n process.exit(1);\n});\n`);\n\n return files;\n}\n\nfunction generateGitWorkflowSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: git-workflow\ndescription: Git workflow automation including conventional commits, branch management, and changelog generation\nversion: 1.0.0\ntags:\n - git\n - workflow\n - development\n---\n\n# Git Workflow\n\nYou are a Git workflow assistant. Help users follow best practices for version control.\n\n## Capabilities\n\n1. **Conventional Commits** — Generate commit messages following the Conventional Commits spec\n2. **Branch Management** — Create, switch, and clean up branches following naming conventions\n3. **PR Descriptions** — Generate pull request descriptions from commit history\n4. **Changelog** — Generate changelogs from commit history\n\n## Conventional Commit Format\n\n\\`\\`\\`\n<type>(<scope>): <description>\n\n[optional body]\n\n[optional footer(s)]\n\\`\\`\\`\n\n### Types\n- \\`feat\\`: New feature (MINOR version bump)\n- \\`fix\\`: Bug fix (PATCH version bump)\n- \\`docs\\`: Documentation changes\n- \\`style\\`: Code style changes (formatting, semicolons)\n- \\`refactor\\`: Code refactoring (no feature/fix)\n- \\`perf\\`: Performance improvements\n- \\`test\\`: Adding or updating tests\n- \\`chore\\`: Build process, tooling, dependencies\n\n## Branch Naming\n\n- \\`feat/<ticket>-<description>\\` — New features\n- \\`fix/<ticket>-<description>\\` — Bug fixes\n- \\`chore/<description>\\` — Maintenance tasks\n- \\`release/<version>\\` — Release branches\n\n## Scripts\n\n- \\`scripts/changelog.ts\\` — Generate changelog from git log\n\n## Guidelines\n\n- One logical change per commit\n- Write commit messages in imperative mood (\"Add feature\" not \"Added feature\")\n- Reference issue/ticket numbers in commits\n- Keep PR descriptions focused on the \"what\" and \"why\"\n- Squash fix-up commits before merging\n`);\n\n files.set('references/commit-examples.md', `# Commit Message Examples\n\n## Good Examples\n\\`\\`\\`\nfeat(auth): add OAuth2 login with Google provider\nfix(api): handle null response from payment gateway\ndocs(readme): add deployment instructions for Cloudflare\nrefactor(db): extract query builder into separate module\nperf(search): add index on user_email column\ntest(auth): add integration tests for JWT refresh flow\nchore(deps): upgrade @mastra/core to 1.4.0\n\\`\\`\\`\n\n## Bad Examples\n\\`\\`\\`\nfixed stuff\nupdate\nWIP\nasdf\nchanges\n\\`\\`\\`\n`);\n\n files.set('scripts/changelog.ts', `#!/usr/bin/env npx tsx\n/**\n * Changelog Generator — Generate changelog from git log\n *\n * Usage: npx tsx scripts/changelog.ts [--since v1.0.0] [--until HEAD]\n */\n\nimport { execSync } from 'child_process';\n\nconst args = process.argv.slice(2);\nlet since = '';\nlet until = 'HEAD';\n\nfor (let i = 0; i < args.length; i++) {\n if (args[i] === '--since' && args[i + 1]) since = args[++i];\n if (args[i] === '--until' && args[i + 1]) until = args[++i];\n}\n\nconst range = since ? \\`\\${since}..\\${until}\\` : until;\nconst log = execSync(\\`git log \\${range} --pretty=format:\"%H|%s|%an|%ai\" 2>/dev/null || echo \"\"\\`, { encoding: 'utf-8' });\n\ninterface Commit {\n hash: string;\n message: string;\n author: string;\n date: string;\n type: string;\n scope: string;\n description: string;\n}\n\nconst commits: Commit[] = log.trim().split('\\\\n').filter(Boolean).map(line => {\n const [hash, message, author, date] = line.split('|');\n const match = message.match(/^(\\\\w+)(?:\\\\(([^)]+)\\\\))?:\\\\s*(.+)$/);\n return {\n hash: hash.slice(0, 7),\n message,\n author,\n date: date.split(' ')[0],\n type: match?.[1] || 'other',\n scope: match?.[2] || '',\n description: match?.[3] || message,\n };\n});\n\nconst grouped: Record<string, Commit[]> = {};\nfor (const c of commits) {\n if (!grouped[c.type]) grouped[c.type] = [];\n grouped[c.type].push(c);\n}\n\nconst typeLabels: Record<string, string> = {\n feat: 'Features',\n fix: 'Bug Fixes',\n docs: 'Documentation',\n refactor: 'Refactoring',\n perf: 'Performance',\n test: 'Tests',\n chore: 'Chores',\n};\n\nlet changelog = '# Changelog\\\\n\\\\n';\nfor (const [type, label] of Object.entries(typeLabels)) {\n if (grouped[type]?.length) {\n changelog += \\`## \\${label}\\\\n\\\\n\\`;\n for (const c of grouped[type]) {\n const scope = c.scope ? \\`**\\${c.scope}**: \\` : '';\n changelog += \\`- \\${scope}\\${c.description} (\\${c.hash})\\\\n\\`;\n }\n changelog += '\\\\n';\n }\n}\n\nconsole.log(JSON.stringify({ changelog, totalCommits: commits.length, types: Object.keys(grouped) }));\n`);\n\n return files;\n}\n\nfunction generateBrowserAutomationSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: browser-automation\ndescription: Browser automation using Playwright. Navigate web pages, interact with elements, extract content, take screenshots, and run JavaScript.\nversion: 1.0.0\ntags:\n - web\n - browser\n - automation\n - scraping\n---\n\n# Browser Automation\n\nYou are a browser automation assistant. Help users interact with web pages programmatically.\n\n## Capabilities\n\n1. **Navigate** — Go to any URL and wait for the page to load\n2. **Click** — Click elements by CSS selector\n3. **Type** — Fill text into input fields\n4. **Screenshot** — Capture the current page as an image\n5. **Extract Text** — Get readable text content from pages or specific elements\n6. **Snapshot** — Get the accessibility tree for understanding page structure\n7. **Evaluate** — Run arbitrary JavaScript on the page\n8. **Wait** — Wait for elements to appear or for a specific duration\n9. **Scroll** — Scroll the page up or down\n10. **Select** — Choose options from dropdown menus\n11. **Hover** — Hover over elements to trigger menus or tooltips\n12. **Navigation** — Go back, forward, or reload the page\n\n## How to Use\n\n### Setup\n\n\\`\\`\\`typescript\nimport { createBrowserTool, MCPServer } from '@agentforge-ai/core';\n\nconst server = new MCPServer({ name: 'my-tools' });\nconst { tool, shutdown } = createBrowserTool({ headless: true });\nserver.registerTool(tool);\n\\`\\`\\`\n\n### Docker Sandbox Mode\n\nFor secure, isolated execution:\n\n\\`\\`\\`typescript\nconst { tool, shutdown } = createBrowserTool({\n sandboxMode: true,\n headless: true,\n});\n\\`\\`\\`\n\n## Agent Instructions\n\n1. Navigate to the target URL first\n2. Wait for key elements before interacting\n3. Use snapshot to understand page structure\n4. Use extractText to get readable content\n5. Use click and type for form interactions\n6. Take screenshots for visual verification\n7. Always close sessions when done\n\n## Guidelines\n\n- Prefer \\`#id\\` selectors over class-based selectors\n- Use \\`wait\\` before clicking or typing on dynamic pages\n- Use \\`extractText\\` with a selector for specific content\n- Take screenshots before and after critical actions\n- Close sessions to free resources\n`);\n\n files.set('references/selectors.md', `# CSS Selector Guide for Browser Automation\n\n## Recommended Selectors (most to least reliable)\n\n1. \\`#id\\` — Element with a specific ID\n2. \\`[data-testid=\"value\"]\\` — Test ID attributes\n3. \\`[aria-label=\"value\"]\\` — Accessibility labels\n4. \\`button:has-text(\"Click me\")\\` — Playwright text selectors\n5. \\`.class-name\\` — CSS class selectors\n6. \\`tag.class\\` — Tag + class combination\n\n## Examples\n\n\\`\\`\\`\n#login-button → Click the login button\ninput[name=\"email\"] → Type into email field\n.nav-menu a:first-child → Click first nav link\nform button[type=submit] → Submit a form\n\\`\\`\\`\n\n## Tips\n\n- Avoid fragile selectors like \\`div > div > span:nth-child(3)\\`\n- Use Playwright's text selectors: \\`text=Submit\\`\n- For dynamic content, wait for the element first\n- Use \\`snapshot\\` action to discover available selectors\n`);\n\n files.set('scripts/scrape.ts', `#!/usr/bin/env npx tsx\n/**\n * Example: Scrape a web page and extract its text content\n *\n * Usage: npx tsx scripts/scrape.ts <url>\n */\n\nconst url = process.argv[2];\nif (!url) {\n console.error('Usage: npx tsx scripts/scrape.ts <url>');\n process.exit(1);\n}\n\nconsole.log(JSON.stringify({\n instruction: 'Use the browser tool to scrape this URL',\n url,\n steps: [\n { action: 'navigate', url },\n { action: 'wait', timeMs: 2000 },\n { action: 'extractText' },\n { action: 'screenshot', fullPage: true },\n { action: 'close' },\n ],\n}));\n`);\n\n return files;\n}\n\n// ─── Command Registration ─────────────────────────────────────────────────────\n\nexport function registerSkillsCommand(program: Command) {\n const skills = program.command('skills').description('Manage agent skills (Mastra Workspace Skills)');\n\n // ─── skills list ──────────────────────────────────────────────────\n skills\n .command('list')\n .option('--json', 'Output as JSON')\n .option('--registry', 'Show available skills from the registry')\n .description('List installed skills or browse the registry')\n .action(async (opts) => {\n if (opts.registry) {\n // Show the built-in registry\n header('AgentForge Skills Registry');\n if (opts.json) {\n console.log(JSON.stringify(BUILTIN_REGISTRY, null, 2));\n return;\n }\n table(BUILTIN_REGISTRY.map((s) => ({\n Name: s.name,\n Description: truncate(s.description, 60),\n Version: s.version,\n Tags: s.tags.join(', '),\n })));\n info(`Install with: ${colors.cyan}agentforge skills install <name>${colors.reset}`);\n return;\n }\n\n // Show installed skills\n const skillsDir = resolveSkillsDir();\n header('Installed Skills');\n\n if (!fs.existsSync(skillsDir)) {\n info('No skills directory found. Install a skill with:');\n dim(` agentforge skills install <name>`);\n dim(` agentforge skills list --registry # browse available skills`);\n return;\n }\n\n const dirs = fs.readdirSync(skillsDir).filter((d: string) => {\n const fullPath = path.join(skillsDir, d);\n return fs.statSync(fullPath).isDirectory() && fs.existsSync(path.join(fullPath, 'SKILL.md'));\n });\n\n if (dirs.length === 0) {\n info('No skills installed. Browse available skills with:');\n dim(` agentforge skills list --registry`);\n return;\n }\n\n const lock = readSkillsLock(skillsDir);\n\n const skillData = dirs.map((d: string) => {\n const meta = readSkillMetadata(path.join(skillsDir, d));\n const lockEntry = lock.skills[d];\n return {\n Name: meta?.name || d,\n Description: truncate(meta?.description || '', 50),\n Version: meta?.version || '?',\n Tags: (meta?.tags || []).join(', '),\n Source: lockEntry?.source || 'local',\n Installed: lockEntry?.installedAt ? new Date(lockEntry.installedAt).toLocaleDateString() : '—',\n };\n });\n\n if (opts.json) {\n console.log(JSON.stringify(skillData, null, 2));\n return;\n }\n\n table(skillData);\n dim(` Skills directory: ${skillsDir}`);\n info('Skills are auto-discovered by the Mastra Workspace.');\n });\n\n // ─── skills install ───────────────────────────────────────────────\n skills\n .command('install')\n .argument('<name>', 'Skill name from registry, GitHub URL, or local path')\n .option('--from <source>', 'Source: registry (default), github, local', 'registry')\n .description('Install a skill into the workspace')\n .action(async (name, opts) => {\n const skillsDir = resolveSkillsDir();\n const targetDir = path.join(skillsDir, name.split('/').pop()!.replace(/\\.git$/, ''));\n\n // Check if already installed\n if (fs.existsSync(targetDir) && fs.existsSync(path.join(targetDir, 'SKILL.md'))) {\n warn(`Skill \"${name}\" is already installed at ${targetDir}`);\n const overwrite = await prompt('Overwrite? (y/N): ');\n if (overwrite.toLowerCase() !== 'y') {\n info('Installation cancelled.');\n return;\n }\n fs.removeSync(targetDir);\n }\n\n // Ensure skills directory exists\n fs.mkdirSync(skillsDir, { recursive: true });\n\n let source: string = opts.from;\n let installedName = name;\n\n if (opts.from === 'local' || fs.existsSync(name)) {\n // ─── Install from local path ─────────────────────────────\n source = 'local';\n const sourcePath = path.resolve(name);\n if (!fs.existsSync(sourcePath)) {\n error(`Local path not found: ${sourcePath}`);\n process.exit(1);\n }\n if (!fs.existsSync(path.join(sourcePath, 'SKILL.md'))) {\n error(`No SKILL.md found in ${sourcePath}. Not a valid skill directory.`);\n process.exit(1);\n }\n installedName = path.basename(sourcePath);\n const dest = path.join(skillsDir, installedName);\n fs.copySync(sourcePath, dest);\n success(`Skill \"${installedName}\" installed from local path.`);\n\n } else if (opts.from === 'github' || name.includes('github.com') || name.includes('/')) {\n // ─── Install from GitHub ─────────────────────────────────\n source = 'github';\n const repoUrl = name.includes('github.com') ? name : `https://github.com/${name}`;\n installedName = name.split('/').pop()!.replace(/\\.git$/, '');\n const dest = path.join(skillsDir, installedName);\n\n info(`Cloning skill from ${repoUrl}...`);\n try {\n execSync(`git clone --depth 1 ${repoUrl} ${dest} 2>&1`, { encoding: 'utf-8' });\n // Remove .git directory\n fs.removeSync(path.join(dest, '.git'));\n\n if (!fs.existsSync(path.join(dest, 'SKILL.md'))) {\n error(`Cloned repo does not contain a SKILL.md. Not a valid skill.`);\n fs.removeSync(dest);\n process.exit(1);\n }\n success(`Skill \"${installedName}\" installed from GitHub.`);\n } catch (err: unknown) {\n error(`Failed to clone: ${(err as Error).message}`);\n process.exit(1);\n }\n\n } else {\n // ─── Install from built-in registry ──────────────────────\n source = 'builtin';\n const entry = findInRegistry(name);\n if (!entry) {\n error(`Skill \"${name}\" not found in the registry.`);\n info('Available skills:');\n BUILTIN_REGISTRY.forEach((s) => {\n dim(` ${colors.cyan}${s.name}${colors.reset} — ${s.description}`);\n });\n info(`\\nOr install from GitHub: ${colors.cyan}agentforge skills install owner/repo --from github${colors.reset}`);\n process.exit(1);\n }\n\n installedName = entry.name;\n const files = generateBuiltinSkill(entry.name);\n if (!files) {\n error(`No content generator for skill \"${entry.name}\".`);\n process.exit(1);\n }\n\n const dest = path.join(skillsDir, installedName);\n fs.mkdirSync(dest, { recursive: true });\n\n for (const [filePath, content] of files) {\n const fullPath = path.join(dest, filePath);\n fs.mkdirSync(path.dirname(fullPath), { recursive: true });\n fs.writeFileSync(fullPath, content);\n }\n\n success(`Skill \"${installedName}\" installed from AgentForge registry.`);\n }\n\n // Update lockfile\n const lock = readSkillsLock(skillsDir);\n const meta = readSkillMetadata(path.join(skillsDir, installedName));\n lock.skills[installedName] = {\n name: installedName,\n version: meta?.version || '1.0.0',\n source,\n installedAt: new Date().toISOString(),\n };\n writeSkillsLock(skillsDir, lock);\n\n // Show skill info\n if (meta) {\n console.log();\n details({\n Name: meta.name,\n Description: meta.description,\n Version: meta.version,\n Tags: (meta.tags || []).join(', ') || '—',\n Path: path.join(skillsDir, installedName),\n });\n }\n\n info('The skill is now available to agents via the Mastra Workspace.');\n dim(' Skills in the workspace/skills/ directory are auto-discovered.');\n\n // Sync to Convex if available (best-effort)\n try {\n const client = await createClient();\n await safeCall(\n () => client.mutation('skills:create' as any, {\n name: installedName,\n displayName: meta?.name || installedName,\n description: meta?.description || '',\n category: (meta?.tags || [])[0] || 'custom',\n version: meta?.version || '1.0.0',\n author: meta?.author || 'Unknown',\n code: `// Skill: ${installedName}\\n// This skill uses the Agent Skills Specification (SKILL.md format)\\n// See: workspace/skills/${installedName}/SKILL.md`,\n }),\n 'Failed to sync skill to Convex'\n );\n dim(' Skill synced to Convex database.');\n } catch {\n // Convex not available — that's fine, skills work locally via filesystem\n dim(' Convex not connected — skill installed locally only.');\n }\n });\n\n // ─── skills remove ────────────────────────────────────────────────\n skills\n .command('remove')\n .argument('<name>', 'Skill name to remove')\n .option('--force', 'Skip confirmation prompt', false)\n .description('Remove an installed skill')\n .action(async (name, opts) => {\n const skillsDir = resolveSkillsDir();\n const skillDir = path.join(skillsDir, name);\n\n if (!fs.existsSync(skillDir)) {\n error(`Skill \"${name}\" not found in ${skillsDir}`);\n info('List installed skills with: agentforge skills list');\n process.exit(1);\n }\n\n if (!opts.force) {\n const confirm = await prompt(`Remove skill \"${name}\" and delete all files? (y/N): `);\n if (confirm.toLowerCase() !== 'y') {\n info('Removal cancelled.');\n return;\n }\n }\n\n // Remove from filesystem\n fs.removeSync(skillDir);\n success(`Skill \"${name}\" removed from disk.`);\n\n // Remove from lockfile\n const lock = readSkillsLock(skillsDir);\n delete lock.skills[name];\n writeSkillsLock(skillsDir, lock);\n\n // Remove from Convex (best-effort)\n try {\n const client = await createClient();\n const skills = await client.query('skills:list' as any, {});\n const skill = (skills as any[]).find((s: any) => s.name === name);\n if (skill) {\n await client.mutation('skills:remove' as any, { id: skill._id });\n dim(' Skill removed from Convex database.');\n }\n } catch {\n // Convex not available — that's fine\n }\n\n info('Skill removed. Agents will no longer discover it.');\n });\n\n // ─── skills search ────────────────────────────────────────────────\n skills\n .command('search')\n .argument('<query>', 'Search query')\n .description('Search for skills in the registry')\n .action(async (query) => {\n header('Skill Search Results');\n const q = query.toLowerCase();\n const matches = BUILTIN_REGISTRY.filter(\n (e) =>\n e.name.includes(q) ||\n e.description.toLowerCase().includes(q) ||\n e.tags.some((t) => t.includes(q))\n );\n\n if (matches.length === 0) {\n info(`No skills matching \"${query}\".`);\n info('Browse all skills: agentforge skills list --registry');\n return;\n }\n\n table(matches.map((e) => ({\n Name: e.name,\n Description: truncate(e.description, 60),\n Tags: e.tags.join(', '),\n Version: e.version,\n })));\n info(`Install with: ${colors.cyan}agentforge skills install <name>${colors.reset}`);\n });\n\n // ─── skills create ────────────────────────────────────────────────\n skills\n .command('create')\n .description('Create a new skill (interactive)')\n .option('--name <name>', 'Skill name (kebab-case)')\n .option('--description <desc>', 'Skill description')\n .option('--tags <tags>', 'Comma-separated tags')\n .action(async (opts) => {\n const name = opts.name || await prompt('Skill name (kebab-case): ');\n const description = opts.description || await prompt('Description: ');\n const tagsInput = opts.tags || await prompt('Tags (comma-separated, e.g. web,search): ');\n const tags = tagsInput ? tagsInput.split(',').map((t: string) => t.trim()).filter(Boolean) : [];\n\n if (!name) { error('Skill name is required.'); process.exit(1); }\n if (!/^[a-z][a-z0-9-]*$/.test(name)) {\n error('Skill name must be kebab-case (lowercase letters, numbers, hyphens).');\n process.exit(1);\n }\n\n const skillsDir = resolveSkillsDir();\n const skillDir = path.join(skillsDir, name);\n\n if (fs.existsSync(skillDir)) {\n error(`Skill \"${name}\" already exists at ${skillDir}`);\n process.exit(1);\n }\n\n // Create skill directory structure\n fs.mkdirSync(path.join(skillDir, 'references'), { recursive: true });\n fs.mkdirSync(path.join(skillDir, 'scripts'), { recursive: true });\n\n // SKILL.md (Agent Skills Specification format)\n const tagsYaml = tags.length > 0\n ? `tags:\\n${tags.map((t: string) => ` - ${t}`).join('\\n')}`\n : 'tags: []';\n\n fs.writeFileSync(path.join(skillDir, 'SKILL.md'), `---\nname: ${name}\ndescription: ${description}\nversion: 1.0.0\n${tagsYaml}\n---\n\n# ${name.split('-').map((w: string) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')}\n\n${description}\n\n## Instructions\n\n<!-- Add instructions for how the agent should use this skill -->\n\n1. Step one\n2. Step two\n3. Step three\n\n## References\n\nSee \\`references/\\` for supporting documentation.\n\n## Scripts\n\nSee \\`scripts/\\` for executable scripts the agent can run.\n\n## Guidelines\n\n- Guideline one\n- Guideline two\n`);\n\n // Placeholder reference\n fs.writeFileSync(path.join(skillDir, 'references', 'README.md'),\n `# References for ${name}\\n\\nAdd supporting documentation here.\\n`);\n\n // Placeholder script\n fs.writeFileSync(path.join(skillDir, 'scripts', 'example.ts'),\n `#!/usr/bin/env npx tsx\\n/**\\n * Example script for ${name}\\n */\\nconsole.log('Hello from ${name}!');\\n`);\n\n // Update lockfile\n const lock = readSkillsLock(skillsDir);\n lock.skills[name] = {\n name,\n version: '1.0.0',\n source: 'local',\n installedAt: new Date().toISOString(),\n };\n writeSkillsLock(skillsDir, lock);\n\n success(`Skill \"${name}\" created at ${skillDir}/`);\n info('Files created:');\n dim(` ${skillDir}/SKILL.md`);\n dim(` ${skillDir}/references/README.md`);\n dim(` ${skillDir}/scripts/example.ts`);\n console.log();\n info(`Edit ${colors.cyan}SKILL.md${colors.reset} to add instructions for your agent.`);\n info('The skill will be auto-discovered by the Mastra Workspace.');\n });\n\n // ─── skills info ──────────────────────────────────────────────────\n skills\n .command('info')\n .argument('<name>', 'Skill name')\n .description('Show detailed information about a skill')\n .action(async (name) => {\n // Check installed first\n const skillsDir = resolveSkillsDir();\n const skillDir = path.join(skillsDir, name);\n\n if (fs.existsSync(skillDir) && fs.existsSync(path.join(skillDir, 'SKILL.md'))) {\n const meta = readSkillMetadata(skillDir);\n const lock = readSkillsLock(skillsDir);\n const lockEntry = lock.skills[name];\n\n header(`Skill: ${meta?.name || name}`);\n details({\n Name: meta?.name || name,\n Description: meta?.description || '—',\n Version: meta?.version || '—',\n Tags: (meta?.tags || []).join(', ') || '—',\n Author: meta?.author || '—',\n Source: lockEntry?.source || 'local',\n 'Installed At': lockEntry?.installedAt || '—',\n Path: skillDir,\n });\n\n // List files\n dim(' Files:');\n const listFiles = (dir: string, prefix: string = '') => {\n const entries = fs.readdirSync(dir);\n for (const entry of entries) {\n const fullPath = path.join(dir, entry);\n const stat = fs.statSync(fullPath);\n if (stat.isDirectory()) {\n dim(` ${prefix}${entry}/`);\n listFiles(fullPath, prefix + ' ');\n } else {\n dim(` ${prefix}${entry}`);\n }\n }\n };\n listFiles(skillDir, ' ');\n console.log();\n\n // Show SKILL.md content\n const content = fs.readFileSync(path.join(skillDir, 'SKILL.md'), 'utf-8');\n const { content: body } = parseSkillMd(content);\n info('Instructions preview:');\n dim(body.trim().split('\\n').slice(0, 10).map((l: string) => ` ${l}`).join('\\n'));\n if (body.trim().split('\\n').length > 10) {\n dim(' ...');\n }\n return;\n }\n\n // Check registry\n const entry = findInRegistry(name);\n if (entry) {\n header(`Registry Skill: ${entry.name}`);\n details({\n Name: entry.name,\n Description: entry.description,\n Version: entry.version,\n Tags: entry.tags.join(', '),\n Author: entry.author,\n Source: entry.source,\n Status: 'Not installed',\n });\n info(`Install with: ${colors.cyan}agentforge skills install ${entry.name}${colors.reset}`);\n return;\n }\n\n error(`Skill \"${name}\" not found (installed or in registry).`);\n });\n\n // ─── Top-level alias: agentforge install <skill> ──────────────────\n program\n .command('install')\n .argument('<name>', 'Skill name to install')\n .option('--from <source>', 'Source: registry (default), github, local', 'registry')\n .description('Install a skill (alias for: agentforge skills install)')\n .action(async (name, opts) => {\n // Delegate to skills install\n const skillsCmd = skills.commands.find((c) => c.name() === 'install');\n if (skillsCmd) {\n await skillsCmd.parseAsync([name, ...(opts.from !== 'registry' ? ['--from', opts.from] : [])], { from: 'user' });\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, success, error, info, formatDate } from '../lib/display.js';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\nexport function registerCronCommand(program: Command) {\n const cron = program.command('cron').description('Manage cron jobs');\n\n cron\n .command('list')\n .option('--json', 'Output as JSON')\n .description('List all cron jobs')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('cronJobs:list' as any, {}), 'Failed to list cron jobs');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Cron Jobs');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No cron jobs. Create one with: agentforge cron create'); return; }\n table(items.map((c: any) => ({\n ID: c._id?.slice(-8) || 'N/A',\n Name: c.name,\n Schedule: c.schedule,\n Agent: c.agentId,\n Enabled: c.isEnabled ? '✔' : '✖',\n 'Last Run': c.lastRun ? formatDate(c.lastRun) : 'Never',\n 'Next Run': c.nextRun ? formatDate(c.nextRun) : 'N/A',\n })));\n });\n\n cron\n .command('create')\n .description('Create a new cron job (interactive)')\n .option('--name <name>', 'Job name')\n .option('--schedule <cron>', 'Cron expression')\n .option('--agent <id>', 'Agent ID')\n .option('--action <action>', 'Action to execute')\n .action(async (opts) => {\n const name = opts.name || await prompt('Job name: ');\n const schedule = opts.schedule || await prompt('Cron schedule (e.g., \"0 */5 * * * *\" for every 5 min): ');\n const agentId = opts.agent || await prompt('Agent ID: ');\n const action = opts.action || await prompt('Action (message to send to agent): ');\n\n if (!name || !schedule || !agentId || !action) {\n error('All fields are required.'); process.exit(1);\n }\n\n const client = await createClient();\n await safeCall(\n () => client.mutation('cronJobs:create' as any, { name, schedule, agentId, prompt: action }),\n 'Failed to create cron job'\n );\n success(`Cron job \"${name}\" created.`);\n });\n\n cron\n .command('delete')\n .argument('<id>', 'Cron job ID')\n .description('Delete a cron job')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('cronJobs:remove' as any, { id }), 'Failed to delete');\n success(`Cron job \"${id}\" deleted.`);\n });\n\n cron\n .command('enable')\n .argument('<id>', 'Cron job ID')\n .description('Enable a cron job')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('cronJobs:update' as any, { id, isEnabled: true }), 'Failed');\n success(`Cron job \"${id}\" enabled.`);\n });\n\n cron\n .command('disable')\n .argument('<id>', 'Cron job ID')\n .description('Disable a cron job')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('cronJobs:update' as any, { id, isEnabled: false }), 'Failed');\n success(`Cron job \"${id}\" disabled.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, details, success, error, info, formatDate } from '../lib/display.js';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\nexport function registerMcpCommand(program: Command) {\n const mcp = program.command('mcp').description('Manage MCP connections');\n\n mcp\n .command('list')\n .option('--json', 'Output as JSON')\n .description('List all MCP connections')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('mcpConnections:list' as any, {}), 'Failed to list connections');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('MCP Connections');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No connections. Add one with: agentforge mcp add'); return; }\n table(items.map((c: any) => ({\n ID: c._id?.slice(-8) || 'N/A',\n Name: c.name,\n Type: c.protocol,\n Endpoint: c.serverUrl,\n Connected: c.isConnected ? '✔' : '✖',\n Enabled: c.isEnabled ? '✔' : '✖',\n })));\n });\n\n mcp\n .command('add')\n .description('Add a new MCP connection (interactive)')\n .option('--name <name>', 'Connection name')\n .option('--type <type>', 'Connection type (stdio, sse, http)')\n .option('--endpoint <url>', 'Endpoint URL or command')\n .action(async (opts) => {\n const name = opts.name || await prompt('Connection name: ');\n const type = opts.type || await prompt('Type (stdio/sse/http): ');\n const endpoint = opts.endpoint || await prompt('Endpoint (URL or command): ');\n\n if (!name || !type || !endpoint) { error('All fields required.'); process.exit(1); }\n\n const client = await createClient();\n await safeCall(\n () => client.mutation('mcpConnections:create' as any, {\n name, serverUrl: endpoint, protocol: type,\n }),\n 'Failed to add connection'\n );\n success(`MCP connection \"${name}\" added.`);\n });\n\n mcp\n .command('remove')\n .argument('<id>', 'Connection ID')\n .description('Remove an MCP connection')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('mcpConnections:remove' as any, { id }), 'Failed');\n success(`Connection \"${id}\" removed.`);\n });\n\n mcp\n .command('test')\n .argument('<id>', 'Connection ID')\n .description('Test an MCP connection')\n .action(async (id) => {\n info(`Testing connection \"${id}\"...`);\n const client = await createClient();\n const conns = await safeCall(() => client.query('mcpConnections:list' as any, {}), 'Failed');\n const conn = (conns as any[]).find((c: any) => c._id === id || c._id?.endsWith(id));\n if (!conn) { error(`Connection \"${id}\" not found.`); process.exit(1); }\n\n // Simple connectivity test\n if (conn.protocol === 'http' || conn.protocol === 'sse') {\n try {\n const res = await fetch(conn.serverUrl, { method: 'HEAD', signal: AbortSignal.timeout(5000) });\n if (res.ok) {\n success(`Connection \"${conn.name}\" is reachable (HTTP ${res.status}).`);\n await client.mutation('mcpConnections:updateStatus' as any, { id: conn._id, isConnected: true });\n } else {\n error(`Connection \"${conn.name}\" returned HTTP ${res.status}.`);\n }\n } catch (e: any) {\n error(`Connection \"${conn.name}\" failed: ${e.message}`);\n }\n } else {\n info(`Connection type \"${conn.protocol}\" — manual verification required.`);\n info(`Endpoint: ${conn.serverUrl}`);\n }\n });\n\n mcp\n .command('enable')\n .argument('<id>', 'Connection ID')\n .description('Enable a connection')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('mcpConnections:update' as any, { id, isEnabled: true }), 'Failed');\n success(`Connection \"${id}\" enabled.`);\n });\n\n mcp\n .command('disable')\n .argument('<id>', 'Connection ID')\n .description('Disable a connection')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('mcpConnections:update' as any, { id, isEnabled: false }), 'Failed');\n success(`Connection \"${id}\" disabled.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, success, error, info, formatDate } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\n\nexport function registerFilesCommand(program: Command) {\n const files = program.command('files').description('Manage files');\n\n files\n .command('list')\n .argument('[folder]', 'Folder ID to list files from')\n .option('--json', 'Output as JSON')\n .description('List files')\n .action(async (folder, opts) => {\n const client = await createClient();\n const args = folder ? { folderId: folder } : {};\n const result = await safeCall(() => client.query('files:list' as any, args), 'Failed to list files');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Files');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No files. Upload one with: agentforge files upload <path>'); return; }\n table(items.map((f: any) => ({\n ID: f._id?.slice(-8) || 'N/A',\n Name: f.name,\n Type: f.mimeType,\n Size: formatSize(f.size),\n Folder: f.folderId || 'root',\n Uploaded: formatDate(f.uploadedAt),\n })));\n });\n\n files\n .command('upload')\n .argument('<filepath>', 'Path to file to upload')\n .option('--folder <id>', 'Folder ID to upload to')\n .option('--project <id>', 'Project ID to associate with')\n .description('Upload a file')\n .action(async (filepath, opts) => {\n const absPath = path.resolve(filepath);\n if (!fs.existsSync(absPath)) { error(`File not found: ${absPath}`); process.exit(1); }\n\n const stat = fs.statSync(absPath);\n const name = path.basename(absPath);\n const ext = path.extname(absPath).toLowerCase();\n const mimeTypes: Record<string, string> = {\n '.txt': 'text/plain', '.md': 'text/markdown', '.json': 'application/json',\n '.js': 'text/javascript', '.ts': 'text/typescript', '.py': 'text/x-python',\n '.pdf': 'application/pdf', '.png': 'image/png', '.jpg': 'image/jpeg',\n '.csv': 'text/csv', '.html': 'text/html', '.xml': 'text/xml',\n };\n const mimeType = mimeTypes[ext] || 'application/octet-stream';\n\n const client = await createClient();\n await safeCall(\n () => client.mutation('files:create' as any, {\n name, originalName: name, mimeType, size: stat.size,\n url: 'pending-upload',\n folderId: opts.folder, projectId: opts.project,\n }),\n 'Failed to upload file metadata'\n );\n success(`File \"${name}\" registered (${formatSize(stat.size)}, ${mimeType}).`);\n info('Note: File content storage requires Convex file storage or R2 integration.');\n });\n\n files\n .command('delete')\n .argument('<id>', 'File ID')\n .description('Delete a file')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('files:remove' as any, { id }), 'Failed to delete file');\n success(`File \"${id}\" deleted.`);\n });\n\n // Folders subcommand\n const folders = program.command('folders').description('Manage folders');\n\n folders\n .command('list')\n .option('--json', 'Output as JSON')\n .description('List all folders')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('folders:list' as any, {}), 'Failed to list folders');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Folders');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No folders. Create one with: agentforge folders create <name>'); return; }\n table(items.map((f: any) => ({\n ID: f._id?.slice(-8) || 'N/A',\n Name: f.name,\n Parent: f.parentId || 'root',\n Created: formatDate(f.createdAt),\n })));\n });\n\n folders\n .command('create')\n .argument('<name>', 'Folder name')\n .option('--parent <id>', 'Parent folder ID')\n .description('Create a folder')\n .action(async (name, opts) => {\n const client = await createClient();\n await safeCall(\n () => client.mutation('folders:create' as any, { name, parentId: opts.parent }),\n 'Failed to create folder'\n );\n success(`Folder \"${name}\" created.`);\n });\n\n folders\n .command('delete')\n .argument('<id>', 'Folder ID')\n .description('Delete a folder')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('folders:remove' as any, { id }), 'Failed to delete folder');\n success(`Folder \"${id}\" deleted.`);\n });\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, details, success, error, info, formatDate } from '../lib/display.js';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\nexport function registerProjectsCommand(program: Command) {\n const projects = program.command('projects').description('Manage projects and workspaces');\n\n projects\n .command('list')\n .option('--json', 'Output as JSON')\n .description('List all projects')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('projects:list' as any, {}), 'Failed to list projects');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Projects');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No projects. Create one with: agentforge projects create <name>'); return; }\n table(items.map((p: any) => ({\n ID: p._id?.slice(-8) || 'N/A',\n Name: p.name,\n Description: (p.description || '').slice(0, 40),\n Created: formatDate(p.createdAt),\n })));\n });\n\n projects\n .command('create')\n .argument('<name>', 'Project name')\n .option('-d, --description <desc>', 'Project description')\n .description('Create a new project')\n .action(async (name, opts) => {\n const description = opts.description || await prompt('Description (optional): ');\n const client = await createClient();\n await safeCall(\n () => client.mutation('projects:create' as any, { name, description: description || undefined }),\n 'Failed to create project'\n );\n success(`Project \"${name}\" created.`);\n });\n\n projects\n .command('inspect')\n .argument('<id>', 'Project ID')\n .description('Show project details')\n .action(async (id) => {\n const client = await createClient();\n const projects = await safeCall(() => client.query('projects:list' as any, {}), 'Failed');\n const project = (projects as any[]).find((p: any) => p._id === id || p._id?.endsWith(id));\n if (!project) { error(`Project \"${id}\" not found.`); process.exit(1); }\n header(`Project: ${project.name}`);\n details({\n ID: project._id,\n Name: project.name,\n Description: project.description || 'N/A',\n Created: formatDate(project.createdAt),\n Updated: formatDate(project.updatedAt),\n });\n });\n\n projects\n .command('delete')\n .argument('<id>', 'Project ID')\n .option('-f, --force', 'Skip confirmation')\n .description('Delete a project')\n .action(async (id, opts) => {\n if (!opts.force) {\n const confirm = await prompt(`Delete project \"${id}\"? (y/N): `);\n if (confirm.toLowerCase() !== 'y') { info('Cancelled.'); return; }\n }\n const client = await createClient();\n await safeCall(() => client.mutation('projects:remove' as any, { id }), 'Failed');\n success(`Project \"${id}\" deleted.`);\n });\n\n projects\n .command('switch')\n .argument('<id>', 'Project ID to switch to')\n .description('Set the active project')\n .action(async (id) => {\n const client = await createClient();\n // Verify project exists\n const projects = await safeCall(() => client.query('projects:list' as any, {}), 'Failed');\n const project = (projects as any[]).find((p: any) => p._id === id || p._id?.endsWith(id));\n if (!project) { error(`Project \"${id}\" not found.`); process.exit(1); }\n // Store active project in settings\n await safeCall(\n () => client.mutation('settings:set' as any, { userId: 'cli', key: 'activeProject', value: project._id }),\n 'Failed to switch project'\n );\n success(`Switched to project \"${project.name}\".`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, success, error, info, details, colors } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\nexport function registerConfigCommand(program: Command) {\n const config = program.command('config').description('Manage configuration');\n\n config\n .command('show')\n .description('Show current configuration')\n .action(async () => {\n header('Configuration');\n\n // Check local .env files\n const cwd = process.cwd();\n const envFiles = ['.env', '.env.local', '.env.production'];\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n console.log(` ${colors.cyan}${envFile}${colors.reset}`);\n const content = fs.readFileSync(envPath, 'utf-8');\n content.split('\\n').forEach((line) => {\n if (line.trim() && !line.startsWith('#')) {\n const [key, ...rest] = line.split('=');\n const value = rest.join('=').trim();\n const masked = key.toLowerCase().includes('key') || key.toLowerCase().includes('secret') || key.toLowerCase().includes('token')\n ? value.slice(0, 4) + '****' + value.slice(-4)\n : value;\n console.log(` ${colors.dim}${key.trim()}${colors.reset} = ${masked}`);\n }\n });\n console.log();\n }\n }\n\n // Check Convex config\n const convexDir = path.join(cwd, '.convex');\n if (fs.existsSync(convexDir)) {\n info('Convex: Configured');\n } else {\n info('Convex: Not configured (run `npx convex dev`)');\n }\n\n // Check skills directory\n const skillsDir = path.join(cwd, 'skills');\n if (fs.existsSync(skillsDir)) {\n const skills = fs.readdirSync(skillsDir).filter((d: string) => fs.statSync(path.join(skillsDir, d)).isDirectory());\n info(`Skills: ${skills.length} installed (${skills.join(', ')})`);\n } else {\n info('Skills: None installed');\n }\n });\n\n config\n .command('set')\n .argument('<key>', 'Configuration key')\n .argument('<value>', 'Configuration value')\n .option('--env <file>', 'Environment file to update', '.env.local')\n .description('Set a configuration value')\n .action(async (key, value, opts) => {\n const envPath = path.join(process.cwd(), opts.env);\n let content = '';\n if (fs.existsSync(envPath)) {\n content = fs.readFileSync(envPath, 'utf-8');\n }\n\n const lines = content.split('\\n');\n const idx = lines.findIndex((l) => l.startsWith(`${key}=`));\n if (idx >= 0) {\n lines[idx] = `${key}=${value}`;\n } else {\n lines.push(`${key}=${value}`);\n }\n\n fs.writeFileSync(envPath, lines.join('\\n'));\n success(`Set ${key} in ${opts.env}`);\n });\n\n config\n .command('get')\n .argument('<key>', 'Configuration key')\n .description('Get a configuration value')\n .action(async (key) => {\n const cwd = process.cwd();\n const envFiles = ['.env.local', '.env', '.env.production'];\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(new RegExp(`^${key}=(.+)$`, 'm'));\n if (match) {\n console.log(match[1].trim());\n return;\n }\n }\n }\n error(`Key \"${key}\" not found in any .env file.`);\n });\n\n config\n .command('init')\n .description('Initialize configuration for a new project')\n .action(async () => {\n header('Project Configuration');\n const convexUrl = await prompt('Convex URL (from `npx convex dev`): ');\n const provider = await prompt('LLM Provider (openai/openrouter/anthropic/google): ') || 'openai';\n const apiKey = await prompt(`${provider.toUpperCase()} API Key: `);\n\n const envContent = [\n `# AgentForge Configuration`,\n `CONVEX_URL=${convexUrl}`,\n ``,\n `# LLM Provider`,\n `LLM_PROVIDER=${provider}`,\n ];\n\n if (provider === 'openai') envContent.push(`OPENAI_API_KEY=${apiKey}`);\n else if (provider === 'openrouter') envContent.push(`OPENROUTER_API_KEY=${apiKey}`);\n else if (provider === 'anthropic') envContent.push(`ANTHROPIC_API_KEY=${apiKey}`);\n else if (provider === 'google') envContent.push(`GOOGLE_API_KEY=${apiKey}`);\n\n fs.writeFileSync(path.join(process.cwd(), '.env.local'), envContent.join('\\n') + '\\n');\n success('Configuration saved to .env.local');\n info('Run `npx convex dev` to start the Convex backend.');\n });\n\n config\n .command('provider')\n .argument('<provider>', 'LLM provider to configure (openai, openrouter, anthropic, google, xai)')\n .description('Configure an LLM provider')\n .action(async (provider) => {\n const keyNames: Record<string, string> = {\n openai: 'OPENAI_API_KEY',\n openrouter: 'OPENROUTER_API_KEY',\n anthropic: 'ANTHROPIC_API_KEY',\n google: 'GOOGLE_API_KEY',\n xai: 'XAI_API_KEY',\n };\n const keyName = keyNames[provider.toLowerCase()];\n if (!keyName) {\n error(`Unknown provider \"${provider}\". Supported: ${Object.keys(keyNames).join(', ')}`);\n process.exit(1);\n }\n const apiKey = await prompt(`${keyName}: `);\n if (!apiKey) { error('API key is required.'); process.exit(1); }\n\n const envPath = path.join(process.cwd(), '.env.local');\n let content = '';\n if (fs.existsSync(envPath)) content = fs.readFileSync(envPath, 'utf-8');\n\n const lines = content.split('\\n');\n const idx = lines.findIndex((l) => l.startsWith(`${keyName}=`));\n if (idx >= 0) lines[idx] = `${keyName}=${apiKey}`;\n else lines.push(`${keyName}=${apiKey}`);\n\n // Also set LLM_PROVIDER\n const provIdx = lines.findIndex((l) => l.startsWith('LLM_PROVIDER='));\n if (provIdx >= 0) lines[provIdx] = `LLM_PROVIDER=${provider}`;\n else lines.push(`LLM_PROVIDER=${provider}`);\n\n fs.writeFileSync(envPath, lines.join('\\n'));\n success(`Provider \"${provider}\" configured.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, success, error, info, dim, colors, formatDate } from '../lib/display.js';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\nfunction promptSecret(q: string): Promise<string> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n // Disable echo for secret input\n if (process.stdin.isTTY) {\n process.stdout.write(q);\n let input = '';\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.setEncoding('utf-8');\n const onData = (char: string) => {\n if (char === '\\n' || char === '\\r') {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdin.removeListener('data', onData);\n console.log();\n rl.close();\n resolve(input);\n } else if (char === '\\u0003') {\n process.exit();\n } else if (char === '\\u007F') {\n input = input.slice(0, -1);\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n process.stdout.write(q + '*'.repeat(input.length));\n } else {\n input += char;\n process.stdout.write('*');\n }\n };\n process.stdin.on('data', onData);\n } else {\n rl.question(q, (ans) => { rl.close(); resolve(ans.trim()); });\n }\n });\n}\n\nexport function registerVaultCommand(program: Command) {\n const vault = program.command('vault').description('Manage secrets securely');\n\n vault\n .command('list')\n .option('--json', 'Output as JSON')\n .description('List all stored secrets (values hidden)')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('vault:list' as any, {}), 'Failed to list secrets');\n if (opts.json) {\n const safe = ((result as any[]) || []).map((s: any) => ({ ...s, encryptedValue: undefined }));\n console.log(JSON.stringify(safe, null, 2));\n return;\n }\n header('Vault — Stored Secrets');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No secrets stored. Add one with: agentforge vault set <name> <value>'); return; }\n table(items.map((s: any) => ({\n Name: s.name,\n Category: s.category || 'general',\n Provider: s.provider || 'N/A',\n 'Last Updated': s.updatedAt ? formatDate(s.updatedAt) : 'Never',\n Created: formatDate(s.createdAt),\n })));\n });\n\n vault\n .command('set')\n .argument('<name>', 'Secret name (e.g., OPENAI_API_KEY)')\n .argument('[value]', 'Secret value (omit for secure prompt)')\n .option('--category <cat>', 'Category (api_key, token, secret, credential)', 'api_key')\n .option('--provider <provider>', 'Provider name (openai, anthropic, etc.)')\n .description('Store a secret securely')\n .action(async (name, value, opts) => {\n if (!value) {\n value = await promptSecret(`Enter value for ${name}: `);\n }\n if (!value) { error('Value is required.'); process.exit(1); }\n\n const client = await createClient();\n await safeCall(\n () => client.mutation('vault:store' as any, {\n name,\n value,\n category: opts.category,\n provider: opts.provider,\n }),\n 'Failed to store secret'\n );\n success(`Secret \"${name}\" stored securely.`);\n });\n\n vault\n .command('get')\n .argument('<name>', 'Secret name')\n .option('--reveal', 'Show the actual value (use with caution)')\n .description('Retrieve a secret')\n .action(async (name, opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('vault:list' as any, {}), 'Failed');\n const secret = ((result as any[]) || []).find((s: any) => s.name === name);\n if (!secret) { error(`Secret \"${name}\" not found.`); process.exit(1); }\n\n if (opts.reveal) {\n // Decrypted values are not accessible from the client (internal mutation only)\n info(`${name} = ${secret.maskedValue || '****'}`);\n dim(' Note: Full decryption is only available server-side for security.');\n } else {\n info(`${name} = ${secret.maskedValue || '****'}`);\n dim(' Use --reveal to attempt to show more details.');\n }\n });\n\n vault\n .command('delete')\n .argument('<name>', 'Secret name')\n .option('-f, --force', 'Skip confirmation')\n .description('Delete a secret')\n .action(async (name, opts) => {\n if (!opts.force) {\n const confirm = await prompt(`Delete secret \"${name}\"? This cannot be undone. (y/N): `);\n if (confirm.toLowerCase() !== 'y') { info('Cancelled.'); return; }\n }\n const client = await createClient();\n const result = await safeCall(() => client.query('vault:list' as any, {}), 'Failed');\n const secret = ((result as any[]) || []).find((s: any) => s.name === name);\n if (!secret) { error(`Secret \"${name}\" not found.`); process.exit(1); }\n await safeCall(() => client.mutation('vault:remove' as any, { id: secret._id }), 'Failed');\n success(`Secret \"${name}\" deleted.`);\n });\n\n vault\n .command('rotate')\n .argument('<name>', 'Secret name')\n .description('Rotate a secret (set a new value)')\n .action(async (name) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('vault:list' as any, {}), 'Failed');\n const secret = ((result as any[]) || []).find((s: any) => s.name === name);\n if (!secret) { error(`Secret \"${name}\" not found.`); process.exit(1); }\n\n const newValue = await promptSecret(`Enter new value for ${name}: `);\n if (!newValue) { error('Value is required.'); process.exit(1); }\n\n await safeCall(\n () => client.mutation('vault:update' as any, { id: secret._id, value: newValue }),\n 'Failed to rotate secret'\n );\n success(`Secret \"${name}\" rotated.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient } from '../lib/convex-client.js';\nimport { header, success, error, info, dim, table } from '../lib/display.js';\n\nfunction safeCall<T>(fn: () => Promise<T>, msg: string): Promise<T> {\n return fn().catch((e: any) => { error(`${msg}: ${e.message}`); process.exit(1); });\n}\n\nfunction formatDate(ts: number): string {\n return new Date(ts).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });\n}\n\nfunction maskKey(key: string): string {\n if (key.length <= 12) return key.substring(0, 4) + '****';\n return key.substring(0, 8) + '...' + key.substring(key.length - 4);\n}\n\nfunction promptSecret(question: string): Promise<string> {\n return new Promise((resolve) => {\n const readline = require('readline');\n if (process.stdin.isTTY) {\n process.stdout.write(question);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.setEncoding('utf8');\n let input = '';\n const onData = (char: string) => {\n if (char === '\\n' || char === '\\r' || char === '\\u0004') {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdin.removeListener('data', onData);\n process.stdout.write('\\n');\n resolve(input);\n } else if (char === '\\u0003') {\n process.exit(0);\n } else if (char === '\\u007f' || char === '\\b') {\n if (input.length > 0) {\n input = input.slice(0, -1);\n process.stdout.write('\\b \\b');\n }\n } else {\n input += char;\n process.stdout.write('*');\n }\n };\n process.stdin.on('data', onData);\n } else {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n rl.question(question, (ans: string) => { rl.close(); resolve(ans.trim()); });\n }\n });\n}\n\nconst PROVIDERS = [\n { id: 'openai', name: 'OpenAI', prefix: 'sk-' },\n { id: 'anthropic', name: 'Anthropic', prefix: 'sk-ant-' },\n { id: 'openrouter', name: 'OpenRouter', prefix: 'sk-or-' },\n { id: 'google', name: 'Google AI', prefix: 'AIza' },\n { id: 'xai', name: 'xAI', prefix: 'xai-' },\n { id: 'groq', name: 'Groq', prefix: 'gsk_' },\n { id: 'together', name: 'Together AI', prefix: '' },\n { id: 'perplexity', name: 'Perplexity', prefix: 'pplx-' },\n];\n\nexport function registerKeysCommand(program: Command) {\n const keys = program.command('keys').description('Manage AI provider API keys');\n\n keys\n .command('list')\n .option('--provider <provider>', 'Filter by provider')\n .option('--json', 'Output as JSON')\n .description('List all configured API keys')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(\n () => client.query('apiKeys:list' as any, opts.provider ? { provider: opts.provider } : {}),\n 'Failed to list API keys'\n );\n\n const items = (result as any[]) || [];\n\n if (opts.json) {\n const safe = items.map((k: any) => ({ ...k, encryptedKey: maskKey(k.encryptedKey) }));\n console.log(JSON.stringify(safe, null, 2));\n return;\n }\n\n header('API Keys');\n\n if (items.length === 0) {\n info('No API keys configured.');\n dim(' Add one with: agentforge keys add <provider> [key]');\n dim('');\n dim(' Supported providers:');\n PROVIDERS.forEach(p => dim(` ${p.id.padEnd(12)} ${p.name}`));\n return;\n }\n\n table(items.map((k: any) => ({\n Provider: k.provider,\n Name: k.keyName,\n Key: maskKey(k.encryptedKey),\n Active: k.isActive ? '✓' : '✗',\n Created: formatDate(k.createdAt),\n 'Last Used': k.lastUsedAt ? formatDate(k.lastUsedAt) : 'Never',\n })));\n });\n\n keys\n .command('add')\n .argument('<provider>', `Provider (${PROVIDERS.map(p => p.id).join(', ')})`)\n .argument('[key]', 'API key value (omit for secure prompt)')\n .option('--name <name>', 'Key display name')\n .description('Add an AI provider API key')\n .action(async (provider, key, opts) => {\n const providerInfo = PROVIDERS.find(p => p.id === provider);\n if (!providerInfo) {\n error(`Unknown provider \"${provider}\". Supported: ${PROVIDERS.map(p => p.id).join(', ')}`);\n process.exit(1);\n }\n\n if (!key) {\n key = await promptSecret(`Enter ${providerInfo.name} API key: `);\n }\n if (!key) { error('API key is required.'); process.exit(1); }\n\n if (providerInfo.prefix && !key.startsWith(providerInfo.prefix)) {\n info(`Warning: ${providerInfo.name} keys typically start with \"${providerInfo.prefix}\".`);\n }\n\n const keyName = opts.name || `${providerInfo.name} Key`;\n const client = await createClient();\n await safeCall(\n () => client.mutation('apiKeys:create' as any, {\n provider,\n keyName,\n encryptedKey: key,\n }),\n 'Failed to store API key'\n );\n success(`${providerInfo.name} API key \"${keyName}\" stored successfully.`);\n });\n\n keys\n .command('remove')\n .argument('<provider>', 'Provider name')\n .option('-f, --force', 'Skip confirmation')\n .description('Remove an API key')\n .action(async (provider, opts) => {\n const client = await createClient();\n const result = await safeCall(\n () => client.query('apiKeys:list' as any, { provider }),\n 'Failed to list keys'\n );\n const items = (result as any[]) || [];\n if (items.length === 0) { error(`No API keys found for \"${provider}\".`); process.exit(1); }\n\n // If multiple keys, remove the first one (or we could add selection)\n const target = items[0];\n\n if (!opts.force) {\n const readline = require('readline');\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) => {\n rl.question(`Delete \"${target.keyName}\" for ${provider}? (y/N): `, (ans: string) => { rl.close(); resolve(ans.trim()); });\n });\n if (answer.toLowerCase() !== 'y') { info('Cancelled.'); return; }\n }\n\n await safeCall(\n () => client.mutation('apiKeys:remove' as any, { id: target._id }),\n 'Failed to remove API key'\n );\n success(`API key \"${target.keyName}\" removed.`);\n });\n\n keys\n .command('test')\n .argument('<provider>', 'Provider to test')\n .description('Test an API key by making a simple request')\n .action(async (provider) => {\n const client = await createClient();\n const result = await safeCall(\n () => client.query('apiKeys:getActiveForProvider' as any, { provider }),\n 'Failed to get key'\n );\n\n if (!result) { error(`No active API key for \"${provider}\". Add one with: agentforge keys add ${provider}`); process.exit(1); }\n\n const key = (result as any).encryptedKey;\n info(`Testing ${provider} API key...`);\n\n try {\n let ok = false;\n if (provider === 'openai') {\n const res = await fetch('https://api.openai.com/v1/models', { headers: { Authorization: `Bearer ${key}` } });\n ok = res.ok;\n } else if (provider === 'anthropic') {\n const res = await fetch('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: { 'x-api-key': key, 'anthropic-version': '2023-06-01', 'Content-Type': 'application/json' },\n body: JSON.stringify({ model: 'claude-3-haiku-20240307', max_tokens: 1, messages: [{ role: 'user', content: 'hi' }] }),\n });\n ok = res.ok;\n } else if (provider === 'openrouter') {\n const res = await fetch('https://openrouter.ai/api/v1/models', { headers: { Authorization: `Bearer ${key}` } });\n ok = res.ok;\n } else if (provider === 'google') {\n const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${key}`);\n ok = res.ok;\n } else if (provider === 'groq') {\n const res = await fetch('https://api.groq.com/openai/v1/models', { headers: { Authorization: `Bearer ${key}` } });\n ok = res.ok;\n } else {\n info(`No test endpoint configured for \"${provider}\". Key is stored.`);\n return;\n }\n\n if (ok) {\n success(`${provider} API key is valid and working.`);\n await safeCall(\n () => client.mutation('apiKeys:updateLastUsed' as any, { id: (result as any)._id }),\n 'Failed to update last used'\n );\n } else {\n error(`${provider} API key returned an error. Check that the key is valid.`);\n }\n } catch (e: any) {\n error(`Connection failed: ${e.message}`);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, details, success, error, info, dim, colors } from '../lib/display.js';\nimport { spawn } from 'node:child_process';\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport readline from 'node:readline';\n\nexport function registerStatusCommand(program: Command) {\n program\n .command('status')\n .description('Show system health and connection status')\n .action(async () => {\n header('AgentForge Status');\n\n const cwd = process.cwd();\n const checks: Record<string, string> = {};\n\n checks['Project Root'] = fs.existsSync(path.join(cwd, 'package.json')) ? '✔ Found' : '✖ Not found';\n checks['Convex Dir'] = fs.existsSync(path.join(cwd, 'convex')) ? '✔ Found' : '✖ Not found';\n checks['Skills Dir'] = fs.existsSync(path.join(cwd, 'skills')) ? '✔ Found' : '✖ Not configured';\n checks['Dashboard Dir'] = fs.existsSync(path.join(cwd, 'dashboard')) ? '✔ Found' : '✖ Not found';\n checks['Env Config'] = fs.existsSync(path.join(cwd, '.env.local')) || fs.existsSync(path.join(cwd, '.env'))\n ? '✔ Found' : '✖ Not found';\n\n // Check Convex connection\n try {\n const client = await createClient();\n const agents = await client.query('agents:list' as any, {});\n checks['Convex Connection'] = `✔ Connected (${(agents as any[])?.length || 0} agents)`;\n } catch {\n checks['Convex Connection'] = '✖ Not connected (run `npx convex dev`)';\n }\n\n // Check LLM provider\n const envFiles = ['.env.local', '.env'];\n let provider = 'Not configured';\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(/LLM_PROVIDER=(.+)/);\n if (match) { provider = match[1].trim(); break; }\n if (content.includes('OPENAI_API_KEY=')) { provider = 'openai'; break; }\n if (content.includes('OPENROUTER_API_KEY=')) { provider = 'openrouter'; break; }\n }\n }\n checks['LLM Provider'] = provider !== 'Not configured' ? `✔ ${provider}` : '✖ Not configured';\n\n details(checks);\n });\n\n program\n .command('dashboard')\n .description('Launch the web dashboard')\n .option('-p, --port <port>', 'Port for the dashboard', '3000')\n .option('--install', 'Install dashboard dependencies before starting')\n .action(async (opts) => {\n const cwd = process.cwd();\n\n // Search for the dashboard in multiple locations (in priority order)\n const searchPaths = [\n path.join(cwd, 'dashboard'), // 1. Bundled in project (agentforge create)\n path.join(cwd, 'packages', 'web'), // 2. Monorepo structure\n path.join(cwd, 'node_modules', '@agentforge-ai', 'web'), // 3. Installed as dependency\n ];\n\n let dashDir = '';\n for (const p of searchPaths) {\n if (fs.existsSync(path.join(p, 'package.json'))) {\n dashDir = p;\n break;\n }\n }\n\n if (!dashDir) {\n error('Dashboard not found!');\n console.log();\n info('The dashboard should be in your project\\'s ./dashboard/ directory.');\n info('If you created this project with an older version of AgentForge,');\n info('you can add it manually:');\n console.log();\n console.log(` ${colors.cyan}# Option 1: Recreate the project${colors.reset}`);\n console.log(` agentforge create my-project`);\n console.log();\n console.log(` ${colors.cyan}# Option 2: Clone the dashboard from the repo${colors.reset}`);\n console.log(` git clone https://github.com/Agentic-Engineering-Agency/agentforge /tmp/af`);\n console.log(` cp -r /tmp/af/packages/web ./dashboard`);\n console.log(` cd dashboard && pnpm install`);\n console.log();\n return;\n }\n\n // Check if node_modules exists, if not install\n const nodeModulesExists = fs.existsSync(path.join(dashDir, 'node_modules'));\n if (!nodeModulesExists || opts.install) {\n header('AgentForge Dashboard — Installing Dependencies');\n info(`Installing in ${path.relative(cwd, dashDir) || '.'}...`);\n console.log();\n\n const installChild = spawn('pnpm', ['install'], {\n cwd: dashDir,\n stdio: 'inherit',\n shell: true,\n });\n\n await new Promise<void>((resolve, reject) => {\n installChild.on('close', (code) => {\n if (code === 0) resolve();\n else reject(new Error(`pnpm install exited with code ${code}`));\n });\n installChild.on('error', reject);\n });\n\n console.log();\n success('Dependencies installed.');\n console.log();\n }\n\n // Read the Convex URL from .env.local and inject it into the dashboard\n const envPath = path.join(cwd, '.env.local');\n if (fs.existsSync(envPath)) {\n const envContent = fs.readFileSync(envPath, 'utf-8');\n const convexUrlMatch = envContent.match(/CONVEX_URL=(.+)/);\n if (convexUrlMatch) {\n const dashEnvPath = path.join(dashDir, '.env.local');\n const dashEnvContent = `VITE_CONVEX_URL=${convexUrlMatch[1].trim()}\\n`;\n fs.writeFileSync(dashEnvPath, dashEnvContent);\n }\n }\n\n header('AgentForge Dashboard');\n info(`Starting dashboard on port ${opts.port}...`);\n info(`Open ${colors.cyan}http://localhost:${opts.port}${colors.reset} in your browser.`);\n console.log();\n\n const child = spawn('pnpm', ['dev', '--port', opts.port], {\n cwd: dashDir,\n stdio: 'inherit',\n shell: true,\n });\n\n child.on('error', (err) => {\n error(`Failed to start dashboard: ${err.message}`);\n });\n });\n\n program\n .command('logs')\n .description('Show recent activity logs')\n .option('-n, --lines <count>', 'Number of log entries', '20')\n .option('--agent <id>', 'Filter by agent ID')\n .option('--json', 'Output as JSON')\n .action(async (opts) => {\n const client = await createClient();\n const args: Record<string, any> = {};\n if (opts.agent) args.agentId = opts.agent;\n\n const result = await safeCall(\n () => client.query('usage:list' as any, args),\n 'Failed to fetch logs'\n );\n\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Activity Logs');\n const items = ((result as any[]) || []).slice(0, parseInt(opts.lines));\n if (items.length === 0) { info('No activity logs found.'); return; }\n\n items.forEach((log: any) => {\n const time = new Date(log.timestamp || log.createdAt).toLocaleString();\n const agent = log.agentId || 'system';\n const action = log.action || log.type || 'unknown';\n const tokens = log.tokensUsed ? `${log.tokensUsed} tokens` : '';\n console.log(` ${colors.dim}${time}${colors.reset} ${colors.cyan}${agent}${colors.reset} ${action} ${tokens}`);\n });\n console.log();\n });\n\n program\n .command('heartbeat')\n .description('Check and resume pending agent tasks')\n .option('--agent <id>', 'Check specific agent')\n .action(async (opts) => {\n const client = await createClient();\n header('Heartbeat Check');\n\n const args: Record<string, any> = {};\n if (opts.agent) args.agentId = opts.agent;\n\n const result = await safeCall(\n () => client.query('heartbeat:listActive' as any, args),\n 'Failed to check heartbeat'\n );\n\n const items = (result as any[]) || [];\n if (items.length === 0) {\n success('All tasks complete. No pending work.');\n return;\n }\n\n info(`Found ${items.length} active heartbeat(s):`);\n items.forEach((task: any, i: number) => {\n console.log(` ${colors.yellow}${i + 1}.${colors.reset} [${task.agentId}] ${task.currentTask || 'No current task'}`);\n console.log(` ${colors.dim}Status: ${task.status} | Pending: ${(task.pendingTasks || []).length} task(s)${colors.reset}`);\n });\n console.log();\n\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((r) => rl.question('Reset stalled heartbeats? (y/N): ', (a) => { rl.close(); r(a.trim()); }));\n if (answer.toLowerCase() === 'y') {\n for (const task of items) {\n info(`Resetting heartbeat for agent \"${task.agentId}\"...`);\n await safeCall(\n () => client.mutation('heartbeat:updateStatus' as any, { agentId: task.agentId, status: 'active', currentTask: undefined }),\n 'Failed to reset heartbeat'\n );\n }\n success('All heartbeats reset.');\n }\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport prompts from 'prompts';\nimport { execSync } from 'node:child_process';\nimport {\n readCredentials,\n writeCredentials,\n deleteCredentials,\n isAuthenticated,\n getCredentialsPath,\n getCloudUrl,\n} from '../lib/credentials.js';\nimport { CloudClient, CloudClientError } from '../lib/cloud-client.js';\nimport { header, success, error, info, details } from '../lib/display.js';\n\n/**\n * Register login, logout, and whoami commands\n */\nexport function registerLoginCommand(program: Command) {\n // Login command\n program\n .command('login')\n .description('Authenticate with AgentForge Cloud')\n .option('--api-key <key>', 'API key for authentication (skips browser flow)')\n .option('--cloud-url <url>', 'Custom AgentForge Cloud URL')\n .action(async (options) => {\n header('AgentForge Cloud Login');\n\n // Check if already logged in\n const existingCreds = await readCredentials();\n if (existingCreds?.apiKey) {\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: 'You are already logged in. Overwrite existing credentials?',\n initial: false,\n });\n\n if (!overwrite) {\n info('Login cancelled.');\n return;\n }\n }\n\n let apiKey: string;\n let cloudUrl: string;\n\n if (options.apiKey) {\n // Use provided API key\n apiKey = options.apiKey;\n cloudUrl = options.cloudUrl || process.env.AGENTFORGE_CLOUD_URL || 'https://cloud.agentforge.ai';\n } else {\n // Interactive login or browser OAuth\n const { method } = await prompts({\n type: 'select',\n name: 'method',\n message: 'How would you like to authenticate?',\n choices: [\n { title: 'Enter API key manually', value: 'api-key' },\n { title: 'Browser (OAuth - coming soon)', value: 'browser', disabled: true },\n ],\n });\n\n if (method === 'api-key') {\n const response = await prompts({\n type: 'password',\n name: 'key',\n message: 'Enter your AgentForge API key:',\n validate: (value) => value.length > 0 ? true : 'API key is required',\n });\n apiKey = response.key;\n } else {\n // Browser flow placeholder\n error('Browser authentication not yet implemented. Use --api-key flag.');\n process.exit(1);\n }\n\n cloudUrl = options.cloudUrl || process.env.AGENTFORGE_CLOUD_URL || 'https://cloud.agentforge.ai';\n }\n\n // Validate the API key\n const spinner = ora('Authenticating with AgentForge Cloud...').start();\n\n try {\n const client = new CloudClient(cloudUrl, apiKey);\n const user = await client.authenticate();\n\n // Store credentials\n await writeCredentials({\n apiKey,\n cloudUrl,\n userEmail: user.email,\n userName: user.name,\n });\n\n spinner.succeed('Authentication successful!');\n\n success(`Logged in as ${chalk.bold(user.email)}`);\n info(`Cloud URL: ${cloudUrl}`);\n info(`Credentials stored at: ${getCredentialsPath()}`);\n } catch (err: any) {\n spinner.fail('Authentication failed');\n\n if (err instanceof CloudClientError) {\n error(err.message);\n if (err.code === 'NETWORK_ERROR') {\n info('Check your internet connection and try again.');\n } else if (err.status === 401) {\n info('Your API key appears to be invalid. Please check and try again.');\n }\n } else {\n error(`Unexpected error: ${err.message || err}`);\n }\n\n process.exit(1);\n }\n });\n\n // Logout command\n program\n .command('logout')\n .description('Clear AgentForge Cloud credentials')\n .action(async () => {\n header('AgentForge Cloud Logout');\n\n const wasLoggedIn = await isAuthenticated();\n \n if (!wasLoggedIn) {\n info('You are not currently logged in.');\n return;\n }\n\n const { confirm } = await prompts({\n type: 'confirm',\n name: 'confirm',\n message: 'Are you sure you want to log out?',\n initial: true,\n });\n\n if (!confirm) {\n info('Logout cancelled.');\n return;\n }\n\n const deleted = await deleteCredentials();\n \n if (deleted) {\n success('Logged out successfully.');\n info('Your credentials have been removed.');\n } else {\n error('Failed to remove credentials.');\n process.exit(1);\n }\n });\n\n // Whoami command\n program\n .command('whoami')\n .description('Show current user information')\n .action(async () => {\n header('Current User');\n\n const creds = await readCredentials();\n const cloudUrl = await getCloudUrl();\n\n if (!creds?.apiKey) {\n info('You are not logged in.');\n info('Run \"agentforge login\" to authenticate.');\n return;\n }\n\n // Display stored info\n details({\n 'Cloud URL': cloudUrl,\n 'Email': creds.userEmail || 'Unknown',\n 'Name': creds.userName || 'Unknown',\n 'Credentials File': getCredentialsPath(),\n });\n\n // Try to validate with the server\n const spinner = ora('Validating session...').start();\n\n try {\n const client = new CloudClient(creds.cloudUrl, creds.apiKey);\n const user = await client.authenticate();\n\n spinner.succeed('Session is valid');\n success(`Authenticated as ${chalk.bold(user.email)}`);\n } catch (err: any) {\n spinner.fail('Session validation failed');\n\n if (err instanceof CloudClientError && err.status === 401) {\n error('Your session has expired or the API key is invalid.');\n info('Run \"agentforge login\" to re-authenticate.');\n } else {\n error(`Error: ${err.message || err}`);\n info('Your credentials are stored but the server could not be reached.');\n }\n }\n });\n}\n","/**\n * CLI Command: agentforge channel:telegram\n *\n * Configure and start a Telegram bot that routes messages through\n * the AgentForge agent execution pipeline.\n *\n * Usage:\n * agentforge channel:telegram start --agent <id> [--token <bot-token>]\n * agentforge channel:telegram configure\n * agentforge channel:telegram status\n */\n\nimport { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, success, error, info, dim, warn, details, colors } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\n/**\n * Read a value from .env files in the current directory.\n */\nfunction readEnvValue(key: string): string | undefined {\n const cwd = process.cwd();\n const envFiles = ['.env.local', '.env', '.env.production'];\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(new RegExp(`^${key}=(.+)$`, 'm'));\n if (match) return match[1].trim().replace(/[\"']/g, '');\n }\n }\n return undefined;\n}\n\n/**\n * Write a value to .env.local in the current directory.\n */\nfunction writeEnvValue(key: string, value: string, envFile: string = '.env.local'): void {\n const envPath = path.join(process.cwd(), envFile);\n let content = '';\n if (fs.existsSync(envPath)) {\n content = fs.readFileSync(envPath, 'utf-8');\n }\n\n const lines = content.split('\\n');\n const idx = lines.findIndex((l) => l.startsWith(`${key}=`));\n if (idx >= 0) {\n lines[idx] = `${key}=${value}`;\n } else {\n lines.push(`${key}=${value}`);\n }\n\n fs.writeFileSync(envPath, lines.join('\\n'));\n}\n\nexport function registerChannelTelegramCommand(program: Command) {\n const channel = program\n .command('channel:telegram')\n .description('Manage the Telegram messaging channel');\n\n // ─── Start ─────────────────────────────────────────────────────────\n channel\n .command('start')\n .description('Start the Telegram bot and begin routing messages to an agent')\n .option('-a, --agent <id>', 'Agent ID to route messages to')\n .option('-t, --token <token>', 'Telegram Bot Token (overrides .env)')\n .option('--webhook-url <url>', 'Use webhook mode with this URL')\n .option('--webhook-secret <secret>', 'Webhook verification secret')\n .option('--bot-username <username>', 'Bot username for @mention detection')\n .option('--polling-interval <ms>', 'Polling interval in milliseconds', '1000')\n .option('--log-level <level>', 'Log level: debug, info, warn, error', 'info')\n .option('--group-mention-only', 'Only respond to @mentions in groups', true)\n .action(async (opts) => {\n header('Telegram Channel');\n\n // Resolve bot token\n const botToken = opts.token || readEnvValue('TELEGRAM_BOT_TOKEN') || process.env.TELEGRAM_BOT_TOKEN;\n if (!botToken) {\n error('Telegram Bot Token not found.');\n info('Set it with: agentforge channel:telegram configure');\n info('Or pass it with: --token <bot-token>');\n info('Or set TELEGRAM_BOT_TOKEN in your .env.local file');\n process.exit(1);\n }\n\n // Resolve Convex URL\n const convexUrl = readEnvValue('CONVEX_URL') || process.env.CONVEX_URL;\n if (!convexUrl) {\n error('CONVEX_URL not found. Run `npx convex dev` first.');\n process.exit(1);\n }\n\n // Resolve agent ID\n let agentId = opts.agent;\n if (!agentId) {\n // Try to get from env\n agentId = readEnvValue('AGENTFORGE_AGENT_ID') || process.env.AGENTFORGE_AGENT_ID;\n }\n\n if (!agentId) {\n // List agents and let user pick\n info('No agent specified. Fetching available agents...');\n const client = await createClient();\n const agents = await safeCall(\n () => client.query('agents:list' as any, {}),\n 'Failed to list agents'\n );\n\n if (!agents || (agents as any[]).length === 0) {\n error('No agents found. Create one first: agentforge agents create');\n process.exit(1);\n }\n\n console.log();\n (agents as any[]).forEach((a: any, i: number) => {\n console.log(\n ` ${colors.cyan}${i + 1}.${colors.reset} ${a.name} ${colors.dim}(${a.id})${colors.reset} — ${a.model}`\n );\n });\n console.log();\n\n const choice = await prompt('Select agent (number or ID): ');\n const idx = parseInt(choice) - 1;\n agentId = idx >= 0 && idx < (agents as any[]).length\n ? (agents as any[])[idx].id\n : choice;\n }\n\n // Display configuration\n info(`Agent: ${agentId}`);\n info(`Convex: ${convexUrl}`);\n info(`Mode: ${opts.webhookUrl ? 'Webhook' : 'Long-polling'}`);\n info(`Log: ${opts.logLevel}`);\n console.log();\n\n // Dynamically import the TelegramChannel from core\n // We use dynamic import because the core package may not be installed\n // in all environments, and we want to give a helpful error message.\n let TelegramChannel: any;\n try {\n // Use string variable to avoid TS2307 — this is a dynamic import for an optional peer\n const corePkg = '@agentforge-ai/core/channels/telegram';\n const mod = await import(/* @vite-ignore */ corePkg);\n TelegramChannel = mod.TelegramChannel;\n } catch (importError: any) {\n // Fallback: try to use the Convex HTTP API directly with a minimal implementation\n error('Could not import @agentforge-ai/core. Using built-in Telegram runner.');\n dim(` Error: ${importError.message}`);\n console.log();\n\n // Use the built-in minimal runner\n await runMinimalTelegramBot({\n botToken,\n agentId,\n convexUrl,\n logLevel: opts.logLevel,\n pollingIntervalMs: parseInt(opts.pollingInterval),\n });\n return;\n }\n\n // Start the Telegram channel\n try {\n const channel = new TelegramChannel({\n botToken,\n agentId,\n convexUrl,\n useWebhook: !!opts.webhookUrl,\n webhookUrl: opts.webhookUrl,\n webhookSecret: opts.webhookSecret,\n botUsername: opts.botUsername,\n groupMentionOnly: opts.groupMentionOnly,\n pollingIntervalMs: parseInt(opts.pollingInterval),\n logLevel: opts.logLevel,\n });\n\n await channel.start();\n success('Telegram bot is running!');\n dim(' Press Ctrl+C to stop.');\n\n // Keep the process alive\n await new Promise(() => {});\n } catch (startError: any) {\n error(`Failed to start Telegram bot: ${startError.message}`);\n process.exit(1);\n }\n });\n\n // ─── Configure ─────────────────────────────────────────────────────\n channel\n .command('configure')\n .description('Configure the Telegram bot token and settings')\n .action(async () => {\n header('Configure Telegram Channel');\n\n const currentToken = readEnvValue('TELEGRAM_BOT_TOKEN');\n if (currentToken) {\n const masked = currentToken.slice(0, 6) + '****' + currentToken.slice(-4);\n info(`Current token: ${masked}`);\n }\n\n console.log();\n info('To get a bot token:');\n dim(' 1. Open Telegram and search for @BotFather');\n dim(' 2. Send /newbot and follow the instructions');\n dim(' 3. Copy the token provided');\n console.log();\n\n const token = await prompt('Telegram Bot Token: ');\n if (!token) {\n error('Bot token is required.');\n process.exit(1);\n }\n\n // Validate the token by calling getMe\n info('Validating token...');\n try {\n const response = await fetch(`https://api.telegram.org/bot${token}/getMe`);\n const data = await response.json() as { ok: boolean; result?: { username: string; first_name: string } };\n if (!data.ok) {\n error('Invalid bot token. Please check and try again.');\n process.exit(1);\n }\n success(`Bot verified: @${data.result?.username} (${data.result?.first_name})`);\n\n // Save bot username too\n if (data.result?.username) {\n writeEnvValue('TELEGRAM_BOT_USERNAME', data.result.username);\n }\n } catch (fetchError: any) {\n warn(`Could not validate token (network error): ${fetchError.message}`);\n info('Saving token anyway. You can validate later with: agentforge channel:telegram status');\n }\n\n writeEnvValue('TELEGRAM_BOT_TOKEN', token);\n success('Token saved to .env.local');\n\n // Ask for default agent\n console.log();\n const defaultAgent = await prompt('Default agent ID (optional, press Enter to skip): ');\n if (defaultAgent) {\n writeEnvValue('AGENTFORGE_AGENT_ID', defaultAgent);\n success(`Default agent set to: ${defaultAgent}`);\n }\n\n console.log();\n success('Configuration complete!');\n info('Start the bot with: agentforge channel:telegram start');\n });\n\n // ─── Status ────────────────────────────────────────────────────────\n channel\n .command('status')\n .description('Check the Telegram bot configuration and connectivity')\n .action(async () => {\n header('Telegram Channel Status');\n\n const token = readEnvValue('TELEGRAM_BOT_TOKEN');\n const agentId = readEnvValue('AGENTFORGE_AGENT_ID');\n const convexUrl = readEnvValue('CONVEX_URL');\n const botUsername = readEnvValue('TELEGRAM_BOT_USERNAME');\n\n const statusData: Record<string, string> = {\n 'Bot Token': token ? `${token.slice(0, 6)}****${token.slice(-4)}` : `${colors.red}Not configured${colors.reset}`,\n 'Bot Username': botUsername ? `@${botUsername}` : `${colors.dim}Unknown${colors.reset}`,\n 'Default Agent': agentId || `${colors.dim}Not set${colors.reset}`,\n 'Convex URL': convexUrl || `${colors.red}Not configured${colors.reset}`,\n };\n\n details(statusData);\n\n // Validate token if present\n if (token) {\n info('Checking bot connectivity...');\n try {\n const response = await fetch(`https://api.telegram.org/bot${token}/getMe`);\n const data = await response.json() as { ok: boolean; result?: { username: string; first_name: string; id: number } };\n if (data.ok) {\n success(`Bot online: @${data.result?.username} (ID: ${data.result?.id})`);\n } else {\n error('Bot token is invalid or expired.');\n }\n } catch {\n warn('Could not reach Telegram API (network error).');\n }\n }\n\n // Check Convex connectivity\n if (convexUrl) {\n info('Checking Convex connectivity...');\n try {\n const client = await createClient();\n const agents = await client.query('agents:list' as any, {});\n success(`Convex connected. ${(agents as any[]).length} agents available.`);\n } catch {\n warn('Could not reach Convex deployment.');\n }\n }\n });\n}\n\n// =====================================================\n// Minimal Built-in Telegram Bot Runner\n// =====================================================\n\n/**\n * A minimal Telegram bot runner that works without the @agentforge-ai/core\n * package. Uses the Telegram Bot API and Convex HTTP API directly.\n *\n * This is a fallback for when the core package isn't available\n * (e.g., in a fresh project before building).\n */\nasync function runMinimalTelegramBot(config: {\n botToken: string;\n agentId: string;\n convexUrl: string;\n logLevel?: string;\n pollingIntervalMs?: number;\n}): Promise<void> {\n const { botToken, agentId, convexUrl } = config;\n const apiBase = `https://api.telegram.org/bot${botToken}`;\n const convexBase = convexUrl.replace(/\\/$/, '');\n const threadMap = new Map<string, string>();\n let lastUpdateId = 0;\n\n // Verify bot\n info('Verifying bot token...');\n const meRes = await fetch(`${apiBase}/getMe`);\n const meData = await meRes.json() as { ok: boolean; result?: { username: string } };\n if (!meData.ok) {\n error('Invalid bot token.');\n process.exit(1);\n }\n success(`Bot connected: @${meData.result?.username}`);\n\n // Delete any existing webhook\n await fetch(`${apiBase}/deleteWebhook`, { method: 'POST' });\n\n info('Polling for messages...');\n dim(' Press Ctrl+C to stop.');\n console.log();\n\n // Graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\nStopping...');\n process.exit(0);\n });\n\n // Convex HTTP helpers\n async function convexMutation(fn: string, args: Record<string, unknown>): Promise<unknown> {\n const res = await fetch(`${convexBase}/api/mutation`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: fn, args }),\n });\n const data = await res.json() as { value?: unknown; status?: string; errorMessage?: string };\n if (data.status === 'error') throw new Error(data.errorMessage);\n return data.value;\n }\n\n async function convexAction(fn: string, args: Record<string, unknown>): Promise<unknown> {\n const res = await fetch(`${convexBase}/api/action`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: fn, args }),\n });\n const data = await res.json() as { value?: unknown; status?: string; errorMessage?: string };\n if (data.status === 'error') throw new Error(data.errorMessage);\n return data.value;\n }\n\n async function sendTelegramMessage(chatId: string, text: string): Promise<void> {\n await fetch(`${apiBase}/sendMessage`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ chat_id: chatId, text }),\n });\n }\n\n async function sendTyping(chatId: string): Promise<void> {\n await fetch(`${apiBase}/sendChatAction`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ chat_id: chatId, action: 'typing' }),\n }).catch(() => {});\n }\n\n async function getOrCreateThread(chatId: string, senderName?: string): Promise<string> {\n const cached = threadMap.get(chatId);\n if (cached) return cached;\n\n const threadId = await convexMutation('chat:createThread', {\n agentId,\n name: senderName ? `Telegram: ${senderName}` : `Telegram Chat ${chatId}`,\n userId: `telegram:${chatId}`,\n }) as string;\n\n threadMap.set(chatId, threadId);\n return threadId;\n }\n\n // Poll loop\n while (true) {\n try {\n const res = await fetch(`${apiBase}/getUpdates`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n offset: lastUpdateId + 1,\n timeout: 30,\n allowed_updates: ['message'],\n }),\n });\n\n const data = await res.json() as { ok: boolean; result?: any[] };\n if (!data.ok || !data.result) continue;\n\n for (const update of data.result) {\n lastUpdateId = update.update_id;\n const msg = update.message;\n if (!msg?.text) continue;\n\n const chatId = String(msg.chat.id);\n const senderName = msg.from?.first_name || 'User';\n const text = msg.text.trim();\n\n // Handle commands\n if (text === '/start') {\n threadMap.delete(chatId);\n await sendTelegramMessage(chatId, `👋 Welcome! I'm powered by AgentForge.\\n\\nSend me a message and I'll respond using AI.\\n\\nCommands:\\n/new — Start a new conversation\\n/help — Show help`);\n continue;\n }\n if (text === '/new') {\n threadMap.delete(chatId);\n await sendTelegramMessage(chatId, '🔄 New conversation started. Send me a message!');\n continue;\n }\n if (text === '/help') {\n await sendTelegramMessage(chatId, '🤖 AgentForge Telegram Bot\\n\\nJust send me a message and I\\'ll respond using AI.\\n\\nCommands:\\n/start — Reset and show welcome\\n/new — Start a fresh conversation\\n/help — Show this help');\n continue;\n }\n\n // Route to agent\n console.log(`[${senderName}] ${text}`);\n await sendTyping(chatId);\n\n try {\n const threadId = await getOrCreateThread(chatId, senderName);\n const result = await convexAction('chat:sendMessage', {\n agentId,\n threadId,\n content: text,\n userId: `telegram:${msg.from?.id || chatId}`,\n }) as { response: string };\n\n if (result?.response) {\n // Split long messages\n const response = result.response;\n if (response.length <= 4096) {\n await sendTelegramMessage(chatId, response);\n } else {\n const chunks = response.match(/.{1,4096}/gs) || [];\n for (const chunk of chunks) {\n await sendTelegramMessage(chatId, chunk);\n }\n }\n console.log(`[Agent] ${response.substring(0, 100)}${response.length > 100 ? '...' : ''}`);\n } else {\n await sendTelegramMessage(chatId, '🤔 I couldn\\'t generate a response. Please try again.');\n }\n } catch (routeError: any) {\n console.error(`Error: ${routeError.message}`);\n await sendTelegramMessage(chatId, '⚠️ Sorry, I encountered an error. Please try again.');\n }\n }\n } catch (pollError: any) {\n if (pollError.message?.includes('ECONNREFUSED') || pollError.message?.includes('fetch failed')) {\n warn('Network error. Retrying in 5s...');\n await new Promise((r) => setTimeout(r, 5000));\n } else {\n console.error(`Poll error: ${pollError.message}`);\n await new Promise((r) => setTimeout(r, 1000));\n }\n }\n }\n}\n","/**\n * CLI Command: agentforge channel:whatsapp\n *\n * Configure and start a WhatsApp webhook server that routes messages\n * through the AgentForge agent execution pipeline.\n *\n * Usage:\n * agentforge channel:whatsapp start --agent <id> [--access-token <token>]\n * agentforge channel:whatsapp configure\n * agentforge channel:whatsapp status\n */\n\nimport { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, success, error, info, dim, warn, details, colors } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\n/**\n * Read a value from .env files in the current directory.\n */\nfunction readEnvValue(key: string): string | undefined {\n const cwd = process.cwd();\n const envFiles = ['.env.local', '.env', '.env.production'];\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(new RegExp(`^${key}=(.+)$`, 'm'));\n if (match) return match[1].trim().replace(/[\"']/g, '');\n }\n }\n return undefined;\n}\n\n/**\n * Write a value to .env.local in the current directory.\n */\nfunction writeEnvValue(key: string, value: string, envFile: string = '.env.local'): void {\n const envPath = path.join(process.cwd(), envFile);\n let content = '';\n if (fs.existsSync(envPath)) {\n content = fs.readFileSync(envPath, 'utf-8');\n }\n\n const lines = content.split('\\n');\n const idx = lines.findIndex((l) => l.startsWith(`${key}=`));\n if (idx >= 0) {\n lines[idx] = `${key}=${value}`;\n } else {\n lines.push(`${key}=${value}`);\n }\n\n fs.writeFileSync(envPath, lines.join('\\n'));\n}\n\nexport function registerChannelWhatsAppCommand(program: Command) {\n const channel = program\n .command('channel:whatsapp')\n .description('Manage the WhatsApp messaging channel');\n\n // ─── Start ─────────────────────────────────────────────────────────\n channel\n .command('start')\n .description('Start the WhatsApp webhook server and begin routing messages to an agent')\n .option('-a, --agent <id>', 'Agent ID to route messages to')\n .option('--access-token <token>', 'WhatsApp Cloud API access token (overrides .env)')\n .option('--phone-number-id <id>', 'WhatsApp Business Phone Number ID (overrides .env)')\n .option('--verify-token <token>', 'Webhook verify token (overrides .env)')\n .option('--webhook-port <port>', 'Port for the webhook server', '3001')\n .option('--webhook-path <path>', 'Path for the webhook endpoint', '/webhook/whatsapp')\n .option('--api-version <version>', 'WhatsApp Cloud API version', 'v21.0')\n .option('--log-level <level>', 'Log level: debug, info, warn, error', 'info')\n .action(async (opts) => {\n header('WhatsApp Channel');\n\n // Resolve access token\n const accessToken = opts.accessToken || readEnvValue('WHATSAPP_ACCESS_TOKEN') || process.env.WHATSAPP_ACCESS_TOKEN;\n if (!accessToken) {\n error('WhatsApp Access Token not found.');\n info('Set it with: agentforge channel:whatsapp configure');\n info('Or pass it with: --access-token <token>');\n info('Or set WHATSAPP_ACCESS_TOKEN in your .env.local file');\n process.exit(1);\n }\n\n // Resolve phone number ID\n const phoneNumberId = opts.phoneNumberId || readEnvValue('WHATSAPP_PHONE_NUMBER_ID') || process.env.WHATSAPP_PHONE_NUMBER_ID;\n if (!phoneNumberId) {\n error('WhatsApp Phone Number ID not found.');\n info('Set it with: agentforge channel:whatsapp configure');\n info('Or pass it with: --phone-number-id <id>');\n info('Or set WHATSAPP_PHONE_NUMBER_ID in your .env.local file');\n process.exit(1);\n }\n\n // Resolve verify token\n const verifyToken = opts.verifyToken || readEnvValue('WHATSAPP_VERIFY_TOKEN') || process.env.WHATSAPP_VERIFY_TOKEN;\n if (!verifyToken) {\n error('WhatsApp Verify Token not found.');\n info('Set it with: agentforge channel:whatsapp configure');\n info('Or pass it with: --verify-token <token>');\n info('Or set WHATSAPP_VERIFY_TOKEN in your .env.local file');\n process.exit(1);\n }\n\n // Resolve Convex URL\n const convexUrl = readEnvValue('CONVEX_URL') || process.env.CONVEX_URL;\n if (!convexUrl) {\n error('CONVEX_URL not found. Run `npx convex dev` first.');\n process.exit(1);\n }\n\n // Resolve agent ID\n let agentId = opts.agent;\n if (!agentId) {\n agentId = readEnvValue('AGENTFORGE_AGENT_ID') || process.env.AGENTFORGE_AGENT_ID;\n }\n\n if (!agentId) {\n // List agents and let user pick\n info('No agent specified. Fetching available agents...');\n const client = await createClient();\n const agents = await safeCall(\n () => client.query('agents:list' as any, {}),\n 'Failed to list agents'\n );\n\n if (!agents || (agents as any[]).length === 0) {\n error('No agents found. Create one first: agentforge agents create');\n process.exit(1);\n }\n\n console.log();\n (agents as any[]).forEach((a: any, i: number) => {\n console.log(\n ` ${colors.cyan}${i + 1}.${colors.reset} ${a.name} ${colors.dim}(${a.id})${colors.reset} — ${a.model}`\n );\n });\n console.log();\n\n const choice = await prompt('Select agent (number or ID): ');\n const idx = parseInt(choice) - 1;\n agentId = idx >= 0 && idx < (agents as any[]).length\n ? (agents as any[])[idx].id\n : choice;\n }\n\n // Display configuration\n const webhookPort = parseInt(opts.webhookPort);\n const webhookPath = opts.webhookPath;\n info(`Agent: ${agentId}`);\n info(`Convex: ${convexUrl}`);\n info(`Webhook: http://localhost:${webhookPort}${webhookPath}`);\n info(`API Version: ${opts.apiVersion}`);\n info(`Log: ${opts.logLevel}`);\n console.log();\n\n // Dynamically import the WhatsAppChannel from core\n let WhatsAppChannel: any;\n try {\n const corePkg = '@agentforge-ai/core/channels/whatsapp';\n const mod = await import(/* @vite-ignore */ corePkg);\n WhatsAppChannel = mod.WhatsAppChannel;\n } catch (importError: any) {\n // Fallback: use the built-in minimal runner\n error('Could not import @agentforge-ai/core. Using built-in WhatsApp runner.');\n dim(` Error: ${importError.message}`);\n console.log();\n\n await runMinimalWhatsAppBot({\n accessToken,\n phoneNumberId,\n verifyToken,\n agentId,\n convexUrl,\n webhookPort,\n webhookPath,\n logLevel: opts.logLevel,\n });\n return;\n }\n\n // Start the WhatsApp channel\n try {\n const channel = new WhatsAppChannel({\n accessToken,\n phoneNumberId,\n verifyToken,\n agentId,\n convexUrl,\n webhookPort,\n webhookPath,\n apiVersion: opts.apiVersion,\n logLevel: opts.logLevel,\n });\n\n await channel.start();\n success('WhatsApp webhook server is running!');\n dim(` Webhook URL: http://localhost:${webhookPort}${webhookPath}`);\n dim(' Configure this URL in your Meta App Dashboard.');\n dim(' Press Ctrl+C to stop.');\n\n // Keep the process alive\n await new Promise(() => {});\n } catch (startError: any) {\n error(`Failed to start WhatsApp channel: ${startError.message}`);\n process.exit(1);\n }\n });\n\n // ─── Configure ─────────────────────────────────────────────────────\n channel\n .command('configure')\n .description('Configure the WhatsApp Cloud API credentials')\n .action(async () => {\n header('Configure WhatsApp Channel');\n\n console.log();\n info('To set up WhatsApp Cloud API:');\n dim(' 1. Go to https://developers.facebook.com/apps/');\n dim(' 2. Create or select a Meta App with WhatsApp product');\n dim(' 3. Go to WhatsApp > API Setup');\n dim(' 4. Copy the Access Token, Phone Number ID, and set a Verify Token');\n console.log();\n\n // Access Token\n const currentToken = readEnvValue('WHATSAPP_ACCESS_TOKEN');\n if (currentToken) {\n const masked = currentToken.slice(0, 10) + '****' + currentToken.slice(-4);\n info(`Current access token: ${masked}`);\n }\n\n const accessToken = await prompt('WhatsApp Access Token: ');\n if (!accessToken) {\n error('Access token is required.');\n process.exit(1);\n }\n\n // Validate the token\n info('Validating access token...');\n try {\n const response = await fetch('https://graph.facebook.com/v21.0/me', {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n const data = await response.json() as { id?: string; name?: string; error?: { message: string } };\n if (data.error) {\n warn(`Token validation warning: ${data.error.message}`);\n info('Saving token anyway. You can validate later with: agentforge channel:whatsapp status');\n } else {\n success(`Token verified: ${data.name || data.id}`);\n }\n } catch (fetchError: any) {\n warn(`Could not validate token (network error): ${fetchError.message}`);\n info('Saving token anyway.');\n }\n\n writeEnvValue('WHATSAPP_ACCESS_TOKEN', accessToken);\n success('Access token saved to .env.local');\n\n // Phone Number ID\n console.log();\n const currentPhoneId = readEnvValue('WHATSAPP_PHONE_NUMBER_ID');\n if (currentPhoneId) {\n info(`Current Phone Number ID: ${currentPhoneId}`);\n }\n\n const phoneNumberId = await prompt('WhatsApp Phone Number ID: ');\n if (!phoneNumberId) {\n error('Phone Number ID is required.');\n process.exit(1);\n }\n\n // Validate the phone number ID\n info('Validating phone number...');\n try {\n const response = await fetch(`https://graph.facebook.com/v21.0/${phoneNumberId}`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n const data = await response.json() as {\n display_phone_number?: string;\n verified_name?: string;\n error?: { message: string };\n };\n if (data.error) {\n warn(`Phone number validation warning: ${data.error.message}`);\n } else {\n success(`Phone number verified: ${data.display_phone_number} (${data.verified_name})`);\n }\n } catch {\n warn('Could not validate phone number (network error).');\n }\n\n writeEnvValue('WHATSAPP_PHONE_NUMBER_ID', phoneNumberId);\n success('Phone Number ID saved to .env.local');\n\n // Verify Token\n console.log();\n const currentVerifyToken = readEnvValue('WHATSAPP_VERIFY_TOKEN');\n if (currentVerifyToken) {\n info(`Current verify token: ${currentVerifyToken.slice(0, 6)}****`);\n }\n\n let verifyToken = await prompt('Webhook Verify Token (press Enter to auto-generate): ');\n if (!verifyToken) {\n // Auto-generate a verify token\n verifyToken = `agentforge_${Date.now()}_${Math.random().toString(36).substring(2, 10)}`;\n info(`Generated verify token: ${verifyToken}`);\n }\n\n writeEnvValue('WHATSAPP_VERIFY_TOKEN', verifyToken);\n success('Verify token saved to .env.local');\n\n // Default agent\n console.log();\n const defaultAgent = await prompt('Default agent ID (optional, press Enter to skip): ');\n if (defaultAgent) {\n writeEnvValue('AGENTFORGE_AGENT_ID', defaultAgent);\n success(`Default agent set to: ${defaultAgent}`);\n }\n\n console.log();\n success('Configuration complete!');\n info('Start the webhook server with: agentforge channel:whatsapp start');\n console.log();\n info('Next steps:');\n dim(' 1. Start the webhook server: agentforge channel:whatsapp start');\n dim(' 2. Expose the webhook URL (e.g., with ngrok or cloudflared)');\n dim(' 3. Configure the webhook URL in your Meta App Dashboard');\n dim(' 4. Subscribe to \"messages\" webhook field');\n });\n\n // ─── Status ────────────────────────────────────────────────────────\n channel\n .command('status')\n .description('Check the WhatsApp channel configuration and connectivity')\n .action(async () => {\n header('WhatsApp Channel Status');\n\n const accessToken = readEnvValue('WHATSAPP_ACCESS_TOKEN');\n const phoneNumberId = readEnvValue('WHATSAPP_PHONE_NUMBER_ID');\n const verifyToken = readEnvValue('WHATSAPP_VERIFY_TOKEN');\n const agentId = readEnvValue('AGENTFORGE_AGENT_ID');\n const convexUrl = readEnvValue('CONVEX_URL');\n\n const statusData: Record<string, string> = {\n 'Access Token': accessToken ? `${accessToken.slice(0, 10)}****${accessToken.slice(-4)}` : `${colors.red}Not configured${colors.reset}`,\n 'Phone Number ID': phoneNumberId || `${colors.red}Not configured${colors.reset}`,\n 'Verify Token': verifyToken ? `${verifyToken.slice(0, 6)}****` : `${colors.red}Not configured${colors.reset}`,\n 'Default Agent': agentId || `${colors.dim}Not set${colors.reset}`,\n 'Convex URL': convexUrl || `${colors.red}Not configured${colors.reset}`,\n };\n\n details(statusData);\n\n // Validate access token and phone number if present\n if (accessToken && phoneNumberId) {\n info('Checking WhatsApp Cloud API connectivity...');\n try {\n const response = await fetch(`https://graph.facebook.com/v21.0/${phoneNumberId}`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n const data = await response.json() as {\n display_phone_number?: string;\n verified_name?: string;\n id?: string;\n error?: { message: string };\n };\n if (data.error) {\n error(`API error: ${data.error.message}`);\n } else {\n success(`WhatsApp Business: ${data.verified_name || data.display_phone_number} (ID: ${data.id})`);\n }\n } catch {\n warn('Could not reach WhatsApp Cloud API (network error).');\n }\n }\n\n // Check Convex connectivity\n if (convexUrl) {\n info('Checking Convex connectivity...');\n try {\n const client = await createClient();\n const agents = await client.query('agents:list' as any, {});\n success(`Convex connected. ${(agents as any[]).length} agents available.`);\n } catch {\n warn('Could not reach Convex deployment.');\n }\n }\n });\n}\n\n// =====================================================\n// Minimal Built-in WhatsApp Bot Runner\n// =====================================================\n\n/**\n * A minimal WhatsApp webhook runner that works without the @agentforge-ai/core\n * package. Uses the WhatsApp Cloud API and Convex HTTP API directly.\n *\n * This is a fallback for when the core package isn't available.\n */\nasync function runMinimalWhatsAppBot(config: {\n accessToken: string;\n phoneNumberId: string;\n verifyToken: string;\n agentId: string;\n convexUrl: string;\n webhookPort: number;\n webhookPath: string;\n logLevel?: string;\n}): Promise<void> {\n const { accessToken, phoneNumberId, verifyToken, agentId, convexUrl, webhookPort, webhookPath } = config;\n const apiBase = `https://graph.facebook.com/v21.0`;\n const convexBase = convexUrl.replace(/\\/$/, '');\n const threadMap = new Map<string, string>();\n\n // Verify access token\n info('Verifying WhatsApp access token...');\n try {\n const res = await fetch(`${apiBase}/${phoneNumberId}`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n const data = await res.json() as { verified_name?: string; display_phone_number?: string; error?: { message: string } };\n if (data.error) {\n error(`API error: ${data.error.message}`);\n process.exit(1);\n }\n success(`WhatsApp Business: ${data.verified_name || data.display_phone_number}`);\n } catch (fetchError: any) {\n warn(`Could not verify token: ${fetchError.message}`);\n info('Continuing anyway...');\n }\n\n // Convex HTTP helpers\n async function convexMutation(fn: string, args: Record<string, unknown>): Promise<unknown> {\n const res = await fetch(`${convexBase}/api/mutation`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: fn, args }),\n });\n const data = await res.json() as { value?: unknown; status?: string; errorMessage?: string };\n if (data.status === 'error') throw new Error(data.errorMessage);\n return data.value;\n }\n\n async function convexAction(fn: string, args: Record<string, unknown>): Promise<unknown> {\n const res = await fetch(`${convexBase}/api/action`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: fn, args }),\n });\n const data = await res.json() as { value?: unknown; status?: string; errorMessage?: string };\n if (data.status === 'error') throw new Error(data.errorMessage);\n return data.value;\n }\n\n async function sendWhatsAppMessage(to: string, text: string): Promise<void> {\n await fetch(`${apiBase}/${phoneNumberId}/messages`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n messaging_product: 'whatsapp',\n to,\n type: 'text',\n text: { body: text },\n }),\n });\n }\n\n async function markAsRead(messageId: string): Promise<void> {\n await fetch(`${apiBase}/${phoneNumberId}/messages`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n messaging_product: 'whatsapp',\n status: 'read',\n message_id: messageId,\n }),\n }).catch(() => {});\n }\n\n async function getOrCreateThread(phoneNumber: string, senderName?: string): Promise<string> {\n const cached = threadMap.get(phoneNumber);\n if (cached) return cached;\n\n const threadId = await convexMutation('chat:createThread', {\n agentId,\n name: senderName ? `WhatsApp: ${senderName}` : `WhatsApp +${phoneNumber}`,\n userId: `whatsapp:${phoneNumber}`,\n }) as string;\n\n threadMap.set(phoneNumber, threadId);\n return threadId;\n }\n\n // Start HTTP server for webhook\n const http = await import('node:http');\n\n const server = http.createServer(async (req, res) => {\n const url = new URL(req.url || '/', `http://localhost:${webhookPort}`);\n\n if (url.pathname !== webhookPath) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n // GET — Webhook verification\n if (req.method === 'GET') {\n const mode = url.searchParams.get('hub.mode');\n const token = url.searchParams.get('hub.verify_token');\n const challenge = url.searchParams.get('hub.challenge');\n\n if (mode === 'subscribe' && token === verifyToken) {\n res.writeHead(200, { 'Content-Type': 'text/plain' });\n res.end(challenge);\n } else {\n res.writeHead(403);\n res.end('Forbidden');\n }\n return;\n }\n\n // POST — Incoming messages\n if (req.method === 'POST') {\n try {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk as Buffer);\n }\n const body = JSON.parse(Buffer.concat(chunks).toString());\n\n // Respond immediately to avoid timeout\n res.writeHead(200);\n res.end('OK');\n\n // Process messages\n if (body.object !== 'whatsapp_business_account') return;\n\n for (const entry of body.entry || []) {\n for (const change of entry.changes || []) {\n if (change.field !== 'messages') continue;\n\n const contacts = change.value.contacts || [];\n const messages = change.value.messages || [];\n\n for (const msg of messages) {\n if (msg.type !== 'text' || !msg.text?.body) continue;\n\n const from = msg.from;\n const text = msg.text.body.trim();\n const contact = contacts.find((c: any) => c.wa_id === from);\n const senderName = contact?.profile?.name || from;\n\n console.log(`[${senderName}] ${text}`);\n\n // Mark as read\n await markAsRead(msg.id);\n\n try {\n const threadId = await getOrCreateThread(from, senderName);\n const result = await convexAction('chat:sendMessage', {\n agentId,\n threadId,\n content: text,\n userId: `whatsapp:${from}`,\n }) as { response: string };\n\n if (result?.response) {\n const response = result.response;\n if (response.length <= 4096) {\n await sendWhatsAppMessage(from, response);\n } else {\n const chunks = response.match(/.{1,4096}/gs) || [];\n for (const chunk of chunks) {\n await sendWhatsAppMessage(from, chunk);\n }\n }\n console.log(`[Agent] ${response.substring(0, 100)}${response.length > 100 ? '...' : ''}`);\n } else {\n await sendWhatsAppMessage(from, \"🤔 I couldn't generate a response. Please try again.\");\n }\n } catch (routeError: any) {\n console.error(`Error: ${routeError.message}`);\n await sendWhatsAppMessage(from, '⚠️ Sorry, I encountered an error. Please try again.');\n }\n }\n }\n }\n } catch (parseError: any) {\n console.error(`Parse error: ${parseError.message}`);\n if (!res.headersSent) {\n res.writeHead(400);\n res.end('Bad Request');\n }\n }\n return;\n }\n\n res.writeHead(405);\n res.end('Method Not Allowed');\n });\n\n // Graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\nStopping...');\n server.close();\n process.exit(0);\n });\n\n server.listen(webhookPort, () => {\n success(`Webhook server listening on port ${webhookPort}`);\n info(`Webhook URL: http://localhost:${webhookPort}${webhookPath}`);\n console.log();\n info('Next steps:');\n dim(' 1. Expose this URL publicly (e.g., ngrok http ' + webhookPort + ')');\n dim(' 2. Configure the webhook URL in your Meta App Dashboard');\n dim(' 3. Subscribe to \"messages\" webhook field');\n dim(' Press Ctrl+C to stop.');\n });\n\n // Keep alive\n await new Promise(() => {});\n}\n"],"mappings":"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","names":["pkg","path","fs","path","execSync","fs","fs","path","error","path","error","fs","path","resolve","execSync","fs","path","error","resolve","program","readline","program","a","program","fs","path","readline","execSync","prompt","program","skills","entry","readline","prompt","program","readline","prompt","program","fs","path","program","readline","prompt","program","projects","fs","path","readline","prompt","program","readline","prompt","resolve","program","safeCall","formatDate","promptSecret","resolve","readline","program","spawn","path","fs","readline","program","resolve","chalk","ora","program","ora","chalk","fs","path","readline","prompt","program","channel","fs","path","readline","prompt","readEnvValue","writeEnvValue","program","channel","chunks","fileURLToPath","__filename","__dirname"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/create.ts","../src/commands/run.ts","../src/commands/deploy.ts","../src/lib/credentials.ts","../src/lib/cloud-client.ts","../src/lib/convex-client.ts","../src/lib/display.ts","../src/commands/agents.ts","../src/commands/chat.ts","../src/commands/sessions.ts","../src/commands/skills.ts","../src/commands/skill.ts","../src/commands/cron.ts","../src/commands/mcp.ts","../src/commands/files.ts","../src/commands/projects.ts","../src/commands/config.ts","../src/commands/vault.ts","../src/commands/keys.ts","../src/commands/status.ts","../src/commands/login.ts","../src/commands/channel-telegram.ts","../src/commands/channel-whatsapp.ts","../src/commands/channel-slack.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createProject } from './commands/create.js';\nimport { runProject } from './commands/run.js';\nimport { deployProject } from './commands/deploy.js';\nimport { registerAgentsCommand } from './commands/agents.js';\nimport { registerChatCommand } from './commands/chat.js';\nimport { registerSessionsCommand, registerThreadsCommand } from './commands/sessions.js';\nimport { registerSkillsCommand } from './commands/skills.js';\nimport { registerSkillCommand } from './commands/skill.js';\nimport { registerCronCommand } from './commands/cron.js';\nimport { registerMcpCommand } from './commands/mcp.js';\nimport { registerFilesCommand } from './commands/files.js';\nimport { registerProjectsCommand } from './commands/projects.js';\nimport { registerConfigCommand } from './commands/config.js';\nimport { registerVaultCommand } from './commands/vault.js';\nimport { registerKeysCommand } from './commands/keys.js';\nimport { registerStatusCommand } from './commands/status.js';\nimport { registerLoginCommand } from './commands/login.js';\nimport { registerChannelTelegramCommand } from './commands/channel-telegram.js';\nimport { registerChannelWhatsAppCommand } from './commands/channel-whatsapp.js';\nimport { registerChannelSlackCommand } from './commands/channel-slack.js';\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, resolve } from 'node:path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('agentforge')\n .description('AgentForge — NanoClaw: A minimalist agent framework powered by Mastra + Convex')\n .version(pkg.version);\n\n// ─── Project Lifecycle ───────────────────────────────────────────\nprogram\n .command('create')\n .argument('<project-name>', 'Name of the project to create')\n .description('Create a new AgentForge project')\n .option('-t, --template <template>', 'Project template to use', 'default')\n .action(async (projectName: string, options: { template: string }) => {\n await createProject(projectName, options);\n });\n\nprogram\n .command('run')\n .description('Start the local development environment')\n .option('-p, --port <port>', 'Port for the dev server', '3000')\n .option('-s, --sandbox <type>', 'Sandbox provider for agent execution (local, docker, e2b, none)', 'local')\n .action(async (options: { port: string; sandbox: string }) => {\n await runProject(options as import('./commands/run.js').RunOptions);\n });\n\nprogram\n .command('deploy')\n .description('Deploy the project to production')\n .option('--env <path>', 'Path to environment file', '.env.production')\n .option('--dry-run', 'Preview deployment without executing', false)\n .option('--rollback', 'Rollback to previous deployment', false)\n .option('--force', 'Skip confirmation prompts', false)\n .option('--provider <provider>', 'Deployment provider (convex or cloud)', 'convex')\n .option('--project <projectId>', 'Project ID for cloud deployments')\n .option('--version <tag>', 'Version tag for the deployment')\n .action(async (options: { \n env: string; \n dryRun: boolean; \n rollback: boolean; \n force: boolean;\n provider: 'convex' | 'cloud';\n project?: string;\n version?: string;\n }) => {\n await deployProject(options);\n });\n\n// ─── Cloud Authentication ────────────────────────────────────────\nregisterLoginCommand(program);\n\n// ─── Agent Management ────────────────────────────────────────────\nregisterAgentsCommand(program);\n\n// ─── Chat ────────────────────────────────────────────────────────\nregisterChatCommand(program);\n\n// ─── Sessions & Threads ──────────────────────────────────────────\nregisterSessionsCommand(program);\nregisterThreadsCommand(program);\n\n// ─── Skills ──────────────────────────────────────────────────────\nregisterSkillsCommand(program);\nregisterSkillCommand(program);\n\n// ─── Cron Jobs ───────────────────────────────────────────────────\nregisterCronCommand(program);\n\n// ─── MCP Connections ─────────────────────────────────────────────\nregisterMcpCommand(program);\n\n// ─── Files & Folders ─────────────────────────────────────────────\nregisterFilesCommand(program);\n\n// ─── Projects / Workspaces ───────────────────────────────────────\nregisterProjectsCommand(program);\n\n// ─── Configuration ───────────────────────────────────────────────\nregisterConfigCommand(program);\n\n// ─── Vault (Secrets) ─────────────────────────────────────────────\nregisterVaultCommand(program);\n\n// ─── AI Provider Keys ────────────────────────────────────────────\nregisterKeysCommand(program);\n\n// ─── Channels ───────────────────────────────────────────────────\nregisterChannelTelegramCommand(program);\nregisterChannelWhatsAppCommand(program);\nregisterChannelSlackCommand(program);\n\n// ─── Status, Dashboard, Logs, Heartbeat ──────────────────────────\nregisterStatusCommand(program);\n\nprogram.parse();\n","import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport fs from 'fs-extra';\nimport { execSync } from 'node:child_process';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Options for the create command.\n */\nexport interface CreateOptions {\n /** The project template to use. */\n template: string;\n}\n\n/**\n * Creates a new AgentForge project from a template.\n *\n * @param projectName - The name of the project to create.\n * @param options - Options for the create command.\n */\nexport async function createProject(\n projectName: string,\n options: CreateOptions\n): Promise<void> {\n const targetDir = path.resolve(process.cwd(), projectName);\n\n // Check if directory already exists\n if (await fs.pathExists(targetDir)) {\n console.error(`Error: Directory \"${projectName}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n🔨 Creating AgentForge project: ${projectName}\\n`);\n\n // Resolve template directory\n // tsup publicDir copies templates/ contents into dist/, so dist/default/ exists\n // When running from dist/index.js, __dirname is dist/, so we check:\n // 1. dist/<template> (built bundle — tsup publicDir)\n // 2. ../templates/<template> (development — running from src/)\n // 3. ../../templates/<template> (fallback)\n const searchDirs = [\n path.resolve(__dirname, options.template), // dist/default (built)\n path.resolve(__dirname, '..', 'templates', options.template), // packages/cli/templates/default (dev)\n path.resolve(__dirname, '..', '..', 'templates', options.template), // fallback\n ];\n\n let templateDir = '';\n for (const dir of searchDirs) {\n if (await fs.pathExists(dir)) {\n templateDir = dir;\n break;\n }\n }\n\n if (!templateDir) {\n console.error(`Error: Template \"${options.template}\" not found.`);\n console.error(`Searched in:`);\n searchDirs.forEach(d => console.error(` - ${d}`));\n process.exit(1);\n }\n\n // Copy template to target directory\n await fs.copy(templateDir, targetDir);\n\n // Update package.json with project name\n const pkgPath = path.join(targetDir, 'package.json');\n if (await fs.pathExists(pkgPath)) {\n const pkg = await fs.readJson(pkgPath);\n pkg.name = projectName;\n await fs.writeJson(pkgPath, pkg, { spaces: 2 });\n }\n\n // Update dashboard package.json name\n const dashPkgPath = path.join(targetDir, 'dashboard', 'package.json');\n if (await fs.pathExists(dashPkgPath)) {\n const dashPkg = await fs.readJson(dashPkgPath);\n dashPkg.name = `${projectName}-dashboard`;\n await fs.writeJson(dashPkgPath, dashPkg, { spaces: 2 });\n }\n\n console.log(` ✅ Project scaffolded at ./${projectName}`);\n\n // Install root dependencies\n console.log(`\\n📦 Installing dependencies...\\n`);\n try {\n execSync('pnpm install', {\n cwd: targetDir,\n stdio: 'inherit',\n });\n console.log(`\\n ✅ Dependencies installed`);\n } catch {\n console.warn(\n `\\n ⚠️ Could not install dependencies. Run \"cd ${projectName} && pnpm install\" manually.`\n );\n }\n\n // Install dashboard dependencies\n const dashDir = path.join(targetDir, 'dashboard');\n if (await fs.pathExists(dashDir)) {\n console.log(`\\n📦 Installing dashboard dependencies...\\n`);\n try {\n execSync('pnpm install', {\n cwd: dashDir,\n stdio: 'inherit',\n });\n console.log(`\\n ✅ Dashboard dependencies installed`);\n } catch {\n console.warn(\n `\\n ⚠️ Could not install dashboard dependencies. Run \"cd ${projectName}/dashboard && pnpm install\" manually.`\n );\n }\n }\n\n // Initialize Convex\n console.log(`\\n⚡ Initializing Convex...\\n`);\n try {\n execSync('npx convex dev --once', {\n cwd: targetDir,\n stdio: 'inherit',\n });\n console.log(`\\n ✅ Convex initialized`);\n } catch {\n console.warn(\n `\\n ⚠️ Convex initialization skipped. Run \"npx convex dev\" to set up your backend.`\n );\n }\n\n console.log(`\n🎉 AgentForge project \"${projectName}\" created successfully!\n\nNext steps:\n cd ${projectName}\n\n # Start the Convex backend\n npx convex dev\n\n # In another terminal, launch the dashboard\n agentforge dashboard\n\n # Or chat with your agent from the CLI\n agentforge chat\n\n # Install skills to extend agent capabilities\n agentforge skills list --registry\n agentforge skills install web-search\n\n # Check system status\n agentforge status\n\nDocumentation: https://github.com/Agentic-Engineering-Agency/agentforge\n`);\n}\n","import { spawn } from 'node:child_process';\nimport path from 'node:path';\nimport fs from 'fs-extra';\n\n/**\n * Supported sandbox providers for agent tool execution.\n */\nexport type SandboxType = 'local' | 'docker' | 'e2b' | 'none';\n\n/**\n * Options for the run command.\n */\nexport interface RunOptions {\n /** The port for the dev server. */\n port: string;\n /** The sandbox provider to use for agent tool execution. */\n sandbox: SandboxType;\n}\n\n/**\n * Starts the local development environment for an AgentForge project.\n *\n * This command starts the Convex development server and watches for file changes.\n * When `--sandbox docker` is specified, agent tool execution will use Docker\n * containers for isolation instead of the default local sandbox.\n *\n * @param options - Options for the run command.\n */\nexport async function runProject(options: RunOptions): Promise<void> {\n const projectDir = process.cwd();\n\n // Verify we're in an AgentForge project\n const pkgPath = path.join(projectDir, 'package.json');\n if (!(await fs.pathExists(pkgPath))) {\n console.error(\n 'Error: No package.json found. Are you in an AgentForge project directory?'\n );\n process.exit(1);\n }\n\n const convexDir = path.join(projectDir, 'convex');\n if (!(await fs.pathExists(convexDir))) {\n console.error(\n 'Error: No convex/ directory found. Are you in an AgentForge project directory?'\n );\n process.exit(1);\n }\n\n console.log(`\\n🚀 Starting AgentForge development server...\\n`);\n console.log(` Convex dev server starting on port ${options.port}...`);\n\n // Log sandbox configuration\n if (options.sandbox === 'docker') {\n console.log(` 🐳 Docker sandbox enabled — agent tools will execute in isolated containers`);\n console.log(` Image: ${process.env['DOCKER_IMAGE'] ?? 'node:22-slim (default)'}`);\n console.log(` Host: ${process.env['DOCKER_HOST'] ?? '/var/run/docker.sock (default)'}`);\n } else if (options.sandbox === 'e2b') {\n console.log(` ☁️ E2B sandbox enabled — agent tools will execute in cloud sandboxes`);\n } else if (options.sandbox === 'none') {\n console.log(` ⚠️ No sandbox — agent tools will execute directly on the host (unsafe)`);\n } else {\n console.log(` 📦 Local sandbox enabled (default)`);\n }\n\n // Set sandbox environment variable for downstream consumers\n const sandboxEnv = {\n ...process.env,\n AGENTFORGE_SANDBOX_PROVIDER: options.sandbox,\n };\n\n // Start the Convex dev server\n const convexProcess = spawn('npx', ['convex', 'dev'], {\n cwd: projectDir,\n stdio: 'inherit',\n shell: true,\n env: sandboxEnv,\n });\n\n convexProcess.on('error', (err) => {\n console.error(`Failed to start Convex dev server: ${err.message}`);\n process.exit(1);\n });\n\n convexProcess.on('close', (code) => {\n if (code !== 0) {\n console.error(`Convex dev server exited with code ${code}`);\n }\n });\n\n // Handle graceful shutdown\n const shutdown = () => {\n console.log('\\n\\n👋 Shutting down AgentForge dev server...');\n convexProcess.kill('SIGTERM');\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n","import path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport prompts from 'prompts';\nimport { CloudClient, CloudClientError, type AgentConfig } from '../lib/cloud-client.js';\nimport { readCredentials, getCloudUrl } from '../lib/credentials.js';\n\n/**\n * Options for the deploy command.\n */\nexport interface DeployOptions {\n /** Path to the environment file. */\n env: string;\n /** Preview deployment without executing. */\n dryRun: boolean;\n /** Rollback to previous deployment. */\n rollback: boolean;\n /** Skip confirmation prompts. */\n force: boolean;\n /** Deployment provider: convex (default) or cloud. */\n provider: 'convex' | 'cloud';\n /** Project ID for cloud deployments. */\n project?: string;\n /** Version tag for the deployment. */\n version?: string;\n}\n\n/**\n * Configuration file format for agentforge.config.ts or agentforge.json\n */\nexport interface AgentForgeConfig {\n projectId?: string;\n agents?: AgentConfig[];\n cloudUrl?: string;\n}\n\n/**\n * Parses a .env file and returns key-value pairs.\n *\n * @param filePath - Absolute path to the .env file.\n * @returns A record of environment variable key-value pairs.\n */\nexport function parseEnvFile(filePath: string): Record<string, string> {\n const content = fs.readFileSync(filePath, 'utf-8');\n const vars: Record<string, string> = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n // Remove surrounding quotes\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n if (key) {\n vars[key] = value;\n }\n }\n\n return vars;\n}\n\n/**\n * Read agentforge configuration from agentforge.config.ts or agentforge.json\n */\nexport async function readAgentForgeConfig(projectDir: string): Promise<AgentForgeConfig | null> {\n // Try agentforge.config.ts first\n const tsConfigPath = path.join(projectDir, 'agentforge.config.ts');\n if (await fs.pathExists(tsConfigPath)) {\n try {\n // For now, we'll read it as a simple module that exports default\n // In production, this might need a dynamic import or esbuild\n const content = await fs.readFile(tsConfigPath, 'utf-8');\n return parseConfigFromContent(content, projectDir);\n } catch {\n // Fall through to JSON\n }\n }\n\n // Try agentforge.json\n const jsonConfigPath = path.join(projectDir, 'agentforge.json');\n if (await fs.pathExists(jsonConfigPath)) {\n try {\n const content = await fs.readFile(jsonConfigPath, 'utf-8');\n return JSON.parse(content) as AgentForgeConfig;\n } catch {\n return null;\n }\n }\n\n return null;\n}\n\n/**\n * Parse config from TypeScript file content\n * This is a simplified parser - in production you might use ts-node or esbuild\n */\nfunction parseConfigFromContent(content: string, projectDir: string): AgentForgeConfig | null {\n const config: AgentForgeConfig = {};\n\n // Extract projectId\n const projectIdMatch = content.match(/projectId\\s*:\\s*[\"']([^\"']+)[\"']/);\n if (projectIdMatch) {\n config.projectId = projectIdMatch[1];\n }\n\n // Try to read agents from the convex/agents.ts file if present\n const agentsPath = path.join(projectDir, 'convex', 'agents.ts');\n if (fs.existsSync(agentsPath)) {\n try {\n const agentsContent = fs.readFileSync(agentsPath, 'utf-8');\n config.agents = parseAgentsFromConvex(agentsContent);\n } catch {\n // Ignore\n }\n }\n\n // Extract cloudUrl\n const cloudUrlMatch = content.match(/cloudUrl\\s*:\\s*[\"']([^\"']+)[\"']/);\n if (cloudUrlMatch) {\n config.cloudUrl = cloudUrlMatch[1];\n }\n\n return Object.keys(config).length > 0 ? config : null;\n}\n\n/**\n * Parse agent definitions from convex/agents.ts\n * This is a simplified parser for common patterns\n */\nfunction parseAgentsFromConvex(content: string): AgentConfig[] {\n const agents: AgentConfig[] = [];\n\n // Look for agent objects in the content\n // Pattern: { id: \"...\", name: \"...\", instructions: \"...\", model: \"...\" }\n const agentPattern = /\\{\\s*id:\\s*[\"']([^\"']+)[\"']\\s*,\\s*name:\\s*[\"']([^\"']+)[\"']([\\s\\S]*?)\\}/g;\n \n let match;\n while ((match = agentPattern.exec(content)) !== null) {\n const id = match[1];\n const name = match[2];\n const rest = match[3];\n\n const agent: AgentConfig = { id, name, instructions: '', model: 'gpt-4o-mini' };\n\n const instructionsMatch = rest.match(/instructions:\\s*[\"']([^\"']+)[\"']/);\n if (instructionsMatch) agent.instructions = instructionsMatch[1];\n\n const modelMatch = rest.match(/model:\\s*[\"']([^\"']+)[\"']/);\n if (modelMatch) agent.model = modelMatch[1];\n\n const providerMatch = rest.match(/provider:\\s*[\"']([^\"']+)[\"']/);\n if (providerMatch) agent.provider = providerMatch[1];\n\n const descriptionMatch = rest.match(/description:\\s*[\"']([^\"']+)[\"']/);\n if (descriptionMatch) agent.description = descriptionMatch[1];\n\n agents.push(agent);\n }\n\n return agents;\n}\n\n/**\n * Deploy to AgentForge Cloud\n */\nasync function deployToCloud(\n options: DeployOptions,\n projectDir: string\n): Promise<void> {\n console.log('\\n☁️ Deploying to AgentForge Cloud...\\n');\n\n // 1. Read credentials\n const credentials = await readCredentials();\n if (!credentials?.apiKey) {\n console.error(chalk.red('✖'), 'Not authenticated with AgentForge Cloud.');\n console.error(' Run \"agentforge login\" to authenticate.\\n');\n process.exit(1);\n }\n\n // 2. Read local configuration\n const spinner = ora('Reading agent configuration...').start();\n const config = await readAgentForgeConfig(projectDir);\n\n // 3. Resolve project ID\n let projectId = options.project || config?.projectId;\n \n if (!projectId) {\n spinner.stop();\n console.error(chalk.red('✖'), 'No project ID specified.');\n console.error(' Use --project flag or set projectId in agentforge.config.ts\\n');\n process.exit(1);\n }\n\n // 4. Extract agents from config\n let agents = config?.agents || [];\n \n if (agents.length === 0) {\n spinner.stop();\n console.error(chalk.red('✖'), 'No agents found in configuration.');\n console.error(' Define agents in agentforge.config.ts or convex/agents.ts\\n');\n process.exit(1);\n }\n\n spinner.succeed(`Found ${agents.length} agent(s) to deploy`);\n\n // 5. Handle dry-run mode\n if (options.dryRun) {\n console.log('\\n' + chalk.blue('ℹ'), 'Dry run - no changes will be made\\n');\n console.log(' Project ID:', chalk.cyan(projectId));\n console.log(' Cloud URL:', chalk.cyan(credentials.cloudUrl || 'https://cloud.agentforge.ai'));\n console.log(' Agents:');\n for (const agent of agents) {\n console.log(` • ${chalk.bold(agent.name)} (${agent.model})`);\n }\n console.log();\n return;\n }\n\n // 6. Create Cloud client\n const cloudSpinner = ora('Connecting to AgentForge Cloud...').start();\n const client = new CloudClient(\n credentials.cloudUrl || process.env.AGENTFORGE_CLOUD_URL,\n credentials.apiKey\n );\n\n // Verify authentication\n try {\n await client.authenticate();\n cloudSpinner.succeed('Connected to AgentForge Cloud');\n } catch (err: any) {\n cloudSpinner.fail('Failed to connect to AgentForge Cloud');\n if (err instanceof CloudClientError) {\n console.error(chalk.red('✖'), err.message);\n } else {\n console.error(chalk.red('✖'), err.message || err);\n }\n process.exit(1);\n }\n\n // 7. Verify project exists\n const projectSpinner = ora('Verifying project...').start();\n try {\n await client.getProject(projectId);\n projectSpinner.succeed(`Project verified: ${chalk.cyan(projectId)}`);\n } catch (err: any) {\n projectSpinner.fail('Project verification failed');\n if (err.status === 404) {\n console.error(chalk.red('✖'), `Project \"${projectId}\" not found.`);\n console.error(' Check the project ID or create the project in the dashboard.\\n');\n } else {\n console.error(chalk.red('✖'), err.message || err);\n }\n process.exit(1);\n }\n\n // 8. Create deployment\n const version = options.version || `v${Date.now()}`;\n const deploySpinner = ora('Creating deployment...').start();\n\n let deploymentId: string;\n try {\n const response = await client.createDeployment({\n projectId,\n agents,\n version,\n });\n deploymentId = response.deploymentId;\n deploySpinner.succeed(`Deployment created: ${chalk.cyan(deploymentId)}`);\n } catch (err: any) {\n deploySpinner.fail('Failed to create deployment');\n if (err instanceof CloudClientError) {\n console.error(chalk.red('✖'), err.message);\n } else {\n console.error(chalk.red('✖'), err.message || err);\n }\n process.exit(1);\n }\n\n // 9. Poll deployment status\n console.log('\\n📦 Deploying agents...\\n');\n const pollSpinner = ora('Waiting for deployment to complete...').start();\n\n const maxAttempts = 60; // 3 minutes max (3s * 60)\n let attempts = 0;\n\n while (attempts < maxAttempts) {\n let status;\n try {\n status = await client.getDeploymentStatus(deploymentId);\n attempts++;\n } catch (err: any) {\n // Continue polling on network errors, but track failures\n attempts++;\n if (attempts >= maxAttempts) {\n pollSpinner.fail('Deployment status check timed out');\n console.error();\n console.error(chalk.yellow('⚠'), 'The deployment may still be in progress.');\n console.error(` Check status at: https://cloud.agentforge.ai/projects/${projectId}/deployments/${deploymentId}`);\n console.error();\n process.exit(1);\n }\n await new Promise((resolve) => setTimeout(resolve, 3000));\n continue;\n }\n\n if (status.status === 'completed') {\n pollSpinner.succeed('Deployment completed successfully!');\n console.log();\n console.log(chalk.green('✔'), `Deployed to ${chalk.bold(`https://cloud.agentforge.ai/projects/${projectId}`)}`);\n if (status.url) {\n console.log(chalk.green('✔'), `Deployment URL: ${chalk.cyan(status.url)}`);\n }\n console.log();\n return;\n } else if (status.status === 'failed') {\n pollSpinner.fail('Deployment failed');\n console.error();\n console.error(chalk.red('✖'), 'Error:', status.errorMessage || 'Unknown error');\n console.error();\n process.exit(1);\n } else if (status.progress !== undefined) {\n pollSpinner.text = `Deploying... ${status.progress}%`;\n } else {\n const statuses: Record<string, string> = {\n pending: 'Waiting to start...',\n building: 'Building...',\n deploying: 'Deploying...',\n };\n pollSpinner.text = statuses[status.status] || `Status: ${status.status}`;\n }\n\n // Wait 3 seconds before polling again\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n\n pollSpinner.fail('Deployment timed out');\n process.exit(1);\n}\n\n/**\n * Deploy to Convex (original behavior)\n */\nasync function deployToConvex(options: DeployOptions): Promise<void> {\n const projectDir = process.cwd();\n\n // Validate project structure\n const pkgPath = path.join(projectDir, 'package.json');\n if (!(await fs.pathExists(pkgPath))) {\n console.error(\n 'Error: No package.json found. Are you in an AgentForge project directory?'\n );\n process.exit(1);\n }\n\n const convexDir = path.join(projectDir, 'convex');\n if (!(await fs.pathExists(convexDir))) {\n console.error(\n 'Error: No convex/ directory found. Are you in an AgentForge project directory?'\n );\n process.exit(1);\n }\n\n // Handle rollback mode\n if (options.rollback) {\n console.log('\\n🔄 Rolling back to previous Convex deployment...\\n');\n try {\n execSync('npx convex deploy --rollback', {\n cwd: projectDir,\n stdio: 'inherit',\n });\n console.log('\\n ✅ Rollback completed successfully.');\n } catch {\n console.error('\\n ❌ Rollback failed.');\n process.exit(1);\n }\n return;\n }\n\n // Resolve and validate env file\n const envPath = path.resolve(projectDir, options.env);\n const envExists = await fs.pathExists(envPath);\n\n // Parse env vars if file exists\n let envVars: Record<string, string> = {};\n if (envExists) {\n envVars = parseEnvFile(envPath);\n }\n\n // Handle dry-run mode\n if (options.dryRun) {\n console.log('\\n🔍 Dry run — previewing deployment plan:\\n');\n console.log(` Project directory: ${projectDir}`);\n console.log(` Convex directory: ${convexDir}`);\n console.log(` Environment file: ${envExists ? envPath : '(not found, skipping env vars)'}`);\n\n if (Object.keys(envVars).length > 0) {\n console.log(`\\n Environment variables to set (${Object.keys(envVars).length}):`);\n for (const key of Object.keys(envVars)) {\n console.log(` • ${key}=${envVars[key].slice(0, 4)}${'*'.repeat(Math.max(0, envVars[key].length - 4))}`);\n }\n } else {\n console.log('\\n No environment variables to set.');\n }\n\n console.log('\\n ℹ️ No changes were made (dry run).\\n');\n return;\n }\n\n // Require env file for actual deployment\n if (!envExists) {\n console.error(\n `Error: Environment file \"${options.env}\" not found. Create it or use --env to specify a different path.`\n );\n process.exit(1);\n }\n\n // Confirmation prompt (unless --force)\n if (!options.force) {\n console.log('\\n🚀 Deployment plan:\\n');\n console.log(` Project: ${projectDir}`);\n console.log(` Env file: ${envPath}`);\n console.log(` Env vars: ${Object.keys(envVars).length} variable(s)`);\n console.log('\\n Use --force to skip this confirmation.\\n');\n\n // In a real CLI, we'd use prompts here. For now, auto-proceed.\n // The --force flag is the recommended path for CI/CD.\n }\n\n console.log('\\n📦 Deploying AgentForge project to production...\\n');\n\n // Step 1: Push environment variables\n if (Object.keys(envVars).length > 0) {\n console.log(' Setting environment variables...');\n for (const [key, value] of Object.entries(envVars)) {\n try {\n execSync(`npx convex env set ${key} \"${value}\"`, {\n cwd: projectDir,\n stdio: 'pipe',\n });\n console.log(` ✅ ${key}`);\n } catch {\n console.error(` ❌ Failed to set ${key}`);\n }\n }\n console.log('');\n }\n\n // Step 2: Deploy\n console.log(' Deploying Convex backend...');\n try {\n execSync('npx convex deploy', {\n cwd: projectDir,\n stdio: 'inherit',\n });\n console.log('\\n ✅ Deployment completed successfully!');\n console.log(' Use \"agentforge deploy --rollback\" to revert if needed.\\n');\n } catch {\n console.error('\\n ❌ Deployment failed.');\n console.error(' Check the Convex dashboard for details.');\n process.exit(1);\n }\n}\n\n/**\n * Deploys an AgentForge project to production.\n *\n * Handles environment variable configuration, provides deployment status\n * feedback, and supports rollback capabilities.\n *\n * @param options - Options for the deploy command.\n */\nexport async function deployProject(options: DeployOptions): Promise<void> {\n const projectDir = process.cwd();\n\n // Route to appropriate provider\n if (options.provider === 'cloud') {\n await deployToCloud(options, projectDir);\n } else {\n await deployToConvex(options);\n }\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\nimport os from 'node:os';\n\n/**\n * AgentForge Cloud credentials storage\n * Stored in ~/.agentforge/credentials.json\n */\n\nexport interface Credentials {\n /** API key for AgentForge Cloud */\n apiKey: string;\n /** Cloud URL (defaults to https://cloud.agentforge.ai) */\n cloudUrl: string;\n /** User email or identifier */\n userEmail?: string;\n /** User display name */\n userName?: string;\n /** Token expiration timestamp */\n expiresAt?: number;\n /** Last refreshed timestamp */\n refreshedAt?: number;\n}\n\nconst CREDENTIALS_DIR = path.join(os.homedir(), '.agentforge');\nconst CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, 'credentials.json');\nconst DEFAULT_CLOUD_URL = 'https://cloud.agentforge.ai';\n\n/**\n * Ensure the credentials directory exists\n */\nasync function ensureCredentialsDir(): Promise<void> {\n await fs.ensureDir(CREDENTIALS_DIR);\n // Set restrictive permissions (owner read/write only)\n try {\n await fs.chmod(CREDENTIALS_DIR, 0o700);\n } catch {\n // Ignore permission errors on Windows\n }\n}\n\n/**\n * Read credentials from the secure storage\n */\nexport async function readCredentials(): Promise<Credentials | null> {\n try {\n if (!(await fs.pathExists(CREDENTIALS_FILE))) {\n return null;\n }\n const content = await fs.readFile(CREDENTIALS_FILE, 'utf-8');\n const creds = JSON.parse(content) as Credentials;\n // Ensure cloudUrl has a default\n if (!creds.cloudUrl) {\n creds.cloudUrl = DEFAULT_CLOUD_URL;\n }\n return creds;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Write credentials to secure storage\n */\nexport async function writeCredentials(credentials: Credentials): Promise<void> {\n await ensureCredentialsDir();\n const data: Credentials = {\n ...credentials,\n cloudUrl: credentials.cloudUrl || DEFAULT_CLOUD_URL,\n refreshedAt: Date.now(),\n };\n await fs.writeFile(CREDENTIALS_FILE, JSON.stringify(data, null, 2), 'utf-8');\n // Set restrictive permissions (owner read/write only)\n try {\n await fs.chmod(CREDENTIALS_FILE, 0o600);\n } catch {\n // Ignore permission errors on Windows\n }\n}\n\n/**\n * Delete credentials (logout)\n */\nexport async function deleteCredentials(): Promise<boolean> {\n try {\n if (await fs.pathExists(CREDENTIALS_FILE)) {\n await fs.remove(CREDENTIALS_FILE);\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if user is authenticated\n */\nexport async function isAuthenticated(): Promise<boolean> {\n const creds = await readCredentials();\n return creds !== null && creds.apiKey !== undefined;\n}\n\n/**\n * Get the cloud URL (from credentials or default)\n */\nexport async function getCloudUrl(): Promise<string> {\n const creds = await readCredentials();\n return creds?.cloudUrl || process.env.AGENTFORGE_CLOUD_URL || DEFAULT_CLOUD_URL;\n}\n\n/**\n * Get API key (returns null if not authenticated)\n */\nexport async function getApiKey(): Promise<string | null> {\n const creds = await readCredentials();\n return creds?.apiKey || null;\n}\n\n/**\n * Get the credentials file path\n */\nexport function getCredentialsPath(): string {\n return CREDENTIALS_FILE;\n}\n\n/**\n * Check if credentials are expired\n */\nexport function isExpired(credentials: Credentials): boolean {\n if (!credentials.expiresAt) return false;\n return Date.now() >= credentials.expiresAt;\n}\n\n/**\n * Update credentials with new data\n */\nexport async function updateCredentials(updates: Partial<Credentials>): Promise<Credentials | null> {\n const current = await readCredentials();\n if (!current) return null;\n const updated = { ...current, ...updates, refreshedAt: Date.now() };\n await writeCredentials(updated);\n return updated;\n}\n","import type { Credentials } from './credentials.js';\nimport { getCloudUrl, getApiKey, readCredentials } from './credentials.js';\n\n/**\n * AgentForge Cloud API Client\n * \n * Handles all HTTP communication with the AgentForge Cloud API.\n * Supports both REST API endpoints and Convex HTTP actions.\n */\n\nexport interface Project {\n id: string;\n name: string;\n description?: string;\n createdAt: number;\n updatedAt: number;\n}\n\nexport interface AgentConfig {\n id?: string;\n name: string;\n description?: string;\n instructions: string;\n model: string;\n provider?: string;\n tools?: any;\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n config?: Record<string, any>;\n}\n\nexport interface Deployment {\n id: string;\n projectId: string;\n status: 'pending' | 'building' | 'deploying' | 'completed' | 'failed' | 'rolled_back';\n version: string;\n agents: AgentConfig[];\n url?: string;\n createdAt: number;\n updatedAt: number;\n errorMessage?: string;\n}\n\nexport interface CreateDeploymentRequest {\n projectId: string;\n agents: AgentConfig[];\n version: string;\n}\n\nexport interface CreateDeploymentResponse {\n deploymentId: string;\n status: string;\n url?: string;\n}\n\nexport interface DeploymentStatusResponse {\n id: string;\n status: string;\n url?: string;\n errorMessage?: string;\n progress?: number;\n}\n\nexport interface UserInfo {\n id: string;\n email: string;\n name?: string;\n}\n\nexport interface CloudApiError {\n message: string;\n code?: string;\n status?: number;\n}\n\n/**\n * Cloud API Error class for typed error handling\n */\nexport class CloudClientError extends Error {\n constructor(\n message: string,\n public code?: string,\n public status?: number\n ) {\n super(message);\n this.name = 'CloudClientError';\n }\n}\n\n/**\n * AgentForge Cloud API Client\n */\nexport class CloudClient {\n private baseUrl: string;\n private apiKey: string | null = null;\n\n constructor(baseUrl?: string, apiKey?: string) {\n this.baseUrl = baseUrl || 'https://cloud.agentforge.ai';\n this.apiKey = apiKey || null;\n }\n\n /**\n * Initialize the client with stored credentials\n */\n async initialize(): Promise<void> {\n this.baseUrl = await getCloudUrl();\n this.apiKey = await getApiKey();\n }\n\n /**\n * Set the API key directly\n */\n setApiKey(apiKey: string): void {\n this.apiKey = apiKey;\n }\n\n /**\n * Set the base URL directly\n */\n setBaseUrl(baseUrl: string): void {\n this.baseUrl = baseUrl;\n }\n\n /**\n * Get the full API URL for an endpoint\n */\n private getUrl(endpoint: string): string {\n const base = this.baseUrl.replace(/\\/$/, '');\n const path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;\n return `${base}${path}`;\n }\n\n /**\n * Get request headers with authentication\n */\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'X-Client-Version': '0.5.1',\n };\n\n if (this.apiKey) {\n headers['Authorization'] = `Bearer ${this.apiKey}`;\n }\n\n return headers;\n }\n\n /**\n * Make an HTTP request to the Cloud API\n */\n private async request<T>(\n method: string,\n endpoint: string,\n body?: unknown\n ): Promise<T> {\n const url = this.getUrl(endpoint);\n const options: RequestInit = {\n method,\n headers: this.getHeaders(),\n };\n\n if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {\n options.body = JSON.stringify(body);\n }\n\n let response: Response;\n try {\n response = await fetch(url, options);\n } catch (error: any) {\n throw new CloudClientError(\n `Network error: ${error.message || 'Failed to connect to AgentForge Cloud'}`,\n 'NETWORK_ERROR'\n );\n }\n\n // Handle non-JSON responses\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n if (!response.ok) {\n const errorBody: CloudApiError | null = isJson ? (await response.json()) as CloudApiError : null;\n const message = errorBody?.message || `HTTP ${response.status}: ${response.statusText}`;\n throw new CloudClientError(\n message,\n errorBody?.code || `HTTP_${response.status}`,\n response.status\n );\n }\n\n if (response.status === 204) {\n return {} as T;\n }\n\n if (!isJson) {\n const text = await response.text();\n return { text } as T;\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Check if credentials are valid\n */\n async authenticate(): Promise<UserInfo> {\n if (!this.apiKey) {\n throw new CloudClientError(\n 'No API key configured. Run \"agentforge login\" to authenticate.',\n 'NO_CREDENTIALS',\n 401\n );\n }\n\n try {\n const user = await this.request<UserInfo>('GET', '/api/auth/me');\n return user;\n } catch (error: any) {\n if (error.status === 401) {\n throw new CloudClientError(\n 'Invalid API key. Run \"agentforge login\" to re-authenticate.',\n 'UNAUTHORIZED',\n 401\n );\n }\n throw error;\n }\n }\n\n /**\n * List all projects for the authenticated user\n */\n async listProjects(): Promise<Project[]> {\n return this.request<Project[]>('GET', '/api/projects');\n }\n\n /**\n * Get a specific project by ID\n */\n async getProject(projectId: string): Promise<Project> {\n return this.request<Project>('GET', `/api/projects/${projectId}`);\n }\n\n /**\n * Upload agent configuration to Cloud\n */\n async uploadAgentConfig(\n projectId: string,\n agentConfig: AgentConfig\n ): Promise<{ agentId: string }> {\n return this.request<{ agentId: string }>(\n 'POST',\n `/api/projects/${projectId}/agents`,\n agentConfig\n );\n }\n\n /**\n * Create a new deployment\n */\n async createDeployment(\n request: CreateDeploymentRequest\n ): Promise<CreateDeploymentResponse> {\n return this.request<CreateDeploymentResponse>(\n 'POST',\n '/api/deployments/create',\n request\n );\n }\n\n /**\n * Get deployment status\n */\n async getDeploymentStatus(\n deploymentId: string\n ): Promise<DeploymentStatusResponse> {\n return this.request<DeploymentStatusResponse>(\n 'GET',\n `/api/deployments/${deploymentId}/status`\n );\n }\n\n /**\n * Get deployment details\n */\n async getDeployment(deploymentId: string): Promise<Deployment> {\n return this.request<Deployment>('GET', `/api/deployments/${deploymentId}`);\n }\n\n /**\n * Rollback a deployment\n */\n async rollbackDeployment(deploymentId: string): Promise<{ success: boolean }> {\n return this.request<{ success: boolean }>(\n 'POST',\n `/api/deployments/${deploymentId}/rollback`\n );\n }\n\n /**\n * List deployments for a project\n */\n async listDeployments(projectId: string): Promise<Deployment[]> {\n return this.request<Deployment[]>('GET', `/api/projects/${projectId}/deployments`);\n }\n}\n\n/**\n * Create a CloudClient with credentials from storage\n */\nexport async function createCloudClient(): Promise<CloudClient> {\n const client = new CloudClient();\n await client.initialize();\n return client;\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\n\n/**\n * Safely get the current working directory.\n * Returns null if the CWD has been deleted or is inaccessible.\n */\nfunction safeCwd(): string | null {\n try {\n return process.cwd();\n } catch {\n return null;\n }\n}\n\n/**\n * Get the Convex deployment URL from the project's .env files.\n * Called lazily — only when a command actually needs Convex.\n */\nfunction getConvexUrl(): string {\n const cwd = safeCwd();\n if (!cwd) {\n throw new Error(\n 'Current directory does not exist or is not accessible.\\n' +\n 'Please navigate to a valid AgentForge project directory and try again.'\n );\n }\n const envFiles = ['.env.local', '.env', '.env.production'];\n\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(/CONVEX_URL\\s*=\\s*(.+)/);\n if (match) {\n return match[1].trim().replace(/[\"']/g, '');\n }\n }\n }\n\n // Also check .convex/deployment.json\n const convexEnv = path.join(cwd, '.convex', 'deployment.json');\n if (fs.existsSync(convexEnv)) {\n try {\n const data = JSON.parse(fs.readFileSync(convexEnv, 'utf-8'));\n if (data.url) return data.url;\n } catch {\n // ignore\n }\n }\n\n throw new Error(\n 'CONVEX_URL not found. Run `npx convex dev` first, or set CONVEX_URL in your .env file.'\n );\n}\n\n/**\n * Create a Convex HTTP client connected to the project's deployment.\n * The ConvexHttpClient import is deferred to avoid triggering\n * process.cwd() at module load time (which crashes if CWD is gone).\n */\nexport async function createClient(): Promise<import('convex/browser').ConvexHttpClient> {\n const { ConvexHttpClient } = await import('convex/browser');\n const url = getConvexUrl();\n return new ConvexHttpClient(url);\n}\n\n/**\n * Safely call a Convex query/mutation and handle errors gracefully.\n */\nexport async function safeCall<T>(\n fn: () => Promise<T>,\n errorMessage: string\n): Promise<T> {\n try {\n return await fn();\n } catch (error: any) {\n if (error.message?.includes('CONVEX_URL not found')) {\n console.error('\\n❌ Not connected to Convex.');\n console.error(' Run `npx convex dev` in your project directory first.\\n');\n } else if (error.message?.includes('Current directory does not exist')) {\n console.error(`\\n❌ ${error.message}\\n`);\n } else if (error.message?.includes('fetch failed') || error.message?.includes('ECONNREFUSED')) {\n console.error('\\n❌ Cannot reach Convex deployment.');\n console.error(' Make sure `npx convex dev` is running.\\n');\n } else {\n console.error(`\\n❌ ${errorMessage}`);\n console.error(` ${error.message}\\n`);\n }\n process.exit(1);\n }\n}\n","/**\n * CLI Display Helpers — Consistent formatting for all commands\n */\n\nexport const colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n gray: '\\x1b[90m',\n};\n\nexport function success(msg: string) {\n console.log(`${colors.green}✔${colors.reset} ${msg}`);\n}\n\nexport function error(msg: string) {\n console.error(`${colors.red}✖${colors.reset} ${msg}`);\n}\n\nexport function warn(msg: string) {\n console.log(`${colors.yellow}⚠${colors.reset} ${msg}`);\n}\n\nexport function info(msg: string) {\n console.log(`${colors.blue}ℹ${colors.reset} ${msg}`);\n}\n\nexport function header(title: string) {\n console.log(`\\n${colors.bold}${colors.cyan}${title}${colors.reset}\\n`);\n}\n\nexport function dim(msg: string) {\n console.log(`${colors.dim}${msg}${colors.reset}`);\n}\n\n/**\n * Print a table from an array of objects\n */\nexport function table(data: Record<string, any>[], columns?: string[]) {\n if (data.length === 0) {\n dim(' (no items)');\n return;\n }\n\n const cols = columns ?? Object.keys(data[0]);\n const widths: Record<string, number> = {};\n\n for (const col of cols) {\n widths[col] = Math.max(\n col.length,\n ...data.map((row) => String(row[col] ?? '').length)\n );\n }\n\n // Header\n const headerRow = cols.map((c) => c.toUpperCase().padEnd(widths[c])).join(' ');\n console.log(` ${colors.bold}${headerRow}${colors.reset}`);\n console.log(` ${cols.map((c) => '─'.repeat(widths[c])).join('──')}`);\n\n // Rows\n for (const row of data) {\n const line = cols.map((c) => String(row[c] ?? '').padEnd(widths[c])).join(' ');\n console.log(` ${line}`);\n }\n console.log();\n}\n\n/**\n * Print key-value details\n */\nexport function details(data: Record<string, any>) {\n const maxKey = Math.max(...Object.keys(data).map((k) => k.length));\n for (const [key, value] of Object.entries(data)) {\n const label = `${colors.dim}${key.padEnd(maxKey)}${colors.reset}`;\n console.log(` ${label} ${value}`);\n }\n console.log();\n}\n\n/**\n * Format a timestamp to a readable date string\n */\nexport function formatDate(ts: number): string {\n return new Date(ts).toLocaleString();\n}\n\n/**\n * Truncate a string to a max length\n */\nexport function truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + '…';\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, details, success, error, info, formatDate } from '../lib/display.js';\nimport readline from 'node:readline';\n\nfunction prompt(question: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => rl.question(question, (ans) => { rl.close(); resolve(ans.trim()); }));\n}\n\nexport function registerAgentsCommand(program: Command) {\n const agents = program.command('agents').description('Manage agents');\n\n agents\n .command('list')\n .description('List all agents')\n .option('--active', 'Show only active agents')\n .option('--json', 'Output as JSON')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(\n () => client.query('agents:list' as any, {}),\n 'Failed to list agents'\n );\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n header('Agents');\n if (!result || (result as any[]).length === 0) {\n info('No agents found. Create one with: agentforge agents create');\n return;\n }\n const filtered = opts.active ? (result as any[]).filter((a: any) => a.isActive) : result;\n table(\n (filtered as any[]).map((a: any) => ({\n ID: a.id,\n Name: a.name,\n Model: a.model,\n Provider: a.provider || 'openai',\n Active: a.isActive ? '✔' : '✖',\n Created: formatDate(a.createdAt),\n }))\n );\n });\n\n agents\n .command('create')\n .description('Create a new agent (interactive)')\n .option('--name <name>', 'Agent name')\n .option('--model <model>', 'Model identifier (e.g., openai:gpt-4o-mini)')\n .option('--instructions <text>', 'System instructions')\n .action(async (opts) => {\n const name = opts.name || await prompt('Agent name: ');\n const model = opts.model || await prompt('Model (e.g., openai:gpt-4o-mini): ');\n const instructions = opts.instructions || await prompt('Instructions: ');\n\n if (!name || !model || !instructions) {\n error('Name, model, and instructions are required.');\n process.exit(1);\n }\n\n const provider = model.includes(':') ? model.split(':')[0] : 'openai';\n const agentId = name.toLowerCase().replace(/[^a-z0-9]+/g, '-');\n\n const client = await createClient();\n await safeCall(\n () => client.mutation('agents:create' as any, {\n id: agentId,\n name,\n instructions,\n model,\n provider,\n }),\n 'Failed to create agent'\n );\n success(`Agent \"${name}\" created with ID: ${agentId}`);\n });\n\n agents\n .command('inspect')\n .argument('<id>', 'Agent ID')\n .description('Show detailed agent information')\n .action(async (id) => {\n const client = await createClient();\n const agent = await safeCall(\n () => client.query('agents:get' as any, { id }),\n 'Failed to fetch agent'\n );\n if (!agent) {\n error(`Agent \"${id}\" not found.`);\n process.exit(1);\n }\n header(`Agent: ${(agent as any).name}`);\n const a = agent as any;\n details({\n 'ID': a.id,\n 'Name': a.name,\n 'Model': a.model,\n 'Provider': a.provider || 'openai',\n 'Active': a.isActive ? 'Yes' : 'No',\n 'Temperature': a.temperature ?? 'default',\n 'Max Tokens': a.maxTokens ?? 'default',\n 'Created': formatDate(a.createdAt),\n 'Updated': formatDate(a.updatedAt),\n });\n if (a.description) info(`Description: ${a.description}`);\n console.log(` Instructions:\\n ${a.instructions.split('\\n').join('\\n ')}\\n`);\n });\n\n agents\n .command('edit')\n .argument('<id>', 'Agent ID')\n .option('--name <name>', 'New name')\n .option('--model <model>', 'New model')\n .option('--instructions <text>', 'New instructions')\n .description('Edit an agent')\n .action(async (id, opts) => {\n const client = await createClient();\n const agent = await safeCall(\n () => client.query('agents:get' as any, { id }),\n 'Failed to fetch agent'\n );\n if (!agent) { error(`Agent \"${id}\" not found.`); process.exit(1); }\n\n const updates: Record<string, any> = {};\n if (opts.name) updates.name = opts.name;\n if (opts.model) {\n updates.model = opts.model;\n updates.provider = opts.model.includes(':') ? opts.model.split(':')[0] : 'openai';\n }\n if (opts.instructions) updates.instructions = opts.instructions;\n\n if (Object.keys(updates).length === 0) {\n const a = agent as any;\n const name = await prompt(`Name [${a.name}]: `);\n const model = await prompt(`Model [${a.model}]: `);\n const instr = await prompt(`Instructions [keep current]: `);\n if (name) updates.name = name;\n if (model) { updates.model = model; updates.provider = model.includes(':') ? model.split(':')[0] : 'openai'; }\n if (instr) updates.instructions = instr;\n }\n\n if (Object.keys(updates).length === 0) { info('No changes made.'); return; }\n\n await safeCall(\n () => client.mutation('agents:update' as any, { id, ...updates }),\n 'Failed to update agent'\n );\n success(`Agent \"${id}\" updated.`);\n });\n\n agents\n .command('delete')\n .argument('<id>', 'Agent ID')\n .option('-f, --force', 'Skip confirmation')\n .description('Delete an agent')\n .action(async (id, opts) => {\n if (!opts.force) {\n const confirm = await prompt(`Delete agent \"${id}\"? (y/N): `);\n if (confirm.toLowerCase() !== 'y') { info('Cancelled.'); return; }\n }\n const client = await createClient();\n const agent = await safeCall(\n () => client.query('agents:get' as any, { id }),\n 'Failed to fetch agent'\n );\n if (!agent) { error(`Agent \"${id}\" not found.`); process.exit(1); }\n await safeCall(\n () => client.mutation('agents:remove' as any, { id }),\n 'Failed to delete agent'\n );\n success(`Agent \"${id}\" deleted.`);\n });\n\n agents\n .command('enable')\n .argument('<id>', 'Agent ID')\n .description('Enable an agent')\n .action(async (id) => {\n const client = await createClient();\n const agent = await safeCall(() => client.query('agents:get' as any, { id }), 'Failed to fetch agent');\n if (!agent) { error(`Agent \"${id}\" not found.`); process.exit(1); }\n await safeCall(() => client.mutation('agents:update' as any, { id, isActive: true }), 'Failed');\n success(`Agent \"${id}\" enabled.`);\n });\n\n agents\n .command('disable')\n .argument('<id>', 'Agent ID')\n .description('Disable an agent')\n .action(async (id) => {\n const client = await createClient();\n const agent = await safeCall(() => client.query('agents:get' as any, { id }), 'Failed to fetch agent');\n if (!agent) { error(`Agent \"${id}\" not found.`); process.exit(1); }\n await safeCall(() => client.mutation('agents:update' as any, { id, isActive: false }), 'Failed');\n success(`Agent \"${id}\" disabled.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, success, error, info, dim, colors } from '../lib/display.js';\nimport readline from 'node:readline';\n\nexport function registerChatCommand(program: Command) {\n program\n .command('chat')\n .argument('[agent-id]', 'Agent ID to chat with')\n .option('-s, --session <id>', 'Resume an existing session')\n .description('Start an interactive chat session with an agent')\n .action(async (agentId, opts) => {\n const client = await createClient();\n\n if (!agentId && !opts.session) {\n const agents = await safeCall(() => client.query('agents:list' as any, {}), 'Failed to list agents');\n if (!agents || (agents as any[]).length === 0) {\n error('No agents found. Create one first: agentforge agents create');\n process.exit(1);\n }\n header('Available Agents');\n (agents as any[]).forEach((a: any, i: number) => {\n console.log(` ${colors.cyan}${i + 1}.${colors.reset} ${a.name} ${colors.dim}(${a.id})${colors.reset}`);\n });\n console.log();\n const rl2 = readline.createInterface({ input: process.stdin, output: process.stdout });\n const choice = await new Promise<string>((r) => rl2.question('Select agent (number or ID): ', (a) => { rl2.close(); r(a.trim()); }));\n const idx = parseInt(choice) - 1;\n agentId = idx >= 0 && idx < (agents as any[]).length ? (agents as any[])[idx].id : choice;\n }\n\n const agent = await safeCall(() => client.query('agents:get' as any, { id: agentId }), 'Failed to fetch agent');\n if (!agent) { error(`Agent \"${agentId}\" not found.`); process.exit(1); }\n\n const a = agent as any;\n header(`Chat with ${a.name}`);\n dim(` Model: ${a.model} | Provider: ${a.provider || 'openai'}`);\n dim(` Type \"exit\" or \"quit\" to end. \"/new\" for new thread. \"/history\" for messages.`);\n console.log();\n\n let threadId = await safeCall(\n () => client.mutation('threads:create' as any, { agentId: a.id }),\n 'Failed to create thread'\n );\n\n const history: Array<{ role: string; content: string }> = [];\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: `${colors.green}You${colors.reset} > ` });\n rl.prompt();\n\n rl.on('line', async (line) => {\n const input = line.trim();\n if (!input) { rl.prompt(); return; }\n if (input === 'exit' || input === 'quit') { success('Session ended. Goodbye!'); process.exit(0); }\n if (input === '/new') {\n threadId = await safeCall(() => client.mutation('threads:create' as any, { agentId: a.id }), 'Failed');\n history.length = 0;\n info('New thread started.');\n rl.prompt();\n return;\n }\n if (input === '/history') {\n history.forEach((m) => {\n const prefix = m.role === 'user' ? `${colors.green}You${colors.reset}` : `${colors.cyan}${a.name}${colors.reset}`;\n console.log(` ${prefix}: ${m.content}`);\n });\n if (history.length === 0) dim(' (no messages yet)');\n console.log();\n rl.prompt();\n return;\n }\n\n history.push({ role: 'user', content: input });\n await safeCall(() => client.mutation('messages:add' as any, { threadId, role: 'user', content: input }), 'Failed to send');\n\n process.stdout.write(`${colors.cyan}${a.name}${colors.reset} > `);\n try {\n const response = await safeCall(\n () => client.action('mastraIntegration:executeAgent' as any, { agentId: a.id, prompt: input, threadId }),\n 'Failed to get response'\n );\n const text = (response as any)?.response || (response as any)?.text || (response as any)?.content || String(response);\n console.log(text);\n history.push({ role: 'assistant', content: text });\n } catch {\n console.log(`${colors.yellow}[Configure your LLM API key in .env to get responses]${colors.reset}`);\n }\n console.log();\n rl.prompt();\n });\n\n rl.on('close', () => { console.log(); info('Session ended.'); process.exit(0); });\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, details, success, error, info, formatDate } from '../lib/display.js';\n\nexport function registerSessionsCommand(program: Command) {\n const sessions = program.command('sessions').description('Manage sessions');\n\n sessions\n .command('list')\n .option('--status <status>', 'Filter by status (active, ended)')\n .option('--json', 'Output as JSON')\n .description('List all sessions')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('sessions:list' as any, {}), 'Failed to list sessions');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Sessions');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No sessions found.'); return; }\n const filtered = opts.status ? items.filter((s: any) => s.status === opts.status) : items;\n table(filtered.map((s: any) => ({\n ID: s._id?.slice(-8) || 'N/A',\n Session: s.sessionId,\n Agent: s.agentId,\n Status: s.status,\n Started: formatDate(s.startedAt),\n 'Last Activity': formatDate(s.lastActivityAt),\n })));\n });\n\n sessions\n .command('inspect')\n .argument('<id>', 'Session ID')\n .description('Show session details')\n .action(async (id) => {\n const client = await createClient();\n const session = await safeCall(() => client.query('sessions:get' as any, { sessionId: id }), 'Failed to fetch session');\n if (!session) { error(`Session \"${id}\" not found.`); process.exit(1); }\n const s = session as any;\n header(`Session: ${s.sessionId}`);\n details({ ID: s._id, 'Session ID': s.sessionId, Agent: s.agentId, Status: s.status, Started: formatDate(s.startedAt), 'Last Activity': formatDate(s.lastActivityAt) });\n });\n\n sessions\n .command('end')\n .argument('<id>', 'Session ID')\n .description('End an active session')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('sessions:updateStatus' as any, { sessionId: id, status: 'completed' }), 'Failed to end session');\n success(`Session \"${id}\" ended.`);\n });\n}\n\nexport function registerThreadsCommand(program: Command) {\n const threads = program.command('threads').description('Manage conversation threads');\n\n threads\n .command('list')\n .option('--agent <id>', 'Filter by agent ID')\n .option('--json', 'Output as JSON')\n .description('List all threads')\n .action(async (opts) => {\n const client = await createClient();\n const args = opts.agent ? { agentId: opts.agent } : {};\n const result = await safeCall(() => client.query('threads:list' as any, args), 'Failed to list threads');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Threads');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No threads found.'); return; }\n table(items.map((t: any) => ({\n ID: t._id?.slice(-8) || 'N/A',\n Name: t.name || 'Unnamed',\n Agent: t.agentId,\n Messages: t.metadata?.messageCount || '-',\n Created: formatDate(t.createdAt),\n })));\n });\n\n threads\n .command('inspect')\n .argument('<id>', 'Thread ID')\n .description('Show thread messages')\n .action(async (id) => {\n const client = await createClient();\n const messages = await safeCall(() => client.query('messages:list' as any, { threadId: id }), 'Failed to fetch messages');\n header(`Thread: ${id}`);\n const items = (messages as any[]) || [];\n if (items.length === 0) { info('No messages in this thread.'); return; }\n items.forEach((m: any) => {\n const role = m.role === 'user' ? '\\x1b[32mUser\\x1b[0m' : m.role === 'assistant' ? '\\x1b[36mAssistant\\x1b[0m' : `\\x1b[33m${m.role}\\x1b[0m`;\n console.log(` ${role}: ${m.content}`);\n });\n console.log();\n });\n\n threads\n .command('delete')\n .argument('<id>', 'Thread ID')\n .description('Delete a thread and its messages')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('threads:remove' as any, { id }), 'Failed to delete thread');\n success(`Thread \"${id}\" deleted.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, success, error, info, dim, warn, colors, formatDate, details, truncate } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\nimport { execSync } from 'node:child_process';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ninterface SkillManifest {\n name: string;\n description: string;\n version: string;\n tags?: string[];\n author?: string;\n repository?: string;\n}\n\ninterface RegistryEntry {\n name: string;\n description: string;\n version: string;\n tags: string[];\n author: string;\n source: 'builtin' | 'github' | 'local' | 'url';\n repository?: string;\n path?: string;\n}\n\ninterface SkillLockEntry {\n name: string;\n version: string;\n source: string;\n installedAt: string;\n repository?: string;\n}\n\ninterface SkillsLock {\n version: 1;\n skills: Record<string, SkillLockEntry>;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst SKILLS_DIR_NAME = 'skills';\nconst SKILLS_LOCK_FILE = 'skills.lock.json';\nconst WORKSPACE_DIR_NAME = 'workspace';\n\n// ─── Built-in Skills Registry ─────────────────────────────────────────────────\n// These are the skills that ship with AgentForge and can be installed via CLI.\n// They follow the Mastra Agent Skills Specification (SKILL.md frontmatter format).\n\nconst BUILTIN_REGISTRY: RegistryEntry[] = [\n {\n name: 'web-search',\n description: 'Search the web for information using DuckDuckGo. Provides structured search results with titles, URLs, and snippets.',\n version: '1.0.0',\n tags: ['web', 'search', 'research'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'file-manager',\n description: 'Advanced file management operations including batch rename, find-and-replace across files, directory comparison, and file organization.',\n version: '1.0.0',\n tags: ['files', 'utility', 'management'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'code-review',\n description: 'Systematic code review following best practices. Checks for bugs, security vulnerabilities, style issues, and suggests improvements.',\n version: '1.0.0',\n tags: ['development', 'review', 'quality'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'data-analyst',\n description: 'Analyze CSV, JSON, and tabular data. Generate summaries, statistics, and insights from structured datasets.',\n version: '1.0.0',\n tags: ['data', 'analysis', 'csv', 'json'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'api-tester',\n description: 'Test REST APIs with structured request/response validation. Supports GET, POST, PUT, DELETE with headers and body.',\n version: '1.0.0',\n tags: ['api', 'testing', 'http', 'rest'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'git-workflow',\n description: 'Git workflow automation including conventional commits, branch management, PR descriptions, and changelog generation.',\n version: '1.0.0',\n tags: ['git', 'workflow', 'development'],\n author: 'AgentForge',\n source: 'builtin',\n },\n {\n name: 'browser-automation',\n description: 'Browser automation using Playwright. Navigate web pages, click elements, type text, extract content, take screenshots, and run JavaScript. Supports Docker sandbox mode for secure execution.',\n version: '1.0.0',\n tags: ['web', 'browser', 'automation', 'scraping'],\n author: 'AgentForge',\n source: 'builtin',\n },\n];\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\n/**\n * Resolve the project's skills directory.\n * Checks for workspace/skills/ first (Mastra Workspace pattern), then falls back to skills/.\n */\nfunction resolveSkillsDir(): string {\n const cwd = process.cwd();\n\n // Mastra Workspace pattern: workspace/skills/\n const workspaceSkillsDir = path.join(cwd, WORKSPACE_DIR_NAME, SKILLS_DIR_NAME);\n if (fs.existsSync(path.join(cwd, WORKSPACE_DIR_NAME))) {\n return workspaceSkillsDir;\n }\n\n // Fallback: skills/ at project root\n return path.join(cwd, SKILLS_DIR_NAME);\n}\n\n/**\n * Read the skills lockfile for tracking installed skills.\n */\nfunction readSkillsLock(skillsDir: string): SkillsLock {\n const lockPath = path.join(path.dirname(skillsDir), SKILLS_LOCK_FILE);\n if (fs.existsSync(lockPath)) {\n try {\n return JSON.parse(fs.readFileSync(lockPath, 'utf-8'));\n } catch {\n // Corrupted lock file, start fresh\n }\n }\n return { version: 1, skills: {} };\n}\n\n/**\n * Write the skills lockfile.\n */\nfunction writeSkillsLock(skillsDir: string, lock: SkillsLock): void {\n const lockPath = path.join(path.dirname(skillsDir), SKILLS_LOCK_FILE);\n fs.writeFileSync(lockPath, JSON.stringify(lock, null, 2) + '\\n');\n}\n\n/**\n * Parse SKILL.md frontmatter to extract metadata.\n * Uses a simple YAML frontmatter parser to avoid heavy dependencies.\n */\nfunction parseSkillMd(content: string): { data: SkillManifest; content: string } {\n // Dynamic import of gray-matter for YAML frontmatter parsing\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const matter = require('gray-matter');\n const parsed = matter(content);\n return {\n data: parsed.data as SkillManifest,\n content: parsed.content,\n };\n } catch {\n // Fallback: simple regex-based frontmatter parsing\n const fmMatch = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n if (!fmMatch) {\n return { data: { name: '', description: '', version: '1.0.0' }, content };\n }\n\n const frontmatter = fmMatch[1];\n const body = fmMatch[2];\n const data: Record<string, unknown> = {};\n\n for (const line of frontmatter.split('\\n')) {\n const match = line.match(/^(\\w+):\\s*(.+)$/);\n if (match) {\n const value = match[2].trim();\n data[match[1]] = value;\n }\n }\n\n return {\n data: data as unknown as SkillManifest,\n content: body,\n };\n }\n}\n\n/**\n * Read a local skill's metadata from its SKILL.md.\n */\nfunction readSkillMetadata(skillDir: string): SkillManifest | null {\n const skillMdPath = path.join(skillDir, 'SKILL.md');\n if (!fs.existsSync(skillMdPath)) return null;\n\n const content = fs.readFileSync(skillMdPath, 'utf-8');\n const { data } = parseSkillMd(content);\n return {\n name: data.name || path.basename(skillDir),\n description: data.description || '',\n version: data.version || '1.0.0',\n tags: data.tags || [],\n author: data.author || 'Unknown',\n };\n}\n\n/**\n * Find a skill in the built-in registry by name.\n */\nfunction findInRegistry(name: string): RegistryEntry | undefined {\n return BUILTIN_REGISTRY.find((s) => s.name === name);\n}\n\n// ─── Built-in Skill Content Generators ────────────────────────────────────────\n// These generate the full SKILL.md + supporting files for each built-in skill.\n\nfunction generateBuiltinSkill(name: string): Map<string, string> | null {\n const generators: Record<string, () => Map<string, string>> = {\n 'web-search': generateWebSearchSkill,\n 'file-manager': generateFileManagerSkill,\n 'code-review': generateCodeReviewSkill,\n 'data-analyst': generateDataAnalystSkill,\n 'api-tester': generateApiTesterSkill,\n 'git-workflow': generateGitWorkflowSkill,\n 'browser-automation': generateBrowserAutomationSkill,\n };\n\n const generator = generators[name];\n return generator ? generator() : null;\n}\n\nfunction generateWebSearchSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: web-search\ndescription: Search the web for information using DuckDuckGo and return structured results\nversion: 1.0.0\ntags:\n - web\n - search\n - research\n---\n\n# Web Search\n\nYou are a web research assistant. When the user asks you to search for information:\n\n1. Use the workspace sandbox to execute the search script at \\`scripts/search.ts\\`\n2. Parse the results and present them in a clear, organized format\n3. Include source URLs for all information\n4. Summarize key findings at the top\n\n## How to Search\n\nRun the search script with the user's query:\n\n\\`\\`\\`bash\nnpx tsx scripts/search.ts \"user query here\"\n\\`\\`\\`\n\nThe script returns JSON with structured results including title, URL, and snippet.\n\n## Result Format\n\nPresent results as:\n- **Title** — Brief description ([Source](url))\n- Group related results together\n- Highlight the most relevant findings first\n\n## Guidelines\n\n- Always cite sources with URLs\n- If results are insufficient, suggest refined queries\n- Cross-reference multiple results for accuracy\n- Note when information may be outdated\n`);\n\n files.set('scripts/search.ts', `#!/usr/bin/env npx tsx\n/**\n * Web Search Script — Uses DuckDuckGo Instant Answer API\n *\n * Usage: npx tsx scripts/search.ts \"your query\"\n */\n\nconst query = process.argv[2];\nif (!query) {\n console.error('Usage: npx tsx scripts/search.ts \"query\"');\n process.exit(1);\n}\n\ninterface SearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\nasync function search(q: string): Promise<SearchResult[]> {\n const url = \\`https://api.duckduckgo.com/?q=\\${encodeURIComponent(q)}&format=json&no_redirect=1&no_html=1\\`;\n const res = await fetch(url);\n const data = await res.json();\n\n const results: SearchResult[] = [];\n\n // Abstract (main answer)\n if (data.Abstract) {\n results.push({\n title: data.Heading || q,\n url: data.AbstractURL || '',\n snippet: data.Abstract,\n });\n }\n\n // Related topics\n if (data.RelatedTopics) {\n for (const topic of data.RelatedTopics) {\n if (topic.Text && topic.FirstURL) {\n results.push({\n title: topic.Text.split(' - ')[0] || topic.Text.slice(0, 80),\n url: topic.FirstURL,\n snippet: topic.Text,\n });\n }\n // Subtopics\n if (topic.Topics) {\n for (const sub of topic.Topics) {\n if (sub.Text && sub.FirstURL) {\n results.push({\n title: sub.Text.split(' - ')[0] || sub.Text.slice(0, 80),\n url: sub.FirstURL,\n snippet: sub.Text,\n });\n }\n }\n }\n }\n }\n\n return results.slice(0, 10);\n}\n\nsearch(query)\n .then((results) => console.log(JSON.stringify({ query, results, count: results.length }, null, 2)))\n .catch((err) => {\n console.error(JSON.stringify({ error: err.message }));\n process.exit(1);\n });\n`);\n\n files.set('references/search-tips.md', `# Search Tips\n\n## Effective Queries\n- Use specific keywords rather than full sentences\n- Include domain-specific terms for technical searches\n- Use quotes for exact phrase matching (in the query string)\n- Add \"site:example.com\" to limit to specific domains\n\n## Result Evaluation\n- Check the date of sources when available\n- Cross-reference claims across multiple results\n- Prefer authoritative sources (.edu, .gov, established publications)\n- Note when results are from forums vs. official documentation\n`);\n\n return files;\n}\n\nfunction generateFileManagerSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: file-manager\ndescription: Advanced file management operations including batch rename, find-and-replace, and directory organization\nversion: 1.0.0\ntags:\n - files\n - utility\n - management\n---\n\n# File Manager\n\nYou are a file management assistant. Help users organize, search, and manipulate files in the workspace.\n\n## Capabilities\n\n1. **List & Search** — Find files by name, extension, or content\n2. **Batch Rename** — Rename multiple files using patterns\n3. **Find & Replace** — Search and replace text across files\n4. **Organize** — Sort files into directories by type, date, or custom rules\n5. **Compare** — Show differences between files or directories\n\n## How to Use\n\nUse the workspace filesystem tools to perform operations:\n\n- \\`mastra_workspace_list_files\\` — List directory contents as a tree\n- \\`mastra_workspace_read_file\\` — Read file contents\n- \\`mastra_workspace_write_file\\` — Create or overwrite files\n- \\`mastra_workspace_edit_file\\` — Find and replace in files\n- \\`mastra_workspace_delete\\` — Remove files or directories\n- \\`mastra_workspace_file_stat\\` — Get file metadata (size, dates)\n- \\`mastra_workspace_mkdir\\` — Create directories\n\nFor complex operations, use \\`mastra_workspace_execute_command\\` with the scripts in this skill.\n\n## Scripts\n\n- \\`scripts/batch-rename.ts\\` — Batch rename files with pattern support\n- \\`scripts/find-replace.ts\\` — Find and replace across multiple files\n- \\`scripts/organize.ts\\` — Organize files by extension into directories\n\n## Guidelines\n\n- Always confirm destructive operations (delete, overwrite) with the user\n- Show a preview of changes before executing batch operations\n- Create backups when performing bulk modifications\n- Report the number of files affected after each operation\n`);\n\n files.set('scripts/batch-rename.ts', `#!/usr/bin/env npx tsx\n/**\n * Batch Rename Script\n *\n * Usage: npx tsx scripts/batch-rename.ts <directory> <find-pattern> <replace-pattern>\n * Example: npx tsx scripts/batch-rename.ts ./docs \"report-\" \"2026-report-\"\n */\n\nimport { readdirSync, renameSync } from 'fs';\nimport { join, basename } from 'path';\n\nconst [dir, findPattern, replacePattern] = process.argv.slice(2);\nif (!dir || !findPattern || !replacePattern) {\n console.error('Usage: npx tsx scripts/batch-rename.ts <dir> <find> <replace>');\n process.exit(1);\n}\n\nconst files = readdirSync(dir);\nconst renames: Array<{ from: string; to: string }> = [];\n\nfor (const file of files) {\n if (file.includes(findPattern)) {\n const newName = file.replace(findPattern, replacePattern);\n renames.push({ from: file, to: newName });\n }\n}\n\nif (renames.length === 0) {\n console.log(JSON.stringify({ message: 'No files matched the pattern', count: 0 }));\n process.exit(0);\n}\n\nfor (const { from, to } of renames) {\n renameSync(join(dir, from), join(dir, to));\n}\n\nconsole.log(JSON.stringify({ renames, count: renames.length }));\n`);\n\n files.set('scripts/find-replace.ts', `#!/usr/bin/env npx tsx\n/**\n * Find and Replace Script\n *\n * Usage: npx tsx scripts/find-replace.ts <directory> <find-text> <replace-text> [--ext .ts,.js]\n */\n\nimport { readdirSync, readFileSync, writeFileSync, statSync } from 'fs';\nimport { join, extname } from 'path';\n\nconst args = process.argv.slice(2);\nconst dir = args[0];\nconst findText = args[1];\nconst replaceText = args[2];\nconst extFilter = args.includes('--ext') ? args[args.indexOf('--ext') + 1]?.split(',') : null;\n\nif (!dir || !findText || replaceText === undefined) {\n console.error('Usage: npx tsx scripts/find-replace.ts <dir> <find> <replace> [--ext .ts,.js]');\n process.exit(1);\n}\n\ninterface Change { file: string; count: number; }\nconst changes: Change[] = [];\n\nfunction processDir(dirPath: string) {\n for (const entry of readdirSync(dirPath)) {\n const fullPath = join(dirPath, entry);\n const stat = statSync(fullPath);\n if (stat.isDirectory() && !entry.startsWith('.') && entry !== 'node_modules') {\n processDir(fullPath);\n } else if (stat.isFile()) {\n if (extFilter && !extFilter.includes(extname(entry))) continue;\n const content = readFileSync(fullPath, 'utf-8');\n const count = (content.match(new RegExp(findText.replace(/[.*+?^\\${}()|[\\\\]\\\\\\\\]/g, '\\\\\\\\$&'), 'g')) || []).length;\n if (count > 0) {\n const newContent = content.replaceAll(findText, replaceText);\n writeFileSync(fullPath, newContent);\n changes.push({ file: fullPath, count });\n }\n }\n }\n}\n\nprocessDir(dir);\nconsole.log(JSON.stringify({ changes, totalFiles: changes.length, totalReplacements: changes.reduce((s, c) => s + c.count, 0) }));\n`);\n\n return files;\n}\n\nfunction generateCodeReviewSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: code-review\ndescription: Systematic code review following best practices for quality, security, and style\nversion: 1.0.0\ntags:\n - development\n - review\n - quality\n---\n\n# Code Review\n\nYou are a code reviewer. When reviewing code, follow this systematic process:\n\n## Review Process\n\n1. **Critical Issues** — Security vulnerabilities, memory leaks, logic bugs, missing error handling\n2. **Code Quality** — Functions over 50 lines, code duplication, confusing names, missing types\n3. **Style Guide** — Check references/style-guide.md for naming and organization conventions\n4. **Performance** — Unnecessary re-renders, N+1 queries, missing memoization, large bundle imports\n5. **Testing** — Missing test coverage, edge cases not handled, brittle assertions\n\n## Feedback Format\n\nProvide feedback in this structure:\n\n**Summary**: One sentence overview of the code quality\n\n**Critical Issues**: List with file paths and line numbers\n- \\`file.ts:42\\` — Description of the issue\n\n**Suggestions**: Improvements that would help\n- Description of suggestion with code example\n\n**Positive Notes**: What the code does well\n\n## What to Look Out For\n\n- Unused variables and imports\n- Missing error handling (try/catch, null checks)\n- Security vulnerabilities (SQL injection, XSS, secrets in code)\n- Performance issues (unnecessary loops, missing indexes)\n- TypeScript: any types, missing return types, loose generics\n- React: missing keys, stale closures, missing deps in useEffect\n\n## Scripts\n\n- \\`scripts/lint.ts\\` — Run linting checks on a file or directory\n`);\n\n files.set('references/style-guide.md', `# Code Style Guide\n\n## TypeScript Conventions\n- Use \\`const\\` by default, \\`let\\` only when reassignment is needed\n- Prefer \\`interface\\` over \\`type\\` for object shapes\n- Always specify return types for exported functions\n- Use \\`unknown\\` instead of \\`any\\` where possible\n- Prefer \\`readonly\\` for properties that shouldn't change\n\n## Naming Conventions\n- **Files**: kebab-case (\\`my-component.tsx\\`)\n- **Components**: PascalCase (\\`MyComponent\\`)\n- **Functions**: camelCase (\\`getUserById\\`)\n- **Constants**: UPPER_SNAKE_CASE (\\`MAX_RETRIES\\`)\n- **Types/Interfaces**: PascalCase (\\`UserProfile\\`)\n\n## File Organization\n- One component per file\n- Co-locate tests with source files (\\`*.test.ts\\`)\n- Group by feature, not by type\n- Keep files under 300 lines\n\n## Error Handling\n- Always handle promise rejections\n- Use typed errors with error codes\n- Log errors with context (user ID, request ID)\n- Never swallow errors silently\n`);\n\n files.set('scripts/lint.ts', `#!/usr/bin/env npx tsx\n/**\n * Simple Lint Script — Checks for common issues\n *\n * Usage: npx tsx scripts/lint.ts <file-or-directory>\n */\n\nimport { readFileSync, readdirSync, statSync } from 'fs';\nimport { join, extname } from 'path';\n\nconst target = process.argv[2];\nif (!target) {\n console.error('Usage: npx tsx scripts/lint.ts <file-or-directory>');\n process.exit(1);\n}\n\ninterface LintIssue {\n file: string;\n line: number;\n severity: 'error' | 'warning';\n message: string;\n}\n\nconst issues: LintIssue[] = [];\n\nfunction lintFile(filePath: string) {\n const content = readFileSync(filePath, 'utf-8');\n const lines = content.split('\\\\n');\n\n lines.forEach((line, i) => {\n const lineNum = i + 1;\n // Check for console.log\n if (line.includes('console.log') && !filePath.includes('test')) {\n issues.push({ file: filePath, line: lineNum, severity: 'warning', message: 'console.log found — remove before production' });\n }\n // Check for debugger\n if (line.trim() === 'debugger' || line.trim() === 'debugger;') {\n issues.push({ file: filePath, line: lineNum, severity: 'error', message: 'debugger statement found' });\n }\n // Check for any type\n if (line.includes(': any') || line.includes('<any>')) {\n issues.push({ file: filePath, line: lineNum, severity: 'warning', message: 'Use of \"any\" type — prefer \"unknown\" or specific type' });\n }\n // Check for var usage\n if (/\\\\bvar\\\\s+/.test(line)) {\n issues.push({ file: filePath, line: lineNum, severity: 'error', message: 'Use \"const\" or \"let\" instead of \"var\"' });\n }\n // Check for TODO/FIXME\n if (/\\\\/\\\\/\\\\s*(TODO|FIXME|HACK|XXX)/.test(line)) {\n issues.push({ file: filePath, line: lineNum, severity: 'warning', message: 'Unresolved TODO/FIXME comment' });\n }\n });\n}\n\nfunction processPath(p: string) {\n const stat = statSync(p);\n if (stat.isFile() && ['.ts', '.tsx', '.js', '.jsx'].includes(extname(p))) {\n lintFile(p);\n } else if (stat.isDirectory()) {\n for (const entry of readdirSync(p)) {\n if (!entry.startsWith('.') && entry !== 'node_modules' && entry !== 'dist') {\n processPath(join(p, entry));\n }\n }\n }\n}\n\nprocessPath(target);\nconsole.log(JSON.stringify({ issues, total: issues.length, errors: issues.filter(i => i.severity === 'error').length, warnings: issues.filter(i => i.severity === 'warning').length }));\n`);\n\n return files;\n}\n\nfunction generateDataAnalystSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: data-analyst\ndescription: Analyze CSV, JSON, and tabular data to generate summaries, statistics, and insights\nversion: 1.0.0\ntags:\n - data\n - analysis\n - csv\n - json\n---\n\n# Data Analyst\n\nYou are a data analysis assistant. Help users understand and extract insights from structured data.\n\n## Capabilities\n\n1. **Load Data** — Read CSV, JSON, and TSV files from the workspace\n2. **Summarize** — Generate column statistics (min, max, mean, median, mode)\n3. **Filter & Query** — Filter rows by conditions, select columns\n4. **Aggregate** — Group by columns and compute aggregates\n5. **Detect Anomalies** — Find outliers and missing values\n\n## How to Analyze\n\n1. First, read the data file using workspace filesystem tools\n2. Use \\`scripts/analyze.ts\\` for statistical analysis\n3. Present findings in a clear table format\n4. Suggest follow-up analyses based on initial findings\n\n## Scripts\n\n- \\`scripts/analyze.ts\\` — Compute statistics on CSV/JSON data\n\n## Output Format\n\nPresent analysis results as:\n- **Dataset Overview**: Row count, column count, column types\n- **Key Statistics**: Per-column min, max, mean, median\n- **Missing Data**: Columns with null/empty values and their percentages\n- **Insights**: Notable patterns, correlations, or anomalies\n\n## Guidelines\n\n- Always show a sample of the data (first 5 rows) before analysis\n- Handle missing values gracefully — report them, don't crash\n- Use appropriate precision for numbers (2 decimal places for percentages)\n- Suggest visualizations when patterns would be clearer in chart form\n`);\n\n files.set('scripts/analyze.ts', `#!/usr/bin/env npx tsx\n/**\n * Data Analysis Script — Basic statistics for CSV/JSON data\n *\n * Usage: npx tsx scripts/analyze.ts <file.csv|file.json>\n */\n\nimport { readFileSync } from 'fs';\nimport { extname } from 'path';\n\nconst filePath = process.argv[2];\nif (!filePath) {\n console.error('Usage: npx tsx scripts/analyze.ts <file.csv|file.json>');\n process.exit(1);\n}\n\nfunction parseCSV(content: string): Record<string, string>[] {\n const lines = content.trim().split('\\\\n');\n const headers = lines[0].split(',').map(h => h.trim().replace(/^\"|\"$/g, ''));\n return lines.slice(1).map(line => {\n const values = line.split(',').map(v => v.trim().replace(/^\"|\"$/g, ''));\n return Object.fromEntries(headers.map((h, i) => [h, values[i] ?? '']));\n });\n}\n\nconst content = readFileSync(filePath, 'utf-8');\nconst ext = extname(filePath).toLowerCase();\nlet data: Record<string, string>[];\n\nif (ext === '.json') {\n const parsed = JSON.parse(content);\n data = Array.isArray(parsed) ? parsed : [parsed];\n} else {\n data = parseCSV(content);\n}\n\nconst columns = Object.keys(data[0] || {});\nconst stats: Record<string, any> = {};\n\nfor (const col of columns) {\n const values = data.map(row => row[col]).filter(v => v !== '' && v !== null && v !== undefined);\n const numValues = values.map(Number).filter(n => !isNaN(n));\n\n stats[col] = {\n total: data.length,\n nonNull: values.length,\n missing: data.length - values.length,\n missingPct: ((data.length - values.length) / data.length * 100).toFixed(1) + '%',\n unique: new Set(values).size,\n };\n\n if (numValues.length > 0) {\n numValues.sort((a, b) => a - b);\n stats[col].type = 'numeric';\n stats[col].min = Math.min(...numValues);\n stats[col].max = Math.max(...numValues);\n stats[col].mean = +(numValues.reduce((s, n) => s + n, 0) / numValues.length).toFixed(2);\n stats[col].median = numValues.length % 2 === 0\n ? +((numValues[numValues.length / 2 - 1] + numValues[numValues.length / 2]) / 2).toFixed(2)\n : numValues[Math.floor(numValues.length / 2)];\n } else {\n stats[col].type = 'string';\n stats[col].sample = values.slice(0, 3);\n }\n}\n\nconsole.log(JSON.stringify({\n rows: data.length,\n columns: columns.length,\n columnNames: columns,\n stats,\n sample: data.slice(0, 5),\n}, null, 2));\n`);\n\n return files;\n}\n\nfunction generateApiTesterSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: api-tester\ndescription: Test REST APIs with structured request/response validation\nversion: 1.0.0\ntags:\n - api\n - testing\n - http\n - rest\n---\n\n# API Tester\n\nYou are an API testing assistant. Help users test and validate REST API endpoints.\n\n## Capabilities\n\n1. **Send Requests** — GET, POST, PUT, PATCH, DELETE with headers and body\n2. **Validate Responses** — Check status codes, response structure, and timing\n3. **Chain Requests** — Use output from one request as input to another\n4. **Generate Reports** — Summarize test results with pass/fail status\n\n## How to Test\n\nUse \\`scripts/request.ts\\` to make HTTP requests:\n\n\\`\\`\\`bash\nnpx tsx scripts/request.ts GET https://api.example.com/users\nnpx tsx scripts/request.ts POST https://api.example.com/users --body '{\"name\":\"test\"}'\n\\`\\`\\`\n\n## Report Format\n\nFor each API test, report:\n- **Endpoint**: METHOD URL\n- **Status**: HTTP status code (with pass/fail indicator)\n- **Response Time**: Duration in milliseconds\n- **Response Body**: Formatted JSON (truncated if large)\n- **Headers**: Key response headers\n\n## Guidelines\n\n- Always show the full request details (method, URL, headers, body)\n- Time every request and flag slow responses (>2s)\n- Validate JSON response structure when a schema is provided\n- Never send real credentials — use placeholders and warn the user\n- Group related tests together (e.g., CRUD operations on one resource)\n`);\n\n files.set('scripts/request.ts', `#!/usr/bin/env npx tsx\n/**\n * HTTP Request Script — Make API requests from the command line\n *\n * Usage: npx tsx scripts/request.ts <METHOD> <URL> [--header \"Key: Value\"] [--body '{\"key\":\"value\"}']\n */\n\nconst args = process.argv.slice(2);\nconst method = args[0]?.toUpperCase() || 'GET';\nconst url = args[1];\n\nif (!url) {\n console.error('Usage: npx tsx scripts/request.ts <METHOD> <URL> [--header \"K: V\"] [--body JSON]');\n process.exit(1);\n}\n\nconst headers: Record<string, string> = { 'Content-Type': 'application/json' };\nlet body: string | undefined;\n\nfor (let i = 2; i < args.length; i++) {\n if (args[i] === '--header' && args[i + 1]) {\n const [key, ...valueParts] = args[++i].split(':');\n headers[key.trim()] = valueParts.join(':').trim();\n }\n if (args[i] === '--body' && args[i + 1]) {\n body = args[++i];\n }\n}\n\nasync function makeRequest() {\n const start = Date.now();\n const res = await fetch(url, {\n method,\n headers,\n ...(body && method !== 'GET' ? { body } : {}),\n });\n const elapsed = Date.now() - start;\n const responseHeaders: Record<string, string> = {};\n res.headers.forEach((v, k) => { responseHeaders[k] = v; });\n\n let responseBody: any;\n const contentType = res.headers.get('content-type') || '';\n if (contentType.includes('json')) {\n responseBody = await res.json();\n } else {\n responseBody = await res.text();\n }\n\n console.log(JSON.stringify({\n request: { method, url, headers, body: body ? JSON.parse(body) : undefined },\n response: {\n status: res.status,\n statusText: res.statusText,\n headers: responseHeaders,\n body: responseBody,\n timeMs: elapsed,\n },\n }, null, 2));\n}\n\nmakeRequest().catch((err) => {\n console.error(JSON.stringify({ error: err.message }));\n process.exit(1);\n});\n`);\n\n return files;\n}\n\nfunction generateGitWorkflowSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: git-workflow\ndescription: Git workflow automation including conventional commits, branch management, and changelog generation\nversion: 1.0.0\ntags:\n - git\n - workflow\n - development\n---\n\n# Git Workflow\n\nYou are a Git workflow assistant. Help users follow best practices for version control.\n\n## Capabilities\n\n1. **Conventional Commits** — Generate commit messages following the Conventional Commits spec\n2. **Branch Management** — Create, switch, and clean up branches following naming conventions\n3. **PR Descriptions** — Generate pull request descriptions from commit history\n4. **Changelog** — Generate changelogs from commit history\n\n## Conventional Commit Format\n\n\\`\\`\\`\n<type>(<scope>): <description>\n\n[optional body]\n\n[optional footer(s)]\n\\`\\`\\`\n\n### Types\n- \\`feat\\`: New feature (MINOR version bump)\n- \\`fix\\`: Bug fix (PATCH version bump)\n- \\`docs\\`: Documentation changes\n- \\`style\\`: Code style changes (formatting, semicolons)\n- \\`refactor\\`: Code refactoring (no feature/fix)\n- \\`perf\\`: Performance improvements\n- \\`test\\`: Adding or updating tests\n- \\`chore\\`: Build process, tooling, dependencies\n\n## Branch Naming\n\n- \\`feat/<ticket>-<description>\\` — New features\n- \\`fix/<ticket>-<description>\\` — Bug fixes\n- \\`chore/<description>\\` — Maintenance tasks\n- \\`release/<version>\\` — Release branches\n\n## Scripts\n\n- \\`scripts/changelog.ts\\` — Generate changelog from git log\n\n## Guidelines\n\n- One logical change per commit\n- Write commit messages in imperative mood (\"Add feature\" not \"Added feature\")\n- Reference issue/ticket numbers in commits\n- Keep PR descriptions focused on the \"what\" and \"why\"\n- Squash fix-up commits before merging\n`);\n\n files.set('references/commit-examples.md', `# Commit Message Examples\n\n## Good Examples\n\\`\\`\\`\nfeat(auth): add OAuth2 login with Google provider\nfix(api): handle null response from payment gateway\ndocs(readme): add deployment instructions for Cloudflare\nrefactor(db): extract query builder into separate module\nperf(search): add index on user_email column\ntest(auth): add integration tests for JWT refresh flow\nchore(deps): upgrade @mastra/core to 1.4.0\n\\`\\`\\`\n\n## Bad Examples\n\\`\\`\\`\nfixed stuff\nupdate\nWIP\nasdf\nchanges\n\\`\\`\\`\n`);\n\n files.set('scripts/changelog.ts', `#!/usr/bin/env npx tsx\n/**\n * Changelog Generator — Generate changelog from git log\n *\n * Usage: npx tsx scripts/changelog.ts [--since v1.0.0] [--until HEAD]\n */\n\nimport { execSync } from 'child_process';\n\nconst args = process.argv.slice(2);\nlet since = '';\nlet until = 'HEAD';\n\nfor (let i = 0; i < args.length; i++) {\n if (args[i] === '--since' && args[i + 1]) since = args[++i];\n if (args[i] === '--until' && args[i + 1]) until = args[++i];\n}\n\nconst range = since ? \\`\\${since}..\\${until}\\` : until;\nconst log = execSync(\\`git log \\${range} --pretty=format:\"%H|%s|%an|%ai\" 2>/dev/null || echo \"\"\\`, { encoding: 'utf-8' });\n\ninterface Commit {\n hash: string;\n message: string;\n author: string;\n date: string;\n type: string;\n scope: string;\n description: string;\n}\n\nconst commits: Commit[] = log.trim().split('\\\\n').filter(Boolean).map(line => {\n const [hash, message, author, date] = line.split('|');\n const match = message.match(/^(\\\\w+)(?:\\\\(([^)]+)\\\\))?:\\\\s*(.+)$/);\n return {\n hash: hash.slice(0, 7),\n message,\n author,\n date: date.split(' ')[0],\n type: match?.[1] || 'other',\n scope: match?.[2] || '',\n description: match?.[3] || message,\n };\n});\n\nconst grouped: Record<string, Commit[]> = {};\nfor (const c of commits) {\n if (!grouped[c.type]) grouped[c.type] = [];\n grouped[c.type].push(c);\n}\n\nconst typeLabels: Record<string, string> = {\n feat: 'Features',\n fix: 'Bug Fixes',\n docs: 'Documentation',\n refactor: 'Refactoring',\n perf: 'Performance',\n test: 'Tests',\n chore: 'Chores',\n};\n\nlet changelog = '# Changelog\\\\n\\\\n';\nfor (const [type, label] of Object.entries(typeLabels)) {\n if (grouped[type]?.length) {\n changelog += \\`## \\${label}\\\\n\\\\n\\`;\n for (const c of grouped[type]) {\n const scope = c.scope ? \\`**\\${c.scope}**: \\` : '';\n changelog += \\`- \\${scope}\\${c.description} (\\${c.hash})\\\\n\\`;\n }\n changelog += '\\\\n';\n }\n}\n\nconsole.log(JSON.stringify({ changelog, totalCommits: commits.length, types: Object.keys(grouped) }));\n`);\n\n return files;\n}\n\nfunction generateBrowserAutomationSkill(): Map<string, string> {\n const files = new Map<string, string>();\n\n files.set('SKILL.md', `---\nname: browser-automation\ndescription: Browser automation using Playwright. Navigate web pages, interact with elements, extract content, take screenshots, and run JavaScript.\nversion: 1.0.0\ntags:\n - web\n - browser\n - automation\n - scraping\n---\n\n# Browser Automation\n\nYou are a browser automation assistant. Help users interact with web pages programmatically.\n\n## Capabilities\n\n1. **Navigate** — Go to any URL and wait for the page to load\n2. **Click** — Click elements by CSS selector\n3. **Type** — Fill text into input fields\n4. **Screenshot** — Capture the current page as an image\n5. **Extract Text** — Get readable text content from pages or specific elements\n6. **Snapshot** — Get the accessibility tree for understanding page structure\n7. **Evaluate** — Run arbitrary JavaScript on the page\n8. **Wait** — Wait for elements to appear or for a specific duration\n9. **Scroll** — Scroll the page up or down\n10. **Select** — Choose options from dropdown menus\n11. **Hover** — Hover over elements to trigger menus or tooltips\n12. **Navigation** — Go back, forward, or reload the page\n\n## How to Use\n\n### Setup\n\n\\`\\`\\`typescript\nimport { createBrowserTool, MCPServer } from '@agentforge-ai/core';\n\nconst server = new MCPServer({ name: 'my-tools' });\nconst { tool, shutdown } = createBrowserTool({ headless: true });\nserver.registerTool(tool);\n\\`\\`\\`\n\n### Docker Sandbox Mode\n\nFor secure, isolated execution:\n\n\\`\\`\\`typescript\nconst { tool, shutdown } = createBrowserTool({\n sandboxMode: true,\n headless: true,\n});\n\\`\\`\\`\n\n## Agent Instructions\n\n1. Navigate to the target URL first\n2. Wait for key elements before interacting\n3. Use snapshot to understand page structure\n4. Use extractText to get readable content\n5. Use click and type for form interactions\n6. Take screenshots for visual verification\n7. Always close sessions when done\n\n## Guidelines\n\n- Prefer \\`#id\\` selectors over class-based selectors\n- Use \\`wait\\` before clicking or typing on dynamic pages\n- Use \\`extractText\\` with a selector for specific content\n- Take screenshots before and after critical actions\n- Close sessions to free resources\n`);\n\n files.set('references/selectors.md', `# CSS Selector Guide for Browser Automation\n\n## Recommended Selectors (most to least reliable)\n\n1. \\`#id\\` — Element with a specific ID\n2. \\`[data-testid=\"value\"]\\` — Test ID attributes\n3. \\`[aria-label=\"value\"]\\` — Accessibility labels\n4. \\`button:has-text(\"Click me\")\\` — Playwright text selectors\n5. \\`.class-name\\` — CSS class selectors\n6. \\`tag.class\\` — Tag + class combination\n\n## Examples\n\n\\`\\`\\`\n#login-button → Click the login button\ninput[name=\"email\"] → Type into email field\n.nav-menu a:first-child → Click first nav link\nform button[type=submit] → Submit a form\n\\`\\`\\`\n\n## Tips\n\n- Avoid fragile selectors like \\`div > div > span:nth-child(3)\\`\n- Use Playwright's text selectors: \\`text=Submit\\`\n- For dynamic content, wait for the element first\n- Use \\`snapshot\\` action to discover available selectors\n`);\n\n files.set('scripts/scrape.ts', `#!/usr/bin/env npx tsx\n/**\n * Example: Scrape a web page and extract its text content\n *\n * Usage: npx tsx scripts/scrape.ts <url>\n */\n\nconst url = process.argv[2];\nif (!url) {\n console.error('Usage: npx tsx scripts/scrape.ts <url>');\n process.exit(1);\n}\n\nconsole.log(JSON.stringify({\n instruction: 'Use the browser tool to scrape this URL',\n url,\n steps: [\n { action: 'navigate', url },\n { action: 'wait', timeMs: 2000 },\n { action: 'extractText' },\n { action: 'screenshot', fullPage: true },\n { action: 'close' },\n ],\n}));\n`);\n\n return files;\n}\n\n// ─── Command Registration ─────────────────────────────────────────────────────\n\nexport function registerSkillsCommand(program: Command) {\n const skills = program.command('skills').description('Manage agent skills (Mastra Workspace Skills)');\n\n // ─── skills list ──────────────────────────────────────────────────\n skills\n .command('list')\n .option('--json', 'Output as JSON')\n .option('--registry', 'Show available skills from the registry')\n .description('List installed skills or browse the registry')\n .action(async (opts) => {\n if (opts.registry) {\n // Show the built-in registry\n header('AgentForge Skills Registry');\n if (opts.json) {\n console.log(JSON.stringify(BUILTIN_REGISTRY, null, 2));\n return;\n }\n table(BUILTIN_REGISTRY.map((s) => ({\n Name: s.name,\n Description: truncate(s.description, 60),\n Version: s.version,\n Tags: s.tags.join(', '),\n })));\n info(`Install with: ${colors.cyan}agentforge skills install <name>${colors.reset}`);\n return;\n }\n\n // Show installed skills\n const skillsDir = resolveSkillsDir();\n header('Installed Skills');\n\n if (!fs.existsSync(skillsDir)) {\n info('No skills directory found. Install a skill with:');\n dim(` agentforge skills install <name>`);\n dim(` agentforge skills list --registry # browse available skills`);\n return;\n }\n\n const dirs = fs.readdirSync(skillsDir).filter((d: string) => {\n const fullPath = path.join(skillsDir, d);\n return fs.statSync(fullPath).isDirectory() && fs.existsSync(path.join(fullPath, 'SKILL.md'));\n });\n\n if (dirs.length === 0) {\n info('No skills installed. Browse available skills with:');\n dim(` agentforge skills list --registry`);\n return;\n }\n\n const lock = readSkillsLock(skillsDir);\n\n const skillData = dirs.map((d: string) => {\n const meta = readSkillMetadata(path.join(skillsDir, d));\n const lockEntry = lock.skills[d];\n return {\n Name: meta?.name || d,\n Description: truncate(meta?.description || '', 50),\n Version: meta?.version || '?',\n Tags: (meta?.tags || []).join(', '),\n Source: lockEntry?.source || 'local',\n Installed: lockEntry?.installedAt ? new Date(lockEntry.installedAt).toLocaleDateString() : '—',\n };\n });\n\n if (opts.json) {\n console.log(JSON.stringify(skillData, null, 2));\n return;\n }\n\n table(skillData);\n dim(` Skills directory: ${skillsDir}`);\n info('Skills are auto-discovered by the Mastra Workspace.');\n });\n\n // ─── skills install ───────────────────────────────────────────────\n skills\n .command('install')\n .argument('<name>', 'Skill name from registry, GitHub URL, or local path')\n .option('--from <source>', 'Source: registry (default), github, local', 'registry')\n .description('Install a skill into the workspace')\n .action(async (name, opts) => {\n const skillsDir = resolveSkillsDir();\n const targetDir = path.join(skillsDir, name.split('/').pop()!.replace(/\\.git$/, ''));\n\n // Check if already installed\n if (fs.existsSync(targetDir) && fs.existsSync(path.join(targetDir, 'SKILL.md'))) {\n warn(`Skill \"${name}\" is already installed at ${targetDir}`);\n const overwrite = await prompt('Overwrite? (y/N): ');\n if (overwrite.toLowerCase() !== 'y') {\n info('Installation cancelled.');\n return;\n }\n fs.removeSync(targetDir);\n }\n\n // Ensure skills directory exists\n fs.mkdirSync(skillsDir, { recursive: true });\n\n let source: string = opts.from;\n let installedName = name;\n\n if (opts.from === 'local' || fs.existsSync(name)) {\n // ─── Install from local path ─────────────────────────────\n source = 'local';\n const sourcePath = path.resolve(name);\n if (!fs.existsSync(sourcePath)) {\n error(`Local path not found: ${sourcePath}`);\n process.exit(1);\n }\n if (!fs.existsSync(path.join(sourcePath, 'SKILL.md'))) {\n error(`No SKILL.md found in ${sourcePath}. Not a valid skill directory.`);\n process.exit(1);\n }\n installedName = path.basename(sourcePath);\n const dest = path.join(skillsDir, installedName);\n fs.copySync(sourcePath, dest);\n success(`Skill \"${installedName}\" installed from local path.`);\n\n } else if (opts.from === 'github' || name.includes('github.com') || name.includes('/')) {\n // ─── Install from GitHub ─────────────────────────────────\n source = 'github';\n const repoUrl = name.includes('github.com') ? name : `https://github.com/${name}`;\n installedName = name.split('/').pop()!.replace(/\\.git$/, '');\n const dest = path.join(skillsDir, installedName);\n\n info(`Cloning skill from ${repoUrl}...`);\n try {\n execSync(`git clone --depth 1 ${repoUrl} ${dest} 2>&1`, { encoding: 'utf-8' });\n // Remove .git directory\n fs.removeSync(path.join(dest, '.git'));\n\n if (!fs.existsSync(path.join(dest, 'SKILL.md'))) {\n error(`Cloned repo does not contain a SKILL.md. Not a valid skill.`);\n fs.removeSync(dest);\n process.exit(1);\n }\n success(`Skill \"${installedName}\" installed from GitHub.`);\n } catch (err: unknown) {\n error(`Failed to clone: ${(err as Error).message}`);\n process.exit(1);\n }\n\n } else {\n // ─── Install from built-in registry ──────────────────────\n source = 'builtin';\n const entry = findInRegistry(name);\n if (!entry) {\n error(`Skill \"${name}\" not found in the registry.`);\n info('Available skills:');\n BUILTIN_REGISTRY.forEach((s) => {\n dim(` ${colors.cyan}${s.name}${colors.reset} — ${s.description}`);\n });\n info(`\\nOr install from GitHub: ${colors.cyan}agentforge skills install owner/repo --from github${colors.reset}`);\n process.exit(1);\n }\n\n installedName = entry.name;\n const files = generateBuiltinSkill(entry.name);\n if (!files) {\n error(`No content generator for skill \"${entry.name}\".`);\n process.exit(1);\n }\n\n const dest = path.join(skillsDir, installedName);\n fs.mkdirSync(dest, { recursive: true });\n\n for (const [filePath, content] of files) {\n const fullPath = path.join(dest, filePath);\n fs.mkdirSync(path.dirname(fullPath), { recursive: true });\n fs.writeFileSync(fullPath, content);\n }\n\n success(`Skill \"${installedName}\" installed from AgentForge registry.`);\n }\n\n // Update lockfile\n const lock = readSkillsLock(skillsDir);\n const meta = readSkillMetadata(path.join(skillsDir, installedName));\n lock.skills[installedName] = {\n name: installedName,\n version: meta?.version || '1.0.0',\n source,\n installedAt: new Date().toISOString(),\n };\n writeSkillsLock(skillsDir, lock);\n\n // Show skill info\n if (meta) {\n console.log();\n details({\n Name: meta.name,\n Description: meta.description,\n Version: meta.version,\n Tags: (meta.tags || []).join(', ') || '—',\n Path: path.join(skillsDir, installedName),\n });\n }\n\n info('The skill is now available to agents via the Mastra Workspace.');\n dim(' Skills in the workspace/skills/ directory are auto-discovered.');\n\n // Sync to Convex if available (best-effort)\n try {\n const client = await createClient();\n await safeCall(\n () => client.mutation('skills:create' as any, {\n name: installedName,\n displayName: meta?.name || installedName,\n description: meta?.description || '',\n category: (meta?.tags || [])[0] || 'custom',\n version: meta?.version || '1.0.0',\n author: meta?.author || 'Unknown',\n code: `// Skill: ${installedName}\\n// This skill uses the Agent Skills Specification (SKILL.md format)\\n// See: workspace/skills/${installedName}/SKILL.md`,\n }),\n 'Failed to sync skill to Convex'\n );\n dim(' Skill synced to Convex database.');\n } catch {\n // Convex not available — that's fine, skills work locally via filesystem\n dim(' Convex not connected — skill installed locally only.');\n }\n });\n\n // ─── skills remove ────────────────────────────────────────────────\n skills\n .command('remove')\n .argument('<name>', 'Skill name to remove')\n .option('--force', 'Skip confirmation prompt', false)\n .description('Remove an installed skill')\n .action(async (name, opts) => {\n const skillsDir = resolveSkillsDir();\n const skillDir = path.join(skillsDir, name);\n\n if (!fs.existsSync(skillDir)) {\n error(`Skill \"${name}\" not found in ${skillsDir}`);\n info('List installed skills with: agentforge skills list');\n process.exit(1);\n }\n\n if (!opts.force) {\n const confirm = await prompt(`Remove skill \"${name}\" and delete all files? (y/N): `);\n if (confirm.toLowerCase() !== 'y') {\n info('Removal cancelled.');\n return;\n }\n }\n\n // Remove from filesystem\n fs.removeSync(skillDir);\n success(`Skill \"${name}\" removed from disk.`);\n\n // Remove from lockfile\n const lock = readSkillsLock(skillsDir);\n delete lock.skills[name];\n writeSkillsLock(skillsDir, lock);\n\n // Remove from Convex (best-effort)\n try {\n const client = await createClient();\n const skills = await client.query('skills:list' as any, {});\n const skill = (skills as any[]).find((s: any) => s.name === name);\n if (skill) {\n await client.mutation('skills:remove' as any, { id: skill._id });\n dim(' Skill removed from Convex database.');\n }\n } catch {\n // Convex not available — that's fine\n }\n\n info('Skill removed. Agents will no longer discover it.');\n });\n\n // ─── skills search ────────────────────────────────────────────────\n skills\n .command('search')\n .argument('<query>', 'Search query')\n .description('Search for skills in the registry')\n .action(async (query) => {\n header('Skill Search Results');\n const q = query.toLowerCase();\n const matches = BUILTIN_REGISTRY.filter(\n (e) =>\n e.name.includes(q) ||\n e.description.toLowerCase().includes(q) ||\n e.tags.some((t) => t.includes(q))\n );\n\n if (matches.length === 0) {\n info(`No skills matching \"${query}\".`);\n info('Browse all skills: agentforge skills list --registry');\n return;\n }\n\n table(matches.map((e) => ({\n Name: e.name,\n Description: truncate(e.description, 60),\n Tags: e.tags.join(', '),\n Version: e.version,\n })));\n info(`Install with: ${colors.cyan}agentforge skills install <name>${colors.reset}`);\n });\n\n // ─── skills create ────────────────────────────────────────────────\n skills\n .command('create')\n .description('Create a new skill (interactive)')\n .option('--name <name>', 'Skill name (kebab-case)')\n .option('--description <desc>', 'Skill description')\n .option('--tags <tags>', 'Comma-separated tags')\n .action(async (opts) => {\n const name = opts.name || await prompt('Skill name (kebab-case): ');\n const description = opts.description || await prompt('Description: ');\n const tagsInput = opts.tags || await prompt('Tags (comma-separated, e.g. web,search): ');\n const tags = tagsInput ? tagsInput.split(',').map((t: string) => t.trim()).filter(Boolean) : [];\n\n if (!name) { error('Skill name is required.'); process.exit(1); }\n if (!/^[a-z][a-z0-9-]*$/.test(name)) {\n error('Skill name must be kebab-case (lowercase letters, numbers, hyphens).');\n process.exit(1);\n }\n\n const skillsDir = resolveSkillsDir();\n const skillDir = path.join(skillsDir, name);\n\n if (fs.existsSync(skillDir)) {\n error(`Skill \"${name}\" already exists at ${skillDir}`);\n process.exit(1);\n }\n\n // Create skill directory structure\n fs.mkdirSync(path.join(skillDir, 'references'), { recursive: true });\n fs.mkdirSync(path.join(skillDir, 'scripts'), { recursive: true });\n\n // SKILL.md (Agent Skills Specification format)\n const tagsYaml = tags.length > 0\n ? `tags:\\n${tags.map((t: string) => ` - ${t}`).join('\\n')}`\n : 'tags: []';\n\n fs.writeFileSync(path.join(skillDir, 'SKILL.md'), `---\nname: ${name}\ndescription: ${description}\nversion: 1.0.0\n${tagsYaml}\n---\n\n# ${name.split('-').map((w: string) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')}\n\n${description}\n\n## Instructions\n\n<!-- Add instructions for how the agent should use this skill -->\n\n1. Step one\n2. Step two\n3. Step three\n\n## References\n\nSee \\`references/\\` for supporting documentation.\n\n## Scripts\n\nSee \\`scripts/\\` for executable scripts the agent can run.\n\n## Guidelines\n\n- Guideline one\n- Guideline two\n`);\n\n // Placeholder reference\n fs.writeFileSync(path.join(skillDir, 'references', 'README.md'),\n `# References for ${name}\\n\\nAdd supporting documentation here.\\n`);\n\n // Placeholder script\n fs.writeFileSync(path.join(skillDir, 'scripts', 'example.ts'),\n `#!/usr/bin/env npx tsx\\n/**\\n * Example script for ${name}\\n */\\nconsole.log('Hello from ${name}!');\\n`);\n\n // Update lockfile\n const lock = readSkillsLock(skillsDir);\n lock.skills[name] = {\n name,\n version: '1.0.0',\n source: 'local',\n installedAt: new Date().toISOString(),\n };\n writeSkillsLock(skillsDir, lock);\n\n success(`Skill \"${name}\" created at ${skillDir}/`);\n info('Files created:');\n dim(` ${skillDir}/SKILL.md`);\n dim(` ${skillDir}/references/README.md`);\n dim(` ${skillDir}/scripts/example.ts`);\n console.log();\n info(`Edit ${colors.cyan}SKILL.md${colors.reset} to add instructions for your agent.`);\n info('The skill will be auto-discovered by the Mastra Workspace.');\n });\n\n // ─── skills info ──────────────────────────────────────────────────\n skills\n .command('info')\n .argument('<name>', 'Skill name')\n .description('Show detailed information about a skill')\n .action(async (name) => {\n // Check installed first\n const skillsDir = resolveSkillsDir();\n const skillDir = path.join(skillsDir, name);\n\n if (fs.existsSync(skillDir) && fs.existsSync(path.join(skillDir, 'SKILL.md'))) {\n const meta = readSkillMetadata(skillDir);\n const lock = readSkillsLock(skillsDir);\n const lockEntry = lock.skills[name];\n\n header(`Skill: ${meta?.name || name}`);\n details({\n Name: meta?.name || name,\n Description: meta?.description || '—',\n Version: meta?.version || '—',\n Tags: (meta?.tags || []).join(', ') || '—',\n Author: meta?.author || '—',\n Source: lockEntry?.source || 'local',\n 'Installed At': lockEntry?.installedAt || '—',\n Path: skillDir,\n });\n\n // List files\n dim(' Files:');\n const listFiles = (dir: string, prefix: string = '') => {\n const entries = fs.readdirSync(dir);\n for (const entry of entries) {\n const fullPath = path.join(dir, entry);\n const stat = fs.statSync(fullPath);\n if (stat.isDirectory()) {\n dim(` ${prefix}${entry}/`);\n listFiles(fullPath, prefix + ' ');\n } else {\n dim(` ${prefix}${entry}`);\n }\n }\n };\n listFiles(skillDir, ' ');\n console.log();\n\n // Show SKILL.md content\n const content = fs.readFileSync(path.join(skillDir, 'SKILL.md'), 'utf-8');\n const { content: body } = parseSkillMd(content);\n info('Instructions preview:');\n dim(body.trim().split('\\n').slice(0, 10).map((l: string) => ` ${l}`).join('\\n'));\n if (body.trim().split('\\n').length > 10) {\n dim(' ...');\n }\n return;\n }\n\n // Check registry\n const entry = findInRegistry(name);\n if (entry) {\n header(`Registry Skill: ${entry.name}`);\n details({\n Name: entry.name,\n Description: entry.description,\n Version: entry.version,\n Tags: entry.tags.join(', '),\n Author: entry.author,\n Source: entry.source,\n Status: 'Not installed',\n });\n info(`Install with: ${colors.cyan}agentforge skills install ${entry.name}${colors.reset}`);\n return;\n }\n\n error(`Skill \"${name}\" not found (installed or in registry).`);\n });\n\n // ─── Top-level alias: agentforge install <skill> ──────────────────\n program\n .command('install')\n .argument('<name>', 'Skill name to install')\n .option('--from <source>', 'Source: registry (default), github, local', 'registry')\n .description('Install a skill (alias for: agentforge skills install)')\n .action(async (name, opts) => {\n // Delegate to skills install\n const skillsCmd = skills.commands.find((c) => c.name() === 'install');\n if (skillsCmd) {\n await skillsCmd.parseAsync([name, ...(opts.from !== 'registry' ? ['--from', opts.from] : [])], { from: 'user' });\n }\n });\n}\n","import type { Command } from 'commander';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { execFileSync } from 'node:child_process';\nimport { header, table, success, error, info, dim, truncate, colors } from '../lib/display.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ninterface SkillMetadata {\n name: string;\n description: string;\n version: string;\n}\n\n// ─── Utility Functions (exported for testing) ─────────────────────────────────\n\n/**\n * Returns the global skills directory: ~/.agentforge/skills/\n */\nexport function getGlobalSkillsDir(): string {\n return path.join(os.homedir(), '.agentforge', 'skills');\n}\n\n/**\n * Parse SKILL.md frontmatter to extract metadata.\n * Uses a simple regex-based YAML frontmatter parser.\n */\nfunction parseSkillMd(content: string): SkillMetadata {\n const fmMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!fmMatch) {\n return { name: '', description: '', version: '1.0.0' };\n }\n\n const frontmatter = fmMatch[1];\n const data: Record<string, string> = {};\n\n for (const line of frontmatter.split('\\n')) {\n const match = line.match(/^(\\w+):\\s*(.+)$/);\n if (match) {\n data[match[1]] = match[2].trim();\n }\n }\n\n return {\n name: data['name'] || '',\n description: data['description'] || '',\n version: data['version'] || '1.0.0',\n };\n}\n\n/**\n * Install a skill from a local directory path into the global skills dir.\n * Returns the path where the skill was installed.\n */\nexport async function installSkillFromPath(\n sourcePath: string,\n skillsDir: string\n): Promise<string> {\n if (!(await fs.pathExists(sourcePath))) {\n throw new Error(`Source path not found: ${sourcePath}`);\n }\n\n const skillMdPath = path.join(sourcePath, 'SKILL.md');\n if (!(await fs.pathExists(skillMdPath))) {\n throw new Error(`No SKILL.md found in ${sourcePath}. Not a valid skill directory.`);\n }\n\n const skillName = path.basename(sourcePath);\n const destPath = path.join(skillsDir, skillName);\n\n await fs.mkdirp(skillsDir);\n await fs.copy(sourcePath, destPath, { overwrite: true });\n\n return destPath;\n}\n\n/**\n * List all skills installed in the given skills directory.\n * Returns an array of skill metadata objects.\n */\nexport async function listInstalledSkills(\n skillsDir: string\n): Promise<Array<{ name: string; version: string; description: string }>> {\n if (!(await fs.pathExists(skillsDir))) {\n return [];\n }\n\n const entries = await fs.readdir(skillsDir);\n const skills: Array<{ name: string; version: string; description: string }> = [];\n\n for (const entry of entries) {\n const entryPath = path.join(skillsDir, entry);\n const stat = await fs.stat(entryPath);\n if (!stat.isDirectory()) continue;\n\n const skillMdPath = path.join(entryPath, 'SKILL.md');\n if (!(await fs.pathExists(skillMdPath))) continue;\n\n const content = await fs.readFile(skillMdPath, 'utf-8');\n const meta = parseSkillMd(content);\n\n skills.push({\n name: meta.name || entry,\n version: meta.version,\n description: meta.description,\n });\n }\n\n return skills;\n}\n\n/**\n * Remove a skill from the skills directory by name.\n * Throws if the skill does not exist.\n */\nexport async function removeSkill(name: string, skillsDir: string): Promise<void> {\n const skillDir = path.join(skillsDir, name);\n\n if (!(await fs.pathExists(skillDir))) {\n throw new Error(`Skill \"${name}\" not found in ${skillsDir}`);\n }\n\n await fs.remove(skillDir);\n}\n\n/**\n * Construct a full GitHub URL from an owner/repo shorthand or return the URL as-is.\n */\nexport function getGitHubUrl(nameOrUrl: string): string {\n if (nameOrUrl.startsWith('https://') || nameOrUrl.startsWith('http://')) {\n return nameOrUrl;\n }\n return `https://github.com/${nameOrUrl}`;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction getConvexUrl(): string | undefined {\n return process.env['CONVEX_URL'] || process.env['NEXT_PUBLIC_CONVEX_URL'];\n}\n\n// ─── Command Registration ─────────────────────────────────────────────────────\n\nexport function registerSkillCommand(program: Command): void {\n const skillCmd = program\n .command('skill')\n .description('Manage global skills installed in ~/.agentforge/skills/');\n\n // ─── skill install ─────────────────────────────────────────────────\n skillCmd\n .command('install')\n .argument('<name>', 'Local path or GitHub owner/repo to install from')\n .description('Install a skill to ~/.agentforge/skills/')\n .action(async (name: string) => {\n const skillsDir = getGlobalSkillsDir();\n\n // Determine if name is a local path or a GitHub shorthand/URL\n const isLocalPath = await fs.pathExists(name);\n\n if (isLocalPath) {\n // ─── Install from local path ─────────────────────────────\n const sourcePath = path.resolve(name);\n try {\n const installedPath = await installSkillFromPath(sourcePath, skillsDir);\n const skillName = path.basename(installedPath);\n success(`Skill \"${skillName}\" installed from local path.`);\n info(`Location: ${installedPath}`);\n } catch (err: unknown) {\n error((err as Error).message);\n process.exit(1);\n }\n } else {\n // ─── Install from GitHub ─────────────────────────────────\n const repoUrl = getGitHubUrl(name);\n const repoName = name.split('/').pop()!.replace(/\\.git$/, '');\n const destPath = path.join(skillsDir, repoName);\n\n await fs.mkdirp(skillsDir);\n\n info(`Cloning skill from ${repoUrl}...`);\n try {\n // Use execFileSync with array args to prevent shell injection\n execFileSync('git', ['clone', '--depth', '1', repoUrl, destPath], {\n encoding: 'utf-8',\n stdio: 'pipe',\n });\n // Remove .git directory to keep it clean\n await fs.remove(path.join(destPath, '.git'));\n\n const skillMdPath = path.join(destPath, 'SKILL.md');\n if (!(await fs.pathExists(skillMdPath))) {\n error('Cloned repo does not contain a SKILL.md. Not a valid skill.');\n await fs.remove(destPath);\n process.exit(1);\n }\n\n success(`Skill \"${repoName}\" installed from GitHub.`);\n info(`Location: ${destPath}`);\n } catch (err: unknown) {\n error(`Failed to clone: ${(err as Error).message}`);\n process.exit(1);\n }\n }\n });\n\n // ─── skill list ────────────────────────────────────────────────────\n skillCmd\n .command('list')\n .description('List skills installed in ~/.agentforge/skills/')\n .option('--json', 'Output as JSON')\n .action(async (opts: { json?: boolean }) => {\n const skillsDir = getGlobalSkillsDir();\n\n header('Global Skills');\n\n let skills: Array<{ name: string; version: string; description: string }>;\n try {\n skills = await listInstalledSkills(skillsDir);\n } catch {\n skills = [];\n }\n\n if (skills.length === 0) {\n info('No global skills installed.');\n dim(\n ` Install a skill with: ${colors.cyan}agentforge skill install <path-or-owner/repo>${colors.reset}`\n );\n return;\n }\n\n if (opts.json) {\n console.log(JSON.stringify(skills, null, 2));\n return;\n }\n\n table(\n skills.map((s) => ({\n Name: s.name,\n Version: s.version,\n Description: truncate(s.description, 60),\n }))\n );\n\n dim(` Skills directory: ${skillsDir}`);\n });\n\n // ─── skill remove ──────────────────────────────────────────────────\n skillCmd\n .command('remove')\n .argument('<name>', 'Skill name to remove')\n .description('Remove a skill from ~/.agentforge/skills/')\n .action(async (name: string) => {\n const skillsDir = getGlobalSkillsDir();\n\n try {\n await removeSkill(name, skillsDir);\n success(`Skill \"${name}\" removed.`);\n } catch (err: unknown) {\n error((err as Error).message);\n info('List installed skills with: agentforge skill list');\n process.exit(1);\n }\n });\n\n // ─── skill search ──────────────────────────────────────────────────\n skillCmd\n .command('search <query>')\n .description('Search the skill marketplace')\n .option('-c, --category <category>', 'Filter by category')\n .action(async (query: string, options: { category?: string }) => {\n const { searchSkills: searchMarketplace } = await import('@agentforge-ai/core');\n const convexUrl = getConvexUrl();\n if (!convexUrl) {\n error('No CONVEX_URL configured. Set CONVEX_URL environment variable.');\n return;\n }\n try {\n info(`Searching marketplace for \"${query}\"...`);\n const skills = await searchMarketplace(query, convexUrl, options.category);\n if (skills.length === 0) {\n info('No skills found matching your query.');\n return;\n }\n header(`Found ${skills.length} skill(s)`);\n table(\n skills.map((s) => ({\n Name: s.name,\n Version: s.version,\n Category: s.category,\n Downloads: s.downloads.toString(),\n Description: truncate(s.description, 50),\n }))\n );\n } catch (err: unknown) {\n error(`Search failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n });\n\n // ─── skill publish ─────────────────────────────────────────────────\n skillCmd\n .command('publish')\n .description('Publish a skill to the marketplace')\n .option('-d, --dir <directory>', 'Skill directory (default: current directory)', '.')\n .action(async (options: { dir: string }) => {\n const fsExtra = await import('fs-extra');\n const pathMod = await import('node:path');\n const { parseSkillManifest, publishSkill: publishToMarketplace } = await import('@agentforge-ai/core');\n\n const convexUrl = getConvexUrl();\n if (!convexUrl) {\n error('No CONVEX_URL configured. Set CONVEX_URL environment variable.');\n return;\n }\n\n const skillDir = pathMod.resolve(options.dir);\n const skillMdPath = pathMod.join(skillDir, 'SKILL.md');\n\n if (!(await fsExtra.pathExists(skillMdPath))) {\n error('No SKILL.md found in the specified directory.');\n return;\n }\n\n try {\n const skillMdContent = await fsExtra.readFile(skillMdPath, 'utf-8');\n const manifest = parseSkillManifest(skillMdContent);\n\n let readmeContent: string | undefined;\n const readmePath = pathMod.join(skillDir, 'README.md');\n if (await fsExtra.pathExists(readmePath)) {\n readmeContent = await fsExtra.readFile(readmePath, 'utf-8');\n }\n\n const meta = manifest.metadata ?? {};\n info(`Publishing \"${manifest.name}\" v${manifest.version}...`);\n await publishToMarketplace(\n {\n name: manifest.name,\n version: manifest.version,\n description: manifest.description,\n author: meta.author ?? 'unknown',\n category: (meta as Record<string, unknown>)['category'] as string ?? 'general',\n tags: meta.tags ?? [],\n skillMdContent,\n readmeContent,\n repositoryUrl: meta.repository,\n },\n convexUrl,\n );\n success(`Skill \"${manifest.name}\" published successfully!`);\n } catch (err: unknown) {\n error(`Publish failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n });\n\n // ─── skill featured ────────────────────────────────────────────────\n skillCmd\n .command('featured')\n .description('Show featured skills from the marketplace')\n .action(async () => {\n const { fetchFeaturedSkills } = await import('@agentforge-ai/core');\n const convexUrl = getConvexUrl();\n if (!convexUrl) {\n error('No CONVEX_URL configured. Set CONVEX_URL environment variable.');\n return;\n }\n try {\n const skills = await fetchFeaturedSkills(convexUrl);\n if (skills.length === 0) {\n info('No featured skills available.');\n return;\n }\n header('Featured Skills');\n table(\n skills.map((s) => ({\n Name: s.name,\n Version: s.version,\n Category: s.category,\n Downloads: s.downloads.toString(),\n Description: truncate(s.description, 60),\n }))\n );\n } catch (err: unknown) {\n error(`Failed to fetch featured skills: ${err instanceof Error ? err.message : String(err)}`);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, success, error, info, formatDate } from '../lib/display.js';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\nexport function registerCronCommand(program: Command) {\n const cron = program.command('cron').description('Manage cron jobs');\n\n cron\n .command('list')\n .option('--json', 'Output as JSON')\n .description('List all cron jobs')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('cronJobs:list' as any, {}), 'Failed to list cron jobs');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Cron Jobs');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No cron jobs. Create one with: agentforge cron create'); return; }\n table(items.map((c: any) => ({\n ID: c._id?.slice(-8) || 'N/A',\n Name: c.name,\n Schedule: c.schedule,\n Agent: c.agentId,\n Enabled: c.isEnabled ? '✔' : '✖',\n 'Last Run': c.lastRun ? formatDate(c.lastRun) : 'Never',\n 'Next Run': c.nextRun ? formatDate(c.nextRun) : 'N/A',\n })));\n });\n\n cron\n .command('create')\n .description('Create a new cron job (interactive)')\n .option('--name <name>', 'Job name')\n .option('--schedule <cron>', 'Cron expression')\n .option('--agent <id>', 'Agent ID')\n .option('--action <action>', 'Action to execute')\n .action(async (opts) => {\n const name = opts.name || await prompt('Job name: ');\n const schedule = opts.schedule || await prompt('Cron schedule (e.g., \"0 */5 * * * *\" for every 5 min): ');\n const agentId = opts.agent || await prompt('Agent ID: ');\n const action = opts.action || await prompt('Action (message to send to agent): ');\n\n if (!name || !schedule || !agentId || !action) {\n error('All fields are required.'); process.exit(1);\n }\n\n const client = await createClient();\n await safeCall(\n () => client.mutation('cronJobs:create' as any, { name, schedule, agentId, prompt: action }),\n 'Failed to create cron job'\n );\n success(`Cron job \"${name}\" created.`);\n });\n\n cron\n .command('delete')\n .argument('<id>', 'Cron job ID')\n .description('Delete a cron job')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('cronJobs:remove' as any, { id }), 'Failed to delete');\n success(`Cron job \"${id}\" deleted.`);\n });\n\n cron\n .command('enable')\n .argument('<id>', 'Cron job ID')\n .description('Enable a cron job')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('cronJobs:update' as any, { id, isEnabled: true }), 'Failed');\n success(`Cron job \"${id}\" enabled.`);\n });\n\n cron\n .command('disable')\n .argument('<id>', 'Cron job ID')\n .description('Disable a cron job')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('cronJobs:update' as any, { id, isEnabled: false }), 'Failed');\n success(`Cron job \"${id}\" disabled.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, details, success, error, info, formatDate } from '../lib/display.js';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\nexport function registerMcpCommand(program: Command) {\n const mcp = program.command('mcp').description('Manage MCP connections');\n\n mcp\n .command('list')\n .option('--json', 'Output as JSON')\n .description('List all MCP connections')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('mcpConnections:list' as any, {}), 'Failed to list connections');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('MCP Connections');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No connections. Add one with: agentforge mcp add'); return; }\n table(items.map((c: any) => ({\n ID: c._id?.slice(-8) || 'N/A',\n Name: c.name,\n Type: c.protocol,\n Endpoint: c.serverUrl,\n Connected: c.isConnected ? '✔' : '✖',\n Enabled: c.isEnabled ? '✔' : '✖',\n })));\n });\n\n mcp\n .command('add')\n .description('Add a new MCP connection (interactive)')\n .option('--name <name>', 'Connection name')\n .option('--type <type>', 'Connection type (stdio, sse, http)')\n .option('--endpoint <url>', 'Endpoint URL or command')\n .action(async (opts) => {\n const name = opts.name || await prompt('Connection name: ');\n const type = opts.type || await prompt('Type (stdio/sse/http): ');\n const endpoint = opts.endpoint || await prompt('Endpoint (URL or command): ');\n\n if (!name || !type || !endpoint) { error('All fields required.'); process.exit(1); }\n\n const client = await createClient();\n await safeCall(\n () => client.mutation('mcpConnections:create' as any, {\n name, serverUrl: endpoint, protocol: type,\n }),\n 'Failed to add connection'\n );\n success(`MCP connection \"${name}\" added.`);\n });\n\n mcp\n .command('remove')\n .argument('<id>', 'Connection ID')\n .description('Remove an MCP connection')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('mcpConnections:remove' as any, { id }), 'Failed');\n success(`Connection \"${id}\" removed.`);\n });\n\n mcp\n .command('test')\n .argument('<id>', 'Connection ID')\n .description('Test an MCP connection')\n .action(async (id) => {\n info(`Testing connection \"${id}\"...`);\n const client = await createClient();\n const conns = await safeCall(() => client.query('mcpConnections:list' as any, {}), 'Failed');\n const conn = (conns as any[]).find((c: any) => c._id === id || c._id?.endsWith(id));\n if (!conn) { error(`Connection \"${id}\" not found.`); process.exit(1); }\n\n // Simple connectivity test\n if (conn.protocol === 'http' || conn.protocol === 'sse') {\n try {\n const res = await fetch(conn.serverUrl, { method: 'HEAD', signal: AbortSignal.timeout(5000) });\n if (res.ok) {\n success(`Connection \"${conn.name}\" is reachable (HTTP ${res.status}).`);\n await client.mutation('mcpConnections:updateStatus' as any, { id: conn._id, isConnected: true });\n } else {\n error(`Connection \"${conn.name}\" returned HTTP ${res.status}.`);\n }\n } catch (e: any) {\n error(`Connection \"${conn.name}\" failed: ${e.message}`);\n }\n } else {\n info(`Connection type \"${conn.protocol}\" — manual verification required.`);\n info(`Endpoint: ${conn.serverUrl}`);\n }\n });\n\n mcp\n .command('enable')\n .argument('<id>', 'Connection ID')\n .description('Enable a connection')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('mcpConnections:update' as any, { id, isEnabled: true }), 'Failed');\n success(`Connection \"${id}\" enabled.`);\n });\n\n mcp\n .command('disable')\n .argument('<id>', 'Connection ID')\n .description('Disable a connection')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('mcpConnections:update' as any, { id, isEnabled: false }), 'Failed');\n success(`Connection \"${id}\" disabled.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, success, error, info, formatDate } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\n\nexport function registerFilesCommand(program: Command) {\n const files = program.command('files').description('Manage files');\n\n files\n .command('list')\n .argument('[folder]', 'Folder ID to list files from')\n .option('--json', 'Output as JSON')\n .description('List files')\n .action(async (folder, opts) => {\n const client = await createClient();\n const args = folder ? { folderId: folder } : {};\n const result = await safeCall(() => client.query('files:list' as any, args), 'Failed to list files');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Files');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No files. Upload one with: agentforge files upload <path>'); return; }\n table(items.map((f: any) => ({\n ID: f._id?.slice(-8) || 'N/A',\n Name: f.name,\n Type: f.mimeType,\n Size: formatSize(f.size),\n Folder: f.folderId || 'root',\n Uploaded: formatDate(f.uploadedAt),\n })));\n });\n\n files\n .command('upload')\n .argument('<filepath>', 'Path to file to upload')\n .option('--folder <id>', 'Folder ID to upload to')\n .option('--project <id>', 'Project ID to associate with')\n .description('Upload a file')\n .action(async (filepath, opts) => {\n const absPath = path.resolve(filepath);\n if (!fs.existsSync(absPath)) { error(`File not found: ${absPath}`); process.exit(1); }\n\n const stat = fs.statSync(absPath);\n const name = path.basename(absPath);\n const ext = path.extname(absPath).toLowerCase();\n const mimeTypes: Record<string, string> = {\n '.txt': 'text/plain', '.md': 'text/markdown', '.json': 'application/json',\n '.js': 'text/javascript', '.ts': 'text/typescript', '.py': 'text/x-python',\n '.pdf': 'application/pdf', '.png': 'image/png', '.jpg': 'image/jpeg',\n '.csv': 'text/csv', '.html': 'text/html', '.xml': 'text/xml',\n };\n const mimeType = mimeTypes[ext] || 'application/octet-stream';\n\n const client = await createClient();\n await safeCall(\n () => client.mutation('files:create' as any, {\n name, originalName: name, mimeType, size: stat.size,\n url: 'pending-upload',\n folderId: opts.folder, projectId: opts.project,\n }),\n 'Failed to upload file metadata'\n );\n success(`File \"${name}\" registered (${formatSize(stat.size)}, ${mimeType}).`);\n info('Note: File content storage requires Convex file storage or R2 integration.');\n });\n\n files\n .command('delete')\n .argument('<id>', 'File ID')\n .description('Delete a file')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('files:remove' as any, { id }), 'Failed to delete file');\n success(`File \"${id}\" deleted.`);\n });\n\n // Folders subcommand\n const folders = program.command('folders').description('Manage folders');\n\n folders\n .command('list')\n .option('--json', 'Output as JSON')\n .description('List all folders')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('folders:list' as any, {}), 'Failed to list folders');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Folders');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No folders. Create one with: agentforge folders create <name>'); return; }\n table(items.map((f: any) => ({\n ID: f._id?.slice(-8) || 'N/A',\n Name: f.name,\n Parent: f.parentId || 'root',\n Created: formatDate(f.createdAt),\n })));\n });\n\n folders\n .command('create')\n .argument('<name>', 'Folder name')\n .option('--parent <id>', 'Parent folder ID')\n .description('Create a folder')\n .action(async (name, opts) => {\n const client = await createClient();\n await safeCall(\n () => client.mutation('folders:create' as any, { name, parentId: opts.parent }),\n 'Failed to create folder'\n );\n success(`Folder \"${name}\" created.`);\n });\n\n folders\n .command('delete')\n .argument('<id>', 'Folder ID')\n .description('Delete a folder')\n .action(async (id) => {\n const client = await createClient();\n await safeCall(() => client.mutation('folders:remove' as any, { id }), 'Failed to delete folder');\n success(`Folder \"${id}\" deleted.`);\n });\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, details, success, error, info, formatDate } from '../lib/display.js';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\nexport function registerProjectsCommand(program: Command) {\n const projects = program.command('projects').description('Manage projects and workspaces');\n\n projects\n .command('list')\n .option('--json', 'Output as JSON')\n .description('List all projects')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('projects:list' as any, {}), 'Failed to list projects');\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Projects');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No projects. Create one with: agentforge projects create <name>'); return; }\n table(items.map((p: any) => ({\n ID: p._id?.slice(-8) || 'N/A',\n Name: p.name,\n Description: (p.description || '').slice(0, 40),\n Created: formatDate(p.createdAt),\n })));\n });\n\n projects\n .command('create')\n .argument('<name>', 'Project name')\n .option('-d, --description <desc>', 'Project description')\n .description('Create a new project')\n .action(async (name, opts) => {\n const description = opts.description || await prompt('Description (optional): ');\n const client = await createClient();\n await safeCall(\n () => client.mutation('projects:create' as any, { name, description: description || undefined }),\n 'Failed to create project'\n );\n success(`Project \"${name}\" created.`);\n });\n\n projects\n .command('inspect')\n .argument('<id>', 'Project ID')\n .description('Show project details')\n .action(async (id) => {\n const client = await createClient();\n const projects = await safeCall(() => client.query('projects:list' as any, {}), 'Failed');\n const project = (projects as any[]).find((p: any) => p._id === id || p._id?.endsWith(id));\n if (!project) { error(`Project \"${id}\" not found.`); process.exit(1); }\n header(`Project: ${project.name}`);\n details({\n ID: project._id,\n Name: project.name,\n Description: project.description || 'N/A',\n Created: formatDate(project.createdAt),\n Updated: formatDate(project.updatedAt),\n });\n });\n\n projects\n .command('delete')\n .argument('<id>', 'Project ID')\n .option('-f, --force', 'Skip confirmation')\n .description('Delete a project')\n .action(async (id, opts) => {\n if (!opts.force) {\n const confirm = await prompt(`Delete project \"${id}\"? (y/N): `);\n if (confirm.toLowerCase() !== 'y') { info('Cancelled.'); return; }\n }\n const client = await createClient();\n await safeCall(() => client.mutation('projects:remove' as any, { id }), 'Failed');\n success(`Project \"${id}\" deleted.`);\n });\n\n projects\n .command('switch')\n .argument('<id>', 'Project ID to switch to')\n .description('Set the active project')\n .action(async (id) => {\n const client = await createClient();\n // Verify project exists\n const projects = await safeCall(() => client.query('projects:list' as any, {}), 'Failed');\n const project = (projects as any[]).find((p: any) => p._id === id || p._id?.endsWith(id));\n if (!project) { error(`Project \"${id}\" not found.`); process.exit(1); }\n // Store active project in settings\n await safeCall(\n () => client.mutation('settings:set' as any, { userId: 'cli', key: 'activeProject', value: project._id }),\n 'Failed to switch project'\n );\n success(`Switched to project \"${project.name}\".`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, success, error, info, details, colors } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\nexport function registerConfigCommand(program: Command) {\n const config = program.command('config').description('Manage configuration');\n\n config\n .command('show')\n .description('Show current configuration')\n .action(async () => {\n header('Configuration');\n\n // Check local .env files\n const cwd = process.cwd();\n const envFiles = ['.env', '.env.local', '.env.production'];\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n console.log(` ${colors.cyan}${envFile}${colors.reset}`);\n const content = fs.readFileSync(envPath, 'utf-8');\n content.split('\\n').forEach((line) => {\n if (line.trim() && !line.startsWith('#')) {\n const [key, ...rest] = line.split('=');\n const value = rest.join('=').trim();\n const masked = key.toLowerCase().includes('key') || key.toLowerCase().includes('secret') || key.toLowerCase().includes('token')\n ? value.slice(0, 4) + '****' + value.slice(-4)\n : value;\n console.log(` ${colors.dim}${key.trim()}${colors.reset} = ${masked}`);\n }\n });\n console.log();\n }\n }\n\n // Check Convex config\n const convexDir = path.join(cwd, '.convex');\n if (fs.existsSync(convexDir)) {\n info('Convex: Configured');\n } else {\n info('Convex: Not configured (run `npx convex dev`)');\n }\n\n // Check skills directory\n const skillsDir = path.join(cwd, 'skills');\n if (fs.existsSync(skillsDir)) {\n const skills = fs.readdirSync(skillsDir).filter((d: string) => fs.statSync(path.join(skillsDir, d)).isDirectory());\n info(`Skills: ${skills.length} installed (${skills.join(', ')})`);\n } else {\n info('Skills: None installed');\n }\n });\n\n config\n .command('set')\n .argument('<key>', 'Configuration key')\n .argument('<value>', 'Configuration value')\n .option('--env <file>', 'Environment file to update', '.env.local')\n .description('Set a configuration value')\n .action(async (key, value, opts) => {\n const envPath = path.join(process.cwd(), opts.env);\n let content = '';\n if (fs.existsSync(envPath)) {\n content = fs.readFileSync(envPath, 'utf-8');\n }\n\n const lines = content.split('\\n');\n const idx = lines.findIndex((l) => l.startsWith(`${key}=`));\n if (idx >= 0) {\n lines[idx] = `${key}=${value}`;\n } else {\n lines.push(`${key}=${value}`);\n }\n\n fs.writeFileSync(envPath, lines.join('\\n'));\n success(`Set ${key} in ${opts.env}`);\n });\n\n config\n .command('get')\n .argument('<key>', 'Configuration key')\n .description('Get a configuration value')\n .action(async (key) => {\n const cwd = process.cwd();\n const envFiles = ['.env.local', '.env', '.env.production'];\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(new RegExp(`^${key}=(.+)$`, 'm'));\n if (match) {\n console.log(match[1].trim());\n return;\n }\n }\n }\n error(`Key \"${key}\" not found in any .env file.`);\n });\n\n config\n .command('init')\n .description('Initialize configuration for a new project')\n .action(async () => {\n header('Project Configuration');\n const convexUrl = await prompt('Convex URL (from `npx convex dev`): ');\n const provider = await prompt('LLM Provider (openai/openrouter/anthropic/google): ') || 'openai';\n const apiKey = await prompt(`${provider.toUpperCase()} API Key: `);\n\n const envContent = [\n `# AgentForge Configuration`,\n `CONVEX_URL=${convexUrl}`,\n ``,\n `# LLM Provider`,\n `LLM_PROVIDER=${provider}`,\n ];\n\n if (provider === 'openai') envContent.push(`OPENAI_API_KEY=${apiKey}`);\n else if (provider === 'openrouter') envContent.push(`OPENROUTER_API_KEY=${apiKey}`);\n else if (provider === 'anthropic') envContent.push(`ANTHROPIC_API_KEY=${apiKey}`);\n else if (provider === 'google') envContent.push(`GOOGLE_API_KEY=${apiKey}`);\n\n fs.writeFileSync(path.join(process.cwd(), '.env.local'), envContent.join('\\n') + '\\n');\n success('Configuration saved to .env.local');\n info('Run `npx convex dev` to start the Convex backend.');\n });\n\n config\n .command('provider')\n .argument('<provider>', 'LLM provider to configure (openai, openrouter, anthropic, google, xai)')\n .description('Configure an LLM provider')\n .action(async (provider) => {\n const keyNames: Record<string, string> = {\n openai: 'OPENAI_API_KEY',\n openrouter: 'OPENROUTER_API_KEY',\n anthropic: 'ANTHROPIC_API_KEY',\n google: 'GOOGLE_API_KEY',\n xai: 'XAI_API_KEY',\n };\n const keyName = keyNames[provider.toLowerCase()];\n if (!keyName) {\n error(`Unknown provider \"${provider}\". Supported: ${Object.keys(keyNames).join(', ')}`);\n process.exit(1);\n }\n const apiKey = await prompt(`${keyName}: `);\n if (!apiKey) { error('API key is required.'); process.exit(1); }\n\n const envPath = path.join(process.cwd(), '.env.local');\n let content = '';\n if (fs.existsSync(envPath)) content = fs.readFileSync(envPath, 'utf-8');\n\n const lines = content.split('\\n');\n const idx = lines.findIndex((l) => l.startsWith(`${keyName}=`));\n if (idx >= 0) lines[idx] = `${keyName}=${apiKey}`;\n else lines.push(`${keyName}=${apiKey}`);\n\n // Also set LLM_PROVIDER\n const provIdx = lines.findIndex((l) => l.startsWith('LLM_PROVIDER='));\n if (provIdx >= 0) lines[provIdx] = `LLM_PROVIDER=${provider}`;\n else lines.push(`LLM_PROVIDER=${provider}`);\n\n fs.writeFileSync(envPath, lines.join('\\n'));\n success(`Provider \"${provider}\" configured.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, table, success, error, info, dim, colors, formatDate } from '../lib/display.js';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\nfunction promptSecret(q: string): Promise<string> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n // Disable echo for secret input\n if (process.stdin.isTTY) {\n process.stdout.write(q);\n let input = '';\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.setEncoding('utf-8');\n const onData = (char: string) => {\n if (char === '\\n' || char === '\\r') {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdin.removeListener('data', onData);\n console.log();\n rl.close();\n resolve(input);\n } else if (char === '\\u0003') {\n process.exit();\n } else if (char === '\\u007F') {\n input = input.slice(0, -1);\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n process.stdout.write(q + '*'.repeat(input.length));\n } else {\n input += char;\n process.stdout.write('*');\n }\n };\n process.stdin.on('data', onData);\n } else {\n rl.question(q, (ans) => { rl.close(); resolve(ans.trim()); });\n }\n });\n}\n\nexport function registerVaultCommand(program: Command) {\n const vault = program.command('vault').description('Manage secrets securely');\n\n vault\n .command('list')\n .option('--json', 'Output as JSON')\n .description('List all stored secrets (values hidden)')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('vault:list' as any, {}), 'Failed to list secrets');\n if (opts.json) {\n const safe = ((result as any[]) || []).map((s: any) => ({ ...s, encryptedValue: undefined }));\n console.log(JSON.stringify(safe, null, 2));\n return;\n }\n header('Vault — Stored Secrets');\n const items = (result as any[]) || [];\n if (items.length === 0) { info('No secrets stored. Add one with: agentforge vault set <name> <value>'); return; }\n table(items.map((s: any) => ({\n Name: s.name,\n Category: s.category || 'general',\n Provider: s.provider || 'N/A',\n 'Last Updated': s.updatedAt ? formatDate(s.updatedAt) : 'Never',\n Created: formatDate(s.createdAt),\n })));\n });\n\n vault\n .command('set')\n .argument('<name>', 'Secret name (e.g., OPENAI_API_KEY)')\n .argument('[value]', 'Secret value (omit for secure prompt)')\n .option('--category <cat>', 'Category (api_key, token, secret, credential)', 'api_key')\n .option('--provider <provider>', 'Provider name (openai, anthropic, etc.)')\n .description('Store a secret securely')\n .action(async (name, value, opts) => {\n if (!value) {\n value = await promptSecret(`Enter value for ${name}: `);\n }\n if (!value) { error('Value is required.'); process.exit(1); }\n\n const client = await createClient();\n await safeCall(\n () => client.mutation('vault:store' as any, {\n name,\n value,\n category: opts.category,\n provider: opts.provider,\n }),\n 'Failed to store secret'\n );\n success(`Secret \"${name}\" stored securely.`);\n });\n\n vault\n .command('get')\n .argument('<name>', 'Secret name')\n .option('--reveal', 'Show the actual value (use with caution)')\n .description('Retrieve a secret')\n .action(async (name, opts) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('vault:list' as any, {}), 'Failed');\n const secret = ((result as any[]) || []).find((s: any) => s.name === name);\n if (!secret) { error(`Secret \"${name}\" not found.`); process.exit(1); }\n\n if (opts.reveal) {\n // Decrypted values are not accessible from the client (internal mutation only)\n info(`${name} = ${secret.maskedValue || '****'}`);\n dim(' Note: Full decryption is only available server-side for security.');\n } else {\n info(`${name} = ${secret.maskedValue || '****'}`);\n dim(' Use --reveal to attempt to show more details.');\n }\n });\n\n vault\n .command('delete')\n .argument('<name>', 'Secret name')\n .option('-f, --force', 'Skip confirmation')\n .description('Delete a secret')\n .action(async (name, opts) => {\n if (!opts.force) {\n const confirm = await prompt(`Delete secret \"${name}\"? This cannot be undone. (y/N): `);\n if (confirm.toLowerCase() !== 'y') { info('Cancelled.'); return; }\n }\n const client = await createClient();\n const result = await safeCall(() => client.query('vault:list' as any, {}), 'Failed');\n const secret = ((result as any[]) || []).find((s: any) => s.name === name);\n if (!secret) { error(`Secret \"${name}\" not found.`); process.exit(1); }\n await safeCall(() => client.mutation('vault:remove' as any, { id: secret._id }), 'Failed');\n success(`Secret \"${name}\" deleted.`);\n });\n\n vault\n .command('rotate')\n .argument('<name>', 'Secret name')\n .description('Rotate a secret (set a new value)')\n .action(async (name) => {\n const client = await createClient();\n const result = await safeCall(() => client.query('vault:list' as any, {}), 'Failed');\n const secret = ((result as any[]) || []).find((s: any) => s.name === name);\n if (!secret) { error(`Secret \"${name}\" not found.`); process.exit(1); }\n\n const newValue = await promptSecret(`Enter new value for ${name}: `);\n if (!newValue) { error('Value is required.'); process.exit(1); }\n\n await safeCall(\n () => client.mutation('vault:update' as any, { id: secret._id, value: newValue }),\n 'Failed to rotate secret'\n );\n success(`Secret \"${name}\" rotated.`);\n });\n}\n","import { Command } from 'commander';\nimport { createClient } from '../lib/convex-client.js';\nimport { header, success, error, info, dim, table } from '../lib/display.js';\n\nfunction safeCall<T>(fn: () => Promise<T>, msg: string): Promise<T> {\n return fn().catch((e: any) => { error(`${msg}: ${e.message}`); process.exit(1); });\n}\n\nfunction formatDate(ts: number): string {\n return new Date(ts).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });\n}\n\nfunction maskKey(key: string): string {\n if (key.length <= 12) return key.substring(0, 4) + '****';\n return key.substring(0, 8) + '...' + key.substring(key.length - 4);\n}\n\nfunction promptSecret(question: string): Promise<string> {\n return new Promise((resolve) => {\n const readline = require('readline');\n if (process.stdin.isTTY) {\n process.stdout.write(question);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.setEncoding('utf8');\n let input = '';\n const onData = (char: string) => {\n if (char === '\\n' || char === '\\r' || char === '\\u0004') {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdin.removeListener('data', onData);\n process.stdout.write('\\n');\n resolve(input);\n } else if (char === '\\u0003') {\n process.exit(0);\n } else if (char === '\\u007f' || char === '\\b') {\n if (input.length > 0) {\n input = input.slice(0, -1);\n process.stdout.write('\\b \\b');\n }\n } else {\n input += char;\n process.stdout.write('*');\n }\n };\n process.stdin.on('data', onData);\n } else {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n rl.question(question, (ans: string) => { rl.close(); resolve(ans.trim()); });\n }\n });\n}\n\nconst PROVIDERS = [\n { id: 'openai', name: 'OpenAI', prefix: 'sk-' },\n { id: 'anthropic', name: 'Anthropic', prefix: 'sk-ant-' },\n { id: 'openrouter', name: 'OpenRouter', prefix: 'sk-or-' },\n { id: 'google', name: 'Google AI', prefix: 'AIza' },\n { id: 'xai', name: 'xAI', prefix: 'xai-' },\n { id: 'groq', name: 'Groq', prefix: 'gsk_' },\n { id: 'together', name: 'Together AI', prefix: '' },\n { id: 'perplexity', name: 'Perplexity', prefix: 'pplx-' },\n];\n\nexport function registerKeysCommand(program: Command) {\n const keys = program.command('keys').description('Manage AI provider API keys');\n\n keys\n .command('list')\n .option('--provider <provider>', 'Filter by provider')\n .option('--json', 'Output as JSON')\n .description('List all configured API keys')\n .action(async (opts) => {\n const client = await createClient();\n const result = await safeCall(\n () => client.query('apiKeys:list' as any, opts.provider ? { provider: opts.provider } : {}),\n 'Failed to list API keys'\n );\n\n const items = (result as any[]) || [];\n\n if (opts.json) {\n const safe = items.map((k: any) => ({ ...k, encryptedKey: maskKey(k.encryptedKey) }));\n console.log(JSON.stringify(safe, null, 2));\n return;\n }\n\n header('API Keys');\n\n if (items.length === 0) {\n info('No API keys configured.');\n dim(' Add one with: agentforge keys add <provider> [key]');\n dim('');\n dim(' Supported providers:');\n PROVIDERS.forEach(p => dim(` ${p.id.padEnd(12)} ${p.name}`));\n return;\n }\n\n table(items.map((k: any) => ({\n Provider: k.provider,\n Name: k.keyName,\n Key: maskKey(k.encryptedKey),\n Active: k.isActive ? '✓' : '✗',\n Created: formatDate(k.createdAt),\n 'Last Used': k.lastUsedAt ? formatDate(k.lastUsedAt) : 'Never',\n })));\n });\n\n keys\n .command('add')\n .argument('<provider>', `Provider (${PROVIDERS.map(p => p.id).join(', ')})`)\n .argument('[key]', 'API key value (omit for secure prompt)')\n .option('--name <name>', 'Key display name')\n .description('Add an AI provider API key')\n .action(async (provider, key, opts) => {\n const providerInfo = PROVIDERS.find(p => p.id === provider);\n if (!providerInfo) {\n error(`Unknown provider \"${provider}\". Supported: ${PROVIDERS.map(p => p.id).join(', ')}`);\n process.exit(1);\n }\n\n if (!key) {\n key = await promptSecret(`Enter ${providerInfo.name} API key: `);\n }\n if (!key) { error('API key is required.'); process.exit(1); }\n\n if (providerInfo.prefix && !key.startsWith(providerInfo.prefix)) {\n info(`Warning: ${providerInfo.name} keys typically start with \"${providerInfo.prefix}\".`);\n }\n\n const keyName = opts.name || `${providerInfo.name} Key`;\n const client = await createClient();\n await safeCall(\n () => client.mutation('apiKeys:create' as any, {\n provider,\n keyName,\n encryptedKey: key,\n }),\n 'Failed to store API key'\n );\n success(`${providerInfo.name} API key \"${keyName}\" stored successfully.`);\n });\n\n keys\n .command('remove')\n .argument('<provider>', 'Provider name')\n .option('-f, --force', 'Skip confirmation')\n .description('Remove an API key')\n .action(async (provider, opts) => {\n const client = await createClient();\n const result = await safeCall(\n () => client.query('apiKeys:list' as any, { provider }),\n 'Failed to list keys'\n );\n const items = (result as any[]) || [];\n if (items.length === 0) { error(`No API keys found for \"${provider}\".`); process.exit(1); }\n\n // If multiple keys, remove the first one (or we could add selection)\n const target = items[0];\n\n if (!opts.force) {\n const readline = require('readline');\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) => {\n rl.question(`Delete \"${target.keyName}\" for ${provider}? (y/N): `, (ans: string) => { rl.close(); resolve(ans.trim()); });\n });\n if (answer.toLowerCase() !== 'y') { info('Cancelled.'); return; }\n }\n\n await safeCall(\n () => client.mutation('apiKeys:remove' as any, { id: target._id }),\n 'Failed to remove API key'\n );\n success(`API key \"${target.keyName}\" removed.`);\n });\n\n keys\n .command('test')\n .argument('<provider>', 'Provider to test')\n .description('Test an API key by making a simple request')\n .action(async (provider) => {\n const client = await createClient();\n const result = await safeCall(\n () => client.query('apiKeys:getActiveForProvider' as any, { provider }),\n 'Failed to get key'\n );\n\n if (!result) { error(`No active API key for \"${provider}\". Add one with: agentforge keys add ${provider}`); process.exit(1); }\n\n const key = (result as any).encryptedKey;\n info(`Testing ${provider} API key...`);\n\n try {\n let ok = false;\n if (provider === 'openai') {\n const res = await fetch('https://api.openai.com/v1/models', { headers: { Authorization: `Bearer ${key}` } });\n ok = res.ok;\n } else if (provider === 'anthropic') {\n const res = await fetch('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: { 'x-api-key': key, 'anthropic-version': '2023-06-01', 'Content-Type': 'application/json' },\n body: JSON.stringify({ model: 'claude-3-haiku-20240307', max_tokens: 1, messages: [{ role: 'user', content: 'hi' }] }),\n });\n ok = res.ok;\n } else if (provider === 'openrouter') {\n const res = await fetch('https://openrouter.ai/api/v1/models', { headers: { Authorization: `Bearer ${key}` } });\n ok = res.ok;\n } else if (provider === 'google') {\n const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${key}`);\n ok = res.ok;\n } else if (provider === 'groq') {\n const res = await fetch('https://api.groq.com/openai/v1/models', { headers: { Authorization: `Bearer ${key}` } });\n ok = res.ok;\n } else {\n info(`No test endpoint configured for \"${provider}\". Key is stored.`);\n return;\n }\n\n if (ok) {\n success(`${provider} API key is valid and working.`);\n await safeCall(\n () => client.mutation('apiKeys:updateLastUsed' as any, { id: (result as any)._id }),\n 'Failed to update last used'\n );\n } else {\n error(`${provider} API key returned an error. Check that the key is valid.`);\n }\n } catch (e: any) {\n error(`Connection failed: ${e.message}`);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, details, success, error, info, dim, colors } from '../lib/display.js';\nimport { spawn } from 'node:child_process';\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport readline from 'node:readline';\n\nexport function registerStatusCommand(program: Command) {\n program\n .command('status')\n .description('Show system health and connection status')\n .action(async () => {\n header('AgentForge Status');\n\n const cwd = process.cwd();\n const checks: Record<string, string> = {};\n\n checks['Project Root'] = fs.existsSync(path.join(cwd, 'package.json')) ? '✔ Found' : '✖ Not found';\n checks['Convex Dir'] = fs.existsSync(path.join(cwd, 'convex')) ? '✔ Found' : '✖ Not found';\n checks['Skills Dir'] = fs.existsSync(path.join(cwd, 'skills')) ? '✔ Found' : '✖ Not configured';\n checks['Dashboard Dir'] = fs.existsSync(path.join(cwd, 'dashboard')) ? '✔ Found' : '✖ Not found';\n checks['Env Config'] = fs.existsSync(path.join(cwd, '.env.local')) || fs.existsSync(path.join(cwd, '.env'))\n ? '✔ Found' : '✖ Not found';\n\n // Check Convex connection\n try {\n const client = await createClient();\n const agents = await client.query('agents:list' as any, {});\n checks['Convex Connection'] = `✔ Connected (${(agents as any[])?.length || 0} agents)`;\n } catch {\n checks['Convex Connection'] = '✖ Not connected (run `npx convex dev`)';\n }\n\n // Check LLM provider\n const envFiles = ['.env.local', '.env'];\n let provider = 'Not configured';\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(/LLM_PROVIDER=(.+)/);\n if (match) { provider = match[1].trim(); break; }\n if (content.includes('OPENAI_API_KEY=')) { provider = 'openai'; break; }\n if (content.includes('OPENROUTER_API_KEY=')) { provider = 'openrouter'; break; }\n }\n }\n checks['LLM Provider'] = provider !== 'Not configured' ? `✔ ${provider}` : '✖ Not configured';\n\n details(checks);\n });\n\n program\n .command('dashboard')\n .description('Launch the web dashboard')\n .option('-p, --port <port>', 'Port for the dashboard', '3000')\n .option('--install', 'Install dashboard dependencies before starting')\n .action(async (opts) => {\n const cwd = process.cwd();\n\n // Search for the dashboard in multiple locations (in priority order)\n const searchPaths = [\n path.join(cwd, 'dashboard'), // 1. Bundled in project (agentforge create)\n path.join(cwd, 'packages', 'web'), // 2. Monorepo structure\n path.join(cwd, 'node_modules', '@agentforge-ai', 'web'), // 3. Installed as dependency\n ];\n\n let dashDir = '';\n for (const p of searchPaths) {\n if (fs.existsSync(path.join(p, 'package.json'))) {\n dashDir = p;\n break;\n }\n }\n\n if (!dashDir) {\n error('Dashboard not found!');\n console.log();\n info('The dashboard should be in your project\\'s ./dashboard/ directory.');\n info('If you created this project with an older version of AgentForge,');\n info('you can add it manually:');\n console.log();\n console.log(` ${colors.cyan}# Option 1: Recreate the project${colors.reset}`);\n console.log(` agentforge create my-project`);\n console.log();\n console.log(` ${colors.cyan}# Option 2: Clone the dashboard from the repo${colors.reset}`);\n console.log(` git clone https://github.com/Agentic-Engineering-Agency/agentforge /tmp/af`);\n console.log(` cp -r /tmp/af/packages/web ./dashboard`);\n console.log(` cd dashboard && pnpm install`);\n console.log();\n return;\n }\n\n // Check if node_modules exists, if not install\n const nodeModulesExists = fs.existsSync(path.join(dashDir, 'node_modules'));\n if (!nodeModulesExists || opts.install) {\n header('AgentForge Dashboard — Installing Dependencies');\n info(`Installing in ${path.relative(cwd, dashDir) || '.'}...`);\n console.log();\n\n const installChild = spawn('pnpm', ['install'], {\n cwd: dashDir,\n stdio: 'inherit',\n shell: true,\n });\n\n await new Promise<void>((resolve, reject) => {\n installChild.on('close', (code) => {\n if (code === 0) resolve();\n else reject(new Error(`pnpm install exited with code ${code}`));\n });\n installChild.on('error', reject);\n });\n\n console.log();\n success('Dependencies installed.');\n console.log();\n }\n\n // Read the Convex URL from .env.local and inject it into the dashboard\n const envPath = path.join(cwd, '.env.local');\n if (fs.existsSync(envPath)) {\n const envContent = fs.readFileSync(envPath, 'utf-8');\n const convexUrlMatch = envContent.match(/CONVEX_URL=(.+)/);\n if (convexUrlMatch) {\n const dashEnvPath = path.join(dashDir, '.env.local');\n const dashEnvContent = `VITE_CONVEX_URL=${convexUrlMatch[1].trim()}\\n`;\n fs.writeFileSync(dashEnvPath, dashEnvContent);\n }\n }\n\n header('AgentForge Dashboard');\n info(`Starting dashboard on port ${opts.port}...`);\n info(`Open ${colors.cyan}http://localhost:${opts.port}${colors.reset} in your browser.`);\n console.log();\n\n const child = spawn('pnpm', ['dev', '--port', opts.port], {\n cwd: dashDir,\n stdio: 'inherit',\n shell: true,\n });\n\n child.on('error', (err) => {\n error(`Failed to start dashboard: ${err.message}`);\n });\n });\n\n program\n .command('logs')\n .description('Show recent activity logs')\n .option('-n, --lines <count>', 'Number of log entries', '20')\n .option('--agent <id>', 'Filter by agent ID')\n .option('--json', 'Output as JSON')\n .action(async (opts) => {\n const client = await createClient();\n const args: Record<string, any> = {};\n if (opts.agent) args.agentId = opts.agent;\n\n const result = await safeCall(\n () => client.query('usage:list' as any, args),\n 'Failed to fetch logs'\n );\n\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return; }\n header('Activity Logs');\n const items = ((result as any[]) || []).slice(0, parseInt(opts.lines));\n if (items.length === 0) { info('No activity logs found.'); return; }\n\n items.forEach((log: any) => {\n const time = new Date(log.timestamp || log.createdAt).toLocaleString();\n const agent = log.agentId || 'system';\n const action = log.action || log.type || 'unknown';\n const tokens = log.tokensUsed ? `${log.tokensUsed} tokens` : '';\n console.log(` ${colors.dim}${time}${colors.reset} ${colors.cyan}${agent}${colors.reset} ${action} ${tokens}`);\n });\n console.log();\n });\n\n program\n .command('heartbeat')\n .description('Check and resume pending agent tasks')\n .option('--agent <id>', 'Check specific agent')\n .action(async (opts) => {\n const client = await createClient();\n header('Heartbeat Check');\n\n const args: Record<string, any> = {};\n if (opts.agent) args.agentId = opts.agent;\n\n const result = await safeCall(\n () => client.query('heartbeat:listActive' as any, args),\n 'Failed to check heartbeat'\n );\n\n const items = (result as any[]) || [];\n if (items.length === 0) {\n success('All tasks complete. No pending work.');\n return;\n }\n\n info(`Found ${items.length} active heartbeat(s):`);\n items.forEach((task: any, i: number) => {\n console.log(` ${colors.yellow}${i + 1}.${colors.reset} [${task.agentId}] ${task.currentTask || 'No current task'}`);\n console.log(` ${colors.dim}Status: ${task.status} | Pending: ${(task.pendingTasks || []).length} task(s)${colors.reset}`);\n });\n console.log();\n\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((r) => rl.question('Reset stalled heartbeats? (y/N): ', (a) => { rl.close(); r(a.trim()); }));\n if (answer.toLowerCase() === 'y') {\n for (const task of items) {\n info(`Resetting heartbeat for agent \"${task.agentId}\"...`);\n await safeCall(\n () => client.mutation('heartbeat:updateStatus' as any, { agentId: task.agentId, status: 'active', currentTask: undefined }),\n 'Failed to reset heartbeat'\n );\n }\n success('All heartbeats reset.');\n }\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport prompts from 'prompts';\nimport { execSync } from 'node:child_process';\nimport {\n readCredentials,\n writeCredentials,\n deleteCredentials,\n isAuthenticated,\n getCredentialsPath,\n getCloudUrl,\n} from '../lib/credentials.js';\nimport { CloudClient, CloudClientError } from '../lib/cloud-client.js';\nimport { header, success, error, info, details } from '../lib/display.js';\n\n/**\n * Register login, logout, and whoami commands\n */\nexport function registerLoginCommand(program: Command) {\n // Login command\n program\n .command('login')\n .description('Authenticate with AgentForge Cloud')\n .option('--api-key <key>', 'API key for authentication (skips browser flow)')\n .option('--cloud-url <url>', 'Custom AgentForge Cloud URL')\n .action(async (options) => {\n header('AgentForge Cloud Login');\n\n // Check if already logged in\n const existingCreds = await readCredentials();\n if (existingCreds?.apiKey) {\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: 'You are already logged in. Overwrite existing credentials?',\n initial: false,\n });\n\n if (!overwrite) {\n info('Login cancelled.');\n return;\n }\n }\n\n let apiKey: string;\n let cloudUrl: string;\n\n if (options.apiKey) {\n // Use provided API key\n apiKey = options.apiKey;\n cloudUrl = options.cloudUrl || process.env.AGENTFORGE_CLOUD_URL || 'https://cloud.agentforge.ai';\n } else {\n // Interactive login or browser OAuth\n const { method } = await prompts({\n type: 'select',\n name: 'method',\n message: 'How would you like to authenticate?',\n choices: [\n { title: 'Enter API key manually', value: 'api-key' },\n { title: 'Browser (OAuth - coming soon)', value: 'browser', disabled: true },\n ],\n });\n\n if (method === 'api-key') {\n const response = await prompts({\n type: 'password',\n name: 'key',\n message: 'Enter your AgentForge API key:',\n validate: (value) => value.length > 0 ? true : 'API key is required',\n });\n apiKey = response.key;\n } else {\n // Browser flow placeholder\n error('Browser authentication not yet implemented. Use --api-key flag.');\n process.exit(1);\n }\n\n cloudUrl = options.cloudUrl || process.env.AGENTFORGE_CLOUD_URL || 'https://cloud.agentforge.ai';\n }\n\n // Validate the API key\n const spinner = ora('Authenticating with AgentForge Cloud...').start();\n\n try {\n const client = new CloudClient(cloudUrl, apiKey);\n const user = await client.authenticate();\n\n // Store credentials\n await writeCredentials({\n apiKey,\n cloudUrl,\n userEmail: user.email,\n userName: user.name,\n });\n\n spinner.succeed('Authentication successful!');\n\n success(`Logged in as ${chalk.bold(user.email)}`);\n info(`Cloud URL: ${cloudUrl}`);\n info(`Credentials stored at: ${getCredentialsPath()}`);\n } catch (err: any) {\n spinner.fail('Authentication failed');\n\n if (err instanceof CloudClientError) {\n error(err.message);\n if (err.code === 'NETWORK_ERROR') {\n info('Check your internet connection and try again.');\n } else if (err.status === 401) {\n info('Your API key appears to be invalid. Please check and try again.');\n }\n } else {\n error(`Unexpected error: ${err.message || err}`);\n }\n\n process.exit(1);\n }\n });\n\n // Logout command\n program\n .command('logout')\n .description('Clear AgentForge Cloud credentials')\n .action(async () => {\n header('AgentForge Cloud Logout');\n\n const wasLoggedIn = await isAuthenticated();\n \n if (!wasLoggedIn) {\n info('You are not currently logged in.');\n return;\n }\n\n const { confirm } = await prompts({\n type: 'confirm',\n name: 'confirm',\n message: 'Are you sure you want to log out?',\n initial: true,\n });\n\n if (!confirm) {\n info('Logout cancelled.');\n return;\n }\n\n const deleted = await deleteCredentials();\n \n if (deleted) {\n success('Logged out successfully.');\n info('Your credentials have been removed.');\n } else {\n error('Failed to remove credentials.');\n process.exit(1);\n }\n });\n\n // Whoami command\n program\n .command('whoami')\n .description('Show current user information')\n .action(async () => {\n header('Current User');\n\n const creds = await readCredentials();\n const cloudUrl = await getCloudUrl();\n\n if (!creds?.apiKey) {\n info('You are not logged in.');\n info('Run \"agentforge login\" to authenticate.');\n return;\n }\n\n // Display stored info\n details({\n 'Cloud URL': cloudUrl,\n 'Email': creds.userEmail || 'Unknown',\n 'Name': creds.userName || 'Unknown',\n 'Credentials File': getCredentialsPath(),\n });\n\n // Try to validate with the server\n const spinner = ora('Validating session...').start();\n\n try {\n const client = new CloudClient(creds.cloudUrl, creds.apiKey);\n const user = await client.authenticate();\n\n spinner.succeed('Session is valid');\n success(`Authenticated as ${chalk.bold(user.email)}`);\n } catch (err: any) {\n spinner.fail('Session validation failed');\n\n if (err instanceof CloudClientError && err.status === 401) {\n error('Your session has expired or the API key is invalid.');\n info('Run \"agentforge login\" to re-authenticate.');\n } else {\n error(`Error: ${err.message || err}`);\n info('Your credentials are stored but the server could not be reached.');\n }\n }\n });\n}\n","/**\n * CLI Command: agentforge channel:telegram\n *\n * Configure and start a Telegram bot that routes messages through\n * the AgentForge agent execution pipeline.\n *\n * Usage:\n * agentforge channel:telegram start --agent <id> [--token <bot-token>]\n * agentforge channel:telegram configure\n * agentforge channel:telegram status\n */\n\nimport { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, success, error, info, dim, warn, details, colors } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\n/**\n * Read a value from .env files in the current directory.\n */\nfunction readEnvValue(key: string): string | undefined {\n const cwd = process.cwd();\n const envFiles = ['.env.local', '.env', '.env.production'];\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(new RegExp(`^${key}=(.+)$`, 'm'));\n if (match) return match[1].trim().replace(/[\"']/g, '');\n }\n }\n return undefined;\n}\n\n/**\n * Write a value to .env.local in the current directory.\n */\nfunction writeEnvValue(key: string, value: string, envFile: string = '.env.local'): void {\n const envPath = path.join(process.cwd(), envFile);\n let content = '';\n if (fs.existsSync(envPath)) {\n content = fs.readFileSync(envPath, 'utf-8');\n }\n\n const lines = content.split('\\n');\n const idx = lines.findIndex((l) => l.startsWith(`${key}=`));\n if (idx >= 0) {\n lines[idx] = `${key}=${value}`;\n } else {\n lines.push(`${key}=${value}`);\n }\n\n fs.writeFileSync(envPath, lines.join('\\n'));\n}\n\nexport function registerChannelTelegramCommand(program: Command) {\n const channel = program\n .command('channel:telegram')\n .description('Manage the Telegram messaging channel');\n\n // ─── Start ─────────────────────────────────────────────────────────\n channel\n .command('start')\n .description('Start the Telegram bot and begin routing messages to an agent')\n .option('-a, --agent <id>', 'Agent ID to route messages to')\n .option('-t, --token <token>', 'Telegram Bot Token (overrides .env)')\n .option('--webhook-url <url>', 'Use webhook mode with this URL')\n .option('--webhook-secret <secret>', 'Webhook verification secret')\n .option('--bot-username <username>', 'Bot username for @mention detection')\n .option('--polling-interval <ms>', 'Polling interval in milliseconds', '1000')\n .option('--log-level <level>', 'Log level: debug, info, warn, error', 'info')\n .option('--group-mention-only', 'Only respond to @mentions in groups', true)\n .action(async (opts) => {\n header('Telegram Channel');\n\n // Resolve bot token\n const botToken = opts.token || readEnvValue('TELEGRAM_BOT_TOKEN') || process.env.TELEGRAM_BOT_TOKEN;\n if (!botToken) {\n error('Telegram Bot Token not found.');\n info('Set it with: agentforge channel:telegram configure');\n info('Or pass it with: --token <bot-token>');\n info('Or set TELEGRAM_BOT_TOKEN in your .env.local file');\n process.exit(1);\n }\n\n // Resolve Convex URL\n const convexUrl = readEnvValue('CONVEX_URL') || process.env.CONVEX_URL;\n if (!convexUrl) {\n error('CONVEX_URL not found. Run `npx convex dev` first.');\n process.exit(1);\n }\n\n // Resolve agent ID\n let agentId = opts.agent;\n if (!agentId) {\n // Try to get from env\n agentId = readEnvValue('AGENTFORGE_AGENT_ID') || process.env.AGENTFORGE_AGENT_ID;\n }\n\n if (!agentId) {\n // List agents and let user pick\n info('No agent specified. Fetching available agents...');\n const client = await createClient();\n const agents = await safeCall(\n () => client.query('agents:list' as any, {}),\n 'Failed to list agents'\n );\n\n if (!agents || (agents as any[]).length === 0) {\n error('No agents found. Create one first: agentforge agents create');\n process.exit(1);\n }\n\n console.log();\n (agents as any[]).forEach((a: any, i: number) => {\n console.log(\n ` ${colors.cyan}${i + 1}.${colors.reset} ${a.name} ${colors.dim}(${a.id})${colors.reset} — ${a.model}`\n );\n });\n console.log();\n\n const choice = await prompt('Select agent (number or ID): ');\n const idx = parseInt(choice) - 1;\n agentId = idx >= 0 && idx < (agents as any[]).length\n ? (agents as any[])[idx].id\n : choice;\n }\n\n // Display configuration\n info(`Agent: ${agentId}`);\n info(`Convex: ${convexUrl}`);\n info(`Mode: ${opts.webhookUrl ? 'Webhook' : 'Long-polling'}`);\n info(`Log: ${opts.logLevel}`);\n console.log();\n\n // Dynamically import the TelegramChannel from core\n // We use dynamic import because the core package may not be installed\n // in all environments, and we want to give a helpful error message.\n let TelegramChannel: any;\n try {\n // Use string variable to avoid TS2307 — this is a dynamic import for an optional peer\n const corePkg = '@agentforge-ai/core/channels/telegram';\n const mod = await import(/* @vite-ignore */ corePkg);\n TelegramChannel = mod.TelegramChannel;\n } catch (importError: any) {\n // Fallback: try to use the Convex HTTP API directly with a minimal implementation\n error('Could not import @agentforge-ai/core. Using built-in Telegram runner.');\n dim(` Error: ${importError.message}`);\n console.log();\n\n // Use the built-in minimal runner\n await runMinimalTelegramBot({\n botToken,\n agentId,\n convexUrl,\n logLevel: opts.logLevel,\n pollingIntervalMs: parseInt(opts.pollingInterval),\n });\n return;\n }\n\n // Start the Telegram channel\n try {\n const channel = new TelegramChannel({\n botToken,\n agentId,\n convexUrl,\n useWebhook: !!opts.webhookUrl,\n webhookUrl: opts.webhookUrl,\n webhookSecret: opts.webhookSecret,\n botUsername: opts.botUsername,\n groupMentionOnly: opts.groupMentionOnly,\n pollingIntervalMs: parseInt(opts.pollingInterval),\n logLevel: opts.logLevel,\n });\n\n await channel.start();\n success('Telegram bot is running!');\n dim(' Press Ctrl+C to stop.');\n\n // Keep the process alive\n await new Promise(() => {});\n } catch (startError: any) {\n error(`Failed to start Telegram bot: ${startError.message}`);\n process.exit(1);\n }\n });\n\n // ─── Configure ─────────────────────────────────────────────────────\n channel\n .command('configure')\n .description('Configure the Telegram bot token and settings')\n .action(async () => {\n header('Configure Telegram Channel');\n\n const currentToken = readEnvValue('TELEGRAM_BOT_TOKEN');\n if (currentToken) {\n const masked = currentToken.slice(0, 6) + '****' + currentToken.slice(-4);\n info(`Current token: ${masked}`);\n }\n\n console.log();\n info('To get a bot token:');\n dim(' 1. Open Telegram and search for @BotFather');\n dim(' 2. Send /newbot and follow the instructions');\n dim(' 3. Copy the token provided');\n console.log();\n\n const token = await prompt('Telegram Bot Token: ');\n if (!token) {\n error('Bot token is required.');\n process.exit(1);\n }\n\n // Validate the token by calling getMe\n info('Validating token...');\n try {\n const response = await fetch(`https://api.telegram.org/bot${token}/getMe`);\n const data = await response.json() as { ok: boolean; result?: { username: string; first_name: string } };\n if (!data.ok) {\n error('Invalid bot token. Please check and try again.');\n process.exit(1);\n }\n success(`Bot verified: @${data.result?.username} (${data.result?.first_name})`);\n\n // Save bot username too\n if (data.result?.username) {\n writeEnvValue('TELEGRAM_BOT_USERNAME', data.result.username);\n }\n } catch (fetchError: any) {\n warn(`Could not validate token (network error): ${fetchError.message}`);\n info('Saving token anyway. You can validate later with: agentforge channel:telegram status');\n }\n\n writeEnvValue('TELEGRAM_BOT_TOKEN', token);\n success('Token saved to .env.local');\n\n // Ask for default agent\n console.log();\n const defaultAgent = await prompt('Default agent ID (optional, press Enter to skip): ');\n if (defaultAgent) {\n writeEnvValue('AGENTFORGE_AGENT_ID', defaultAgent);\n success(`Default agent set to: ${defaultAgent}`);\n }\n\n console.log();\n success('Configuration complete!');\n info('Start the bot with: agentforge channel:telegram start');\n });\n\n // ─── Status ────────────────────────────────────────────────────────\n channel\n .command('status')\n .description('Check the Telegram bot configuration and connectivity')\n .action(async () => {\n header('Telegram Channel Status');\n\n const token = readEnvValue('TELEGRAM_BOT_TOKEN');\n const agentId = readEnvValue('AGENTFORGE_AGENT_ID');\n const convexUrl = readEnvValue('CONVEX_URL');\n const botUsername = readEnvValue('TELEGRAM_BOT_USERNAME');\n\n const statusData: Record<string, string> = {\n 'Bot Token': token ? `${token.slice(0, 6)}****${token.slice(-4)}` : `${colors.red}Not configured${colors.reset}`,\n 'Bot Username': botUsername ? `@${botUsername}` : `${colors.dim}Unknown${colors.reset}`,\n 'Default Agent': agentId || `${colors.dim}Not set${colors.reset}`,\n 'Convex URL': convexUrl || `${colors.red}Not configured${colors.reset}`,\n };\n\n details(statusData);\n\n // Validate token if present\n if (token) {\n info('Checking bot connectivity...');\n try {\n const response = await fetch(`https://api.telegram.org/bot${token}/getMe`);\n const data = await response.json() as { ok: boolean; result?: { username: string; first_name: string; id: number } };\n if (data.ok) {\n success(`Bot online: @${data.result?.username} (ID: ${data.result?.id})`);\n } else {\n error('Bot token is invalid or expired.');\n }\n } catch {\n warn('Could not reach Telegram API (network error).');\n }\n }\n\n // Check Convex connectivity\n if (convexUrl) {\n info('Checking Convex connectivity...');\n try {\n const client = await createClient();\n const agents = await client.query('agents:list' as any, {});\n success(`Convex connected. ${(agents as any[]).length} agents available.`);\n } catch {\n warn('Could not reach Convex deployment.');\n }\n }\n });\n}\n\n// =====================================================\n// Minimal Built-in Telegram Bot Runner\n// =====================================================\n\n/**\n * A minimal Telegram bot runner that works without the @agentforge-ai/core\n * package. Uses the Telegram Bot API and Convex HTTP API directly.\n *\n * This is a fallback for when the core package isn't available\n * (e.g., in a fresh project before building).\n */\nasync function runMinimalTelegramBot(config: {\n botToken: string;\n agentId: string;\n convexUrl: string;\n logLevel?: string;\n pollingIntervalMs?: number;\n}): Promise<void> {\n const { botToken, agentId, convexUrl } = config;\n const apiBase = `https://api.telegram.org/bot${botToken}`;\n const convexBase = convexUrl.replace(/\\/$/, '');\n const threadMap = new Map<string, string>();\n let lastUpdateId = 0;\n\n // Verify bot\n info('Verifying bot token...');\n const meRes = await fetch(`${apiBase}/getMe`);\n const meData = await meRes.json() as { ok: boolean; result?: { username: string } };\n if (!meData.ok) {\n error('Invalid bot token.');\n process.exit(1);\n }\n success(`Bot connected: @${meData.result?.username}`);\n\n // Delete any existing webhook\n await fetch(`${apiBase}/deleteWebhook`, { method: 'POST' });\n\n info('Polling for messages...');\n dim(' Press Ctrl+C to stop.');\n console.log();\n\n // Graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\nStopping...');\n process.exit(0);\n });\n\n // Convex HTTP helpers\n async function convexMutation(fn: string, args: Record<string, unknown>): Promise<unknown> {\n const res = await fetch(`${convexBase}/api/mutation`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: fn, args }),\n });\n const data = await res.json() as { value?: unknown; status?: string; errorMessage?: string };\n if (data.status === 'error') throw new Error(data.errorMessage);\n return data.value;\n }\n\n async function convexAction(fn: string, args: Record<string, unknown>): Promise<unknown> {\n const res = await fetch(`${convexBase}/api/action`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: fn, args }),\n });\n const data = await res.json() as { value?: unknown; status?: string; errorMessage?: string };\n if (data.status === 'error') throw new Error(data.errorMessage);\n return data.value;\n }\n\n async function sendTelegramMessage(chatId: string, text: string): Promise<void> {\n await fetch(`${apiBase}/sendMessage`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ chat_id: chatId, text }),\n });\n }\n\n async function sendTyping(chatId: string): Promise<void> {\n await fetch(`${apiBase}/sendChatAction`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ chat_id: chatId, action: 'typing' }),\n }).catch(() => {});\n }\n\n async function getOrCreateThread(chatId: string, senderName?: string): Promise<string> {\n const cached = threadMap.get(chatId);\n if (cached) return cached;\n\n const threadId = await convexMutation('chat:createThread', {\n agentId,\n name: senderName ? `Telegram: ${senderName}` : `Telegram Chat ${chatId}`,\n userId: `telegram:${chatId}`,\n }) as string;\n\n threadMap.set(chatId, threadId);\n return threadId;\n }\n\n // Poll loop\n while (true) {\n try {\n const res = await fetch(`${apiBase}/getUpdates`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n offset: lastUpdateId + 1,\n timeout: 30,\n allowed_updates: ['message'],\n }),\n });\n\n const data = await res.json() as { ok: boolean; result?: any[] };\n if (!data.ok || !data.result) continue;\n\n for (const update of data.result) {\n lastUpdateId = update.update_id;\n const msg = update.message;\n if (!msg?.text) continue;\n\n const chatId = String(msg.chat.id);\n const senderName = msg.from?.first_name || 'User';\n const text = msg.text.trim();\n\n // Handle commands\n if (text === '/start') {\n threadMap.delete(chatId);\n await sendTelegramMessage(chatId, `👋 Welcome! I'm powered by AgentForge.\\n\\nSend me a message and I'll respond using AI.\\n\\nCommands:\\n/new — Start a new conversation\\n/help — Show help`);\n continue;\n }\n if (text === '/new') {\n threadMap.delete(chatId);\n await sendTelegramMessage(chatId, '🔄 New conversation started. Send me a message!');\n continue;\n }\n if (text === '/help') {\n await sendTelegramMessage(chatId, '🤖 AgentForge Telegram Bot\\n\\nJust send me a message and I\\'ll respond using AI.\\n\\nCommands:\\n/start — Reset and show welcome\\n/new — Start a fresh conversation\\n/help — Show this help');\n continue;\n }\n\n // Route to agent\n console.log(`[${senderName}] ${text}`);\n await sendTyping(chatId);\n\n try {\n const threadId = await getOrCreateThread(chatId, senderName);\n const result = await convexAction('chat:sendMessage', {\n agentId,\n threadId,\n content: text,\n userId: `telegram:${msg.from?.id || chatId}`,\n }) as { response: string };\n\n if (result?.response) {\n // Split long messages\n const response = result.response;\n if (response.length <= 4096) {\n await sendTelegramMessage(chatId, response);\n } else {\n const chunks = response.match(/.{1,4096}/gs) || [];\n for (const chunk of chunks) {\n await sendTelegramMessage(chatId, chunk);\n }\n }\n console.log(`[Agent] ${response.substring(0, 100)}${response.length > 100 ? '...' : ''}`);\n } else {\n await sendTelegramMessage(chatId, '🤔 I couldn\\'t generate a response. Please try again.');\n }\n } catch (routeError: any) {\n console.error(`Error: ${routeError.message}`);\n await sendTelegramMessage(chatId, '⚠️ Sorry, I encountered an error. Please try again.');\n }\n }\n } catch (pollError: any) {\n if (pollError.message?.includes('ECONNREFUSED') || pollError.message?.includes('fetch failed')) {\n warn('Network error. Retrying in 5s...');\n await new Promise((r) => setTimeout(r, 5000));\n } else {\n console.error(`Poll error: ${pollError.message}`);\n await new Promise((r) => setTimeout(r, 1000));\n }\n }\n }\n}\n","/**\n * CLI Command: agentforge channel:whatsapp\n *\n * Configure and start a WhatsApp webhook server that routes messages\n * through the AgentForge agent execution pipeline.\n *\n * Usage:\n * agentforge channel:whatsapp start --agent <id> [--access-token <token>]\n * agentforge channel:whatsapp configure\n * agentforge channel:whatsapp status\n */\n\nimport { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, success, error, info, dim, warn, details, colors } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\n/**\n * Read a value from .env files in the current directory.\n */\nfunction readEnvValue(key: string): string | undefined {\n const cwd = process.cwd();\n const envFiles = ['.env.local', '.env', '.env.production'];\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(new RegExp(`^${key}=(.+)$`, 'm'));\n if (match) return match[1].trim().replace(/[\"']/g, '');\n }\n }\n return undefined;\n}\n\n/**\n * Write a value to .env.local in the current directory.\n */\nfunction writeEnvValue(key: string, value: string, envFile: string = '.env.local'): void {\n const envPath = path.join(process.cwd(), envFile);\n let content = '';\n if (fs.existsSync(envPath)) {\n content = fs.readFileSync(envPath, 'utf-8');\n }\n\n const lines = content.split('\\n');\n const idx = lines.findIndex((l) => l.startsWith(`${key}=`));\n if (idx >= 0) {\n lines[idx] = `${key}=${value}`;\n } else {\n lines.push(`${key}=${value}`);\n }\n\n fs.writeFileSync(envPath, lines.join('\\n'));\n}\n\nexport function registerChannelWhatsAppCommand(program: Command) {\n const channel = program\n .command('channel:whatsapp')\n .description('Manage the WhatsApp messaging channel');\n\n // ─── Start ─────────────────────────────────────────────────────────\n channel\n .command('start')\n .description('Start the WhatsApp webhook server and begin routing messages to an agent')\n .option('-a, --agent <id>', 'Agent ID to route messages to')\n .option('--access-token <token>', 'WhatsApp Cloud API access token (overrides .env)')\n .option('--phone-number-id <id>', 'WhatsApp Business Phone Number ID (overrides .env)')\n .option('--verify-token <token>', 'Webhook verify token (overrides .env)')\n .option('--webhook-port <port>', 'Port for the webhook server', '3001')\n .option('--webhook-path <path>', 'Path for the webhook endpoint', '/webhook/whatsapp')\n .option('--api-version <version>', 'WhatsApp Cloud API version', 'v21.0')\n .option('--log-level <level>', 'Log level: debug, info, warn, error', 'info')\n .action(async (opts) => {\n header('WhatsApp Channel');\n\n // Resolve access token\n const accessToken = opts.accessToken || readEnvValue('WHATSAPP_ACCESS_TOKEN') || process.env.WHATSAPP_ACCESS_TOKEN;\n if (!accessToken) {\n error('WhatsApp Access Token not found.');\n info('Set it with: agentforge channel:whatsapp configure');\n info('Or pass it with: --access-token <token>');\n info('Or set WHATSAPP_ACCESS_TOKEN in your .env.local file');\n process.exit(1);\n }\n\n // Resolve phone number ID\n const phoneNumberId = opts.phoneNumberId || readEnvValue('WHATSAPP_PHONE_NUMBER_ID') || process.env.WHATSAPP_PHONE_NUMBER_ID;\n if (!phoneNumberId) {\n error('WhatsApp Phone Number ID not found.');\n info('Set it with: agentforge channel:whatsapp configure');\n info('Or pass it with: --phone-number-id <id>');\n info('Or set WHATSAPP_PHONE_NUMBER_ID in your .env.local file');\n process.exit(1);\n }\n\n // Resolve verify token\n const verifyToken = opts.verifyToken || readEnvValue('WHATSAPP_VERIFY_TOKEN') || process.env.WHATSAPP_VERIFY_TOKEN;\n if (!verifyToken) {\n error('WhatsApp Verify Token not found.');\n info('Set it with: agentforge channel:whatsapp configure');\n info('Or pass it with: --verify-token <token>');\n info('Or set WHATSAPP_VERIFY_TOKEN in your .env.local file');\n process.exit(1);\n }\n\n // Resolve Convex URL\n const convexUrl = readEnvValue('CONVEX_URL') || process.env.CONVEX_URL;\n if (!convexUrl) {\n error('CONVEX_URL not found. Run `npx convex dev` first.');\n process.exit(1);\n }\n\n // Resolve agent ID\n let agentId = opts.agent;\n if (!agentId) {\n agentId = readEnvValue('AGENTFORGE_AGENT_ID') || process.env.AGENTFORGE_AGENT_ID;\n }\n\n if (!agentId) {\n // List agents and let user pick\n info('No agent specified. Fetching available agents...');\n const client = await createClient();\n const agents = await safeCall(\n () => client.query('agents:list' as any, {}),\n 'Failed to list agents'\n );\n\n if (!agents || (agents as any[]).length === 0) {\n error('No agents found. Create one first: agentforge agents create');\n process.exit(1);\n }\n\n console.log();\n (agents as any[]).forEach((a: any, i: number) => {\n console.log(\n ` ${colors.cyan}${i + 1}.${colors.reset} ${a.name} ${colors.dim}(${a.id})${colors.reset} — ${a.model}`\n );\n });\n console.log();\n\n const choice = await prompt('Select agent (number or ID): ');\n const idx = parseInt(choice) - 1;\n agentId = idx >= 0 && idx < (agents as any[]).length\n ? (agents as any[])[idx].id\n : choice;\n }\n\n // Display configuration\n const webhookPort = parseInt(opts.webhookPort);\n const webhookPath = opts.webhookPath;\n info(`Agent: ${agentId}`);\n info(`Convex: ${convexUrl}`);\n info(`Webhook: http://localhost:${webhookPort}${webhookPath}`);\n info(`API Version: ${opts.apiVersion}`);\n info(`Log: ${opts.logLevel}`);\n console.log();\n\n // Dynamically import the WhatsAppChannel from core\n let WhatsAppChannel: any;\n try {\n const corePkg = '@agentforge-ai/core/channels/whatsapp';\n const mod = await import(/* @vite-ignore */ corePkg);\n WhatsAppChannel = mod.WhatsAppChannel;\n } catch (importError: any) {\n // Fallback: use the built-in minimal runner\n error('Could not import @agentforge-ai/core. Using built-in WhatsApp runner.');\n dim(` Error: ${importError.message}`);\n console.log();\n\n await runMinimalWhatsAppBot({\n accessToken,\n phoneNumberId,\n verifyToken,\n agentId,\n convexUrl,\n webhookPort,\n webhookPath,\n logLevel: opts.logLevel,\n });\n return;\n }\n\n // Start the WhatsApp channel\n try {\n const channel = new WhatsAppChannel({\n accessToken,\n phoneNumberId,\n verifyToken,\n agentId,\n convexUrl,\n webhookPort,\n webhookPath,\n apiVersion: opts.apiVersion,\n logLevel: opts.logLevel,\n });\n\n await channel.start();\n success('WhatsApp webhook server is running!');\n dim(` Webhook URL: http://localhost:${webhookPort}${webhookPath}`);\n dim(' Configure this URL in your Meta App Dashboard.');\n dim(' Press Ctrl+C to stop.');\n\n // Keep the process alive\n await new Promise(() => {});\n } catch (startError: any) {\n error(`Failed to start WhatsApp channel: ${startError.message}`);\n process.exit(1);\n }\n });\n\n // ─── Configure ─────────────────────────────────────────────────────\n channel\n .command('configure')\n .description('Configure the WhatsApp Cloud API credentials')\n .action(async () => {\n header('Configure WhatsApp Channel');\n\n console.log();\n info('To set up WhatsApp Cloud API:');\n dim(' 1. Go to https://developers.facebook.com/apps/');\n dim(' 2. Create or select a Meta App with WhatsApp product');\n dim(' 3. Go to WhatsApp > API Setup');\n dim(' 4. Copy the Access Token, Phone Number ID, and set a Verify Token');\n console.log();\n\n // Access Token\n const currentToken = readEnvValue('WHATSAPP_ACCESS_TOKEN');\n if (currentToken) {\n const masked = currentToken.slice(0, 10) + '****' + currentToken.slice(-4);\n info(`Current access token: ${masked}`);\n }\n\n const accessToken = await prompt('WhatsApp Access Token: ');\n if (!accessToken) {\n error('Access token is required.');\n process.exit(1);\n }\n\n // Validate the token\n info('Validating access token...');\n try {\n const response = await fetch('https://graph.facebook.com/v21.0/me', {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n const data = await response.json() as { id?: string; name?: string; error?: { message: string } };\n if (data.error) {\n warn(`Token validation warning: ${data.error.message}`);\n info('Saving token anyway. You can validate later with: agentforge channel:whatsapp status');\n } else {\n success(`Token verified: ${data.name || data.id}`);\n }\n } catch (fetchError: any) {\n warn(`Could not validate token (network error): ${fetchError.message}`);\n info('Saving token anyway.');\n }\n\n writeEnvValue('WHATSAPP_ACCESS_TOKEN', accessToken);\n success('Access token saved to .env.local');\n\n // Phone Number ID\n console.log();\n const currentPhoneId = readEnvValue('WHATSAPP_PHONE_NUMBER_ID');\n if (currentPhoneId) {\n info(`Current Phone Number ID: ${currentPhoneId}`);\n }\n\n const phoneNumberId = await prompt('WhatsApp Phone Number ID: ');\n if (!phoneNumberId) {\n error('Phone Number ID is required.');\n process.exit(1);\n }\n\n // Validate the phone number ID\n info('Validating phone number...');\n try {\n const response = await fetch(`https://graph.facebook.com/v21.0/${phoneNumberId}`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n const data = await response.json() as {\n display_phone_number?: string;\n verified_name?: string;\n error?: { message: string };\n };\n if (data.error) {\n warn(`Phone number validation warning: ${data.error.message}`);\n } else {\n success(`Phone number verified: ${data.display_phone_number} (${data.verified_name})`);\n }\n } catch {\n warn('Could not validate phone number (network error).');\n }\n\n writeEnvValue('WHATSAPP_PHONE_NUMBER_ID', phoneNumberId);\n success('Phone Number ID saved to .env.local');\n\n // Verify Token\n console.log();\n const currentVerifyToken = readEnvValue('WHATSAPP_VERIFY_TOKEN');\n if (currentVerifyToken) {\n info(`Current verify token: ${currentVerifyToken.slice(0, 6)}****`);\n }\n\n let verifyToken = await prompt('Webhook Verify Token (press Enter to auto-generate): ');\n if (!verifyToken) {\n // Auto-generate a verify token\n verifyToken = `agentforge_${Date.now()}_${Math.random().toString(36).substring(2, 10)}`;\n info(`Generated verify token: ${verifyToken}`);\n }\n\n writeEnvValue('WHATSAPP_VERIFY_TOKEN', verifyToken);\n success('Verify token saved to .env.local');\n\n // Default agent\n console.log();\n const defaultAgent = await prompt('Default agent ID (optional, press Enter to skip): ');\n if (defaultAgent) {\n writeEnvValue('AGENTFORGE_AGENT_ID', defaultAgent);\n success(`Default agent set to: ${defaultAgent}`);\n }\n\n console.log();\n success('Configuration complete!');\n info('Start the webhook server with: agentforge channel:whatsapp start');\n console.log();\n info('Next steps:');\n dim(' 1. Start the webhook server: agentforge channel:whatsapp start');\n dim(' 2. Expose the webhook URL (e.g., with ngrok or cloudflared)');\n dim(' 3. Configure the webhook URL in your Meta App Dashboard');\n dim(' 4. Subscribe to \"messages\" webhook field');\n });\n\n // ─── Status ────────────────────────────────────────────────────────\n channel\n .command('status')\n .description('Check the WhatsApp channel configuration and connectivity')\n .action(async () => {\n header('WhatsApp Channel Status');\n\n const accessToken = readEnvValue('WHATSAPP_ACCESS_TOKEN');\n const phoneNumberId = readEnvValue('WHATSAPP_PHONE_NUMBER_ID');\n const verifyToken = readEnvValue('WHATSAPP_VERIFY_TOKEN');\n const agentId = readEnvValue('AGENTFORGE_AGENT_ID');\n const convexUrl = readEnvValue('CONVEX_URL');\n\n const statusData: Record<string, string> = {\n 'Access Token': accessToken ? `${accessToken.slice(0, 10)}****${accessToken.slice(-4)}` : `${colors.red}Not configured${colors.reset}`,\n 'Phone Number ID': phoneNumberId || `${colors.red}Not configured${colors.reset}`,\n 'Verify Token': verifyToken ? `${verifyToken.slice(0, 6)}****` : `${colors.red}Not configured${colors.reset}`,\n 'Default Agent': agentId || `${colors.dim}Not set${colors.reset}`,\n 'Convex URL': convexUrl || `${colors.red}Not configured${colors.reset}`,\n };\n\n details(statusData);\n\n // Validate access token and phone number if present\n if (accessToken && phoneNumberId) {\n info('Checking WhatsApp Cloud API connectivity...');\n try {\n const response = await fetch(`https://graph.facebook.com/v21.0/${phoneNumberId}`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n const data = await response.json() as {\n display_phone_number?: string;\n verified_name?: string;\n id?: string;\n error?: { message: string };\n };\n if (data.error) {\n error(`API error: ${data.error.message}`);\n } else {\n success(`WhatsApp Business: ${data.verified_name || data.display_phone_number} (ID: ${data.id})`);\n }\n } catch {\n warn('Could not reach WhatsApp Cloud API (network error).');\n }\n }\n\n // Check Convex connectivity\n if (convexUrl) {\n info('Checking Convex connectivity...');\n try {\n const client = await createClient();\n const agents = await client.query('agents:list' as any, {});\n success(`Convex connected. ${(agents as any[]).length} agents available.`);\n } catch {\n warn('Could not reach Convex deployment.');\n }\n }\n });\n}\n\n// =====================================================\n// Minimal Built-in WhatsApp Bot Runner\n// =====================================================\n\n/**\n * A minimal WhatsApp webhook runner that works without the @agentforge-ai/core\n * package. Uses the WhatsApp Cloud API and Convex HTTP API directly.\n *\n * This is a fallback for when the core package isn't available.\n */\nasync function runMinimalWhatsAppBot(config: {\n accessToken: string;\n phoneNumberId: string;\n verifyToken: string;\n agentId: string;\n convexUrl: string;\n webhookPort: number;\n webhookPath: string;\n logLevel?: string;\n}): Promise<void> {\n const { accessToken, phoneNumberId, verifyToken, agentId, convexUrl, webhookPort, webhookPath } = config;\n const apiBase = `https://graph.facebook.com/v21.0`;\n const convexBase = convexUrl.replace(/\\/$/, '');\n const threadMap = new Map<string, string>();\n\n // Verify access token\n info('Verifying WhatsApp access token...');\n try {\n const res = await fetch(`${apiBase}/${phoneNumberId}`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n const data = await res.json() as { verified_name?: string; display_phone_number?: string; error?: { message: string } };\n if (data.error) {\n error(`API error: ${data.error.message}`);\n process.exit(1);\n }\n success(`WhatsApp Business: ${data.verified_name || data.display_phone_number}`);\n } catch (fetchError: any) {\n warn(`Could not verify token: ${fetchError.message}`);\n info('Continuing anyway...');\n }\n\n // Convex HTTP helpers\n async function convexMutation(fn: string, args: Record<string, unknown>): Promise<unknown> {\n const res = await fetch(`${convexBase}/api/mutation`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: fn, args }),\n });\n const data = await res.json() as { value?: unknown; status?: string; errorMessage?: string };\n if (data.status === 'error') throw new Error(data.errorMessage);\n return data.value;\n }\n\n async function convexAction(fn: string, args: Record<string, unknown>): Promise<unknown> {\n const res = await fetch(`${convexBase}/api/action`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: fn, args }),\n });\n const data = await res.json() as { value?: unknown; status?: string; errorMessage?: string };\n if (data.status === 'error') throw new Error(data.errorMessage);\n return data.value;\n }\n\n async function sendWhatsAppMessage(to: string, text: string): Promise<void> {\n await fetch(`${apiBase}/${phoneNumberId}/messages`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n messaging_product: 'whatsapp',\n to,\n type: 'text',\n text: { body: text },\n }),\n });\n }\n\n async function markAsRead(messageId: string): Promise<void> {\n await fetch(`${apiBase}/${phoneNumberId}/messages`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n messaging_product: 'whatsapp',\n status: 'read',\n message_id: messageId,\n }),\n }).catch(() => {});\n }\n\n async function getOrCreateThread(phoneNumber: string, senderName?: string): Promise<string> {\n const cached = threadMap.get(phoneNumber);\n if (cached) return cached;\n\n const threadId = await convexMutation('chat:createThread', {\n agentId,\n name: senderName ? `WhatsApp: ${senderName}` : `WhatsApp +${phoneNumber}`,\n userId: `whatsapp:${phoneNumber}`,\n }) as string;\n\n threadMap.set(phoneNumber, threadId);\n return threadId;\n }\n\n // Start HTTP server for webhook\n const http = await import('node:http');\n\n const server = http.createServer(async (req, res) => {\n const url = new URL(req.url || '/', `http://localhost:${webhookPort}`);\n\n if (url.pathname !== webhookPath) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n // GET — Webhook verification\n if (req.method === 'GET') {\n const mode = url.searchParams.get('hub.mode');\n const token = url.searchParams.get('hub.verify_token');\n const challenge = url.searchParams.get('hub.challenge');\n\n if (mode === 'subscribe' && token === verifyToken) {\n res.writeHead(200, { 'Content-Type': 'text/plain' });\n res.end(challenge);\n } else {\n res.writeHead(403);\n res.end('Forbidden');\n }\n return;\n }\n\n // POST — Incoming messages\n if (req.method === 'POST') {\n try {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk as Buffer);\n }\n const body = JSON.parse(Buffer.concat(chunks).toString());\n\n // Respond immediately to avoid timeout\n res.writeHead(200);\n res.end('OK');\n\n // Process messages\n if (body.object !== 'whatsapp_business_account') return;\n\n for (const entry of body.entry || []) {\n for (const change of entry.changes || []) {\n if (change.field !== 'messages') continue;\n\n const contacts = change.value.contacts || [];\n const messages = change.value.messages || [];\n\n for (const msg of messages) {\n if (msg.type !== 'text' || !msg.text?.body) continue;\n\n const from = msg.from;\n const text = msg.text.body.trim();\n const contact = contacts.find((c: any) => c.wa_id === from);\n const senderName = contact?.profile?.name || from;\n\n console.log(`[${senderName}] ${text}`);\n\n // Mark as read\n await markAsRead(msg.id);\n\n try {\n const threadId = await getOrCreateThread(from, senderName);\n const result = await convexAction('chat:sendMessage', {\n agentId,\n threadId,\n content: text,\n userId: `whatsapp:${from}`,\n }) as { response: string };\n\n if (result?.response) {\n const response = result.response;\n if (response.length <= 4096) {\n await sendWhatsAppMessage(from, response);\n } else {\n const chunks = response.match(/.{1,4096}/gs) || [];\n for (const chunk of chunks) {\n await sendWhatsAppMessage(from, chunk);\n }\n }\n console.log(`[Agent] ${response.substring(0, 100)}${response.length > 100 ? '...' : ''}`);\n } else {\n await sendWhatsAppMessage(from, \"🤔 I couldn't generate a response. Please try again.\");\n }\n } catch (routeError: any) {\n console.error(`Error: ${routeError.message}`);\n await sendWhatsAppMessage(from, '⚠️ Sorry, I encountered an error. Please try again.');\n }\n }\n }\n }\n } catch (parseError: any) {\n console.error(`Parse error: ${parseError.message}`);\n if (!res.headersSent) {\n res.writeHead(400);\n res.end('Bad Request');\n }\n }\n return;\n }\n\n res.writeHead(405);\n res.end('Method Not Allowed');\n });\n\n // Graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\nStopping...');\n server.close();\n process.exit(0);\n });\n\n server.listen(webhookPort, () => {\n success(`Webhook server listening on port ${webhookPort}`);\n info(`Webhook URL: http://localhost:${webhookPort}${webhookPath}`);\n console.log();\n info('Next steps:');\n dim(' 1. Expose this URL publicly (e.g., ngrok http ' + webhookPort + ')');\n dim(' 2. Configure the webhook URL in your Meta App Dashboard');\n dim(' 3. Subscribe to \"messages\" webhook field');\n dim(' Press Ctrl+C to stop.');\n });\n\n // Keep alive\n await new Promise(() => {});\n}\n","/**\n * CLI Command: agentforge channel:slack\n *\n * Configure and start a Slack bot that routes messages through\n * the AgentForge agent execution pipeline via Slack Bolt.js.\n *\n * Usage:\n * agentforge channel:slack start --agent <id> [--bot-token <token>]\n * agentforge channel:slack configure\n * agentforge channel:slack status\n */\n\nimport { Command } from 'commander';\nimport { createClient, safeCall } from '../lib/convex-client.js';\nimport { header, success, error, info, dim, warn, details, colors } from '../lib/display.js';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\n\nfunction prompt(q: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));\n}\n\n/**\n * Read a value from .env files in the current directory.\n */\nfunction readEnvValue(key: string): string | undefined {\n const cwd = process.cwd();\n const envFiles = ['.env.local', '.env', '.env.production'];\n for (const envFile of envFiles) {\n const envPath = path.join(cwd, envFile);\n if (fs.existsSync(envPath)) {\n const content = fs.readFileSync(envPath, 'utf-8');\n const match = content.match(new RegExp(`^${key}=(.+)$`, 'm'));\n if (match) return match[1].trim().replace(/[\"']/g, '');\n }\n }\n return undefined;\n}\n\n/**\n * Write a value to .env.local in the current directory.\n */\nfunction writeEnvValue(key: string, value: string, envFile: string = '.env.local'): void {\n const envPath = path.join(process.cwd(), envFile);\n let content = '';\n if (fs.existsSync(envPath)) {\n content = fs.readFileSync(envPath, 'utf-8');\n }\n\n const lines = content.split('\\n');\n const idx = lines.findIndex((l) => l.startsWith(`${key}=`));\n if (idx >= 0) {\n lines[idx] = `${key}=${value}`;\n } else {\n lines.push(`${key}=${value}`);\n }\n\n fs.writeFileSync(envPath, lines.join('\\n'));\n}\n\nexport function registerChannelSlackCommand(program: Command) {\n const channel = program\n .command('channel:slack')\n .description('Manage the Slack messaging channel');\n\n // ─── Start ─────────────────────────────────────────────────────────\n channel\n .command('start')\n .description('Start the Slack bot and begin routing messages to an agent')\n .option('-a, --agent <id>', 'Agent ID to route messages to')\n .option('--bot-token <token>', 'Slack bot token (xoxb-...) (overrides .env)')\n .option('--app-token <token>', 'Slack app-level token (xapp-...) for socket mode (overrides .env)')\n .option('--signing-secret <secret>', 'Slack signing secret (overrides .env)')\n .option('--socket-mode', 'Enable socket mode (default: true)', true)\n .option('--log-level <level>', 'Log level: debug, info, warn, error', 'info')\n .action(async (opts) => {\n header('Slack Channel');\n\n // Resolve bot token\n const botToken = opts.botToken || readEnvValue('SLACK_BOT_TOKEN') || process.env.SLACK_BOT_TOKEN;\n if (!botToken) {\n error('Slack Bot Token not found.');\n info('Set it with: agentforge channel:slack configure');\n info('Or pass it with: --bot-token <token>');\n info('Or set SLACK_BOT_TOKEN in your .env.local file');\n process.exit(1);\n }\n\n // Resolve app token (required for socket mode)\n const appToken = opts.appToken || readEnvValue('SLACK_APP_TOKEN') || process.env.SLACK_APP_TOKEN;\n if (opts.socketMode && !appToken) {\n error('Slack App Token not found (required for socket mode).');\n info('Set it with: agentforge channel:slack configure');\n info('Or pass it with: --app-token <token>');\n info('Or set SLACK_APP_TOKEN in your .env.local file');\n info('Or disable socket mode with: --no-socket-mode');\n process.exit(1);\n }\n\n // Resolve signing secret\n const signingSecret = opts.signingSecret || readEnvValue('SLACK_SIGNING_SECRET') || process.env.SLACK_SIGNING_SECRET;\n if (!signingSecret) {\n error('Slack Signing Secret not found.');\n info('Set it with: agentforge channel:slack configure');\n info('Or pass it with: --signing-secret <secret>');\n info('Or set SLACK_SIGNING_SECRET in your .env.local file');\n process.exit(1);\n }\n\n // Resolve Convex URL\n const convexUrl = readEnvValue('CONVEX_URL') || process.env.CONVEX_URL;\n if (!convexUrl) {\n error('CONVEX_URL not found. Run `npx convex dev` first.');\n process.exit(1);\n }\n\n // Resolve agent ID\n let agentId = opts.agent;\n if (!agentId) {\n agentId = readEnvValue('AGENTFORGE_AGENT_ID') || process.env.AGENTFORGE_AGENT_ID;\n }\n\n if (!agentId) {\n // List agents and let user pick\n info('No agent specified. Fetching available agents...');\n const client = await createClient();\n const agents = await safeCall(\n () => client.query('agents:list' as any, {}),\n 'Failed to list agents'\n );\n\n if (!agents || (agents as any[]).length === 0) {\n error('No agents found. Create one first: agentforge agents create');\n process.exit(1);\n }\n\n console.log();\n (agents as any[]).forEach((a: any, i: number) => {\n console.log(\n ` ${colors.cyan}${i + 1}.${colors.reset} ${a.name} ${colors.dim}(${a.id})${colors.reset} — ${a.model}`\n );\n });\n console.log();\n\n const choice = await prompt('Select agent (number or ID): ');\n const idx = parseInt(choice) - 1;\n agentId = idx >= 0 && idx < (agents as any[]).length\n ? (agents as any[])[idx].id\n : choice;\n }\n\n // Display configuration\n info(`Agent: ${agentId}`);\n info(`Convex: ${convexUrl}`);\n info(`Mode: ${opts.socketMode ? 'Socket Mode' : 'Events API'}`);\n info(`Log: ${opts.logLevel}`);\n console.log();\n\n // Dynamically import the SlackChannel from channels-slack\n let startSlackChannel: any;\n try {\n const slackPkg = '@agentforge-ai/channels-slack';\n const mod = await import(/* @vite-ignore */ slackPkg);\n startSlackChannel = mod.startSlackChannel;\n } catch (importError: any) {\n // Fallback: use the built-in minimal runner\n error('Could not import @agentforge-ai/channels-slack. Using built-in Slack runner.');\n dim(` Error: ${importError.message}`);\n console.log();\n\n await runMinimalSlackBot({\n botToken,\n appToken: appToken || '',\n signingSecret,\n agentId,\n convexUrl,\n socketMode: opts.socketMode,\n logLevel: opts.logLevel,\n });\n return;\n }\n\n // Start the Slack channel\n try {\n await startSlackChannel({\n botToken,\n appToken,\n signingSecret,\n agentId,\n convexUrl,\n socketMode: opts.socketMode,\n logLevel: opts.logLevel,\n });\n\n success('Slack bot is running!');\n dim(' Press Ctrl+C to stop.');\n\n // Keep the process alive\n await new Promise(() => {});\n } catch (startError: any) {\n error(`Failed to start Slack bot: ${startError.message}`);\n process.exit(1);\n }\n });\n\n // ─── Configure ─────────────────────────────────────────────────────\n channel\n .command('configure')\n .description('Configure the Slack bot credentials and settings')\n .action(async () => {\n header('Configure Slack Channel');\n\n console.log();\n info('To set up a Slack app:');\n dim(' 1. Go to https://api.slack.com/apps and create a new app');\n dim(' 2. Enable Socket Mode under Settings > Socket Mode');\n dim(' 3. Add bot scopes: chat:write, im:history, im:read, channels:history');\n dim(' 4. Install the app to your workspace');\n dim(' 5. Copy the Bot Token, App-Level Token, and Signing Secret');\n console.log();\n\n // Bot Token\n const currentBotToken = readEnvValue('SLACK_BOT_TOKEN');\n if (currentBotToken) {\n const masked = currentBotToken.slice(0, 8) + '****' + currentBotToken.slice(-4);\n info(`Current bot token: ${masked}`);\n }\n\n const botToken = await prompt('Slack Bot Token (xoxb-...): ');\n if (!botToken) {\n error('Bot token is required.');\n process.exit(1);\n }\n\n if (!botToken.startsWith('xoxb-')) {\n warn('Bot token should start with \"xoxb-\". Please verify this is correct.');\n }\n\n // Validate the bot token via auth.test\n info('Validating bot token...');\n try {\n const response = await fetch('https://slack.com/api/auth.test', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${botToken}`,\n 'Content-Type': 'application/json',\n },\n });\n const data = await response.json() as {\n ok: boolean;\n team?: string;\n user?: string;\n bot_id?: string;\n error?: string;\n };\n if (!data.ok) {\n warn(`Token validation warning: ${data.error}`);\n info('Saving token anyway. You can validate later with: agentforge channel:slack status');\n } else {\n success(`Bot verified: @${data.user} in workspace \"${data.team}\"`);\n }\n } catch (fetchError: any) {\n warn(`Could not validate token (network error): ${fetchError.message}`);\n info('Saving token anyway.');\n }\n\n writeEnvValue('SLACK_BOT_TOKEN', botToken);\n success('Bot token saved to .env.local');\n\n // App Token\n console.log();\n const currentAppToken = readEnvValue('SLACK_APP_TOKEN');\n if (currentAppToken) {\n const masked = currentAppToken.slice(0, 8) + '****' + currentAppToken.slice(-4);\n info(`Current app token: ${masked}`);\n }\n\n const appToken = await prompt('Slack App-Level Token (xapp-..., for socket mode): ');\n if (!appToken) {\n warn('App-level token not provided. Socket mode will not be available.');\n } else {\n if (!appToken.startsWith('xapp-')) {\n warn('App token should start with \"xapp-\". Please verify this is correct.');\n }\n writeEnvValue('SLACK_APP_TOKEN', appToken);\n success('App token saved to .env.local');\n }\n\n // Signing Secret\n console.log();\n const currentSigningSecret = readEnvValue('SLACK_SIGNING_SECRET');\n if (currentSigningSecret) {\n info(`Current signing secret: ${currentSigningSecret.slice(0, 6)}****`);\n }\n\n const signingSecret = await prompt('Slack Signing Secret: ');\n if (!signingSecret) {\n error('Signing secret is required.');\n process.exit(1);\n }\n\n if (signingSecret.length < 20) {\n warn('Signing secret looks too short. Please verify this is correct.');\n }\n\n writeEnvValue('SLACK_SIGNING_SECRET', signingSecret);\n success('Signing secret saved to .env.local');\n\n // Default agent\n console.log();\n const defaultAgent = await prompt('Default agent ID (optional, press Enter to skip): ');\n if (defaultAgent) {\n writeEnvValue('AGENTFORGE_AGENT_ID', defaultAgent);\n success(`Default agent set to: ${defaultAgent}`);\n }\n\n console.log();\n success('Configuration complete!');\n info('Start the bot with: agentforge channel:slack start');\n });\n\n // ─── Status ────────────────────────────────────────────────────────\n channel\n .command('status')\n .description('Check the Slack bot configuration and connectivity')\n .action(async () => {\n header('Slack Channel Status');\n\n const botToken = readEnvValue('SLACK_BOT_TOKEN');\n const appToken = readEnvValue('SLACK_APP_TOKEN');\n const signingSecret = readEnvValue('SLACK_SIGNING_SECRET');\n const agentId = readEnvValue('AGENTFORGE_AGENT_ID');\n const convexUrl = readEnvValue('CONVEX_URL');\n\n const statusData: Record<string, string> = {\n 'Bot Token': botToken ? `${botToken.slice(0, 8)}****${botToken.slice(-4)}` : `${colors.red}Not configured${colors.reset}`,\n 'App Token': appToken ? `${appToken.slice(0, 8)}****${appToken.slice(-4)}` : `${colors.dim}Not set${colors.reset}`,\n 'Signing Secret': signingSecret ? `${signingSecret.slice(0, 6)}****` : `${colors.red}Not configured${colors.reset}`,\n 'Default Agent': agentId || `${colors.dim}Not set${colors.reset}`,\n 'Convex URL': convexUrl || `${colors.red}Not configured${colors.reset}`,\n };\n\n details(statusData);\n\n // Validate bot token if present\n if (botToken) {\n info('Checking Slack API connectivity...');\n try {\n const response = await fetch('https://slack.com/api/auth.test', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${botToken}`,\n 'Content-Type': 'application/json',\n },\n });\n const data = await response.json() as {\n ok: boolean;\n team?: string;\n user?: string;\n team_id?: string;\n bot_id?: string;\n error?: string;\n };\n if (data.ok) {\n success(`Slack API connected: @${data.user} in workspace \"${data.team}\" (${data.team_id})`);\n } else {\n error(`Slack API error: ${data.error}`);\n }\n } catch {\n warn('Could not reach Slack API (network error).');\n }\n }\n\n // Check Convex connectivity\n if (convexUrl) {\n info('Checking Convex connectivity...');\n try {\n const client = await createClient();\n const agents = await client.query('agents:list' as any, {});\n success(`Convex connected. ${(agents as any[]).length} agents available.`);\n } catch {\n warn('Could not reach Convex deployment.');\n }\n }\n });\n}\n\n// =====================================================\n// Minimal Built-in Slack Bot Runner\n// =====================================================\n\n/**\n * A minimal Slack bot runner that works without the @agentforge-ai/channels-slack\n * package. Uses the Slack Web API and Convex HTTP API directly.\n *\n * This is a fallback for when the channels-slack package isn't available\n * (e.g., in a fresh project before building).\n *\n * Uses Socket Mode via the Slack Events API if an app token is provided,\n * otherwise falls back to a basic HTTP server for the Events API.\n */\nexport async function runMinimalSlackBot(config: {\n botToken: string;\n appToken: string;\n signingSecret: string;\n agentId: string;\n convexUrl: string;\n socketMode?: boolean;\n logLevel?: string;\n}): Promise<void> {\n const { botToken, appToken, signingSecret, agentId, convexUrl } = config;\n const convexBase = convexUrl.replace(/\\/$/, '');\n const threadMap = new Map<string, string>();\n\n // Verify bot token\n info('Verifying Slack bot token...');\n try {\n const res = await fetch('https://slack.com/api/auth.test', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${botToken}`,\n 'Content-Type': 'application/json',\n },\n });\n const data = await res.json() as { ok: boolean; team?: string; user?: string; error?: string };\n if (!data.ok) {\n error(`Slack auth error: ${data.error}`);\n process.exit(1);\n }\n success(`Slack bot connected: @${data.user} in \"${data.team}\"`);\n } catch (fetchError: any) {\n warn(`Could not verify bot token: ${fetchError.message}`);\n info('Continuing anyway...');\n }\n\n // Convex HTTP helpers\n async function convexMutation(fn: string, args: Record<string, unknown>): Promise<unknown> {\n const res = await fetch(`${convexBase}/api/mutation`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: fn, args }),\n });\n const data = await res.json() as { value?: unknown; status?: string; errorMessage?: string };\n if (data.status === 'error') throw new Error(data.errorMessage);\n return data.value;\n }\n\n async function convexAction(fn: string, args: Record<string, unknown>): Promise<unknown> {\n const res = await fetch(`${convexBase}/api/action`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: fn, args }),\n });\n const data = await res.json() as { value?: unknown; status?: string; errorMessage?: string };\n if (data.status === 'error') throw new Error(data.errorMessage);\n return data.value;\n }\n\n async function sendSlackMessage(channel: string, text: string, threadTs?: string): Promise<void> {\n const body: Record<string, unknown> = { channel, text };\n if (threadTs) body.thread_ts = threadTs;\n\n await fetch('https://slack.com/api/chat.postMessage', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${botToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n });\n }\n\n async function getOrCreateThread(channelThreadKey: string, senderName?: string): Promise<string> {\n const cached = threadMap.get(channelThreadKey);\n if (cached) return cached;\n\n const threadId = await convexMutation('chat:createThread', {\n agentId,\n name: senderName ? `Slack: ${senderName}` : `Slack ${channelThreadKey}`,\n userId: `slack:${channelThreadKey}`,\n }) as string;\n\n threadMap.set(channelThreadKey, threadId);\n return threadId;\n }\n\n async function handleSlackMessage(event: any): Promise<void> {\n if (event.bot_id || event.subtype) return;\n\n const channelId = event.channel;\n const userId = event.user;\n const text = (event.text || '').trim();\n const threadTs = event.thread_ts || event.ts;\n\n if (!text) return;\n\n const threadKey = `${channelId}:${userId}`;\n console.log(`[Slack:${channelId}] ${text}`);\n\n try {\n const convexThreadId = await getOrCreateThread(threadKey, `slack:${userId}`);\n const result = await convexAction('chat:sendMessage', {\n agentId,\n threadId: convexThreadId,\n content: text,\n userId: `slack:${userId}`,\n }) as { response: string };\n\n if (result?.response) {\n const response = result.response;\n // Split long messages at 4000 chars (Slack's limit)\n if (response.length <= 4000) {\n await sendSlackMessage(channelId, response, threadTs);\n } else {\n const chunks = response.match(/.{1,4000}/gs) || [];\n for (const chunk of chunks) {\n await sendSlackMessage(channelId, chunk, threadTs);\n }\n }\n console.log(`[Agent] ${response.substring(0, 100)}${response.length > 100 ? '...' : ''}`);\n } else {\n await sendSlackMessage(channelId, \"I couldn't generate a response. Please try again.\", threadTs);\n }\n } catch (routeError: any) {\n console.error(`Error: ${routeError.message}`);\n await sendSlackMessage(channelId, 'Sorry, I encountered an error. Please try again.', threadTs);\n }\n }\n\n // If app token is available, use Socket Mode\n if (appToken && config.socketMode !== false) {\n info('Starting in Socket Mode...');\n\n try {\n // Attempt to connect via Slack Socket Mode WebSocket\n const wsUrlRes = await fetch('https://slack.com/api/apps.connections.open', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${appToken}`,\n 'Content-Type': 'application/json',\n },\n });\n const wsData = await wsUrlRes.json() as { ok: boolean; url?: string; error?: string };\n\n if (!wsData.ok || !wsData.url) {\n throw new Error(`Could not open WebSocket connection: ${wsData.error}`);\n }\n\n const { default: WebSocket } = await import('ws' as any);\n const ws = new WebSocket(wsData.url);\n\n ws.on('open', () => {\n success('Socket Mode connected!');\n dim(' Listening for messages. Press Ctrl+C to stop.');\n console.log();\n });\n\n ws.on('message', async (data: Buffer) => {\n try {\n const payload = JSON.parse(data.toString());\n\n // Acknowledge the event\n if (payload.envelope_id) {\n ws.send(JSON.stringify({ envelope_id: payload.envelope_id }));\n }\n\n // Handle events\n if (payload.type === 'events_api' && payload.payload?.event) {\n const event = payload.payload.event;\n if (event.type === 'message') {\n await handleSlackMessage(event);\n }\n }\n\n // Handle slash commands\n if (payload.type === 'slash_commands' && payload.payload) {\n const slashPayload = payload.payload;\n const command = slashPayload.command;\n const channelId = slashPayload.channel_id;\n const userId = slashPayload.user_id;\n const text = slashPayload.text || '';\n\n if (command === '/start' || command === '/new') {\n const key = `${channelId}:${userId}`;\n threadMap.delete(key);\n await sendSlackMessage(channelId, 'New conversation started! Send me a message.');\n } else if (command === '/help') {\n await sendSlackMessage(channelId, 'AgentForge Slack Bot\\n\\nJust send me a message and I\\'ll respond using AI.\\n\\nCommands:\\n/start — Reset and start fresh\\n/new — Start a fresh conversation\\n/help — Show this help\\n/ask <question> — Ask a question');\n } else if (command === '/ask') {\n await handleSlackMessage({ channel: channelId, user: userId, text, ts: Date.now().toString() });\n }\n }\n } catch (parseError: any) {\n console.error(`Error processing message: ${parseError.message}`);\n }\n });\n\n ws.on('close', (code: number) => {\n warn(`Socket Mode disconnected (code: ${code}). Reconnecting in 5s...`);\n setTimeout(() => runMinimalSlackBot(config), 5000);\n });\n\n ws.on('error', (err: Error) => {\n console.error(`WebSocket error: ${err.message}`);\n });\n\n // Graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\nStopping...');\n ws.close();\n process.exit(0);\n });\n\n // Keep alive\n await new Promise(() => {});\n } catch (socketError: any) {\n warn(`Socket Mode failed: ${socketError.message}`);\n info('Falling back to HTTP Events API server...');\n }\n }\n\n // Fallback: HTTP server for Events API\n info('Starting HTTP server for Events API...');\n const port = 3002;\n const path_ = '/slack/events';\n\n const http = await import('node:http');\n const { createHmac, timingSafeEqual } = await import('node:crypto');\n\n function verifySlackSignature(body: string, timestamp: string, signature: string): boolean {\n const sigBaseString = `v0:${timestamp}:${body}`;\n const hmac = createHmac('sha256', signingSecret);\n hmac.update(sigBaseString);\n const computedSig = `v0=${hmac.digest('hex')}`;\n try {\n return timingSafeEqual(Buffer.from(computedSig), Buffer.from(signature));\n } catch {\n return false;\n }\n }\n\n const server = http.createServer(async (req, res) => {\n const url = new URL(req.url || '/', `http://localhost:${port}`);\n\n if (url.pathname !== path_) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n if (req.method !== 'POST') {\n res.writeHead(405);\n res.end('Method Not Allowed');\n return;\n }\n\n try {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk as Buffer);\n }\n const rawBody = Buffer.concat(chunks).toString();\n\n // Verify Slack signature\n const timestamp = req.headers['x-slack-request-timestamp'] as string;\n const signature = req.headers['x-slack-signature'] as string;\n\n if (timestamp && signature && signingSecret) {\n const now = Math.floor(Date.now() / 1000);\n if (Math.abs(now - parseInt(timestamp)) > 300) {\n res.writeHead(403);\n res.end('Request too old');\n return;\n }\n\n if (!verifySlackSignature(rawBody, timestamp, signature)) {\n res.writeHead(403);\n res.end('Invalid signature');\n return;\n }\n }\n\n const body = JSON.parse(rawBody);\n\n // Handle URL verification challenge\n if (body.type === 'url_verification') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ challenge: body.challenge }));\n return;\n }\n\n // Acknowledge immediately\n res.writeHead(200);\n res.end('OK');\n\n // Handle message events\n if (body.type === 'event_callback' && body.event?.type === 'message') {\n await handleSlackMessage(body.event);\n }\n } catch (parseError: any) {\n console.error(`Parse error: ${parseError.message}`);\n if (!res.headersSent) {\n res.writeHead(400);\n res.end('Bad Request');\n }\n }\n });\n\n // Graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\nStopping...');\n server.close();\n process.exit(0);\n });\n\n server.listen(port, () => {\n success(`Events API server listening on port ${port}`);\n info(`Events API URL: http://localhost:${port}${path_}`);\n console.log();\n info('Next steps:');\n dim(' 1. Expose this URL publicly (e.g., ngrok http ' + port + ')');\n dim(' 2. Configure the Events API URL in your Slack app settings');\n dim(' 3. Subscribe to the \"message.im\" and \"message.channels\" events');\n dim(' Press Ctrl+C to stop.');\n });\n\n // Keep alive\n await new Promise(() => {});\n}\n"],"mappings":"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","names":["pkg","path","fs","path","execSync","fs","fs","path","error","path","error","fs","path","resolve","execSync","fs","path","error","resolve","program","readline","program","a","program","fs","path","readline","execSync","prompt","program","skills","entry","fs","path","os","path","os","parseSkillMd","fs","getConvexUrl","program","readline","prompt","program","readline","prompt","program","fs","path","program","readline","prompt","program","projects","fs","path","readline","prompt","program","readline","prompt","resolve","program","safeCall","formatDate","promptSecret","resolve","readline","program","spawn","path","fs","readline","program","resolve","chalk","ora","program","ora","chalk","fs","path","readline","prompt","program","channel","fs","path","readline","prompt","readEnvValue","writeEnvValue","program","channel","chunks","fs","path","readline","prompt","readEnvValue","writeEnvValue","program","fileURLToPath","__filename","__dirname"]}
|