@openbat/cli 0.2.0 → 0.2.2
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/api-client.js +6 -6
- package/dist/api-client.mjs +1 -1
- package/dist/{chunk-NYKJTHHK.mjs → chunk-MCDJLQI2.mjs} +6 -6
- package/dist/index.js +82 -81
- package/dist/index.mjs +77 -76
- package/package.json +1 -1
package/dist/api-client.js
CHANGED
|
@@ -32,7 +32,7 @@ __export(api_client_exports, {
|
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(api_client_exports);
|
|
34
34
|
var import_node_url = require("url");
|
|
35
|
-
var CLI_VERSION = "0.
|
|
35
|
+
var CLI_VERSION = "0.2.2";
|
|
36
36
|
var KEY_REGEX = /ob_(?:live|read|admin|pat)_[0-9a-f]{32}/g;
|
|
37
37
|
function redact(s) {
|
|
38
38
|
return s.replace(KEY_REGEX, (k) => `${k.slice(0, 16)}\u2026<hidden>`);
|
|
@@ -82,7 +82,7 @@ var ApiClient = class {
|
|
|
82
82
|
const msg = err instanceof Error ? err.message : String(err);
|
|
83
83
|
throw new Error(`Request to ${redact(url)} failed: ${redact(msg)}`);
|
|
84
84
|
}
|
|
85
|
-
return parseResponse(res, url);
|
|
85
|
+
return parseResponse(res, url, "GET");
|
|
86
86
|
}
|
|
87
87
|
/** Issue a POST with a JSON body. */
|
|
88
88
|
async post(path, body) {
|
|
@@ -144,12 +144,12 @@ mutate_fn = async function(method, path, body) {
|
|
|
144
144
|
const msg = err instanceof Error ? err.message : String(err);
|
|
145
145
|
throw new Error(`Request to ${redact(url)} failed: ${redact(msg)}`);
|
|
146
146
|
}
|
|
147
|
-
return parseResponse(res, url);
|
|
147
|
+
return parseResponse(res, url, method);
|
|
148
148
|
};
|
|
149
|
-
async function parseResponse(res, url) {
|
|
149
|
+
async function parseResponse(res, url, method) {
|
|
150
150
|
if (res.status === 401) {
|
|
151
151
|
throw new Error(
|
|
152
|
-
"Unauthorized. The API key was rejected (invalid, wrong kind for this endpoint, expired, or revoked)."
|
|
152
|
+
"Unauthorized. The API key was rejected (invalid, wrong kind for this endpoint, expired, or revoked). Run `openbat login` to refresh credentials."
|
|
153
153
|
);
|
|
154
154
|
}
|
|
155
155
|
if (res.status === 403) {
|
|
@@ -170,7 +170,7 @@ async function parseResponse(res, url) {
|
|
|
170
170
|
} catch {
|
|
171
171
|
}
|
|
172
172
|
throw new Error(
|
|
173
|
-
|
|
173
|
+
`${method} ${redact(url)} \u2192 ${res.status} ${res.statusText}${errBody?.error ? `: ${redact(errBody.error)}` : ""}`
|
|
174
174
|
);
|
|
175
175
|
}
|
|
176
176
|
try {
|
package/dist/api-client.mjs
CHANGED
|
@@ -9,7 +9,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
9
9
|
|
|
10
10
|
// src/api-client.ts
|
|
11
11
|
import { URL } from "url";
|
|
12
|
-
var CLI_VERSION = "0.
|
|
12
|
+
var CLI_VERSION = "0.2.2";
|
|
13
13
|
var KEY_REGEX = /ob_(?:live|read|admin|pat)_[0-9a-f]{32}/g;
|
|
14
14
|
function redact(s) {
|
|
15
15
|
return s.replace(KEY_REGEX, (k) => `${k.slice(0, 16)}\u2026<hidden>`);
|
|
@@ -59,7 +59,7 @@ var ApiClient = class {
|
|
|
59
59
|
const msg = err instanceof Error ? err.message : String(err);
|
|
60
60
|
throw new Error(`Request to ${redact(url)} failed: ${redact(msg)}`);
|
|
61
61
|
}
|
|
62
|
-
return parseResponse(res, url);
|
|
62
|
+
return parseResponse(res, url, "GET");
|
|
63
63
|
}
|
|
64
64
|
/** Issue a POST with a JSON body. */
|
|
65
65
|
async post(path, body) {
|
|
@@ -121,12 +121,12 @@ mutate_fn = async function(method, path, body) {
|
|
|
121
121
|
const msg = err instanceof Error ? err.message : String(err);
|
|
122
122
|
throw new Error(`Request to ${redact(url)} failed: ${redact(msg)}`);
|
|
123
123
|
}
|
|
124
|
-
return parseResponse(res, url);
|
|
124
|
+
return parseResponse(res, url, method);
|
|
125
125
|
};
|
|
126
|
-
async function parseResponse(res, url) {
|
|
126
|
+
async function parseResponse(res, url, method) {
|
|
127
127
|
if (res.status === 401) {
|
|
128
128
|
throw new Error(
|
|
129
|
-
"Unauthorized. The API key was rejected (invalid, wrong kind for this endpoint, expired, or revoked)."
|
|
129
|
+
"Unauthorized. The API key was rejected (invalid, wrong kind for this endpoint, expired, or revoked). Run `openbat login` to refresh credentials."
|
|
130
130
|
);
|
|
131
131
|
}
|
|
132
132
|
if (res.status === 403) {
|
|
@@ -147,7 +147,7 @@ async function parseResponse(res, url) {
|
|
|
147
147
|
} catch {
|
|
148
148
|
}
|
|
149
149
|
throw new Error(
|
|
150
|
-
|
|
150
|
+
`${method} ${redact(url)} \u2192 ${res.status} ${res.statusText}${errBody?.error ? `: ${redact(errBody.error)}` : ""}`
|
|
151
151
|
);
|
|
152
152
|
}
|
|
153
153
|
try {
|
package/dist/index.js
CHANGED
|
@@ -42,7 +42,7 @@ var import_node_fs = require("fs");
|
|
|
42
42
|
var import_node_os = require("os");
|
|
43
43
|
var import_node_path = require("path");
|
|
44
44
|
var CONFIG_PATH = (0, import_node_path.join)((0, import_node_os.homedir)(), ".openbatrc");
|
|
45
|
-
var DEFAULT_BASE_URL = "https://
|
|
45
|
+
var DEFAULT_BASE_URL = "https://openbat.dev";
|
|
46
46
|
async function readConfig() {
|
|
47
47
|
try {
|
|
48
48
|
const st = (0, import_node_fs.statSync)(CONFIG_PATH);
|
|
@@ -163,7 +163,7 @@ function configPath() {
|
|
|
163
163
|
|
|
164
164
|
// src/api-client.ts
|
|
165
165
|
var import_node_url = require("url");
|
|
166
|
-
var CLI_VERSION = "0.
|
|
166
|
+
var CLI_VERSION = "0.2.2";
|
|
167
167
|
var KEY_REGEX = /ob_(?:live|read|admin|pat)_[0-9a-f]{32}/g;
|
|
168
168
|
function redact(s) {
|
|
169
169
|
return s.replace(KEY_REGEX, (k) => `${k.slice(0, 16)}\u2026<hidden>`);
|
|
@@ -213,7 +213,7 @@ var ApiClient = class {
|
|
|
213
213
|
const msg = err instanceof Error ? err.message : String(err);
|
|
214
214
|
throw new Error(`Request to ${redact(url)} failed: ${redact(msg)}`);
|
|
215
215
|
}
|
|
216
|
-
return parseResponse(res, url);
|
|
216
|
+
return parseResponse(res, url, "GET");
|
|
217
217
|
}
|
|
218
218
|
/** Issue a POST with a JSON body. */
|
|
219
219
|
async post(path, body) {
|
|
@@ -275,12 +275,12 @@ mutate_fn = async function(method, path, body) {
|
|
|
275
275
|
const msg = err instanceof Error ? err.message : String(err);
|
|
276
276
|
throw new Error(`Request to ${redact(url)} failed: ${redact(msg)}`);
|
|
277
277
|
}
|
|
278
|
-
return parseResponse(res, url);
|
|
278
|
+
return parseResponse(res, url, method);
|
|
279
279
|
};
|
|
280
|
-
async function parseResponse(res, url) {
|
|
280
|
+
async function parseResponse(res, url, method) {
|
|
281
281
|
if (res.status === 401) {
|
|
282
282
|
throw new Error(
|
|
283
|
-
"Unauthorized. The API key was rejected (invalid, wrong kind for this endpoint, expired, or revoked)."
|
|
283
|
+
"Unauthorized. The API key was rejected (invalid, wrong kind for this endpoint, expired, or revoked). Run `openbat login` to refresh credentials."
|
|
284
284
|
);
|
|
285
285
|
}
|
|
286
286
|
if (res.status === 403) {
|
|
@@ -301,7 +301,7 @@ async function parseResponse(res, url) {
|
|
|
301
301
|
} catch {
|
|
302
302
|
}
|
|
303
303
|
throw new Error(
|
|
304
|
-
|
|
304
|
+
`${method} ${redact(url)} \u2192 ${res.status} ${res.statusText}${errBody?.error ? `: ${redact(errBody.error)}` : ""}`
|
|
305
305
|
);
|
|
306
306
|
}
|
|
307
307
|
try {
|
|
@@ -388,7 +388,9 @@ function configCommand() {
|
|
|
388
388
|
const cmd = new import_commander.Command("config").description(
|
|
389
389
|
"Manage the CLI's ~/.openbatrc settings"
|
|
390
390
|
);
|
|
391
|
-
cmd.command("set-key").description(
|
|
391
|
+
cmd.command("set-key").description(
|
|
392
|
+
"Store your API key in ~/.openbatrc. Reads from stdin by default; use --value to pass inline (discouraged \u2014 leaks into shell history)."
|
|
393
|
+
).option(
|
|
392
394
|
"--value <key>",
|
|
393
395
|
"Pass the key inline. Discouraged \u2014 leaks into shell history."
|
|
394
396
|
).action(async (opts) => {
|
|
@@ -404,13 +406,13 @@ function configCommand() {
|
|
|
404
406
|
key = Buffer.concat(chunks).toString("utf8").trim();
|
|
405
407
|
if (!key) {
|
|
406
408
|
fatal(
|
|
407
|
-
"No key on stdin. Try: echo 'ob_read_...' | openbat config set-key
|
|
409
|
+
"No key on stdin. Try: echo 'ob_read_...' | openbat config set-key"
|
|
408
410
|
);
|
|
409
411
|
}
|
|
410
412
|
}
|
|
411
413
|
await setApiKey(key);
|
|
412
414
|
process.stdout.write(
|
|
413
|
-
`Saved
|
|
415
|
+
`Saved key to ${configPath()} (mode 0600).
|
|
414
416
|
`
|
|
415
417
|
);
|
|
416
418
|
} catch (err) {
|
|
@@ -418,7 +420,7 @@ function configCommand() {
|
|
|
418
420
|
}
|
|
419
421
|
});
|
|
420
422
|
cmd.command("set-url <baseUrl>").description(
|
|
421
|
-
"Override the OpenBat API base URL (default: https://
|
|
423
|
+
"Override the OpenBat API base URL (default: https://openbat.dev)"
|
|
422
424
|
).action(async (baseUrl) => {
|
|
423
425
|
try {
|
|
424
426
|
await setBaseUrl(baseUrl);
|
|
@@ -529,7 +531,9 @@ async function resolveChatbotId(api, chatbotFlag) {
|
|
|
529
531
|
);
|
|
530
532
|
const chatbots = list.chatbots ?? [];
|
|
531
533
|
if (chatbots.length === 0) {
|
|
532
|
-
fatal(
|
|
534
|
+
fatal(
|
|
535
|
+
"No chatbots yet. Run `openbat chatbots create --name <name>`, or ask an org owner to invite you."
|
|
536
|
+
);
|
|
533
537
|
}
|
|
534
538
|
if (chatbotFlag) {
|
|
535
539
|
if (UUID_RE2.test(chatbotFlag)) {
|
|
@@ -714,18 +718,6 @@ function exportCommand() {
|
|
|
714
718
|
|
|
715
719
|
// src/commands/auth.ts
|
|
716
720
|
var import_commander3 = require("commander");
|
|
717
|
-
async function client2(globals) {
|
|
718
|
-
const cfg = await resolveConfig({
|
|
719
|
-
apiKeyFlag: globals.apiKey ?? null,
|
|
720
|
-
baseUrlFlag: globals.baseUrl ?? null
|
|
721
|
-
});
|
|
722
|
-
if (!cfg.apiKey) {
|
|
723
|
-
fatal(
|
|
724
|
-
"No API key configured. Run `openbat config set-key`, pass --api-key, or set OPENBAT_API_KEY."
|
|
725
|
-
);
|
|
726
|
-
}
|
|
727
|
-
return new ApiClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
|
|
728
|
-
}
|
|
729
721
|
function detectKind(apiKey) {
|
|
730
722
|
if (apiKey.startsWith("ob_read_")) return "read";
|
|
731
723
|
if (apiKey.startsWith("ob_admin_")) return "admin";
|
|
@@ -777,17 +769,6 @@ function authCommand() {
|
|
|
777
769
|
fatal(err instanceof Error ? err.message : String(err));
|
|
778
770
|
}
|
|
779
771
|
});
|
|
780
|
-
cmd.command("audit-log").description("Show recent audit-log entries for the current user").option("--days <n>", "Look-back window in days", "7").action(async function() {
|
|
781
|
-
try {
|
|
782
|
-
process.stderr.write(
|
|
783
|
-
"audit-log: endpoint not yet exposed via HTTP \u2014 query `select * from api_audit_log` in Supabase Studio for now.\n"
|
|
784
|
-
);
|
|
785
|
-
const _c = await client2(this.optsWithGlobals());
|
|
786
|
-
void _c;
|
|
787
|
-
} catch (err) {
|
|
788
|
-
fatal(err instanceof Error ? err.message : String(err));
|
|
789
|
-
}
|
|
790
|
-
});
|
|
791
772
|
return cmd;
|
|
792
773
|
}
|
|
793
774
|
|
|
@@ -1074,7 +1055,15 @@ async function pickDefaultChatbot(token, baseUrl) {
|
|
|
1074
1055
|
return;
|
|
1075
1056
|
}
|
|
1076
1057
|
if (chatbots.length === 0) {
|
|
1077
|
-
process.stdout.write(
|
|
1058
|
+
process.stdout.write(
|
|
1059
|
+
[
|
|
1060
|
+
"",
|
|
1061
|
+
"No chatbots yet. To get one:",
|
|
1062
|
+
" \u2022 Create one: openbat chatbots create --name <name>",
|
|
1063
|
+
" \u2022 Or ask an org owner to invite you, then run `openbat login` again",
|
|
1064
|
+
""
|
|
1065
|
+
].join("\n")
|
|
1066
|
+
);
|
|
1078
1067
|
return;
|
|
1079
1068
|
}
|
|
1080
1069
|
if (chatbots.length === 1) {
|
|
@@ -1142,7 +1131,7 @@ function logoutCommand() {
|
|
|
1142
1131
|
}
|
|
1143
1132
|
} else {
|
|
1144
1133
|
process.stderr.write(
|
|
1145
|
-
"Note: read/admin keys can't self-revoke.
|
|
1134
|
+
"Note: read/admin keys can't self-revoke server-side. Revoke them in the dashboard if needed; clearing local config only.\n"
|
|
1146
1135
|
);
|
|
1147
1136
|
}
|
|
1148
1137
|
await clearApiKey();
|
|
@@ -1155,7 +1144,7 @@ function logoutCommand() {
|
|
|
1155
1144
|
|
|
1156
1145
|
// src/commands/org.ts
|
|
1157
1146
|
var import_commander6 = require("commander");
|
|
1158
|
-
async function
|
|
1147
|
+
async function client2(globals) {
|
|
1159
1148
|
const cfg = await resolveConfig({
|
|
1160
1149
|
apiKeyFlag: globals.apiKey ?? null,
|
|
1161
1150
|
baseUrlFlag: globals.baseUrl ?? null
|
|
@@ -1175,7 +1164,7 @@ function orgCommand() {
|
|
|
1175
1164
|
cmd.command("list").description("List orgs the current PAT's user belongs to").action(async function() {
|
|
1176
1165
|
try {
|
|
1177
1166
|
const globals = this.optsWithGlobals();
|
|
1178
|
-
const c = await
|
|
1167
|
+
const c = await client2(globals);
|
|
1179
1168
|
const result = await c.get("/api/v1/orgs");
|
|
1180
1169
|
emit(result.orgs, { json: !!globals.json });
|
|
1181
1170
|
} catch (err) {
|
|
@@ -1185,7 +1174,7 @@ function orgCommand() {
|
|
|
1185
1174
|
cmd.command("show").description("Show the active org (id, name, members)").action(async function() {
|
|
1186
1175
|
try {
|
|
1187
1176
|
const globals = this.optsWithGlobals();
|
|
1188
|
-
const c = await
|
|
1177
|
+
const c = await client2(globals);
|
|
1189
1178
|
const result = await c.get(
|
|
1190
1179
|
"/api/v1/orgs/active"
|
|
1191
1180
|
);
|
|
@@ -1200,7 +1189,7 @@ function orgCommand() {
|
|
|
1200
1189
|
cmd.command("rename").description("Rename an org (owner only)").requiredOption("--id <orgId>", "Org id").requiredOption("--name <name>", "New name").action(async function(opts) {
|
|
1201
1190
|
try {
|
|
1202
1191
|
const globals = this.optsWithGlobals();
|
|
1203
|
-
const c = await
|
|
1192
|
+
const c = await client2(globals);
|
|
1204
1193
|
await c.patch(`/api/v1/orgs/${opts.id}`, { name: opts.name });
|
|
1205
1194
|
emit({ ok: true, renamed: opts.id }, { json: !!globals.json });
|
|
1206
1195
|
} catch (err) {
|
|
@@ -1211,7 +1200,7 @@ function orgCommand() {
|
|
|
1211
1200
|
members.command("list").requiredOption("--id <orgId>", "Org id").action(async function(opts) {
|
|
1212
1201
|
try {
|
|
1213
1202
|
const globals = this.optsWithGlobals();
|
|
1214
|
-
const c = await
|
|
1203
|
+
const c = await client2(globals);
|
|
1215
1204
|
const result = await c.get(
|
|
1216
1205
|
`/api/v1/orgs/${opts.id}/members`
|
|
1217
1206
|
);
|
|
@@ -1223,7 +1212,7 @@ function orgCommand() {
|
|
|
1223
1212
|
members.command("invite").requiredOption("--id <orgId>", "Org id").requiredOption("--email <email>", "Invitee email").option("--role <role>", "member | admin", "member").action(async function(opts) {
|
|
1224
1213
|
try {
|
|
1225
1214
|
const globals = this.optsWithGlobals();
|
|
1226
|
-
const c = await
|
|
1215
|
+
const c = await client2(globals);
|
|
1227
1216
|
const result = await c.post(
|
|
1228
1217
|
`/api/v1/orgs/${opts.id}/members`,
|
|
1229
1218
|
{ email: opts.email, role: opts.role }
|
|
@@ -1241,7 +1230,7 @@ function orgCommand() {
|
|
|
1241
1230
|
members.command("set-role").requiredOption("--id <orgId>", "Org id").requiredOption("--member <memberId>", "Member id").requiredOption("--role <role>", "admin | member").action(async function(opts) {
|
|
1242
1231
|
try {
|
|
1243
1232
|
const globals = this.optsWithGlobals();
|
|
1244
|
-
const c = await
|
|
1233
|
+
const c = await client2(globals);
|
|
1245
1234
|
await c.patch(`/api/v1/orgs/${opts.id}/members/${opts.member}`, {
|
|
1246
1235
|
role: opts.role
|
|
1247
1236
|
});
|
|
@@ -1253,7 +1242,7 @@ function orgCommand() {
|
|
|
1253
1242
|
members.command("remove").requiredOption("--id <orgId>", "Org id").requiredOption("--member <memberId>", "Member id").action(async function(opts) {
|
|
1254
1243
|
try {
|
|
1255
1244
|
const globals = this.optsWithGlobals();
|
|
1256
|
-
const c = await
|
|
1245
|
+
const c = await client2(globals);
|
|
1257
1246
|
await c.delete(`/api/v1/orgs/${opts.id}/members/${opts.member}`);
|
|
1258
1247
|
emit({ ok: true }, { json: !!globals.json });
|
|
1259
1248
|
} catch (err) {
|
|
@@ -1264,7 +1253,7 @@ function orgCommand() {
|
|
|
1264
1253
|
invitations.command("list").requiredOption("--id <orgId>", "Org id").action(async function(opts) {
|
|
1265
1254
|
try {
|
|
1266
1255
|
const globals = this.optsWithGlobals();
|
|
1267
|
-
const c = await
|
|
1256
|
+
const c = await client2(globals);
|
|
1268
1257
|
const result = await c.get(
|
|
1269
1258
|
`/api/v1/orgs/${opts.id}/invitations`
|
|
1270
1259
|
);
|
|
@@ -1278,7 +1267,7 @@ function orgCommand() {
|
|
|
1278
1267
|
|
|
1279
1268
|
// src/commands/write.ts
|
|
1280
1269
|
var import_commander7 = require("commander");
|
|
1281
|
-
async function
|
|
1270
|
+
async function client3(globals) {
|
|
1282
1271
|
const cfg = await resolveConfig({
|
|
1283
1272
|
apiKeyFlag: globals.apiKey ?? null,
|
|
1284
1273
|
baseUrlFlag: globals.baseUrl ?? null
|
|
@@ -1307,7 +1296,7 @@ function chatbotsCommand() {
|
|
|
1307
1296
|
cmd.command("list").description("List every chatbot the credential can reach").action(async function() {
|
|
1308
1297
|
try {
|
|
1309
1298
|
const globals = this.optsWithGlobals();
|
|
1310
|
-
const c = await
|
|
1299
|
+
const c = await client3(globals);
|
|
1311
1300
|
const result = await c.get(
|
|
1312
1301
|
"/api/v1/chatbots"
|
|
1313
1302
|
);
|
|
@@ -1319,7 +1308,7 @@ function chatbotsCommand() {
|
|
|
1319
1308
|
cmd.command("create").description("Create a new chatbot (PAT scope required)").requiredOption("--name <name>", "Chatbot name").option("--website <url>").option("--docs-url <url>").option("--mcp-url <url>").option("--language <code>", "Primary language code (default: en)", "en").action(async function(opts) {
|
|
1320
1309
|
try {
|
|
1321
1310
|
const globals = this.optsWithGlobals();
|
|
1322
|
-
const c = await
|
|
1311
|
+
const c = await client3(globals);
|
|
1323
1312
|
const result = await c.post("/api/v1/chatbots", {
|
|
1324
1313
|
name: opts.name,
|
|
1325
1314
|
websiteUrl: opts.website,
|
|
@@ -1339,7 +1328,7 @@ function chatbotsCommand() {
|
|
|
1339
1328
|
cmd.command("delete <chatbotId>").description("Delete a chatbot (irreversible \u2014 cascade-deletes everything)").action(async function(chatbotId) {
|
|
1340
1329
|
try {
|
|
1341
1330
|
const globals = this.optsWithGlobals();
|
|
1342
|
-
const c = await
|
|
1331
|
+
const c = await client3(globals);
|
|
1343
1332
|
await c.delete(`/api/v1/chatbots/${chatbotId}`);
|
|
1344
1333
|
emit({ ok: true, deleted: chatbotId }, { json: !!globals.json });
|
|
1345
1334
|
} catch (err) {
|
|
@@ -1353,7 +1342,7 @@ function webhooksCommand() {
|
|
|
1353
1342
|
cmd.command("list").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1354
1343
|
try {
|
|
1355
1344
|
const globals = this.optsWithGlobals();
|
|
1356
|
-
const c = await
|
|
1345
|
+
const c = await client3(globals);
|
|
1357
1346
|
const result = await c.get(
|
|
1358
1347
|
`/api/v1/chatbots/${opts.chatbot}/webhooks`
|
|
1359
1348
|
);
|
|
@@ -1365,7 +1354,7 @@ function webhooksCommand() {
|
|
|
1365
1354
|
cmd.command("create").requiredOption("--chatbot <id>", "Chatbot id").requiredOption("--name <name>").requiredOption("--url <url>").option("--type <type>", "discord | slack | custom", "custom").action(async function(opts) {
|
|
1366
1355
|
try {
|
|
1367
1356
|
const globals = this.optsWithGlobals();
|
|
1368
|
-
const c = await
|
|
1357
|
+
const c = await client3(globals);
|
|
1369
1358
|
const result = await c.post(`/api/v1/chatbots/${opts.chatbot}/webhooks`, {
|
|
1370
1359
|
name: opts.name,
|
|
1371
1360
|
url: opts.url,
|
|
@@ -1380,7 +1369,7 @@ function webhooksCommand() {
|
|
|
1380
1369
|
cmd.command("delete").requiredOption("--chatbot <id>", "Chatbot id").requiredOption("--webhook <id>", "Webhook id").action(async function(opts) {
|
|
1381
1370
|
try {
|
|
1382
1371
|
const globals = this.optsWithGlobals();
|
|
1383
|
-
const c = await
|
|
1372
|
+
const c = await client3(globals);
|
|
1384
1373
|
await c.delete(`/api/v1/chatbots/${opts.chatbot}/webhooks/${opts.webhook}`);
|
|
1385
1374
|
emit({ ok: true, deleted: opts.webhook }, { json: !!globals.json });
|
|
1386
1375
|
} catch (err) {
|
|
@@ -1397,7 +1386,7 @@ function settingsCommand() {
|
|
|
1397
1386
|
keys.command("rotate-ingest").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1398
1387
|
try {
|
|
1399
1388
|
const globals = this.optsWithGlobals();
|
|
1400
|
-
const c = await
|
|
1389
|
+
const c = await client3(globals);
|
|
1401
1390
|
const result = await c.post(
|
|
1402
1391
|
`/api/v1/chatbots/${opts.chatbot}/keys/ingest/rotate`,
|
|
1403
1392
|
{}
|
|
@@ -1411,7 +1400,7 @@ function settingsCommand() {
|
|
|
1411
1400
|
keys.command("generate-read").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1412
1401
|
try {
|
|
1413
1402
|
const globals = this.optsWithGlobals();
|
|
1414
|
-
const c = await
|
|
1403
|
+
const c = await client3(globals);
|
|
1415
1404
|
const result = await c.post(
|
|
1416
1405
|
`/api/v1/chatbots/${opts.chatbot}/keys/read`,
|
|
1417
1406
|
{}
|
|
@@ -1425,7 +1414,7 @@ function settingsCommand() {
|
|
|
1425
1414
|
keys.command("generate-admin").requiredOption("--chatbot <id>", "Chatbot id").requiredOption("--name <name>", "Human-friendly name (e.g. 'CI key')").option("--expires-in-days <n>", "Auto-expire after N days").action(async function(opts) {
|
|
1426
1415
|
try {
|
|
1427
1416
|
const globals = this.optsWithGlobals();
|
|
1428
|
-
const c = await
|
|
1417
|
+
const c = await client3(globals);
|
|
1429
1418
|
const result = await c.post(`/api/v1/chatbots/${opts.chatbot}/admin-keys`, {
|
|
1430
1419
|
name: opts.name,
|
|
1431
1420
|
expiresInDays: opts.expiresInDays ? Number(opts.expiresInDays) : void 0
|
|
@@ -1439,7 +1428,7 @@ function settingsCommand() {
|
|
|
1439
1428
|
keys.command("list-admin").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1440
1429
|
try {
|
|
1441
1430
|
const globals = this.optsWithGlobals();
|
|
1442
|
-
const c = await
|
|
1431
|
+
const c = await client3(globals);
|
|
1443
1432
|
const result = await c.get(
|
|
1444
1433
|
`/api/v1/chatbots/${opts.chatbot}/admin-keys`
|
|
1445
1434
|
);
|
|
@@ -1451,7 +1440,7 @@ function settingsCommand() {
|
|
|
1451
1440
|
keys.command("revoke-admin").requiredOption("--chatbot <id>", "Chatbot id").requiredOption("--key <keyId>", "Admin key id").action(async function(opts) {
|
|
1452
1441
|
try {
|
|
1453
1442
|
const globals = this.optsWithGlobals();
|
|
1454
|
-
const c = await
|
|
1443
|
+
const c = await client3(globals);
|
|
1455
1444
|
await c.delete(`/api/v1/chatbots/${opts.chatbot}/admin-keys/${opts.key}`);
|
|
1456
1445
|
emit({ ok: true, revoked: opts.key }, { json: !!globals.json });
|
|
1457
1446
|
} catch (err) {
|
|
@@ -1468,7 +1457,7 @@ function settingsCommand() {
|
|
|
1468
1457
|
fatal("Provide at least one setting to update.");
|
|
1469
1458
|
}
|
|
1470
1459
|
const globals = this.optsWithGlobals();
|
|
1471
|
-
const c = await
|
|
1460
|
+
const c = await client3(globals);
|
|
1472
1461
|
await c.patch(`/api/v1/chatbots/${opts.chatbot}/settings`, { settings });
|
|
1473
1462
|
emit({ ok: true }, { json: !!globals.json });
|
|
1474
1463
|
} catch (err) {
|
|
@@ -1482,7 +1471,7 @@ function workflowsCommand() {
|
|
|
1482
1471
|
cmd.command("list").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1483
1472
|
try {
|
|
1484
1473
|
const globals = this.optsWithGlobals();
|
|
1485
|
-
const c = await
|
|
1474
|
+
const c = await client3(globals);
|
|
1486
1475
|
const result = await c.get(
|
|
1487
1476
|
`/api/v1/chatbots/${opts.chatbot}/workflows`
|
|
1488
1477
|
);
|
|
@@ -1500,7 +1489,7 @@ function workflowsCommand() {
|
|
|
1500
1489
|
).requiredOption("--webhook <id>", "Webhook id to fire").option("--message <tpl>", "Message template (supports {{user.id}}, etc.)").action(async function(opts) {
|
|
1501
1490
|
try {
|
|
1502
1491
|
const globals = this.optsWithGlobals();
|
|
1503
|
-
const c = await
|
|
1492
|
+
const c = await client3(globals);
|
|
1504
1493
|
const result = await c.post(`/api/v1/chatbots/${opts.chatbot}/workflows`, {
|
|
1505
1494
|
name: opts.name,
|
|
1506
1495
|
template: opts.template,
|
|
@@ -1520,7 +1509,7 @@ function reportsCommand() {
|
|
|
1520
1509
|
cmd.command("list").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1521
1510
|
try {
|
|
1522
1511
|
const globals = this.optsWithGlobals();
|
|
1523
|
-
const c = await
|
|
1512
|
+
const c = await client3(globals);
|
|
1524
1513
|
const result = await c.get(
|
|
1525
1514
|
`/api/v1/chatbots/${opts.chatbot}/reports`
|
|
1526
1515
|
);
|
|
@@ -1532,7 +1521,7 @@ function reportsCommand() {
|
|
|
1532
1521
|
cmd.command("create").description("Create a new AI report; returns the org-private dashboard URL").requiredOption("--chatbot <id>", "Chatbot id").option("--name <name>", "Report name", "Untitled Report").action(async function(opts) {
|
|
1533
1522
|
try {
|
|
1534
1523
|
const globals = this.optsWithGlobals();
|
|
1535
|
-
const c = await
|
|
1524
|
+
const c = await client3(globals);
|
|
1536
1525
|
const result = await c.post(`/api/v1/chatbots/${opts.chatbot}/reports`, { name: opts.name });
|
|
1537
1526
|
process.stderr.write(
|
|
1538
1527
|
`
|
|
@@ -1556,7 +1545,7 @@ function analysisCommand() {
|
|
|
1556
1545
|
cmd.command("list").requiredOption("--chatbot <id>", "Chatbot id").option("--type <t>", "intent | flag | assistant_outcome | assistant_issue").option("--pending", "Include pending suggestions").action(async function(opts) {
|
|
1557
1546
|
try {
|
|
1558
1547
|
const globals = this.optsWithGlobals();
|
|
1559
|
-
const c = await
|
|
1548
|
+
const c = await client3(globals);
|
|
1560
1549
|
const qs = new URLSearchParams();
|
|
1561
1550
|
if (opts.type) qs.set("type", opts.type);
|
|
1562
1551
|
if (opts.pending) qs.set("pending", "true");
|
|
@@ -1574,7 +1563,7 @@ function analysisCommand() {
|
|
|
1574
1563
|
).requiredOption("--name <slug>", "snake_case slug").requiredOption("--display-name <text>").requiredOption("--description <text>").action(async function(opts) {
|
|
1575
1564
|
try {
|
|
1576
1565
|
const globals = this.optsWithGlobals();
|
|
1577
|
-
const c = await
|
|
1566
|
+
const c = await client3(globals);
|
|
1578
1567
|
const result = await c.post(
|
|
1579
1568
|
`/api/v1/chatbots/${opts.chatbot}/analysis-definitions`,
|
|
1580
1569
|
{
|
|
@@ -1598,7 +1587,7 @@ function usersCommand() {
|
|
|
1598
1587
|
cmd.command("list").requiredOption("--chatbot <id>", "Chatbot id").option("--from <iso>").option("--to <iso>").option("--days <n>", "Convenience: last N days").option("--search <q>").option("--limit <n>", "Page size", "20").action(async function(opts) {
|
|
1599
1588
|
try {
|
|
1600
1589
|
const globals = this.optsWithGlobals();
|
|
1601
|
-
const c = await
|
|
1590
|
+
const c = await client3(globals);
|
|
1602
1591
|
const qs = new URLSearchParams();
|
|
1603
1592
|
let from = opts.from;
|
|
1604
1593
|
if (!from && opts.days) {
|
|
@@ -1629,7 +1618,7 @@ function sdkCommand() {
|
|
|
1629
1618
|
);
|
|
1630
1619
|
cmd.command("install-instructions").description("Print markdown the calling agent can follow").option(
|
|
1631
1620
|
"--framework <name>",
|
|
1632
|
-
"next |
|
|
1621
|
+
"next | vercel-ai-sdk (default: next)",
|
|
1633
1622
|
"next"
|
|
1634
1623
|
).option("--chatbot <id>", "Chatbot id (for the example snippet)").action(async function(opts) {
|
|
1635
1624
|
const chatbotId = opts.chatbot ?? "<chatbotId>";
|
|
@@ -1689,24 +1678,36 @@ function sdkCommand() {
|
|
|
1689
1678
|
cmd.command("verify").description("Check whether any event has arrived for the chatbot yet").requiredOption("--chatbot <id>", "Chatbot id").option("--timeout <n>", "Seconds to wait (default: 60)", "60").action(async function(opts) {
|
|
1690
1679
|
try {
|
|
1691
1680
|
const globals = this.optsWithGlobals();
|
|
1692
|
-
const c = await
|
|
1693
|
-
const
|
|
1681
|
+
const c = await client3(globals);
|
|
1682
|
+
const timeoutSec = Number(opts.timeout);
|
|
1683
|
+
const deadline = Date.now() + timeoutSec * 1e3;
|
|
1684
|
+
const params = new URLSearchParams({
|
|
1685
|
+
chatbotId: opts.chatbot,
|
|
1686
|
+
limit: "1"
|
|
1687
|
+
});
|
|
1688
|
+
process.stderr.write(
|
|
1689
|
+
`Waiting for first event on chatbot ${opts.chatbot} (timeout ${timeoutSec}s)\u2026
|
|
1690
|
+
`
|
|
1691
|
+
);
|
|
1692
|
+
let lastTick = Date.now();
|
|
1694
1693
|
while (Date.now() < deadline) {
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
`\u2713 First event detected. ${result.total} conversation(s) ingested.
|
|
1694
|
+
const result = await c.get(`/api/v1/conversations?${params}`);
|
|
1695
|
+
if (result.total > 0) {
|
|
1696
|
+
process.stderr.write(
|
|
1697
|
+
`First event detected. ${result.total} conversation(s) ingested.
|
|
1700
1698
|
`
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1699
|
+
);
|
|
1700
|
+
return;
|
|
1701
|
+
}
|
|
1702
|
+
if (Date.now() - lastTick >= 5e3) {
|
|
1703
|
+
process.stderr.write(".");
|
|
1704
|
+
lastTick = Date.now();
|
|
1705
1705
|
}
|
|
1706
1706
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
1707
1707
|
}
|
|
1708
1708
|
process.stderr.write(
|
|
1709
|
-
`
|
|
1709
|
+
`
|
|
1710
|
+
Timed out after ${timeoutSec}s \u2014 no events yet. Confirm OPENBAT_API_KEY and that recordMessages is being called.
|
|
1710
1711
|
`
|
|
1711
1712
|
);
|
|
1712
1713
|
process.exit(2);
|
|
@@ -1721,9 +1722,9 @@ function sdkCommand() {
|
|
|
1721
1722
|
var program = new import_commander8.Command();
|
|
1722
1723
|
program.name("openbat").description(
|
|
1723
1724
|
"Query OpenBat chatbot data \u2014 conversations, sentiment, analytics, exports."
|
|
1724
|
-
).version("0.2.
|
|
1725
|
+
).version("0.2.2").option("--api-key <key>", "Override the stored Read API key (footgun \u2014 leaks into shell history)").option(
|
|
1725
1726
|
"--base-url <url>",
|
|
1726
|
-
"Override the OpenBat API base URL (defaults to ~/.openbatrc or https://
|
|
1727
|
+
"Override the OpenBat API base URL (defaults to ~/.openbatrc or https://openbat.dev)"
|
|
1727
1728
|
).option(
|
|
1728
1729
|
"--chatbot <id|name>",
|
|
1729
1730
|
"Override the active chatbot for this invocation (UUID or chatbot name)"
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ApiClient
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MCDJLQI2.mjs";
|
|
5
5
|
|
|
6
6
|
// src/index.ts
|
|
7
7
|
import { Command as Command8 } from "commander";
|
|
@@ -14,7 +14,7 @@ import { promises as fs, statSync, chmodSync } from "fs";
|
|
|
14
14
|
import { homedir } from "os";
|
|
15
15
|
import { join } from "path";
|
|
16
16
|
var CONFIG_PATH = join(homedir(), ".openbatrc");
|
|
17
|
-
var DEFAULT_BASE_URL = "https://
|
|
17
|
+
var DEFAULT_BASE_URL = "https://openbat.dev";
|
|
18
18
|
async function readConfig() {
|
|
19
19
|
try {
|
|
20
20
|
const st = statSync(CONFIG_PATH);
|
|
@@ -210,7 +210,9 @@ function configCommand() {
|
|
|
210
210
|
const cmd = new Command("config").description(
|
|
211
211
|
"Manage the CLI's ~/.openbatrc settings"
|
|
212
212
|
);
|
|
213
|
-
cmd.command("set-key").description(
|
|
213
|
+
cmd.command("set-key").description(
|
|
214
|
+
"Store your API key in ~/.openbatrc. Reads from stdin by default; use --value to pass inline (discouraged \u2014 leaks into shell history)."
|
|
215
|
+
).option(
|
|
214
216
|
"--value <key>",
|
|
215
217
|
"Pass the key inline. Discouraged \u2014 leaks into shell history."
|
|
216
218
|
).action(async (opts) => {
|
|
@@ -226,13 +228,13 @@ function configCommand() {
|
|
|
226
228
|
key = Buffer.concat(chunks).toString("utf8").trim();
|
|
227
229
|
if (!key) {
|
|
228
230
|
fatal(
|
|
229
|
-
"No key on stdin. Try: echo 'ob_read_...' | openbat config set-key
|
|
231
|
+
"No key on stdin. Try: echo 'ob_read_...' | openbat config set-key"
|
|
230
232
|
);
|
|
231
233
|
}
|
|
232
234
|
}
|
|
233
235
|
await setApiKey(key);
|
|
234
236
|
process.stdout.write(
|
|
235
|
-
`Saved
|
|
237
|
+
`Saved key to ${configPath()} (mode 0600).
|
|
236
238
|
`
|
|
237
239
|
);
|
|
238
240
|
} catch (err) {
|
|
@@ -240,7 +242,7 @@ function configCommand() {
|
|
|
240
242
|
}
|
|
241
243
|
});
|
|
242
244
|
cmd.command("set-url <baseUrl>").description(
|
|
243
|
-
"Override the OpenBat API base URL (default: https://
|
|
245
|
+
"Override the OpenBat API base URL (default: https://openbat.dev)"
|
|
244
246
|
).action(async (baseUrl) => {
|
|
245
247
|
try {
|
|
246
248
|
await setBaseUrl(baseUrl);
|
|
@@ -351,7 +353,9 @@ async function resolveChatbotId(api, chatbotFlag) {
|
|
|
351
353
|
);
|
|
352
354
|
const chatbots = list.chatbots ?? [];
|
|
353
355
|
if (chatbots.length === 0) {
|
|
354
|
-
fatal(
|
|
356
|
+
fatal(
|
|
357
|
+
"No chatbots yet. Run `openbat chatbots create --name <name>`, or ask an org owner to invite you."
|
|
358
|
+
);
|
|
355
359
|
}
|
|
356
360
|
if (chatbotFlag) {
|
|
357
361
|
if (UUID_RE2.test(chatbotFlag)) {
|
|
@@ -536,18 +540,6 @@ function exportCommand() {
|
|
|
536
540
|
|
|
537
541
|
// src/commands/auth.ts
|
|
538
542
|
import { Command as Command3 } from "commander";
|
|
539
|
-
async function client2(globals) {
|
|
540
|
-
const cfg = await resolveConfig({
|
|
541
|
-
apiKeyFlag: globals.apiKey ?? null,
|
|
542
|
-
baseUrlFlag: globals.baseUrl ?? null
|
|
543
|
-
});
|
|
544
|
-
if (!cfg.apiKey) {
|
|
545
|
-
fatal(
|
|
546
|
-
"No API key configured. Run `openbat config set-key`, pass --api-key, or set OPENBAT_API_KEY."
|
|
547
|
-
);
|
|
548
|
-
}
|
|
549
|
-
return new ApiClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
|
|
550
|
-
}
|
|
551
543
|
function detectKind(apiKey) {
|
|
552
544
|
if (apiKey.startsWith("ob_read_")) return "read";
|
|
553
545
|
if (apiKey.startsWith("ob_admin_")) return "admin";
|
|
@@ -599,17 +591,6 @@ function authCommand() {
|
|
|
599
591
|
fatal(err instanceof Error ? err.message : String(err));
|
|
600
592
|
}
|
|
601
593
|
});
|
|
602
|
-
cmd.command("audit-log").description("Show recent audit-log entries for the current user").option("--days <n>", "Look-back window in days", "7").action(async function() {
|
|
603
|
-
try {
|
|
604
|
-
process.stderr.write(
|
|
605
|
-
"audit-log: endpoint not yet exposed via HTTP \u2014 query `select * from api_audit_log` in Supabase Studio for now.\n"
|
|
606
|
-
);
|
|
607
|
-
const _c = await client2(this.optsWithGlobals());
|
|
608
|
-
void _c;
|
|
609
|
-
} catch (err) {
|
|
610
|
-
fatal(err instanceof Error ? err.message : String(err));
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
594
|
return cmd;
|
|
614
595
|
}
|
|
615
596
|
|
|
@@ -896,7 +877,15 @@ async function pickDefaultChatbot(token, baseUrl) {
|
|
|
896
877
|
return;
|
|
897
878
|
}
|
|
898
879
|
if (chatbots.length === 0) {
|
|
899
|
-
process.stdout.write(
|
|
880
|
+
process.stdout.write(
|
|
881
|
+
[
|
|
882
|
+
"",
|
|
883
|
+
"No chatbots yet. To get one:",
|
|
884
|
+
" \u2022 Create one: openbat chatbots create --name <name>",
|
|
885
|
+
" \u2022 Or ask an org owner to invite you, then run `openbat login` again",
|
|
886
|
+
""
|
|
887
|
+
].join("\n")
|
|
888
|
+
);
|
|
900
889
|
return;
|
|
901
890
|
}
|
|
902
891
|
if (chatbots.length === 1) {
|
|
@@ -964,7 +953,7 @@ function logoutCommand() {
|
|
|
964
953
|
}
|
|
965
954
|
} else {
|
|
966
955
|
process.stderr.write(
|
|
967
|
-
"Note: read/admin keys can't self-revoke.
|
|
956
|
+
"Note: read/admin keys can't self-revoke server-side. Revoke them in the dashboard if needed; clearing local config only.\n"
|
|
968
957
|
);
|
|
969
958
|
}
|
|
970
959
|
await clearApiKey();
|
|
@@ -977,7 +966,7 @@ function logoutCommand() {
|
|
|
977
966
|
|
|
978
967
|
// src/commands/org.ts
|
|
979
968
|
import { Command as Command6 } from "commander";
|
|
980
|
-
async function
|
|
969
|
+
async function client2(globals) {
|
|
981
970
|
const cfg = await resolveConfig({
|
|
982
971
|
apiKeyFlag: globals.apiKey ?? null,
|
|
983
972
|
baseUrlFlag: globals.baseUrl ?? null
|
|
@@ -997,7 +986,7 @@ function orgCommand() {
|
|
|
997
986
|
cmd.command("list").description("List orgs the current PAT's user belongs to").action(async function() {
|
|
998
987
|
try {
|
|
999
988
|
const globals = this.optsWithGlobals();
|
|
1000
|
-
const c = await
|
|
989
|
+
const c = await client2(globals);
|
|
1001
990
|
const result = await c.get("/api/v1/orgs");
|
|
1002
991
|
emit(result.orgs, { json: !!globals.json });
|
|
1003
992
|
} catch (err) {
|
|
@@ -1007,7 +996,7 @@ function orgCommand() {
|
|
|
1007
996
|
cmd.command("show").description("Show the active org (id, name, members)").action(async function() {
|
|
1008
997
|
try {
|
|
1009
998
|
const globals = this.optsWithGlobals();
|
|
1010
|
-
const c = await
|
|
999
|
+
const c = await client2(globals);
|
|
1011
1000
|
const result = await c.get(
|
|
1012
1001
|
"/api/v1/orgs/active"
|
|
1013
1002
|
);
|
|
@@ -1022,7 +1011,7 @@ function orgCommand() {
|
|
|
1022
1011
|
cmd.command("rename").description("Rename an org (owner only)").requiredOption("--id <orgId>", "Org id").requiredOption("--name <name>", "New name").action(async function(opts) {
|
|
1023
1012
|
try {
|
|
1024
1013
|
const globals = this.optsWithGlobals();
|
|
1025
|
-
const c = await
|
|
1014
|
+
const c = await client2(globals);
|
|
1026
1015
|
await c.patch(`/api/v1/orgs/${opts.id}`, { name: opts.name });
|
|
1027
1016
|
emit({ ok: true, renamed: opts.id }, { json: !!globals.json });
|
|
1028
1017
|
} catch (err) {
|
|
@@ -1033,7 +1022,7 @@ function orgCommand() {
|
|
|
1033
1022
|
members.command("list").requiredOption("--id <orgId>", "Org id").action(async function(opts) {
|
|
1034
1023
|
try {
|
|
1035
1024
|
const globals = this.optsWithGlobals();
|
|
1036
|
-
const c = await
|
|
1025
|
+
const c = await client2(globals);
|
|
1037
1026
|
const result = await c.get(
|
|
1038
1027
|
`/api/v1/orgs/${opts.id}/members`
|
|
1039
1028
|
);
|
|
@@ -1045,7 +1034,7 @@ function orgCommand() {
|
|
|
1045
1034
|
members.command("invite").requiredOption("--id <orgId>", "Org id").requiredOption("--email <email>", "Invitee email").option("--role <role>", "member | admin", "member").action(async function(opts) {
|
|
1046
1035
|
try {
|
|
1047
1036
|
const globals = this.optsWithGlobals();
|
|
1048
|
-
const c = await
|
|
1037
|
+
const c = await client2(globals);
|
|
1049
1038
|
const result = await c.post(
|
|
1050
1039
|
`/api/v1/orgs/${opts.id}/members`,
|
|
1051
1040
|
{ email: opts.email, role: opts.role }
|
|
@@ -1063,7 +1052,7 @@ function orgCommand() {
|
|
|
1063
1052
|
members.command("set-role").requiredOption("--id <orgId>", "Org id").requiredOption("--member <memberId>", "Member id").requiredOption("--role <role>", "admin | member").action(async function(opts) {
|
|
1064
1053
|
try {
|
|
1065
1054
|
const globals = this.optsWithGlobals();
|
|
1066
|
-
const c = await
|
|
1055
|
+
const c = await client2(globals);
|
|
1067
1056
|
await c.patch(`/api/v1/orgs/${opts.id}/members/${opts.member}`, {
|
|
1068
1057
|
role: opts.role
|
|
1069
1058
|
});
|
|
@@ -1075,7 +1064,7 @@ function orgCommand() {
|
|
|
1075
1064
|
members.command("remove").requiredOption("--id <orgId>", "Org id").requiredOption("--member <memberId>", "Member id").action(async function(opts) {
|
|
1076
1065
|
try {
|
|
1077
1066
|
const globals = this.optsWithGlobals();
|
|
1078
|
-
const c = await
|
|
1067
|
+
const c = await client2(globals);
|
|
1079
1068
|
await c.delete(`/api/v1/orgs/${opts.id}/members/${opts.member}`);
|
|
1080
1069
|
emit({ ok: true }, { json: !!globals.json });
|
|
1081
1070
|
} catch (err) {
|
|
@@ -1086,7 +1075,7 @@ function orgCommand() {
|
|
|
1086
1075
|
invitations.command("list").requiredOption("--id <orgId>", "Org id").action(async function(opts) {
|
|
1087
1076
|
try {
|
|
1088
1077
|
const globals = this.optsWithGlobals();
|
|
1089
|
-
const c = await
|
|
1078
|
+
const c = await client2(globals);
|
|
1090
1079
|
const result = await c.get(
|
|
1091
1080
|
`/api/v1/orgs/${opts.id}/invitations`
|
|
1092
1081
|
);
|
|
@@ -1100,7 +1089,7 @@ function orgCommand() {
|
|
|
1100
1089
|
|
|
1101
1090
|
// src/commands/write.ts
|
|
1102
1091
|
import { Command as Command7 } from "commander";
|
|
1103
|
-
async function
|
|
1092
|
+
async function client3(globals) {
|
|
1104
1093
|
const cfg = await resolveConfig({
|
|
1105
1094
|
apiKeyFlag: globals.apiKey ?? null,
|
|
1106
1095
|
baseUrlFlag: globals.baseUrl ?? null
|
|
@@ -1129,7 +1118,7 @@ function chatbotsCommand() {
|
|
|
1129
1118
|
cmd.command("list").description("List every chatbot the credential can reach").action(async function() {
|
|
1130
1119
|
try {
|
|
1131
1120
|
const globals = this.optsWithGlobals();
|
|
1132
|
-
const c = await
|
|
1121
|
+
const c = await client3(globals);
|
|
1133
1122
|
const result = await c.get(
|
|
1134
1123
|
"/api/v1/chatbots"
|
|
1135
1124
|
);
|
|
@@ -1141,7 +1130,7 @@ function chatbotsCommand() {
|
|
|
1141
1130
|
cmd.command("create").description("Create a new chatbot (PAT scope required)").requiredOption("--name <name>", "Chatbot name").option("--website <url>").option("--docs-url <url>").option("--mcp-url <url>").option("--language <code>", "Primary language code (default: en)", "en").action(async function(opts) {
|
|
1142
1131
|
try {
|
|
1143
1132
|
const globals = this.optsWithGlobals();
|
|
1144
|
-
const c = await
|
|
1133
|
+
const c = await client3(globals);
|
|
1145
1134
|
const result = await c.post("/api/v1/chatbots", {
|
|
1146
1135
|
name: opts.name,
|
|
1147
1136
|
websiteUrl: opts.website,
|
|
@@ -1161,7 +1150,7 @@ function chatbotsCommand() {
|
|
|
1161
1150
|
cmd.command("delete <chatbotId>").description("Delete a chatbot (irreversible \u2014 cascade-deletes everything)").action(async function(chatbotId) {
|
|
1162
1151
|
try {
|
|
1163
1152
|
const globals = this.optsWithGlobals();
|
|
1164
|
-
const c = await
|
|
1153
|
+
const c = await client3(globals);
|
|
1165
1154
|
await c.delete(`/api/v1/chatbots/${chatbotId}`);
|
|
1166
1155
|
emit({ ok: true, deleted: chatbotId }, { json: !!globals.json });
|
|
1167
1156
|
} catch (err) {
|
|
@@ -1175,7 +1164,7 @@ function webhooksCommand() {
|
|
|
1175
1164
|
cmd.command("list").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1176
1165
|
try {
|
|
1177
1166
|
const globals = this.optsWithGlobals();
|
|
1178
|
-
const c = await
|
|
1167
|
+
const c = await client3(globals);
|
|
1179
1168
|
const result = await c.get(
|
|
1180
1169
|
`/api/v1/chatbots/${opts.chatbot}/webhooks`
|
|
1181
1170
|
);
|
|
@@ -1187,7 +1176,7 @@ function webhooksCommand() {
|
|
|
1187
1176
|
cmd.command("create").requiredOption("--chatbot <id>", "Chatbot id").requiredOption("--name <name>").requiredOption("--url <url>").option("--type <type>", "discord | slack | custom", "custom").action(async function(opts) {
|
|
1188
1177
|
try {
|
|
1189
1178
|
const globals = this.optsWithGlobals();
|
|
1190
|
-
const c = await
|
|
1179
|
+
const c = await client3(globals);
|
|
1191
1180
|
const result = await c.post(`/api/v1/chatbots/${opts.chatbot}/webhooks`, {
|
|
1192
1181
|
name: opts.name,
|
|
1193
1182
|
url: opts.url,
|
|
@@ -1202,7 +1191,7 @@ function webhooksCommand() {
|
|
|
1202
1191
|
cmd.command("delete").requiredOption("--chatbot <id>", "Chatbot id").requiredOption("--webhook <id>", "Webhook id").action(async function(opts) {
|
|
1203
1192
|
try {
|
|
1204
1193
|
const globals = this.optsWithGlobals();
|
|
1205
|
-
const c = await
|
|
1194
|
+
const c = await client3(globals);
|
|
1206
1195
|
await c.delete(`/api/v1/chatbots/${opts.chatbot}/webhooks/${opts.webhook}`);
|
|
1207
1196
|
emit({ ok: true, deleted: opts.webhook }, { json: !!globals.json });
|
|
1208
1197
|
} catch (err) {
|
|
@@ -1219,7 +1208,7 @@ function settingsCommand() {
|
|
|
1219
1208
|
keys.command("rotate-ingest").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1220
1209
|
try {
|
|
1221
1210
|
const globals = this.optsWithGlobals();
|
|
1222
|
-
const c = await
|
|
1211
|
+
const c = await client3(globals);
|
|
1223
1212
|
const result = await c.post(
|
|
1224
1213
|
`/api/v1/chatbots/${opts.chatbot}/keys/ingest/rotate`,
|
|
1225
1214
|
{}
|
|
@@ -1233,7 +1222,7 @@ function settingsCommand() {
|
|
|
1233
1222
|
keys.command("generate-read").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1234
1223
|
try {
|
|
1235
1224
|
const globals = this.optsWithGlobals();
|
|
1236
|
-
const c = await
|
|
1225
|
+
const c = await client3(globals);
|
|
1237
1226
|
const result = await c.post(
|
|
1238
1227
|
`/api/v1/chatbots/${opts.chatbot}/keys/read`,
|
|
1239
1228
|
{}
|
|
@@ -1247,7 +1236,7 @@ function settingsCommand() {
|
|
|
1247
1236
|
keys.command("generate-admin").requiredOption("--chatbot <id>", "Chatbot id").requiredOption("--name <name>", "Human-friendly name (e.g. 'CI key')").option("--expires-in-days <n>", "Auto-expire after N days").action(async function(opts) {
|
|
1248
1237
|
try {
|
|
1249
1238
|
const globals = this.optsWithGlobals();
|
|
1250
|
-
const c = await
|
|
1239
|
+
const c = await client3(globals);
|
|
1251
1240
|
const result = await c.post(`/api/v1/chatbots/${opts.chatbot}/admin-keys`, {
|
|
1252
1241
|
name: opts.name,
|
|
1253
1242
|
expiresInDays: opts.expiresInDays ? Number(opts.expiresInDays) : void 0
|
|
@@ -1261,7 +1250,7 @@ function settingsCommand() {
|
|
|
1261
1250
|
keys.command("list-admin").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1262
1251
|
try {
|
|
1263
1252
|
const globals = this.optsWithGlobals();
|
|
1264
|
-
const c = await
|
|
1253
|
+
const c = await client3(globals);
|
|
1265
1254
|
const result = await c.get(
|
|
1266
1255
|
`/api/v1/chatbots/${opts.chatbot}/admin-keys`
|
|
1267
1256
|
);
|
|
@@ -1273,7 +1262,7 @@ function settingsCommand() {
|
|
|
1273
1262
|
keys.command("revoke-admin").requiredOption("--chatbot <id>", "Chatbot id").requiredOption("--key <keyId>", "Admin key id").action(async function(opts) {
|
|
1274
1263
|
try {
|
|
1275
1264
|
const globals = this.optsWithGlobals();
|
|
1276
|
-
const c = await
|
|
1265
|
+
const c = await client3(globals);
|
|
1277
1266
|
await c.delete(`/api/v1/chatbots/${opts.chatbot}/admin-keys/${opts.key}`);
|
|
1278
1267
|
emit({ ok: true, revoked: opts.key }, { json: !!globals.json });
|
|
1279
1268
|
} catch (err) {
|
|
@@ -1290,7 +1279,7 @@ function settingsCommand() {
|
|
|
1290
1279
|
fatal("Provide at least one setting to update.");
|
|
1291
1280
|
}
|
|
1292
1281
|
const globals = this.optsWithGlobals();
|
|
1293
|
-
const c = await
|
|
1282
|
+
const c = await client3(globals);
|
|
1294
1283
|
await c.patch(`/api/v1/chatbots/${opts.chatbot}/settings`, { settings });
|
|
1295
1284
|
emit({ ok: true }, { json: !!globals.json });
|
|
1296
1285
|
} catch (err) {
|
|
@@ -1304,7 +1293,7 @@ function workflowsCommand() {
|
|
|
1304
1293
|
cmd.command("list").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1305
1294
|
try {
|
|
1306
1295
|
const globals = this.optsWithGlobals();
|
|
1307
|
-
const c = await
|
|
1296
|
+
const c = await client3(globals);
|
|
1308
1297
|
const result = await c.get(
|
|
1309
1298
|
`/api/v1/chatbots/${opts.chatbot}/workflows`
|
|
1310
1299
|
);
|
|
@@ -1322,7 +1311,7 @@ function workflowsCommand() {
|
|
|
1322
1311
|
).requiredOption("--webhook <id>", "Webhook id to fire").option("--message <tpl>", "Message template (supports {{user.id}}, etc.)").action(async function(opts) {
|
|
1323
1312
|
try {
|
|
1324
1313
|
const globals = this.optsWithGlobals();
|
|
1325
|
-
const c = await
|
|
1314
|
+
const c = await client3(globals);
|
|
1326
1315
|
const result = await c.post(`/api/v1/chatbots/${opts.chatbot}/workflows`, {
|
|
1327
1316
|
name: opts.name,
|
|
1328
1317
|
template: opts.template,
|
|
@@ -1342,7 +1331,7 @@ function reportsCommand() {
|
|
|
1342
1331
|
cmd.command("list").requiredOption("--chatbot <id>", "Chatbot id").action(async function(opts) {
|
|
1343
1332
|
try {
|
|
1344
1333
|
const globals = this.optsWithGlobals();
|
|
1345
|
-
const c = await
|
|
1334
|
+
const c = await client3(globals);
|
|
1346
1335
|
const result = await c.get(
|
|
1347
1336
|
`/api/v1/chatbots/${opts.chatbot}/reports`
|
|
1348
1337
|
);
|
|
@@ -1354,7 +1343,7 @@ function reportsCommand() {
|
|
|
1354
1343
|
cmd.command("create").description("Create a new AI report; returns the org-private dashboard URL").requiredOption("--chatbot <id>", "Chatbot id").option("--name <name>", "Report name", "Untitled Report").action(async function(opts) {
|
|
1355
1344
|
try {
|
|
1356
1345
|
const globals = this.optsWithGlobals();
|
|
1357
|
-
const c = await
|
|
1346
|
+
const c = await client3(globals);
|
|
1358
1347
|
const result = await c.post(`/api/v1/chatbots/${opts.chatbot}/reports`, { name: opts.name });
|
|
1359
1348
|
process.stderr.write(
|
|
1360
1349
|
`
|
|
@@ -1378,7 +1367,7 @@ function analysisCommand() {
|
|
|
1378
1367
|
cmd.command("list").requiredOption("--chatbot <id>", "Chatbot id").option("--type <t>", "intent | flag | assistant_outcome | assistant_issue").option("--pending", "Include pending suggestions").action(async function(opts) {
|
|
1379
1368
|
try {
|
|
1380
1369
|
const globals = this.optsWithGlobals();
|
|
1381
|
-
const c = await
|
|
1370
|
+
const c = await client3(globals);
|
|
1382
1371
|
const qs = new URLSearchParams();
|
|
1383
1372
|
if (opts.type) qs.set("type", opts.type);
|
|
1384
1373
|
if (opts.pending) qs.set("pending", "true");
|
|
@@ -1396,7 +1385,7 @@ function analysisCommand() {
|
|
|
1396
1385
|
).requiredOption("--name <slug>", "snake_case slug").requiredOption("--display-name <text>").requiredOption("--description <text>").action(async function(opts) {
|
|
1397
1386
|
try {
|
|
1398
1387
|
const globals = this.optsWithGlobals();
|
|
1399
|
-
const c = await
|
|
1388
|
+
const c = await client3(globals);
|
|
1400
1389
|
const result = await c.post(
|
|
1401
1390
|
`/api/v1/chatbots/${opts.chatbot}/analysis-definitions`,
|
|
1402
1391
|
{
|
|
@@ -1420,7 +1409,7 @@ function usersCommand() {
|
|
|
1420
1409
|
cmd.command("list").requiredOption("--chatbot <id>", "Chatbot id").option("--from <iso>").option("--to <iso>").option("--days <n>", "Convenience: last N days").option("--search <q>").option("--limit <n>", "Page size", "20").action(async function(opts) {
|
|
1421
1410
|
try {
|
|
1422
1411
|
const globals = this.optsWithGlobals();
|
|
1423
|
-
const c = await
|
|
1412
|
+
const c = await client3(globals);
|
|
1424
1413
|
const qs = new URLSearchParams();
|
|
1425
1414
|
let from = opts.from;
|
|
1426
1415
|
if (!from && opts.days) {
|
|
@@ -1451,7 +1440,7 @@ function sdkCommand() {
|
|
|
1451
1440
|
);
|
|
1452
1441
|
cmd.command("install-instructions").description("Print markdown the calling agent can follow").option(
|
|
1453
1442
|
"--framework <name>",
|
|
1454
|
-
"next |
|
|
1443
|
+
"next | vercel-ai-sdk (default: next)",
|
|
1455
1444
|
"next"
|
|
1456
1445
|
).option("--chatbot <id>", "Chatbot id (for the example snippet)").action(async function(opts) {
|
|
1457
1446
|
const chatbotId = opts.chatbot ?? "<chatbotId>";
|
|
@@ -1511,24 +1500,36 @@ function sdkCommand() {
|
|
|
1511
1500
|
cmd.command("verify").description("Check whether any event has arrived for the chatbot yet").requiredOption("--chatbot <id>", "Chatbot id").option("--timeout <n>", "Seconds to wait (default: 60)", "60").action(async function(opts) {
|
|
1512
1501
|
try {
|
|
1513
1502
|
const globals = this.optsWithGlobals();
|
|
1514
|
-
const c = await
|
|
1515
|
-
const
|
|
1503
|
+
const c = await client3(globals);
|
|
1504
|
+
const timeoutSec = Number(opts.timeout);
|
|
1505
|
+
const deadline = Date.now() + timeoutSec * 1e3;
|
|
1506
|
+
const params = new URLSearchParams({
|
|
1507
|
+
chatbotId: opts.chatbot,
|
|
1508
|
+
limit: "1"
|
|
1509
|
+
});
|
|
1510
|
+
process.stderr.write(
|
|
1511
|
+
`Waiting for first event on chatbot ${opts.chatbot} (timeout ${timeoutSec}s)\u2026
|
|
1512
|
+
`
|
|
1513
|
+
);
|
|
1514
|
+
let lastTick = Date.now();
|
|
1516
1515
|
while (Date.now() < deadline) {
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
`\u2713 First event detected. ${result.total} conversation(s) ingested.
|
|
1516
|
+
const result = await c.get(`/api/v1/conversations?${params}`);
|
|
1517
|
+
if (result.total > 0) {
|
|
1518
|
+
process.stderr.write(
|
|
1519
|
+
`First event detected. ${result.total} conversation(s) ingested.
|
|
1522
1520
|
`
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1521
|
+
);
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1524
|
+
if (Date.now() - lastTick >= 5e3) {
|
|
1525
|
+
process.stderr.write(".");
|
|
1526
|
+
lastTick = Date.now();
|
|
1527
1527
|
}
|
|
1528
1528
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
1529
1529
|
}
|
|
1530
1530
|
process.stderr.write(
|
|
1531
|
-
`
|
|
1531
|
+
`
|
|
1532
|
+
Timed out after ${timeoutSec}s \u2014 no events yet. Confirm OPENBAT_API_KEY and that recordMessages is being called.
|
|
1532
1533
|
`
|
|
1533
1534
|
);
|
|
1534
1535
|
process.exit(2);
|
|
@@ -1543,9 +1544,9 @@ function sdkCommand() {
|
|
|
1543
1544
|
var program = new Command8();
|
|
1544
1545
|
program.name("openbat").description(
|
|
1545
1546
|
"Query OpenBat chatbot data \u2014 conversations, sentiment, analytics, exports."
|
|
1546
|
-
).version("0.2.
|
|
1547
|
+
).version("0.2.2").option("--api-key <key>", "Override the stored Read API key (footgun \u2014 leaks into shell history)").option(
|
|
1547
1548
|
"--base-url <url>",
|
|
1548
|
-
"Override the OpenBat API base URL (defaults to ~/.openbatrc or https://
|
|
1549
|
+
"Override the OpenBat API base URL (defaults to ~/.openbatrc or https://openbat.dev)"
|
|
1549
1550
|
).option(
|
|
1550
1551
|
"--chatbot <id|name>",
|
|
1551
1552
|
"Override the active chatbot for this invocation (UUID or chatbot name)"
|