{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG","sourcesContent":["#!/usr/bin/env node\n/**\n * Piagnet CLI\n *\n * Commands:\n * - piagnet gateway start    Start the gateway server\n * - piagnet gateway stop     Stop the gateway server\n * - piagnet gateway status   Check gateway status\n * - piagnet config init      Initialize configuration\n * - piagnet config show      Show current configuration\n * - piagnet agent create     Create a new agent\n * - piagnet agent list       List all agents\n * - piagnet channel add      Add a channel\n * - piagnet channel list     List all channels\n */\n\nimport * as fs from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { ConfigManager } from \"./config/manager.js\";\nimport { defaultConfig } from \"./config/schema.js\";\nimport { Gateway } from \"./gateway/server.js\";\nimport { SessionManager } from \"./gateway/sessions.js\";\n\nconst VERSION = \"0.51.7\";\n\n/** CLI command handler */\nasync function main(): Promise<void> {\n\tconst args = process.argv.slice(2);\n\tconst command = args[0];\n\tconst subcommand = args[1];\n\n\tif (!command || command === \"--help\" || command === \"-h\") {\n\t\tshowHelp();\n\t\tprocess.exit(0);\n\t}\n\n\tif (command === \"--version\" || command === \"-v\") {\n\t\tconsole.log(`piagnet v${VERSION}`);\n\t\tprocess.exit(0);\n\t}\n\n\ttry {\n\t\tswitch (command) {\n\t\t\tcase \"gateway\":\n\t\t\t\tawait handleGateway(subcommand, args.slice(2));\n\t\t\t\tbreak;\n\n\t\t\tcase \"config\":\n\t\t\t\tawait handleConfig(subcommand, args.slice(2));\n\t\t\t\tbreak;\n\n\t\t\tcase \"agent\":\n\t\t\t\tawait handleAgent(subcommand, args.slice(2));\n\t\t\t\tbreak;\n\n\t\t\tcase \"channel\":\n\t\t\t\tawait handleChannel(subcommand, args.slice(2));\n\t\t\t\tbreak;\n\n\t\t\tcase \"doctor\":\n\t\t\t\tawait runDoctor();\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tconsole.error(`Unknown command: ${command}`);\n\t\t\t\tshowHelp();\n\t\t\t\tprocess.exit(1);\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(\"Error:\", error instanceof Error ? error.message : error);\n\t\tprocess.exit(1);\n\t}\n}\n\n/** Gateway commands */\nasync function handleGateway(subcommand: string | undefined, args: string[]): Promise<void> {\n\tconst configManager = await ConfigManager.create();\n\tawait configManager.load();\n\n\tswitch (subcommand) {\n\t\tcase \"start\": {\n\t\t\tconst sessionManager = new SessionManager({\n\t\t\t\tsessionDir: configManager.getGatewayConfig().sessionDir,\n\t\t\t});\n\t\t\tawait sessionManager.initialize();\n\n\t\t\tconst gateway = new Gateway({ configManager, sessionManager });\n\t\t\tawait gateway.start();\n\n\t\t\tconsole.log(`Gateway started on port ${configManager.getGatewayConfig().port}`);\n\t\t\tconsole.log(\"Press Ctrl+C to stop\");\n\n\t\t\t// Keep running\n\t\t\tprocess.on(\"SIGINT\", async () => {\n\t\t\t\tconsole.log(\"\\nShutting down...\");\n\t\t\t\tawait gateway.stop();\n\t\t\t\tprocess.exit(0);\n\t\t\t});\n\n\t\t\t// Keep alive\n\t\t\tawait new Promise(() => {});\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"stop\":\n\t\t\t// For now, just show status\n\t\t\tconsole.log(\"Gateway stop not implemented (use Ctrl+C or kill process)\");\n\t\t\tbreak;\n\n\t\tcase \"status\": {\n\t\t\t// Check if port is in use\n\t\t\tconst port = configManager.getGatewayConfig().port;\n\t\t\tconst isRunning = await checkPortInUse(port);\n\t\t\tconsole.log(`Gateway status: ${isRunning ? \"running\" : \"stopped\"}`);\n\t\t\tconsole.log(`Port: ${port}`);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"restart\":\n\t\t\tconsole.log(\"Gateway restart not implemented\");\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tconsole.log(\"Usage: piagnet gateway <start|stop|status|restart>\");\n\t}\n}\n\n/** Config commands */\nasync function handleConfig(subcommand: string | undefined, args: string[]): Promise<void> {\n\tconst configManager = new ConfigManager();\n\n\tswitch (subcommand) {\n\t\tcase \"init\": {\n\t\t\tconst created = await configManager.createInitialConfig();\n\t\t\tif (created) {\n\t\t\t\tconsole.log(`Created configuration at ${configManager.getConfigPath()}`);\n\t\t\t\tconsole.log(\"Edit this file to configure your agents and channels.\");\n\t\t\t} else {\n\t\t\t\tconsole.log(`Configuration already exists at ${configManager.getConfigPath()}`);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"show\": {\n\t\t\tawait configManager.load();\n\t\t\tconst config = configManager.getConfig();\n\t\t\tconsole.log(JSON.stringify(config, null, 2));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"validate\": {\n\t\t\tawait configManager.load();\n\t\t\tconst result = configManager.validate();\n\t\t\tif (result.valid) {\n\t\t\t\tconsole.log(\"Configuration is valid\");\n\t\t\t} else {\n\t\t\t\tconsole.error(\"Configuration errors:\");\n\t\t\t\tfor (const error of result.errors) {\n\t\t\t\t\tconsole.error(`  - ${error}`);\n\t\t\t\t}\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"path\": {\n\t\t\tconsole.log(configManager.getConfigPath());\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tconsole.log(\"Usage: piagnet config <init|show|validate|path>\");\n\t}\n}\n\n/** Agent commands */\nasync function handleAgent(subcommand: string | undefined, args: string[]): Promise<void> {\n\tconst configManager = await ConfigManager.create();\n\tawait configManager.load();\n\n\tswitch (subcommand) {\n\t\tcase \"list\": {\n\t\t\tconst agents = configManager.getConfig().agents;\n\t\t\tif (agents.length === 0) {\n\t\t\t\tconsole.log(\"No agents configured\");\n\t\t\t} else {\n\t\t\t\tconsole.log(\"Agents:\");\n\t\t\t\tfor (const agent of agents) {\n\t\t\t\t\tconst defaultMarker = configManager.getConfig().defaults.agent === agent.id ? \" (default)\" : \"\";\n\t\t\t\t\tconsole.log(`  - ${agent.id}: ${agent.name}${defaultMarker}`);\n\t\t\t\t\tconsole.log(`      Model: ${agent.model.provider}/${agent.model.model}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"create\": {\n\t\t\tconst id = args[0];\n\t\t\tif (!id) {\n\t\t\t\tconsole.error(\"Usage: piagnet agent create <id>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst existing = configManager.getAgent(id);\n\t\t\tif (existing) {\n\t\t\t\tconsole.error(`Agent ${id} already exists`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconfigManager.upsertAgent({\n\t\t\t\tid,\n\t\t\t\tname: id,\n\t\t\t\tmodel: {\n\t\t\t\t\tprovider: \"anthropic\",\n\t\t\t\t\tmodel: \"claude-3-5-sonnet-20241022\",\n\t\t\t\t},\n\t\t\t\tskills: [],\n\t\t\t\tsession: {\n\t\t\t\t\thistoryLimit: 100,\n\t\t\t\t\tidleMinutes: 60,\n\t\t\t\t\tdailyResetHour: 4,\n\t\t\t\t\tcompression: \"summary\",\n\t\t\t\t\tqueuing: \"sequential\",\n\t\t\t\t},\n\t\t\t\tbootstrap: {\n\t\t\t\t\tfiles: [\"AGENTS.md\", \"SOUL.md\", \"USER.md\", \"IDENTITY.md\", \"TOOLS.md\"],\n\t\t\t\t\tmaxChars: 20000,\n\t\t\t\t},\n\t\t\t\tmemory: {\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tfiles: [\"MEMORY.md\"],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait configManager.save();\n\t\t\tconsole.log(`Created agent: ${id}`);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"delete\": {\n\t\t\tconst id = args[0];\n\t\t\tif (!id) {\n\t\t\t\tconsole.error(\"Usage: piagnet agent delete <id>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst removed = configManager.removeAgent(id);\n\t\t\tif (removed) {\n\t\t\t\tawait configManager.save();\n\t\t\t\tconsole.log(`Deleted agent: ${id}`);\n\t\t\t} else {\n\t\t\t\tconsole.error(`Agent ${id} not found`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tconsole.log(\"Usage: piagnet agent <list|create|delete>\");\n\t}\n}\n\n/** Channel commands */\nasync function handleChannel(subcommand: string | undefined, args: string[]): Promise<void> {\n\tconst configManager = await ConfigManager.create();\n\tawait configManager.load();\n\n\tswitch (subcommand) {\n\t\tcase \"list\": {\n\t\t\tconst channels = configManager.getConfig().channels;\n\t\t\tif (channels.length === 0) {\n\t\t\t\tconsole.log(\"No channels configured\");\n\t\t\t} else {\n\t\t\t\tconsole.log(\"Channels:\");\n\t\t\t\tfor (const channel of channels) {\n\t\t\t\t\tconst status = channel.enabled ? \"enabled\" : \"disabled\";\n\t\t\t\t\tconsole.log(`  - ${channel.type}: ${channel.name} (${status})`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"add\": {\n\t\t\tconst type = args[0];\n\t\t\tif (!type) {\n\t\t\t\tconsole.error(\"Usage: piagnet channel add <type>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst existing = configManager.getChannel(type);\n\t\t\tif (existing) {\n\t\t\t\tconsole.error(`Channel ${type} already exists`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconfigManager.upsertChannel({\n\t\t\t\ttype,\n\t\t\t\tname: type,\n\t\t\t\tenabled: false,\n\t\t\t\tconfig: {},\n\t\t\t\taccess: {\n\t\t\t\t\tdmPolicy: \"pairing\",\n\t\t\t\t\tgroupPolicy: \"mention\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait configManager.save();\n\t\t\tconsole.log(`Added channel: ${type}`);\n\t\t\tconsole.log(`Edit ${configManager.getConfigPath()} to configure the channel.`);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"remove\": {\n\t\t\tconst type = args[0];\n\t\t\tif (!type) {\n\t\t\t\tconsole.error(\"Usage: piagnet channel remove <type>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst removed = configManager.removeChannel(type);\n\t\t\tif (removed) {\n\t\t\t\tawait configManager.save();\n\t\t\t\tconsole.log(`Removed channel: ${type}`);\n\t\t\t} else {\n\t\t\t\tconsole.error(`Channel ${type} not found`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tconsole.log(\"Usage: piagnet channel <list|add|remove>\");\n\t}\n}\n\n/** Doctor - diagnostic checks */\nasync function runDoctor(): Promise<void> {\n\tconsole.log(\"Running diagnostic checks...\\n\");\n\n\tlet issues = 0;\n\n\t// Check Node.js version\n\tconst nodeVersion = process.version;\n\tconst majorVersion = parseInt(nodeVersion.slice(1).split(\".\")[0]);\n\tif (majorVersion < 20) {\n\t\tconsole.log(\"❌ Node.js version should be >= 20\");\n\t\tconsole.log(`   Current: ${nodeVersion}`);\n\t\tissues++;\n\t} else {\n\t\tconsole.log(`✓ Node.js version: ${nodeVersion}`);\n\t}\n\n\t// Check configuration\n\tconst configManager = new ConfigManager();\n\ttry {\n\t\tawait configManager.load();\n\t\tconst result = configManager.validate();\n\t\tif (result.valid) {\n\t\t\tconsole.log(\"✓ Configuration is valid\");\n\t\t} else {\n\t\t\tconsole.log(\"❌ Configuration has errors:\");\n\t\t\tfor (const error of result.errors) {\n\t\t\t\tconsole.log(`   - ${error}`);\n\t\t\t}\n\t\t\tissues++;\n\t\t}\n\t} catch (error) {\n\t\tconsole.log(\"⚠ Configuration not found (run 'piagnet config init')\");\n\t}\n\n\t// Check session directory\n\tconst sessionDir = configManager.getGatewayConfig().sessionDir;\n\ttry {\n\t\tawait fs.access(sessionDir);\n\t\tconsole.log(`✓ Session directory exists: ${sessionDir}`);\n\t} catch {\n\t\tconsole.log(`⚠ Session directory will be created: ${sessionDir}`);\n\t}\n\n\tconsole.log(\"\\n\" + (issues === 0 ? \"All checks passed!\" : `${issues} issue(s) found`));\n}\n\n/** Check if port is in use */\nasync function checkPortInUse(port: number): Promise<boolean> {\n\t// This is a simple check - in a real implementation,\n\t// we might want to check if Piagnet specifically is running\n\treturn false;\n}\n\n/** Show help */\nfunction showHelp(): void {\n\tconsole.log(`\npiagnet v${VERSION} - Multi-channel AI Gateway\n\nUsage: piagnet <command> [options]\n\nCommands:\n  gateway <start|stop|status|restart>  Manage gateway server\n  config  <init|show|validate|path>    Configuration management\n  agent   <list|create|delete>        Agent management\n  channel <list|add|remove>           Channel management\n  doctor                              Run diagnostic checks\n\nOptions:\n  -h, --help     Show help\n  -v, --version  Show version\n\nExamples:\n  piagnet config init\n  piagnet gateway start\n  piagnet agent create my-assistant\n  piagnet channel add telegram\n`);\n}\n\n// Run CLI\nmain();\n"]}