@protoboxai/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -0
- package/bin/protobox.js +8 -0
- package/dist/cli.js +60 -0
- package/dist/commands/auth.js +294 -0
- package/dist/commands/chat.js +203 -0
- package/dist/commands/config.js +237 -0
- package/dist/commands/health.js +59 -0
- package/dist/commands/index.js +25 -0
- package/dist/commands/knowledge.js +539 -0
- package/dist/commands/mcp.js +589 -0
- package/dist/commands/prompts.js +295 -0
- package/dist/commands/tools.js +632 -0
- package/dist/commands/toolsets.js +464 -0
- package/dist/commands/workspaces.js +170 -0
- package/dist/index.js +6 -0
- package/dist/utils/config-store.js +209 -0
- package/dist/utils/output.js +221 -0
- package/dist/utils/sdk-factory.js +46 -0
- package/package.json +62 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { configStore } from "../utils/config-store.js";
|
|
4
|
+
import {
|
|
5
|
+
printSuccess,
|
|
6
|
+
printError,
|
|
7
|
+
printLabel,
|
|
8
|
+
printBlank,
|
|
9
|
+
printTable,
|
|
10
|
+
isJsonOutput,
|
|
11
|
+
printJson,
|
|
12
|
+
maskString
|
|
13
|
+
} from "../utils/output.js";
|
|
14
|
+
const VALID_KEYS = [
|
|
15
|
+
"apiKey",
|
|
16
|
+
"baseUrl",
|
|
17
|
+
"server",
|
|
18
|
+
"deployment",
|
|
19
|
+
"apiPrefix",
|
|
20
|
+
"workspaceId",
|
|
21
|
+
"defaultFormat"
|
|
22
|
+
];
|
|
23
|
+
const ENVIRONMENT_PRESETS = {
|
|
24
|
+
production: "https://platform.chanl.ai"
|
|
25
|
+
};
|
|
26
|
+
const KEY_DESCRIPTIONS = {
|
|
27
|
+
apiKey: "Chanl API key for authentication",
|
|
28
|
+
jwtToken: "JWT access token (from browser login)",
|
|
29
|
+
refreshToken: "JWT refresh token (from browser login)",
|
|
30
|
+
baseUrl: "Base URL for the Chanl API",
|
|
31
|
+
server: "Alias for baseUrl (e.g. http://localhost:18005)",
|
|
32
|
+
deployment: "local | cloud \u2014 local rewrites /api/v1 paths for OSS scenario servers",
|
|
33
|
+
apiPrefix: "Override API prefix; empty string for flat /scenarios routes",
|
|
34
|
+
workspaceId: "Default workspace ID",
|
|
35
|
+
appUrl: "App URL for browser-based flows",
|
|
36
|
+
defaultFormat: "Default output format (table or json)"
|
|
37
|
+
};
|
|
38
|
+
function createConfigCommand() {
|
|
39
|
+
const config = new Command("config").description("Manage CLI configuration");
|
|
40
|
+
config.command("list").description("List all configuration values").action(handleConfigList);
|
|
41
|
+
config.command("get <key>").description("Get a configuration value").action(handleConfigGet);
|
|
42
|
+
config.command("set <key> <value>").description("Set a configuration value").action(handleConfigSet);
|
|
43
|
+
config.command("delete <key>").alias("unset").description("Delete a configuration value").action(handleConfigDelete);
|
|
44
|
+
config.command("path").description("Show path to configuration file").action(handleConfigPath);
|
|
45
|
+
config.command("use <environment>").description("Reset to production API (or set a custom base URL with `config set baseUrl`)").action(handleConfigUse);
|
|
46
|
+
return config;
|
|
47
|
+
}
|
|
48
|
+
function handleConfigList() {
|
|
49
|
+
const allConfig = configStore.getAll();
|
|
50
|
+
if (isJsonOutput()) {
|
|
51
|
+
const safeConfig = {
|
|
52
|
+
...allConfig,
|
|
53
|
+
apiKey: allConfig.apiKey ? maskString(allConfig.apiKey) : void 0
|
|
54
|
+
};
|
|
55
|
+
printJson(safeConfig);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
printBlank();
|
|
59
|
+
const rows = VALID_KEYS.map((key) => {
|
|
60
|
+
let value = allConfig[key];
|
|
61
|
+
const source = getConfigSource(key);
|
|
62
|
+
if (key === "apiKey" && typeof value === "string") {
|
|
63
|
+
value = maskString(value);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
key,
|
|
67
|
+
value: value ?? chalk.dim("(not set)"),
|
|
68
|
+
source,
|
|
69
|
+
description: KEY_DESCRIPTIONS[key]
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
printTable(
|
|
73
|
+
[
|
|
74
|
+
{ header: "Key", key: "key", width: 15 },
|
|
75
|
+
{ header: "Value", key: "value", width: 30 },
|
|
76
|
+
{ header: "Source", key: "source", width: 10 }
|
|
77
|
+
],
|
|
78
|
+
rows
|
|
79
|
+
);
|
|
80
|
+
printBlank();
|
|
81
|
+
printLabel("Config file", configStore.getPath());
|
|
82
|
+
printBlank();
|
|
83
|
+
}
|
|
84
|
+
function handleConfigGet(key) {
|
|
85
|
+
if (!isValidKey(key)) {
|
|
86
|
+
printError(`Unknown configuration key: ${key}`);
|
|
87
|
+
printBlank();
|
|
88
|
+
printLabel("Valid keys", VALID_KEYS.join(", "));
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const typedKey = key;
|
|
93
|
+
let value;
|
|
94
|
+
switch (typedKey) {
|
|
95
|
+
case "apiKey":
|
|
96
|
+
value = configStore.getApiKey();
|
|
97
|
+
break;
|
|
98
|
+
case "baseUrl":
|
|
99
|
+
value = configStore.getBaseUrl();
|
|
100
|
+
break;
|
|
101
|
+
case "workspaceId":
|
|
102
|
+
value = configStore.getWorkspaceId();
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
value = configStore.get(typedKey);
|
|
106
|
+
}
|
|
107
|
+
if (isJsonOutput()) {
|
|
108
|
+
printJson({
|
|
109
|
+
key,
|
|
110
|
+
value: key === "apiKey" && value ? maskString(value) : value,
|
|
111
|
+
source: getConfigSource(typedKey)
|
|
112
|
+
});
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (value === void 0) {
|
|
116
|
+
console.log(chalk.dim("(not set)"));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (key === "apiKey") {
|
|
120
|
+
console.log(maskString(value));
|
|
121
|
+
} else {
|
|
122
|
+
console.log(value);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function handleConfigSet(key, value) {
|
|
126
|
+
if (!isValidKey(key)) {
|
|
127
|
+
printError(`Unknown configuration key: ${key}`);
|
|
128
|
+
printBlank();
|
|
129
|
+
printLabel("Valid keys", VALID_KEYS.join(", "));
|
|
130
|
+
process.exitCode = 1;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const typedKey = key;
|
|
134
|
+
if (typedKey === "defaultFormat") {
|
|
135
|
+
if (value !== "table" && value !== "json") {
|
|
136
|
+
printError(`Invalid format: ${value}`);
|
|
137
|
+
printLabel("Valid values", "table, json");
|
|
138
|
+
process.exitCode = 1;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (typedKey === "baseUrl") {
|
|
143
|
+
try {
|
|
144
|
+
new URL(value);
|
|
145
|
+
} catch {
|
|
146
|
+
printError(`Invalid URL: ${value}`);
|
|
147
|
+
process.exitCode = 1;
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
configStore.set(typedKey, value);
|
|
152
|
+
if (isJsonOutput()) {
|
|
153
|
+
printJson({
|
|
154
|
+
success: true,
|
|
155
|
+
key,
|
|
156
|
+
value: key === "apiKey" ? maskString(value) : value
|
|
157
|
+
});
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const displayValue = key === "apiKey" ? maskString(value) : value;
|
|
161
|
+
printSuccess(`Set ${key} = ${displayValue}`);
|
|
162
|
+
}
|
|
163
|
+
function handleConfigDelete(key) {
|
|
164
|
+
if (!isValidKey(key)) {
|
|
165
|
+
printError(`Unknown configuration key: ${key}`);
|
|
166
|
+
printBlank();
|
|
167
|
+
printLabel("Valid keys", VALID_KEYS.join(", "));
|
|
168
|
+
process.exitCode = 1;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const typedKey = key;
|
|
172
|
+
if (!configStore.has(typedKey)) {
|
|
173
|
+
if (isJsonOutput()) {
|
|
174
|
+
printJson({ success: true, key, message: "Key was not set" });
|
|
175
|
+
} else {
|
|
176
|
+
printSuccess(`${key} was not set`);
|
|
177
|
+
}
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
configStore.delete(typedKey);
|
|
181
|
+
if (isJsonOutput()) {
|
|
182
|
+
printJson({ success: true, key, message: "Deleted" });
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
printSuccess(`Deleted ${key}`);
|
|
186
|
+
}
|
|
187
|
+
function handleConfigPath() {
|
|
188
|
+
const path = configStore.getPath();
|
|
189
|
+
if (isJsonOutput()) {
|
|
190
|
+
printJson({ path });
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
console.log(path);
|
|
194
|
+
}
|
|
195
|
+
function isValidKey(key) {
|
|
196
|
+
return VALID_KEYS.includes(key);
|
|
197
|
+
}
|
|
198
|
+
function getConfigSource(key) {
|
|
199
|
+
const envVarMap = {
|
|
200
|
+
apiKey: "CHANL_API_KEY",
|
|
201
|
+
baseUrl: "CHANL_BASE_URL",
|
|
202
|
+
workspaceId: "CHANL_WORKSPACE_ID"
|
|
203
|
+
};
|
|
204
|
+
const envVar = envVarMap[key];
|
|
205
|
+
if (envVar && process.env[envVar]) {
|
|
206
|
+
return chalk.cyan("env");
|
|
207
|
+
}
|
|
208
|
+
if (configStore.has(key)) {
|
|
209
|
+
return chalk.green("config");
|
|
210
|
+
}
|
|
211
|
+
return chalk.dim("default");
|
|
212
|
+
}
|
|
213
|
+
function handleConfigUse(environment) {
|
|
214
|
+
const env = environment.toLowerCase();
|
|
215
|
+
const url = ENVIRONMENT_PRESETS[env];
|
|
216
|
+
if (!url) {
|
|
217
|
+
printError(`Unknown environment: ${environment}`);
|
|
218
|
+
printBlank();
|
|
219
|
+
printLabel("Available environments", Object.keys(ENVIRONMENT_PRESETS).join(", "));
|
|
220
|
+
process.exitCode = 1;
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
configStore.set("baseUrl", url);
|
|
224
|
+
if (isJsonOutput()) {
|
|
225
|
+
printJson({
|
|
226
|
+
success: true,
|
|
227
|
+
environment: env,
|
|
228
|
+
baseUrl: url
|
|
229
|
+
});
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
printSuccess(`Switched to ${env}: ${url}`);
|
|
233
|
+
}
|
|
234
|
+
export {
|
|
235
|
+
createConfigCommand
|
|
236
|
+
};
|
|
237
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { ChanlSDK } from "@protoboxai/sdk";
|
|
5
|
+
import { configStore } from "../utils/config-store.js";
|
|
6
|
+
import {
|
|
7
|
+
printSuccess,
|
|
8
|
+
printError,
|
|
9
|
+
printBlank,
|
|
10
|
+
isJsonOutput,
|
|
11
|
+
printJson
|
|
12
|
+
} from "../utils/output.js";
|
|
13
|
+
function createHealthCommand() {
|
|
14
|
+
const health = new Command("health").description("Check API health status").action(handleHealth);
|
|
15
|
+
return health;
|
|
16
|
+
}
|
|
17
|
+
async function handleHealth() {
|
|
18
|
+
const baseUrl = configStore.getBaseUrl();
|
|
19
|
+
const sdk = new ChanlSDK({ baseUrl });
|
|
20
|
+
const spinner = ora("Checking API health...").start();
|
|
21
|
+
try {
|
|
22
|
+
const response = await sdk.health.getHealth();
|
|
23
|
+
spinner.stop();
|
|
24
|
+
if (!response.success || !response.data) {
|
|
25
|
+
printError("API health check failed", response.message);
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (isJsonOutput()) {
|
|
30
|
+
printJson(response.data);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
printBlank();
|
|
34
|
+
console.log(chalk.bold("API Health Status:"));
|
|
35
|
+
const isHealthy = response.data.status === "healthy" || response.data.status === "ok";
|
|
36
|
+
console.log(` Status: ${isHealthy ? chalk.green("\u2713 healthy") : chalk.red("\u2717 unhealthy")}`);
|
|
37
|
+
console.log(` API URL: ${baseUrl}`);
|
|
38
|
+
if (response.data.version) {
|
|
39
|
+
const version = typeof response.data.version === "object" ? response.data.version.commit || JSON.stringify(response.data.version) : response.data.version;
|
|
40
|
+
console.log(` Version: ${version}`);
|
|
41
|
+
}
|
|
42
|
+
if (response.data.uptime) {
|
|
43
|
+
console.log(` Uptime: ${Math.floor(response.data.uptime / 60)} min`);
|
|
44
|
+
}
|
|
45
|
+
printBlank();
|
|
46
|
+
if (isHealthy) {
|
|
47
|
+
printSuccess("API is healthy");
|
|
48
|
+
}
|
|
49
|
+
} catch (error) {
|
|
50
|
+
spinner.fail("Health check failed");
|
|
51
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
52
|
+
printError("Error", message);
|
|
53
|
+
process.exitCode = 1;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
createHealthCommand
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createAuthCommand, createLoginCommand, createLogoutCommand } from "./auth.js";
|
|
2
|
+
import { createConfigCommand } from "./config.js";
|
|
3
|
+
import { createToolsCommand } from "./tools.js";
|
|
4
|
+
import { createToolsetsCommand } from "./toolsets.js";
|
|
5
|
+
import { createHealthCommand } from "./health.js";
|
|
6
|
+
import { createMcpCommand } from "./mcp.js";
|
|
7
|
+
import { createKnowledgeCommand } from "./knowledge.js";
|
|
8
|
+
import { createChatCommand } from "./chat.js";
|
|
9
|
+
import { createPromptsCommand } from "./prompts.js";
|
|
10
|
+
import { createWorkspacesCommand } from "./workspaces.js";
|
|
11
|
+
export {
|
|
12
|
+
createAuthCommand,
|
|
13
|
+
createChatCommand,
|
|
14
|
+
createConfigCommand,
|
|
15
|
+
createHealthCommand,
|
|
16
|
+
createKnowledgeCommand,
|
|
17
|
+
createLoginCommand,
|
|
18
|
+
createLogoutCommand,
|
|
19
|
+
createMcpCommand,
|
|
20
|
+
createPromptsCommand,
|
|
21
|
+
createToolsCommand,
|
|
22
|
+
createToolsetsCommand,
|
|
23
|
+
createWorkspacesCommand
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=index.js.map
|