@chanl/cli 2.0.4 → 3.0.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.
Files changed (59) hide show
  1. package/dist/__tests__/agents.test.js +574 -0
  2. package/dist/__tests__/agents.test.js.map +1 -0
  3. package/dist/__tests__/auth.test.d.ts +2 -0
  4. package/dist/__tests__/auth.test.js +87 -0
  5. package/dist/__tests__/auth.test.js.map +1 -0
  6. package/dist/__tests__/calls.test.d.ts +2 -0
  7. package/dist/__tests__/calls.test.js +115 -0
  8. package/dist/__tests__/calls.test.js.map +1 -0
  9. package/dist/__tests__/chat.test.d.ts +2 -0
  10. package/dist/__tests__/chat.test.js +357 -0
  11. package/dist/__tests__/chat.test.js.map +1 -0
  12. package/dist/__tests__/cli-base.test.d.ts +2 -0
  13. package/dist/__tests__/cli-base.test.js +87 -0
  14. package/dist/__tests__/cli-base.test.js.map +1 -0
  15. package/dist/__tests__/cli-missing.test.d.ts +2 -0
  16. package/dist/__tests__/cli-missing.test.js +546 -0
  17. package/dist/__tests__/cli-missing.test.js.map +1 -0
  18. package/dist/__tests__/helpers.d.ts +234 -0
  19. package/dist/__tests__/helpers.js +314 -0
  20. package/dist/__tests__/helpers.js.map +1 -0
  21. package/dist/__tests__/mcp.test.d.ts +2 -0
  22. package/dist/__tests__/mcp.test.js +470 -0
  23. package/dist/__tests__/mcp.test.js.map +1 -0
  24. package/dist/__tests__/prompts.test.d.ts +2 -0
  25. package/dist/__tests__/prompts.test.js +227 -0
  26. package/dist/__tests__/prompts.test.js.map +1 -0
  27. package/dist/__tests__/scenarios.test.d.ts +2 -0
  28. package/dist/__tests__/scenarios.test.js +270 -0
  29. package/dist/__tests__/scenarios.test.js.map +1 -0
  30. package/dist/__tests__/tools.test.d.ts +2 -0
  31. package/dist/__tests__/tools.test.js +331 -0
  32. package/dist/__tests__/tools.test.js.map +1 -0
  33. package/dist/__tests__/toolsets.test.d.ts +2 -0
  34. package/dist/__tests__/toolsets.test.js +196 -0
  35. package/dist/__tests__/toolsets.test.js.map +1 -0
  36. package/dist/__tests__/workspaces.test.d.ts +2 -0
  37. package/dist/__tests__/workspaces.test.js +155 -0
  38. package/dist/__tests__/workspaces.test.js.map +1 -0
  39. package/dist/commands/agents.js +96 -6
  40. package/dist/commands/agents.js.map +1 -1
  41. package/dist/commands/chat.js +2 -2
  42. package/dist/commands/chat.js.map +1 -1
  43. package/dist/commands/config.js +24 -2
  44. package/dist/commands/config.js.map +1 -1
  45. package/dist/commands/memory.js +134 -1
  46. package/dist/commands/memory.js.map +1 -1
  47. package/dist/commands/prompts.js +148 -1
  48. package/dist/commands/prompts.js.map +1 -1
  49. package/dist/commands/scorecards.js +3 -3
  50. package/dist/commands/scorecards.js.map +1 -1
  51. package/dist/utils/config-store.d.ts +8 -0
  52. package/dist/utils/config-store.js +18 -1
  53. package/dist/utils/config-store.js.map +1 -1
  54. package/dist/utils/sdk-factory.js +15 -3
  55. package/dist/utils/sdk-factory.js.map +1 -1
  56. package/package.json +4 -4
  57. package/dist/__tests__/cli.test.js +0 -2308
  58. package/dist/__tests__/cli.test.js.map +0 -1
  59. /package/dist/__tests__/{cli.test.d.ts → agents.test.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/prompts.ts"],"sourcesContent":["import { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { readFileSync } from 'fs';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport {\n printError,\n printSuccess,\n printInfo,\n printBlank,\n printSimpleTable,\n printLabel,\n isJsonOutput,\n printJson,\n formatDate,\n} from '../utils/output.js';\n\n/**\n * Create the prompts command group\n */\nexport function createPromptsCommand(): Command {\n const prompts = new Command('prompts')\n .description('Manage prompt templates')\n .addHelpText(\n 'after',\n `\nWhat are Prompts?\n Prompts are reusable templates for AI agent instructions. They support\n variables, versioning, and categories for organizing across use cases.\n\nQuick Start:\n $ chanl prompts list # List all prompts\n $ chanl prompts get <id> # View prompt details\n $ chanl prompts create -f prompt.json # Create from JSON file\n $ chanl prompts update <id> -f data.json # Update a prompt\n $ chanl prompts delete <id> # Delete a prompt`\n );\n\n // prompts list\n prompts\n .command('list')\n .description('List all prompts')\n .option('-c, --category <category>', 'Filter by category (support, sales, onboarding, general)')\n .option('-s, --status <status>', 'Filter by status (active, draft, archived)')\n .option('--search <query>', 'Search by name or content')\n .option('-l, --limit <number>', 'Number of items per page', '20')\n .option('--page <number>', 'Page number', '1')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl prompts list # List all prompts\n $ chanl prompts list --category support # Filter by category\n $ chanl prompts list --status active # Only active prompts\n $ chanl prompts list --json # Output as JSON`\n )\n .action(handlePromptsList);\n\n // prompts get <id>\n prompts\n .command('get <id>')\n .description('Get prompt details')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl prompts get abc123 # Get prompt details\n $ chanl prompts get abc123 --json # Output as JSON`\n )\n .action(handlePromptsGet);\n\n // prompts create\n prompts\n .command('create')\n .description('Create a new prompt')\n .option('-f, --file <path>', 'Path to JSON file with prompt data')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl prompts create -f prompt.json # Create from file\n\nJSON file format:\n {\n \"name\": \"Support Greeting\",\n \"content\": \"Hello! How can I help you today?\",\n \"category\": \"support\",\n \"status\": \"active\",\n \"tags\": [\"greeting\", \"support\"]\n }`\n )\n .action(handlePromptsCreate);\n\n // prompts update <id>\n prompts\n .command('update <id>')\n .description('Update an existing prompt')\n .option('-f, --file <path>', 'Path to JSON file with update data')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl prompts update abc123 -f updates.json`\n )\n .action(handlePromptsUpdate);\n\n // prompts delete <id>\n prompts\n .command('delete <id>')\n .description('Delete a prompt')\n .option('-y, --yes', 'Skip confirmation prompt')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl prompts delete abc123\n $ chanl prompts delete abc123 --yes # Skip confirmation`\n )\n .action(handlePromptsDelete);\n\n return prompts;\n}\n\n/**\n * Format prompt status with color\n */\nfunction formatStatus(status?: string): string {\n switch (status) {\n case 'active':\n return chalk.green('active');\n case 'draft':\n return chalk.yellow('draft');\n case 'archived':\n return chalk.gray('archived');\n default:\n return chalk.gray(status || 'unknown');\n }\n}\n\n/**\n * Handle prompts list command\n */\nasync function handlePromptsList(options: {\n category?: string;\n status?: string;\n search?: string;\n limit: string;\n page: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching prompts...').start();\n\n try {\n const response = await sdk.prompts.list({\n category: options.category as any,\n status: options.status as any,\n search: options.search,\n limit: parseInt(options.limit, 10),\n page: parseInt(options.page, 10),\n });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch prompts', response.message);\n process.exitCode = 1;\n return;\n }\n\n const prompts = Array.isArray(response.data) ? response.data : [];\n\n if (isJsonOutput()) {\n printJson(prompts);\n return;\n }\n\n if (prompts.length === 0) {\n printInfo('No prompts found');\n printInfo(\"Use 'chanl prompts create -f prompt.json' to create a prompt\");\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Name', 'Category', 'Status', 'Version', 'Updated'],\n prompts.map((p: any) => [\n p.id.slice(-12),\n (p.name || 'Untitled').slice(0, 30),\n p.category || '-',\n formatStatus(p.status),\n String(p.version || '-'),\n formatDate(p.updatedAt || p.createdAt),\n ])\n );\n\n printBlank();\n printInfo(`Total: ${prompts.length} prompts`);\n } catch (error) {\n spinner.fail('Failed to fetch prompts');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle prompts get command\n */\nasync function handlePromptsGet(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching prompt...').start();\n\n try {\n const response = await sdk.prompts.get(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n const prompt = response.data;\n\n if (isJsonOutput()) {\n printJson(prompt);\n return;\n }\n\n printBlank();\n console.log(chalk.bold('Prompt Details:'));\n printLabel('ID', prompt.id);\n printLabel('Name', prompt.name);\n if (prompt.description) printLabel('Description', prompt.description);\n if (prompt.category) printLabel('Category', prompt.category);\n printLabel('Status', formatStatus(prompt.status));\n if (prompt.version) printLabel('Version', prompt.version.toString());\n if (prompt.tags && prompt.tags.length > 0) {\n printLabel('Tags', prompt.tags.join(', '));\n }\n if (prompt.createdAt) printLabel('Created', formatDate(prompt.createdAt));\n if (prompt.updatedAt) printLabel('Updated', formatDate(prompt.updatedAt));\n\n if (prompt.content) {\n printBlank();\n console.log(chalk.bold('Content:'));\n console.log(chalk.dim(prompt.content.slice(0, 500) + (prompt.content.length > 500 ? '...' : '')));\n }\n\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle prompts create command\n */\nasync function handlePromptsCreate(options: {\n file?: string;\n}): Promise<void> {\n if (!options.file) {\n printError('Missing required option', \"Use '-f <file>' to specify prompt data\");\n process.exitCode = 1;\n return;\n }\n\n const sdk = createSdk();\n if (!sdk) return;\n\n // Read and parse the file\n let promptData: any;\n try {\n const content = readFileSync(options.file, 'utf-8');\n promptData = JSON.parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Creating prompt...').start();\n\n try {\n const response = await sdk.prompts.create(promptData);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to create prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const prompt = response.data;\n printSuccess(`Prompt created: ${prompt.name}`);\n printLabel('ID', prompt.id);\n if (prompt.category) printLabel('Category', prompt.category);\n } catch (error) {\n spinner.fail('Failed to create prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle prompts update command\n */\nasync function handlePromptsUpdate(\n id: string,\n options: { file?: string }\n): Promise<void> {\n if (!options.file) {\n printError('Missing required option', \"Use '-f <file>' to specify update data\");\n process.exitCode = 1;\n return;\n }\n\n const sdk = createSdk();\n if (!sdk) return;\n\n // Read and parse the file\n let updateData: any;\n try {\n const content = readFileSync(options.file, 'utf-8');\n updateData = JSON.parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Updating prompt...').start();\n\n try {\n const response = await sdk.prompts.update(id, updateData);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to update prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const prompt = response.data;\n printSuccess(`Prompt updated: ${prompt.name}`);\n } catch (error) {\n spinner.fail('Failed to update prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle prompts delete command\n */\nasync function handlePromptsDelete(\n id: string,\n options: { yes?: boolean }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n if (!options.yes) {\n printInfo(`About to delete prompt: ${id}`);\n printInfo(\"Use '--yes' flag to skip this confirmation\");\n }\n\n const spinner = ora('Deleting prompt...').start();\n\n try {\n const response = await sdk.prompts.delete(id);\n\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to delete prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson({ success: true, deleted: id });\n return;\n }\n\n printSuccess(`Prompt deleted: ${id}`);\n } catch (error) {\n spinner.fail('Failed to delete prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/commands/prompts.ts"],"sourcesContent":["import { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { readFileSync } from 'fs';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport {\n printError,\n printSuccess,\n printInfo,\n printBlank,\n printSimpleTable,\n printLabel,\n isJsonOutput,\n printJson,\n formatDate,\n} from '../utils/output.js';\n\n/**\n * Create the prompts command group\n */\nexport function createPromptsCommand(): Command {\n const prompts = new Command('prompts')\n .description('Manage prompt templates')\n .addHelpText(\n 'after',\n `\nWhat are Prompts?\n Prompts are reusable templates for AI agent instructions. They support\n variables, versioning, and categories for organizing across use cases.\n\nQuick Start:\n $ chanl prompts list # List all prompts\n $ chanl prompts get <id> # View prompt details\n $ chanl prompts create -f prompt.json # Create from JSON file\n $ chanl prompts update <id> -f data.json # Update a prompt\n $ chanl prompts delete <id> # Delete a prompt`\n );\n\n // prompts list\n prompts\n .command('list')\n .description('List all prompts')\n .option('-c, --category <category>', 'Filter by category (support, sales, onboarding, general)')\n .option('-s, --status <status>', 'Filter by status (active, draft, archived)')\n .option('--search <query>', 'Search by name or content')\n .option('-l, --limit <number>', 'Number of items per page', '20')\n .option('--page <number>', 'Page number', '1')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl prompts list # List all prompts\n $ chanl prompts list --category support # Filter by category\n $ chanl prompts list --status active # Only active prompts\n $ chanl prompts list --json # Output as JSON`\n )\n .action(handlePromptsList);\n\n // prompts get <id>\n prompts\n .command('get <id>')\n .description('Get prompt details')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl prompts get abc123 # Get prompt details\n $ chanl prompts get abc123 --json # Output as JSON`\n )\n .action(handlePromptsGet);\n\n // prompts create\n prompts\n .command('create')\n .description('Create a new prompt')\n .option('-f, --file <path>', 'Path to JSON file with prompt data')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl prompts create -f prompt.json # Create from file\n\nJSON file format:\n {\n \"name\": \"Support Greeting\",\n \"content\": \"Hello! How can I help you today?\",\n \"category\": \"support\",\n \"status\": \"active\",\n \"tags\": [\"greeting\", \"support\"]\n }`\n )\n .action(handlePromptsCreate);\n\n // prompts update <id>\n prompts\n .command('update <id>')\n .description('Update an existing prompt')\n .option('-f, --file <path>', 'Path to JSON file with update data')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl prompts update abc123 -f updates.json`\n )\n .action(handlePromptsUpdate);\n\n // prompts delete <id>\n prompts\n .command('delete <id>')\n .description('Delete a prompt')\n .option('-y, --yes', 'Skip confirmation prompt')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl prompts delete abc123\n $ chanl prompts delete abc123 --yes # Skip confirmation`\n )\n .action(handlePromptsDelete);\n\n // prompts versions list <id>\n prompts\n .command('versions')\n .description('Prompt version operations')\n .addCommand(\n new Command('list')\n .argument('<id>', 'Prompt ID')\n .description('List version history for a prompt')\n .action(handlePromptsVersionsList)\n );\n\n // prompts revert <id>\n prompts\n .command('revert <id>')\n .description('Revert a prompt to a previous version')\n .requiredOption('--to-version <number>', 'Version number to revert to')\n .action(handlePromptsRevert);\n\n // prompts resolve <id>\n prompts\n .command('resolve <id>')\n .description('Resolve template variables in prompt content')\n .option('-f, --file <path>', 'JSON file with { \"variables\": { ... } }')\n .action(handlePromptsResolve);\n\n // prompts apply <id>\n prompts\n .command('apply <id>')\n .description('Apply a prompt to an agent')\n .requiredOption('-a, --agent <agentId>', 'Agent ID')\n .option('--sync', 'Sync agent to external platform after apply')\n .action(handlePromptsApply);\n\n return prompts;\n}\n\n/**\n * Format prompt status with color\n */\nfunction formatStatus(status?: string): string {\n switch (status) {\n case 'active':\n return chalk.green('active');\n case 'draft':\n return chalk.yellow('draft');\n case 'archived':\n return chalk.gray('archived');\n default:\n return chalk.gray(status || 'unknown');\n }\n}\n\n/**\n * Handle prompts list command\n */\nasync function handlePromptsList(options: {\n category?: string;\n status?: string;\n search?: string;\n limit: string;\n page: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching prompts...').start();\n\n try {\n const response = await sdk.prompts.list({\n category: options.category as any,\n status: options.status as any,\n search: options.search,\n limit: parseInt(options.limit, 10),\n page: parseInt(options.page, 10),\n });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch prompts', response.message);\n process.exitCode = 1;\n return;\n }\n\n const data = response.data as { prompts?: unknown[] } | unknown[] | undefined;\n const prompts = Array.isArray(data) ? data : (data?.prompts ?? []);\n\n if (isJsonOutput()) {\n printJson(prompts);\n return;\n }\n\n if (prompts.length === 0) {\n printInfo('No prompts found');\n printInfo(\"Use 'chanl prompts create -f prompt.json' to create a prompt\");\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Name', 'Category', 'Status', 'Version', 'Updated'],\n prompts.map((p: any) => [\n p.id.slice(-12),\n (p.name || 'Untitled').slice(0, 30),\n p.category || '-',\n formatStatus(p.status),\n String(p.version || '-'),\n formatDate(p.updatedAt || p.createdAt),\n ])\n );\n\n printBlank();\n printInfo(`Total: ${prompts.length} prompts`);\n } catch (error) {\n spinner.fail('Failed to fetch prompts');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle prompts get command\n */\nasync function handlePromptsGet(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching prompt...').start();\n\n try {\n const response = await sdk.prompts.get(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n const prompt = response.data;\n\n if (isJsonOutput()) {\n printJson(prompt);\n return;\n }\n\n printBlank();\n console.log(chalk.bold('Prompt Details:'));\n printLabel('ID', prompt.id);\n printLabel('Name', prompt.name);\n if (prompt.description) printLabel('Description', prompt.description);\n if (prompt.category) printLabel('Category', prompt.category);\n printLabel('Status', formatStatus(prompt.status));\n if (prompt.version) printLabel('Version', prompt.version.toString());\n if (prompt.tags && prompt.tags.length > 0) {\n printLabel('Tags', prompt.tags.join(', '));\n }\n if (prompt.createdAt) printLabel('Created', formatDate(prompt.createdAt));\n if (prompt.updatedAt) printLabel('Updated', formatDate(prompt.updatedAt));\n\n if (prompt.content) {\n printBlank();\n console.log(chalk.bold('Content:'));\n console.log(chalk.dim(prompt.content.slice(0, 500) + (prompt.content.length > 500 ? '...' : '')));\n }\n\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle prompts create command\n */\nasync function handlePromptsCreate(options: {\n file?: string;\n}): Promise<void> {\n if (!options.file) {\n printError('Missing required option', \"Use '-f <file>' to specify prompt data\");\n process.exitCode = 1;\n return;\n }\n\n const sdk = createSdk();\n if (!sdk) return;\n\n // Read and parse the file\n let promptData: any;\n try {\n const content = readFileSync(options.file, 'utf-8');\n promptData = JSON.parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Creating prompt...').start();\n\n try {\n const response = await sdk.prompts.create(promptData);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to create prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const prompt = response.data;\n printSuccess(`Prompt created: ${prompt.name}`);\n printLabel('ID', prompt.id);\n if (prompt.category) printLabel('Category', prompt.category);\n } catch (error) {\n spinner.fail('Failed to create prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle prompts update command\n */\nasync function handlePromptsUpdate(\n id: string,\n options: { file?: string }\n): Promise<void> {\n if (!options.file) {\n printError('Missing required option', \"Use '-f <file>' to specify update data\");\n process.exitCode = 1;\n return;\n }\n\n const sdk = createSdk();\n if (!sdk) return;\n\n // Read and parse the file\n let updateData: any;\n try {\n const content = readFileSync(options.file, 'utf-8');\n updateData = JSON.parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Updating prompt...').start();\n\n try {\n const response = await sdk.prompts.update(id, updateData);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to update prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const prompt = response.data;\n printSuccess(`Prompt updated: ${prompt.name}`);\n } catch (error) {\n spinner.fail('Failed to update prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle prompts delete command\n */\nasync function handlePromptsDelete(\n id: string,\n options: { yes?: boolean }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n if (!options.yes) {\n printInfo(`About to delete prompt: ${id}`);\n printInfo(\"Use '--yes' flag to skip this confirmation\");\n }\n\n const spinner = ora('Deleting prompt...').start();\n\n try {\n const response = await sdk.prompts.delete(id);\n\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to delete prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson({ success: true, deleted: id });\n return;\n }\n\n printSuccess(`Prompt deleted: ${id}`);\n } catch (error) {\n spinner.fail('Failed to delete prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\nasync function handlePromptsVersionsList(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching versions...').start();\n\n try {\n const response = await sdk.prompts.getVersions(id);\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch versions', response.message);\n process.exitCode = 1;\n return;\n }\n\n const versions = Array.isArray(response.data) ? response.data : [];\n\n if (isJsonOutput()) {\n printJson(versions);\n return;\n }\n\n if (versions.length === 0) {\n printInfo('No versions found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['Version', 'Name', 'Active', 'Created'],\n versions.map((v: { version?: number; versionName?: string; isActive?: boolean; createdAt?: string }) => [\n String(v.version ?? '-'),\n (v.versionName || '-').slice(0, 30),\n v.isActive ? chalk.green('yes') : chalk.gray('no'),\n formatDate(v.createdAt),\n ])\n );\n } catch (error) {\n spinner.fail('Failed to fetch versions');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\nasync function handlePromptsRevert(\n id: string,\n options: { toVersion: string }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const version = parseInt(options.toVersion, 10);\n if (Number.isNaN(version)) {\n printError('Invalid version', 'Version must be a number');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Reverting prompt...').start();\n\n try {\n const response = await sdk.prompts.revert(id, { version });\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to revert prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n printSuccess(`Prompt reverted to version ${version}`);\n printLabel('ID', response.data.id);\n printLabel('Current version', String(response.data.version ?? version));\n } catch (error) {\n spinner.fail('Failed to revert prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\nasync function handlePromptsResolve(\n id: string,\n options: { file?: string }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n let variables: Record<string, string> | undefined;\n if (options.file) {\n try {\n const content = readFileSync(options.file, 'utf-8');\n const parsed = JSON.parse(content);\n variables = parsed.variables ?? parsed;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n }\n\n const spinner = ora('Resolving variables...').start();\n\n try {\n const response = await sdk.prompts.resolve(id, variables ? { variables } : undefined);\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to resolve prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n printBlank();\n console.log(chalk.bold('Resolved content:'));\n console.log(response.data.content);\n if (response.data.unresolvedVariables?.length) {\n printBlank();\n printInfo(`Unresolved: ${response.data.unresolvedVariables.join(', ')}`);\n }\n } catch (error) {\n spinner.fail('Failed to resolve prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\nasync function handlePromptsApply(\n id: string,\n options: { agent: string; sync?: boolean }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Applying prompt to agent...').start();\n\n try {\n const response = await sdk.prompts.apply(id, {\n agentId: options.agent,\n syncToPlatform: options.sync,\n });\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to apply prompt', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data ?? { success: true });\n return;\n }\n\n printSuccess(`Prompt applied to agent ${options.agent}`);\n } catch (error) {\n spinner.fail('Failed to apply prompt');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n"],"mappings":"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","names":[]}
@@ -97,12 +97,12 @@ Examples:
97
97
  $ chanl scorecards delete abc123 # Delete with confirmation
98
98
  $ chanl scorecards delete abc123 --yes # Delete without confirmation`
99
99
  ).action(handleScorecardsDelete);
100
- scorecards.command("evaluate <callId>").description("Evaluate a call with a scorecard").requiredOption("-s, --scorecard <id>", "Scorecard ID to use").option("--force", "Force re-evaluation even if already done").addHelpText(
100
+ scorecards.command("evaluate <callId>").description("Evaluate an interaction with a scorecard").requiredOption("-s, --scorecard <id>", "Scorecard ID to use").option("--async", "Process evaluation asynchronously via queue").addHelpText(
101
101
  "after",
102
102
  `
103
103
  Examples:
104
104
  $ chanl scorecards evaluate call123 -s scorecard456
105
- $ chanl scorecards evaluate call123 -s scorecard456 --force`
105
+ $ chanl scorecards evaluate call123 -s scorecard456 --async`
106
106
  ).action(handleScorecardsEvaluate);
107
107
  scorecards.command("results <callId>").description("View evaluation results for a call").option("-s, --scorecard <id>", "Filter by scorecard ID").addHelpText(
108
108
  "after",
@@ -390,7 +390,7 @@ async function handleScorecardsEvaluate(callId, options) {
390
390
  try {
391
391
  const response = await sdk.scorecard.evaluate(callId, {
392
392
  scorecardId: options.scorecard,
393
- force: options.force
393
+ async: options.async
394
394
  });
395
395
  spinner.stop();
396
396
  if (!response.success || !response.data) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/scorecards.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { readFile } from 'fs/promises';\nimport { confirm } from '@inquirer/prompts';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport type {\n Scorecard,\n ScorecardResult,\n ScorecardCategory,\n ScorecardCriteria,\n CreateScorecardRequest,\n UpdateScorecardRequest,\n ScorecardStatus,\n} from '@chanl/sdk';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport {\n printSuccess,\n printError,\n printInfo,\n printWarning,\n printLabel,\n printBlank,\n printSimpleTable,\n isJsonOutput,\n printJson,\n formatDate,\n} from '../utils/output.js';\n\n/**\n * Create the scorecards command group\n */\nexport function createScorecardsCommand(): Command {\n const scorecards = new Command('scorecards')\n .description('Manage scorecards for call evaluation')\n .addHelpText(\n 'after',\n `\nWhat are Scorecards?\n Scorecards define criteria for evaluating call quality. Each scorecard\n contains categories and criteria that are used to score calls.\n\nQuick Start:\n $ chanl scorecards list # List all scorecards\n $ chanl scorecards get <id> # View scorecard details\n $ chanl scorecards create -f scorecard.json # Create from file\n $ chanl scorecards evaluate <callId> -s <scorecardId> # Evaluate a call\n\nWorkflow:\n 1. Create a scorecard with categories and criteria\n 2. Import or record a call\n 3. Evaluate the call against the scorecard\n 4. View results with 'results <callId>'`\n );\n\n // scorecards list\n scorecards\n .command('list')\n .description('List scorecards')\n .option('-s, --status <status>', 'Filter by status (active, inactive, draft)')\n .option('-l, --limit <number>', 'Items per page', '20')\n .option('-p, --page <number>', 'Page number', '1')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards list # List all scorecards\n $ chanl scorecards list --status active # Only active scorecards\n $ chanl scorecards list --json # Output as JSON`\n )\n .action(handleScorecardsList);\n\n // scorecards get <id>\n scorecards\n .command('get <id>')\n .description('Get scorecard details')\n .option('-c, --categories', 'Include categories and criteria')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards get abc123 # Get scorecard details\n $ chanl scorecards get abc123 --categories # Include categories\n $ chanl scorecards get abc123 --json # Output as JSON`\n )\n .action(handleScorecardsGet);\n\n // scorecards create\n scorecards\n .command('create')\n .description('Create a new scorecard')\n .option('-f, --file <path>', 'JSON file with scorecard definition')\n .option('-n, --name <name>', 'Scorecard name')\n .option('-d, --description <desc>', 'Scorecard description')\n .option('-s, --status <status>', 'Status (active, inactive, draft)', 'draft')\n .addHelpText(\n 'after',\n `\nExamples:\n # Create from JSON file\n $ chanl scorecards create -f scorecard.json\n\n # Create with basic options\n $ chanl scorecards create -n \"Quality Check\" -d \"Basic quality scorecard\"\n\nJSON file format:\n {\n \"name\": \"Quality Scorecard\",\n \"description\": \"Evaluates call quality\",\n \"status\": \"active\",\n \"categories\": [\n {\n \"name\": \"Communication\",\n \"weight\": 50,\n \"criteria\": [\n {\n \"name\": \"Greeting\",\n \"type\": \"prompt\",\n \"settings\": { \"prompt\": \"Did the agent greet the customer?\" }\n }\n ]\n }\n ]\n }`\n )\n .action(handleScorecardsCreate);\n\n // scorecards update <id>\n scorecards\n .command('update <id>')\n .description('Update a scorecard')\n .option('-f, --file <path>', 'JSON file with updates')\n .option('-n, --name <name>', 'New name')\n .option('-d, --description <desc>', 'New description')\n .option('-s, --status <status>', 'New status (active, inactive, draft)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards update abc123 -s active # Activate scorecard\n $ chanl scorecards update abc123 -n \"New Name\" # Update name\n $ chanl scorecards update abc123 -f updates.json # Update from file`\n )\n .action(handleScorecardsUpdate);\n\n // scorecards delete <id>\n scorecards\n .command('delete <id>')\n .description('Delete a scorecard')\n .option('-y, --yes', 'Skip confirmation prompt')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards delete abc123 # Delete with confirmation\n $ chanl scorecards delete abc123 --yes # Delete without confirmation`\n )\n .action(handleScorecardsDelete);\n\n // scorecards evaluate <callId>\n scorecards\n .command('evaluate <callId>')\n .description('Evaluate a call with a scorecard')\n .requiredOption('-s, --scorecard <id>', 'Scorecard ID to use')\n .option('--force', 'Force re-evaluation even if already done')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards evaluate call123 -s scorecard456\n $ chanl scorecards evaluate call123 -s scorecard456 --force`\n )\n .action(handleScorecardsEvaluate);\n\n // scorecards results <callId>\n scorecards\n .command('results <callId>')\n .description('View evaluation results for a call')\n .option('-s, --scorecard <id>', 'Filter by scorecard ID')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards results call123 # All results for call\n $ chanl scorecards results call123 -s scorecard456 # Results for specific scorecard\n $ chanl scorecards results call123 --json # Output as JSON`\n )\n .action(handleScorecardsResults);\n\n // scorecards categories <scorecardId>\n scorecards\n .command('categories <scorecardId>')\n .description('List categories in a scorecard')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards categories abc123 # List categories\n $ chanl scorecards categories abc123 --json # Output as JSON`\n )\n .action(handleScorecardsCategories);\n\n // scorecards criteria <categoryId>\n scorecards\n .command('criteria <categoryId>')\n .description('List criteria in a category')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards criteria cat123 # List criteria\n $ chanl scorecards criteria cat123 --json # Output as JSON`\n )\n .action(handleScorecardsCriteria);\n\n return scorecards;\n}\n\n/**\n * Format status with color\n */\nfunction formatStatus(status?: string): string {\n switch (status) {\n case 'active':\n return chalk.green('active');\n case 'inactive':\n return chalk.gray('inactive');\n case 'draft':\n return chalk.yellow('draft');\n default:\n return chalk.gray(status || 'unknown');\n }\n}\n\n/**\n * Format score with color\n */\nfunction formatScore(score?: number): string {\n if (score === undefined || score === null) return '-';\n if (score >= 80) return chalk.green(`${score.toFixed(1)}%`);\n if (score >= 60) return chalk.yellow(`${score.toFixed(1)}%`);\n return chalk.red(`${score.toFixed(1)}%`);\n}\n\n/**\n * Handle scorecards list command\n */\nasync function handleScorecardsList(options: {\n status?: string;\n limit: string;\n page: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching scorecards...').start();\n\n try {\n const response = await sdk.scorecard.list({\n status: options.status as ScorecardStatus | undefined,\n limit: parseInt(options.limit, 10),\n page: parseInt(options.page, 10),\n });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch scorecards', response.message);\n process.exitCode = 1;\n return;\n }\n\n const { scorecards, pagination } = response.data;\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n if (scorecards.length === 0) {\n printInfo('No scorecards found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Name', 'Status', 'Categories', 'Created'],\n scorecards.map((s: Scorecard) => [\n s.id.slice(-12),\n s.name.slice(0, 30),\n formatStatus(s.status),\n (s.categories?.length || 0).toString(),\n formatDate(s.createdAt),\n ])\n );\n\n printBlank();\n if (pagination) {\n printInfo(`Total: ${pagination.total} scorecards (Page ${pagination.page} of ${pagination.totalPages})`);\n }\n } catch (error) {\n spinner.fail('Failed to fetch scorecards');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards get command\n */\nasync function handleScorecardsGet(\n id: string,\n options: { categories?: boolean }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching scorecard...').start();\n\n try {\n const response = await sdk.scorecard.get(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch scorecard', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const scorecard = response.data;\n\n printBlank();\n console.log(chalk.bold('Scorecard Details:'));\n console.log(` ID: ${scorecard.id}`);\n console.log(` Name: ${scorecard.name}`);\n console.log(` Status: ${formatStatus(scorecard.status)}`);\n if (scorecard.description) {\n console.log(` Description: ${scorecard.description}`);\n }\n if (scorecard.version) {\n console.log(` Version: ${scorecard.version}`);\n }\n console.log(` Created: ${formatDate(scorecard.createdAt)}`);\n if (scorecard.updatedAt) {\n console.log(` Updated: ${formatDate(scorecard.updatedAt)}`);\n }\n\n if (options.categories && scorecard.categories && scorecard.categories.length > 0) {\n console.log(chalk.bold('\\n Categories:'));\n for (const cat of scorecard.categories) {\n console.log(`\\n ${chalk.cyan(cat.name)} (weight: ${cat.weight}%)`);\n if (cat.criteria && cat.criteria.length > 0) {\n for (const crit of cat.criteria) {\n console.log(` - ${crit.name} [${crit.type}]`);\n }\n }\n }\n }\n\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch scorecard');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards create command\n */\nasync function handleScorecardsCreate(options: {\n file?: string;\n name?: string;\n description?: string;\n status?: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n let createRequest: CreateScorecardRequest;\n\n if (options.file) {\n try {\n const content = await readFile(options.file, 'utf-8');\n createRequest = JSON.parse(content) as CreateScorecardRequest;\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n } else if (options.name) {\n createRequest = {\n name: options.name,\n description: options.description,\n status: (options.status as ScorecardStatus) || 'draft',\n };\n } else {\n printError('Missing required options', 'Provide --file or --name');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Creating scorecard...').start();\n\n try {\n const response = await sdk.scorecard.create(createRequest);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to create scorecard', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const scorecard = response.data;\n\n printBlank();\n printSuccess('Scorecard created successfully');\n printLabel('ID', scorecard.id);\n printLabel('Name', scorecard.name);\n printLabel('Status', formatStatus(scorecard.status));\n printBlank();\n printInfo(`Run 'chanl scorecards get ${scorecard.id}' to view details`);\n printBlank();\n } catch (error) {\n spinner.fail('Failed to create scorecard');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards update command\n */\nasync function handleScorecardsUpdate(\n id: string,\n options: {\n file?: string;\n name?: string;\n description?: string;\n status?: string;\n }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n let updateRequest: UpdateScorecardRequest;\n\n if (options.file) {\n try {\n const content = await readFile(options.file, 'utf-8');\n updateRequest = JSON.parse(content) as UpdateScorecardRequest;\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n } else {\n updateRequest = {};\n if (options.name) updateRequest.name = options.name;\n if (options.description) updateRequest.description = options.description;\n if (options.status) updateRequest.status = options.status as ScorecardStatus;\n\n if (Object.keys(updateRequest).length === 0) {\n printError('No updates provided', 'Provide --file or update options');\n process.exitCode = 1;\n return;\n }\n }\n\n const spinner = ora('Updating scorecard...').start();\n\n try {\n const response = await sdk.scorecard.update(id, updateRequest);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to update scorecard', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const scorecard = response.data;\n\n printBlank();\n printSuccess('Scorecard updated successfully');\n printLabel('ID', scorecard.id);\n printLabel('Name', scorecard.name);\n printLabel('Status', formatStatus(scorecard.status));\n printBlank();\n } catch (error) {\n spinner.fail('Failed to update scorecard');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards delete command\n */\nasync function handleScorecardsDelete(\n id: string,\n options: { yes?: boolean }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n if (!options.yes) {\n printWarning(`This will permanently delete scorecard ${id.slice(-12)}`);\n const confirmed = await confirm({ message: 'Are you sure?', default: false });\n if (!confirmed) {\n printInfo('Cancelled');\n return;\n }\n }\n\n const spinner = ora('Deleting scorecard...').start();\n\n try {\n const response = await sdk.scorecard.delete(id);\n\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to delete scorecard', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson({ deleted: true, scorecardId: id });\n return;\n }\n\n printSuccess(`Scorecard ${id.slice(-12)} deleted successfully`);\n } catch (error) {\n spinner.fail('Failed to delete scorecard');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards evaluate command\n */\nasync function handleScorecardsEvaluate(\n callId: string,\n options: { scorecard: string; force?: boolean }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Triggering evaluation...').start();\n\n try {\n const response = await sdk.scorecard.evaluate(callId, {\n scorecardId: options.scorecard,\n force: options.force,\n });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to trigger evaluation', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const { resultId, status } = response.data;\n\n printBlank();\n if (status === 'completed') {\n printSuccess('Evaluation completed');\n } else {\n printSuccess('Evaluation queued');\n }\n if (resultId) {\n printLabel('Result ID', resultId);\n }\n printLabel('Status', status);\n printBlank();\n printInfo(`Run 'chanl scorecards results ${callId}' to view results`);\n printBlank();\n } catch (error) {\n spinner.fail('Failed to trigger evaluation');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards results command\n */\nasync function handleScorecardsResults(\n callId: string,\n options: { scorecard?: string }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching results...').start();\n\n try {\n const response = await sdk.scorecard.getResultsByCall(callId);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch results', response.message);\n process.exitCode = 1;\n return;\n }\n\n let results = response.data.results;\n\n // Filter by scorecard if specified\n if (options.scorecard && Array.isArray(results)) {\n results = results.filter((r: ScorecardResult) => r.scorecardId === options.scorecard);\n }\n\n if (isJsonOutput()) {\n printJson(results);\n return;\n }\n\n if (!results || results.length === 0) {\n printInfo('No evaluation results found for this call');\n printInfo(`Run 'chanl scorecards evaluate ${callId} -s <scorecardId>' to evaluate`);\n return;\n }\n\n const resultArray = results;\n\n printBlank();\n console.log(chalk.bold(`Evaluation Results for Call ${callId.slice(-12)}`));\n console.log(chalk.dim('-'.repeat(60)));\n\n for (const result of resultArray) {\n console.log(chalk.bold(`\\nScorecard: ${result.scorecardId?.slice(-12) || 'Unknown'}`));\n console.log(` Overall Score: ${formatScore(result.overallScore)}`);\n console.log(` Status: ${result.status || 'completed'}`);\n if (result.createdAt) {\n console.log(` Evaluated: ${formatDate(result.createdAt)}`);\n }\n\n if (result.categoryScores && Object.keys(result.categoryScores).length > 0) {\n console.log(chalk.bold('\\n Category Scores:'));\n for (const [categoryName, score] of Object.entries(result.categoryScores)) {\n console.log(` ${categoryName}: ${formatScore(score)}`);\n }\n }\n\n if (result.llmAnalysis?.summary) {\n console.log(chalk.bold('\\n Summary:'));\n console.log(` ${result.llmAnalysis.summary}`);\n }\n\n if (result.llmAnalysis?.improvementSuggestions && result.llmAnalysis.improvementSuggestions.length > 0) {\n console.log(chalk.bold('\\n Improvement Suggestions:'));\n for (const suggestion of result.llmAnalysis.improvementSuggestions) {\n console.log(` - ${suggestion}`);\n }\n }\n }\n\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch results');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards categories command\n */\nasync function handleScorecardsCategories(scorecardId: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching categories...').start();\n\n try {\n const response = await sdk.scorecard.listCategories(scorecardId);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch categories', response.message);\n process.exitCode = 1;\n return;\n }\n\n const categories = response.data.categories;\n\n if (isJsonOutput()) {\n printJson(categories);\n return;\n }\n\n if (!categories || categories.length === 0) {\n printInfo('No categories found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Name', 'Weight', 'Criteria'],\n categories.map((c: ScorecardCategory) => [\n c.id.slice(-12),\n c.name.slice(0, 30),\n `${c.weight}%`,\n (c.criteria?.length || 0).toString(),\n ])\n );\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch categories');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards criteria command\n */\nasync function handleScorecardsCriteria(categoryId: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching criteria...').start();\n\n try {\n const response = await sdk.scorecard.listCriteria(categoryId);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch criteria', response.message);\n process.exitCode = 1;\n return;\n }\n\n const criteria = response.data.criteria;\n\n if (isJsonOutput()) {\n printJson(criteria);\n return;\n }\n\n if (!criteria || criteria.length === 0) {\n printInfo('No criteria found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Name', 'Type', 'Order', 'Active'],\n criteria.map((c: ScorecardCriteria) => [\n c.id.slice(-12),\n c.name.slice(0, 25),\n c.type,\n c.order.toString(),\n c.isActive ? chalk.green('yes') : chalk.gray('no'),\n ])\n );\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch criteria');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/commands/scorecards.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { readFile } from 'fs/promises';\nimport { confirm } from '@inquirer/prompts';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport type {\n Scorecard,\n ScorecardResult,\n ScorecardCategory,\n ScorecardCriteria,\n CreateScorecardRequest,\n UpdateScorecardRequest,\n ScorecardStatus,\n} from '@chanl/sdk';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport {\n printSuccess,\n printError,\n printInfo,\n printWarning,\n printLabel,\n printBlank,\n printSimpleTable,\n isJsonOutput,\n printJson,\n formatDate,\n} from '../utils/output.js';\n\n/**\n * Create the scorecards command group\n */\nexport function createScorecardsCommand(): Command {\n const scorecards = new Command('scorecards')\n .description('Manage scorecards for call evaluation')\n .addHelpText(\n 'after',\n `\nWhat are Scorecards?\n Scorecards define criteria for evaluating call quality. Each scorecard\n contains categories and criteria that are used to score calls.\n\nQuick Start:\n $ chanl scorecards list # List all scorecards\n $ chanl scorecards get <id> # View scorecard details\n $ chanl scorecards create -f scorecard.json # Create from file\n $ chanl scorecards evaluate <callId> -s <scorecardId> # Evaluate a call\n\nWorkflow:\n 1. Create a scorecard with categories and criteria\n 2. Import or record a call\n 3. Evaluate the call against the scorecard\n 4. View results with 'results <callId>'`\n );\n\n // scorecards list\n scorecards\n .command('list')\n .description('List scorecards')\n .option('-s, --status <status>', 'Filter by status (active, inactive, draft)')\n .option('-l, --limit <number>', 'Items per page', '20')\n .option('-p, --page <number>', 'Page number', '1')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards list # List all scorecards\n $ chanl scorecards list --status active # Only active scorecards\n $ chanl scorecards list --json # Output as JSON`\n )\n .action(handleScorecardsList);\n\n // scorecards get <id>\n scorecards\n .command('get <id>')\n .description('Get scorecard details')\n .option('-c, --categories', 'Include categories and criteria')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards get abc123 # Get scorecard details\n $ chanl scorecards get abc123 --categories # Include categories\n $ chanl scorecards get abc123 --json # Output as JSON`\n )\n .action(handleScorecardsGet);\n\n // scorecards create\n scorecards\n .command('create')\n .description('Create a new scorecard')\n .option('-f, --file <path>', 'JSON file with scorecard definition')\n .option('-n, --name <name>', 'Scorecard name')\n .option('-d, --description <desc>', 'Scorecard description')\n .option('-s, --status <status>', 'Status (active, inactive, draft)', 'draft')\n .addHelpText(\n 'after',\n `\nExamples:\n # Create from JSON file\n $ chanl scorecards create -f scorecard.json\n\n # Create with basic options\n $ chanl scorecards create -n \"Quality Check\" -d \"Basic quality scorecard\"\n\nJSON file format:\n {\n \"name\": \"Quality Scorecard\",\n \"description\": \"Evaluates call quality\",\n \"status\": \"active\",\n \"categories\": [\n {\n \"name\": \"Communication\",\n \"weight\": 50,\n \"criteria\": [\n {\n \"name\": \"Greeting\",\n \"type\": \"prompt\",\n \"settings\": { \"prompt\": \"Did the agent greet the customer?\" }\n }\n ]\n }\n ]\n }`\n )\n .action(handleScorecardsCreate);\n\n // scorecards update <id>\n scorecards\n .command('update <id>')\n .description('Update a scorecard')\n .option('-f, --file <path>', 'JSON file with updates')\n .option('-n, --name <name>', 'New name')\n .option('-d, --description <desc>', 'New description')\n .option('-s, --status <status>', 'New status (active, inactive, draft)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards update abc123 -s active # Activate scorecard\n $ chanl scorecards update abc123 -n \"New Name\" # Update name\n $ chanl scorecards update abc123 -f updates.json # Update from file`\n )\n .action(handleScorecardsUpdate);\n\n // scorecards delete <id>\n scorecards\n .command('delete <id>')\n .description('Delete a scorecard')\n .option('-y, --yes', 'Skip confirmation prompt')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards delete abc123 # Delete with confirmation\n $ chanl scorecards delete abc123 --yes # Delete without confirmation`\n )\n .action(handleScorecardsDelete);\n\n // scorecards evaluate <callId>\n scorecards\n .command('evaluate <callId>')\n .description('Evaluate an interaction with a scorecard')\n .requiredOption('-s, --scorecard <id>', 'Scorecard ID to use')\n .option('--async', 'Process evaluation asynchronously via queue')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards evaluate call123 -s scorecard456\n $ chanl scorecards evaluate call123 -s scorecard456 --async`\n )\n .action(handleScorecardsEvaluate);\n\n // scorecards results <callId>\n scorecards\n .command('results <callId>')\n .description('View evaluation results for a call')\n .option('-s, --scorecard <id>', 'Filter by scorecard ID')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards results call123 # All results for call\n $ chanl scorecards results call123 -s scorecard456 # Results for specific scorecard\n $ chanl scorecards results call123 --json # Output as JSON`\n )\n .action(handleScorecardsResults);\n\n // scorecards categories <scorecardId>\n scorecards\n .command('categories <scorecardId>')\n .description('List categories in a scorecard')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards categories abc123 # List categories\n $ chanl scorecards categories abc123 --json # Output as JSON`\n )\n .action(handleScorecardsCategories);\n\n // scorecards criteria <categoryId>\n scorecards\n .command('criteria <categoryId>')\n .description('List criteria in a category')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl scorecards criteria cat123 # List criteria\n $ chanl scorecards criteria cat123 --json # Output as JSON`\n )\n .action(handleScorecardsCriteria);\n\n return scorecards;\n}\n\n/**\n * Format status with color\n */\nfunction formatStatus(status?: string): string {\n switch (status) {\n case 'active':\n return chalk.green('active');\n case 'inactive':\n return chalk.gray('inactive');\n case 'draft':\n return chalk.yellow('draft');\n default:\n return chalk.gray(status || 'unknown');\n }\n}\n\n/**\n * Format score with color\n */\nfunction formatScore(score?: number): string {\n if (score === undefined || score === null) return '-';\n if (score >= 80) return chalk.green(`${score.toFixed(1)}%`);\n if (score >= 60) return chalk.yellow(`${score.toFixed(1)}%`);\n return chalk.red(`${score.toFixed(1)}%`);\n}\n\n/**\n * Handle scorecards list command\n */\nasync function handleScorecardsList(options: {\n status?: string;\n limit: string;\n page: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching scorecards...').start();\n\n try {\n const response = await sdk.scorecard.list({\n status: options.status as ScorecardStatus | undefined,\n limit: parseInt(options.limit, 10),\n page: parseInt(options.page, 10),\n });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch scorecards', response.message);\n process.exitCode = 1;\n return;\n }\n\n const { scorecards, pagination } = response.data;\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n if (scorecards.length === 0) {\n printInfo('No scorecards found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Name', 'Status', 'Categories', 'Created'],\n scorecards.map((s: Scorecard) => [\n s.id.slice(-12),\n s.name.slice(0, 30),\n formatStatus(s.status),\n (s.categories?.length || 0).toString(),\n formatDate(s.createdAt),\n ])\n );\n\n printBlank();\n if (pagination) {\n printInfo(`Total: ${pagination.total} scorecards (Page ${pagination.page} of ${pagination.totalPages})`);\n }\n } catch (error) {\n spinner.fail('Failed to fetch scorecards');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards get command\n */\nasync function handleScorecardsGet(\n id: string,\n options: { categories?: boolean }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching scorecard...').start();\n\n try {\n const response = await sdk.scorecard.get(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch scorecard', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const scorecard = response.data;\n\n printBlank();\n console.log(chalk.bold('Scorecard Details:'));\n console.log(` ID: ${scorecard.id}`);\n console.log(` Name: ${scorecard.name}`);\n console.log(` Status: ${formatStatus(scorecard.status)}`);\n if (scorecard.description) {\n console.log(` Description: ${scorecard.description}`);\n }\n if (scorecard.version) {\n console.log(` Version: ${scorecard.version}`);\n }\n console.log(` Created: ${formatDate(scorecard.createdAt)}`);\n if (scorecard.updatedAt) {\n console.log(` Updated: ${formatDate(scorecard.updatedAt)}`);\n }\n\n if (options.categories && scorecard.categories && scorecard.categories.length > 0) {\n console.log(chalk.bold('\\n Categories:'));\n for (const cat of scorecard.categories) {\n console.log(`\\n ${chalk.cyan(cat.name)} (weight: ${cat.weight}%)`);\n if (cat.criteria && cat.criteria.length > 0) {\n for (const crit of cat.criteria) {\n console.log(` - ${crit.name} [${crit.type}]`);\n }\n }\n }\n }\n\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch scorecard');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards create command\n */\nasync function handleScorecardsCreate(options: {\n file?: string;\n name?: string;\n description?: string;\n status?: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n let createRequest: CreateScorecardRequest;\n\n if (options.file) {\n try {\n const content = await readFile(options.file, 'utf-8');\n createRequest = JSON.parse(content) as CreateScorecardRequest;\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n } else if (options.name) {\n createRequest = {\n name: options.name,\n description: options.description,\n status: (options.status as ScorecardStatus) || 'draft',\n };\n } else {\n printError('Missing required options', 'Provide --file or --name');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Creating scorecard...').start();\n\n try {\n const response = await sdk.scorecard.create(createRequest);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to create scorecard', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const scorecard = response.data;\n\n printBlank();\n printSuccess('Scorecard created successfully');\n printLabel('ID', scorecard.id);\n printLabel('Name', scorecard.name);\n printLabel('Status', formatStatus(scorecard.status));\n printBlank();\n printInfo(`Run 'chanl scorecards get ${scorecard.id}' to view details`);\n printBlank();\n } catch (error) {\n spinner.fail('Failed to create scorecard');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards update command\n */\nasync function handleScorecardsUpdate(\n id: string,\n options: {\n file?: string;\n name?: string;\n description?: string;\n status?: string;\n }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n let updateRequest: UpdateScorecardRequest;\n\n if (options.file) {\n try {\n const content = await readFile(options.file, 'utf-8');\n updateRequest = JSON.parse(content) as UpdateScorecardRequest;\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n } else {\n updateRequest = {};\n if (options.name) updateRequest.name = options.name;\n if (options.description) updateRequest.description = options.description;\n if (options.status) updateRequest.status = options.status as ScorecardStatus;\n\n if (Object.keys(updateRequest).length === 0) {\n printError('No updates provided', 'Provide --file or update options');\n process.exitCode = 1;\n return;\n }\n }\n\n const spinner = ora('Updating scorecard...').start();\n\n try {\n const response = await sdk.scorecard.update(id, updateRequest);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to update scorecard', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const scorecard = response.data;\n\n printBlank();\n printSuccess('Scorecard updated successfully');\n printLabel('ID', scorecard.id);\n printLabel('Name', scorecard.name);\n printLabel('Status', formatStatus(scorecard.status));\n printBlank();\n } catch (error) {\n spinner.fail('Failed to update scorecard');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards delete command\n */\nasync function handleScorecardsDelete(\n id: string,\n options: { yes?: boolean }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n if (!options.yes) {\n printWarning(`This will permanently delete scorecard ${id.slice(-12)}`);\n const confirmed = await confirm({ message: 'Are you sure?', default: false });\n if (!confirmed) {\n printInfo('Cancelled');\n return;\n }\n }\n\n const spinner = ora('Deleting scorecard...').start();\n\n try {\n const response = await sdk.scorecard.delete(id);\n\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to delete scorecard', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson({ deleted: true, scorecardId: id });\n return;\n }\n\n printSuccess(`Scorecard ${id.slice(-12)} deleted successfully`);\n } catch (error) {\n spinner.fail('Failed to delete scorecard');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards evaluate command\n */\nasync function handleScorecardsEvaluate(\n callId: string,\n options: { scorecard: string; async?: boolean }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Triggering evaluation...').start();\n\n try {\n const response = await sdk.scorecard.evaluate(callId, {\n scorecardId: options.scorecard,\n async: options.async,\n });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to trigger evaluation', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const { resultId, status } = response.data;\n\n printBlank();\n if (status === 'completed') {\n printSuccess('Evaluation completed');\n } else {\n printSuccess('Evaluation queued');\n }\n if (resultId) {\n printLabel('Result ID', resultId);\n }\n printLabel('Status', status);\n printBlank();\n printInfo(`Run 'chanl scorecards results ${callId}' to view results`);\n printBlank();\n } catch (error) {\n spinner.fail('Failed to trigger evaluation');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards results command\n */\nasync function handleScorecardsResults(\n callId: string,\n options: { scorecard?: string }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching results...').start();\n\n try {\n const response = await sdk.scorecard.getResultsByCall(callId);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch results', response.message);\n process.exitCode = 1;\n return;\n }\n\n let results = response.data.results;\n\n // Filter by scorecard if specified\n if (options.scorecard && Array.isArray(results)) {\n results = results.filter((r: ScorecardResult) => r.scorecardId === options.scorecard);\n }\n\n if (isJsonOutput()) {\n printJson(results);\n return;\n }\n\n if (!results || results.length === 0) {\n printInfo('No evaluation results found for this call');\n printInfo(`Run 'chanl scorecards evaluate ${callId} -s <scorecardId>' to evaluate`);\n return;\n }\n\n const resultArray = results;\n\n printBlank();\n console.log(chalk.bold(`Evaluation Results for Call ${callId.slice(-12)}`));\n console.log(chalk.dim('-'.repeat(60)));\n\n for (const result of resultArray) {\n console.log(chalk.bold(`\\nScorecard: ${result.scorecardId?.slice(-12) || 'Unknown'}`));\n console.log(` Overall Score: ${formatScore(result.overallScore)}`);\n console.log(` Status: ${result.status || 'completed'}`);\n if (result.createdAt) {\n console.log(` Evaluated: ${formatDate(result.createdAt)}`);\n }\n\n if (result.categoryScores && Object.keys(result.categoryScores).length > 0) {\n console.log(chalk.bold('\\n Category Scores:'));\n for (const [categoryName, score] of Object.entries(result.categoryScores)) {\n console.log(` ${categoryName}: ${formatScore(score)}`);\n }\n }\n\n if (result.llmAnalysis?.summary) {\n console.log(chalk.bold('\\n Summary:'));\n console.log(` ${result.llmAnalysis.summary}`);\n }\n\n if (result.llmAnalysis?.improvementSuggestions && result.llmAnalysis.improvementSuggestions.length > 0) {\n console.log(chalk.bold('\\n Improvement Suggestions:'));\n for (const suggestion of result.llmAnalysis.improvementSuggestions) {\n console.log(` - ${suggestion}`);\n }\n }\n }\n\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch results');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards categories command\n */\nasync function handleScorecardsCategories(scorecardId: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching categories...').start();\n\n try {\n const response = await sdk.scorecard.listCategories(scorecardId);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch categories', response.message);\n process.exitCode = 1;\n return;\n }\n\n const categories = response.data.categories;\n\n if (isJsonOutput()) {\n printJson(categories);\n return;\n }\n\n if (!categories || categories.length === 0) {\n printInfo('No categories found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Name', 'Weight', 'Criteria'],\n categories.map((c: ScorecardCategory) => [\n c.id.slice(-12),\n c.name.slice(0, 30),\n `${c.weight}%`,\n (c.criteria?.length || 0).toString(),\n ])\n );\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch categories');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle scorecards criteria command\n */\nasync function handleScorecardsCriteria(categoryId: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching criteria...').start();\n\n try {\n const response = await sdk.scorecard.listCriteria(categoryId);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch criteria', response.message);\n process.exitCode = 1;\n return;\n }\n\n const criteria = response.data.criteria;\n\n if (isJsonOutput()) {\n printJson(criteria);\n return;\n }\n\n if (!criteria || criteria.length === 0) {\n printInfo('No criteria found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Name', 'Type', 'Order', 'Active'],\n criteria.map((c: ScorecardCriteria) => [\n c.id.slice(-12),\n c.name.slice(0, 25),\n c.type,\n c.order.toString(),\n c.isActive ? chalk.green('yes') : chalk.gray('no'),\n ])\n );\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch criteria');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n"],"mappings":"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","names":[]}
@@ -6,6 +6,12 @@ interface ChanlCliConfig {
6
6
  jwtToken?: string;
7
7
  refreshToken?: string;
8
8
  baseUrl: string;
9
+ /** Alias for baseUrl (e.g. local eval server URL). */
10
+ server?: string;
11
+ /** `local` rewrites `/api/v1` paths for OSS-style servers. */
12
+ deployment?: 'local' | 'cloud';
13
+ /** Override API prefix; use empty string for flat `/scenarios` routes. */
14
+ apiPrefix?: string;
9
15
  workspaceId?: string;
10
16
  appUrl?: string;
11
17
  defaultFormat: 'table' | 'json';
@@ -69,6 +75,8 @@ declare class ConfigStore {
69
75
  * Priority: CHANL_BASE_URL env var > config file > default
70
76
  */
71
77
  getBaseUrl(): string;
78
+ getDeployment(): 'local' | 'cloud' | undefined;
79
+ getApiPrefix(): string | undefined;
72
80
  /**
73
81
  * Get the app URL for browser-based flows (e.g., CLI auth)
74
82
  * Priority: CHANL_APP_URL env var > config file > derived from baseUrl
@@ -29,6 +29,9 @@ class ConfigStore {
29
29
  jwtToken: { type: "string" },
30
30
  refreshToken: { type: "string" },
31
31
  baseUrl: { type: "string", default: DEFAULT_CONFIG.baseUrl },
32
+ server: { type: "string" },
33
+ deployment: { type: "string" },
34
+ apiPrefix: { type: "string" },
32
35
  workspaceId: { type: "string" },
33
36
  appUrl: { type: "string" },
34
37
  defaultFormat: {
@@ -106,7 +109,21 @@ class ConfigStore {
106
109
  * Priority: CHANL_BASE_URL env var > config file > default
107
110
  */
108
111
  getBaseUrl() {
109
- return process.env["CHANL_BASE_URL"] || this.get("baseUrl");
112
+ return process.env["CHANL_BASE_URL"] || this.get("server") || this.get("baseUrl");
113
+ }
114
+ getDeployment() {
115
+ const d = process.env["CHANL_DEPLOYMENT"] || this.get("deployment");
116
+ if (d === "local" || d === "cloud") return d;
117
+ const base = this.getBaseUrl();
118
+ if (base.includes("localhost:18005") || base.includes("127.0.0.1:18005")) {
119
+ return "local";
120
+ }
121
+ return void 0;
122
+ }
123
+ getApiPrefix() {
124
+ const fromEnv = process.env["CHANL_API_PREFIX"];
125
+ if (fromEnv !== void 0) return fromEnv;
126
+ return this.get("apiPrefix");
110
127
  }
111
128
  /**
112
129
  * Get the app URL for browser-based flows (e.g., CLI auth)
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/config-store.ts"],"sourcesContent":["import Conf from 'conf';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync, mkdirSync } from 'node:fs';\n\n/**\n * CLI configuration schema\n */\nexport interface ChanlCliConfig {\n apiKey?: string;\n jwtToken?: string;\n refreshToken?: string;\n baseUrl: string;\n workspaceId?: string;\n appUrl?: string;\n defaultFormat: 'table' | 'json';\n}\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG: ChanlCliConfig = {\n baseUrl: 'https://platform.chanl.ai',\n defaultFormat: 'table',\n};\n\n/**\n * Get the Chanl config directory path\n * Uses ~/.chanl/ for storing configuration\n */\nexport function getConfigDir(): string {\n return join(homedir(), '.chanl');\n}\n\n/**\n * Ensure the config directory exists\n */\nfunction ensureConfigDir(): void {\n const configDir = getConfigDir();\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n}\n\n/**\n * Config store using Conf library\n * Stores configuration in ~/.chanl/config.json\n */\nclass ConfigStore {\n private store: Conf<ChanlCliConfig>;\n\n constructor() {\n ensureConfigDir();\n this.store = new Conf<ChanlCliConfig>({\n projectName: 'chanl',\n cwd: getConfigDir(),\n configName: 'config',\n defaults: DEFAULT_CONFIG,\n schema: {\n apiKey: { type: 'string' },\n jwtToken: { type: 'string' },\n refreshToken: { type: 'string' },\n baseUrl: { type: 'string', default: DEFAULT_CONFIG.baseUrl },\n workspaceId: { type: 'string' },\n appUrl: { type: 'string' },\n defaultFormat: {\n type: 'string',\n enum: ['table', 'json'],\n default: 'table',\n },\n },\n });\n }\n\n /**\n * Get a configuration value\n * Supports dot notation for nested values\n */\n get<K extends keyof ChanlCliConfig>(key: K): ChanlCliConfig[K] {\n return this.store.get(key);\n }\n\n /**\n * Set a configuration value\n */\n set<K extends keyof ChanlCliConfig>(key: K, value: ChanlCliConfig[K]): void {\n this.store.set(key, value);\n }\n\n /**\n * Delete a configuration value\n */\n delete(key: keyof ChanlCliConfig): void {\n this.store.delete(key);\n }\n\n /**\n * Get all configuration values\n */\n getAll(): ChanlCliConfig {\n return this.store.store;\n }\n\n /**\n * Check if a key exists in the configuration\n */\n has(key: keyof ChanlCliConfig): boolean {\n return this.store.has(key);\n }\n\n /**\n * Clear all configuration\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Get the path to the config file\n */\n getPath(): string {\n return this.store.path;\n }\n\n /**\n * Get API key with environment variable fallback\n * Priority: CHANL_API_KEY env var > config file\n */\n getApiKey(): string | undefined {\n return process.env['CHANL_API_KEY'] || this.get('apiKey');\n }\n\n /**\n * Get JWT token from config\n */\n getJwtToken(): string | undefined {\n return this.get('jwtToken');\n }\n\n /**\n * Get refresh token from config\n */\n getRefreshToken(): string | undefined {\n return this.get('refreshToken');\n }\n\n /**\n * Get base URL with environment variable fallback\n * Priority: CHANL_BASE_URL env var > config file > default\n */\n getBaseUrl(): string {\n return process.env['CHANL_BASE_URL'] || this.get('baseUrl');\n }\n\n /**\n * Get the app URL for browser-based flows (e.g., CLI auth)\n * Priority: CHANL_APP_URL env var > config file > derived from baseUrl\n */\n getAppUrl(): string {\n if (process.env['CHANL_APP_URL']) return process.env['CHANL_APP_URL'];\n const stored = this.get('appUrl');\n if (stored) return stored;\n\n // Derive from baseUrl — localhost auto-maps to local frontend\n const baseUrl = this.getBaseUrl();\n if (baseUrl.includes('localhost')) return 'http://localhost:3001';\n return 'https://app.chanl.ai';\n }\n\n /**\n * Get workspace ID with environment variable fallback\n * Priority: CHANL_WORKSPACE_ID env var > config file\n */\n getWorkspaceId(): string | undefined {\n return process.env['CHANL_WORKSPACE_ID'] || this.get('workspaceId');\n }\n\n /**\n * Check if user is authenticated (has API key or JWT token)\n */\n isAuthenticated(): boolean {\n return !!(this.getApiKey() || this.getJwtToken());\n }\n\n /**\n * Get the auth method in use\n */\n getAuthMethod(): 'api-key' | 'jwt' | null {\n if (this.getApiKey()) return 'api-key';\n if (this.getJwtToken()) return 'jwt';\n return null;\n }\n\n /**\n * Set API key in config\n */\n setApiKey(apiKey: string): void {\n this.set('apiKey', apiKey);\n }\n\n /**\n * Set JWT tokens in config (from browser login)\n */\n setJwtAuth(jwtToken: string, refreshToken: string): void {\n this.set('jwtToken', jwtToken);\n this.set('refreshToken', refreshToken);\n // Clear API key if switching to JWT auth\n this.delete('apiKey');\n }\n\n /**\n * Remove all auth credentials from config (logout)\n */\n clearAuth(): void {\n this.delete('apiKey');\n this.delete('jwtToken');\n this.delete('refreshToken');\n }\n\n /**\n * Remove API key from config (logout)\n */\n removeApiKey(): void {\n this.delete('apiKey');\n }\n\n /**\n * Set workspace ID in config\n */\n setWorkspaceId(workspaceId: string): void {\n this.set('workspaceId', workspaceId);\n }\n\n /**\n * Set base URL in config\n */\n setBaseUrl(baseUrl: string): void {\n this.set('baseUrl', baseUrl);\n }\n}\n\n// Export singleton instance\nexport const configStore = new ConfigStore();\n\n// Export class for testing purposes\nexport { ConfigStore };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/utils/config-store.ts"],"sourcesContent":["import Conf from 'conf';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync, mkdirSync } from 'node:fs';\n\n/**\n * CLI configuration schema\n */\nexport interface ChanlCliConfig {\n apiKey?: string;\n jwtToken?: string;\n refreshToken?: string;\n baseUrl: string;\n /** Alias for baseUrl (e.g. local eval server URL). */\n server?: string;\n /** `local` rewrites `/api/v1` paths for OSS-style servers. */\n deployment?: 'local' | 'cloud';\n /** Override API prefix; use empty string for flat `/scenarios` routes. */\n apiPrefix?: string;\n workspaceId?: string;\n appUrl?: string;\n defaultFormat: 'table' | 'json';\n}\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG: ChanlCliConfig = {\n baseUrl: 'https://platform.chanl.ai',\n defaultFormat: 'table',\n};\n\n/**\n * Get the Chanl config directory path\n * Uses ~/.chanl/ for storing configuration\n */\nexport function getConfigDir(): string {\n return join(homedir(), '.chanl');\n}\n\n/**\n * Ensure the config directory exists\n */\nfunction ensureConfigDir(): void {\n const configDir = getConfigDir();\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n}\n\n/**\n * Config store using Conf library\n * Stores configuration in ~/.chanl/config.json\n */\nclass ConfigStore {\n private store: Conf<ChanlCliConfig>;\n\n constructor() {\n ensureConfigDir();\n this.store = new Conf<ChanlCliConfig>({\n projectName: 'chanl',\n cwd: getConfigDir(),\n configName: 'config',\n defaults: DEFAULT_CONFIG,\n schema: {\n apiKey: { type: 'string' },\n jwtToken: { type: 'string' },\n refreshToken: { type: 'string' },\n baseUrl: { type: 'string', default: DEFAULT_CONFIG.baseUrl },\n server: { type: 'string' },\n deployment: { type: 'string' },\n apiPrefix: { type: 'string' },\n workspaceId: { type: 'string' },\n appUrl: { type: 'string' },\n defaultFormat: {\n type: 'string',\n enum: ['table', 'json'],\n default: 'table',\n },\n },\n });\n }\n\n /**\n * Get a configuration value\n * Supports dot notation for nested values\n */\n get<K extends keyof ChanlCliConfig>(key: K): ChanlCliConfig[K] {\n return this.store.get(key);\n }\n\n /**\n * Set a configuration value\n */\n set<K extends keyof ChanlCliConfig>(key: K, value: ChanlCliConfig[K]): void {\n this.store.set(key, value);\n }\n\n /**\n * Delete a configuration value\n */\n delete(key: keyof ChanlCliConfig): void {\n this.store.delete(key);\n }\n\n /**\n * Get all configuration values\n */\n getAll(): ChanlCliConfig {\n return this.store.store;\n }\n\n /**\n * Check if a key exists in the configuration\n */\n has(key: keyof ChanlCliConfig): boolean {\n return this.store.has(key);\n }\n\n /**\n * Clear all configuration\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Get the path to the config file\n */\n getPath(): string {\n return this.store.path;\n }\n\n /**\n * Get API key with environment variable fallback\n * Priority: CHANL_API_KEY env var > config file\n */\n getApiKey(): string | undefined {\n return process.env['CHANL_API_KEY'] || this.get('apiKey');\n }\n\n /**\n * Get JWT token from config\n */\n getJwtToken(): string | undefined {\n return this.get('jwtToken');\n }\n\n /**\n * Get refresh token from config\n */\n getRefreshToken(): string | undefined {\n return this.get('refreshToken');\n }\n\n /**\n * Get base URL with environment variable fallback\n * Priority: CHANL_BASE_URL env var > config file > default\n */\n getBaseUrl(): string {\n return (\n process.env['CHANL_BASE_URL'] ||\n this.get('server') ||\n this.get('baseUrl')\n );\n }\n\n getDeployment(): 'local' | 'cloud' | undefined {\n const d = process.env['CHANL_DEPLOYMENT'] || this.get('deployment');\n if (d === 'local' || d === 'cloud') return d;\n const base = this.getBaseUrl();\n if (\n base.includes('localhost:18005') ||\n base.includes('127.0.0.1:18005')\n ) {\n return 'local';\n }\n return undefined;\n }\n\n getApiPrefix(): string | undefined {\n const fromEnv = process.env['CHANL_API_PREFIX'];\n if (fromEnv !== undefined) return fromEnv;\n return this.get('apiPrefix') as string | undefined;\n }\n\n /**\n * Get the app URL for browser-based flows (e.g., CLI auth)\n * Priority: CHANL_APP_URL env var > config file > derived from baseUrl\n */\n getAppUrl(): string {\n if (process.env['CHANL_APP_URL']) return process.env['CHANL_APP_URL'];\n const stored = this.get('appUrl');\n if (stored) return stored;\n\n // Derive from baseUrl — localhost auto-maps to local frontend\n const baseUrl = this.getBaseUrl();\n if (baseUrl.includes('localhost')) return 'http://localhost:3001';\n return 'https://app.chanl.ai';\n }\n\n /**\n * Get workspace ID with environment variable fallback\n * Priority: CHANL_WORKSPACE_ID env var > config file\n */\n getWorkspaceId(): string | undefined {\n return process.env['CHANL_WORKSPACE_ID'] || this.get('workspaceId');\n }\n\n /**\n * Check if user is authenticated (has API key or JWT token)\n */\n isAuthenticated(): boolean {\n return !!(this.getApiKey() || this.getJwtToken());\n }\n\n /**\n * Get the auth method in use\n */\n getAuthMethod(): 'api-key' | 'jwt' | null {\n if (this.getApiKey()) return 'api-key';\n if (this.getJwtToken()) return 'jwt';\n return null;\n }\n\n /**\n * Set API key in config\n */\n setApiKey(apiKey: string): void {\n this.set('apiKey', apiKey);\n }\n\n /**\n * Set JWT tokens in config (from browser login)\n */\n setJwtAuth(jwtToken: string, refreshToken: string): void {\n this.set('jwtToken', jwtToken);\n this.set('refreshToken', refreshToken);\n // Clear API key if switching to JWT auth\n this.delete('apiKey');\n }\n\n /**\n * Remove all auth credentials from config (logout)\n */\n clearAuth(): void {\n this.delete('apiKey');\n this.delete('jwtToken');\n this.delete('refreshToken');\n }\n\n /**\n * Remove API key from config (logout)\n */\n removeApiKey(): void {\n this.delete('apiKey');\n }\n\n /**\n * Set workspace ID in config\n */\n setWorkspaceId(workspaceId: string): void {\n this.set('workspaceId', workspaceId);\n }\n\n /**\n * Set base URL in config\n */\n setBaseUrl(baseUrl: string): void {\n this.set('baseUrl', baseUrl);\n }\n}\n\n// Export singleton instance\nexport const configStore = new ConfigStore();\n\n// Export class for testing purposes\nexport { ConfigStore };\n"],"mappings":"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","names":[]}
@@ -10,13 +10,25 @@ function createSdk() {
10
10
  process.exitCode = 1;
11
11
  return null;
12
12
  }
13
+ const deployment = configStore.getDeployment();
14
+ const apiPrefix = configStore.getApiPrefix();
13
15
  if (apiKey) {
14
16
  if (apiKey.startsWith("eyJ")) {
15
- return new ChanlSDK({ jwtToken: apiKey, baseUrl });
17
+ return new ChanlSDK({
18
+ jwtToken: apiKey,
19
+ baseUrl,
20
+ deployment,
21
+ apiPrefix
22
+ });
16
23
  }
17
- return new ChanlSDK({ apiKey, baseUrl });
24
+ return new ChanlSDK({ apiKey, baseUrl, deployment, apiPrefix });
18
25
  }
19
- return new ChanlSDK({ jwtToken, baseUrl });
26
+ return new ChanlSDK({
27
+ jwtToken,
28
+ baseUrl,
29
+ deployment,
30
+ apiPrefix
31
+ });
20
32
  }
21
33
  function getWorkspaceId() {
22
34
  const workspaceId = configStore.getWorkspaceId();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/sdk-factory.ts"],"sourcesContent":["import { ChanlSDK } from '@chanl/sdk';\nimport { configStore } from './config-store.js';\nimport { printError } from './output.js';\n\n/**\n * Create an authenticated SDK instance from stored config.\n * Supports both API key and JWT token auth.\n * Returns null with error message if not authenticated.\n */\nexport function createSdk(): ChanlSDK | null {\n const apiKey = configStore.getApiKey();\n const jwtToken = configStore.getJwtToken();\n const baseUrl = configStore.getBaseUrl();\n\n if (!apiKey && !jwtToken) {\n printError('Not authenticated', \"Run 'chanl login' to authenticate\");\n process.exitCode = 1;\n return null;\n }\n\n if (apiKey) {\n // API key might be a JWT (legacy compat)\n if (apiKey.startsWith('eyJ')) {\n return new ChanlSDK({ jwtToken: apiKey, baseUrl });\n }\n return new ChanlSDK({ apiKey, baseUrl });\n }\n\n return new ChanlSDK({ jwtToken: jwtToken!, baseUrl });\n}\n\n/**\n * Get workspace ID from config, with error message if not set.\n * Returns null with error message if no workspace selected.\n */\nexport function getWorkspaceId(): string | null {\n const workspaceId = configStore.getWorkspaceId();\n\n if (!workspaceId) {\n printError('No workspace selected', \"Run 'chanl config set workspaceId <id>' to select a workspace\");\n process.exitCode = 1;\n return null;\n }\n\n return workspaceId;\n}\n"],"mappings":"AAAA,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAOpB,SAAS,YAA6B;AAC3C,QAAM,SAAS,YAAY,UAAU;AACrC,QAAM,WAAW,YAAY,YAAY;AACzC,QAAM,UAAU,YAAY,WAAW;AAEvC,MAAI,CAAC,UAAU,CAAC,UAAU;AACxB,eAAW,qBAAqB,mCAAmC;AACnE,YAAQ,WAAW;AACnB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ;AAEV,QAAI,OAAO,WAAW,KAAK,GAAG;AAC5B,aAAO,IAAI,SAAS,EAAE,UAAU,QAAQ,QAAQ,CAAC;AAAA,IACnD;AACA,WAAO,IAAI,SAAS,EAAE,QAAQ,QAAQ,CAAC;AAAA,EACzC;AAEA,SAAO,IAAI,SAAS,EAAE,UAAqB,QAAQ,CAAC;AACtD;AAMO,SAAS,iBAAgC;AAC9C,QAAM,cAAc,YAAY,eAAe;AAE/C,MAAI,CAAC,aAAa;AAChB,eAAW,yBAAyB,+DAA+D;AACnG,YAAQ,WAAW;AACnB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/sdk-factory.ts"],"sourcesContent":["import { ChanlSDK } from '@chanl/sdk';\nimport { configStore } from './config-store.js';\nimport { printError } from './output.js';\n\n/**\n * Create an authenticated SDK instance from stored config.\n * Supports both API key and JWT token auth.\n * Returns null with error message if not authenticated.\n */\nexport function createSdk(): ChanlSDK | null {\n const apiKey = configStore.getApiKey();\n const jwtToken = configStore.getJwtToken();\n const baseUrl = configStore.getBaseUrl();\n\n if (!apiKey && !jwtToken) {\n printError('Not authenticated', \"Run 'chanl login' to authenticate\");\n process.exitCode = 1;\n return null;\n }\n\n const deployment = configStore.getDeployment();\n const apiPrefix = configStore.getApiPrefix();\n\n if (apiKey) {\n // API key might be a JWT (legacy compat)\n if (apiKey.startsWith('eyJ')) {\n return new ChanlSDK({\n jwtToken: apiKey,\n baseUrl,\n deployment,\n apiPrefix,\n });\n }\n return new ChanlSDK({ apiKey, baseUrl, deployment, apiPrefix });\n }\n\n return new ChanlSDK({\n jwtToken: jwtToken!,\n baseUrl,\n deployment,\n apiPrefix,\n });\n}\n\n/**\n * Get workspace ID from config, with error message if not set.\n * Returns null with error message if no workspace selected.\n */\nexport function getWorkspaceId(): string | null {\n const workspaceId = configStore.getWorkspaceId();\n\n if (!workspaceId) {\n printError('No workspace selected', \"Run 'chanl config set workspaceId <id>' to select a workspace\");\n process.exitCode = 1;\n return null;\n }\n\n return workspaceId;\n}\n"],"mappings":"AAAA,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAOpB,SAAS,YAA6B;AAC3C,QAAM,SAAS,YAAY,UAAU;AACrC,QAAM,WAAW,YAAY,YAAY;AACzC,QAAM,UAAU,YAAY,WAAW;AAEvC,MAAI,CAAC,UAAU,CAAC,UAAU;AACxB,eAAW,qBAAqB,mCAAmC;AACnE,YAAQ,WAAW;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,YAAY,cAAc;AAC7C,QAAM,YAAY,YAAY,aAAa;AAE3C,MAAI,QAAQ;AAEV,QAAI,OAAO,WAAW,KAAK,GAAG;AAC5B,aAAO,IAAI,SAAS;AAAA,QAClB,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO,IAAI,SAAS,EAAE,QAAQ,SAAS,YAAY,UAAU,CAAC;AAAA,EAChE;AAEA,SAAO,IAAI,SAAS;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAMO,SAAS,iBAAgC;AAC9C,QAAM,cAAc,YAAY,eAAe;AAE/C,MAAI,CAAC,aAAa;AAChB,eAAW,yBAAyB,+DAA+D;AACnG,YAAQ,WAAW;AACnB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chanl/cli",
3
- "version": "2.0.4",
4
- "description": "Command-line interface for Chanl Analytics",
3
+ "version": "3.0.0",
4
+ "description": "Command-line interface for the Chanl AI platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "bin": {
@@ -21,11 +21,11 @@
21
21
  "keywords": [
22
22
  "chanl",
23
23
  "cli",
24
- "analytics",
24
+ "ai-agents",
25
25
  "api",
26
26
  "command-line"
27
27
  ],
28
- "author": "Chanl Analytics",
28
+ "author": "Chanl AI",
29
29
  "license": "MIT",
30
30
  "dependencies": {
31
31
  "@chanl/sdk": "*",