@chanl/cli 2.0.1 → 2.0.3

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 (45) hide show
  1. package/dist/__tests__/cli.test.d.ts +2 -0
  2. package/dist/__tests__/cli.test.js +1 -1
  3. package/dist/__tests__/cli.test.js.map +1 -1
  4. package/dist/cli.d.ts +12 -0
  5. package/dist/cli.js +3 -1
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/agents.d.ts +8 -0
  8. package/dist/commands/agents.js +1 -1
  9. package/dist/commands/agents.js.map +1 -1
  10. package/dist/commands/auth.d.ts +16 -0
  11. package/dist/commands/call.d.ts +8 -0
  12. package/dist/commands/calls.d.ts +8 -0
  13. package/dist/commands/chat.d.ts +8 -0
  14. package/dist/commands/config.d.ts +8 -0
  15. package/dist/commands/health.d.ts +8 -0
  16. package/dist/commands/health.js +7 -3
  17. package/dist/commands/health.js.map +1 -1
  18. package/dist/commands/index.d.ts +18 -0
  19. package/dist/commands/knowledge.d.ts +8 -0
  20. package/dist/commands/mcp.d.ts +8 -0
  21. package/dist/commands/mcp.js +4 -4
  22. package/dist/commands/mcp.js.map +1 -1
  23. package/dist/commands/memory.d.ts +8 -0
  24. package/dist/commands/personas.d.ts +8 -0
  25. package/dist/commands/personas.js +1 -1
  26. package/dist/commands/personas.js.map +1 -1
  27. package/dist/commands/prompts.d.ts +8 -0
  28. package/dist/commands/scenarios.d.ts +8 -0
  29. package/dist/commands/scenarios.js +1 -1
  30. package/dist/commands/scenarios.js.map +1 -1
  31. package/dist/commands/scorecards.d.ts +8 -0
  32. package/dist/commands/scorecards.js +1 -1
  33. package/dist/commands/scorecards.js.map +1 -1
  34. package/dist/commands/tools.d.ts +8 -0
  35. package/dist/commands/toolsets.d.ts +8 -0
  36. package/dist/commands/toolsets.js +3 -3
  37. package/dist/commands/toolsets.js.map +1 -1
  38. package/dist/commands/workspaces.d.ts +8 -0
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.js.map +1 -1
  41. package/dist/utils/config-store.d.ts +117 -0
  42. package/dist/utils/interactive.d.ts +41 -0
  43. package/dist/utils/output.d.ts +100 -0
  44. package/dist/utils/sdk-factory.d.ts +15 -0
  45. package/package.json +5 -4
@@ -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.pages})`);\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 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":[]}
@@ -0,0 +1,8 @@
1
+ import { Command } from 'commander';
2
+
3
+ /**
4
+ * Create the tools command group
5
+ */
6
+ declare function createToolsCommand(): Command;
7
+
8
+ export { createToolsCommand };
@@ -0,0 +1,8 @@
1
+ import { Command } from 'commander';
2
+
3
+ /**
4
+ * Create the toolsets command group
5
+ */
6
+ declare function createToolsetsCommand(): Command;
7
+
8
+ export { createToolsetsCommand };
@@ -125,8 +125,8 @@ async function handleToolsetsList(options) {
125
125
  process.exitCode = 1;
126
126
  return;
127
127
  }
128
- const toolsets = response.data.data;
129
- const total = response.data.total;
128
+ const toolsets = response.data.items || response.data.data || [];
129
+ const total = response.data.total ?? response.data.pagination?.total ?? toolsets.length;
130
130
  const pagination = response.data.pagination || {
131
131
  page: parseInt(options.page, 10),
132
132
  limit: parseInt(options.limit, 10),
@@ -147,7 +147,7 @@ async function handleToolsetsList(options) {
147
147
  ["Name", "Tool Count", "Enabled", "Tags", "Version"],
148
148
  toolsets.map((toolset) => [
149
149
  toolset.name,
150
- toolset.toolCount.toString(),
150
+ (toolset.toolCount ?? toolset.tools?.length ?? 0).toString(),
151
151
  toolset.enabled ? chalk.green("Yes") : chalk.red("No"),
152
152
  toolset.tags && toolset.tags.length > 0 ? toolset.tags.join(", ") : "-",
153
153
  toolset.version
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/toolsets.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 { Toolset, CreateToolsetInput, UpdateToolsetInput } from '@chanl/sdk';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport {\n printSuccess,\n printError,\n printInfo,\n printLabel,\n printBlank,\n printSimpleTable,\n isJsonOutput,\n printJson,\n formatDate,\n} from '../utils/output.js';\n\n// Sample toolset template\nconst TOOLSET_TEMPLATE = {\n name: 'my-toolset',\n description: 'A curated collection of tools for a specific use case',\n tools: ['tool-id-1', 'tool-id-2'],\n toolOverrides: {\n 'tool-id-1': {\n name: 'custom_name',\n description: 'Override description for this tool',\n },\n },\n isEnabled: true,\n tags: ['production', 'customer-facing'],\n};\n\n/**\n * Create the toolsets command group\n */\nexport function createToolsetsCommand(): Command {\n const toolsets = new Command('toolsets')\n .description('Manage MCP toolsets (collections of tools)')\n .addHelpText(\n 'after',\n `\nWhat are Toolsets?\n Toolsets group multiple tools together and allow you to customize how they\n appear to AI agents. Use toolsets to:\n - Create curated tool collections for specific use cases\n - Override tool names/descriptions per context\n - Enable/disable entire groups of tools at once\n\nExamples:\n $ chanl toolsets list # List all toolsets\n $ chanl toolsets create -f toolset.json # Create new toolset\n $ chanl toolsets add-tools <id> -t id1,id2 # Add tools to toolset`\n );\n\n // toolsets list\n toolsets\n .command('list')\n .description('List all toolsets in the workspace')\n .option('-e, --enabled', 'Show only enabled toolsets')\n .option('-d, --disabled', 'Show only disabled toolsets')\n .option('--tag <tag>', 'Filter by tag')\n .option('-s, --search <search>', 'Search by name or description')\n .option('-l, --limit <number>', 'Items per page (default: 20)', '20')\n .option('-p, --page <number>', 'Page number (default: 1)', '1')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl toolsets list # List all\n $ chanl toolsets list --enabled # Only enabled\n $ chanl toolsets list --search \"api\" # Search by name`\n )\n .action(handleToolsetsList);\n\n // toolsets get <id>\n toolsets\n .command('get <id>')\n .description('Get detailed info about a toolset')\n .addHelpText(\n 'after',\n `\nExample:\n $ chanl toolsets get 507f1f77bcf86cd799439011`\n )\n .action(handleToolsetsGet);\n\n // toolsets create\n toolsets\n .command('create')\n .description('Create a new toolset from JSON file')\n .option('-f, --file <path>', 'Path to JSON file with toolset definition')\n .option('--template', 'Output a sample JSON template')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl toolsets create --template > my-toolset.json # Generate template\n $ chanl toolsets create -f my-toolset.json # Create from file\n\nRequired JSON fields:\n name Toolset name\n description What this toolset is for\n tools Array of tool IDs to include\n\nOptional fields:\n toolOverrides Override name/description per tool\n isEnabled Enable immediately (default: true)\n tags Array of category tags`\n )\n .action(handleToolsetsCreate);\n\n // toolsets update <id>\n toolsets\n .command('update <id>')\n .description('Update a toolset from JSON file')\n .requiredOption('-f, --file <path>', 'Path to JSON file with updates')\n .addHelpText(\n 'after',\n `\nExample:\n $ chanl toolsets update 507f1f77bcf86cd799439011 -f updates.json`\n )\n .action(handleToolsetsUpdate);\n\n // toolsets delete <id>\n toolsets\n .command('delete <id>')\n .description('Delete a toolset permanently')\n .option('-y, --yes', 'Skip confirmation prompt')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl toolsets delete 507f1f77bcf86cd799439011 # With confirmation\n $ chanl toolsets delete 507f1f77bcf86cd799439011 -y # Skip confirmation`\n )\n .action(handleToolsetsDelete);\n\n // toolsets enable <id>\n toolsets\n .command('enable <id>')\n .description('Enable a toolset (makes its tools available)')\n .action(handleToolsetsEnable);\n\n // toolsets disable <id>\n toolsets\n .command('disable <id>')\n .description('Disable a toolset (hides its tools)')\n .action(handleToolsetsDisable);\n\n // toolsets add-tools <id>\n toolsets\n .command('add-tools <id>')\n .description('Add tools to an existing toolset')\n .requiredOption('-t, --tools <ids>', 'Comma-separated tool IDs')\n .addHelpText(\n 'after',\n `\nExample:\n $ chanl toolsets add-tools 507f1f77bcf86cd799439011 -t tool1,tool2,tool3`\n )\n .action(handleToolsetsAddTools);\n\n // toolsets remove-tools <id>\n toolsets\n .command('remove-tools <id>')\n .description('Remove tools from a toolset')\n .requiredOption('-t, --tools <ids>', 'Comma-separated tool IDs')\n .addHelpText(\n 'after',\n `\nExample:\n $ chanl toolsets remove-tools 507f1f77bcf86cd799439011 -t tool1,tool2`\n )\n .action(handleToolsetsRemoveTools);\n\n return toolsets;\n}\n\n/**\n * Handle toolsets list command\n */\nasync function handleToolsetsList(options: {\n enabled?: boolean;\n disabled?: boolean;\n tag?: 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 toolsets...').start();\n\n try {\n // Determine enabled filter\n let enabled: boolean | undefined;\n if (options.enabled) enabled = true;\n else if (options.disabled) enabled = false;\n\n const response = await sdk.toolsets.list({\n enabled,\n tag: options.tag,\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 toolsets', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolsets = response.data.data;\n const total = response.data.total;\n const pagination = response.data.pagination || {\n page: parseInt(options.page, 10),\n limit: parseInt(options.limit, 10),\n totalPages: Math.ceil(total / parseInt(options.limit, 10)),\n hasNext: false,\n hasPrev: false,\n };\n\n if (isJsonOutput()) {\n printJson({ toolsets, total, pagination });\n return;\n }\n\n if (toolsets.length === 0) {\n printInfo('No toolsets found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['Name', 'Tool Count', 'Enabled', 'Tags', 'Version'],\n toolsets.map((toolset) => [\n toolset.name,\n toolset.toolCount.toString(),\n toolset.enabled ? chalk.green('Yes') : chalk.red('No'),\n toolset.tags && toolset.tags.length > 0 ? toolset.tags.join(', ') : '-',\n toolset.version,\n ])\n );\n\n printBlank();\n printInfo(`Total: ${total} toolsets (Page ${pagination.page} of ${pagination.totalPages})`);\n } catch (error) {\n spinner.fail('Failed to fetch toolsets');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets get command\n */\nasync function handleToolsetsGet(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching toolset...').start();\n\n try {\n const response = await sdk.toolsets.get(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n // API returns toolset directly in data (not nested as { toolset: ... })\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson(toolset);\n return;\n }\n\n printBlank();\n printToolsetDetails(toolset);\n } catch (error) {\n spinner.fail('Failed to fetch toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets create command\n */\nasync function handleToolsetsCreate(options: { file?: string; template?: boolean }): Promise<void> {\n // Handle --template flag: output sample JSON and exit\n if (options.template) {\n console.log(JSON.stringify(TOOLSET_TEMPLATE, null, 2));\n return;\n }\n\n // Require --file if not using --template\n if (!options.file) {\n printError('Missing required option', \"Use '-f, --file <path>' or '--template' for sample JSON\");\n printInfo(\"Run 'chanl toolsets create --help' for usage\");\n process.exitCode = 1;\n return;\n }\n\n const sdk = createSdk();\n if (!sdk) return;\n\n // Read and parse JSON file\n let input: Record<string, unknown>;\n try {\n const content = await readFile(options.file, 'utf-8');\n input = 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 toolset...').start();\n\n try {\n const response = await sdk.toolsets.create(input as unknown as CreateToolsetInput);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to create toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Created toolset: ${toolset.name} (${toolset.id})`);\n } catch (error) {\n spinner.fail('Failed to create toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets update command\n */\nasync function handleToolsetsUpdate(id: string, options: { file: string }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n // Read and parse JSON file\n let input: Record<string, unknown>;\n try {\n const content = await readFile(options.file, 'utf-8');\n input = 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 toolset...').start();\n\n try {\n const response = await sdk.toolsets.update(id, input as unknown as UpdateToolsetInput);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to update toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Updated toolset: ${toolset.name} (${toolset.id})`);\n } catch (error) {\n spinner.fail('Failed to update toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets delete command\n */\nasync function handleToolsetsDelete(id: string, options: { yes?: boolean }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n // Confirm deletion unless --yes flag is provided\n if (!options.yes) {\n try {\n const confirmed = await confirm({\n message: `Are you sure you want to delete toolset '${id}'?`,\n default: false,\n });\n\n if (!confirmed) {\n printInfo('Deletion cancelled');\n return;\n }\n } catch {\n // User cancelled (Ctrl+C)\n printBlank();\n printInfo('Deletion cancelled');\n return;\n }\n }\n\n const spinner = ora('Deleting toolset...').start();\n\n try {\n const response = await sdk.toolsets.delete(id);\n\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to delete toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson({ success: true, deleted: true, id });\n return;\n }\n\n printSuccess(`Deleted toolset: ${id}`);\n } catch (error) {\n spinner.fail('Failed to delete toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets enable command\n */\nasync function handleToolsetsEnable(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Enabling toolset...').start();\n\n try {\n const response = await sdk.toolsets.enable(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to enable toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Enabled toolset: ${toolset.name} (${toolset.id})`);\n } catch (error) {\n spinner.fail('Failed to enable toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets disable command\n */\nasync function handleToolsetsDisable(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Disabling toolset...').start();\n\n try {\n const response = await sdk.toolsets.disable(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to disable toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Disabled toolset: ${toolset.name} (${toolset.id})`);\n } catch (error) {\n spinner.fail('Failed to disable toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets add-tools command\n */\nasync function handleToolsetsAddTools(id: string, options: { tools: string }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const toolIds = options.tools.split(',').map((t) => t.trim()).filter(Boolean);\n\n if (toolIds.length === 0) {\n printError('No tool IDs provided', 'Provide tool IDs with --tools flag');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Adding tools to toolset...').start();\n\n try {\n const response = await sdk.toolsets.manageTools(id, { add: toolIds });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to add tools', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Added ${toolIds.length} tool(s) to toolset: ${toolset.name}`);\n printInfo(`Toolset now has ${toolset.toolCount} tool(s)`);\n } catch (error) {\n spinner.fail('Failed to add tools');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets remove-tools command\n */\nasync function handleToolsetsRemoveTools(id: string, options: { tools: string }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const toolIds = options.tools.split(',').map((t) => t.trim()).filter(Boolean);\n\n if (toolIds.length === 0) {\n printError('No tool IDs provided', 'Provide tool IDs with --tools flag');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Removing tools from toolset...').start();\n\n try {\n const response = await sdk.toolsets.manageTools(id, { remove: toolIds });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to remove tools', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Removed ${toolIds.length} tool(s) from toolset: ${toolset.name}`);\n printInfo(`Toolset now has ${toolset.toolCount} tool(s)`);\n } catch (error) {\n spinner.fail('Failed to remove tools');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Print toolset details in formatted output\n */\nfunction printToolsetDetails(toolset: Toolset): void {\n printLabel('Name', toolset.name);\n printLabel('ID', toolset.id);\n printLabel('Description', toolset.description);\n printLabel('Version', toolset.version);\n printLabel('Enabled', toolset.enabled ? chalk.green('Yes') : chalk.red('No'));\n printLabel('Public', toolset.isPublic ? chalk.green('Yes') : chalk.red('No'));\n\n if (toolset.registryId) {\n printLabel('Registry ID', toolset.registryId);\n }\n\n if (toolset.tags && toolset.tags.length > 0) {\n printLabel('Tags', toolset.tags.join(', '));\n }\n\n printBlank();\n printInfo(`Tools (${toolset.toolCount}):`);\n if (toolset.tools.length > 0) {\n for (const toolId of toolset.tools) {\n console.log(chalk.gray(` - ${toolId}`));\n }\n } else {\n console.log(chalk.gray(' No tools in this toolset'));\n }\n\n if (toolset.toolOverrides && Object.keys(toolset.toolOverrides).length > 0) {\n printBlank();\n printInfo('Tool Overrides:');\n for (const [toolId, override] of Object.entries(toolset.toolOverrides)) {\n console.log(chalk.gray(` ${toolId}:`));\n if (override.name) console.log(chalk.gray(` name: ${override.name}`));\n if (override.description) console.log(chalk.gray(` description: ${override.description}`));\n }\n }\n\n printBlank();\n printLabel('Created', formatDate(toolset.createdAt));\n printLabel('Updated', formatDate(toolset.updatedAt));\n printBlank();\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/commands/toolsets.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 { Toolset, CreateToolsetInput, UpdateToolsetInput } from '@chanl/sdk';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport {\n printSuccess,\n printError,\n printInfo,\n printLabel,\n printBlank,\n printSimpleTable,\n isJsonOutput,\n printJson,\n formatDate,\n} from '../utils/output.js';\n\n// Sample toolset template\nconst TOOLSET_TEMPLATE = {\n name: 'my-toolset',\n description: 'A curated collection of tools for a specific use case',\n tools: ['tool-id-1', 'tool-id-2'],\n toolOverrides: {\n 'tool-id-1': {\n name: 'custom_name',\n description: 'Override description for this tool',\n },\n },\n isEnabled: true,\n tags: ['production', 'customer-facing'],\n};\n\n/**\n * Create the toolsets command group\n */\nexport function createToolsetsCommand(): Command {\n const toolsets = new Command('toolsets')\n .description('Manage MCP toolsets (collections of tools)')\n .addHelpText(\n 'after',\n `\nWhat are Toolsets?\n Toolsets group multiple tools together and allow you to customize how they\n appear to AI agents. Use toolsets to:\n - Create curated tool collections for specific use cases\n - Override tool names/descriptions per context\n - Enable/disable entire groups of tools at once\n\nExamples:\n $ chanl toolsets list # List all toolsets\n $ chanl toolsets create -f toolset.json # Create new toolset\n $ chanl toolsets add-tools <id> -t id1,id2 # Add tools to toolset`\n );\n\n // toolsets list\n toolsets\n .command('list')\n .description('List all toolsets in the workspace')\n .option('-e, --enabled', 'Show only enabled toolsets')\n .option('-d, --disabled', 'Show only disabled toolsets')\n .option('--tag <tag>', 'Filter by tag')\n .option('-s, --search <search>', 'Search by name or description')\n .option('-l, --limit <number>', 'Items per page (default: 20)', '20')\n .option('-p, --page <number>', 'Page number (default: 1)', '1')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl toolsets list # List all\n $ chanl toolsets list --enabled # Only enabled\n $ chanl toolsets list --search \"api\" # Search by name`\n )\n .action(handleToolsetsList);\n\n // toolsets get <id>\n toolsets\n .command('get <id>')\n .description('Get detailed info about a toolset')\n .addHelpText(\n 'after',\n `\nExample:\n $ chanl toolsets get 507f1f77bcf86cd799439011`\n )\n .action(handleToolsetsGet);\n\n // toolsets create\n toolsets\n .command('create')\n .description('Create a new toolset from JSON file')\n .option('-f, --file <path>', 'Path to JSON file with toolset definition')\n .option('--template', 'Output a sample JSON template')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl toolsets create --template > my-toolset.json # Generate template\n $ chanl toolsets create -f my-toolset.json # Create from file\n\nRequired JSON fields:\n name Toolset name\n description What this toolset is for\n tools Array of tool IDs to include\n\nOptional fields:\n toolOverrides Override name/description per tool\n isEnabled Enable immediately (default: true)\n tags Array of category tags`\n )\n .action(handleToolsetsCreate);\n\n // toolsets update <id>\n toolsets\n .command('update <id>')\n .description('Update a toolset from JSON file')\n .requiredOption('-f, --file <path>', 'Path to JSON file with updates')\n .addHelpText(\n 'after',\n `\nExample:\n $ chanl toolsets update 507f1f77bcf86cd799439011 -f updates.json`\n )\n .action(handleToolsetsUpdate);\n\n // toolsets delete <id>\n toolsets\n .command('delete <id>')\n .description('Delete a toolset permanently')\n .option('-y, --yes', 'Skip confirmation prompt')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl toolsets delete 507f1f77bcf86cd799439011 # With confirmation\n $ chanl toolsets delete 507f1f77bcf86cd799439011 -y # Skip confirmation`\n )\n .action(handleToolsetsDelete);\n\n // toolsets enable <id>\n toolsets\n .command('enable <id>')\n .description('Enable a toolset (makes its tools available)')\n .action(handleToolsetsEnable);\n\n // toolsets disable <id>\n toolsets\n .command('disable <id>')\n .description('Disable a toolset (hides its tools)')\n .action(handleToolsetsDisable);\n\n // toolsets add-tools <id>\n toolsets\n .command('add-tools <id>')\n .description('Add tools to an existing toolset')\n .requiredOption('-t, --tools <ids>', 'Comma-separated tool IDs')\n .addHelpText(\n 'after',\n `\nExample:\n $ chanl toolsets add-tools 507f1f77bcf86cd799439011 -t tool1,tool2,tool3`\n )\n .action(handleToolsetsAddTools);\n\n // toolsets remove-tools <id>\n toolsets\n .command('remove-tools <id>')\n .description('Remove tools from a toolset')\n .requiredOption('-t, --tools <ids>', 'Comma-separated tool IDs')\n .addHelpText(\n 'after',\n `\nExample:\n $ chanl toolsets remove-tools 507f1f77bcf86cd799439011 -t tool1,tool2`\n )\n .action(handleToolsetsRemoveTools);\n\n return toolsets;\n}\n\n/**\n * Handle toolsets list command\n */\nasync function handleToolsetsList(options: {\n enabled?: boolean;\n disabled?: boolean;\n tag?: 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 toolsets...').start();\n\n try {\n // Determine enabled filter\n let enabled: boolean | undefined;\n if (options.enabled) enabled = true;\n else if (options.disabled) enabled = false;\n\n const response = await sdk.toolsets.list({\n enabled,\n tag: options.tag,\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 toolsets', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolsets = response.data.items || response.data.data || [];\n const total = response.data.total ?? response.data.pagination?.total ?? toolsets.length;\n const pagination = response.data.pagination || {\n page: parseInt(options.page, 10),\n limit: parseInt(options.limit, 10),\n totalPages: Math.ceil(total / parseInt(options.limit, 10)),\n hasNext: false,\n hasPrev: false,\n };\n\n if (isJsonOutput()) {\n printJson({ toolsets, total, pagination });\n return;\n }\n\n if (toolsets.length === 0) {\n printInfo('No toolsets found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['Name', 'Tool Count', 'Enabled', 'Tags', 'Version'],\n toolsets.map((toolset) => [\n toolset.name,\n (toolset.toolCount ?? toolset.tools?.length ?? 0).toString(),\n toolset.enabled ? chalk.green('Yes') : chalk.red('No'),\n toolset.tags && toolset.tags.length > 0 ? toolset.tags.join(', ') : '-',\n toolset.version,\n ])\n );\n\n printBlank();\n printInfo(`Total: ${total} toolsets (Page ${pagination.page} of ${pagination.totalPages})`);\n } catch (error) {\n spinner.fail('Failed to fetch toolsets');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets get command\n */\nasync function handleToolsetsGet(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching toolset...').start();\n\n try {\n const response = await sdk.toolsets.get(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n // API returns toolset directly in data (not nested as { toolset: ... })\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson(toolset);\n return;\n }\n\n printBlank();\n printToolsetDetails(toolset);\n } catch (error) {\n spinner.fail('Failed to fetch toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets create command\n */\nasync function handleToolsetsCreate(options: { file?: string; template?: boolean }): Promise<void> {\n // Handle --template flag: output sample JSON and exit\n if (options.template) {\n console.log(JSON.stringify(TOOLSET_TEMPLATE, null, 2));\n return;\n }\n\n // Require --file if not using --template\n if (!options.file) {\n printError('Missing required option', \"Use '-f, --file <path>' or '--template' for sample JSON\");\n printInfo(\"Run 'chanl toolsets create --help' for usage\");\n process.exitCode = 1;\n return;\n }\n\n const sdk = createSdk();\n if (!sdk) return;\n\n // Read and parse JSON file\n let input: Record<string, unknown>;\n try {\n const content = await readFile(options.file, 'utf-8');\n input = 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 toolset...').start();\n\n try {\n const response = await sdk.toolsets.create(input as unknown as CreateToolsetInput);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to create toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Created toolset: ${toolset.name} (${toolset.id})`);\n } catch (error) {\n spinner.fail('Failed to create toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets update command\n */\nasync function handleToolsetsUpdate(id: string, options: { file: string }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n // Read and parse JSON file\n let input: Record<string, unknown>;\n try {\n const content = await readFile(options.file, 'utf-8');\n input = 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 toolset...').start();\n\n try {\n const response = await sdk.toolsets.update(id, input as unknown as UpdateToolsetInput);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to update toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Updated toolset: ${toolset.name} (${toolset.id})`);\n } catch (error) {\n spinner.fail('Failed to update toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets delete command\n */\nasync function handleToolsetsDelete(id: string, options: { yes?: boolean }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n // Confirm deletion unless --yes flag is provided\n if (!options.yes) {\n try {\n const confirmed = await confirm({\n message: `Are you sure you want to delete toolset '${id}'?`,\n default: false,\n });\n\n if (!confirmed) {\n printInfo('Deletion cancelled');\n return;\n }\n } catch {\n // User cancelled (Ctrl+C)\n printBlank();\n printInfo('Deletion cancelled');\n return;\n }\n }\n\n const spinner = ora('Deleting toolset...').start();\n\n try {\n const response = await sdk.toolsets.delete(id);\n\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to delete toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson({ success: true, deleted: true, id });\n return;\n }\n\n printSuccess(`Deleted toolset: ${id}`);\n } catch (error) {\n spinner.fail('Failed to delete toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets enable command\n */\nasync function handleToolsetsEnable(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Enabling toolset...').start();\n\n try {\n const response = await sdk.toolsets.enable(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to enable toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Enabled toolset: ${toolset.name} (${toolset.id})`);\n } catch (error) {\n spinner.fail('Failed to enable toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets disable command\n */\nasync function handleToolsetsDisable(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Disabling toolset...').start();\n\n try {\n const response = await sdk.toolsets.disable(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to disable toolset', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Disabled toolset: ${toolset.name} (${toolset.id})`);\n } catch (error) {\n spinner.fail('Failed to disable toolset');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets add-tools command\n */\nasync function handleToolsetsAddTools(id: string, options: { tools: string }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const toolIds = options.tools.split(',').map((t) => t.trim()).filter(Boolean);\n\n if (toolIds.length === 0) {\n printError('No tool IDs provided', 'Provide tool IDs with --tools flag');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Adding tools to toolset...').start();\n\n try {\n const response = await sdk.toolsets.manageTools(id, { add: toolIds });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to add tools', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Added ${toolIds.length} tool(s) to toolset: ${toolset.name}`);\n printInfo(`Toolset now has ${toolset.toolCount} tool(s)`);\n } catch (error) {\n spinner.fail('Failed to add tools');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle toolsets remove-tools command\n */\nasync function handleToolsetsRemoveTools(id: string, options: { tools: string }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const toolIds = options.tools.split(',').map((t) => t.trim()).filter(Boolean);\n\n if (toolIds.length === 0) {\n printError('No tool IDs provided', 'Provide tool IDs with --tools flag');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Removing tools from toolset...').start();\n\n try {\n const response = await sdk.toolsets.manageTools(id, { remove: toolIds });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to remove tools', response.message);\n process.exitCode = 1;\n return;\n }\n\n const toolset = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, toolset });\n return;\n }\n\n printSuccess(`Removed ${toolIds.length} tool(s) from toolset: ${toolset.name}`);\n printInfo(`Toolset now has ${toolset.toolCount} tool(s)`);\n } catch (error) {\n spinner.fail('Failed to remove tools');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Print toolset details in formatted output\n */\nfunction printToolsetDetails(toolset: Toolset): void {\n printLabel('Name', toolset.name);\n printLabel('ID', toolset.id);\n printLabel('Description', toolset.description);\n printLabel('Version', toolset.version);\n printLabel('Enabled', toolset.enabled ? chalk.green('Yes') : chalk.red('No'));\n printLabel('Public', toolset.isPublic ? chalk.green('Yes') : chalk.red('No'));\n\n if (toolset.registryId) {\n printLabel('Registry ID', toolset.registryId);\n }\n\n if (toolset.tags && toolset.tags.length > 0) {\n printLabel('Tags', toolset.tags.join(', '));\n }\n\n printBlank();\n printInfo(`Tools (${toolset.toolCount}):`);\n if (toolset.tools.length > 0) {\n for (const toolId of toolset.tools) {\n console.log(chalk.gray(` - ${toolId}`));\n }\n } else {\n console.log(chalk.gray(' No tools in this toolset'));\n }\n\n if (toolset.toolOverrides && Object.keys(toolset.toolOverrides).length > 0) {\n printBlank();\n printInfo('Tool Overrides:');\n for (const [toolId, override] of Object.entries(toolset.toolOverrides)) {\n console.log(chalk.gray(` ${toolId}:`));\n if (override.name) console.log(chalk.gray(` name: ${override.name}`));\n if (override.description) console.log(chalk.gray(` description: ${override.description}`));\n }\n }\n\n printBlank();\n printLabel('Created', formatDate(toolset.createdAt));\n printLabel('Updated', formatDate(toolset.updatedAt));\n printBlank();\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,8 @@
1
+ import { Command } from 'commander';
2
+
3
+ /**
4
+ * Create the workspaces command group
5
+ */
6
+ declare function createWorkspacesCommand(): Command;
7
+
8
+ export { createWorkspacesCommand };
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @chanl-ai/cli - Command-line interface for Chanl\n *\n * Entry point for the CLI application.\n */\n\nimport { run } from './cli.js';\n\n// Run the CLI\nrun().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n"],"mappings":"AAMA,SAAS,WAAW;AAGpB,IAAI,EAAE,MAAM,CAAC,UAAU;AACrB,UAAQ,MAAM,gBAAgB,KAAK;AACnC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @chanl/cli - Command-line interface for Chanl\n *\n * Entry point for the CLI application.\n */\n\nimport { run } from './cli.js';\n\n// Run the CLI\nrun().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n"],"mappings":"AAMA,SAAS,WAAW;AAGpB,IAAI,EAAE,MAAM,CAAC,UAAU;AACrB,UAAQ,MAAM,gBAAgB,KAAK;AACnC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * CLI configuration schema
3
+ */
4
+ interface ChanlCliConfig {
5
+ apiKey?: string;
6
+ jwtToken?: string;
7
+ refreshToken?: string;
8
+ baseUrl: string;
9
+ workspaceId?: string;
10
+ appUrl?: string;
11
+ defaultFormat: 'table' | 'json';
12
+ }
13
+ /**
14
+ * Get the Chanl config directory path
15
+ * Uses ~/.chanl/ for storing configuration
16
+ */
17
+ declare function getConfigDir(): string;
18
+ /**
19
+ * Config store using Conf library
20
+ * Stores configuration in ~/.chanl/config.json
21
+ */
22
+ declare class ConfigStore {
23
+ private store;
24
+ constructor();
25
+ /**
26
+ * Get a configuration value
27
+ * Supports dot notation for nested values
28
+ */
29
+ get<K extends keyof ChanlCliConfig>(key: K): ChanlCliConfig[K];
30
+ /**
31
+ * Set a configuration value
32
+ */
33
+ set<K extends keyof ChanlCliConfig>(key: K, value: ChanlCliConfig[K]): void;
34
+ /**
35
+ * Delete a configuration value
36
+ */
37
+ delete(key: keyof ChanlCliConfig): void;
38
+ /**
39
+ * Get all configuration values
40
+ */
41
+ getAll(): ChanlCliConfig;
42
+ /**
43
+ * Check if a key exists in the configuration
44
+ */
45
+ has(key: keyof ChanlCliConfig): boolean;
46
+ /**
47
+ * Clear all configuration
48
+ */
49
+ clear(): void;
50
+ /**
51
+ * Get the path to the config file
52
+ */
53
+ getPath(): string;
54
+ /**
55
+ * Get API key with environment variable fallback
56
+ * Priority: CHANL_API_KEY env var > config file
57
+ */
58
+ getApiKey(): string | undefined;
59
+ /**
60
+ * Get JWT token from config
61
+ */
62
+ getJwtToken(): string | undefined;
63
+ /**
64
+ * Get refresh token from config
65
+ */
66
+ getRefreshToken(): string | undefined;
67
+ /**
68
+ * Get base URL with environment variable fallback
69
+ * Priority: CHANL_BASE_URL env var > config file > default
70
+ */
71
+ getBaseUrl(): string;
72
+ /**
73
+ * Get the app URL for browser-based flows (e.g., CLI auth)
74
+ * Priority: CHANL_APP_URL env var > config file > derived from baseUrl
75
+ */
76
+ getAppUrl(): string;
77
+ /**
78
+ * Get workspace ID with environment variable fallback
79
+ * Priority: CHANL_WORKSPACE_ID env var > config file
80
+ */
81
+ getWorkspaceId(): string | undefined;
82
+ /**
83
+ * Check if user is authenticated (has API key or JWT token)
84
+ */
85
+ isAuthenticated(): boolean;
86
+ /**
87
+ * Get the auth method in use
88
+ */
89
+ getAuthMethod(): 'api-key' | 'jwt' | null;
90
+ /**
91
+ * Set API key in config
92
+ */
93
+ setApiKey(apiKey: string): void;
94
+ /**
95
+ * Set JWT tokens in config (from browser login)
96
+ */
97
+ setJwtAuth(jwtToken: string, refreshToken: string): void;
98
+ /**
99
+ * Remove all auth credentials from config (logout)
100
+ */
101
+ clearAuth(): void;
102
+ /**
103
+ * Remove API key from config (logout)
104
+ */
105
+ removeApiKey(): void;
106
+ /**
107
+ * Set workspace ID in config
108
+ */
109
+ setWorkspaceId(workspaceId: string): void;
110
+ /**
111
+ * Set base URL in config
112
+ */
113
+ setBaseUrl(baseUrl: string): void;
114
+ }
115
+ declare const configStore: ConfigStore;
116
+
117
+ export { type ChanlCliConfig, ConfigStore, configStore, getConfigDir };
@@ -0,0 +1,41 @@
1
+ import { CallScorecardResult } from '@chanl/sdk';
2
+
3
+ /**
4
+ * Shared interactive utilities for live call/scenario monitoring
5
+ *
6
+ * Display functions for transcript segments, scorecards, and status.
7
+ * Polling logic has moved to the SDK's LiveCall/LiveExecution classes.
8
+ */
9
+
10
+ interface TranscriptSegment {
11
+ speaker: string;
12
+ text: string;
13
+ start: number;
14
+ end: number;
15
+ }
16
+ /**
17
+ * Print a transcript segment with speaker label and timestamp
18
+ */
19
+ declare function printSegment(segment: TranscriptSegment): void;
20
+ /**
21
+ * Format a speaker name for display
22
+ */
23
+ declare function formatSpeaker(speaker: string): string;
24
+ /**
25
+ * Display a scorecard result in a formatted way
26
+ */
27
+ declare function displayScorecard(results: CallScorecardResult[]): void;
28
+ /**
29
+ * Format elapsed time as MM:SS
30
+ */
31
+ declare function formatElapsed(startTime: Date): string;
32
+ /**
33
+ * Terminal call statuses that mean the call is done
34
+ */
35
+ declare const TERMINAL_CALL_STATUSES: Set<string>;
36
+ /**
37
+ * Check if a call status is terminal
38
+ */
39
+ declare function isTerminalStatus(status: string): boolean;
40
+
41
+ export { TERMINAL_CALL_STATUSES, type TranscriptSegment, displayScorecard, formatElapsed, formatSpeaker, isTerminalStatus, printSegment };
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Output formatting options
3
+ */
4
+ interface OutputOptions {
5
+ json?: boolean;
6
+ noColor?: boolean;
7
+ }
8
+ /**
9
+ * Set global output options
10
+ */
11
+ declare function setOutputOptions(options: OutputOptions): void;
12
+ /**
13
+ * Get current output options
14
+ */
15
+ declare function getOutputOptions(): OutputOptions;
16
+ /**
17
+ * Check if JSON output is enabled
18
+ */
19
+ declare function isJsonOutput(): boolean;
20
+ /**
21
+ * Print JSON output
22
+ */
23
+ declare function printJson(data: unknown): void;
24
+ /**
25
+ * Print success message with checkmark
26
+ */
27
+ declare function printSuccess(message: string): void;
28
+ /**
29
+ * Print error message with X mark
30
+ */
31
+ declare function printError(message: string, details?: string): void;
32
+ /**
33
+ * Print warning message
34
+ */
35
+ declare function printWarning(message: string): void;
36
+ /**
37
+ * Print info message
38
+ */
39
+ declare function printInfo(message: string): void;
40
+ /**
41
+ * Print a labeled value
42
+ */
43
+ declare function printLabel(label: string, value: string | number | boolean): void;
44
+ /**
45
+ * Print a header/title
46
+ */
47
+ declare function printHeader(title: string): void;
48
+ /**
49
+ * Print a blank line
50
+ */
51
+ declare function printBlank(): void;
52
+ /**
53
+ * Table column definition
54
+ */
55
+ interface TableColumn {
56
+ header: string;
57
+ key: string;
58
+ width?: number;
59
+ align?: 'left' | 'right' | 'center';
60
+ format?: (value: unknown) => string;
61
+ }
62
+ /**
63
+ * Print a simple table
64
+ */
65
+ declare function printTable<T extends Record<string, unknown>>(columns: TableColumn[], rows: T[]): void;
66
+ /**
67
+ * Format a boolean as checkmark or X
68
+ */
69
+ declare function formatBoolean(value: unknown): string;
70
+ /**
71
+ * Format a date relative to now
72
+ */
73
+ declare function formatRelativeDate(dateStr: string | Date | undefined): string;
74
+ /**
75
+ * Truncate string with ellipsis
76
+ */
77
+ declare function truncate(str: string, maxLength: number): string;
78
+ /**
79
+ * Mask sensitive string (show first and last few characters)
80
+ */
81
+ declare function maskString(str: string, showFirst?: number, showLast?: number): string;
82
+ /**
83
+ * Format duration in milliseconds
84
+ */
85
+ declare function formatDuration(ms: number | undefined): string;
86
+ /**
87
+ * Format status with color
88
+ */
89
+ declare function formatStatus(status: string): string;
90
+ /**
91
+ * Format a date as a short date string
92
+ */
93
+ declare function formatDate(dateStr: string | Date | undefined): string;
94
+ /**
95
+ * Print a simple table from header and row arrays
96
+ * Simplified version for string[][] data
97
+ */
98
+ declare function printSimpleTable(headers: string[], rows: string[][]): void;
99
+
100
+ export { type OutputOptions, type TableColumn, formatBoolean, formatDate, formatDuration, formatRelativeDate, formatStatus, getOutputOptions, isJsonOutput, maskString, printBlank, printError, printHeader, printInfo, printJson, printLabel, printSimpleTable, printSuccess, printTable, printWarning, setOutputOptions, truncate };