@operor/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -0
- package/dist/config-Bn2pbORi.js +34 -0
- package/dist/config-Bn2pbORi.js.map +1 -0
- package/dist/converse-C_PB7-JH.js +142 -0
- package/dist/converse-C_PB7-JH.js.map +1 -0
- package/dist/doctor-98gPl743.js +122 -0
- package/dist/doctor-98gPl743.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2268 -0
- package/dist/index.js.map +1 -0
- package/dist/llm-override-BIQl0V6H.js +445 -0
- package/dist/llm-override-BIQl0V6H.js.map +1 -0
- package/dist/reset-DT8SBgFS.js +87 -0
- package/dist/reset-DT8SBgFS.js.map +1 -0
- package/dist/simulate-BKv62GJc.js +144 -0
- package/dist/simulate-BKv62GJc.js.map +1 -0
- package/dist/status-D6LIZvQa.js +82 -0
- package/dist/status-D6LIZvQa.js.map +1 -0
- package/dist/test-DYjkxbtK.js +177 -0
- package/dist/test-DYjkxbtK.js.map +1 -0
- package/dist/test-suite-D8H_5uKs.js +209 -0
- package/dist/test-suite-D8H_5uKs.js.map +1 -0
- package/dist/utils-BuV4q7f6.js +11 -0
- package/dist/utils-BuV4q7f6.js.map +1 -0
- package/dist/vibe-Bl_js3Jo.js +395 -0
- package/dist/vibe-Bl_js3Jo.js.map +1 -0
- package/package.json +43 -0
- package/src/commands/analytics.ts +408 -0
- package/src/commands/chat.ts +310 -0
- package/src/commands/config.ts +34 -0
- package/src/commands/converse.ts +182 -0
- package/src/commands/doctor.ts +154 -0
- package/src/commands/history.ts +60 -0
- package/src/commands/init.ts +163 -0
- package/src/commands/kb.ts +429 -0
- package/src/commands/llm-override.ts +480 -0
- package/src/commands/reset.ts +72 -0
- package/src/commands/simulate.ts +187 -0
- package/src/commands/status.ts +112 -0
- package/src/commands/test-suite.ts +247 -0
- package/src/commands/test.ts +177 -0
- package/src/commands/vibe.ts +478 -0
- package/src/config.ts +127 -0
- package/src/index.ts +190 -0
- package/src/log-timestamps.ts +26 -0
- package/src/setup.ts +712 -0
- package/src/start.ts +573 -0
- package/src/utils.ts +6 -0
- package/templates/agents/_defaults/SOUL.md +20 -0
- package/templates/agents/_defaults/USER.md +16 -0
- package/templates/agents/customer-support/IDENTITY.md +6 -0
- package/templates/agents/customer-support/INSTRUCTIONS.md +79 -0
- package/templates/agents/customer-support/SOUL.md +26 -0
- package/templates/agents/faq-bot/IDENTITY.md +6 -0
- package/templates/agents/faq-bot/INSTRUCTIONS.md +53 -0
- package/templates/agents/faq-bot/SOUL.md +19 -0
- package/templates/agents/sales/IDENTITY.md +6 -0
- package/templates/agents/sales/INSTRUCTIONS.md +67 -0
- package/templates/agents/sales/SOUL.md +20 -0
- package/tsconfig.json +9 -0
- package/tsdown.config.ts +13 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["resolvePath"],"sources":["../src/log-timestamps.ts","../src/config.ts","../src/setup.ts","../src/start.ts","../src/commands/kb.ts","../src/commands/analytics.ts","../src/commands/history.ts","../src/commands/chat.ts","../src/commands/init.ts","../src/index.ts"],"sourcesContent":["/**\n * Global console override that prepends timestamps to all log output.\n * Format: [YYYY-MM-DD HH:mm:ss.SSS] — similar to NLog/structured logging.\n *\n * Import this file once at the entry point (index.ts) for automatic timestamps.\n */\n\nconst originalLog = console.log;\nconst originalWarn = console.warn;\nconst originalError = console.error;\n\nfunction timestamp(): string {\n const now = new Date();\n const y = now.getFullYear();\n const mo = String(now.getMonth() + 1).padStart(2, '0');\n const d = String(now.getDate()).padStart(2, '0');\n const h = String(now.getHours()).padStart(2, '0');\n const mi = String(now.getMinutes()).padStart(2, '0');\n const s = String(now.getSeconds()).padStart(2, '0');\n const ms = String(now.getMilliseconds()).padStart(3, '0');\n return `[${y}-${mo}-${d} ${h}:${mi}:${s}.${ms}]`;\n}\n\nconsole.log = (...args: any[]) => originalLog(timestamp(), ...args);\nconsole.warn = (...args: any[]) => originalWarn(timestamp(), ...args);\nconsole.error = (...args: any[]) => originalError(timestamp(), ...args);\n","import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nconst ENV_PATH = resolve(process.cwd(), '.env');\n\nexport interface AppConfig {\n // LLM\n LLM_PROVIDER?: string;\n LLM_API_KEY?: string;\n LLM_MODEL?: string;\n LLM_BASE_URL?: string;\n // Channel\n CHANNEL?: string;\n // Telegram\n TELEGRAM_BOT_TOKEN?: string;\n // Skills\n SKILLS_ENABLED?: string;\n // WATI\n WATI_API_TOKEN?: string;\n WATI_TENANT_ID?: string;\n WATI_WEBHOOK_PORT?: string;\n // Memory\n MEMORY_TYPE?: string;\n MEMORY_DB_PATH?: string;\n // Intent\n INTENT_CLASSIFIER?: string;\n // Knowledge Base\n KB_ENABLED?: string;\n KB_DB_PATH?: string;\n KB_EMBEDDING_PROVIDER?: string;\n KB_EMBEDDING_MODEL?: string;\n KB_EMBEDDING_API_KEY?: string;\n KB_RENDER_JS?: string;\n KB_CHUNK_SIZE?: string;\n KB_CHUNK_OVERLAP?: string;\n // Training Mode\n TRAINING_MODE_ENABLED?: string;\n TRAINING_MODE_WHITELIST?: string;\n // Training Copilot\n COPILOT_ENABLED?: string;\n COPILOT_DB_PATH?: string;\n COPILOT_TRACKING_THRESHOLD?: string;\n COPILOT_CLUSTER_THRESHOLD?: string;\n COPILOT_DIGEST_INTERVAL?: string;\n COPILOT_DIGEST_MAX_ITEMS?: string;\n COPILOT_AUTO_SUGGEST?: string;\n // Analytics\n ANALYTICS_ENABLED?: string;\n ANALYTICS_DB_PATH?: string;\n ANALYTICS_DIGEST_ENABLED?: string;\n ANALYTICS_DIGEST_SCHEDULE?: string;\n ANALYTICS_DIGEST_TIME?: string;\n [key: string]: string | undefined;\n}\n\nexport function configExists(): boolean {\n return existsSync(ENV_PATH);\n}\n\nexport function readConfig(): AppConfig {\n if (!existsSync(ENV_PATH)) return {};\n const content = readFileSync(ENV_PATH, 'utf-8');\n const config: AppConfig = {};\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 const value = trimmed.slice(eqIndex + 1).trim();\n config[key] = value;\n }\n return config;\n}\n\nexport function writeConfig(config: AppConfig): void {\n const lines: string[] = [\n '# Operor Configuration',\n '# Generated by operor setup',\n '',\n ];\n\n const sections: { header: string; keys: string[] }[] = [\n { header: 'LLM', keys: ['LLM_PROVIDER', 'LLM_API_KEY', 'LLM_MODEL', 'LLM_BASE_URL'] },\n { header: 'Channel', keys: ['CHANNEL'] },\n { header: 'Telegram', keys: ['TELEGRAM_BOT_TOKEN'] },\n { header: 'Skills', keys: ['SKILLS_ENABLED'] },\n { header: 'WATI', keys: ['WATI_API_TOKEN', 'WATI_TENANT_ID', 'WATI_WEBHOOK_PORT'] },\n { header: 'Memory', keys: ['MEMORY_TYPE', 'MEMORY_DB_PATH'] },\n { header: 'Intent', keys: ['INTENT_CLASSIFIER'] },\n { header: 'Knowledge Base', keys: ['KB_ENABLED', 'KB_DB_PATH', 'KB_EMBEDDING_PROVIDER', 'KB_EMBEDDING_MODEL', 'KB_EMBEDDING_API_KEY', 'KB_RENDER_JS', 'KB_CHUNK_SIZE', 'KB_CHUNK_OVERLAP'] },\n { header: 'Training Mode', keys: ['TRAINING_MODE_ENABLED', 'TRAINING_MODE_WHITELIST'] },\n { header: 'Training Copilot', keys: ['COPILOT_ENABLED', 'COPILOT_DB_PATH', 'COPILOT_TRACKING_THRESHOLD', 'COPILOT_CLUSTER_THRESHOLD', 'COPILOT_DIGEST_INTERVAL', 'COPILOT_DIGEST_MAX_ITEMS', 'COPILOT_AUTO_SUGGEST'] },\n { header: 'Analytics', keys: ['ANALYTICS_ENABLED', 'ANALYTICS_DB_PATH', 'ANALYTICS_DIGEST_ENABLED', 'ANALYTICS_DIGEST_SCHEDULE', 'ANALYTICS_DIGEST_TIME'] },\n ];\n\n const knownKeys = new Set<string>();\n for (const section of sections) {\n const sectionLines: string[] = [];\n for (const key of section.keys) {\n knownKeys.add(key);\n if (config[key]) {\n sectionLines.push(`${key}=${config[key]}`);\n }\n }\n if (sectionLines.length > 0) {\n lines.push(`# ${section.header}`);\n lines.push(...sectionLines);\n lines.push('');\n }\n }\n\n // Preserve any extra keys not covered by known sections\n const extraLines: string[] = [];\n for (const [key, value] of Object.entries(config)) {\n if (value && !knownKeys.has(key)) {\n extraLines.push(`${key}=${value}`);\n }\n }\n if (extraLines.length > 0) {\n lines.push('# Other');\n lines.push(...extraLines);\n lines.push('');\n }\n\n writeFileSync(ENV_PATH, lines.join('\\n'));\n}\n","import * as clack from '@clack/prompts';\nimport { readFileSync, writeFileSync, readdirSync, existsSync } from 'node:fs';\nimport { resolve as resolvePath, join } from 'node:path';\nimport matter from 'gray-matter';\nimport { readConfig, writeConfig, type AppConfig } from './config.js';\nimport { AIProvider } from '@operor/llm';\nimport { loadSkillCatalog, findSkillInCatalog, catalogEntryToConfig } from '@operor/skills';\n\nfunction detectApiKey(provider: string): string | undefined {\n const envVars: Record<string, string[]> = {\n openai: ['OPENAI_API_KEY'],\n anthropic: ['ANTHROPIC_API_KEY'],\n google: ['GOOGLE_API_KEY', 'GOOGLE_GENERATIVE_AI_API_KEY'],\n groq: ['GROQ_API_KEY'],\n };\n\n const vars = envVars[provider] || [];\n for (const varName of vars) {\n const value = process.env[varName];\n if (value) return value;\n }\n return undefined;\n}\n\nfunction maskApiKey(key: string): string {\n if (key.length <= 8) return '••••••••';\n return key.slice(0, 4) + '••••' + key.slice(-4);\n}\n\nexport async function runQuickSetup(): Promise<void> {\n console.clear();\n clack.intro('Operor - Quick Setup');\n\n // 1. LLM Provider\n const llmProvider = await clack.select({\n message: 'Choose your LLM provider',\n options: [\n { value: 'openai', label: 'OpenAI' },\n { value: 'anthropic', label: 'Anthropic (Claude)' },\n { value: 'google', label: 'Google (Gemini)' },\n { value: 'groq', label: 'Groq' },\n { value: 'ollama', label: 'Ollama (local)' },\n ],\n });\n\n if (clack.isCancel(llmProvider)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n // 2. API Key (skip for ollama)\n let llmApiKey: string | symbol = '';\n if (llmProvider !== 'ollama') {\n const detectedKey = detectApiKey(llmProvider as string);\n if (detectedKey) {\n const useExisting = await clack.confirm({\n message: `Found existing API key (${maskApiKey(detectedKey)}). Use it?`,\n initialValue: true,\n });\n if (clack.isCancel(useExisting)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n llmApiKey = useExisting ? detectedKey : await clack.password({\n message: 'Enter your API key',\n validate: (value) => (!value ? 'API key is required' : undefined),\n });\n } else {\n llmApiKey = await clack.password({\n message: 'Enter your API key',\n validate: (value) => (!value ? 'API key is required' : undefined),\n });\n }\n\n if (clack.isCancel(llmApiKey)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n }\n\n // 3. Validate LLM credentials\n const spinner = clack.spinner();\n spinner.start('Validating LLM credentials');\n try {\n const provider = new AIProvider({\n provider: llmProvider as any,\n apiKey: llmApiKey as string,\n });\n await provider.complete([{ role: 'user', content: 'test' }]);\n spinner.stop('LLM credentials validated');\n } catch (error: any) {\n spinner.stop('LLM validation failed');\n clack.log.error(`Failed to validate LLM credentials: ${error.message}`);\n process.exit(1);\n }\n\n // 4. Auto-set sensible defaults\n const config: AppConfig = {\n LLM_PROVIDER: llmProvider as string,\n LLM_API_KEY: llmApiKey as string,\n CHANNEL: 'mock',\n MEMORY_TYPE: 'sqlite',\n INTENT_CLASSIFIER: 'llm',\n KB_ENABLED: 'true',\n KB_EMBEDDING_PROVIDER: llmProvider as string,\n KB_EMBEDDING_API_KEY: llmApiKey as string,\n TRAINING_MODE_ENABLED: 'false',\n ANALYTICS_ENABLED: 'true',\n };\n\n // Merge with any existing config to preserve extra keys\n const existingConfig = readConfig();\n const finalConfig = { ...existingConfig, ...config };\n writeConfig(finalConfig);\n\n // 5. Summary\n clack.log.success('Configuration saved to .env');\n clack.log.info(` LLM Provider: ${llmProvider}`);\n clack.log.info(` Channel: mock (testing)`);\n clack.log.info(` Memory: sqlite`);\n clack.log.info(` Intent: llm`);\n clack.log.info(` Knowledge Base: enabled`);\n clack.log.info(` Analytics: enabled`);\n clack.log.info(` Training Mode: disabled`);\n clack.outro('Quick setup complete. Starting Operor...');\n}\n\nexport async function runSetup(): Promise<void> {\n console.clear();\n clack.intro('Operor - Setup');\n\n // Load existing config to use as defaults\n const existingConfig = readConfig();\n\n // LLM Provider\n const llmProvider = await clack.select({\n message: 'Choose your LLM provider',\n options: [\n { value: 'openai', label: 'OpenAI' },\n { value: 'anthropic', label: 'Anthropic (Claude)' },\n { value: 'google', label: 'Google (Gemini)' },\n { value: 'groq', label: 'Groq' },\n { value: 'ollama', label: 'Ollama (local)' },\n ],\n initialValue: existingConfig.LLM_PROVIDER || undefined,\n });\n\n if (clack.isCancel(llmProvider)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n // Detect existing API key from .env or environment variables\n const detectedKey = detectApiKey(llmProvider as string);\n const existingApiKey = existingConfig.LLM_API_KEY || detectedKey;\n let llmApiKey: string | symbol;\n\n if (existingApiKey && llmProvider !== 'ollama') {\n const useExisting = await clack.confirm({\n message: `Found existing API key (${maskApiKey(existingApiKey)}). Use it?`,\n initialValue: true,\n });\n\n if (clack.isCancel(useExisting)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n if (useExisting) {\n llmApiKey = existingApiKey;\n } else {\n llmApiKey = await clack.password({\n message: 'Enter your API key',\n validate: (value) => (!value ? 'API key is required' : undefined),\n });\n }\n } else {\n llmApiKey = await clack.password({\n message: 'Enter your API key',\n validate: (value) => {\n if (llmProvider === 'ollama') return; // Ollama doesn't need API key\n if (!value) return 'API key is required';\n },\n });\n }\n\n if (clack.isCancel(llmApiKey)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n const llmModel = await clack.text({\n message: 'Enter model name (optional, press Enter for default)',\n placeholder: getDefaultModel(llmProvider as string),\n initialValue: existingConfig.LLM_MODEL || undefined,\n });\n\n if (clack.isCancel(llmModel)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n // Validate LLM credentials\n const spinner = clack.spinner();\n spinner.start('Validating LLM credentials');\n try {\n const provider = new AIProvider({\n provider: llmProvider as any,\n apiKey: llmApiKey as string,\n model: (llmModel as string) || undefined,\n });\n await provider.complete([{ role: 'user', content: 'test' }]);\n spinner.stop('LLM credentials validated');\n } catch (error: any) {\n spinner.stop('LLM validation failed');\n clack.log.error(`Failed to validate LLM credentials: ${error.message}`);\n process.exit(1);\n }\n\n // Channel\n const channel = await clack.select({\n message: 'Choose your messaging channel',\n options: [\n { value: 'whatsapp', label: 'WhatsApp (Baileys)' },\n { value: 'wati', label: 'WhatsApp via WATI (Business API)' },\n { value: 'telegram', label: 'Telegram (grammY)' },\n { value: 'mock', label: 'Mock (for testing)' },\n ],\n initialValue: existingConfig.CHANNEL || undefined,\n });\n\n if (clack.isCancel(channel)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n // Channel-specific credentials (collected separately, merged into config later)\n const channelConfig: AppConfig = {};\n\n if (channel === 'telegram') {\n const botToken = await clack.password({\n message: 'Telegram Bot Token (from @BotFather)',\n validate: (value) => (!value ? 'Bot token is required' : undefined),\n });\n if (clack.isCancel(botToken)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n channelConfig.TELEGRAM_BOT_TOKEN = botToken as string;\n }\n\n if (channel === 'wati') {\n const apiToken = await clack.password({\n message: 'WATI API Token (from your WATI dashboard)',\n validate: (value) => (!value ? 'API token is required' : undefined),\n });\n if (clack.isCancel(apiToken)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n const tenantId = await clack.text({\n message: 'WATI Tenant ID',\n validate: (value) => (!value ? 'Tenant ID is required' : undefined),\n initialValue: existingConfig.WATI_TENANT_ID || undefined,\n });\n if (clack.isCancel(tenantId)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n channelConfig.WATI_API_TOKEN = apiToken as string;\n channelConfig.WATI_TENANT_ID = tenantId as string;\n }\n\n // MCP Skills\n const enableSkills = await clack.confirm({\n message: 'Configure MCP skills? (Shopify, Stripe, search, etc. via mcp.json)',\n initialValue: existingConfig.SKILLS_ENABLED === 'true',\n });\n\n if (clack.isCancel(enableSkills)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n let selectedSkills: string[] = [];\n if (enableSkills) {\n const catalog = loadSkillCatalog();\n const skillOptions = catalog.skills.map((s) => ({\n value: s.name,\n label: `${s.displayName} — ${s.description}`,\n }));\n\n const skills = await clack.multiselect({\n message: 'Select MCP skills to enable (space to toggle)',\n options: skillOptions,\n required: false,\n });\n if (clack.isCancel(skills)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n selectedSkills = skills as string[];\n }\n\n // Memory backend\n const memoryType = await clack.select({\n message: 'Choose storage backend',\n options: [\n { value: 'sqlite', label: 'SQLite (recommended, zero config)' },\n { value: 'memory', label: 'In-memory (data lost on restart)' },\n ],\n initialValue: existingConfig.MEMORY_TYPE || undefined,\n });\n\n if (clack.isCancel(memoryType)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n // Intent classification\n const intentClassifier = await clack.select({\n message: 'Choose intent classification method',\n options: [\n { value: 'llm', label: 'LLM-based (uses your LLM provider)' },\n { value: 'keyword', label: 'Keyword matching (no LLM cost)' },\n ],\n initialValue: existingConfig.INTENT_CLASSIFIER || undefined,\n });\n\n if (clack.isCancel(intentClassifier)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n // Knowledge Base\n const kbEnabled = await clack.confirm({\n message: 'Enable Knowledge Base (RAG)?',\n initialValue: existingConfig.KB_ENABLED === 'true',\n });\n\n if (clack.isCancel(kbEnabled)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n let kbEmbeddingProvider: string | undefined;\n let kbEmbeddingApiKey: string | undefined;\n let kbEmbeddingModel: string | undefined;\n let kbDbPath: string | undefined;\n\n if (kbEnabled) {\n const embProvider = await clack.select({\n message: 'Embedding provider',\n options: [\n { value: 'openai', label: 'OpenAI (text-embedding-3-small, 1536d)' },\n { value: 'google', label: 'Google (text-embedding-004, 768d)' },\n { value: 'mistral', label: 'Mistral (mistral-embed, 1024d)' },\n { value: 'cohere', label: 'Cohere (embed-english-v3.0, 1024d)' },\n { value: 'ollama', label: 'Ollama (local, nomic-embed-text, 768d)' },\n ],\n initialValue: existingConfig.KB_EMBEDDING_PROVIDER || undefined,\n });\n if (clack.isCancel(embProvider)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n kbEmbeddingProvider = embProvider as string;\n\n if (kbEmbeddingProvider !== 'ollama') {\n const embKey = await clack.password({\n message: 'Embedding API key (or Enter to reuse LLM key)',\n });\n if (clack.isCancel(embKey)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n kbEmbeddingApiKey = (embKey as string) || (llmApiKey as string);\n }\n\n const embModel = await clack.text({\n message: 'Embedding model (optional, press Enter for default)',\n placeholder: getDefaultEmbeddingModel(kbEmbeddingProvider),\n initialValue: existingConfig.KB_EMBEDDING_MODEL || undefined,\n });\n if (clack.isCancel(embModel)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n kbEmbeddingModel = (embModel as string) || undefined;\n\n const dbPath = await clack.text({\n message: 'Knowledge base DB path',\n placeholder: './knowledge.db',\n initialValue: existingConfig.KB_DB_PATH || undefined,\n });\n if (clack.isCancel(dbPath)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n kbDbPath = (dbPath as string) || './knowledge.db';\n }\n\n // Training Mode\n const trainingEnabled = await clack.confirm({\n message: 'Enable training mode? (allows /teach command to add FAQ answers)',\n initialValue: existingConfig.TRAINING_MODE_ENABLED === 'true',\n });\n\n if (clack.isCancel(trainingEnabled)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n let trainingWhitelist = '';\n if (trainingEnabled) {\n const whitelistInput = await clack.text({\n message: 'Whitelist phone numbers for training (comma-separated, e.g. 85253332683,85291234567)',\n placeholder: '85253332683,85291234567',\n initialValue: existingConfig.TRAINING_MODE_WHITELIST || undefined,\n });\n if (clack.isCancel(whitelistInput)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n trainingWhitelist = (whitelistInput as string) || '';\n }\n\n // Training Copilot (requires KB to be enabled)\n let copilotConfig: Partial<AppConfig> = {};\n if (kbEnabled) {\n const copilotEnabled = await clack.confirm({\n message: 'Enable Training Copilot? (auto-tracks unanswered queries, suggests FAQ additions)',\n initialValue: existingConfig.COPILOT_ENABLED !== 'false',\n });\n\n if (clack.isCancel(copilotEnabled)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n if (copilotEnabled) {\n copilotConfig.COPILOT_ENABLED = 'true';\n\n const copilotDbPath = await clack.text({\n message: 'Copilot database path',\n placeholder: './copilot.db',\n initialValue: existingConfig.COPILOT_DB_PATH || undefined,\n });\n if (clack.isCancel(copilotDbPath)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n copilotConfig.COPILOT_DB_PATH = (copilotDbPath as string) || './copilot.db';\n\n const trackingThreshold = await clack.text({\n message: 'Tracking threshold (KB score below which queries are tracked)',\n placeholder: '0.70',\n initialValue: existingConfig.COPILOT_TRACKING_THRESHOLD || undefined,\n });\n if (clack.isCancel(trackingThreshold)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n if (trackingThreshold) copilotConfig.COPILOT_TRACKING_THRESHOLD = trackingThreshold as string;\n\n const autoSuggest = await clack.confirm({\n message: 'Auto-generate LLM answer suggestions for unanswered queries?',\n initialValue: existingConfig.COPILOT_AUTO_SUGGEST !== 'false',\n });\n if (clack.isCancel(autoSuggest)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n copilotConfig.COPILOT_AUTO_SUGGEST = autoSuggest ? 'true' : 'false';\n } else {\n copilotConfig.COPILOT_ENABLED = 'false';\n }\n }\n\n // Analytics & Reporting (after Copilot)\n let analyticsConfig: Partial<AppConfig> = {};\n const analyticsEnabled = await clack.confirm({\n message: 'Enable Analytics & Reporting? (tracks response times, token usage, conversation metrics)',\n initialValue: existingConfig.ANALYTICS_ENABLED !== 'false',\n });\n\n if (clack.isCancel(analyticsEnabled)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n if (analyticsEnabled) {\n analyticsConfig.ANALYTICS_ENABLED = 'true';\n\n const analyticsDbPath = await clack.text({\n message: 'Analytics database path',\n placeholder: './analytics.db',\n initialValue: existingConfig.ANALYTICS_DB_PATH || undefined,\n });\n if (clack.isCancel(analyticsDbPath)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n analyticsConfig.ANALYTICS_DB_PATH = (analyticsDbPath as string) || './analytics.db';\n\n const digestEnabled = await clack.select({\n message: 'Enable daily digest reports via WhatsApp?',\n options: [\n { value: 'daily', label: 'Yes, daily digest' },\n { value: 'weekly', label: 'Weekly only' },\n { value: 'both', label: 'Both daily and weekly' },\n { value: 'false', label: 'No digest reports' },\n ],\n initialValue: existingConfig.ANALYTICS_DIGEST_ENABLED === 'true'\n ? (existingConfig.ANALYTICS_DIGEST_SCHEDULE || 'daily')\n : 'false',\n });\n if (clack.isCancel(digestEnabled)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n\n if (digestEnabled !== 'false') {\n analyticsConfig.ANALYTICS_DIGEST_ENABLED = 'true';\n analyticsConfig.ANALYTICS_DIGEST_SCHEDULE = digestEnabled as string;\n\n const digestTime = await clack.text({\n message: 'Digest delivery time (HH:MM, 24h format)',\n placeholder: '09:00',\n initialValue: existingConfig.ANALYTICS_DIGEST_TIME || undefined,\n validate: (value) => {\n if (!value) return undefined; // accept default\n if (!/^\\d{2}:\\d{2}$/.test(value)) return 'Use HH:MM format (e.g. 09:00)';\n },\n });\n if (clack.isCancel(digestTime)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n analyticsConfig.ANALYTICS_DIGEST_TIME = (digestTime as string) || '09:00';\n } else {\n analyticsConfig.ANALYTICS_DIGEST_ENABLED = 'false';\n }\n } else {\n analyticsConfig.ANALYTICS_ENABLED = 'false';\n }\n\n // Build new config from wizard answers\n const newConfig: AppConfig = {\n LLM_PROVIDER: llmProvider as string,\n LLM_API_KEY: llmApiKey as string,\n LLM_MODEL: (llmModel as string) || undefined,\n CHANNEL: channel as string,\n SKILLS_ENABLED: enableSkills ? 'true' : 'false',\n MEMORY_TYPE: memoryType as string,\n INTENT_CLASSIFIER: intentClassifier as string,\n ...channelConfig,\n ...(kbEnabled && {\n KB_ENABLED: 'true',\n KB_DB_PATH: kbDbPath,\n KB_EMBEDDING_PROVIDER: kbEmbeddingProvider,\n KB_EMBEDDING_MODEL: kbEmbeddingModel,\n KB_EMBEDDING_API_KEY: kbEmbeddingApiKey,\n }),\n TRAINING_MODE_ENABLED: trainingEnabled ? 'true' : 'false',\n ...(trainingWhitelist && { TRAINING_MODE_WHITELIST: trainingWhitelist }),\n ...copilotConfig,\n ...analyticsConfig,\n };\n\n // Collect MCP skill-specific API keys and create mcp.json\n if (enableSkills && selectedSkills.length > 0) {\n const catalog = loadSkillCatalog();\n const mcpSkills: any[] = [];\n\n // Read existing mcp.json to determine which skills were removed\n const mcpPath = resolvePath(process.cwd(), 'mcp.json');\n let previousSkillNames: string[] = [];\n try {\n const existing = JSON.parse(readFileSync(mcpPath, 'utf-8'));\n previousSkillNames = (existing.skills || []).map((s: any) => s.name);\n } catch {\n // No existing mcp.json — nothing was previously enabled\n }\n\n for (const skillName of selectedSkills) {\n const entry = findSkillInCatalog(catalog, skillName);\n if (!entry) continue;\n\n // Prompt for each required env var\n for (const [varName, spec] of Object.entries(entry.envVars)) {\n if (!spec.required) continue;\n const value = await clack.password({\n message: `${entry.displayName}: ${spec.description}`,\n validate: (v) => (!v ? `${varName} is required` : undefined),\n });\n if (clack.isCancel(value)) {\n clack.cancel('Setup cancelled');\n process.exit(0);\n }\n newConfig[varName] = value as string;\n }\n\n mcpSkills.push(catalogEntryToConfig(entry));\n }\n\n // Write mcp.json\n const mcpConfig = { skills: mcpSkills };\n writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2) + '\\n');\n clack.log.info(' MCP config saved to mcp.json');\n\n // Sync skills to agent INSTRUCTIONS.md files\n const addedSkills = selectedSkills.filter((s) => !previousSkillNames.includes(s));\n const removedSkills = previousSkillNames.filter((s) => !selectedSkills.includes(s));\n const agentsDir = resolvePath(process.cwd(), 'agents');\n const updatedAgents = syncSkillsToAgents(agentsDir, addedSkills, removedSkills);\n if (updatedAgents.length > 0) {\n clack.log.info(` Updated skills in: ${updatedAgents.join(', ')}`);\n }\n }\n\n // Merge: existing config as base, wizard values on top.\n // Preserves any keys the wizard doesn't prompt for (e.g. LLM_BASE_URL, custom keys).\n const finalConfig = { ...existingConfig, ...newConfig };\n writeConfig(finalConfig);\n clack.outro('Config saved to .env. Starting Operor...');\n}\n\n/**\n * Sync skill names into agent INSTRUCTIONS.md frontmatter.\n * Only touches agents that already have a `skills:` field.\n * If the resulting skills array is empty, removes the `skills` key entirely.\n */\nexport function syncSkillsToAgents(\n agentsDir: string,\n addedSkills: string[],\n removedSkills: string[],\n): string[] {\n if (addedSkills.length === 0 && removedSkills.length === 0) return [];\n\n const updated: string[] = [];\n\n let entries: string[];\n try {\n entries = readdirSync(agentsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory() && !d.name.startsWith('_'))\n .map((d) => d.name);\n } catch {\n return [];\n }\n\n for (const agentName of entries) {\n const instrPath = join(agentsDir, agentName, 'INSTRUCTIONS.md');\n if (!existsSync(instrPath)) continue;\n\n const raw = readFileSync(instrPath, 'utf-8');\n const parsed = matter(raw);\n\n // Only touch agents that explicitly declare a skills array\n if (!Array.isArray(parsed.data.skills)) continue;\n\n const currentSkills: string[] = parsed.data.skills;\n let newSkills = currentSkills.filter((s: string) => !removedSkills.includes(s));\n for (const skill of addedSkills) {\n if (!newSkills.includes(skill)) newSkills.push(skill);\n }\n\n // Check if anything changed\n if (\n newSkills.length === currentSkills.length &&\n newSkills.every((s, i) => s === currentSkills[i])\n ) {\n continue;\n }\n\n // If empty after removals, drop the skills key so agent gets all tools\n if (newSkills.length === 0) {\n delete parsed.data.skills;\n } else {\n parsed.data.skills = newSkills;\n }\n\n writeFileSync(instrPath, matter.stringify(parsed.content, parsed.data));\n updated.push(agentName);\n }\n\n return updated;\n}\n\nfunction getDefaultModel(provider: string): string {\n const defaults: Record<string, string> = {\n openai: 'gpt-5-mini',\n anthropic: 'claude-3-5-sonnet-20241022',\n google: 'gemini-2.0-flash-exp',\n groq: 'llama-3.3-70b-versatile',\n ollama: 'llama3.2',\n };\n return defaults[provider] || '';\n}\n\nfunction getDefaultEmbeddingModel(provider: string): string {\n const defaults: Record<string, string> = {\n openai: 'text-embedding-3-small',\n google: 'text-embedding-004',\n mistral: 'mistral-embed',\n cohere: 'embed-english-v3.0',\n ollama: 'nomic-embed-text',\n };\n return defaults[provider] || '';\n}\n","import fs from 'fs';\nimport type { Skill, Tool } from '@operor/core';\nimport { readConfig } from './config.js';\nimport { applyLLMOverride } from './commands/llm-override.js';\n\nexport async function startOperor(): Promise<void> {\n const config = readConfig();\n\n if (!config.LLM_PROVIDER || !config.CHANNEL) {\n console.error('Missing configuration. Run \"operor setup\" first.');\n process.exit(1);\n }\n\n console.log('[Operor] Starting...');\n\n // Dynamic imports to avoid requiring all deps upfront\n const { Operor, LLMIntentClassifier, AgentLoader } = await import('@operor/core');\n const { AIProvider } = await import('@operor/llm');\n\n // Setup memory store (before LLM so we can load persisted model settings)\n let memory: any;\n if (config.MEMORY_TYPE === 'sqlite') {\n const { SQLiteMemory } = await import('@operor/memory');\n memory = new SQLiteMemory(config.MEMORY_DB_PATH || './operor.db');\n console.log('[Operor] Using SQLite memory store');\n }\n\n // Load persisted model settings (override env vars if stored)\n let llmProvider = config.LLM_PROVIDER as 'openai' | 'anthropic' | 'google' | 'groq' | 'ollama';\n let llmModel = config.LLM_MODEL;\n let llmApiKey = config.LLM_API_KEY;\n if (memory?.getSetting) {\n try {\n const storedProvider = await memory.getSetting('llm_provider');\n const storedModel = await memory.getSetting('llm_model');\n if (storedProvider) llmProvider = storedProvider as any;\n if (storedModel) llmModel = storedModel;\n // Load stored API key for the active provider\n const storedKey = await memory.getSetting(`llm_apikey_${llmProvider}`);\n if (storedKey) llmApiKey = storedKey;\n } catch { /* getSetting not available */ }\n }\n\n // Setup LLM (needed for both completion and intent classification)\n const llm = new AIProvider({\n provider: llmProvider,\n apiKey: llmApiKey,\n model: llmModel,\n });\n\n // Load stored API keys for other providers\n if (memory?.getSetting) {\n for (const p of ['openai', 'anthropic', 'google', 'groq', 'ollama']) {\n if (p === llmProvider) continue;\n try {\n const k = await memory.getSetting(`llm_apikey_${p}`);\n if (k) llm.setApiKey(p, k);\n } catch { /* ignore */ }\n }\n }\n\n // Setup intent classifier\n let intentClassifier: any;\n if (config.INTENT_CLASSIFIER === 'llm') {\n intentClassifier = new LLMIntentClassifier(llm);\n console.log('[Operor] Using LLM intent classification');\n }\n\n // Setup Knowledge Base runtime (if enabled)\n let kbRuntime: any;\n let embedder: any;\n if (config.KB_ENABLED === 'true') {\n try {\n const {\n SQLiteKnowledgeStore,\n EmbeddingService,\n TextChunker,\n IngestionPipeline,\n RetrievalPipeline,\n QueryRewriter,\n UrlIngestor,\n SiteCrawler,\n FileIngestor,\n } = await import('@operor/knowledge');\n\n embedder = new EmbeddingService({\n provider: (config.KB_EMBEDDING_PROVIDER || 'openai') as any,\n apiKey: config.KB_EMBEDDING_API_KEY || config.LLM_API_KEY,\n model: config.KB_EMBEDDING_MODEL,\n });\n\n const kbStore = new SQLiteKnowledgeStore(\n config.KB_DB_PATH || './knowledge.db',\n embedder.dimensions,\n );\n await kbStore.initialize();\n\n const chunker = new TextChunker({\n chunkSize: config.KB_CHUNK_SIZE ? parseInt(config.KB_CHUNK_SIZE) : undefined,\n chunkOverlap: config.KB_CHUNK_OVERLAP ? parseInt(config.KB_CHUNK_OVERLAP) : undefined,\n });\n const ingestion = new IngestionPipeline(kbStore, embedder, chunker);\n\n // Setup optional LLM query rewriter (Layer 4)\n let queryRewriter: InstanceType<typeof QueryRewriter> | undefined;\n try {\n const rewriteModel = llm.getModel();\n queryRewriter = new QueryRewriter({ model: rewriteModel });\n } catch {\n // LLM not available for rewriting — layers 1-3 still work\n }\n\n const retrieval = new RetrievalPipeline(kbStore, embedder, {\n faqThreshold: 0.85,\n queryRewriter,\n fusionStrategy: (config.FUSION_STRATEGY as 'rrf' | 'weighted') || 'rrf',\n });\n\n // Create ingestors for URL, site, and file ingestion\n const crawl4aiUrl = config.CRAWL4AI_URL || undefined;\n const urlIngestor = new UrlIngestor(ingestion, { crawl4aiUrl });\n const siteCrawler = new SiteCrawler(ingestion, { crawl4aiUrl });\n const fileIngestor = new FileIngestor(ingestion);\n\n // Wrap in KnowledgeBaseRuntime interface\n kbRuntime = {\n ingestFaq: async (question: string, answer: string, metadata?: Record<string, any>) => {\n const result = await ingestion.ingestFaq(question, answer, metadata);\n return { id: result.id, existingMatch: (result as any).existingMatch };\n },\n listDocuments: async () => {\n return await kbStore.listDocuments();\n },\n deleteDocument: async (id: string) => {\n return await kbStore.deleteDocument(id);\n },\n retrieve: async (query: string) => {\n return await retrieval.retrieve(query);\n },\n getStats: async () => {\n return await kbStore.getStats();\n },\n ingestUrl: async (url: string) => {\n const doc = await urlIngestor.ingestUrl(url);\n const faqCount = doc.metadata?.faqCount;\n const chunks = faqCount ?? (kbStore.getChunkCount ? kbStore.getChunkCount(doc.id) : 0);\n return { id: doc.id, title: doc.title, chunks, faqCount };\n },\n ingestSite: async (url: string, options?: { maxDepth?: number; maxPages?: number; onProgress?: (crawled: number, total: number, url: string) => void }) => {\n const docs = await siteCrawler.crawlSite(url, {\n ...options,\n onProgress: options?.onProgress,\n });\n const totalChunks = docs.reduce((sum, doc) => {\n const count = kbStore.getChunkCount ? kbStore.getChunkCount(doc.id) : 0;\n return sum + count;\n }, 0);\n return { documents: docs.length, chunks: totalChunks };\n },\n ingestFile: async (buffer: Buffer, fileName: string) => {\n // Write buffer to temp file, ingest, then clean up\n const { writeFile, unlink } = await import('fs/promises');\n const { join } = await import('path');\n const { tmpdir } = await import('os');\n const tempPath = join(tmpdir(), `operor-${Date.now()}-${fileName}`);\n await writeFile(tempPath, buffer);\n try {\n const doc = await fileIngestor.ingestFile(tempPath, fileName);\n const chunkCount = kbStore.getChunkCount ? kbStore.getChunkCount(doc.id) : 0;\n return { id: doc.id, title: doc.title, chunks: chunkCount };\n } finally {\n await unlink(tempPath).catch(() => {}); // Clean up temp file\n }\n },\n rebuild: async () => {\n return await ingestion.rebuild();\n },\n };\n\n console.log('[Operor] Knowledge Base enabled');\n } catch (error: any) {\n console.error(`[Operor] Failed to initialize Knowledge Base: ${error.message}`);\n }\n }\n\n // Setup Training Copilot (if enabled)\n let copilotHandler: any;\n let copilotTracker: any;\n if (config.COPILOT_ENABLED !== 'false' && kbRuntime) {\n try {\n const {\n SQLiteCopilotStore,\n UnansweredQueryTracker,\n QueryClusterer,\n SuggestionEngine,\n CopilotCommandHandler,\n DigestScheduler,\n DEFAULT_COPILOT_CONFIG,\n } = await import('@operor/copilot');\n\n const copilotConfig = {\n ...DEFAULT_COPILOT_CONFIG,\n enabled: true,\n trackingThreshold: config.COPILOT_TRACKING_THRESHOLD ? parseFloat(config.COPILOT_TRACKING_THRESHOLD) : DEFAULT_COPILOT_CONFIG.trackingThreshold,\n clusterThreshold: config.COPILOT_CLUSTER_THRESHOLD ? parseFloat(config.COPILOT_CLUSTER_THRESHOLD) : DEFAULT_COPILOT_CONFIG.clusterThreshold,\n digestIntervalMs: config.COPILOT_DIGEST_INTERVAL ? parseInt(config.COPILOT_DIGEST_INTERVAL) : DEFAULT_COPILOT_CONFIG.digestIntervalMs,\n digestMaxItems: config.COPILOT_DIGEST_MAX_ITEMS ? parseInt(config.COPILOT_DIGEST_MAX_ITEMS) : DEFAULT_COPILOT_CONFIG.digestMaxItems,\n autoSuggest: config.COPILOT_AUTO_SUGGEST !== 'false',\n };\n\n // Reuse the same embedder dimensions from KB\n const copilotStore = new SQLiteCopilotStore(\n config.COPILOT_DB_PATH || './copilot.db',\n embedder.dimensions,\n );\n await copilotStore.initialize();\n\n const clusterer = new QueryClusterer(copilotStore, embedder, {\n clusterThreshold: copilotConfig.clusterThreshold,\n });\n\n copilotTracker = new UnansweredQueryTracker(\n copilotStore,\n copilotConfig,\n embedder,\n clusterer,\n );\n\n // SuggestionEngine wraps the LLM for generating draft answers\n const suggestionEngine = copilotConfig.autoSuggest\n ? new SuggestionEngine(\n { generateText: (opts: any) => llm.complete([\n ...(opts.system ? [{ role: 'system' as const, content: opts.system }] : []),\n { role: 'user' as const, content: opts.prompt },\n ]) },\n kbRuntime,\n )\n : undefined;\n\n copilotHandler = new CopilotCommandHandler(\n copilotStore,\n suggestionEngine,\n kbRuntime,\n clusterer,\n );\n\n // Start digest scheduler if training mode whitelist is configured\n const adminPhones = config.TRAINING_MODE_WHITELIST?.split(',').map((p: string) => p.trim()).filter(Boolean) || [];\n if (adminPhones.length > 0) {\n const digest = new DigestScheduler(copilotStore, copilotConfig, async (phone: string, text: string) => {\n try {\n if (provider && typeof provider.sendMessage === 'function') {\n await provider.sendMessage(phone, text);\n }\n } catch (err: any) {\n console.warn('[Copilot] Failed to send digest:', err?.message);\n }\n });\n digest.start(adminPhones);\n }\n\n console.log('[Operor] Training Copilot enabled');\n } catch (error: any) {\n console.error(`[Operor] Failed to initialize Training Copilot: ${error.message}`);\n console.error('[Operor] /review commands will not be available. Try running \"pnpm install\" if packages are missing.');\n }\n }\n\n // Setup Analytics (enabled by default)\n let analyticsCollector: any;\n let analyticsStore: any;\n if (config.ANALYTICS_ENABLED !== 'false') {\n try {\n const { SQLiteAnalyticsStore, AnalyticsCollector } = await import('@operor/analytics');\n analyticsStore = new SQLiteAnalyticsStore(config.ANALYTICS_DB_PATH || './analytics.db');\n await analyticsStore.initialize();\n analyticsCollector = new AnalyticsCollector(analyticsStore, { debug: true });\n console.log('[Operor] Analytics enabled');\n } catch (error: any) {\n console.error(`[Operor] Failed to initialize Analytics: ${error.message}`);\n }\n }\n\n // Build training whitelist — DB is source of truth, env var is bootstrap seed\n let trainingWhitelist: string[] = config.TRAINING_MODE_WHITELIST?.split(',').map(p => p.trim()).filter(Boolean) || [];\n\n if (config.TRAINING_MODE_ENABLED === 'true' && memory?.getSetting) {\n try {\n const stored = await memory.getSetting('training_whitelist');\n if (stored) {\n trainingWhitelist = stored.split(',').map((p: string) => p.trim()).filter(Boolean);\n } else if (trainingWhitelist.length > 0) {\n // Seed DB from env var on first run\n await memory.setSetting('training_whitelist', trainingWhitelist.join(','));\n }\n } catch {\n // getSetting not available — fall back to env var\n }\n }\n\n // Pre-load skills module for injection into Operor (avoids circular dep: core cannot import skills)\n let skillsModule: any;\n try {\n skillsModule = await import('@operor/skills');\n } catch {\n // skills package not available — catalog commands will show \"not available\"\n }\n\n // Detect agents directory early so Operor can persist frontmatter changes\n const agentsDir = `${process.cwd()}/agents`;\n const hasAgentsDir = fs.existsSync(agentsDir);\n\n // Create Operor instance\n const os = new Operor({\n debug: true,\n llmProvider: llm,\n ...(memory && { memory }),\n ...(intentClassifier && { intentClassifier }),\n ...(kbRuntime && { kb: kbRuntime }),\n ...(copilotHandler && { copilotHandler }),\n ...(copilotTracker && { copilotTracker }),\n ...(analyticsCollector && { analyticsCollector }),\n ...(analyticsStore && { analyticsStore }),\n ...(skillsModule && { skillsModule }),\n ...(hasAgentsDir && { agentsDir }),\n ...(config.TRAINING_MODE_ENABLED === 'true' && {\n trainingMode: {\n enabled: true,\n whitelist: trainingWhitelist,\n },\n }),\n });\n\n // Setup provider\n let provider: any;\n if (config.CHANNEL === 'whatsapp') {\n const { BaileysProvider } = await import('@operor/provider-baileys');\n provider = new BaileysProvider({\n groupMode: (config.WHATSAPP_GROUP_MODE as any) || 'mention-only',\n });\n } else if (config.CHANNEL === 'telegram') {\n const { TelegramProvider } = await import('@operor/provider-telegram');\n provider = new TelegramProvider({ botToken: config.TELEGRAM_BOT_TOKEN! });\n } else if (config.CHANNEL === 'wati') {\n const { WatiProvider } = await import('@operor/provider-wati');\n provider = new WatiProvider({\n apiToken: config.WATI_API_TOKEN!,\n tenantId: config.WATI_TENANT_ID!,\n webhookPort: config.WATI_WEBHOOK_PORT ? parseInt(config.WATI_WEBHOOK_PORT) : undefined,\n });\n } else {\n const { MockProvider } = await import('@operor/provider-mock');\n provider = new MockProvider();\n }\n os.addProvider(provider);\n\n // Setup MCP skills from mcp.json\n let skillManager: any;\n const skillInstances: Skill[] = [];\n let loadSkillsConfig: any;\n try {\n const skillsMod = await import('@operor/skills');\n loadSkillsConfig = skillsMod.loadSkillsConfig;\n const { SkillManager } = skillsMod;\n const skillsConfig = loadSkillsConfig();\n skillManager = new SkillManager();\n const mcpSkills = await skillManager.initialize(skillsConfig);\n for (const skill of mcpSkills) {\n os.addSkill(skill);\n skillInstances.push(skill);\n }\n if (mcpSkills.length > 0) {\n console.log(`[Operor] ${mcpSkills.length} MCP skill(s) loaded`);\n }\n } catch (error: any) {\n // Graceful if mcp.json doesn't exist or skills fail to load\n if (config.SKILLS_ENABLED === 'true') {\n console.warn(`[Operor] Failed to load MCP skills: ${error.message}`);\n }\n }\n\n // Collect all tools from skills\n const allTools: Tool[] = skillInstances.flatMap((skill) => Object.values(skill.tools));\n\n // Helper: get prompt skill name+content for an agent (filtered by skills list)\n const getPromptSkills = (agentSkillNames?: string[]): Array<{name: string, content: string}> => {\n return skillInstances\n .filter((s): s is any => typeof (s as any).getContent === 'function')\n .filter((s) => !agentSkillNames || agentSkillNames.includes(s.name))\n .map((s) => ({ name: s.name, content: (s as any).getContent() }));\n };\n\n // Track per-agent tool arrays so we can mutate them in-place on hot-reload\n const agentToolsMap = new Map<string, Tool[]>();\n\n let definitions: Awaited<ReturnType<InstanceType<typeof AgentLoader>['loadAll']>> = [];\n\n if (hasAgentsDir) {\n // File-based agent definitions\n const loader = new AgentLoader(process.cwd());\n definitions = await loader.loadAll();\n\n if (definitions.length === 0) {\n console.error('[Operor] agents/ directory found but no valid agent definitions. Check INSTRUCTIONS.md files.');\n process.exit(1);\n }\n\n for (const def of definitions) {\n // Filter tools for this agent based on its skills list\n const agentTools: Tool[] = def.config.skills\n ? skillInstances\n .filter((skill) => def.config.skills!.includes(skill.name))\n .flatMap((skill) => Object.values(skill.tools))\n : allTools;\n\n agentToolsMap.set(def.config.name, agentTools);\n\n const agent = os.createAgent({\n ...def.config,\n tools: agentTools,\n });\n\n // Override agent.process with LLM using the file-based systemPrompt\n applyLLMOverride(agent, llm, agentTools, {\n systemPrompt: def.systemPrompt,\n kbRuntime,\n useKB: def.config.knowledgeBase,\n guardrails: def.config.guardrails,\n promptSkills: getPromptSkills(def.config.skills),\n });\n\n console.log(\n `[Operor] Loaded agent: ${def.config.name}` +\n (def.config.channels ? ` (channels: ${def.config.channels.join(', ')})` : '') +\n (def.config.skills ? ` (skills: ${def.config.skills.join(', ')})` : '') +\n (def.config.knowledgeBase ? ' (KB)' : '') +\n (def.config.priority ? ` (priority: ${def.config.priority})` : '')\n );\n }\n\n console.log(`[Operor] Loaded ${definitions.length} agent(s) from agents/ directory`);\n } else {\n // Fallback: single agent (backward compatible)\n const agent = os.createAgent({\n name: 'support',\n purpose: 'Customer support agent',\n personality: 'Friendly, helpful, and professional',\n triggers: ['*'],\n tools: allTools,\n });\n\n agentToolsMap.set('support', allTools);\n applyLLMOverride(agent, llm, allTools, { kbRuntime, promptSkills: getPromptSkills() });\n console.log('[Operor] Using default single-agent mode');\n }\n\n // --- Hot-reload MCP skills on mcp.json change ---\n const reloadSkills = async () => {\n if (!skillManager || !loadSkillsConfig) return;\n\n console.log('[Operor] \\uD83D\\uDD04 Reloading MCP skills...');\n try {\n // 1. Re-read mcp.json\n const newConfig = loadSkillsConfig();\n\n // 2. Remove old skills from Operor (closes MCP clients)\n for (const skill of skillInstances) {\n await os.removeSkill(skill.name);\n }\n\n // 3. Reset SkillManager internal state\n await skillManager.closeAll();\n\n // 4. Initialize new skills\n const newSkills = await skillManager.initialize(newConfig);\n\n // 5. Update skillInstances in-place\n skillInstances.splice(0, skillInstances.length, ...newSkills);\n\n // 6. Add new skills to Operor (double-init guarded)\n for (const skill of newSkills) {\n await os.addSkill(skill);\n }\n\n // 7. Rebuild allTools in-place so existing closures see the change\n const freshTools: Tool[] = skillInstances.flatMap((skill) => Object.values(skill.tools));\n allTools.splice(0, allTools.length, ...freshTools);\n\n // 8. Rebuild each agent's tools array in-place\n for (const def of definitions) {\n const agentTools = agentToolsMap.get(def.config.name);\n if (!agentTools) continue;\n const newAgentTools: Tool[] = def.config.skills\n ? skillInstances\n .filter((skill) => def.config.skills!.includes(skill.name))\n .flatMap((skill) => Object.values(skill.tools))\n : freshTools;\n agentTools.splice(0, agentTools.length, ...newAgentTools);\n }\n\n // Also update fallback single-agent if no definitions\n if (definitions.length === 0) {\n const fallbackTools = agentToolsMap.get('support');\n if (fallbackTools) {\n fallbackTools.splice(0, fallbackTools.length, ...freshTools);\n }\n }\n\n // 9. Re-apply LLM override for agents whose prompt skill content may have changed\n for (const def of definitions) {\n const agentTools = agentToolsMap.get(def.config.name);\n if (!agentTools) continue;\n const agent = os.getAgents().find((a: any) => a.getConfig?.().name === def.config.name || a.config?.name === def.config.name);\n if (agent) {\n applyLLMOverride(agent, llm, agentTools, {\n systemPrompt: def.systemPrompt,\n kbRuntime,\n useKB: def.config.knowledgeBase,\n guardrails: def.config.guardrails,\n promptSkills: getPromptSkills(def.config.skills),\n });\n }\n }\n\n console.log(`[Operor] \\u2705 Reloaded ${newSkills.length} skill(s)`);\n } catch (error: any) {\n console.error(`[Operor] \\u274C Failed to reload MCP skills: ${error.message}`);\n }\n };\n\n // Start\n await os.start();\n console.log('[Operor] Running. Press Ctrl+C to stop.');\n\n // Watch mcp.json for changes and hot-reload skills\n const mcpJsonPath = `${process.cwd()}/mcp.json`;\n if (fs.existsSync(mcpJsonPath) && loadSkillsConfig) {\n let reloadTimer: ReturnType<typeof setTimeout> | null = null;\n fs.watch(mcpJsonPath, () => {\n if (reloadTimer) clearTimeout(reloadTimer);\n reloadTimer = setTimeout(() => {\n reloadTimer = null;\n reloadSkills().catch((err) => {\n console.error(`[Operor] Skill reload error: ${err.message}`);\n });\n }, 500);\n });\n console.log('[Operor] Watching mcp.json for changes');\n }\n\n // Graceful shutdown — close MCP skills\n const shutdown = async () => {\n console.log('\\n[Operor] Shutting down...');\n if (skillManager) {\n await skillManager.closeAll();\n }\n await os.stop();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n // For mock provider, simulate a test message\n if (config.CHANNEL === 'mock') {\n setTimeout(() => {\n provider.simulateIncomingMessage(\n '+1234567890',\n 'Hi, I need help with my order #1001'\n );\n }, 2000);\n }\n}\n","import { Command } from 'commander';\nimport * as clack from '@clack/prompts';\nimport { readConfig, configExists } from '../config.js';\n\nfunction getKBConfig() {\n if (!configExists()) {\n clack.log.error('.env file not found. Run \"operor setup\" first.');\n process.exit(1);\n }\n const config = readConfig();\n if (config.KB_ENABLED !== 'true') {\n clack.log.error('Knowledge Base is not enabled. Run \"operor setup\" or set KB_ENABLED=true.');\n process.exit(1);\n }\n return config;\n}\n\nasync function loadKB(config: ReturnType<typeof readConfig>) {\n try {\n const {\n SQLiteKnowledgeStore,\n EmbeddingService,\n TextChunker,\n IngestionPipeline,\n RetrievalPipeline,\n UrlIngestor,\n FileIngestor,\n SiteCrawler,\n } = await import('@operor/knowledge');\n\n const embeddings = new EmbeddingService({\n provider: (config.KB_EMBEDDING_PROVIDER as 'openai' | 'google' | 'mistral' | 'cohere' | 'ollama') || 'openai',\n apiKey: config.KB_EMBEDDING_API_KEY,\n model: config.KB_EMBEDDING_MODEL,\n });\n\n const store = new SQLiteKnowledgeStore(\n config.KB_DB_PATH || './knowledge.db',\n embeddings.dimensions,\n );\n await store.initialize();\n\n const chunker = new TextChunker({\n chunkSize: config.KB_CHUNK_SIZE ? parseInt(config.KB_CHUNK_SIZE) : undefined,\n chunkOverlap: config.KB_CHUNK_OVERLAP ? parseInt(config.KB_CHUNK_OVERLAP) : undefined,\n });\n\n // Create LLM provider for Q&A extraction during ingestion (if configured)\n let llmProvider: any;\n if (config.LLM_PROVIDER && config.LLM_API_KEY) {\n const { AIProvider } = await import('@operor/llm');\n llmProvider = new AIProvider({\n provider: config.LLM_PROVIDER as any,\n apiKey: config.LLM_API_KEY,\n model: config.LLM_MODEL,\n });\n }\n\n const ingestion = new IngestionPipeline(store, embeddings, chunker, llmProvider);\n const retrieval = new RetrievalPipeline(store, embeddings);\n const crawl4aiUrl = config.CRAWL4AI_URL || undefined;\n const urlIngestor = new UrlIngestor(ingestion, { crawl4aiUrl });\n const fileIngestor = new FileIngestor(ingestion);\n const siteCrawler = new SiteCrawler(ingestion, { crawl4aiUrl });\n\n return { store, embeddings, ingestion, retrieval, urlIngestor, fileIngestor, siteCrawler };\n } catch {\n clack.log.error(\n '@operor/knowledge package not found. Install it first:\\n pnpm add @operor/knowledge'\n );\n process.exit(1);\n }\n}\n\nexport function registerKBCommand(program: Command): void {\n const kb = program.command('kb').description('Knowledge Base management');\n\n kb.command('add-url')\n .description('Ingest a URL into the knowledge base')\n .argument('<url>', 'URL to ingest')\n .option('--priority <n>', 'Document priority (1=official, 2=supplementary, 3=archived)', '2')\n .option('--extract-qa', 'Use LLM to extract Q&A pairs instead of chunking')\n .action(async (url: string, opts: { priority: string; extractQa?: boolean }) => {\n clack.intro('KB — Add URL');\n const config = getKBConfig();\n const { store, urlIngestor } = await loadKB(config);\n\n const spinner = clack.spinner();\n spinner.start(`Fetching and ingesting ${url}`);\n try {\n const doc = await urlIngestor.ingestUrl(url, {\n priority: parseInt(opts.priority),\n extractQA: opts.extractQa,\n });\n spinner.stop(`Ingested: ${doc.title || url}`);\n clack.log.success(`Document ID: ${doc.id}`);\n } catch (error: any) {\n spinner.stop(`Failed to ingest URL`);\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n store.close();\n }\n clack.outro('Done');\n });\n\n kb.command('add-site')\n .description('Crawl and ingest an entire website')\n .argument('<url>', 'Website URL to crawl')\n .option('--depth <n>', 'Maximum crawl depth', '2')\n .option('--max-pages <n>', 'Maximum pages to crawl', '50')\n .option('--no-sitemap', 'Skip sitemap.xml and use link crawling only')\n .option('--delay <ms>', 'Delay between requests in milliseconds', '500')\n .action(async (url: string, opts: { depth: string; maxPages: string; sitemap: boolean; delay: string }) => {\n clack.intro('KB — Crawl Site');\n const config = getKBConfig();\n const { store, siteCrawler } = await loadKB(config);\n\n const spinner = clack.spinner();\n spinner.start('Starting crawl...');\n\n try {\n const docs = await siteCrawler.crawlSite(url, {\n maxDepth: parseInt(opts.depth),\n maxPages: parseInt(opts.maxPages),\n useSitemap: opts.sitemap,\n delayMs: parseInt(opts.delay),\n onProgress: (crawled, discovered, currentUrl) => {\n const shortUrl = currentUrl.length > 60 ? currentUrl.slice(0, 57) + '...' : currentUrl;\n spinner.message(`Crawling... (${crawled}/${discovered} pages) ${shortUrl}`);\n },\n });\n\n spinner.stop(`Crawled ${docs.length} page(s)`);\n clack.log.success(`Ingested ${docs.length} document(s) from ${url}`);\n } catch (error: any) {\n spinner.stop('Crawl failed');\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n store.close();\n }\n clack.outro('Done');\n });\n\n kb.command('add-file')\n .description('Ingest a document file into the knowledge base')\n .argument('<path>', 'File path to ingest')\n .option('--priority <n>', 'Document priority (1=official, 2=supplementary, 3=archived)', '2')\n .action(async (filePath: string, opts: { priority: string }) => {\n clack.intro('KB — Add File');\n const config = getKBConfig();\n const { store, fileIngestor } = await loadKB(config);\n\n const spinner = clack.spinner();\n spinner.start(`Ingesting ${filePath}`);\n try {\n const doc = await fileIngestor.ingestFile(filePath, undefined, { priority: parseInt(opts.priority) });\n spinner.stop(`Ingested: ${doc.title || filePath}`);\n clack.log.success(`Document ID: ${doc.id}`);\n } catch (error: any) {\n spinner.stop(`Failed to ingest file`);\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n store.close();\n }\n clack.outro('Done');\n });\n\n kb.command('add-faq')\n .description('Add a manual FAQ entry')\n .argument('<question>', 'FAQ question')\n .argument('<answer>', 'FAQ answer')\n .action(async (question: string, answer: string) => {\n clack.intro('KB — Add FAQ');\n const config = getKBConfig();\n const { store, ingestion } = await loadKB(config);\n\n const spinner = clack.spinner();\n spinner.start('Adding FAQ entry');\n try {\n let doc = await ingestion.ingestFaq(question, answer);\n // CLI auto-replaces similar FAQs silently\n if ((doc as any).existingMatch) {\n const match = (doc as any).existingMatch;\n clack.log.info(`Replacing similar FAQ (${(match.score * 100).toFixed(0)}% match): \"${match.question}\"`);\n doc = await ingestion.ingestFaq(question, answer, { forceReplace: true, replaceId: match.id });\n }\n spinner.stop('FAQ entry added');\n clack.log.success(`Document ID: ${doc.id}`);\n } catch (error: any) {\n spinner.stop('Failed to add FAQ');\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n store.close();\n }\n clack.outro('Done');\n });\n\n kb.command('list')\n .description('List all KB documents')\n .action(async () => {\n clack.intro('KB — Documents');\n const config = getKBConfig();\n const { store } = await loadKB(config);\n\n try {\n const docs = await store.listDocuments();\n if (docs.length === 0) {\n clack.log.info('No documents in the knowledge base.');\n } else {\n const header = `${'ID'.padEnd(40)} ${'Type'.padEnd(12)} Title / Source`;\n clack.log.info(header);\n clack.log.info('─'.repeat(header.length));\n for (const doc of docs) {\n const line = `${doc.id.padEnd(40)} ${doc.sourceType.padEnd(12)} ${doc.title || doc.sourceUrl || doc.fileName || '—'}`;\n clack.log.info(line);\n }\n clack.log.info(`\\n${docs.length} document(s)`);\n }\n } catch (error: any) {\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n store.close();\n }\n clack.outro('');\n });\n\n kb.command('search')\n .description('Test search against the knowledge base')\n .argument('<query>', 'Search query')\n .option('-n, --limit <n>', 'Max results', '5')\n .action(async (query: string, opts: { limit: string }) => {\n clack.intro('KB — Search');\n const config = getKBConfig();\n const { store, retrieval } = await loadKB(config);\n\n const spinner = clack.spinner();\n spinner.start(`Searching for \"${query}\"`);\n try {\n const result = await retrieval.retrieve(query, { limit: parseInt(opts.limit) });\n spinner.stop(`Found ${result.results.length} result(s)`);\n\n if (result.results.length === 0) {\n clack.log.info('No results found.');\n } else {\n for (const r of result.results) {\n clack.log.info(`\\n[Score: ${r.score.toFixed(4)}] Doc #${r.document.id}`);\n const preview = r.chunk.content.length > 200 ? r.chunk.content.slice(0, 200) + '…' : r.chunk.content;\n clack.log.message(preview);\n }\n }\n } catch (error: any) {\n spinner.stop('Search failed');\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n store.close();\n }\n clack.outro('');\n });\n\n kb.command('ask')\n .description('Ask a question using KB retrieval + LLM generation (RAG)')\n .argument('<question>', 'Question to answer')\n .option('-n, --limit <n>', 'Max KB chunks to retrieve', '5')\n .option('--no-sources', 'Hide source attribution')\n .action(async (question: string, opts: { limit: string; sources: boolean }) => {\n clack.intro('KB — Ask');\n const config = getKBConfig();\n const { store, retrieval } = await loadKB(config);\n\n const spinner = clack.spinner();\n spinner.start('Searching knowledge base...');\n try {\n const result = await retrieval.retrieve(question, { limit: parseInt(opts.limit) });\n\n // FAQ fast-path — no LLM needed\n if (result.isFaqMatch && result.results.length > 0) {\n spinner.stop('FAQ match found');\n clack.log.success(result.results[0].chunk.content);\n if (opts.sources) {\n clack.log.info(`\\nSource: FAQ (score: ${result.results[0].score.toFixed(4)})`);\n }\n return;\n }\n\n if (result.results.length === 0) {\n spinner.stop('No relevant KB content found');\n clack.log.warn('Cannot answer — no matching documents.');\n return;\n }\n\n // LLM generation\n if (!config.LLM_PROVIDER || !config.LLM_API_KEY) {\n spinner.stop('KB results found, but no LLM configured');\n clack.log.error('LLM_PROVIDER and LLM_API_KEY required. Use \"operor kb search\" for retrieval-only.');\n return;\n }\n\n spinner.message('Generating answer...');\n const { AIProvider } = await import('@operor/llm');\n const llm = new AIProvider({\n provider: config.LLM_PROVIDER as any,\n apiKey: config.LLM_API_KEY,\n model: config.LLM_MODEL,\n });\n\n const response = await llm.complete([\n { role: 'system', content: `Answer using ONLY the provided context. If insufficient, say so.\\n\\n${result.context}` },\n { role: 'user', content: question },\n ]);\n\n spinner.stop('Answer generated');\n clack.log.success(response.text);\n\n if (opts.sources) {\n clack.log.info('\\nSources:');\n for (const r of result.results) {\n const title = r.document?.title || r.document?.id || 'unknown';\n clack.log.info(` - ${title} (score: ${r.score.toFixed(4)})`);\n }\n }\n } catch (error: any) {\n spinner.stop('Failed');\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n store.close();\n }\n clack.outro('');\n });\n\n kb.command('delete')\n .description('Delete a document from the knowledge base')\n .argument('<id>', 'Document ID to delete')\n .action(async (id: string) => {\n clack.intro('KB — Delete');\n const config = getKBConfig();\n const { store } = await loadKB(config);\n\n try {\n await store.deleteDocument(id);\n clack.log.success(`Document #${id} deleted`);\n } catch (error: any) {\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n store.close();\n }\n clack.outro('Done');\n });\n\n kb.command('rebuild')\n .description('Rebuild all KB vector embeddings using the current embedding provider')\n .action(async () => {\n clack.intro('KB — Rebuild Embeddings');\n const config = getKBConfig();\n const { store, ingestion } = await loadKB(config);\n\n const spinner = clack.spinner();\n try {\n const stats = await store.getStats();\n if (stats.documentCount === 0) {\n clack.log.warn('Knowledge Base is empty — nothing to rebuild.');\n return;\n }\n\n clack.log.info(`Provider: ${config.KB_EMBEDDING_PROVIDER || 'openai'}`);\n clack.log.info(`Documents: ${stats.documentCount}, Chunks: ${stats.chunkCount}`);\n spinner.start('Rebuilding embeddings...');\n\n const result = await ingestion.rebuild((current, total, docTitle) => {\n if (current < total) {\n spinner.message(`Rebuilding... (${current + 1}/${total}) ${docTitle}`);\n }\n });\n\n spinner.stop('Rebuild complete');\n clack.log.success([\n `Documents rebuilt: ${result.documentsRebuilt}`,\n `Chunks rebuilt: ${result.chunksRebuilt}`,\n `Old dimensions: ${result.oldDimensions}`,\n `New dimensions: ${result.newDimensions}`,\n ].join('\\n'));\n } catch (error: any) {\n spinner.stop('Rebuild failed');\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n store.close();\n }\n clack.outro('Done');\n });\n\n kb.command('stats')\n .description('Show knowledge base statistics')\n .action(async () => {\n clack.intro('KB — Statistics');\n const config = getKBConfig();\n const { store } = await loadKB(config);\n\n try {\n const stats = await store.getStats();\n clack.log.info(`Documents: ${stats.documentCount}`);\n clack.log.info(`Chunks: ${stats.chunkCount}`);\n clack.log.info(`Embedding dims: ${stats.embeddingDimensions || '—'}`);\n clack.log.info(`DB size: ${formatBytes(stats.dbSizeBytes)}`);\n clack.log.info(`DB path: ${config.KB_DB_PATH || './knowledge.db'}`);\n clack.log.info(`Embedding provider: ${config.KB_EMBEDDING_PROVIDER || 'openai'}`);\n clack.log.info(`Embedding model: ${config.KB_EMBEDDING_MODEL || 'default'}`);\n } catch (error: any) {\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n store.close();\n }\n clack.outro('');\n });\n}\n\nfunction formatBytes(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 * as clack from '@clack/prompts';\nimport { readConfig, configExists } from '../config.js';\n\nfunction getAnalyticsConfig() {\n if (!configExists()) {\n clack.log.error('.env file not found. Run \"operor setup\" first.');\n process.exit(1);\n }\n const config = readConfig();\n if (config.ANALYTICS_ENABLED === 'false') {\n clack.log.error('Analytics is disabled. Set ANALYTICS_ENABLED=true in .env.');\n process.exit(1);\n }\n return config;\n}\n\nasync function loadStore(config: ReturnType<typeof readConfig>) {\n try {\n const { SQLiteAnalyticsStore } = await import('@operor/analytics');\n const store = new SQLiteAnalyticsStore(config.ANALYTICS_DB_PATH || './analytics.db');\n await store.initialize();\n return store;\n } catch {\n clack.log.error(\n '@operor/analytics package not found. Install it first:\\n pnpm add @operor/analytics',\n );\n process.exit(1);\n }\n}\n\nfunction makeRange(days: number): { from: number; to: number } {\n const to = Date.now();\n const from = to - days * 24 * 60 * 60 * 1000;\n return { from, to };\n}\n\n/** Simple sparkline from an array of numbers */\nfunction sparkline(values: number[]): string {\n if (values.length === 0) return '';\n const chars = '▁▂▃▄▅▆▇█';\n const max = Math.max(...values);\n if (max === 0) return chars[0].repeat(values.length);\n return values.map(v => chars[Math.min(Math.floor((v / max) * (chars.length - 1)), chars.length - 1)]).join('');\n}\n\n/** Simple horizontal bar */\nfunction bar(value: number, max: number, width = 30): string {\n if (max === 0) return '';\n const filled = Math.round((value / max) * width);\n return '█'.repeat(filled) + '░'.repeat(width - filled);\n}\n\nfunction maskPhone(phone: string): string {\n if (phone.length <= 6) return '***' + phone.slice(-3);\n return phone.slice(0, 3) + '***' + phone.slice(-3);\n}\n\nfunction fmtMs(ms: number): string {\n if (ms < 1000) return `${Math.round(ms)}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction fmtPct(pct: number): string {\n return `${pct.toFixed(1)}%`;\n}\n\nexport function registerAnalyticsCommand(program: Command): void {\n const analytics = program.command('analytics').description('Usage analytics and insights');\n\n // Default: summary dashboard\n analytics\n .option('--days <n>', 'Number of days to include', '7')\n .action(async (opts: { days: string }) => {\n clack.intro('Analytics — Dashboard');\n const config = getAnalyticsConfig();\n const store = await loadStore(config);\n const range = makeRange(parseInt(opts.days));\n\n try {\n const [summary, volume, agents] = await Promise.all([\n store.getSummary(range),\n store.getMessageVolume(range, 'day'),\n store.getAgentStats(range),\n ]);\n\n if (summary.totalMessages === 0) {\n clack.log.info('No messages recorded in this period.');\n return;\n }\n\n // Messages\n const trend = sparkline(volume.map(v => v.count));\n clack.log.info(` Messages`);\n clack.log.info(` Total: ${summary.totalMessages}`);\n clack.log.info(` Avg/day: ${summary.avgPerDay.toFixed(1)}`);\n clack.log.info(` Peak day: ${summary.peakDay || '—'}`);\n clack.log.info(` Trend: ${trend}`);\n\n // Response quality\n clack.log.info('');\n clack.log.info(` Response Quality`);\n clack.log.info(` KB answered: ${fmtPct(summary.kbAnsweredPct)}`);\n clack.log.info(` LLM fallback: ${fmtPct(summary.llmFallbackPct)}`);\n clack.log.info(` No answer: ${fmtPct(summary.noAnswerPct)}`);\n clack.log.info(` Avg response: ${fmtMs(summary.avgResponseTime)}`);\n clack.log.info(` FAQ hit rate: ${fmtPct(summary.faqHitRate)}`);\n\n // Customers\n clack.log.info('');\n clack.log.info(` Customers`);\n clack.log.info(` Unique: ${summary.uniqueCustomers}`);\n clack.log.info(` New: ${summary.newCustomers}`);\n clack.log.info(` Returning: ${summary.returningCustomers}`);\n if (summary.uniqueCustomers > 0) {\n clack.log.info(` Avg msgs: ${(summary.totalMessages / summary.uniqueCustomers).toFixed(1)}/customer`);\n }\n\n // Agents\n if (agents.length > 0) {\n clack.log.info('');\n clack.log.info(` Agents`);\n for (const a of agents) {\n const pct = summary.totalMessages > 0\n ? ((a.messageCount / summary.totalMessages) * 100).toFixed(1)\n : '0.0';\n clack.log.info(` ${a.agentName.padEnd(20)} ${String(a.messageCount).padStart(5)} msgs (${pct}%) avg ${fmtMs(a.avgResponseTimeMs)}`);\n }\n }\n\n // Copilot\n if (summary.pendingReviews > 0) {\n clack.log.info('');\n clack.log.info(` Copilot`);\n clack.log.info(` Pending reviews: ${summary.pendingReviews}`);\n }\n } catch (error: any) {\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n await store.close();\n }\n clack.outro('');\n });\n\n // Messages subcommand\n analytics\n .command('messages')\n .description('Message volume breakdown')\n .option('--days <n>', 'Number of days to include', '7')\n .action(async (opts: { days: string }) => {\n clack.intro('Analytics — Messages');\n const config = getAnalyticsConfig();\n const store = await loadStore(config);\n const days = parseInt(opts.days);\n const range = makeRange(days);\n\n try {\n const [daily, hourly] = await Promise.all([\n store.getMessageVolume(range, 'day'),\n store.getMessageVolume(makeRange(1), 'hour'),\n ]);\n\n if (daily.length === 0) {\n clack.log.info('No messages recorded in this period.');\n return;\n }\n\n // Daily breakdown\n const maxDaily = Math.max(...daily.map(d => d.count));\n clack.log.info(' Daily Volume');\n for (const d of daily) {\n clack.log.info(` ${d.date} ${bar(d.count, maxDaily, 25)} ${d.count}`);\n }\n\n // Hourly distribution (today)\n if (hourly.length > 0) {\n const maxHourly = Math.max(...hourly.map(h => h.count));\n clack.log.info('');\n clack.log.info(' Today — Hourly');\n for (const h of hourly) {\n const hour = h.date.split(' ')[1] || h.date;\n clack.log.info(` ${hour} ${bar(h.count, maxHourly, 20)} ${h.count}`);\n }\n }\n } catch (error: any) {\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n await store.close();\n }\n clack.outro('');\n });\n\n // Agents subcommand\n analytics\n .command('agents')\n .description('Per-agent performance breakdown')\n .option('--days <n>', 'Number of days to include', '7')\n .action(async (opts: { days: string }) => {\n clack.intro('Analytics — Agents');\n const config = getAnalyticsConfig();\n const store = await loadStore(config);\n const range = makeRange(parseInt(opts.days));\n\n try {\n const [agents, summary] = await Promise.all([\n store.getAgentStats(range),\n store.getSummary(range),\n ]);\n\n if (agents.length === 0) {\n clack.log.info('No agent activity in this period.');\n return;\n }\n\n const header = `${'Agent'.padEnd(22)} ${'Msgs'.padStart(6)} ${'%'.padStart(6)} ${'Avg Time'.padStart(10)} ${'Confidence'.padStart(11)} ${'Escalations'.padStart(12)} ${'Tools'.padStart(6)}`;\n clack.log.info(header);\n clack.log.info('─'.repeat(header.length));\n\n for (const a of agents) {\n const pct = summary.totalMessages > 0\n ? ((a.messageCount / summary.totalMessages) * 100).toFixed(1)\n : '0.0';\n const line = `${a.agentName.padEnd(22)} ${String(a.messageCount).padStart(6)} ${(pct + '%').padStart(6)} ${fmtMs(a.avgResponseTimeMs).padStart(10)} ${fmtPct(a.avgConfidence * 100).padStart(11)} ${String(a.escalationCount).padStart(12)} ${String(a.toolCallCount).padStart(6)}`;\n clack.log.info(line);\n }\n } catch (error: any) {\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n await store.close();\n }\n clack.outro('');\n });\n\n // Customers subcommand\n analytics\n .command('customers')\n .description('Customer engagement metrics')\n .option('--days <n>', 'Number of days to include', '7')\n .option('-n, --limit <n>', 'Top customers to show', '10')\n .action(async (opts: { days: string; limit: string }) => {\n clack.intro('Analytics — Customers');\n const config = getAnalyticsConfig();\n const store = await loadStore(config);\n const range = makeRange(parseInt(opts.days));\n\n try {\n const [customers, summary] = await Promise.all([\n store.getCustomerStats(range, parseInt(opts.limit)),\n store.getSummary(range),\n ]);\n\n if (customers.length === 0) {\n clack.log.info('No customer activity in this period.');\n return;\n }\n\n clack.log.info(` Unique: ${summary.uniqueCustomers}`);\n clack.log.info(` New: ${summary.newCustomers}`);\n clack.log.info(` Returning: ${summary.returningCustomers}`);\n\n // Engagement distribution\n const buckets = { '1 msg': 0, '2-5': 0, '6-10': 0, '10+': 0 };\n for (const c of customers) {\n if (c.messageCount === 1) buckets['1 msg']++;\n else if (c.messageCount <= 5) buckets['2-5']++;\n else if (c.messageCount <= 10) buckets['6-10']++;\n else buckets['10+']++;\n }\n clack.log.info('');\n clack.log.info(' Engagement Distribution');\n const maxBucket = Math.max(...Object.values(buckets));\n for (const [label, count] of Object.entries(buckets)) {\n clack.log.info(` ${label.padEnd(8)} ${bar(count, maxBucket, 20)} ${count}`);\n }\n\n // Top customers\n clack.log.info('');\n clack.log.info(' Top Customers');\n const header = `${'Phone'.padEnd(16)} ${'Msgs'.padStart(6)} ${'Status'.padStart(8)} ${'Last Seen'.padStart(12)}`;\n clack.log.info(` ${header}`);\n clack.log.info(` ${'─'.repeat(header.length)}`);\n for (const c of customers) {\n const lastSeen = new Date(c.lastSeen).toLocaleDateString();\n const status = c.isNew ? 'new' : 'return';\n clack.log.info(` ${maskPhone(c.customerPhone).padEnd(16)} ${String(c.messageCount).padStart(6)} ${status.padStart(8)} ${lastSeen.padStart(12)}`);\n }\n } catch (error: any) {\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n await store.close();\n }\n clack.outro('');\n });\n\n // KB subcommand\n analytics\n .command('kb')\n .description('Knowledge Base performance metrics')\n .option('--days <n>', 'Number of days to include', '7')\n .action(async (opts: { days: string }) => {\n clack.intro('Analytics — Knowledge Base');\n const config = getAnalyticsConfig();\n const store = await loadStore(config);\n const range = makeRange(parseInt(opts.days));\n\n try {\n const kbStats = await store.getKbStats(range);\n\n if (kbStats.totalQueries === 0) {\n clack.log.info('No KB queries in this period.');\n return;\n }\n\n clack.log.info(` Total queries: ${kbStats.totalQueries}`);\n clack.log.info(` FAQ hits: ${kbStats.faqHits} (${fmtPct(kbStats.faqHitRate)})`);\n clack.log.info(` Avg top score: ${kbStats.avgTopScore.toFixed(4)}`);\n\n // Pipeline breakdown\n const hybridCount = kbStats.totalQueries - kbStats.faqHits;\n clack.log.info('');\n clack.log.info(' Pipeline Breakdown');\n clack.log.info(` FAQ fast-path: ${kbStats.faqHits}`);\n clack.log.info(` Hybrid/LLM: ${hybridCount}`);\n\n // Top FAQ hits\n if (kbStats.topFaqHits.length > 0) {\n clack.log.info('');\n clack.log.info(' Top FAQ Hits');\n for (const h of kbStats.topFaqHits.slice(0, 10)) {\n clack.log.info(` ${String(h.count).padStart(4)}x ${h.intent}`);\n }\n }\n\n // Top misses\n if (kbStats.topMisses.length > 0) {\n clack.log.info('');\n clack.log.info(' Top Misses (consider teaching these)');\n for (const m of kbStats.topMisses.slice(0, 10)) {\n clack.log.info(` ${String(m.count).padStart(4)}x ${m.intent} (avg score: ${m.avgScore.toFixed(3)})`);\n }\n clack.log.info('');\n clack.log.info(' Tip: Use \"operor kb add-faq <question> <answer>\" to teach missed queries.');\n }\n } catch (error: any) {\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n await store.close();\n }\n clack.outro('');\n });\n\n // Export subcommand\n analytics\n .command('export')\n .description('Export analytics data as CSV or JSON')\n .option('--days <n>', 'Number of days to include', '7')\n .option('--json', 'Export as JSON instead of CSV')\n .option('-o, --output <file>', 'Output file path')\n .action(async (opts: { days: string; json?: boolean; output?: string }) => {\n clack.intro('Analytics — Export');\n const config = getAnalyticsConfig();\n const store = await loadStore(config);\n const range = makeRange(parseInt(opts.days));\n\n try {\n const [summary, volume, agents, customers, kbStats] = await Promise.all([\n store.getSummary(range),\n store.getMessageVolume(range, 'day'),\n store.getAgentStats(range),\n store.getCustomerStats(range, 100),\n store.getKbStats(range),\n ]);\n\n const data = { summary, volume, agents, customers, kbStats };\n\n let output: string;\n if (opts.json) {\n output = JSON.stringify(data, null, 2);\n } else {\n // CSV: export daily volume as the primary table\n const lines = ['date,messages'];\n for (const v of volume) {\n lines.push(`${v.date},${v.count}`);\n }\n output = lines.join('\\n');\n }\n\n if (opts.output) {\n const { writeFileSync } = await import('node:fs');\n writeFileSync(opts.output, output);\n clack.log.success(`Exported to ${opts.output}`);\n } else {\n console.log(output);\n }\n } catch (error: any) {\n clack.log.error(error.message);\n process.exit(1);\n } finally {\n await store.close();\n }\n clack.outro('');\n });\n}\n","import { Command } from 'commander';\nimport { createInterface } from 'node:readline';\nimport { readConfig, configExists } from '../config.js';\n\nexport function registerHistoryCommand(program: Command): void {\n const history = program.command('history').description('Conversation history management');\n\n history\n .command('clear')\n .description('Clear conversation history from the memory database')\n .option('--customer <id>', 'Clear history for a specific customer ID')\n .option('--agent <name>', 'Clear history for a specific agent')\n .option('--all', 'Clear all conversation history')\n .option('--yes', 'Skip confirmation prompt')\n .action(async (opts: { customer?: string; agent?: string; all?: boolean; yes?: boolean }) => {\n if (!opts.customer && !opts.agent && !opts.all) {\n console.error('Specify --customer <id>, --agent <name>, --all, or a combination.');\n process.exit(1);\n }\n\n if (!configExists()) {\n console.error('.env file not found. Run \"operor setup\" first.');\n process.exit(1);\n }\n\n const config = readConfig();\n if (config.MEMORY_TYPE !== 'sqlite') {\n console.error('History clear requires SQLite memory (MEMORY_TYPE=sqlite).');\n process.exit(1);\n }\n\n const { SQLiteMemory } = await import('@operor/memory');\n const memory = new SQLiteMemory(config.MEMORY_DB_PATH || './operor.db');\n await memory.initialize();\n\n try {\n const scope = opts.all\n ? 'ALL conversation history'\n : `history for ${[opts.customer && `customer=${opts.customer}`, opts.agent && `agent=${opts.agent}`].filter(Boolean).join(', ')}`;\n\n if (!opts.yes) {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>(r => rl.question(`Delete ${scope}? Type \"yes\" to confirm: `, r));\n rl.close();\n if (answer.trim().toLowerCase() !== 'yes') {\n console.log('Aborted.');\n return;\n }\n }\n\n const { deletedCount } = await memory.clearHistory(\n opts.all ? undefined : opts.customer,\n opts.agent,\n );\n console.log(`Deleted ${deletedCount} message(s).`);\n } finally {\n await memory.close();\n }\n });\n}\n","import fs from 'fs';\nimport { Command } from 'commander';\nimport * as clack from '@clack/prompts';\nimport * as readline from 'node:readline';\nimport type { Skill, Tool } from '@operor/core';\nimport { readConfig, configExists } from '../config.js';\nimport { applyLLMOverride } from './llm-override.js';\n\ninterface ChatOptions {\n message?: string;\n debug?: boolean;\n kb?: boolean;\n tools?: boolean;\n}\n\nasync function buildPipeline(opts: ChatOptions) {\n const config = readConfig();\n\n if (!config.LLM_PROVIDER || !config.LLM_API_KEY) {\n clack.log.error('LLM_PROVIDER and LLM_API_KEY required. Run \"operor setup\" first.');\n process.exit(1);\n }\n\n const { Operor, LLMIntentClassifier, AgentLoader } = await import('@operor/core');\n const { AIProvider } = await import('@operor/llm');\n const { MockProvider } = await import('@operor/provider-mock');\n\n const llm = new AIProvider({\n provider: config.LLM_PROVIDER as 'openai' | 'anthropic' | 'google' | 'groq' | 'ollama',\n apiKey: config.LLM_API_KEY,\n model: config.LLM_MODEL,\n });\n\n let intentClassifier: any;\n if (config.INTENT_CLASSIFIER === 'llm') {\n intentClassifier = new LLMIntentClassifier(llm);\n }\n\n let skillsModule: any;\n try { skillsModule = await import('@operor/skills'); } catch {}\n\n const os = new Operor({\n debug: !!opts.debug,\n ...(intentClassifier && { intentClassifier }),\n ...(skillsModule && { skillsModule }),\n });\n\n const provider = new MockProvider();\n os.addProvider(provider);\n\n // Load MCP skills + tools\n const skillInstances: Skill[] = [];\n\n if (config.SKILLS_ENABLED !== 'false') {\n try {\n const { SkillManager, loadSkillsConfig } = await import('@operor/skills');\n const skillsConfig = loadSkillsConfig();\n const skillManager = new SkillManager();\n const skills = await skillManager.initialize(skillsConfig);\n for (const skill of skills) {\n os.addSkill(skill);\n skillInstances.push(skill);\n if (opts.debug) clack.log.info(`[debug] MCP skill loaded: ${skill.name}`);\n }\n } catch (error: any) {\n if (opts.debug) clack.log.warn(`[debug] MCP skills not available: ${error.message}`);\n }\n }\n\n const allTools: Tool[] = opts.tools !== false\n ? skillInstances.flatMap((skill) => Object.values(skill.tools))\n : [];\n\n // Helper: get prompt skill name+content for an agent (filtered by skills list)\n const getPromptSkills = (agentSkillNames?: string[]): Array<{name: string, content: string}> => {\n return skillInstances\n .filter((s): s is any => typeof (s as any).getContent === 'function')\n .filter((s) => !agentSkillNames || agentSkillNames.includes(s.name))\n .map((s) => ({ name: s.name, content: (s as any).getContent() }));\n };\n\n // KB runtime (optional) — same pattern as start.ts\n let kbRuntime: any;\n let kbStore: any = null;\n if (opts.kb !== false && config.KB_ENABLED === 'true') {\n try {\n const {\n SQLiteKnowledgeStore,\n EmbeddingService,\n TextChunker,\n IngestionPipeline,\n RetrievalPipeline,\n QueryRewriter,\n } = await import('@operor/knowledge');\n\n const embedder = new EmbeddingService({\n provider: (config.KB_EMBEDDING_PROVIDER as any) || 'openai',\n apiKey: config.KB_EMBEDDING_API_KEY || config.LLM_API_KEY,\n model: config.KB_EMBEDDING_MODEL,\n });\n\n kbStore = new SQLiteKnowledgeStore(\n config.KB_DB_PATH || './knowledge.db',\n embedder.dimensions,\n );\n await kbStore.initialize();\n\n // Setup optional LLM query rewriter\n let queryRewriter: InstanceType<typeof QueryRewriter> | undefined;\n try {\n queryRewriter = new QueryRewriter({ model: llm.getModel() });\n } catch { /* LLM not available for rewriting */ }\n\n const retrieval = new RetrievalPipeline(kbStore, embedder, {\n faqThreshold: 0.85,\n queryRewriter,\n });\n\n kbRuntime = {\n retrieve: async (query: string) => retrieval.retrieve(query),\n getStats: async () => kbStore.getStats(),\n };\n\n if (opts.debug) clack.log.info('[debug] Knowledge Base loaded');\n } catch (e: any) {\n clack.log.warn(`Knowledge Base configured but failed to load: ${e?.message}. Continuing without KB.`);\n }\n }\n\n // Check if agents/ directory exists for file-based agent definitions\n const agentsDir = `${process.cwd()}/agents`;\n const hasAgentsDir = fs.existsSync(agentsDir);\n\n if (hasAgentsDir) {\n // File-based agent definitions — same as start.ts\n const loader = new AgentLoader(process.cwd());\n const definitions = await loader.loadAll();\n\n if (definitions.length === 0) {\n clack.log.warn('agents/ directory found but no valid agent definitions. Falling back to default agent.');\n } else {\n for (const def of definitions) {\n const agentTools: Tool[] = def.config.skills\n ? skillInstances\n .filter((skill) => def.config.skills!.includes(skill.name))\n .flatMap((skill) => Object.values(skill.tools))\n : allTools;\n\n const agent = os.createAgent({\n ...def.config,\n tools: agentTools,\n });\n\n applyLLMOverride(agent, llm, agentTools, {\n systemPrompt: def.systemPrompt,\n kbRuntime,\n useKB: def.config.knowledgeBase,\n guardrails: def.config.guardrails,\n promptSkills: getPromptSkills(def.config.skills),\n });\n\n if (opts.debug) {\n clack.log.info(\n `[debug] Loaded agent: ${def.config.name}` +\n (def.config.skills ? ` (skills: ${def.config.skills.join(', ')})` : '') +\n (def.config.knowledgeBase ? ' (KB)' : '')\n );\n }\n }\n\n if (opts.debug) clack.log.info(`[debug] Loaded ${definitions.length} agent(s) from agents/`);\n\n // Wire up assistant message tracking\n os.on('message:processed', (event) => {\n os.addAssistantMessage(event.customer.id, event.response.text);\n if (opts.debug) {\n clack.log.info(`[debug] Agent: ${event.agent}, intent: ${event.intent?.name || 'default'}, ${event.duration}ms`);\n }\n });\n\n return { os, provider, llm, kbStore };\n }\n }\n\n // Fallback: single default agent (no agents/ directory or empty)\n const agent = os.createAgent({\n name: 'support',\n purpose: 'Customer support agent',\n personality: 'Friendly, helpful, and professional',\n triggers: ['*'],\n tools: allTools,\n ...(kbRuntime && { knowledgeBase: true }),\n });\n\n applyLLMOverride(agent, llm, allTools, {\n kbRuntime,\n promptSkills: getPromptSkills(),\n });\n\n // Wire up assistant message tracking\n os.on('message:processed', (event) => {\n os.addAssistantMessage(event.customer.id, event.response.text);\n if (opts.debug) {\n clack.log.info(`[debug] Agent: ${event.agent}, intent: ${event.intent?.name || 'default'}, ${event.duration}ms`);\n }\n });\n\n return { os, provider, llm, kbStore };\n}\n\nexport function registerChatCommand(program: Command): void {\n program\n .command('chat')\n .description('Chat with your agent (full pipeline REPL)')\n .option('-m, --message <text>', 'One-shot mode: send a single message and exit')\n .option('--debug', 'Show intent, agent selection, and KB retrieval details')\n .option('--no-kb', 'Skip Knowledge Base context injection')\n .option('--no-tools', 'Disable tool calling')\n .action(async (opts: ChatOptions) => {\n if (!configExists()) {\n clack.log.error('No configuration found. Run \"operor setup\" first.');\n process.exit(1);\n }\n\n clack.intro('Operor — Chat');\n\n const spinner = clack.spinner();\n spinner.start('Loading pipeline...');\n\n let pipeline: Awaited<ReturnType<typeof buildPipeline>>;\n try {\n pipeline = await buildPipeline(opts);\n } catch (error: any) {\n spinner.stop('Failed to load pipeline');\n clack.log.error(error.message);\n process.exit(1);\n }\n\n const { os, provider, kbStore } = pipeline;\n await os.start();\n spinner.stop('Pipeline ready');\n\n const cleanup = () => {\n if (kbStore) kbStore.close();\n };\n\n if (opts.message) {\n // One-shot mode\n const responsePromise = new Promise<string>((resolve) => {\n os.on('message:processed', (event) => {\n resolve(event.response.text);\n });\n });\n\n provider.simulateIncomingMessage('+cli-user', opts.message);\n const response = await responsePromise;\n console.log(response);\n cleanup();\n clack.outro('');\n return;\n }\n\n // Interactive REPL\n clack.log.info('Type your message and press Enter. Type \"exit\" or Ctrl+C to quit.\\n');\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const askQuestion = (): void => {\n rl.question('You: ', async (input) => {\n const trimmed = input.trim();\n if (!trimmed || trimmed === 'exit' || trimmed === 'quit') {\n rl.close();\n cleanup();\n clack.outro('Goodbye');\n return;\n }\n\n const responsePromise = new Promise<string>((resolve) => {\n const handler = (event: any) => {\n os.removeListener('message:processed', handler);\n resolve(event.response.text);\n };\n os.on('message:processed', handler);\n });\n\n provider.simulateIncomingMessage('+cli-user', trimmed);\n\n try {\n const response = await responsePromise;\n console.log(`\\nAgent: ${response}\\n`);\n } catch (error: any) {\n console.log(`\\nError: ${error.message}\\n`);\n }\n\n askQuestion();\n });\n };\n\n rl.on('close', () => {\n cleanup();\n clack.outro('Goodbye');\n process.exit(0);\n });\n\n askQuestion();\n });\n}\n","import { Command } from 'commander';\nimport * as clack from '@clack/prompts';\nimport { readdir, cp, mkdir, access } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { existsSync } from 'node:fs';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nfunction getTemplatesDir(): string {\n // Walk up from __dirname to find templates/agents — works from both\n // dist/index.js (production bundle) and src/commands/init.ts (dev)\n let dir = __dirname;\n for (let i = 0; i < 5; i++) {\n const candidate = join(dir, 'templates', 'agents');\n if (existsSync(candidate)) return candidate;\n dir = dirname(dir);\n }\n throw new Error('Could not find templates directory. Ensure packages/cli/templates/agents/ exists.');\n}\n\nconst TEMPLATES = ['customer-support', 'sales', 'faq-bot'] as const;\ntype TemplateName = (typeof TEMPLATES)[number];\n\nasync function copyDir(src: string, dest: string): Promise<void> {\n await mkdir(dest, { recursive: true });\n const entries = await readdir(src, { withFileTypes: true });\n for (const entry of entries) {\n const srcPath = join(src, entry.name);\n const destPath = join(dest, entry.name);\n if (entry.isDirectory()) {\n await copyDir(srcPath, destPath);\n } else {\n await cp(srcPath, destPath);\n }\n }\n}\n\nasync function dirExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function runInit(templateArg?: string): Promise<void> {\n clack.intro('Operor — Initialize Agent');\n\n const templatesDir = getTemplatesDir();\n let template: TemplateName;\n\n if (templateArg && TEMPLATES.includes(templateArg as TemplateName)) {\n template = templateArg as TemplateName;\n } else if (templateArg === 'blank') {\n // Blank template: just create the directory structure\n const name = await clack.text({\n message: 'Agent name:',\n placeholder: 'my-agent',\n validate: (v) => (v.length === 0 ? 'Name is required' : undefined),\n });\n if (clack.isCancel(name)) { clack.cancel('Cancelled.'); process.exit(0); }\n\n const agentDir = join(process.cwd(), 'agents', name as string);\n if (await dirExists(agentDir)) {\n clack.log.error(`Directory already exists: agents/${name}`);\n process.exit(1);\n }\n\n await mkdir(agentDir, { recursive: true });\n\n // Copy defaults if available\n const defaultsDir = join(templatesDir, '_defaults');\n if (await dirExists(defaultsDir)) {\n const defaultsTarget = join(process.cwd(), 'agents', '_defaults');\n if (!(await dirExists(defaultsTarget))) {\n await copyDir(defaultsDir, defaultsTarget);\n clack.log.info('Created agents/_defaults/');\n }\n }\n\n clack.log.success(`Created blank agent at agents/${name}/`);\n clack.log.info('Add INSTRUCTIONS.md, IDENTITY.md, and SOUL.md to configure your agent.');\n clack.outro('Done!');\n return;\n } else {\n // Prompt user to choose a template\n const choice = await clack.select({\n message: 'Choose a template:',\n options: [\n { value: 'customer-support', label: 'Customer Support', hint: 'E-commerce support with Shopify' },\n { value: 'sales', label: 'Sales', hint: 'Lead qualification and demo booking' },\n { value: 'faq-bot', label: 'FAQ Bot', hint: 'Simple knowledge base Q&A' },\n { value: 'blank', label: 'Blank', hint: 'Empty agent directory' },\n ],\n });\n if (clack.isCancel(choice)) { clack.cancel('Cancelled.'); process.exit(0); }\n\n if (choice === 'blank') {\n await runInit('blank');\n return;\n }\n template = choice as TemplateName;\n }\n\n // Ask for agent name\n const name = await clack.text({\n message: 'Agent name:',\n placeholder: template,\n defaultValue: template,\n validate: (v) => (v.length === 0 ? 'Name is required' : undefined),\n });\n if (clack.isCancel(name)) { clack.cancel('Cancelled.'); process.exit(0); }\n\n const agentName = name as string;\n const agentDir = join(process.cwd(), 'agents', agentName);\n\n if (await dirExists(agentDir)) {\n clack.log.error(`Directory already exists: agents/${agentName}`);\n process.exit(1);\n }\n\n const templateDir = join(templatesDir, template);\n if (!(await dirExists(templateDir))) {\n clack.log.error(`Template not found: ${template}`);\n process.exit(1);\n }\n\n // Copy template files\n await copyDir(templateDir, agentDir);\n clack.log.success(`Created agent from \"${template}\" template at agents/${agentName}/`);\n\n // Copy defaults if they don't already exist\n const defaultsDir = join(templatesDir, '_defaults');\n if (await dirExists(defaultsDir)) {\n const defaultsTarget = join(process.cwd(), 'agents', '_defaults');\n if (!(await dirExists(defaultsTarget))) {\n await copyDir(defaultsDir, defaultsTarget);\n clack.log.info('Created agents/_defaults/');\n }\n }\n\n // Copy USER.md to workspace root if it doesn't exist\n // AgentLoader reads USER.md from the workspace root, not agents/\n const userMdSrc = join(templatesDir, '_defaults', 'USER.md');\n const userMdDest = join(process.cwd(), 'USER.md');\n if (await dirExists(userMdSrc) && !(await dirExists(userMdDest))) {\n await cp(userMdSrc, userMdDest);\n clack.log.info('Created USER.md');\n }\n\n clack.outro('Done! Edit the files in agents/' + agentName + '/ to customize your agent.');\n}\n\nexport function registerInitCommand(program: Command): void {\n program\n .command('init [template]')\n .description('Initialize a new agent from a template (customer-support, sales, faq-bot, blank)')\n .action(async (template?: string) => {\n await runInit(template);\n });\n}\n","import './log-timestamps.js';\nimport { Command } from 'commander';\nimport { configExists } from './config.js';\nimport { runSetup, runQuickSetup } from './setup.js';\nimport { startOperor } from './start.js';\n\nconst program = new Command();\n\nprogram\n .name('operor')\n .description('Operor - AI Agent Operating System')\n .version('0.1.0');\n\nprogram\n .command('setup')\n .description('Run the interactive setup wizard')\n .option('--quick', 'Quick setup with sensible defaults (3 questions)')\n .action(async (opts) => {\n if (opts.quick) {\n await runQuickSetup();\n } else {\n await runSetup();\n }\n await startOperor();\n });\n\nprogram\n .command('start')\n .description('Start Operor with existing configuration')\n .action(async () => {\n if (!configExists()) {\n console.error('No configuration found. Run \"operor setup\" first.');\n process.exit(1);\n }\n await startOperor();\n });\n\nprogram\n .command('status')\n .description('Show Operor configuration status')\n .action(async () => {\n const { runStatus } = await import('./commands/status.js');\n await runStatus();\n });\n\nprogram\n .command('doctor')\n .description('Validate Operor configuration and test connections')\n .action(async () => {\n const { runDoctor } = await import('./commands/doctor.js');\n await runDoctor();\n });\n\nprogram\n .command('test')\n .description('Run Operor test scenarios')\n .option('--csv <path>', 'Load test cases from a CSV file')\n .option('--tag <tag>', 'Filter test cases by tag')\n .option('--report <path>', 'Save JSON results to file')\n .option('--real', 'Use real skills instead of mocks')\n .option('--allow-writes', 'Allow write operations with real skills')\n .option('--dry-run', 'Real reads, mock writes')\n .action(async (opts) => {\n const { runTest } = await import('./commands/test.js');\n await runTest(opts);\n });\n\nprogram\n .command('test-suite <file>')\n .description('Run a test suite from a CSV or JSON file')\n .option('--strategy <type>', 'Evaluation strategy: exact, contains, semantic', 'contains')\n .option('--timeout <ms>', 'Per-test timeout in milliseconds', parseInt)\n .option('--parallel', 'Run tests in parallel')\n .option('--verbose', 'Show detailed output for failed tests')\n .option('--json', 'Output results as JSON')\n .option('--real', 'Use real skills instead of mocks')\n .option('--allow-writes', 'Allow write operations with real skills')\n .option('--dry-run', 'Real reads, mock writes')\n .option('--llm', 'Use LLM-based agent processing instead of pattern matcher')\n .action(async (file, opts) => {\n const { runTestSuite } = await import('./commands/test-suite.js');\n await runTestSuite(file, opts);\n });\n\nprogram\n .command('converse [scenario]')\n .description('Run multi-turn conversation test scenarios')\n .option('--file <path>', 'Load scenarios from a JSON file')\n .option('--turns <n>', 'Override max turns per scenario', parseInt)\n .option('--persona <style>', 'Override persona (polite|frustrated|confused|terse|verbose)')\n .option('--verbose', 'Show full conversation transcripts')\n .option('--json', 'Output results as JSON')\n .option('--real', 'Use real skills instead of mocks')\n .option('--allow-writes', 'Allow write operations with real skills')\n .option('--dry-run', 'Real reads, mock writes')\n .action(async (scenario, opts) => {\n const { runConverse } = await import('./commands/converse.js');\n await runConverse({ scenario, ...opts });\n });\n\nprogram\n .command('simulate')\n .description('Run pre-deployment simulation (test suites + conversation scenarios)')\n .option('--tests <files...>', 'CSV/JSON test suite files to include')\n .option('--scenarios <names...>', 'Scenario names to run (or \"all\" for built-in)')\n .option('--conversations <n>', 'Number of conversations to run (default: 10)', parseInt)\n .option('--strategy <type>', 'Evaluation strategy: exact, similarity, llm_judge', 'similarity')\n .option('--real', 'Use real skills instead of mocks')\n .option('--allow-writes', 'Allow write operations with real skills')\n .option('--dry-run', 'Real reads, mock writes')\n .option('--timeout <ms>', 'Per-test timeout in milliseconds', parseInt)\n .option('--parallel', 'Run tests in parallel')\n .option('--json', 'Output full report as JSON')\n .option('--report <file>', 'Save detailed JSON report to file')\n .action(async (opts) => {\n const { runSimulate } = await import('./commands/simulate.js');\n await runSimulate({ ...opts, output: opts.report });\n });\n\n// Knowledge Base commands\nimport { registerKBCommand } from './commands/kb.js';\nregisterKBCommand(program);\n\n// Analytics commands\nimport { registerAnalyticsCommand } from './commands/analytics.js';\nregisterAnalyticsCommand(program);\n\n// History commands\nimport { registerHistoryCommand } from './commands/history.js';\nregisterHistoryCommand(program);\n\n// Chat command\nimport { registerChatCommand } from './commands/chat.js';\nregisterChatCommand(program);\n\n// Init command\nimport { registerInitCommand } from './commands/init.js';\nregisterInitCommand(program);\n\nprogram\n .command('reset')\n .description('Delete all data (KB, memory, analytics, copilot, skills, auth) to start fresh')\n .option('--yes', 'Skip confirmation prompt')\n .option('--keep-config', 'Keep .env and mcp.json, only delete databases')\n .action(async (opts) => {\n const { runReset } = await import('./commands/reset.js');\n await runReset(opts);\n });\n\nprogram\n .command('vibe [action]')\n .description('AI-powered agent copilot for creating and customizing agents')\n .option('--agent <name>', 'Target a specific agent')\n .action(async (action, opts) => {\n const { runVibe } = await import('./commands/vibe.js');\n await runVibe({ action, agent: opts.agent });\n });\n\nconst configCmd = program.command('config').description('View and modify configuration');\nconfigCmd\n .command('show')\n .description('Show current config')\n .action(async () => {\n const { showConfig } = await import('./commands/config.js');\n showConfig();\n });\nconfigCmd\n .command('set <key> <value>')\n .description('Set a config value')\n .action(async (k, v) => {\n const { setConfigValue } = await import('./commands/config.js');\n setConfigValue(k, v);\n });\nconfigCmd\n .command('unset <key>')\n .description('Remove a config value')\n .action(async (k) => {\n const { unsetConfigValue } = await import('./commands/config.js');\n unsetConfigValue(k);\n });\n\n// Default action: setup if no config, otherwise start\nprogram.action(async () => {\n if (!configExists()) {\n await runSetup();\n }\n await startOperor();\n});\n\nprogram.parse();\n"],"mappings":"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"}
|