@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.
- package/bin/chanl.js +10 -0
- package/dist/__tests__/cli.test.d.ts +2 -0
- package/dist/__tests__/cli.test.js +2313 -0
- package/dist/__tests__/cli.test.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.js +72 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/agents.d.ts +8 -0
- package/dist/commands/agents.js +671 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/auth.d.ts +16 -0
- package/dist/commands/auth.js +294 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/call.d.ts +8 -0
- package/dist/commands/call.js +166 -0
- package/dist/commands/call.js.map +1 -0
- package/dist/commands/calls.d.ts +8 -0
- package/dist/commands/calls.js +719 -0
- package/dist/commands/calls.js.map +1 -0
- package/dist/commands/chat.d.ts +8 -0
- package/dist/commands/chat.js +203 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.js +231 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/health.d.ts +8 -0
- package/dist/commands/health.js +55 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/index.d.ts +18 -0
- package/dist/commands/index.js +39 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/knowledge.d.ts +8 -0
- package/dist/commands/knowledge.js +539 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/mcp.d.ts +8 -0
- package/dist/commands/mcp.js +589 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/memory.d.ts +8 -0
- package/dist/commands/memory.js +408 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/personas.d.ts +8 -0
- package/dist/commands/personas.js +356 -0
- package/dist/commands/personas.js.map +1 -0
- package/dist/commands/prompts.d.ts +8 -0
- package/dist/commands/prompts.js +295 -0
- package/dist/commands/prompts.js.map +1 -0
- package/dist/commands/scenarios.d.ts +8 -0
- package/dist/commands/scenarios.js +591 -0
- package/dist/commands/scenarios.js.map +1 -0
- package/dist/commands/scorecards.d.ts +8 -0
- package/dist/commands/scorecards.js +570 -0
- package/dist/commands/scorecards.js.map +1 -0
- package/dist/commands/tools.d.ts +8 -0
- package/dist/commands/tools.js +632 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/commands/toolsets.d.ts +8 -0
- package/dist/commands/toolsets.js +464 -0
- package/dist/commands/toolsets.js.map +1 -0
- package/dist/commands/workspaces.d.ts +8 -0
- package/dist/commands/workspaces.js +170 -0
- package/dist/commands/workspaces.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/config-store.d.ts +117 -0
- package/dist/utils/config-store.js +191 -0
- package/dist/utils/config-store.js.map +1 -0
- package/dist/utils/interactive.d.ts +41 -0
- package/dist/utils/interactive.js +83 -0
- package/dist/utils/interactive.js.map +1 -0
- package/dist/utils/output.d.ts +100 -0
- package/dist/utils/output.js +221 -0
- package/dist/utils/output.js.map +1 -0
- package/dist/utils/sdk-factory.d.ts +15 -0
- package/dist/utils/sdk-factory.js +34 -0
- package/dist/utils/sdk-factory.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { readFile } from "fs/promises";
|
|
3
|
+
import { confirm } from "@inquirer/prompts";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { createSdk } from "../utils/sdk-factory.js";
|
|
7
|
+
import {
|
|
8
|
+
printSuccess,
|
|
9
|
+
printError,
|
|
10
|
+
printInfo,
|
|
11
|
+
printLabel,
|
|
12
|
+
printBlank,
|
|
13
|
+
printSimpleTable,
|
|
14
|
+
isJsonOutput,
|
|
15
|
+
printJson,
|
|
16
|
+
formatDate
|
|
17
|
+
} from "../utils/output.js";
|
|
18
|
+
const TOOL_TEMPLATES = {
|
|
19
|
+
http: {
|
|
20
|
+
name: "my-api-tool",
|
|
21
|
+
description: "Calls an external API endpoint",
|
|
22
|
+
type: "http",
|
|
23
|
+
inputSchema: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
query: { type: "string", description: "Search query" }
|
|
27
|
+
},
|
|
28
|
+
required: ["query"]
|
|
29
|
+
},
|
|
30
|
+
configuration: {
|
|
31
|
+
http: {
|
|
32
|
+
method: "POST",
|
|
33
|
+
url: "https://api.example.com/search",
|
|
34
|
+
headers: { "Content-Type": "application/json" },
|
|
35
|
+
bodyTemplate: '{"q": "{{query}}"}'
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
isEnabled: true,
|
|
39
|
+
tags: ["api", "search"]
|
|
40
|
+
},
|
|
41
|
+
javascript: {
|
|
42
|
+
name: "my-js-tool",
|
|
43
|
+
description: "Executes JavaScript code",
|
|
44
|
+
type: "javascript",
|
|
45
|
+
inputSchema: {
|
|
46
|
+
type: "object",
|
|
47
|
+
properties: {
|
|
48
|
+
a: { type: "number", description: "First number" },
|
|
49
|
+
b: { type: "number", description: "Second number" }
|
|
50
|
+
},
|
|
51
|
+
required: ["a", "b"]
|
|
52
|
+
},
|
|
53
|
+
configuration: {
|
|
54
|
+
javascript: {
|
|
55
|
+
code: "return { result: args.a + args.b };"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
isEnabled: true
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
function createToolsCommand() {
|
|
62
|
+
const tools = new Command("tools").description("Manage MCP tools");
|
|
63
|
+
tools.command("list").description("List all tools in the workspace").option("-t, --type <type>", "Filter by type: http, javascript, code").option("-e, --enabled", "Show only enabled tools").option("-d, --disabled", "Show only disabled tools").option("--tag <tag>", "Filter by tag (e.g., --tag api)").option("--no-system", "Exclude system tools (kb_search, chanl_reason, etc.)").option("-l, --limit <number>", "Items per page (default: 20)", "20").option("-p, --page <number>", "Page number (default: 1)", "1").addHelpText(
|
|
64
|
+
"after",
|
|
65
|
+
`
|
|
66
|
+
Examples:
|
|
67
|
+
$ chanl tools list # List all tools
|
|
68
|
+
$ chanl tools list --enabled # Only enabled tools
|
|
69
|
+
$ chanl tools list --type http # Only HTTP tools
|
|
70
|
+
$ chanl tools list --tag api # Filter by tag
|
|
71
|
+
$ chanl tools list --no-system # Exclude system tools
|
|
72
|
+
$ chanl tools list --json # Output as JSON`
|
|
73
|
+
).action(handleToolsList);
|
|
74
|
+
tools.command("get <id>").description("Get detailed info about a tool").addHelpText(
|
|
75
|
+
"after",
|
|
76
|
+
`
|
|
77
|
+
Examples:
|
|
78
|
+
$ chanl tools get 507f1f77bcf86cd799439011
|
|
79
|
+
$ chanl tools get 507f1f77bcf86cd799439011 --json`
|
|
80
|
+
).action(handleToolsGet);
|
|
81
|
+
tools.command("create").description("Create a new tool from JSON file").option("-f, --file <path>", "Path to JSON file with tool definition").option("--template [type]", "Output a sample JSON template (http or javascript)").addHelpText(
|
|
82
|
+
"after",
|
|
83
|
+
`
|
|
84
|
+
Examples:
|
|
85
|
+
$ chanl tools create --template http > my-tool.json # Generate template
|
|
86
|
+
$ chanl tools create -f my-tool.json # Create from file
|
|
87
|
+
|
|
88
|
+
Required JSON fields:
|
|
89
|
+
name Tool name (used in MCP)
|
|
90
|
+
description What the tool does
|
|
91
|
+
type "http" | "javascript" | "code"
|
|
92
|
+
inputSchema JSON Schema for input parameters
|
|
93
|
+
configuration Tool-specific config (http.url, http.method, etc.)
|
|
94
|
+
|
|
95
|
+
Optional fields:
|
|
96
|
+
isEnabled Enable immediately (default: true)
|
|
97
|
+
tags Array of category tags
|
|
98
|
+
|
|
99
|
+
Run 'chanl tools create --template' to see full structure.`
|
|
100
|
+
).action(handleToolsCreate);
|
|
101
|
+
tools.command("update <id>").description("Update a tool from JSON file").requiredOption("-f, --file <path>", "Path to JSON file with updates").addHelpText(
|
|
102
|
+
"after",
|
|
103
|
+
`
|
|
104
|
+
Examples:
|
|
105
|
+
$ chanl tools update 507f1f77bcf86cd799439011 -f updates.json
|
|
106
|
+
|
|
107
|
+
The JSON file only needs fields you want to change:
|
|
108
|
+
{"description": "Updated description", "isEnabled": false}`
|
|
109
|
+
).action(handleToolsUpdate);
|
|
110
|
+
tools.command("delete <id>").description("Delete a tool permanently").option("-y, --yes", "Skip confirmation prompt").addHelpText(
|
|
111
|
+
"after",
|
|
112
|
+
`
|
|
113
|
+
Examples:
|
|
114
|
+
$ chanl tools delete 507f1f77bcf86cd799439011 # With confirmation
|
|
115
|
+
$ chanl tools delete 507f1f77bcf86cd799439011 -y # Skip confirmation`
|
|
116
|
+
).action(handleToolsDelete);
|
|
117
|
+
tools.command("execute <id>").description("Execute a tool and get results").requiredOption("-i, --input <json>", "Input arguments as JSON string").addHelpText(
|
|
118
|
+
"after",
|
|
119
|
+
`
|
|
120
|
+
Examples:
|
|
121
|
+
$ chanl tools execute 507f1f77bcf86cd799439011 -i '{"query": "hello"}'
|
|
122
|
+
$ chanl tools execute my-tool-id -i '{"location": "London"}' --json`
|
|
123
|
+
).action(handleToolsExecute);
|
|
124
|
+
tools.command("test <id>").description("Test a tool execution (dry run)").requiredOption("-i, --input <json>", "Input arguments as JSON string").addHelpText(
|
|
125
|
+
"after",
|
|
126
|
+
`
|
|
127
|
+
Examples:
|
|
128
|
+
$ chanl tools test 507f1f77bcf86cd799439011 -i '{"message": "test"}'`
|
|
129
|
+
).action(handleToolsTest);
|
|
130
|
+
tools.command("executions <id>").description("Get execution history for a tool").option("-l, --limit <number>", "Items per page (default: 10)", "10").option("-p, --page <number>", "Page number (default: 1)", "1").option("--status <status>", "Filter: pending, running, completed, failed").addHelpText(
|
|
131
|
+
"after",
|
|
132
|
+
`
|
|
133
|
+
Examples:
|
|
134
|
+
$ chanl tools executions 507f1f77bcf86cd799439011
|
|
135
|
+
$ chanl tools executions my-tool-id --status failed --limit 5`
|
|
136
|
+
).action(handleToolsExecutions);
|
|
137
|
+
tools.command("enable <id>").description("Enable a tool (makes it available in MCP)").action(handleToolsEnable);
|
|
138
|
+
tools.command("disable <id>").description("Disable a tool (hides from MCP)").action(handleToolsDisable);
|
|
139
|
+
tools.command("categories").description("Show tool categories (tags) with counts").addHelpText(
|
|
140
|
+
"after",
|
|
141
|
+
`
|
|
142
|
+
Shows all tags used across tools with:
|
|
143
|
+
- Total tools in each category
|
|
144
|
+
- Number of enabled tools`
|
|
145
|
+
).action(handleToolsCategories);
|
|
146
|
+
return tools;
|
|
147
|
+
}
|
|
148
|
+
async function handleToolsList(options) {
|
|
149
|
+
const sdk = createSdk();
|
|
150
|
+
if (!sdk) return;
|
|
151
|
+
const spinner = ora("Fetching tools...").start();
|
|
152
|
+
try {
|
|
153
|
+
let isEnabled;
|
|
154
|
+
if (options.enabled) isEnabled = true;
|
|
155
|
+
else if (options.disabled) isEnabled = false;
|
|
156
|
+
const response = await sdk.tools.list({
|
|
157
|
+
type: options.type,
|
|
158
|
+
isEnabled,
|
|
159
|
+
tag: options.tag,
|
|
160
|
+
includeSystem: options.system,
|
|
161
|
+
// --no-system sets this to false
|
|
162
|
+
limit: parseInt(options.limit, 10),
|
|
163
|
+
page: parseInt(options.page, 10)
|
|
164
|
+
});
|
|
165
|
+
spinner.stop();
|
|
166
|
+
if (!response.success || !response.data) {
|
|
167
|
+
printError("Failed to fetch tools", response.message);
|
|
168
|
+
process.exitCode = 1;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const { tools, total, pagination } = response.data;
|
|
172
|
+
if (isJsonOutput()) {
|
|
173
|
+
printJson({ tools, total, pagination });
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (tools.length === 0) {
|
|
177
|
+
printInfo("No tools found");
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
printBlank();
|
|
181
|
+
printSimpleTable(
|
|
182
|
+
["Name", "Type", "Enabled", "Tags", "Last Called"],
|
|
183
|
+
tools.map((tool) => [
|
|
184
|
+
tool.name,
|
|
185
|
+
tool.type,
|
|
186
|
+
tool.isEnabled ? chalk.green("\u2713") : chalk.red("\u2717"),
|
|
187
|
+
tool.tags.length > 0 ? tool.tags.join(", ") : "-",
|
|
188
|
+
tool.stats.lastCalledAt ? formatDate(tool.stats.lastCalledAt) : "Never"
|
|
189
|
+
])
|
|
190
|
+
);
|
|
191
|
+
printBlank();
|
|
192
|
+
printInfo(`Total: ${total} tools (Page ${pagination.page} of ${pagination.totalPages})`);
|
|
193
|
+
} catch (error) {
|
|
194
|
+
spinner.fail("Failed to fetch tools");
|
|
195
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
196
|
+
printError("Error", message);
|
|
197
|
+
process.exitCode = 1;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async function handleToolsGet(id) {
|
|
201
|
+
const sdk = createSdk();
|
|
202
|
+
if (!sdk) return;
|
|
203
|
+
const spinner = ora("Fetching tool...").start();
|
|
204
|
+
try {
|
|
205
|
+
const response = await sdk.tools.get(id);
|
|
206
|
+
spinner.stop();
|
|
207
|
+
if (!response.success || !response.data) {
|
|
208
|
+
printError("Failed to fetch tool", response.message);
|
|
209
|
+
process.exitCode = 1;
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const { tool } = response.data;
|
|
213
|
+
if (isJsonOutput()) {
|
|
214
|
+
printJson(tool);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
printBlank();
|
|
218
|
+
printToolDetails(tool);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
spinner.fail("Failed to fetch tool");
|
|
221
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
222
|
+
printError("Error", message);
|
|
223
|
+
process.exitCode = 1;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
async function handleToolsCreate(options) {
|
|
227
|
+
if (options.template !== void 0) {
|
|
228
|
+
const templateType = typeof options.template === "string" ? options.template : "http";
|
|
229
|
+
const template = TOOL_TEMPLATES[templateType];
|
|
230
|
+
if (!template) {
|
|
231
|
+
printError("Unknown template type", `Available: http, javascript`);
|
|
232
|
+
process.exitCode = 1;
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
console.log(JSON.stringify(template, null, 2));
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (!options.file) {
|
|
239
|
+
printError("Missing required option", "Use '-f, --file <path>' or '--template' for sample JSON");
|
|
240
|
+
printInfo("Run 'chanl tools create --help' for usage");
|
|
241
|
+
process.exitCode = 1;
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const sdk = createSdk();
|
|
245
|
+
if (!sdk) return;
|
|
246
|
+
let input;
|
|
247
|
+
try {
|
|
248
|
+
const content = await readFile(options.file, "utf-8");
|
|
249
|
+
input = JSON.parse(content);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
252
|
+
printError("Failed to read file", message);
|
|
253
|
+
process.exitCode = 1;
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const spinner = ora("Creating tool...").start();
|
|
257
|
+
try {
|
|
258
|
+
const response = await sdk.tools.create(input);
|
|
259
|
+
spinner.stop();
|
|
260
|
+
if (!response.success || !response.data) {
|
|
261
|
+
printError("Failed to create tool", response.message);
|
|
262
|
+
process.exitCode = 1;
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const { tool } = response.data;
|
|
266
|
+
if (isJsonOutput()) {
|
|
267
|
+
printJson({ success: true, tool });
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
printSuccess(`Created tool: ${tool.name} (${tool.id})`);
|
|
271
|
+
} catch (error) {
|
|
272
|
+
spinner.fail("Failed to create tool");
|
|
273
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
274
|
+
printError("Error", message);
|
|
275
|
+
process.exitCode = 1;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
async function handleToolsUpdate(id, options) {
|
|
279
|
+
const sdk = createSdk();
|
|
280
|
+
if (!sdk) return;
|
|
281
|
+
let input;
|
|
282
|
+
try {
|
|
283
|
+
const content = await readFile(options.file, "utf-8");
|
|
284
|
+
input = JSON.parse(content);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
287
|
+
printError("Failed to read file", message);
|
|
288
|
+
process.exitCode = 1;
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
const spinner = ora("Updating tool...").start();
|
|
292
|
+
try {
|
|
293
|
+
const response = await sdk.tools.update(id, input);
|
|
294
|
+
spinner.stop();
|
|
295
|
+
if (!response.success || !response.data) {
|
|
296
|
+
printError("Failed to update tool", response.message);
|
|
297
|
+
process.exitCode = 1;
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const { tool } = response.data;
|
|
301
|
+
if (isJsonOutput()) {
|
|
302
|
+
printJson({ success: true, tool });
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
printSuccess(`Updated tool: ${tool.name} (${tool.id})`);
|
|
306
|
+
} catch (error) {
|
|
307
|
+
spinner.fail("Failed to update tool");
|
|
308
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
309
|
+
printError("Error", message);
|
|
310
|
+
process.exitCode = 1;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
async function handleToolsDelete(id, options) {
|
|
314
|
+
const sdk = createSdk();
|
|
315
|
+
if (!sdk) return;
|
|
316
|
+
if (!options.yes) {
|
|
317
|
+
try {
|
|
318
|
+
const confirmed = await confirm({
|
|
319
|
+
message: `Are you sure you want to delete tool '${id}'?`,
|
|
320
|
+
default: false
|
|
321
|
+
});
|
|
322
|
+
if (!confirmed) {
|
|
323
|
+
printInfo("Deletion cancelled");
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
} catch {
|
|
327
|
+
printBlank();
|
|
328
|
+
printInfo("Deletion cancelled");
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const spinner = ora("Deleting tool...").start();
|
|
333
|
+
try {
|
|
334
|
+
const response = await sdk.tools.delete(id);
|
|
335
|
+
spinner.stop();
|
|
336
|
+
if (!response.success) {
|
|
337
|
+
printError("Failed to delete tool", response.message);
|
|
338
|
+
process.exitCode = 1;
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
if (isJsonOutput()) {
|
|
342
|
+
printJson({ success: true, deleted: true, id });
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
printSuccess(`Deleted tool: ${id}`);
|
|
346
|
+
} catch (error) {
|
|
347
|
+
spinner.fail("Failed to delete tool");
|
|
348
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
349
|
+
printError("Error", message);
|
|
350
|
+
process.exitCode = 1;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
async function handleToolsExecute(id, options) {
|
|
354
|
+
const sdk = createSdk();
|
|
355
|
+
if (!sdk) return;
|
|
356
|
+
let args;
|
|
357
|
+
try {
|
|
358
|
+
args = JSON.parse(options.input);
|
|
359
|
+
} catch {
|
|
360
|
+
printError("Invalid JSON input", `Could not parse: ${options.input}`);
|
|
361
|
+
process.exitCode = 1;
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
const spinner = ora("Executing tool...").start();
|
|
365
|
+
try {
|
|
366
|
+
const response = await sdk.tools.execute(id, args);
|
|
367
|
+
spinner.stop();
|
|
368
|
+
if (!response.success || !response.data) {
|
|
369
|
+
printError("Execution failed", response.message);
|
|
370
|
+
process.exitCode = 1;
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
const execution = response.data;
|
|
374
|
+
if (isJsonOutput()) {
|
|
375
|
+
printJson(execution);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
printExecutionResult(execution);
|
|
379
|
+
} catch (error) {
|
|
380
|
+
spinner.fail("Execution failed");
|
|
381
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
382
|
+
printError("Error", message);
|
|
383
|
+
process.exitCode = 1;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
async function handleToolsTest(id, options) {
|
|
387
|
+
const sdk = createSdk();
|
|
388
|
+
if (!sdk) return;
|
|
389
|
+
let args;
|
|
390
|
+
try {
|
|
391
|
+
args = JSON.parse(options.input);
|
|
392
|
+
} catch {
|
|
393
|
+
printError("Invalid JSON input", `Could not parse: ${options.input}`);
|
|
394
|
+
process.exitCode = 1;
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
const spinner = ora("Testing tool...").start();
|
|
398
|
+
try {
|
|
399
|
+
const response = await sdk.tools.test(id, args);
|
|
400
|
+
spinner.stop();
|
|
401
|
+
if (!response.success || !response.data) {
|
|
402
|
+
printError("Test failed", response.message);
|
|
403
|
+
process.exitCode = 1;
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const execution = response.data;
|
|
407
|
+
if (isJsonOutput()) {
|
|
408
|
+
printJson(execution);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
printInfo("Test execution:");
|
|
412
|
+
printExecutionResult(execution);
|
|
413
|
+
} catch (error) {
|
|
414
|
+
spinner.fail("Test failed");
|
|
415
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
416
|
+
printError("Error", message);
|
|
417
|
+
process.exitCode = 1;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async function handleToolsExecutions(id, options) {
|
|
421
|
+
const sdk = createSdk();
|
|
422
|
+
if (!sdk) return;
|
|
423
|
+
const spinner = ora("Fetching executions...").start();
|
|
424
|
+
try {
|
|
425
|
+
const response = await sdk.tools.getExecutions(id, {
|
|
426
|
+
limit: parseInt(options.limit, 10),
|
|
427
|
+
page: parseInt(options.page, 10),
|
|
428
|
+
status: options.status
|
|
429
|
+
});
|
|
430
|
+
spinner.stop();
|
|
431
|
+
if (!response.success || !response.data) {
|
|
432
|
+
printError("Failed to fetch executions", response.message);
|
|
433
|
+
process.exitCode = 1;
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const { data: executions, total, pagination } = response.data;
|
|
437
|
+
if (isJsonOutput()) {
|
|
438
|
+
printJson({ executions, total, pagination });
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
if (executions.length === 0) {
|
|
442
|
+
printInfo("No executions found");
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
printBlank();
|
|
446
|
+
printSimpleTable(
|
|
447
|
+
["Execution ID", "Status", "Duration", "Source", "Created"],
|
|
448
|
+
executions.map((exec) => [
|
|
449
|
+
exec.id.substring(0, 12) + "...",
|
|
450
|
+
formatStatus(exec.status),
|
|
451
|
+
exec.executionTimeMs ? `${exec.executionTimeMs}ms` : "-",
|
|
452
|
+
exec.source,
|
|
453
|
+
formatDate(exec.createdAt)
|
|
454
|
+
])
|
|
455
|
+
);
|
|
456
|
+
printBlank();
|
|
457
|
+
printInfo(`Total: ${total} executions (Page ${pagination.page} of ${pagination.totalPages})`);
|
|
458
|
+
} catch (error) {
|
|
459
|
+
spinner.fail("Failed to fetch executions");
|
|
460
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
461
|
+
printError("Error", message);
|
|
462
|
+
process.exitCode = 1;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
async function handleToolsEnable(id) {
|
|
466
|
+
const sdk = createSdk();
|
|
467
|
+
if (!sdk) return;
|
|
468
|
+
const spinner = ora("Enabling tool...").start();
|
|
469
|
+
try {
|
|
470
|
+
const response = await sdk.tools.enable(id);
|
|
471
|
+
spinner.stop();
|
|
472
|
+
if (!response.success || !response.data) {
|
|
473
|
+
printError("Failed to enable tool", response.message);
|
|
474
|
+
process.exitCode = 1;
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
const { tool } = response.data;
|
|
478
|
+
if (isJsonOutput()) {
|
|
479
|
+
printJson({ success: true, tool });
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
printSuccess(`Enabled tool: ${tool.name} (${tool.id})`);
|
|
483
|
+
} catch (error) {
|
|
484
|
+
spinner.fail("Failed to enable tool");
|
|
485
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
486
|
+
printError("Error", message);
|
|
487
|
+
process.exitCode = 1;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
async function handleToolsDisable(id) {
|
|
491
|
+
const sdk = createSdk();
|
|
492
|
+
if (!sdk) return;
|
|
493
|
+
const spinner = ora("Disabling tool...").start();
|
|
494
|
+
try {
|
|
495
|
+
const response = await sdk.tools.disable(id);
|
|
496
|
+
spinner.stop();
|
|
497
|
+
if (!response.success || !response.data) {
|
|
498
|
+
printError("Failed to disable tool", response.message);
|
|
499
|
+
process.exitCode = 1;
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
const { tool } = response.data;
|
|
503
|
+
if (isJsonOutput()) {
|
|
504
|
+
printJson({ success: true, tool });
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
printSuccess(`Disabled tool: ${tool.name} (${tool.id})`);
|
|
508
|
+
} catch (error) {
|
|
509
|
+
spinner.fail("Failed to disable tool");
|
|
510
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
511
|
+
printError("Error", message);
|
|
512
|
+
process.exitCode = 1;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
async function handleToolsCategories() {
|
|
516
|
+
const sdk = createSdk();
|
|
517
|
+
if (!sdk) return;
|
|
518
|
+
const spinner = ora("Fetching categories...").start();
|
|
519
|
+
try {
|
|
520
|
+
const response = await sdk.tools.getCategories();
|
|
521
|
+
spinner.stop();
|
|
522
|
+
if (!response.success || !response.data) {
|
|
523
|
+
printError("Failed to fetch categories", response.message);
|
|
524
|
+
process.exitCode = 1;
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
const { categories, uncategorized } = response.data;
|
|
528
|
+
if (isJsonOutput()) {
|
|
529
|
+
printJson({ categories, uncategorized });
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
if (categories.length === 0 && uncategorized.count === 0) {
|
|
533
|
+
printInfo("No categories found");
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
printBlank();
|
|
537
|
+
printSimpleTable(
|
|
538
|
+
["Category", "Total", "Enabled"],
|
|
539
|
+
[
|
|
540
|
+
...categories.map((cat) => [
|
|
541
|
+
cat.tag,
|
|
542
|
+
cat.count.toString(),
|
|
543
|
+
`${cat.enabled} (${Math.round(cat.enabled / cat.count * 100)}%)`
|
|
544
|
+
]),
|
|
545
|
+
[
|
|
546
|
+
chalk.gray("(uncategorized)"),
|
|
547
|
+
uncategorized.count.toString(),
|
|
548
|
+
uncategorized.count > 0 ? `${uncategorized.enabled} (${Math.round(uncategorized.enabled / uncategorized.count * 100)}%)` : "0 (0%)"
|
|
549
|
+
]
|
|
550
|
+
]
|
|
551
|
+
);
|
|
552
|
+
const totalCount = categories.reduce((sum, c) => sum + c.count, 0) + uncategorized.count;
|
|
553
|
+
const totalEnabled = categories.reduce((sum, c) => sum + c.enabled, 0) + uncategorized.enabled;
|
|
554
|
+
printBlank();
|
|
555
|
+
printInfo(`Total: ${totalCount} tools, ${totalEnabled} enabled`);
|
|
556
|
+
} catch (error) {
|
|
557
|
+
spinner.fail("Failed to fetch categories");
|
|
558
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
559
|
+
printError("Error", message);
|
|
560
|
+
process.exitCode = 1;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
function printToolDetails(tool) {
|
|
564
|
+
printLabel("Name", tool.name);
|
|
565
|
+
printLabel("ID", tool.id);
|
|
566
|
+
printLabel("Type", tool.type);
|
|
567
|
+
printLabel("Enabled", tool.isEnabled ? chalk.green("Yes") : chalk.red("No"));
|
|
568
|
+
printLabel("Description", tool.description);
|
|
569
|
+
if (tool.tags.length > 0) {
|
|
570
|
+
printLabel("Tags", tool.tags.join(", "));
|
|
571
|
+
}
|
|
572
|
+
printBlank();
|
|
573
|
+
printInfo("Input Schema:");
|
|
574
|
+
console.log(chalk.gray(JSON.stringify(tool.inputSchema, null, 2)));
|
|
575
|
+
printBlank();
|
|
576
|
+
printInfo("Configuration:");
|
|
577
|
+
console.log(chalk.gray(JSON.stringify(tool.configuration, null, 2)));
|
|
578
|
+
printBlank();
|
|
579
|
+
printInfo("Statistics:");
|
|
580
|
+
printLabel(" Total Calls", tool.stats.totalCalls.toString());
|
|
581
|
+
printLabel(" Successful", tool.stats.successfulCalls.toString());
|
|
582
|
+
printLabel(" Failed", tool.stats.failedCalls.toString());
|
|
583
|
+
printLabel(" Avg Latency", `${tool.stats.averageLatencyMs}ms`);
|
|
584
|
+
if (tool.stats.lastCalledAt) {
|
|
585
|
+
printLabel(" Last Called", formatDate(tool.stats.lastCalledAt));
|
|
586
|
+
}
|
|
587
|
+
printBlank();
|
|
588
|
+
printLabel("Created", formatDate(tool.createdAt));
|
|
589
|
+
printLabel("Updated", formatDate(tool.updatedAt));
|
|
590
|
+
printBlank();
|
|
591
|
+
}
|
|
592
|
+
function printExecutionResult(result) {
|
|
593
|
+
printBlank();
|
|
594
|
+
const statusText = result.success ? chalk.green("\u2713 Success") : chalk.red("\u2717 Failed");
|
|
595
|
+
printLabel("Status", statusText);
|
|
596
|
+
if (result.latencyMs) {
|
|
597
|
+
printLabel("Duration", `${result.latencyMs}ms`);
|
|
598
|
+
}
|
|
599
|
+
if (result.executionId) {
|
|
600
|
+
printLabel("Execution ID", result.executionId);
|
|
601
|
+
}
|
|
602
|
+
if (!result.success && result.error) {
|
|
603
|
+
printBlank();
|
|
604
|
+
printError("Error", result.error);
|
|
605
|
+
}
|
|
606
|
+
if (result.data) {
|
|
607
|
+
printBlank();
|
|
608
|
+
printInfo("Output:");
|
|
609
|
+
console.log(chalk.gray(JSON.stringify(result.data, null, 2)));
|
|
610
|
+
}
|
|
611
|
+
printBlank();
|
|
612
|
+
}
|
|
613
|
+
function formatStatus(status) {
|
|
614
|
+
switch (status) {
|
|
615
|
+
case "completed":
|
|
616
|
+
return chalk.green("\u2713 completed");
|
|
617
|
+
case "failed":
|
|
618
|
+
return chalk.red("\u2717 failed");
|
|
619
|
+
case "running":
|
|
620
|
+
return chalk.blue("\u22EF running");
|
|
621
|
+
case "pending":
|
|
622
|
+
return chalk.gray("\u25CB pending");
|
|
623
|
+
case "corrected":
|
|
624
|
+
return chalk.yellow("\u26A1 corrected");
|
|
625
|
+
default:
|
|
626
|
+
return status;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
export {
|
|
630
|
+
createToolsCommand
|
|
631
|
+
};
|
|
632
|
+
//# sourceMappingURL=tools.js.map
|