@chanl-ai/cli 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/bin/chanl.js +10 -0
  2. package/dist/__tests__/cli.test.d.ts +2 -0
  3. package/dist/__tests__/cli.test.js +2313 -0
  4. package/dist/__tests__/cli.test.js.map +1 -0
  5. package/dist/cli.d.ts +12 -0
  6. package/dist/cli.js +72 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/agents.d.ts +8 -0
  9. package/dist/commands/agents.js +671 -0
  10. package/dist/commands/agents.js.map +1 -0
  11. package/dist/commands/auth.d.ts +16 -0
  12. package/dist/commands/auth.js +294 -0
  13. package/dist/commands/auth.js.map +1 -0
  14. package/dist/commands/call.d.ts +8 -0
  15. package/dist/commands/call.js +166 -0
  16. package/dist/commands/call.js.map +1 -0
  17. package/dist/commands/calls.d.ts +8 -0
  18. package/dist/commands/calls.js +719 -0
  19. package/dist/commands/calls.js.map +1 -0
  20. package/dist/commands/chat.d.ts +8 -0
  21. package/dist/commands/chat.js +203 -0
  22. package/dist/commands/chat.js.map +1 -0
  23. package/dist/commands/config.d.ts +8 -0
  24. package/dist/commands/config.js +231 -0
  25. package/dist/commands/config.js.map +1 -0
  26. package/dist/commands/health.d.ts +8 -0
  27. package/dist/commands/health.js +55 -0
  28. package/dist/commands/health.js.map +1 -0
  29. package/dist/commands/index.d.ts +18 -0
  30. package/dist/commands/index.js +39 -0
  31. package/dist/commands/index.js.map +1 -0
  32. package/dist/commands/knowledge.d.ts +8 -0
  33. package/dist/commands/knowledge.js +539 -0
  34. package/dist/commands/knowledge.js.map +1 -0
  35. package/dist/commands/mcp.d.ts +8 -0
  36. package/dist/commands/mcp.js +589 -0
  37. package/dist/commands/mcp.js.map +1 -0
  38. package/dist/commands/memory.d.ts +8 -0
  39. package/dist/commands/memory.js +408 -0
  40. package/dist/commands/memory.js.map +1 -0
  41. package/dist/commands/personas.d.ts +8 -0
  42. package/dist/commands/personas.js +356 -0
  43. package/dist/commands/personas.js.map +1 -0
  44. package/dist/commands/prompts.d.ts +8 -0
  45. package/dist/commands/prompts.js +295 -0
  46. package/dist/commands/prompts.js.map +1 -0
  47. package/dist/commands/scenarios.d.ts +8 -0
  48. package/dist/commands/scenarios.js +591 -0
  49. package/dist/commands/scenarios.js.map +1 -0
  50. package/dist/commands/scorecards.d.ts +8 -0
  51. package/dist/commands/scorecards.js +570 -0
  52. package/dist/commands/scorecards.js.map +1 -0
  53. package/dist/commands/tools.d.ts +8 -0
  54. package/dist/commands/tools.js +632 -0
  55. package/dist/commands/tools.js.map +1 -0
  56. package/dist/commands/toolsets.d.ts +8 -0
  57. package/dist/commands/toolsets.js +464 -0
  58. package/dist/commands/toolsets.js.map +1 -0
  59. package/dist/commands/workspaces.d.ts +8 -0
  60. package/dist/commands/workspaces.js +170 -0
  61. package/dist/commands/workspaces.js.map +1 -0
  62. package/dist/index.d.ts +2 -0
  63. package/dist/index.js +6 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/utils/config-store.d.ts +117 -0
  66. package/dist/utils/config-store.js +191 -0
  67. package/dist/utils/config-store.js.map +1 -0
  68. package/dist/utils/interactive.d.ts +41 -0
  69. package/dist/utils/interactive.js +83 -0
  70. package/dist/utils/interactive.js.map +1 -0
  71. package/dist/utils/output.d.ts +100 -0
  72. package/dist/utils/output.js +221 -0
  73. package/dist/utils/output.js.map +1 -0
  74. package/dist/utils/sdk-factory.d.ts +15 -0
  75. package/dist/utils/sdk-factory.js +34 -0
  76. package/dist/utils/sdk-factory.js.map +1 -0
  77. package/package.json +67 -0
@@ -0,0 +1,170 @@
1
+ import { Command } from "commander";
2
+ import ora from "ora";
3
+ import chalk from "chalk";
4
+ import { createSdk } from "../utils/sdk-factory.js";
5
+ import { configStore } from "../utils/config-store.js";
6
+ import {
7
+ printError,
8
+ printSuccess,
9
+ printInfo,
10
+ printBlank,
11
+ printSimpleTable,
12
+ printLabel,
13
+ isJsonOutput,
14
+ printJson,
15
+ formatDate
16
+ } from "../utils/output.js";
17
+ function createWorkspacesCommand() {
18
+ const workspaces = new Command("workspaces").description("Manage workspaces").addHelpText(
19
+ "after",
20
+ `
21
+ What are Workspaces?
22
+ Workspaces are isolated environments for organizing agents, tools, and
23
+ configurations. Switch between workspaces to manage different projects.
24
+
25
+ Quick Start:
26
+ $ chanl workspaces list # List your workspaces
27
+ $ chanl workspaces get <id> # View workspace details
28
+ $ chanl workspaces use <id> # Set active workspace`
29
+ );
30
+ workspaces.command("list").description("List workspaces").addHelpText(
31
+ "after",
32
+ `
33
+ Examples:
34
+ $ chanl workspaces list # List all workspaces
35
+ $ chanl workspaces list --json # Output as JSON`
36
+ ).action(handleWorkspacesList);
37
+ workspaces.command("get <id>").description("Get workspace details").addHelpText(
38
+ "after",
39
+ `
40
+ Examples:
41
+ $ chanl workspaces get ws_abc123 # Get workspace details
42
+ $ chanl workspaces get ws_abc123 --json # Output as JSON`
43
+ ).action(handleWorkspacesGet);
44
+ workspaces.command("use <id>").description("Set active workspace (saves to config)").addHelpText(
45
+ "after",
46
+ `
47
+ Examples:
48
+ $ chanl workspaces use ws_abc123 # Switch to workspace
49
+
50
+ This saves the workspace ID to your CLI config. All subsequent commands
51
+ will use this workspace by default.`
52
+ ).action(handleWorkspacesUse);
53
+ return workspaces;
54
+ }
55
+ async function handleWorkspacesList() {
56
+ const sdk = createSdk();
57
+ if (!sdk) return;
58
+ const spinner = ora("Fetching workspaces...").start();
59
+ try {
60
+ const response = await sdk.workspace.getAll();
61
+ spinner.stop();
62
+ if (!response.success || !response.data) {
63
+ printError("Failed to fetch workspaces", response.message);
64
+ process.exitCode = 1;
65
+ return;
66
+ }
67
+ const workspaces = Array.isArray(response.data) ? response.data : [];
68
+ const currentWorkspaceId = configStore.getWorkspaceId();
69
+ if (isJsonOutput()) {
70
+ printJson(workspaces);
71
+ return;
72
+ }
73
+ if (workspaces.length === 0) {
74
+ printInfo("No workspaces found");
75
+ return;
76
+ }
77
+ printBlank();
78
+ printSimpleTable(
79
+ ["", "ID", "Name", "Description", "Created"],
80
+ workspaces.map((ws) => [
81
+ ws.id === currentWorkspaceId ? chalk.green("*") : " ",
82
+ ws.id,
83
+ (ws.name || "Untitled").slice(0, 30),
84
+ (ws.description || "-").slice(0, 40),
85
+ formatDate(ws.createdAt)
86
+ ])
87
+ );
88
+ printBlank();
89
+ if (currentWorkspaceId) {
90
+ printInfo(`Active workspace: ${currentWorkspaceId}`);
91
+ }
92
+ printInfo(`Total: ${workspaces.length} workspaces`);
93
+ } catch (error) {
94
+ spinner.fail("Failed to fetch workspaces");
95
+ const message = error instanceof Error ? error.message : "Unknown error";
96
+ printError("Error", message);
97
+ process.exitCode = 1;
98
+ }
99
+ }
100
+ async function handleWorkspacesGet(id) {
101
+ const sdk = createSdk();
102
+ if (!sdk) return;
103
+ const spinner = ora("Fetching workspace...").start();
104
+ try {
105
+ const response = await sdk.workspace.getById(id);
106
+ spinner.stop();
107
+ if (!response.success || !response.data) {
108
+ printError("Failed to fetch workspace", response.message);
109
+ process.exitCode = 1;
110
+ return;
111
+ }
112
+ const workspace = response.data;
113
+ if (isJsonOutput()) {
114
+ printJson(workspace);
115
+ return;
116
+ }
117
+ printBlank();
118
+ console.log(chalk.bold("Workspace Details:"));
119
+ printLabel("ID", workspace.id);
120
+ printLabel("Name", workspace.name);
121
+ if (workspace.description) printLabel("Description", workspace.description);
122
+ if (workspace.createdAt) printLabel("Created", formatDate(workspace.createdAt));
123
+ if (workspace.updatedAt) printLabel("Updated", formatDate(workspace.updatedAt));
124
+ const currentWorkspaceId = configStore.getWorkspaceId();
125
+ if (workspace.id === currentWorkspaceId) {
126
+ printBlank();
127
+ printInfo("This is your active workspace");
128
+ }
129
+ printBlank();
130
+ } catch (error) {
131
+ spinner.fail("Failed to fetch workspace");
132
+ const message = error instanceof Error ? error.message : "Unknown error";
133
+ printError("Error", message);
134
+ process.exitCode = 1;
135
+ }
136
+ }
137
+ async function handleWorkspacesUse(id) {
138
+ const sdk = createSdk();
139
+ if (!sdk) return;
140
+ const spinner = ora("Verifying workspace...").start();
141
+ try {
142
+ const response = await sdk.workspace.getById(id);
143
+ spinner.stop();
144
+ if (!response.success || !response.data) {
145
+ printError("Workspace not found", response.message || `Could not find workspace: ${id}`);
146
+ process.exitCode = 1;
147
+ return;
148
+ }
149
+ const workspace = response.data;
150
+ configStore.setWorkspaceId(id);
151
+ if (isJsonOutput()) {
152
+ printJson({
153
+ success: true,
154
+ workspaceId: id,
155
+ name: workspace.name
156
+ });
157
+ return;
158
+ }
159
+ printSuccess(`Active workspace set to: ${workspace.name} (${id})`);
160
+ } catch (error) {
161
+ spinner.fail("Failed to set workspace");
162
+ const message = error instanceof Error ? error.message : "Unknown error";
163
+ printError("Error", message);
164
+ process.exitCode = 1;
165
+ }
166
+ }
167
+ export {
168
+ createWorkspacesCommand
169
+ };
170
+ //# sourceMappingURL=workspaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/commands/workspaces.ts"],"sourcesContent":["import { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport { configStore } from '../utils/config-store.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 workspaces command group\n */\nexport function createWorkspacesCommand(): Command {\n const workspaces = new Command('workspaces')\n .description('Manage workspaces')\n .addHelpText(\n 'after',\n `\nWhat are Workspaces?\n Workspaces are isolated environments for organizing agents, tools, and\n configurations. Switch between workspaces to manage different projects.\n\nQuick Start:\n $ chanl workspaces list # List your workspaces\n $ chanl workspaces get <id> # View workspace details\n $ chanl workspaces use <id> # Set active workspace`\n );\n\n // workspaces list\n workspaces\n .command('list')\n .description('List workspaces')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl workspaces list # List all workspaces\n $ chanl workspaces list --json # Output as JSON`\n )\n .action(handleWorkspacesList);\n\n // workspaces get <id>\n workspaces\n .command('get <id>')\n .description('Get workspace details')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl workspaces get ws_abc123 # Get workspace details\n $ chanl workspaces get ws_abc123 --json # Output as JSON`\n )\n .action(handleWorkspacesGet);\n\n // workspaces use <id>\n workspaces\n .command('use <id>')\n .description('Set active workspace (saves to config)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl workspaces use ws_abc123 # Switch to workspace\n\nThis saves the workspace ID to your CLI config. All subsequent commands\nwill use this workspace by default.`\n )\n .action(handleWorkspacesUse);\n\n return workspaces;\n}\n\n/**\n * Handle workspaces list command\n */\nasync function handleWorkspacesList(): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching workspaces...').start();\n\n try {\n const response = await sdk.workspace.getAll();\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch workspaces', response.message);\n process.exitCode = 1;\n return;\n }\n\n const workspaces = Array.isArray(response.data) ? response.data : [];\n const currentWorkspaceId = configStore.getWorkspaceId();\n\n if (isJsonOutput()) {\n printJson(workspaces);\n return;\n }\n\n if (workspaces.length === 0) {\n printInfo('No workspaces found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['', 'ID', 'Name', 'Description', 'Created'],\n workspaces.map((ws: any) => [\n ws.id === currentWorkspaceId ? chalk.green('*') : ' ',\n ws.id,\n (ws.name || 'Untitled').slice(0, 30),\n (ws.description || '-').slice(0, 40),\n formatDate(ws.createdAt),\n ])\n );\n\n printBlank();\n if (currentWorkspaceId) {\n printInfo(`Active workspace: ${currentWorkspaceId}`);\n }\n printInfo(`Total: ${workspaces.length} workspaces`);\n } catch (error) {\n spinner.fail('Failed to fetch workspaces');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle workspaces get command\n */\nasync function handleWorkspacesGet(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching workspace...').start();\n\n try {\n const response = await sdk.workspace.getById(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch workspace', response.message);\n process.exitCode = 1;\n return;\n }\n\n const workspace = response.data;\n\n if (isJsonOutput()) {\n printJson(workspace);\n return;\n }\n\n printBlank();\n console.log(chalk.bold('Workspace Details:'));\n printLabel('ID', workspace.id);\n printLabel('Name', workspace.name);\n if (workspace.description) printLabel('Description', workspace.description);\n if (workspace.createdAt) printLabel('Created', formatDate(workspace.createdAt));\n if (workspace.updatedAt) printLabel('Updated', formatDate(workspace.updatedAt));\n\n const currentWorkspaceId = configStore.getWorkspaceId();\n if (workspace.id === currentWorkspaceId) {\n printBlank();\n printInfo('This is your active workspace');\n }\n\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch workspace');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle workspaces use command\n */\nasync function handleWorkspacesUse(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Verifying workspace...').start();\n\n try {\n // Verify the workspace exists before saving\n const response = await sdk.workspace.getById(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Workspace not found', response.message || `Could not find workspace: ${id}`);\n process.exitCode = 1;\n return;\n }\n\n const workspace = response.data;\n\n // Save to config\n configStore.setWorkspaceId(id);\n\n if (isJsonOutput()) {\n printJson({\n success: true,\n workspaceId: id,\n name: workspace.name,\n });\n return;\n }\n\n printSuccess(`Active workspace set to: ${workspace.name} (${id})`);\n } catch (error) {\n spinner.fail('Failed to set workspace');\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,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import { run } from "./cli.js";
2
+ run().catch((error) => {
3
+ console.error("Fatal error:", error);
4
+ process.exit(1);
5
+ });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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":[]}
@@ -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,191 @@
1
+ import Conf from "conf";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { existsSync, mkdirSync } from "node:fs";
5
+ const DEFAULT_CONFIG = {
6
+ baseUrl: "https://platform.chanl.ai",
7
+ defaultFormat: "table"
8
+ };
9
+ function getConfigDir() {
10
+ return join(homedir(), ".chanl");
11
+ }
12
+ function ensureConfigDir() {
13
+ const configDir = getConfigDir();
14
+ if (!existsSync(configDir)) {
15
+ mkdirSync(configDir, { recursive: true });
16
+ }
17
+ }
18
+ class ConfigStore {
19
+ store;
20
+ constructor() {
21
+ ensureConfigDir();
22
+ this.store = new Conf({
23
+ projectName: "chanl",
24
+ cwd: getConfigDir(),
25
+ configName: "config",
26
+ defaults: DEFAULT_CONFIG,
27
+ schema: {
28
+ apiKey: { type: "string" },
29
+ jwtToken: { type: "string" },
30
+ refreshToken: { type: "string" },
31
+ baseUrl: { type: "string", default: DEFAULT_CONFIG.baseUrl },
32
+ workspaceId: { type: "string" },
33
+ appUrl: { type: "string" },
34
+ defaultFormat: {
35
+ type: "string",
36
+ enum: ["table", "json"],
37
+ default: "table"
38
+ }
39
+ }
40
+ });
41
+ }
42
+ /**
43
+ * Get a configuration value
44
+ * Supports dot notation for nested values
45
+ */
46
+ get(key) {
47
+ return this.store.get(key);
48
+ }
49
+ /**
50
+ * Set a configuration value
51
+ */
52
+ set(key, value) {
53
+ this.store.set(key, value);
54
+ }
55
+ /**
56
+ * Delete a configuration value
57
+ */
58
+ delete(key) {
59
+ this.store.delete(key);
60
+ }
61
+ /**
62
+ * Get all configuration values
63
+ */
64
+ getAll() {
65
+ return this.store.store;
66
+ }
67
+ /**
68
+ * Check if a key exists in the configuration
69
+ */
70
+ has(key) {
71
+ return this.store.has(key);
72
+ }
73
+ /**
74
+ * Clear all configuration
75
+ */
76
+ clear() {
77
+ this.store.clear();
78
+ }
79
+ /**
80
+ * Get the path to the config file
81
+ */
82
+ getPath() {
83
+ return this.store.path;
84
+ }
85
+ /**
86
+ * Get API key with environment variable fallback
87
+ * Priority: CHANL_API_KEY env var > config file
88
+ */
89
+ getApiKey() {
90
+ return process.env["CHANL_API_KEY"] || this.get("apiKey");
91
+ }
92
+ /**
93
+ * Get JWT token from config
94
+ */
95
+ getJwtToken() {
96
+ return this.get("jwtToken");
97
+ }
98
+ /**
99
+ * Get refresh token from config
100
+ */
101
+ getRefreshToken() {
102
+ return this.get("refreshToken");
103
+ }
104
+ /**
105
+ * Get base URL with environment variable fallback
106
+ * Priority: CHANL_BASE_URL env var > config file > default
107
+ */
108
+ getBaseUrl() {
109
+ return process.env["CHANL_BASE_URL"] || this.get("baseUrl");
110
+ }
111
+ /**
112
+ * Get the app URL for browser-based flows (e.g., CLI auth)
113
+ * Priority: CHANL_APP_URL env var > config file > derived from baseUrl
114
+ */
115
+ getAppUrl() {
116
+ if (process.env["CHANL_APP_URL"]) return process.env["CHANL_APP_URL"];
117
+ const stored = this.get("appUrl");
118
+ if (stored) return stored;
119
+ const baseUrl = this.getBaseUrl();
120
+ if (baseUrl.includes("localhost")) return "http://localhost:3001";
121
+ return "https://app.chanl.ai";
122
+ }
123
+ /**
124
+ * Get workspace ID with environment variable fallback
125
+ * Priority: CHANL_WORKSPACE_ID env var > config file
126
+ */
127
+ getWorkspaceId() {
128
+ return process.env["CHANL_WORKSPACE_ID"] || this.get("workspaceId");
129
+ }
130
+ /**
131
+ * Check if user is authenticated (has API key or JWT token)
132
+ */
133
+ isAuthenticated() {
134
+ return !!(this.getApiKey() || this.getJwtToken());
135
+ }
136
+ /**
137
+ * Get the auth method in use
138
+ */
139
+ getAuthMethod() {
140
+ if (this.getApiKey()) return "api-key";
141
+ if (this.getJwtToken()) return "jwt";
142
+ return null;
143
+ }
144
+ /**
145
+ * Set API key in config
146
+ */
147
+ setApiKey(apiKey) {
148
+ this.set("apiKey", apiKey);
149
+ }
150
+ /**
151
+ * Set JWT tokens in config (from browser login)
152
+ */
153
+ setJwtAuth(jwtToken, refreshToken) {
154
+ this.set("jwtToken", jwtToken);
155
+ this.set("refreshToken", refreshToken);
156
+ this.delete("apiKey");
157
+ }
158
+ /**
159
+ * Remove all auth credentials from config (logout)
160
+ */
161
+ clearAuth() {
162
+ this.delete("apiKey");
163
+ this.delete("jwtToken");
164
+ this.delete("refreshToken");
165
+ }
166
+ /**
167
+ * Remove API key from config (logout)
168
+ */
169
+ removeApiKey() {
170
+ this.delete("apiKey");
171
+ }
172
+ /**
173
+ * Set workspace ID in config
174
+ */
175
+ setWorkspaceId(workspaceId) {
176
+ this.set("workspaceId", workspaceId);
177
+ }
178
+ /**
179
+ * Set base URL in config
180
+ */
181
+ setBaseUrl(baseUrl) {
182
+ this.set("baseUrl", baseUrl);
183
+ }
184
+ }
185
+ const configStore = new ConfigStore();
186
+ export {
187
+ ConfigStore,
188
+ configStore,
189
+ getConfigDir
190
+ };
191
+ //# sourceMappingURL=config-store.js.map
@@ -0,0 +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":[]}
@@ -0,0 +1,41 @@
1
+ import { CallScorecardResult } from '@chanl-ai/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,83 @@
1
+ import chalk from "chalk";
2
+ import { printInfo } from "./output.js";
3
+ function printSegment(segment) {
4
+ const speaker = formatSpeaker(segment.speaker);
5
+ const time = chalk.dim(`[${formatSeconds(segment.start)}]`);
6
+ console.log(` ${speaker} ${time}: ${segment.text}`);
7
+ }
8
+ function formatSpeaker(speaker) {
9
+ switch (speaker) {
10
+ case "speaker_0":
11
+ case "agent":
12
+ return chalk.cyan("Agent");
13
+ case "speaker_1":
14
+ case "customer":
15
+ return chalk.yellow("Customer");
16
+ case "persona":
17
+ return chalk.magenta("Persona");
18
+ default:
19
+ return chalk.dim(speaker);
20
+ }
21
+ }
22
+ function formatSeconds(seconds) {
23
+ const mins = Math.floor(seconds / 60);
24
+ const secs = Math.floor(seconds % 60).toString().padStart(2, "0");
25
+ return `${mins}:${secs}`;
26
+ }
27
+ function displayScorecard(results) {
28
+ if (!results || results.length === 0) {
29
+ printInfo("No scorecard results available");
30
+ return;
31
+ }
32
+ for (const result of results) {
33
+ const overallScore = result.overallScore ?? 0;
34
+ const scoreColor = overallScore >= 80 ? chalk.green : overallScore >= 60 ? chalk.yellow : chalk.red;
35
+ console.log(chalk.bold(`
36
+ Scorecard: ${scoreColor(`${overallScore}/100`)}`));
37
+ if (result.criteriaResults && result.criteriaResults.length > 0) {
38
+ for (const criterion of result.criteriaResults) {
39
+ const passed = criterion.score >= 70;
40
+ const icon = passed ? chalk.green("\u2713") : chalk.red("\u2717");
41
+ const scoreStr = `(${criterion.score}/100)`;
42
+ const feedback = criterion.feedback ? chalk.dim(` \u2014 ${criterion.feedback}`) : "";
43
+ console.log(` ${icon} ${criterion.criterionName} ${scoreStr}${feedback}`);
44
+ }
45
+ } else if (result.categoryScores && result.categoryScores.length > 0) {
46
+ for (const cat of result.categoryScores) {
47
+ const passed = cat.score >= 70;
48
+ const icon = passed ? chalk.green("\u2713") : chalk.red("\u2717");
49
+ console.log(` ${icon} ${cat.categoryName} (${cat.score}/100)`);
50
+ }
51
+ }
52
+ if (result.feedback) {
53
+ console.log(chalk.dim(`
54
+ ${result.feedback}`));
55
+ }
56
+ }
57
+ }
58
+ function formatElapsed(startTime) {
59
+ const elapsed = Math.floor((Date.now() - startTime.getTime()) / 1e3);
60
+ const mins = Math.floor(elapsed / 60).toString().padStart(2, "0");
61
+ const secs = (elapsed % 60).toString().padStart(2, "0");
62
+ return `${mins}:${secs}`;
63
+ }
64
+ const TERMINAL_CALL_STATUSES = /* @__PURE__ */ new Set([
65
+ "ended",
66
+ "completed",
67
+ "failed",
68
+ "no-answer",
69
+ "busy",
70
+ "cancelled"
71
+ ]);
72
+ function isTerminalStatus(status) {
73
+ return TERMINAL_CALL_STATUSES.has(status);
74
+ }
75
+ export {
76
+ TERMINAL_CALL_STATUSES,
77
+ displayScorecard,
78
+ formatElapsed,
79
+ formatSpeaker,
80
+ isTerminalStatus,
81
+ printSegment
82
+ };
83
+ //# sourceMappingURL=interactive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/interactive.ts"],"sourcesContent":["/**\n * Shared interactive utilities for live call/scenario monitoring\n *\n * Display functions for transcript segments, scorecards, and status.\n * Polling logic has moved to the SDK's LiveCall/LiveExecution classes.\n */\n\nimport chalk from 'chalk';\nimport type { CallScorecardResult } from '@chanl-ai/sdk';\nimport { printInfo } from './output.js';\n\n// ==================== Transcript Display ====================\n\nexport interface TranscriptSegment {\n speaker: string;\n text: string;\n start: number;\n end: number;\n}\n\n/**\n * Print a transcript segment with speaker label and timestamp\n */\nexport function printSegment(segment: TranscriptSegment): void {\n const speaker = formatSpeaker(segment.speaker);\n const time = chalk.dim(`[${formatSeconds(segment.start)}]`);\n console.log(` ${speaker} ${time}: ${segment.text}`);\n}\n\n/**\n * Format a speaker name for display\n */\nexport function formatSpeaker(speaker: string): string {\n switch (speaker) {\n case 'speaker_0':\n case 'agent':\n return chalk.cyan('Agent');\n case 'speaker_1':\n case 'customer':\n return chalk.yellow('Customer');\n case 'persona':\n return chalk.magenta('Persona');\n default:\n return chalk.dim(speaker);\n }\n}\n\n/**\n * Format seconds as M:SS\n */\nfunction formatSeconds(seconds: number): string {\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60).toString().padStart(2, '0');\n return `${mins}:${secs}`;\n}\n\n// ==================== Scorecard Display ====================\n\n/**\n * Display a scorecard result in a formatted way\n */\nexport function displayScorecard(results: CallScorecardResult[]): void {\n if (!results || results.length === 0) {\n printInfo('No scorecard results available');\n return;\n }\n\n for (const result of results) {\n const overallScore = result.overallScore ?? 0;\n const scoreColor = overallScore >= 80 ? chalk.green : overallScore >= 60 ? chalk.yellow : chalk.red;\n\n console.log(chalk.bold(`\\n Scorecard: ${scoreColor(`${overallScore}/100`)}`));\n\n if (result.criteriaResults && result.criteriaResults.length > 0) {\n for (const criterion of result.criteriaResults) {\n const passed = criterion.score >= 70;\n const icon = passed ? chalk.green('✓') : chalk.red('✗');\n const scoreStr = `(${criterion.score}/100)`;\n const feedback = criterion.feedback ? chalk.dim(` — ${criterion.feedback}`) : '';\n console.log(` ${icon} ${criterion.criterionName} ${scoreStr}${feedback}`);\n }\n } else if (result.categoryScores && result.categoryScores.length > 0) {\n for (const cat of result.categoryScores) {\n const passed = cat.score >= 70;\n const icon = passed ? chalk.green('✓') : chalk.red('✗');\n console.log(` ${icon} ${cat.categoryName} (${cat.score}/100)`);\n }\n }\n\n if (result.feedback) {\n console.log(chalk.dim(`\\n ${result.feedback}`));\n }\n }\n}\n\n// ==================== Status Line ====================\n\n/**\n * Format elapsed time as MM:SS\n */\nexport function formatElapsed(startTime: Date): string {\n const elapsed = Math.floor((Date.now() - startTime.getTime()) / 1000);\n const mins = Math.floor(elapsed / 60).toString().padStart(2, '0');\n const secs = (elapsed % 60).toString().padStart(2, '0');\n return `${mins}:${secs}`;\n}\n\n// ==================== Call Status ====================\n\n/**\n * Terminal call statuses that mean the call is done\n */\nexport const TERMINAL_CALL_STATUSES = new Set([\n 'ended', 'completed', 'failed', 'no-answer', 'busy', 'cancelled',\n]);\n\n/**\n * Check if a call status is terminal\n */\nexport function isTerminalStatus(status: string): boolean {\n return TERMINAL_CALL_STATUSES.has(status);\n}\n"],"mappings":"AAOA,OAAO,WAAW;AAElB,SAAS,iBAAiB;AAcnB,SAAS,aAAa,SAAkC;AAC7D,QAAM,UAAU,cAAc,QAAQ,OAAO;AAC7C,QAAM,OAAO,MAAM,IAAI,IAAI,cAAc,QAAQ,KAAK,CAAC,GAAG;AAC1D,UAAQ,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ,IAAI,EAAE;AACrD;AAKO,SAAS,cAAc,SAAyB;AACrD,UAAQ,SAAS;AAAA,IACf,KAAK;AAAA,IACL,KAAK;AACH,aAAO,MAAM,KAAK,OAAO;AAAA,IAC3B,KAAK;AAAA,IACL,KAAK;AACH,aAAO,MAAM,OAAO,UAAU;AAAA,IAChC,KAAK;AACH,aAAO,MAAM,QAAQ,SAAS;AAAA,IAChC;AACE,aAAO,MAAM,IAAI,OAAO;AAAA,EAC5B;AACF;AAKA,SAAS,cAAc,SAAyB;AAC9C,QAAM,OAAO,KAAK,MAAM,UAAU,EAAE;AACpC,QAAM,OAAO,KAAK,MAAM,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG;AAChE,SAAO,GAAG,IAAI,IAAI,IAAI;AACxB;AAOO,SAAS,iBAAiB,SAAsC;AACrE,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,cAAU,gCAAgC;AAC1C;AAAA,EACF;AAEA,aAAW,UAAU,SAAS;AAC5B,UAAM,eAAe,OAAO,gBAAgB;AAC5C,UAAM,aAAa,gBAAgB,KAAK,MAAM,QAAQ,gBAAgB,KAAK,MAAM,SAAS,MAAM;AAEhG,YAAQ,IAAI,MAAM,KAAK;AAAA,eAAkB,WAAW,GAAG,YAAY,MAAM,CAAC,EAAE,CAAC;AAE7E,QAAI,OAAO,mBAAmB,OAAO,gBAAgB,SAAS,GAAG;AAC/D,iBAAW,aAAa,OAAO,iBAAiB;AAC9C,cAAM,SAAS,UAAU,SAAS;AAClC,cAAM,OAAO,SAAS,MAAM,MAAM,QAAG,IAAI,MAAM,IAAI,QAAG;AACtD,cAAM,WAAW,IAAI,UAAU,KAAK;AACpC,cAAM,WAAW,UAAU,WAAW,MAAM,IAAI,WAAM,UAAU,QAAQ,EAAE,IAAI;AAC9E,gBAAQ,IAAI,OAAO,IAAI,IAAI,UAAU,aAAa,IAAI,QAAQ,GAAG,QAAQ,EAAE;AAAA,MAC7E;AAAA,IACF,WAAW,OAAO,kBAAkB,OAAO,eAAe,SAAS,GAAG;AACpE,iBAAW,OAAO,OAAO,gBAAgB;AACvC,cAAM,SAAS,IAAI,SAAS;AAC5B,cAAM,OAAO,SAAS,MAAM,MAAM,QAAG,IAAI,MAAM,IAAI,QAAG;AACtD,gBAAQ,IAAI,OAAO,IAAI,IAAI,IAAI,YAAY,KAAK,IAAI,KAAK,OAAO;AAAA,MAClE;AAAA,IACF;AAEA,QAAI,OAAO,UAAU;AACnB,cAAQ,IAAI,MAAM,IAAI;AAAA,MAAS,OAAO,QAAQ,EAAE,CAAC;AAAA,IACnD;AAAA,EACF;AACF;AAOO,SAAS,cAAc,WAAyB;AACrD,QAAM,UAAU,KAAK,OAAO,KAAK,IAAI,IAAI,UAAU,QAAQ,KAAK,GAAI;AACpE,QAAM,OAAO,KAAK,MAAM,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG;AAChE,QAAM,QAAQ,UAAU,IAAI,SAAS,EAAE,SAAS,GAAG,GAAG;AACtD,SAAO,GAAG,IAAI,IAAI,IAAI;AACxB;AAOO,MAAM,yBAAyB,oBAAI,IAAI;AAAA,EAC5C;AAAA,EAAS;AAAA,EAAa;AAAA,EAAU;AAAA,EAAa;AAAA,EAAQ;AACvD,CAAC;AAKM,SAAS,iBAAiB,QAAyB;AACxD,SAAO,uBAAuB,IAAI,MAAM;AAC1C;","names":[]}