@openbat/cli 0.2.2 → 0.2.3
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 +1 -1
- package/dist/api-client.mjs +1 -1
- package/dist/{chunk-MCDJLQI2.mjs → chunk-HBSCN3HV.mjs} +1 -1
- package/dist/index.js +66 -37
- package/dist/index.mjs +66 -37
- package/package.json +5 -2
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.2.
|
|
35
|
+
var CLI_VERSION = "0.2.3";
|
|
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>`);
|
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.2.
|
|
12
|
+
var CLI_VERSION = "0.2.3";
|
|
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>`);
|
package/dist/index.js
CHANGED
|
@@ -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.2.
|
|
166
|
+
var CLI_VERSION = "0.2.3";
|
|
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>`);
|
|
@@ -1277,6 +1277,15 @@ async function client3(globals) {
|
|
|
1277
1277
|
}
|
|
1278
1278
|
return new ApiClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
|
|
1279
1279
|
}
|
|
1280
|
+
function requireChatbotId(cmd) {
|
|
1281
|
+
const globals = cmd.optsWithGlobals();
|
|
1282
|
+
if (!globals.chatbot) {
|
|
1283
|
+
fatal(
|
|
1284
|
+
"--chatbot <id> is required. Pass it inline or set a default with `openbat use <id>`."
|
|
1285
|
+
);
|
|
1286
|
+
}
|
|
1287
|
+
return globals.chatbot;
|
|
1288
|
+
}
|
|
1280
1289
|
function surfacePlaintext(plaintext, label) {
|
|
1281
1290
|
process.stderr.write(
|
|
1282
1291
|
`
|
|
@@ -1339,23 +1348,25 @@ function chatbotsCommand() {
|
|
|
1339
1348
|
}
|
|
1340
1349
|
function webhooksCommand() {
|
|
1341
1350
|
const cmd = new import_commander7.Command("webhooks").description("Manage webhooks for a chatbot");
|
|
1342
|
-
cmd.command("list").
|
|
1351
|
+
cmd.command("list").action(async function() {
|
|
1343
1352
|
try {
|
|
1353
|
+
const chatbotId = requireChatbotId(this);
|
|
1344
1354
|
const globals = this.optsWithGlobals();
|
|
1345
1355
|
const c = await client3(globals);
|
|
1346
1356
|
const result = await c.get(
|
|
1347
|
-
`/api/v1/chatbots/${
|
|
1357
|
+
`/api/v1/chatbots/${chatbotId}/webhooks`
|
|
1348
1358
|
);
|
|
1349
1359
|
emit(result.webhooks, { json: !!globals.json });
|
|
1350
1360
|
} catch (err) {
|
|
1351
1361
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1352
1362
|
}
|
|
1353
1363
|
});
|
|
1354
|
-
cmd.command("create").requiredOption("--
|
|
1364
|
+
cmd.command("create").requiredOption("--name <name>").requiredOption("--url <url>").option("--type <type>", "discord | slack | custom", "custom").action(async function(opts) {
|
|
1355
1365
|
try {
|
|
1366
|
+
const chatbotId = requireChatbotId(this);
|
|
1356
1367
|
const globals = this.optsWithGlobals();
|
|
1357
1368
|
const c = await client3(globals);
|
|
1358
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1369
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/webhooks`, {
|
|
1359
1370
|
name: opts.name,
|
|
1360
1371
|
url: opts.url,
|
|
1361
1372
|
type: opts.type
|
|
@@ -1366,11 +1377,12 @@ function webhooksCommand() {
|
|
|
1366
1377
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1367
1378
|
}
|
|
1368
1379
|
});
|
|
1369
|
-
cmd.command("delete").requiredOption("--
|
|
1380
|
+
cmd.command("delete").requiredOption("--webhook <id>", "Webhook id").action(async function(opts) {
|
|
1370
1381
|
try {
|
|
1382
|
+
const chatbotId = requireChatbotId(this);
|
|
1371
1383
|
const globals = this.optsWithGlobals();
|
|
1372
1384
|
const c = await client3(globals);
|
|
1373
|
-
await c.delete(`/api/v1/chatbots/${
|
|
1385
|
+
await c.delete(`/api/v1/chatbots/${chatbotId}/webhooks/${opts.webhook}`);
|
|
1374
1386
|
emit({ ok: true, deleted: opts.webhook }, { json: !!globals.json });
|
|
1375
1387
|
} catch (err) {
|
|
1376
1388
|
fatal(err instanceof Error ? err.message : String(err));
|
|
@@ -1383,12 +1395,13 @@ function settingsCommand() {
|
|
|
1383
1395
|
"Manage chatbot settings + per-chatbot keys"
|
|
1384
1396
|
);
|
|
1385
1397
|
const keys = cmd.command("keys").description("Manage API keys for a chatbot");
|
|
1386
|
-
keys.command("rotate-ingest").
|
|
1398
|
+
keys.command("rotate-ingest").action(async function() {
|
|
1387
1399
|
try {
|
|
1400
|
+
const chatbotId = requireChatbotId(this);
|
|
1388
1401
|
const globals = this.optsWithGlobals();
|
|
1389
1402
|
const c = await client3(globals);
|
|
1390
1403
|
const result = await c.post(
|
|
1391
|
-
`/api/v1/chatbots/${
|
|
1404
|
+
`/api/v1/chatbots/${chatbotId}/keys/ingest/rotate`,
|
|
1392
1405
|
{}
|
|
1393
1406
|
);
|
|
1394
1407
|
surfacePlaintext(result.plaintext, "New ingest key (ob_live_*)");
|
|
@@ -1397,12 +1410,13 @@ function settingsCommand() {
|
|
|
1397
1410
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1398
1411
|
}
|
|
1399
1412
|
});
|
|
1400
|
-
keys.command("generate-read").
|
|
1413
|
+
keys.command("generate-read").action(async function() {
|
|
1401
1414
|
try {
|
|
1415
|
+
const chatbotId = requireChatbotId(this);
|
|
1402
1416
|
const globals = this.optsWithGlobals();
|
|
1403
1417
|
const c = await client3(globals);
|
|
1404
1418
|
const result = await c.post(
|
|
1405
|
-
`/api/v1/chatbots/${
|
|
1419
|
+
`/api/v1/chatbots/${chatbotId}/keys/read`,
|
|
1406
1420
|
{}
|
|
1407
1421
|
);
|
|
1408
1422
|
surfacePlaintext(result.plaintext, "New read key (ob_read_*)");
|
|
@@ -1411,11 +1425,12 @@ function settingsCommand() {
|
|
|
1411
1425
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1412
1426
|
}
|
|
1413
1427
|
});
|
|
1414
|
-
keys.command("generate-admin").requiredOption("--
|
|
1428
|
+
keys.command("generate-admin").requiredOption("--name <name>", "Human-friendly name (e.g. 'CI key')").option("--expires-in-days <n>", "Auto-expire after N days").action(async function(opts) {
|
|
1415
1429
|
try {
|
|
1430
|
+
const chatbotId = requireChatbotId(this);
|
|
1416
1431
|
const globals = this.optsWithGlobals();
|
|
1417
1432
|
const c = await client3(globals);
|
|
1418
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1433
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/admin-keys`, {
|
|
1419
1434
|
name: opts.name,
|
|
1420
1435
|
expiresInDays: opts.expiresInDays ? Number(opts.expiresInDays) : void 0
|
|
1421
1436
|
});
|
|
@@ -1425,30 +1440,33 @@ function settingsCommand() {
|
|
|
1425
1440
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1426
1441
|
}
|
|
1427
1442
|
});
|
|
1428
|
-
keys.command("list-admin").
|
|
1443
|
+
keys.command("list-admin").action(async function() {
|
|
1429
1444
|
try {
|
|
1445
|
+
const chatbotId = requireChatbotId(this);
|
|
1430
1446
|
const globals = this.optsWithGlobals();
|
|
1431
1447
|
const c = await client3(globals);
|
|
1432
1448
|
const result = await c.get(
|
|
1433
|
-
`/api/v1/chatbots/${
|
|
1449
|
+
`/api/v1/chatbots/${chatbotId}/admin-keys`
|
|
1434
1450
|
);
|
|
1435
1451
|
emit(result.keys, { json: !!globals.json });
|
|
1436
1452
|
} catch (err) {
|
|
1437
1453
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1438
1454
|
}
|
|
1439
1455
|
});
|
|
1440
|
-
keys.command("revoke-admin").requiredOption("--
|
|
1456
|
+
keys.command("revoke-admin").requiredOption("--key <keyId>", "Admin key id").action(async function(opts) {
|
|
1441
1457
|
try {
|
|
1458
|
+
const chatbotId = requireChatbotId(this);
|
|
1442
1459
|
const globals = this.optsWithGlobals();
|
|
1443
1460
|
const c = await client3(globals);
|
|
1444
|
-
await c.delete(`/api/v1/chatbots/${
|
|
1461
|
+
await c.delete(`/api/v1/chatbots/${chatbotId}/admin-keys/${opts.key}`);
|
|
1445
1462
|
emit({ ok: true, revoked: opts.key }, { json: !!globals.json });
|
|
1446
1463
|
} catch (err) {
|
|
1447
1464
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1448
1465
|
}
|
|
1449
1466
|
});
|
|
1450
|
-
cmd.command("update").description("Patch a chatbot's settings JSONB").
|
|
1467
|
+
cmd.command("update").description("Patch a chatbot's settings JSONB").option("--description <text>").option("--website-url <url>").option("--language <code>").action(async function(opts) {
|
|
1451
1468
|
try {
|
|
1469
|
+
const chatbotId = requireChatbotId(this);
|
|
1452
1470
|
const settings = {};
|
|
1453
1471
|
if (opts.description) settings.description = opts.description;
|
|
1454
1472
|
if (opts.websiteUrl) settings.website_url = opts.websiteUrl;
|
|
@@ -1458,7 +1476,7 @@ function settingsCommand() {
|
|
|
1458
1476
|
}
|
|
1459
1477
|
const globals = this.optsWithGlobals();
|
|
1460
1478
|
const c = await client3(globals);
|
|
1461
|
-
await c.patch(`/api/v1/chatbots/${
|
|
1479
|
+
await c.patch(`/api/v1/chatbots/${chatbotId}/settings`, { settings });
|
|
1462
1480
|
emit({ ok: true }, { json: !!globals.json });
|
|
1463
1481
|
} catch (err) {
|
|
1464
1482
|
fatal(err instanceof Error ? err.message : String(err));
|
|
@@ -1468,19 +1486,20 @@ function settingsCommand() {
|
|
|
1468
1486
|
}
|
|
1469
1487
|
function workflowsCommand() {
|
|
1470
1488
|
const cmd = new import_commander7.Command("workflows").description("Manage workflows");
|
|
1471
|
-
cmd.command("list").
|
|
1489
|
+
cmd.command("list").action(async function() {
|
|
1472
1490
|
try {
|
|
1491
|
+
const chatbotId = requireChatbotId(this);
|
|
1473
1492
|
const globals = this.optsWithGlobals();
|
|
1474
1493
|
const c = await client3(globals);
|
|
1475
1494
|
const result = await c.get(
|
|
1476
|
-
`/api/v1/chatbots/${
|
|
1495
|
+
`/api/v1/chatbots/${chatbotId}/workflows`
|
|
1477
1496
|
);
|
|
1478
1497
|
emit(result.workflows, { json: !!globals.json });
|
|
1479
1498
|
} catch (err) {
|
|
1480
1499
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1481
1500
|
}
|
|
1482
1501
|
});
|
|
1483
|
-
cmd.command("create").description("Create a workflow from a built-in template").requiredOption("--
|
|
1502
|
+
cmd.command("create").description("Create a workflow from a built-in template").requiredOption("--name <name>").requiredOption(
|
|
1484
1503
|
"--template <name>",
|
|
1485
1504
|
"flag-to-webhook | outcome-to-webhook | sentiment-drop-to-webhook"
|
|
1486
1505
|
).requiredOption(
|
|
@@ -1488,9 +1507,10 @@ function workflowsCommand() {
|
|
|
1488
1507
|
"Flag value / outcome value / sentiment threshold"
|
|
1489
1508
|
).requiredOption("--webhook <id>", "Webhook id to fire").option("--message <tpl>", "Message template (supports {{user.id}}, etc.)").action(async function(opts) {
|
|
1490
1509
|
try {
|
|
1510
|
+
const chatbotId = requireChatbotId(this);
|
|
1491
1511
|
const globals = this.optsWithGlobals();
|
|
1492
1512
|
const c = await client3(globals);
|
|
1493
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1513
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/workflows`, {
|
|
1494
1514
|
name: opts.name,
|
|
1495
1515
|
template: opts.template,
|
|
1496
1516
|
triggerValue: opts.triggerValue,
|
|
@@ -1506,23 +1526,25 @@ function workflowsCommand() {
|
|
|
1506
1526
|
}
|
|
1507
1527
|
function reportsCommand() {
|
|
1508
1528
|
const cmd = new import_commander7.Command("reports").description("Manage AI reports");
|
|
1509
|
-
cmd.command("list").
|
|
1529
|
+
cmd.command("list").action(async function() {
|
|
1510
1530
|
try {
|
|
1531
|
+
const chatbotId = requireChatbotId(this);
|
|
1511
1532
|
const globals = this.optsWithGlobals();
|
|
1512
1533
|
const c = await client3(globals);
|
|
1513
1534
|
const result = await c.get(
|
|
1514
|
-
`/api/v1/chatbots/${
|
|
1535
|
+
`/api/v1/chatbots/${chatbotId}/reports`
|
|
1515
1536
|
);
|
|
1516
1537
|
emit(result.reports, { json: !!globals.json });
|
|
1517
1538
|
} catch (err) {
|
|
1518
1539
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1519
1540
|
}
|
|
1520
1541
|
});
|
|
1521
|
-
cmd.command("create").description("Create a new AI report; returns the org-private dashboard URL").
|
|
1542
|
+
cmd.command("create").description("Create a new AI report; returns the org-private dashboard URL").option("--name <name>", "Report name", "Untitled Report").action(async function(opts) {
|
|
1522
1543
|
try {
|
|
1544
|
+
const chatbotId = requireChatbotId(this);
|
|
1523
1545
|
const globals = this.optsWithGlobals();
|
|
1524
1546
|
const c = await client3(globals);
|
|
1525
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1547
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/reports`, { name: opts.name });
|
|
1526
1548
|
process.stderr.write(
|
|
1527
1549
|
`
|
|
1528
1550
|
Created report. View it (org members only):
|
|
@@ -1542,30 +1564,32 @@ Created report. View it (org members only):
|
|
|
1542
1564
|
}
|
|
1543
1565
|
function analysisCommand() {
|
|
1544
1566
|
const cmd = new import_commander7.Command("analysis").description("Manage analysis definitions");
|
|
1545
|
-
cmd.command("list").
|
|
1567
|
+
cmd.command("list").option("--type <t>", "intent | flag | assistant_outcome | assistant_issue").option("--pending", "Include pending suggestions").action(async function(opts) {
|
|
1546
1568
|
try {
|
|
1569
|
+
const chatbotId = requireChatbotId(this);
|
|
1547
1570
|
const globals = this.optsWithGlobals();
|
|
1548
1571
|
const c = await client3(globals);
|
|
1549
1572
|
const qs = new URLSearchParams();
|
|
1550
1573
|
if (opts.type) qs.set("type", opts.type);
|
|
1551
1574
|
if (opts.pending) qs.set("pending", "true");
|
|
1552
1575
|
const result = await c.get(
|
|
1553
|
-
`/api/v1/chatbots/${
|
|
1576
|
+
`/api/v1/chatbots/${chatbotId}/analysis-definitions${qs.size ? `?${qs}` : ""}`
|
|
1554
1577
|
);
|
|
1555
1578
|
emit(result.definitions, { json: !!globals.json });
|
|
1556
1579
|
} catch (err) {
|
|
1557
1580
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1558
1581
|
}
|
|
1559
1582
|
});
|
|
1560
|
-
cmd.command("add").requiredOption(
|
|
1583
|
+
cmd.command("add").requiredOption(
|
|
1561
1584
|
"--type <t>",
|
|
1562
1585
|
"intent | flag | assistant_outcome | assistant_issue"
|
|
1563
1586
|
).requiredOption("--name <slug>", "snake_case slug").requiredOption("--display-name <text>").requiredOption("--description <text>").action(async function(opts) {
|
|
1564
1587
|
try {
|
|
1588
|
+
const chatbotId = requireChatbotId(this);
|
|
1565
1589
|
const globals = this.optsWithGlobals();
|
|
1566
1590
|
const c = await client3(globals);
|
|
1567
1591
|
const result = await c.post(
|
|
1568
|
-
`/api/v1/chatbots/${
|
|
1592
|
+
`/api/v1/chatbots/${chatbotId}/analysis-definitions`,
|
|
1569
1593
|
{
|
|
1570
1594
|
analysisType: opts.type,
|
|
1571
1595
|
name: opts.name,
|
|
@@ -1584,8 +1608,9 @@ function usersCommand() {
|
|
|
1584
1608
|
const cmd = new import_commander7.Command("users").description(
|
|
1585
1609
|
"List external users (chatbot customers) with health metrics"
|
|
1586
1610
|
);
|
|
1587
|
-
cmd.command("list").
|
|
1611
|
+
cmd.command("list").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) {
|
|
1588
1612
|
try {
|
|
1613
|
+
const chatbotId = requireChatbotId(this);
|
|
1589
1614
|
const globals = this.optsWithGlobals();
|
|
1590
1615
|
const c = await client3(globals);
|
|
1591
1616
|
const qs = new URLSearchParams();
|
|
@@ -1600,7 +1625,7 @@ function usersCommand() {
|
|
|
1600
1625
|
if (opts.search) qs.set("search", opts.search);
|
|
1601
1626
|
qs.set("limit", opts.limit);
|
|
1602
1627
|
const result = await c.get(
|
|
1603
|
-
`/api/v1/chatbots/${
|
|
1628
|
+
`/api/v1/chatbots/${chatbotId}/external-users?${qs}`
|
|
1604
1629
|
);
|
|
1605
1630
|
emit(result.users, { json: !!globals.json });
|
|
1606
1631
|
process.stderr.write(`
|
|
@@ -1675,18 +1700,22 @@ function sdkCommand() {
|
|
|
1675
1700
|
const out = opts.framework === "vercel-ai-sdk" ? snippetWrapper : snippetNext;
|
|
1676
1701
|
process.stdout.write(out);
|
|
1677
1702
|
});
|
|
1678
|
-
cmd.command("verify").description("Check whether any event has arrived for the chatbot yet").
|
|
1703
|
+
cmd.command("verify").description("Check whether any event has arrived for the chatbot yet").option("--timeout <n>", "Seconds to wait (default: 60)", "60").action(async function(opts) {
|
|
1679
1704
|
try {
|
|
1680
1705
|
const globals = this.optsWithGlobals();
|
|
1706
|
+
const chatbotId = globals.chatbot;
|
|
1707
|
+
if (!chatbotId) {
|
|
1708
|
+
fatal("--chatbot <id> is required (also accepts the persisted active chatbot).");
|
|
1709
|
+
}
|
|
1681
1710
|
const c = await client3(globals);
|
|
1682
1711
|
const timeoutSec = Number(opts.timeout);
|
|
1683
1712
|
const deadline = Date.now() + timeoutSec * 1e3;
|
|
1684
1713
|
const params = new URLSearchParams({
|
|
1685
|
-
chatbotId
|
|
1714
|
+
chatbotId,
|
|
1686
1715
|
limit: "1"
|
|
1687
1716
|
});
|
|
1688
1717
|
process.stderr.write(
|
|
1689
|
-
`Waiting for first event on chatbot ${
|
|
1718
|
+
`Waiting for first event on chatbot ${chatbotId} (timeout ${timeoutSec}s)\u2026
|
|
1690
1719
|
`
|
|
1691
1720
|
);
|
|
1692
1721
|
let lastTick = Date.now();
|
|
@@ -1722,7 +1751,7 @@ Timed out after ${timeoutSec}s \u2014 no events yet. Confirm OPENBAT_API_KEY and
|
|
|
1722
1751
|
var program = new import_commander8.Command();
|
|
1723
1752
|
program.name("openbat").description(
|
|
1724
1753
|
"Query OpenBat chatbot data \u2014 conversations, sentiment, analytics, exports."
|
|
1725
|
-
).version("0.2.
|
|
1754
|
+
).version("0.2.3").option("--api-key <key>", "Override the stored Read API key (footgun \u2014 leaks into shell history)").option(
|
|
1726
1755
|
"--base-url <url>",
|
|
1727
1756
|
"Override the OpenBat API base URL (defaults to ~/.openbatrc or https://openbat.dev)"
|
|
1728
1757
|
).option(
|
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-HBSCN3HV.mjs";
|
|
5
5
|
|
|
6
6
|
// src/index.ts
|
|
7
7
|
import { Command as Command8 } from "commander";
|
|
@@ -1099,6 +1099,15 @@ async function client3(globals) {
|
|
|
1099
1099
|
}
|
|
1100
1100
|
return new ApiClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
|
|
1101
1101
|
}
|
|
1102
|
+
function requireChatbotId(cmd) {
|
|
1103
|
+
const globals = cmd.optsWithGlobals();
|
|
1104
|
+
if (!globals.chatbot) {
|
|
1105
|
+
fatal(
|
|
1106
|
+
"--chatbot <id> is required. Pass it inline or set a default with `openbat use <id>`."
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
return globals.chatbot;
|
|
1110
|
+
}
|
|
1102
1111
|
function surfacePlaintext(plaintext, label) {
|
|
1103
1112
|
process.stderr.write(
|
|
1104
1113
|
`
|
|
@@ -1161,23 +1170,25 @@ function chatbotsCommand() {
|
|
|
1161
1170
|
}
|
|
1162
1171
|
function webhooksCommand() {
|
|
1163
1172
|
const cmd = new Command7("webhooks").description("Manage webhooks for a chatbot");
|
|
1164
|
-
cmd.command("list").
|
|
1173
|
+
cmd.command("list").action(async function() {
|
|
1165
1174
|
try {
|
|
1175
|
+
const chatbotId = requireChatbotId(this);
|
|
1166
1176
|
const globals = this.optsWithGlobals();
|
|
1167
1177
|
const c = await client3(globals);
|
|
1168
1178
|
const result = await c.get(
|
|
1169
|
-
`/api/v1/chatbots/${
|
|
1179
|
+
`/api/v1/chatbots/${chatbotId}/webhooks`
|
|
1170
1180
|
);
|
|
1171
1181
|
emit(result.webhooks, { json: !!globals.json });
|
|
1172
1182
|
} catch (err) {
|
|
1173
1183
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1174
1184
|
}
|
|
1175
1185
|
});
|
|
1176
|
-
cmd.command("create").requiredOption("--
|
|
1186
|
+
cmd.command("create").requiredOption("--name <name>").requiredOption("--url <url>").option("--type <type>", "discord | slack | custom", "custom").action(async function(opts) {
|
|
1177
1187
|
try {
|
|
1188
|
+
const chatbotId = requireChatbotId(this);
|
|
1178
1189
|
const globals = this.optsWithGlobals();
|
|
1179
1190
|
const c = await client3(globals);
|
|
1180
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1191
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/webhooks`, {
|
|
1181
1192
|
name: opts.name,
|
|
1182
1193
|
url: opts.url,
|
|
1183
1194
|
type: opts.type
|
|
@@ -1188,11 +1199,12 @@ function webhooksCommand() {
|
|
|
1188
1199
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1189
1200
|
}
|
|
1190
1201
|
});
|
|
1191
|
-
cmd.command("delete").requiredOption("--
|
|
1202
|
+
cmd.command("delete").requiredOption("--webhook <id>", "Webhook id").action(async function(opts) {
|
|
1192
1203
|
try {
|
|
1204
|
+
const chatbotId = requireChatbotId(this);
|
|
1193
1205
|
const globals = this.optsWithGlobals();
|
|
1194
1206
|
const c = await client3(globals);
|
|
1195
|
-
await c.delete(`/api/v1/chatbots/${
|
|
1207
|
+
await c.delete(`/api/v1/chatbots/${chatbotId}/webhooks/${opts.webhook}`);
|
|
1196
1208
|
emit({ ok: true, deleted: opts.webhook }, { json: !!globals.json });
|
|
1197
1209
|
} catch (err) {
|
|
1198
1210
|
fatal(err instanceof Error ? err.message : String(err));
|
|
@@ -1205,12 +1217,13 @@ function settingsCommand() {
|
|
|
1205
1217
|
"Manage chatbot settings + per-chatbot keys"
|
|
1206
1218
|
);
|
|
1207
1219
|
const keys = cmd.command("keys").description("Manage API keys for a chatbot");
|
|
1208
|
-
keys.command("rotate-ingest").
|
|
1220
|
+
keys.command("rotate-ingest").action(async function() {
|
|
1209
1221
|
try {
|
|
1222
|
+
const chatbotId = requireChatbotId(this);
|
|
1210
1223
|
const globals = this.optsWithGlobals();
|
|
1211
1224
|
const c = await client3(globals);
|
|
1212
1225
|
const result = await c.post(
|
|
1213
|
-
`/api/v1/chatbots/${
|
|
1226
|
+
`/api/v1/chatbots/${chatbotId}/keys/ingest/rotate`,
|
|
1214
1227
|
{}
|
|
1215
1228
|
);
|
|
1216
1229
|
surfacePlaintext(result.plaintext, "New ingest key (ob_live_*)");
|
|
@@ -1219,12 +1232,13 @@ function settingsCommand() {
|
|
|
1219
1232
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1220
1233
|
}
|
|
1221
1234
|
});
|
|
1222
|
-
keys.command("generate-read").
|
|
1235
|
+
keys.command("generate-read").action(async function() {
|
|
1223
1236
|
try {
|
|
1237
|
+
const chatbotId = requireChatbotId(this);
|
|
1224
1238
|
const globals = this.optsWithGlobals();
|
|
1225
1239
|
const c = await client3(globals);
|
|
1226
1240
|
const result = await c.post(
|
|
1227
|
-
`/api/v1/chatbots/${
|
|
1241
|
+
`/api/v1/chatbots/${chatbotId}/keys/read`,
|
|
1228
1242
|
{}
|
|
1229
1243
|
);
|
|
1230
1244
|
surfacePlaintext(result.plaintext, "New read key (ob_read_*)");
|
|
@@ -1233,11 +1247,12 @@ function settingsCommand() {
|
|
|
1233
1247
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1234
1248
|
}
|
|
1235
1249
|
});
|
|
1236
|
-
keys.command("generate-admin").requiredOption("--
|
|
1250
|
+
keys.command("generate-admin").requiredOption("--name <name>", "Human-friendly name (e.g. 'CI key')").option("--expires-in-days <n>", "Auto-expire after N days").action(async function(opts) {
|
|
1237
1251
|
try {
|
|
1252
|
+
const chatbotId = requireChatbotId(this);
|
|
1238
1253
|
const globals = this.optsWithGlobals();
|
|
1239
1254
|
const c = await client3(globals);
|
|
1240
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1255
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/admin-keys`, {
|
|
1241
1256
|
name: opts.name,
|
|
1242
1257
|
expiresInDays: opts.expiresInDays ? Number(opts.expiresInDays) : void 0
|
|
1243
1258
|
});
|
|
@@ -1247,30 +1262,33 @@ function settingsCommand() {
|
|
|
1247
1262
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1248
1263
|
}
|
|
1249
1264
|
});
|
|
1250
|
-
keys.command("list-admin").
|
|
1265
|
+
keys.command("list-admin").action(async function() {
|
|
1251
1266
|
try {
|
|
1267
|
+
const chatbotId = requireChatbotId(this);
|
|
1252
1268
|
const globals = this.optsWithGlobals();
|
|
1253
1269
|
const c = await client3(globals);
|
|
1254
1270
|
const result = await c.get(
|
|
1255
|
-
`/api/v1/chatbots/${
|
|
1271
|
+
`/api/v1/chatbots/${chatbotId}/admin-keys`
|
|
1256
1272
|
);
|
|
1257
1273
|
emit(result.keys, { json: !!globals.json });
|
|
1258
1274
|
} catch (err) {
|
|
1259
1275
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1260
1276
|
}
|
|
1261
1277
|
});
|
|
1262
|
-
keys.command("revoke-admin").requiredOption("--
|
|
1278
|
+
keys.command("revoke-admin").requiredOption("--key <keyId>", "Admin key id").action(async function(opts) {
|
|
1263
1279
|
try {
|
|
1280
|
+
const chatbotId = requireChatbotId(this);
|
|
1264
1281
|
const globals = this.optsWithGlobals();
|
|
1265
1282
|
const c = await client3(globals);
|
|
1266
|
-
await c.delete(`/api/v1/chatbots/${
|
|
1283
|
+
await c.delete(`/api/v1/chatbots/${chatbotId}/admin-keys/${opts.key}`);
|
|
1267
1284
|
emit({ ok: true, revoked: opts.key }, { json: !!globals.json });
|
|
1268
1285
|
} catch (err) {
|
|
1269
1286
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1270
1287
|
}
|
|
1271
1288
|
});
|
|
1272
|
-
cmd.command("update").description("Patch a chatbot's settings JSONB").
|
|
1289
|
+
cmd.command("update").description("Patch a chatbot's settings JSONB").option("--description <text>").option("--website-url <url>").option("--language <code>").action(async function(opts) {
|
|
1273
1290
|
try {
|
|
1291
|
+
const chatbotId = requireChatbotId(this);
|
|
1274
1292
|
const settings = {};
|
|
1275
1293
|
if (opts.description) settings.description = opts.description;
|
|
1276
1294
|
if (opts.websiteUrl) settings.website_url = opts.websiteUrl;
|
|
@@ -1280,7 +1298,7 @@ function settingsCommand() {
|
|
|
1280
1298
|
}
|
|
1281
1299
|
const globals = this.optsWithGlobals();
|
|
1282
1300
|
const c = await client3(globals);
|
|
1283
|
-
await c.patch(`/api/v1/chatbots/${
|
|
1301
|
+
await c.patch(`/api/v1/chatbots/${chatbotId}/settings`, { settings });
|
|
1284
1302
|
emit({ ok: true }, { json: !!globals.json });
|
|
1285
1303
|
} catch (err) {
|
|
1286
1304
|
fatal(err instanceof Error ? err.message : String(err));
|
|
@@ -1290,19 +1308,20 @@ function settingsCommand() {
|
|
|
1290
1308
|
}
|
|
1291
1309
|
function workflowsCommand() {
|
|
1292
1310
|
const cmd = new Command7("workflows").description("Manage workflows");
|
|
1293
|
-
cmd.command("list").
|
|
1311
|
+
cmd.command("list").action(async function() {
|
|
1294
1312
|
try {
|
|
1313
|
+
const chatbotId = requireChatbotId(this);
|
|
1295
1314
|
const globals = this.optsWithGlobals();
|
|
1296
1315
|
const c = await client3(globals);
|
|
1297
1316
|
const result = await c.get(
|
|
1298
|
-
`/api/v1/chatbots/${
|
|
1317
|
+
`/api/v1/chatbots/${chatbotId}/workflows`
|
|
1299
1318
|
);
|
|
1300
1319
|
emit(result.workflows, { json: !!globals.json });
|
|
1301
1320
|
} catch (err) {
|
|
1302
1321
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1303
1322
|
}
|
|
1304
1323
|
});
|
|
1305
|
-
cmd.command("create").description("Create a workflow from a built-in template").requiredOption("--
|
|
1324
|
+
cmd.command("create").description("Create a workflow from a built-in template").requiredOption("--name <name>").requiredOption(
|
|
1306
1325
|
"--template <name>",
|
|
1307
1326
|
"flag-to-webhook | outcome-to-webhook | sentiment-drop-to-webhook"
|
|
1308
1327
|
).requiredOption(
|
|
@@ -1310,9 +1329,10 @@ function workflowsCommand() {
|
|
|
1310
1329
|
"Flag value / outcome value / sentiment threshold"
|
|
1311
1330
|
).requiredOption("--webhook <id>", "Webhook id to fire").option("--message <tpl>", "Message template (supports {{user.id}}, etc.)").action(async function(opts) {
|
|
1312
1331
|
try {
|
|
1332
|
+
const chatbotId = requireChatbotId(this);
|
|
1313
1333
|
const globals = this.optsWithGlobals();
|
|
1314
1334
|
const c = await client3(globals);
|
|
1315
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1335
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/workflows`, {
|
|
1316
1336
|
name: opts.name,
|
|
1317
1337
|
template: opts.template,
|
|
1318
1338
|
triggerValue: opts.triggerValue,
|
|
@@ -1328,23 +1348,25 @@ function workflowsCommand() {
|
|
|
1328
1348
|
}
|
|
1329
1349
|
function reportsCommand() {
|
|
1330
1350
|
const cmd = new Command7("reports").description("Manage AI reports");
|
|
1331
|
-
cmd.command("list").
|
|
1351
|
+
cmd.command("list").action(async function() {
|
|
1332
1352
|
try {
|
|
1353
|
+
const chatbotId = requireChatbotId(this);
|
|
1333
1354
|
const globals = this.optsWithGlobals();
|
|
1334
1355
|
const c = await client3(globals);
|
|
1335
1356
|
const result = await c.get(
|
|
1336
|
-
`/api/v1/chatbots/${
|
|
1357
|
+
`/api/v1/chatbots/${chatbotId}/reports`
|
|
1337
1358
|
);
|
|
1338
1359
|
emit(result.reports, { json: !!globals.json });
|
|
1339
1360
|
} catch (err) {
|
|
1340
1361
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1341
1362
|
}
|
|
1342
1363
|
});
|
|
1343
|
-
cmd.command("create").description("Create a new AI report; returns the org-private dashboard URL").
|
|
1364
|
+
cmd.command("create").description("Create a new AI report; returns the org-private dashboard URL").option("--name <name>", "Report name", "Untitled Report").action(async function(opts) {
|
|
1344
1365
|
try {
|
|
1366
|
+
const chatbotId = requireChatbotId(this);
|
|
1345
1367
|
const globals = this.optsWithGlobals();
|
|
1346
1368
|
const c = await client3(globals);
|
|
1347
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1369
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/reports`, { name: opts.name });
|
|
1348
1370
|
process.stderr.write(
|
|
1349
1371
|
`
|
|
1350
1372
|
Created report. View it (org members only):
|
|
@@ -1364,30 +1386,32 @@ Created report. View it (org members only):
|
|
|
1364
1386
|
}
|
|
1365
1387
|
function analysisCommand() {
|
|
1366
1388
|
const cmd = new Command7("analysis").description("Manage analysis definitions");
|
|
1367
|
-
cmd.command("list").
|
|
1389
|
+
cmd.command("list").option("--type <t>", "intent | flag | assistant_outcome | assistant_issue").option("--pending", "Include pending suggestions").action(async function(opts) {
|
|
1368
1390
|
try {
|
|
1391
|
+
const chatbotId = requireChatbotId(this);
|
|
1369
1392
|
const globals = this.optsWithGlobals();
|
|
1370
1393
|
const c = await client3(globals);
|
|
1371
1394
|
const qs = new URLSearchParams();
|
|
1372
1395
|
if (opts.type) qs.set("type", opts.type);
|
|
1373
1396
|
if (opts.pending) qs.set("pending", "true");
|
|
1374
1397
|
const result = await c.get(
|
|
1375
|
-
`/api/v1/chatbots/${
|
|
1398
|
+
`/api/v1/chatbots/${chatbotId}/analysis-definitions${qs.size ? `?${qs}` : ""}`
|
|
1376
1399
|
);
|
|
1377
1400
|
emit(result.definitions, { json: !!globals.json });
|
|
1378
1401
|
} catch (err) {
|
|
1379
1402
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1380
1403
|
}
|
|
1381
1404
|
});
|
|
1382
|
-
cmd.command("add").requiredOption(
|
|
1405
|
+
cmd.command("add").requiredOption(
|
|
1383
1406
|
"--type <t>",
|
|
1384
1407
|
"intent | flag | assistant_outcome | assistant_issue"
|
|
1385
1408
|
).requiredOption("--name <slug>", "snake_case slug").requiredOption("--display-name <text>").requiredOption("--description <text>").action(async function(opts) {
|
|
1386
1409
|
try {
|
|
1410
|
+
const chatbotId = requireChatbotId(this);
|
|
1387
1411
|
const globals = this.optsWithGlobals();
|
|
1388
1412
|
const c = await client3(globals);
|
|
1389
1413
|
const result = await c.post(
|
|
1390
|
-
`/api/v1/chatbots/${
|
|
1414
|
+
`/api/v1/chatbots/${chatbotId}/analysis-definitions`,
|
|
1391
1415
|
{
|
|
1392
1416
|
analysisType: opts.type,
|
|
1393
1417
|
name: opts.name,
|
|
@@ -1406,8 +1430,9 @@ function usersCommand() {
|
|
|
1406
1430
|
const cmd = new Command7("users").description(
|
|
1407
1431
|
"List external users (chatbot customers) with health metrics"
|
|
1408
1432
|
);
|
|
1409
|
-
cmd.command("list").
|
|
1433
|
+
cmd.command("list").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) {
|
|
1410
1434
|
try {
|
|
1435
|
+
const chatbotId = requireChatbotId(this);
|
|
1411
1436
|
const globals = this.optsWithGlobals();
|
|
1412
1437
|
const c = await client3(globals);
|
|
1413
1438
|
const qs = new URLSearchParams();
|
|
@@ -1422,7 +1447,7 @@ function usersCommand() {
|
|
|
1422
1447
|
if (opts.search) qs.set("search", opts.search);
|
|
1423
1448
|
qs.set("limit", opts.limit);
|
|
1424
1449
|
const result = await c.get(
|
|
1425
|
-
`/api/v1/chatbots/${
|
|
1450
|
+
`/api/v1/chatbots/${chatbotId}/external-users?${qs}`
|
|
1426
1451
|
);
|
|
1427
1452
|
emit(result.users, { json: !!globals.json });
|
|
1428
1453
|
process.stderr.write(`
|
|
@@ -1497,18 +1522,22 @@ function sdkCommand() {
|
|
|
1497
1522
|
const out = opts.framework === "vercel-ai-sdk" ? snippetWrapper : snippetNext;
|
|
1498
1523
|
process.stdout.write(out);
|
|
1499
1524
|
});
|
|
1500
|
-
cmd.command("verify").description("Check whether any event has arrived for the chatbot yet").
|
|
1525
|
+
cmd.command("verify").description("Check whether any event has arrived for the chatbot yet").option("--timeout <n>", "Seconds to wait (default: 60)", "60").action(async function(opts) {
|
|
1501
1526
|
try {
|
|
1502
1527
|
const globals = this.optsWithGlobals();
|
|
1528
|
+
const chatbotId = globals.chatbot;
|
|
1529
|
+
if (!chatbotId) {
|
|
1530
|
+
fatal("--chatbot <id> is required (also accepts the persisted active chatbot).");
|
|
1531
|
+
}
|
|
1503
1532
|
const c = await client3(globals);
|
|
1504
1533
|
const timeoutSec = Number(opts.timeout);
|
|
1505
1534
|
const deadline = Date.now() + timeoutSec * 1e3;
|
|
1506
1535
|
const params = new URLSearchParams({
|
|
1507
|
-
chatbotId
|
|
1536
|
+
chatbotId,
|
|
1508
1537
|
limit: "1"
|
|
1509
1538
|
});
|
|
1510
1539
|
process.stderr.write(
|
|
1511
|
-
`Waiting for first event on chatbot ${
|
|
1540
|
+
`Waiting for first event on chatbot ${chatbotId} (timeout ${timeoutSec}s)\u2026
|
|
1512
1541
|
`
|
|
1513
1542
|
);
|
|
1514
1543
|
let lastTick = Date.now();
|
|
@@ -1544,7 +1573,7 @@ Timed out after ${timeoutSec}s \u2014 no events yet. Confirm OPENBAT_API_KEY and
|
|
|
1544
1573
|
var program = new Command8();
|
|
1545
1574
|
program.name("openbat").description(
|
|
1546
1575
|
"Query OpenBat chatbot data \u2014 conversations, sentiment, analytics, exports."
|
|
1547
|
-
).version("0.2.
|
|
1576
|
+
).version("0.2.3").option("--api-key <key>", "Override the stored Read API key (footgun \u2014 leaks into shell history)").option(
|
|
1548
1577
|
"--base-url <url>",
|
|
1549
1578
|
"Override the OpenBat API base URL (defaults to ~/.openbatrc or https://openbat.dev)"
|
|
1550
1579
|
).option(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openbat/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Command-line tool for querying OpenBat chatbot data — conversations, sentiment, analytics, exports",
|
|
5
5
|
"bin": {
|
|
6
6
|
"openbat": "bin/openbat"
|
|
@@ -37,7 +37,10 @@
|
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "tsup",
|
|
39
39
|
"dev": "tsup --watch",
|
|
40
|
-
"prepublishOnly": "npm run build"
|
|
40
|
+
"prepublishOnly": "npm run build",
|
|
41
|
+
"pretest": "npm run build",
|
|
42
|
+
"test": "node --test --experimental-strip-types --no-warnings 'tests/**/*.test.ts'",
|
|
43
|
+
"test:integration": "node --test --experimental-strip-types --no-warnings 'tests/integration/**/*.test.ts'"
|
|
41
44
|
},
|
|
42
45
|
"keywords": [
|
|
43
46
|
"openbat",
|