@chanl/cli 2.0.4 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/agents.test.js +574 -0
- package/dist/__tests__/agents.test.js.map +1 -0
- package/dist/__tests__/auth.test.d.ts +2 -0
- package/dist/__tests__/auth.test.js +87 -0
- package/dist/__tests__/auth.test.js.map +1 -0
- package/dist/__tests__/calls.test.d.ts +2 -0
- package/dist/__tests__/calls.test.js +115 -0
- package/dist/__tests__/calls.test.js.map +1 -0
- package/dist/__tests__/chat.test.d.ts +2 -0
- package/dist/__tests__/chat.test.js +357 -0
- package/dist/__tests__/chat.test.js.map +1 -0
- package/dist/__tests__/cli-base.test.d.ts +2 -0
- package/dist/__tests__/cli-base.test.js +87 -0
- package/dist/__tests__/cli-base.test.js.map +1 -0
- package/dist/__tests__/cli-missing.test.d.ts +2 -0
- package/dist/__tests__/cli-missing.test.js +546 -0
- package/dist/__tests__/cli-missing.test.js.map +1 -0
- package/dist/__tests__/cli-p0-scenarios.test.d.ts +2 -0
- package/dist/__tests__/cli-p0-scenarios.test.js +123 -0
- package/dist/__tests__/cli-p0-scenarios.test.js.map +1 -0
- package/dist/__tests__/helpers.d.ts +234 -0
- package/dist/__tests__/helpers.js +314 -0
- package/dist/__tests__/helpers.js.map +1 -0
- package/dist/__tests__/mcp.test.d.ts +2 -0
- package/dist/__tests__/mcp.test.js +470 -0
- package/dist/__tests__/mcp.test.js.map +1 -0
- package/dist/__tests__/prompts.test.d.ts +2 -0
- package/dist/__tests__/prompts.test.js +227 -0
- package/dist/__tests__/prompts.test.js.map +1 -0
- package/dist/__tests__/scenarios.test.d.ts +2 -0
- package/dist/__tests__/scenarios.test.js +270 -0
- package/dist/__tests__/scenarios.test.js.map +1 -0
- package/dist/__tests__/tools.test.d.ts +2 -0
- package/dist/__tests__/tools.test.js +331 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/__tests__/toolsets.test.d.ts +2 -0
- package/dist/__tests__/toolsets.test.js +196 -0
- package/dist/__tests__/toolsets.test.js.map +1 -0
- package/dist/__tests__/workspaces.test.d.ts +2 -0
- package/dist/__tests__/workspaces.test.js +155 -0
- package/dist/__tests__/workspaces.test.js.map +1 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/agents.js +194 -6
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/chat.js +2 -2
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/config.js +24 -2
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/customers.d.ts +8 -0
- package/dist/commands/customers.js +289 -0
- package/dist/commands/customers.js.map +1 -0
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/index.js +7 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/memory.js +134 -1
- package/dist/commands/memory.js.map +1 -1
- package/dist/commands/messaging.d.ts +12 -0
- package/dist/commands/messaging.js +208 -0
- package/dist/commands/messaging.js.map +1 -0
- package/dist/commands/prompts.js +148 -1
- package/dist/commands/prompts.js.map +1 -1
- package/dist/commands/scenarios.js +121 -0
- package/dist/commands/scenarios.js.map +1 -1
- package/dist/commands/scorecards.js +3 -3
- package/dist/commands/scorecards.js.map +1 -1
- package/dist/commands/whatsapp.d.ts +8 -0
- package/dist/commands/whatsapp.js +332 -0
- package/dist/commands/whatsapp.js.map +1 -0
- package/dist/utils/config-store.d.ts +8 -0
- package/dist/utils/config-store.js +18 -1
- package/dist/utils/config-store.js.map +1 -1
- package/dist/utils/sdk-factory.js +15 -3
- package/dist/utils/sdk-factory.js.map +1 -1
- package/package.json +4 -4
- package/dist/__tests__/cli.test.js +0 -2308
- package/dist/__tests__/cli.test.js.map +0 -1
- /package/dist/__tests__/{cli.test.d.ts → agents.test.d.ts} +0 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
2
|
+
import { configStore } from "../utils/config-store";
|
|
3
|
+
import { ChanlSDK } from "@chanl/sdk";
|
|
4
|
+
import {
|
|
5
|
+
runCli,
|
|
6
|
+
makeMockSdk,
|
|
7
|
+
setupAuthenticatedConfigStore
|
|
8
|
+
} from "./helpers";
|
|
9
|
+
vi.mock("@chanl/sdk", () => ({
|
|
10
|
+
ChanlSDK: vi.fn()
|
|
11
|
+
}));
|
|
12
|
+
vi.mock("../utils/config-store", () => ({
|
|
13
|
+
configStore: {
|
|
14
|
+
getApiKey: vi.fn(),
|
|
15
|
+
getBaseUrl: vi.fn(() => "https://api.chanl.ai"),
|
|
16
|
+
getWorkspaceId: vi.fn(() => "ws_123"),
|
|
17
|
+
getJwtToken: vi.fn(() => null),
|
|
18
|
+
getAuthMethod: vi.fn(() => null),
|
|
19
|
+
getAppUrl: vi.fn(() => "https://app.chanl.ai"),
|
|
20
|
+
getDeployment: vi.fn(() => "cloud"),
|
|
21
|
+
getApiPrefix: vi.fn(() => "/api/v1"),
|
|
22
|
+
setApiKey: vi.fn(),
|
|
23
|
+
setBaseUrl: vi.fn(),
|
|
24
|
+
setWorkspaceId: vi.fn(),
|
|
25
|
+
removeApiKey: vi.fn(),
|
|
26
|
+
clearAuth: vi.fn(),
|
|
27
|
+
delete: vi.fn(),
|
|
28
|
+
isAuthenticated: vi.fn(),
|
|
29
|
+
getPath: vi.fn(() => "/home/user/.chanl/config.json")
|
|
30
|
+
}
|
|
31
|
+
}));
|
|
32
|
+
describe("CLI", () => {
|
|
33
|
+
let mockSdk;
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
vi.clearAllMocks();
|
|
36
|
+
mockSdk = makeMockSdk();
|
|
37
|
+
ChanlSDK.mockImplementation(() => mockSdk);
|
|
38
|
+
setupAuthenticatedConfigStore(configStore);
|
|
39
|
+
});
|
|
40
|
+
afterEach(() => {
|
|
41
|
+
process.exitCode = void 0;
|
|
42
|
+
});
|
|
43
|
+
describe("workspaces list", () => {
|
|
44
|
+
it("should list workspaces with table output", async () => {
|
|
45
|
+
mockSdk.workspace.getAll.mockResolvedValue({
|
|
46
|
+
success: true,
|
|
47
|
+
data: [
|
|
48
|
+
{
|
|
49
|
+
id: "ws_abc123",
|
|
50
|
+
name: "My Workspace",
|
|
51
|
+
description: "Main workspace",
|
|
52
|
+
createdAt: "2025-01-01T00:00:00Z",
|
|
53
|
+
updatedAt: "2025-01-15T10:30:00Z"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: "ws_def456",
|
|
57
|
+
name: "Test Workspace",
|
|
58
|
+
description: "Testing environment",
|
|
59
|
+
createdAt: "2025-02-01T00:00:00Z",
|
|
60
|
+
updatedAt: "2025-02-05T10:30:00Z"
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
message: "Success",
|
|
64
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
65
|
+
});
|
|
66
|
+
const { logs, exitCode } = await runCli(["workspaces", "list"]);
|
|
67
|
+
expect(exitCode).toBe(0);
|
|
68
|
+
expect(mockSdk.workspace.getAll).toHaveBeenCalled();
|
|
69
|
+
const output = logs.join("\n");
|
|
70
|
+
expect(output).toContain("My Workspace");
|
|
71
|
+
expect(output).toContain("Test Workspace");
|
|
72
|
+
});
|
|
73
|
+
it("should list workspaces with JSON output", async () => {
|
|
74
|
+
const mockWorkspaces = [
|
|
75
|
+
{
|
|
76
|
+
id: "ws_abc123",
|
|
77
|
+
name: "My Workspace",
|
|
78
|
+
description: "Main workspace",
|
|
79
|
+
createdAt: "2025-01-01T00:00:00Z",
|
|
80
|
+
updatedAt: "2025-01-15T10:30:00Z"
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
mockSdk.workspace.getAll.mockResolvedValue({
|
|
84
|
+
success: true,
|
|
85
|
+
data: mockWorkspaces,
|
|
86
|
+
message: "Success",
|
|
87
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
88
|
+
});
|
|
89
|
+
const { logs, exitCode } = await runCli(["--json", "workspaces", "list"]);
|
|
90
|
+
expect(exitCode).toBe(0);
|
|
91
|
+
const output = logs.join("\n");
|
|
92
|
+
const parsed = JSON.parse(output);
|
|
93
|
+
expect(parsed).toHaveLength(1);
|
|
94
|
+
expect(parsed[0].name).toBe("My Workspace");
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe("workspaces get", () => {
|
|
98
|
+
it("should get workspace details by ID", async () => {
|
|
99
|
+
mockSdk.workspace.getById.mockResolvedValue({
|
|
100
|
+
success: true,
|
|
101
|
+
data: {
|
|
102
|
+
id: "ws_abc123",
|
|
103
|
+
name: "My Workspace",
|
|
104
|
+
description: "Main workspace",
|
|
105
|
+
settings: { timezone: "UTC" },
|
|
106
|
+
createdAt: "2025-01-01T00:00:00Z",
|
|
107
|
+
updatedAt: "2025-01-15T10:30:00Z"
|
|
108
|
+
},
|
|
109
|
+
message: "Success",
|
|
110
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
111
|
+
});
|
|
112
|
+
const { logs, exitCode } = await runCli(["workspaces", "get", "ws_abc123"]);
|
|
113
|
+
expect(exitCode).toBe(0);
|
|
114
|
+
expect(mockSdk.workspace.getById).toHaveBeenCalledWith("ws_abc123");
|
|
115
|
+
const output = logs.join("\n");
|
|
116
|
+
expect(output).toContain("My Workspace");
|
|
117
|
+
expect(output).toContain("ws_abc123");
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
describe("workspaces use", () => {
|
|
121
|
+
it("should set active workspace", async () => {
|
|
122
|
+
mockSdk.workspace.getById.mockResolvedValue({
|
|
123
|
+
success: true,
|
|
124
|
+
data: {
|
|
125
|
+
id: "ws_abc123",
|
|
126
|
+
name: "My Workspace",
|
|
127
|
+
description: "Main workspace",
|
|
128
|
+
settings: {},
|
|
129
|
+
createdAt: "2025-01-01T00:00:00Z",
|
|
130
|
+
updatedAt: "2025-01-15T10:30:00Z"
|
|
131
|
+
},
|
|
132
|
+
message: "Success",
|
|
133
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
134
|
+
});
|
|
135
|
+
const { logs, exitCode } = await runCli(["workspaces", "use", "ws_abc123"]);
|
|
136
|
+
expect(exitCode).toBe(0);
|
|
137
|
+
expect(configStore.setWorkspaceId).toHaveBeenCalledWith("ws_abc123");
|
|
138
|
+
const output = logs.join("\n");
|
|
139
|
+
expect(output).toContain("ws_abc123");
|
|
140
|
+
});
|
|
141
|
+
it("should handle invalid workspace ID", async () => {
|
|
142
|
+
mockSdk.workspace.getById.mockResolvedValue({
|
|
143
|
+
success: false,
|
|
144
|
+
data: null,
|
|
145
|
+
message: "Workspace not found",
|
|
146
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
147
|
+
});
|
|
148
|
+
const { exitCode, errors } = await runCli(["workspaces", "use", "ws_invalid"]);
|
|
149
|
+
expect(exitCode).toBe(1);
|
|
150
|
+
expect(errors.some((e) => e.includes("not found") || e.includes("Failed"))).toBe(true);
|
|
151
|
+
expect(configStore.setWorkspaceId).not.toHaveBeenCalled();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
//# sourceMappingURL=workspaces.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/__tests__/workspaces.test.ts"],"sourcesContent":["/**\n * CLI workspaces tests — workspaces list, workspaces get, workspaces use\n */\n\nimport { describe, it, expect, beforeEach, afterEach, vi, Mock } from 'vitest';\nimport { configStore } from '../utils/config-store';\nimport { ChanlSDK } from '@chanl/sdk';\nimport {\n runCli,\n makeMockSdk,\n setupAuthenticatedConfigStore,\n type MockSdk,\n} from './helpers';\n\n// Mock the SDK\nvi.mock('@chanl/sdk', () => ({\n ChanlSDK: vi.fn(),\n}));\n\n// Mock config store\nvi.mock('../utils/config-store', () => ({\n configStore: {\n getApiKey: vi.fn(),\n getBaseUrl: vi.fn(() => 'https://api.chanl.ai'),\n getWorkspaceId: vi.fn(() => 'ws_123'),\n getJwtToken: vi.fn(() => null),\n getAuthMethod: vi.fn(() => null),\n getAppUrl: vi.fn(() => 'https://app.chanl.ai'),\n getDeployment: vi.fn(() => 'cloud'),\n getApiPrefix: vi.fn(() => '/api/v1'),\n setApiKey: vi.fn(),\n setBaseUrl: vi.fn(),\n setWorkspaceId: vi.fn(),\n removeApiKey: vi.fn(),\n clearAuth: vi.fn(),\n delete: vi.fn(),\n isAuthenticated: vi.fn(),\n getPath: vi.fn(() => '/home/user/.chanl/config.json'),\n },\n}));\n\ndescribe('CLI', () => {\n let mockSdk: MockSdk;\n\n beforeEach(() => {\n vi.clearAllMocks();\n mockSdk = makeMockSdk();\n (ChanlSDK as Mock).mockImplementation(() => mockSdk);\n setupAuthenticatedConfigStore(configStore as unknown as {\n getApiKey: Mock;\n getWorkspaceId: Mock;\n isAuthenticated: Mock;\n });\n });\n\n afterEach(() => {\n process.exitCode = undefined;\n });\n\n // ==========================================================================\n // WORKSPACES CLI TESTS (Story 9)\n // ==========================================================================\n\n describe('workspaces list', () => {\n it('should list workspaces with table output', async () => {\n mockSdk.workspace.getAll.mockResolvedValue({\n success: true,\n data: [\n {\n id: 'ws_abc123',\n name: 'My Workspace',\n description: 'Main workspace',\n createdAt: '2025-01-01T00:00:00Z',\n updatedAt: '2025-01-15T10:30:00Z',\n },\n {\n id: 'ws_def456',\n name: 'Test Workspace',\n description: 'Testing environment',\n createdAt: '2025-02-01T00:00:00Z',\n updatedAt: '2025-02-05T10:30:00Z',\n },\n ],\n message: 'Success',\n timestamp: new Date().toISOString(),\n });\n\n const { logs, exitCode } = await runCli(['workspaces', 'list']);\n\n expect(exitCode).toBe(0);\n expect(mockSdk.workspace.getAll).toHaveBeenCalled();\n\n const output = logs.join('\\n');\n expect(output).toContain('My Workspace');\n expect(output).toContain('Test Workspace');\n });\n\n it('should list workspaces with JSON output', async () => {\n const mockWorkspaces = [\n {\n id: 'ws_abc123',\n name: 'My Workspace',\n description: 'Main workspace',\n createdAt: '2025-01-01T00:00:00Z',\n updatedAt: '2025-01-15T10:30:00Z',\n },\n ];\n\n mockSdk.workspace.getAll.mockResolvedValue({\n success: true,\n data: mockWorkspaces,\n message: 'Success',\n timestamp: new Date().toISOString(),\n });\n\n const { logs, exitCode } = await runCli(['--json', 'workspaces', 'list']);\n\n expect(exitCode).toBe(0);\n\n const output = logs.join('\\n');\n const parsed = JSON.parse(output);\n expect(parsed).toHaveLength(1);\n expect(parsed[0].name).toBe('My Workspace');\n });\n });\n\n describe('workspaces get', () => {\n it('should get workspace details by ID', async () => {\n mockSdk.workspace.getById.mockResolvedValue({\n success: true,\n data: {\n id: 'ws_abc123',\n name: 'My Workspace',\n description: 'Main workspace',\n settings: { timezone: 'UTC' },\n createdAt: '2025-01-01T00:00:00Z',\n updatedAt: '2025-01-15T10:30:00Z',\n },\n message: 'Success',\n timestamp: new Date().toISOString(),\n });\n\n const { logs, exitCode } = await runCli(['workspaces', 'get', 'ws_abc123']);\n\n expect(exitCode).toBe(0);\n expect(mockSdk.workspace.getById).toHaveBeenCalledWith('ws_abc123');\n\n const output = logs.join('\\n');\n expect(output).toContain('My Workspace');\n expect(output).toContain('ws_abc123');\n });\n });\n\n describe('workspaces use', () => {\n it('should set active workspace', async () => {\n mockSdk.workspace.getById.mockResolvedValue({\n success: true,\n data: {\n id: 'ws_abc123',\n name: 'My Workspace',\n description: 'Main workspace',\n settings: {},\n createdAt: '2025-01-01T00:00:00Z',\n updatedAt: '2025-01-15T10:30:00Z',\n },\n message: 'Success',\n timestamp: new Date().toISOString(),\n });\n\n const { logs, exitCode } = await runCli(['workspaces', 'use', 'ws_abc123']);\n\n expect(exitCode).toBe(0);\n expect(configStore.setWorkspaceId).toHaveBeenCalledWith('ws_abc123');\n\n const output = logs.join('\\n');\n expect(output).toContain('ws_abc123');\n });\n\n it('should handle invalid workspace ID', async () => {\n mockSdk.workspace.getById.mockResolvedValue({\n success: false,\n data: null,\n message: 'Workspace not found',\n timestamp: new Date().toISOString(),\n });\n\n const { exitCode, errors } = await runCli(['workspaces', 'use', 'ws_invalid']);\n\n expect(exitCode).toBe(1);\n expect(errors.some((e) => e.includes('not found') || e.includes('Failed'))).toBe(true);\n expect(configStore.setWorkspaceId).not.toHaveBeenCalled();\n });\n });\n});\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -12,6 +12,10 @@ import {
|
|
|
12
12
|
createCallCommand,
|
|
13
13
|
createCallsCommand,
|
|
14
14
|
createPersonasCommand,
|
|
15
|
+
createCustomersCommand,
|
|
16
|
+
createConversationsCommand,
|
|
17
|
+
createMessagesCommand,
|
|
18
|
+
createWhatsAppCommand,
|
|
15
19
|
createAgentsCommand,
|
|
16
20
|
createHealthCommand,
|
|
17
21
|
createMcpCommand,
|
|
@@ -43,6 +47,10 @@ function createProgram() {
|
|
|
43
47
|
program.addCommand(createCallCommand());
|
|
44
48
|
program.addCommand(createCallsCommand());
|
|
45
49
|
program.addCommand(createPersonasCommand());
|
|
50
|
+
program.addCommand(createCustomersCommand());
|
|
51
|
+
program.addCommand(createConversationsCommand());
|
|
52
|
+
program.addCommand(createMessagesCommand());
|
|
53
|
+
program.addCommand(createWhatsAppCommand());
|
|
46
54
|
program.addCommand(createAgentsCommand());
|
|
47
55
|
program.addCommand(createHealthCommand());
|
|
48
56
|
program.addCommand(createMcpCommand());
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createRequire } from 'module';\nimport { setOutputOptions } from './utils/output.js';\nimport {\n createAuthCommand,\n createLoginCommand,\n createLogoutCommand,\n createConfigCommand,\n createToolsCommand,\n createToolsetsCommand,\n createScenariosCommand,\n createCallCommand,\n createCallsCommand,\n createPersonasCommand,\n createAgentsCommand,\n createHealthCommand,\n createMcpCommand,\n createScorecardsCommand,\n createKnowledgeCommand,\n createMemoryCommand,\n createChatCommand,\n createPromptsCommand,\n createWorkspacesCommand,\n} from './commands/index.js';\n\nconst require = createRequire(import.meta.url);\nconst { version: CLI_VERSION } = require('../package.json') as { version: string };\n\n/**\n * Create and configure the CLI program\n */\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name('chanl')\n .description('Command-line interface for Chanl Analytics')\n .version(CLI_VERSION, '-v, --version', 'Show CLI version')\n .option('--json', 'Output results as JSON')\n .option('--no-color', 'Disable colored output')\n .hook('preAction', (thisCommand) => {\n // Set global output options before any command runs\n const opts = thisCommand.opts();\n setOutputOptions({\n json: opts['json'] === true,\n noColor: opts['color'] === false,\n });\n });\n\n // Add commands\n program.addCommand(createLoginCommand());\n program.addCommand(createLogoutCommand());\n program.addCommand(createAuthCommand());\n program.addCommand(createConfigCommand());\n program.addCommand(createToolsCommand());\n program.addCommand(createToolsetsCommand());\n program.addCommand(createScenariosCommand());\n program.addCommand(createCallCommand());\n program.addCommand(createCallsCommand());\n program.addCommand(createPersonasCommand());\n program.addCommand(createAgentsCommand());\n program.addCommand(createHealthCommand());\n program.addCommand(createMcpCommand());\n program.addCommand(createScorecardsCommand());\n program.addCommand(createKnowledgeCommand());\n program.addCommand(createMemoryCommand());\n program.addCommand(createChatCommand());\n program.addCommand(createPromptsCommand());\n program.addCommand(createWorkspacesCommand());\n\n // Add helpful error handling\n program.showHelpAfterError(true);\n program.showSuggestionAfterError(true);\n\n return program;\n}\n\n/**\n * Run the CLI program\n */\nexport async function run(argv: string[] = process.argv): Promise<void> {\n const program = createProgram();\n\n try {\n await program.parseAsync(argv);\n } catch (error) {\n // Commander handles most errors, but catch any unhandled ones\n if (error instanceof Error) {\n console.error('Error:', error.message);\n }\n process.exitCode = 1;\n }\n}\n"],"mappings":"AAAA,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAMA,WAAU,cAAc,YAAY,GAAG;AAC7C,MAAM,EAAE,SAAS,YAAY,IAAIA,SAAQ,iBAAiB;AAKnD,SAAS,gBAAyB;AACvC,QAAM,UAAU,IAAI,QAAQ;AAE5B,UACG,KAAK,OAAO,EACZ,YAAY,4CAA4C,EACxD,QAAQ,aAAa,iBAAiB,kBAAkB,EACxD,OAAO,UAAU,wBAAwB,EACzC,OAAO,cAAc,wBAAwB,EAC7C,KAAK,aAAa,CAAC,gBAAgB;AAElC,UAAM,OAAO,YAAY,KAAK;AAC9B,qBAAiB;AAAA,MACf,MAAM,KAAK,MAAM,MAAM;AAAA,MACvB,SAAS,KAAK,OAAO,MAAM;AAAA,IAC7B,CAAC;AAAA,EACH,CAAC;AAGH,UAAQ,WAAW,mBAAmB,CAAC;AACvC,UAAQ,WAAW,oBAAoB,CAAC;AACxC,UAAQ,WAAW,kBAAkB,CAAC;AACtC,UAAQ,WAAW,oBAAoB,CAAC;AACxC,UAAQ,WAAW,mBAAmB,CAAC;AACvC,UAAQ,WAAW,sBAAsB,CAAC;AAC1C,UAAQ,WAAW,uBAAuB,CAAC;AAC3C,UAAQ,WAAW,kBAAkB,CAAC;AACtC,UAAQ,WAAW,mBAAmB,CAAC;AACvC,UAAQ,WAAW,sBAAsB,CAAC;AAC1C,UAAQ,WAAW,oBAAoB,CAAC;AACxC,UAAQ,WAAW,oBAAoB,CAAC;AACxC,UAAQ,WAAW,iBAAiB,CAAC;AACrC,UAAQ,WAAW,wBAAwB,CAAC;AAC5C,UAAQ,WAAW,uBAAuB,CAAC;AAC3C,UAAQ,WAAW,oBAAoB,CAAC;AACxC,UAAQ,WAAW,kBAAkB,CAAC;AACtC,UAAQ,WAAW,qBAAqB,CAAC;AACzC,UAAQ,WAAW,wBAAwB,CAAC;AAG5C,UAAQ,mBAAmB,IAAI;AAC/B,UAAQ,yBAAyB,IAAI;AAErC,SAAO;AACT;AAKA,eAAsB,IAAI,OAAiB,QAAQ,MAAqB;AACtE,QAAM,UAAU,cAAc;AAE9B,MAAI;AACF,UAAM,QAAQ,WAAW,IAAI;AAAA,EAC/B,SAAS,OAAO;AAEd,QAAI,iBAAiB,OAAO;AAC1B,cAAQ,MAAM,UAAU,MAAM,OAAO;AAAA,IACvC;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;","names":["require"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createRequire } from 'module';\nimport { setOutputOptions } from './utils/output.js';\nimport {\n createAuthCommand,\n createLoginCommand,\n createLogoutCommand,\n createConfigCommand,\n createToolsCommand,\n createToolsetsCommand,\n createScenariosCommand,\n createCallCommand,\n createCallsCommand,\n createPersonasCommand,\n createCustomersCommand,\n createConversationsCommand,\n createMessagesCommand,\n createWhatsAppCommand,\n createAgentsCommand,\n createHealthCommand,\n createMcpCommand,\n createScorecardsCommand,\n createKnowledgeCommand,\n createMemoryCommand,\n createChatCommand,\n createPromptsCommand,\n createWorkspacesCommand,\n} from './commands/index.js';\n\nconst require = createRequire(import.meta.url);\nconst { version: CLI_VERSION } = require('../package.json') as { version: string };\n\n/**\n * Create and configure the CLI program\n */\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name('chanl')\n .description('Command-line interface for Chanl Analytics')\n .version(CLI_VERSION, '-v, --version', 'Show CLI version')\n .option('--json', 'Output results as JSON')\n .option('--no-color', 'Disable colored output')\n .hook('preAction', (thisCommand) => {\n // Set global output options before any command runs\n const opts = thisCommand.opts();\n setOutputOptions({\n json: opts['json'] === true,\n noColor: opts['color'] === false,\n });\n });\n\n // Add commands\n program.addCommand(createLoginCommand());\n program.addCommand(createLogoutCommand());\n program.addCommand(createAuthCommand());\n program.addCommand(createConfigCommand());\n program.addCommand(createToolsCommand());\n program.addCommand(createToolsetsCommand());\n program.addCommand(createScenariosCommand());\n program.addCommand(createCallCommand());\n program.addCommand(createCallsCommand());\n program.addCommand(createPersonasCommand());\n program.addCommand(createCustomersCommand());\n program.addCommand(createConversationsCommand());\n program.addCommand(createMessagesCommand());\n program.addCommand(createWhatsAppCommand());\n program.addCommand(createAgentsCommand());\n program.addCommand(createHealthCommand());\n program.addCommand(createMcpCommand());\n program.addCommand(createScorecardsCommand());\n program.addCommand(createKnowledgeCommand());\n program.addCommand(createMemoryCommand());\n program.addCommand(createChatCommand());\n program.addCommand(createPromptsCommand());\n program.addCommand(createWorkspacesCommand());\n\n // Add helpful error handling\n program.showHelpAfterError(true);\n program.showSuggestionAfterError(true);\n\n return program;\n}\n\n/**\n * Run the CLI program\n */\nexport async function run(argv: string[] = process.argv): Promise<void> {\n const program = createProgram();\n\n try {\n await program.parseAsync(argv);\n } catch (error) {\n // Commander handles most errors, but catch any unhandled ones\n if (error instanceof Error) {\n console.error('Error:', error.message);\n }\n process.exitCode = 1;\n }\n}\n"],"mappings":"AAAA,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAMA,WAAU,cAAc,YAAY,GAAG;AAC7C,MAAM,EAAE,SAAS,YAAY,IAAIA,SAAQ,iBAAiB;AAKnD,SAAS,gBAAyB;AACvC,QAAM,UAAU,IAAI,QAAQ;AAE5B,UACG,KAAK,OAAO,EACZ,YAAY,4CAA4C,EACxD,QAAQ,aAAa,iBAAiB,kBAAkB,EACxD,OAAO,UAAU,wBAAwB,EACzC,OAAO,cAAc,wBAAwB,EAC7C,KAAK,aAAa,CAAC,gBAAgB;AAElC,UAAM,OAAO,YAAY,KAAK;AAC9B,qBAAiB;AAAA,MACf,MAAM,KAAK,MAAM,MAAM;AAAA,MACvB,SAAS,KAAK,OAAO,MAAM;AAAA,IAC7B,CAAC;AAAA,EACH,CAAC;AAGH,UAAQ,WAAW,mBAAmB,CAAC;AACvC,UAAQ,WAAW,oBAAoB,CAAC;AACxC,UAAQ,WAAW,kBAAkB,CAAC;AACtC,UAAQ,WAAW,oBAAoB,CAAC;AACxC,UAAQ,WAAW,mBAAmB,CAAC;AACvC,UAAQ,WAAW,sBAAsB,CAAC;AAC1C,UAAQ,WAAW,uBAAuB,CAAC;AAC3C,UAAQ,WAAW,kBAAkB,CAAC;AACtC,UAAQ,WAAW,mBAAmB,CAAC;AACvC,UAAQ,WAAW,sBAAsB,CAAC;AAC1C,UAAQ,WAAW,uBAAuB,CAAC;AAC3C,UAAQ,WAAW,2BAA2B,CAAC;AAC/C,UAAQ,WAAW,sBAAsB,CAAC;AAC1C,UAAQ,WAAW,sBAAsB,CAAC;AAC1C,UAAQ,WAAW,oBAAoB,CAAC;AACxC,UAAQ,WAAW,oBAAoB,CAAC;AACxC,UAAQ,WAAW,iBAAiB,CAAC;AACrC,UAAQ,WAAW,wBAAwB,CAAC;AAC5C,UAAQ,WAAW,uBAAuB,CAAC;AAC3C,UAAQ,WAAW,oBAAoB,CAAC;AACxC,UAAQ,WAAW,kBAAkB,CAAC;AACtC,UAAQ,WAAW,qBAAqB,CAAC;AACzC,UAAQ,WAAW,wBAAwB,CAAC;AAG5C,UAAQ,mBAAmB,IAAI;AAC/B,UAAQ,yBAAyB,IAAI;AAErC,SAAO;AACT;AAKA,eAAsB,IAAI,OAAiB,QAAQ,MAAqB;AACtE,QAAM,UAAU,cAAc;AAE9B,MAAI;AACF,UAAM,QAAQ,WAAW,IAAI;AAAA,EAC/B,SAAS,OAAO;AAEd,QAAI,iBAAiB,OAAO;AAC1B,cAAQ,MAAM,UAAU,MAAM,OAAO;AAAA,IACvC;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;","names":["require"]}
|
package/dist/commands/agents.js
CHANGED
|
@@ -27,7 +27,9 @@ Quick Start:
|
|
|
27
27
|
$ chanl agents list # List all agents
|
|
28
28
|
$ chanl agents get <id> # View agent details
|
|
29
29
|
$ chanl agents sync vapi # Sync from VAPI
|
|
30
|
-
$ chanl agents
|
|
30
|
+
$ chanl agents templates # List provisionable templates
|
|
31
|
+
$ chanl agents create --from-template lead-qualifier --name "Lead Gen Bot"
|
|
32
|
+
$ chanl agents create --template vapi # Generate local VAPI scaffold
|
|
31
33
|
$ chanl agents stats # View statistics
|
|
32
34
|
|
|
33
35
|
Workflow:
|
|
@@ -52,15 +54,29 @@ Examples:
|
|
|
52
54
|
$ chanl agents get abc123 # Get agent details
|
|
53
55
|
$ chanl agents get abc123 --json # Output as JSON`
|
|
54
56
|
).action(handleAgentsGet);
|
|
55
|
-
agents.command("
|
|
57
|
+
agents.command("templates").description("List registry templates you can provision an agent from").addHelpText(
|
|
56
58
|
"after",
|
|
57
59
|
`
|
|
58
60
|
Examples:
|
|
59
|
-
$ chanl agents
|
|
60
|
-
$ chanl agents
|
|
61
|
+
$ chanl agents templates # List registry templates
|
|
62
|
+
$ chanl agents templates --json # Output as JSON
|
|
63
|
+
|
|
64
|
+
Provision one with:
|
|
65
|
+
$ chanl agents create --from-template lead-qualifier --name "My Agent"`
|
|
66
|
+
).action(handleAgentsTemplates);
|
|
67
|
+
agents.command("create").description("Create a new agent").option("-f, --file <path>", "Path to JSON file with agent data").option("--template [platform]", "Output a local scaffold JSON (vapi, elevenlabs, custom) \u2014 no server call").option("--from-template <templateId>", "Provision from a registry template (see 'chanl agents templates')").option("-n, --name <name>", "Agent name (used with --from-template)").addHelpText(
|
|
68
|
+
"after",
|
|
69
|
+
`
|
|
70
|
+
Examples:
|
|
71
|
+
$ chanl agents create --from-template lead-qualifier --name "Lead Gen Bot"
|
|
72
|
+
# Provision from registry template
|
|
73
|
+
$ chanl agents create --template vapi > agent.json # VAPI scaffold JSON (local, no server call)
|
|
74
|
+
$ chanl agents create --template custom > agent.json # Custom scaffold JSON
|
|
61
75
|
$ chanl agents create -f agent.json # Create from file
|
|
62
76
|
|
|
63
|
-
|
|
77
|
+
'--from-template' creates a real, configured agent via the platform's template
|
|
78
|
+
registry (run 'chanl agents templates' to see what's available). '--template'
|
|
79
|
+
just prints a local JSON scaffold to fill in yourself.`
|
|
64
80
|
).action(handleAgentsCreate);
|
|
65
81
|
agents.command("update <id>").description("Update an existing agent").option("-f, --file <path>", "Path to JSON file with update data").option("--sync-to-vapi", "Sync changes back to VAPI platform").addHelpText(
|
|
66
82
|
"after",
|
|
@@ -116,6 +132,21 @@ Examples:
|
|
|
116
132
|
$ chanl agents push-mcp agent_123 --to vapi --target ext_456
|
|
117
133
|
$ chanl agents push-mcp agent_123 --to vapi --json`
|
|
118
134
|
).action(handleAgentsPushMcp);
|
|
135
|
+
agents.command("clone <id>").description("Clone an agent with optional overrides").option("-n, --name <name>", "New agent name").option("--model <provider/model>", "Override model (e.g., anthropic/claude-sonnet-4-5-20250929)").option("--type <type>", "Override type (voice, text, hybrid)").option("--platform <platform>", "Override platform").option("--prompt <text>", "Override system prompt").addHelpText(
|
|
136
|
+
"after",
|
|
137
|
+
`
|
|
138
|
+
Examples:
|
|
139
|
+
$ chanl agents clone agent_abc -n "Copy of Bot"
|
|
140
|
+
$ chanl agents clone agent_abc --model openai/gpt-4o-mini --type text
|
|
141
|
+
$ chanl agents clone agent_abc --json`
|
|
142
|
+
).action(handleAgentsClone);
|
|
143
|
+
agents.command("report <agentId>").description("View scenario test report for an agent").option("--from <date>", "Report start date (ISO)").option("--to <date>", "Report end date (ISO)").addHelpText(
|
|
144
|
+
"after",
|
|
145
|
+
`
|
|
146
|
+
Examples:
|
|
147
|
+
$ chanl agents report agent_abc
|
|
148
|
+
$ chanl agents report agent_abc --json`
|
|
149
|
+
).action(handleAgentsReport);
|
|
119
150
|
agents.command("stats").description("View agent statistics").addHelpText(
|
|
120
151
|
"after",
|
|
121
152
|
`
|
|
@@ -293,6 +324,73 @@ async function handleAgentsGet(id) {
|
|
|
293
324
|
process.exitCode = 1;
|
|
294
325
|
}
|
|
295
326
|
}
|
|
327
|
+
async function handleAgentsTemplates() {
|
|
328
|
+
const sdk = createSdk();
|
|
329
|
+
if (!sdk) return;
|
|
330
|
+
const spinner = ora("Fetching templates...").start();
|
|
331
|
+
try {
|
|
332
|
+
const response = await sdk.agents.listTemplates();
|
|
333
|
+
spinner.stop();
|
|
334
|
+
if (!response.success || !response.data) {
|
|
335
|
+
printError("Failed to fetch templates", response.message);
|
|
336
|
+
process.exitCode = 1;
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const { templates } = response.data;
|
|
340
|
+
if (isJsonOutput()) {
|
|
341
|
+
printJson(response.data);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (templates.length === 0) {
|
|
345
|
+
printInfo("No templates available");
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
printBlank();
|
|
349
|
+
printSimpleTable(
|
|
350
|
+
["ID", "Name", "Version", "Description"],
|
|
351
|
+
templates.map((t) => [t.id, t.name, t.version.toString(), t.description])
|
|
352
|
+
);
|
|
353
|
+
printBlank();
|
|
354
|
+
printInfo('Provision one with: chanl agents create --from-template <id> --name "My Agent"');
|
|
355
|
+
} catch (error) {
|
|
356
|
+
spinner.fail("Failed to fetch templates");
|
|
357
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
358
|
+
printError("Error", message);
|
|
359
|
+
process.exitCode = 1;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
async function handleAgentsCreateFromTemplate(templateId, name) {
|
|
363
|
+
if (!name) {
|
|
364
|
+
printError("Missing required option", "Use '-n, --name <name>' together with --from-template");
|
|
365
|
+
process.exitCode = 1;
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
const sdk = createSdk();
|
|
369
|
+
if (!sdk) return;
|
|
370
|
+
const spinner = ora(`Provisioning agent from template '${templateId}'...`).start();
|
|
371
|
+
try {
|
|
372
|
+
const response = await sdk.agents.createFromTemplate(templateId, { name });
|
|
373
|
+
spinner.stop();
|
|
374
|
+
if (!response.success || !response.data) {
|
|
375
|
+
printError("Failed to create agent from template", response.message);
|
|
376
|
+
process.exitCode = 1;
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
if (isJsonOutput()) {
|
|
380
|
+
printJson(response.data);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const agent = response.data;
|
|
384
|
+
printSuccess(`Agent created from template: ${agent.name}`);
|
|
385
|
+
printLabel("ID", agent.id);
|
|
386
|
+
printLabel("Template", templateId);
|
|
387
|
+
} catch (error) {
|
|
388
|
+
spinner.fail("Failed to create agent from template");
|
|
389
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
390
|
+
printError("Error", message);
|
|
391
|
+
process.exitCode = 1;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
296
394
|
async function handleAgentsCreate(options) {
|
|
297
395
|
if (options.template !== void 0) {
|
|
298
396
|
const platform = typeof options.template === "string" ? options.template : "custom";
|
|
@@ -300,8 +398,15 @@ async function handleAgentsCreate(options) {
|
|
|
300
398
|
console.log(JSON.stringify(template, null, 2));
|
|
301
399
|
return;
|
|
302
400
|
}
|
|
401
|
+
if (options.fromTemplate) {
|
|
402
|
+
await handleAgentsCreateFromTemplate(options.fromTemplate, options.name);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
303
405
|
if (!options.file) {
|
|
304
|
-
printError(
|
|
406
|
+
printError(
|
|
407
|
+
"Missing required option",
|
|
408
|
+
"Use '-f <file>' for agent data, '--from-template <id>' to provision from a registry template, or '--template [platform]' for a local scaffold"
|
|
409
|
+
);
|
|
305
410
|
process.exitCode = 1;
|
|
306
411
|
return;
|
|
307
412
|
}
|
|
@@ -665,6 +770,89 @@ async function handleAgentsStats() {
|
|
|
665
770
|
process.exitCode = 1;
|
|
666
771
|
}
|
|
667
772
|
}
|
|
773
|
+
async function handleAgentsClone(id, options) {
|
|
774
|
+
const sdk = createSdk();
|
|
775
|
+
if (!sdk) return;
|
|
776
|
+
const spinner = ora("Cloning agent...").start();
|
|
777
|
+
try {
|
|
778
|
+
const response = await sdk.agents.clone(id, {
|
|
779
|
+
name: options.name,
|
|
780
|
+
model: options.model,
|
|
781
|
+
type: options.type,
|
|
782
|
+
platform: options.platform,
|
|
783
|
+
prompt: options.prompt
|
|
784
|
+
});
|
|
785
|
+
spinner.stop();
|
|
786
|
+
if (!response.success || !response.data) {
|
|
787
|
+
printError("Clone failed", response.message);
|
|
788
|
+
process.exitCode = 1;
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
const cloned = response.data;
|
|
792
|
+
if (isJsonOutput()) {
|
|
793
|
+
printJson(cloned);
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
printBlank();
|
|
797
|
+
console.log(chalk.green(`Cloned agent: ${cloned.id}`));
|
|
798
|
+
printLabel("Name", cloned.name);
|
|
799
|
+
if (cloned.type) printLabel("Type", cloned.type);
|
|
800
|
+
if (cloned.platform) printLabel("Platform", cloned.platform);
|
|
801
|
+
const model = cloned.configuration?.model;
|
|
802
|
+
if (model?.provider && model?.model) {
|
|
803
|
+
printLabel("Model", `${model.provider} / ${model.model}`);
|
|
804
|
+
}
|
|
805
|
+
printLabel("Cloned from", id);
|
|
806
|
+
printBlank();
|
|
807
|
+
} catch (error) {
|
|
808
|
+
spinner.fail("Clone failed");
|
|
809
|
+
printError("Error", error instanceof Error ? error.message : "Unknown error");
|
|
810
|
+
process.exitCode = 1;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
async function handleAgentsReport(agentId, options) {
|
|
814
|
+
const sdk = createSdk();
|
|
815
|
+
if (!sdk) return;
|
|
816
|
+
const spinner = ora("Fetching agent test report...").start();
|
|
817
|
+
try {
|
|
818
|
+
const response = await sdk.scenarios.getAgentTestReport(agentId, {
|
|
819
|
+
from: options.from,
|
|
820
|
+
to: options.to
|
|
821
|
+
});
|
|
822
|
+
spinner.stop();
|
|
823
|
+
if (!response.success || !response.data) {
|
|
824
|
+
printError("Failed to fetch report", response.message);
|
|
825
|
+
process.exitCode = 1;
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
if (isJsonOutput()) {
|
|
829
|
+
printJson(response.data);
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
const report = response.data;
|
|
833
|
+
printBlank();
|
|
834
|
+
console.log(chalk.bold(`Test Report: ${agentId}`));
|
|
835
|
+
console.log(` Total runs: ${report.totalRuns} Passed: ${report.passed} Failed: ${report.failed}`);
|
|
836
|
+
console.log(` Avg score: ${report.avgScore}% Success rate: ${report.successRate}%`);
|
|
837
|
+
if (report.scenarios?.length) {
|
|
838
|
+
printBlank();
|
|
839
|
+
printSimpleTable(
|
|
840
|
+
["Scenario", "Runs", "Avg Score", "Last Passed"],
|
|
841
|
+
report.scenarios.map((s) => [
|
|
842
|
+
s.scenarioName,
|
|
843
|
+
s.runs.toString(),
|
|
844
|
+
`${s.avgScore}%`,
|
|
845
|
+
s.lastPassed ? chalk.green("yes") : chalk.red("no")
|
|
846
|
+
])
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
printBlank();
|
|
850
|
+
} catch (error) {
|
|
851
|
+
spinner.fail("Failed to fetch report");
|
|
852
|
+
printError("Error", error instanceof Error ? error.message : "Unknown error");
|
|
853
|
+
process.exitCode = 1;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
668
856
|
export {
|
|
669
857
|
createAgentsCommand
|
|
670
858
|
};
|