@openbat/cli 0.2.2 → 0.3.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 +47 -6
- package/dist/api-client.js +1 -1
- package/dist/api-client.mjs +1 -1
- package/dist/{chunk-MCDJLQI2.mjs → chunk-KIY62R3O.mjs} +1 -1
- package/dist/index.js +335 -60
- package/dist/index.mjs +335 -60
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
|
|
|
32
32
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
33
33
|
|
|
34
34
|
// src/index.ts
|
|
35
|
-
var
|
|
35
|
+
var import_commander10 = require("commander");
|
|
36
36
|
|
|
37
37
|
// src/commands/config.ts
|
|
38
38
|
var import_commander = require("commander");
|
|
@@ -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.3.0";
|
|
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>`);
|
|
@@ -433,12 +433,24 @@ function configCommand() {
|
|
|
433
433
|
cmd.command("show").description("Show the current resolved config (key prefix only)").action(async () => {
|
|
434
434
|
const cfg = await resolveConfig({});
|
|
435
435
|
const keyDisplay = cfg.apiKey ? `${cfg.apiKey.slice(0, 16)}\u2026<hidden>` : "(not set)";
|
|
436
|
+
let activeChatbot = cfg.activeChatbotId ?? "(not set)";
|
|
437
|
+
if (cfg.apiKey && cfg.activeChatbotId) {
|
|
438
|
+
try {
|
|
439
|
+
const api = new ApiClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
|
|
440
|
+
const list = await api.get("/api/v1/chatbots");
|
|
441
|
+
const hit = (list.chatbots ?? []).find(
|
|
442
|
+
(c) => c.id === cfg.activeChatbotId
|
|
443
|
+
);
|
|
444
|
+
if (hit) activeChatbot = `${hit.name} (${hit.id})`;
|
|
445
|
+
} catch {
|
|
446
|
+
}
|
|
447
|
+
}
|
|
436
448
|
emit({
|
|
437
449
|
apiKey: keyDisplay,
|
|
438
450
|
apiKeySource: cfg.apiKeySource,
|
|
439
451
|
baseUrl: cfg.baseUrl,
|
|
440
452
|
baseUrlSource: cfg.baseUrlSource,
|
|
441
|
-
|
|
453
|
+
activeChatbot,
|
|
442
454
|
activeChatbotIdSource: cfg.activeChatbotIdSource,
|
|
443
455
|
configFile: configPath()
|
|
444
456
|
});
|
|
@@ -493,9 +505,46 @@ async function resolveTargetChatbotId(target) {
|
|
|
493
505
|
}
|
|
494
506
|
return matches[0].id;
|
|
495
507
|
}
|
|
508
|
+
async function showCurrentAndOptions() {
|
|
509
|
+
const cfg = await resolveConfig({});
|
|
510
|
+
if (!cfg.apiKey) {
|
|
511
|
+
fatal("No API key configured. Run `openbat config set-key` first.");
|
|
512
|
+
}
|
|
513
|
+
const api = new ApiClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
|
|
514
|
+
const list = await api.get(
|
|
515
|
+
"/api/v1/chatbots"
|
|
516
|
+
);
|
|
517
|
+
const chatbots = list.chatbots ?? [];
|
|
518
|
+
if (cfg.activeChatbotId) {
|
|
519
|
+
const hit = chatbots.find((c) => c.id === cfg.activeChatbotId);
|
|
520
|
+
process.stdout.write(
|
|
521
|
+
hit ? `Active chatbot: ${hit.name} (${hit.id})
|
|
522
|
+
|
|
523
|
+
` : `Active chatbot: ${cfg.activeChatbotId} (not in reachable set)
|
|
524
|
+
|
|
525
|
+
`
|
|
526
|
+
);
|
|
527
|
+
} else {
|
|
528
|
+
process.stdout.write("No active chatbot set.\n\n");
|
|
529
|
+
}
|
|
530
|
+
if (chatbots.length === 0) {
|
|
531
|
+
process.stdout.write("No chatbots reachable by this key.\n");
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
process.stdout.write("Reachable chatbots \u2014 pin one with `openbat use <id>`:\n");
|
|
535
|
+
for (const c of chatbots) {
|
|
536
|
+
const marker = c.id === cfg.activeChatbotId ? "\u25CF" : "\u25CB";
|
|
537
|
+
process.stdout.write(` ${marker} ${c.name} ${c.id}
|
|
538
|
+
`);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
496
541
|
function useCommand() {
|
|
497
|
-
return new import_commander.Command("use").argument("
|
|
542
|
+
return new import_commander.Command("use").argument("[id-or-name]", "Chatbot UUID or exact name (omit to show current + options)").description("Set the active chatbot for this CLI (omit the arg to see current + options)").action(async (target) => {
|
|
498
543
|
try {
|
|
544
|
+
if (!target) {
|
|
545
|
+
await showCurrentAndOptions();
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
499
548
|
const id = await resolveTargetChatbotId(target);
|
|
500
549
|
await setActiveChatbotId(id);
|
|
501
550
|
process.stdout.write(`Active chatbot saved: ${id}
|
|
@@ -525,6 +574,10 @@ async function client(globals) {
|
|
|
525
574
|
};
|
|
526
575
|
}
|
|
527
576
|
var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
577
|
+
function announceScope(name, id) {
|
|
578
|
+
process.stderr.write(`\u2192 chatbot: ${name} (${id})
|
|
579
|
+
`);
|
|
580
|
+
}
|
|
528
581
|
async function resolveChatbotId(api, chatbotFlag) {
|
|
529
582
|
const list = await api.get(
|
|
530
583
|
"/api/v1/chatbots"
|
|
@@ -543,6 +596,7 @@ async function resolveChatbotId(api, chatbotFlag) {
|
|
|
543
596
|
`Chatbot ${chatbotFlag} is not reachable by this API key. Run \`openbat chatbot list\` to see what is.`
|
|
544
597
|
);
|
|
545
598
|
}
|
|
599
|
+
announceScope(hit.name, hit.id);
|
|
546
600
|
return hit.id;
|
|
547
601
|
}
|
|
548
602
|
const lower = chatbotFlag.toLowerCase();
|
|
@@ -557,9 +611,13 @@ async function resolveChatbotId(api, chatbotFlag) {
|
|
|
557
611
|
`Multiple chatbots named "${chatbotFlag}". Use the UUID instead \u2014 list them with \`openbat chatbot list\`.`
|
|
558
612
|
);
|
|
559
613
|
}
|
|
614
|
+
announceScope(matches[0].name, matches[0].id);
|
|
560
615
|
return matches[0].id;
|
|
561
616
|
}
|
|
562
|
-
if (chatbots.length === 1)
|
|
617
|
+
if (chatbots.length === 1) {
|
|
618
|
+
announceScope(chatbots[0].name, chatbots[0].id);
|
|
619
|
+
return chatbots[0].id;
|
|
620
|
+
}
|
|
563
621
|
const lines = chatbots.map((c) => ` \u2022 ${c.name} ${c.id}`).join("\n");
|
|
564
622
|
fatal(
|
|
565
623
|
`This API key targets multiple chatbots. Pick one with \`openbat use <id>\` (persistent) or \`--chatbot <id>\` (one-off):
|
|
@@ -687,9 +745,10 @@ function exportCommand() {
|
|
|
687
745
|
`/api/v1/export/${id}?format=${format}`
|
|
688
746
|
);
|
|
689
747
|
if (opts.out) {
|
|
690
|
-
const { createWriteStream } = await
|
|
691
|
-
|
|
692
|
-
|
|
748
|
+
const [{ createWriteStream }, { Writable, Readable }] = await Promise.all([
|
|
749
|
+
import("fs"),
|
|
750
|
+
import("stream")
|
|
751
|
+
]);
|
|
693
752
|
const file = createWriteStream(opts.out);
|
|
694
753
|
const nodeReadable = Readable.fromWeb(
|
|
695
754
|
body
|
|
@@ -724,6 +783,13 @@ function detectKind(apiKey) {
|
|
|
724
783
|
if (apiKey.startsWith("ob_pat_")) return "pat";
|
|
725
784
|
return "unknown";
|
|
726
785
|
}
|
|
786
|
+
function activeChatbotDisplay(activeId, chatbots) {
|
|
787
|
+
if (!activeId) {
|
|
788
|
+
return chatbots.length > 1 ? `(not pinned \u2014 ${chatbots.length} reachable; run \`openbat use <id>\`)` : "(not pinned)";
|
|
789
|
+
}
|
|
790
|
+
const hit = chatbots.find((c) => c.id === activeId);
|
|
791
|
+
return hit ? `${hit.name} (${hit.id})` : `${activeId} (not in reachable set)`;
|
|
792
|
+
}
|
|
727
793
|
function authCommand() {
|
|
728
794
|
const cmd = new import_commander3.Command("auth").description(
|
|
729
795
|
"Inspect the current credential's scope and audit history"
|
|
@@ -747,6 +813,10 @@ function authCommand() {
|
|
|
747
813
|
{
|
|
748
814
|
kind,
|
|
749
815
|
keyPrefix: `${cfg.apiKey.slice(0, 16)}\u2026<hidden>`,
|
|
816
|
+
activeChatbot: activeChatbotDisplay(
|
|
817
|
+
cfg.activeChatbotId,
|
|
818
|
+
chatbots.chatbots
|
|
819
|
+
),
|
|
750
820
|
orgs: orgs.orgs,
|
|
751
821
|
chatbots: chatbots.chatbots
|
|
752
822
|
},
|
|
@@ -760,6 +830,10 @@ function authCommand() {
|
|
|
760
830
|
{
|
|
761
831
|
kind,
|
|
762
832
|
keyPrefix: `${cfg.apiKey.slice(0, 16)}\u2026<hidden>`,
|
|
833
|
+
activeChatbot: activeChatbotDisplay(
|
|
834
|
+
cfg.activeChatbotId,
|
|
835
|
+
chatbots.chatbots
|
|
836
|
+
),
|
|
763
837
|
chatbots: chatbots.chatbots
|
|
764
838
|
},
|
|
765
839
|
{ json: !!globals.json }
|
|
@@ -772,8 +846,178 @@ function authCommand() {
|
|
|
772
846
|
return cmd;
|
|
773
847
|
}
|
|
774
848
|
|
|
775
|
-
// src/commands/
|
|
849
|
+
// src/commands/review.ts
|
|
776
850
|
var import_commander4 = require("commander");
|
|
851
|
+
function parseSinceToMinutes(s) {
|
|
852
|
+
const match = /^(\d+)\s*(m|h|d)?$/.exec(s.trim().toLowerCase());
|
|
853
|
+
if (!match) {
|
|
854
|
+
fatal(`Invalid --since "${s}". Use e.g. 45m, 6h, or 7d.`);
|
|
855
|
+
}
|
|
856
|
+
const n = Number(match[1]);
|
|
857
|
+
const unit = match[2] ?? "m";
|
|
858
|
+
const minutes = unit === "d" ? n * 1440 : unit === "h" ? n * 60 : n;
|
|
859
|
+
if (minutes < 1) fatal("--since must be at least 1 minute.");
|
|
860
|
+
if (minutes > 43200) fatal("--since cannot exceed 30 days (43200m / 720h / 30d).");
|
|
861
|
+
return minutes;
|
|
862
|
+
}
|
|
863
|
+
var arrow = (t) => t === "up" ? "\u25B2" : t === "down" ? "\u25BC" : "=";
|
|
864
|
+
var pctDelta = (d) => d === null ? "(new)" : `${arrow(d >= 0 ? "up" : "down")} ${d >= 0 ? "+" : ""}${d}%`;
|
|
865
|
+
var ptsDelta = (d) => `${arrow(d >= 0 ? "up" : "down")} ${d >= 0 ? "+" : ""}${d} pts`;
|
|
866
|
+
function renderReview(r) {
|
|
867
|
+
const L = [];
|
|
868
|
+
const h = r.headline;
|
|
869
|
+
L.push(`OpenBat review \xB7 last ${r.window.since} \xB7 vs prior ${r.window.since}`);
|
|
870
|
+
L.push("");
|
|
871
|
+
L.push(` Conversations ${h.conversations.value} ${pctDelta(h.conversations.delta_pct)}`);
|
|
872
|
+
L.push(` Messages ${h.messages.value}`);
|
|
873
|
+
L.push(` Resolved ${h.outcomes.resolved.pct}% ${ptsDelta(h.outcomes.resolved.delta_pts)}`);
|
|
874
|
+
L.push(` Partial ${h.outcomes.partially_resolved.pct}% ${ptsDelta(h.outcomes.partially_resolved.delta_pts)}`);
|
|
875
|
+
L.push(` Failed ${h.outcomes.failed.pct}% ${ptsDelta(h.outcomes.failed.delta_pts)}`);
|
|
876
|
+
const sent = h.avg_sentiment.value ?? "\u2014";
|
|
877
|
+
const sentDelta = h.avg_sentiment.delta === null ? "" : ` ${arrow(h.avg_sentiment.delta >= 0 ? "up" : "down")} ${h.avg_sentiment.delta >= 0 ? "+" : ""}${h.avg_sentiment.delta}`;
|
|
878
|
+
L.push(` Avg sentiment ${sent}${sentDelta}`);
|
|
879
|
+
L.push(` Flagged ${h.flagged}`);
|
|
880
|
+
if (r.clusters.issues.length) {
|
|
881
|
+
L.push("");
|
|
882
|
+
L.push("Top issues");
|
|
883
|
+
for (const i of r.clusters.issues) {
|
|
884
|
+
const ans = i.answer_available.true + i.answer_available.false;
|
|
885
|
+
const ansStr = ans > 0 ? ` answer_available ${i.answer_available.true}/${ans}` : "";
|
|
886
|
+
L.push(
|
|
887
|
+
` ${i.type} ${i.count} ${arrow(i.trend)} high ${i.severity.high} \xB7 med ${i.severity.medium} \xB7 low ${i.severity.low}${ansStr}`
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
if (r.clusters.flags.length) {
|
|
892
|
+
L.push("");
|
|
893
|
+
L.push(`Top flags ${r.clusters.flags.map((f) => `${f.value} ${f.count} ${arrow(f.trend)}`).join(" \xB7 ")}`);
|
|
894
|
+
}
|
|
895
|
+
if (r.clusters.intents.length) {
|
|
896
|
+
L.push(`Top intents ${r.clusters.intents.map((i) => `${i.value} ${i.count} ${arrow(i.trend)}`).join(" \xB7 ")}`);
|
|
897
|
+
}
|
|
898
|
+
const reps = [
|
|
899
|
+
...r.clusters.issues.flatMap((i) => i.representatives),
|
|
900
|
+
...r.clusters.failedOutcomes
|
|
901
|
+
];
|
|
902
|
+
if (reps.length) {
|
|
903
|
+
L.push("");
|
|
904
|
+
L.push("Representative failures");
|
|
905
|
+
for (const rep of reps.slice(0, 8)) {
|
|
906
|
+
const tag = rep.type ? `[${rep.type} \xB7 ${rep.severity ?? "?"} \xB7 answer_available=${rep.answer_available ?? "?"} \xB7 source=${rep.verification_source ?? "?"}]` : `[failed outcome]`;
|
|
907
|
+
L.push(` ${tag}`);
|
|
908
|
+
L.push(` conv ${rep.conversationId ?? "?"} msg ${rep.messageId}`);
|
|
909
|
+
if (rep.reasoning) L.push(` why: ${rep.reasoning}`);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
L.push("");
|
|
913
|
+
L.push("Drill in: openbat conversations show <id> \xB7 Fix: openbat-optimize skill");
|
|
914
|
+
return L.join("\n");
|
|
915
|
+
}
|
|
916
|
+
function reviewCommand() {
|
|
917
|
+
return new import_commander4.Command("review").description(
|
|
918
|
+
"Daily eval digest for the active chatbot \u2014 flags, issues, outcomes + reasonings"
|
|
919
|
+
).option(
|
|
920
|
+
"--since <duration>",
|
|
921
|
+
"Look-back window: 45m, 6h, 7d (max 30d)",
|
|
922
|
+
"24h"
|
|
923
|
+
).action(async function(opts) {
|
|
924
|
+
try {
|
|
925
|
+
const windowMinutes = parseSinceToMinutes(opts.since);
|
|
926
|
+
const globals = this.optsWithGlobals();
|
|
927
|
+
const { api, chatbotFlag } = await client(globals);
|
|
928
|
+
const id = await resolveChatbotId(api, chatbotFlag);
|
|
929
|
+
const params = new URLSearchParams({
|
|
930
|
+
windowMinutes: String(windowMinutes)
|
|
931
|
+
});
|
|
932
|
+
const result = await api.get(
|
|
933
|
+
`/api/v1/chatbots/${id}/review?${params}`
|
|
934
|
+
);
|
|
935
|
+
if (this.optsWithGlobals().json) {
|
|
936
|
+
emit(result, { json: true });
|
|
937
|
+
} else {
|
|
938
|
+
process.stdout.write(renderReview(result) + "\n");
|
|
939
|
+
}
|
|
940
|
+
} catch (err) {
|
|
941
|
+
fatal(err instanceof Error ? err.message : String(err));
|
|
942
|
+
}
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// src/commands/prompts.ts
|
|
947
|
+
var import_commander5 = require("commander");
|
|
948
|
+
var import_node_fs2 = require("fs");
|
|
949
|
+
function promptsCommand() {
|
|
950
|
+
const cmd = new import_commander5.Command("prompts").description(
|
|
951
|
+
"Manage the live published system prompt (list / publish / activate / kill-switch)"
|
|
952
|
+
);
|
|
953
|
+
cmd.command("list").description("List system-prompt versions + live controls (active version, kill switch)").action(async function() {
|
|
954
|
+
try {
|
|
955
|
+
const { api, chatbotFlag } = await client(this.optsWithGlobals());
|
|
956
|
+
const id = await resolveChatbotId(api, chatbotFlag);
|
|
957
|
+
const result = await api.get(
|
|
958
|
+
`/api/v1/chatbots/${id}/prompts`
|
|
959
|
+
);
|
|
960
|
+
emit(result, { json: !!this.optsWithGlobals().json });
|
|
961
|
+
} catch (err) {
|
|
962
|
+
fatal(err instanceof Error ? err.message : String(err));
|
|
963
|
+
}
|
|
964
|
+
});
|
|
965
|
+
cmd.command("publish").description("Publish a template as the LIVE prompt (from --file or --text)").option("--file <path>", "Read the template text from a file").option("--text <text>", "Inline template text (prefer --file for long prompts)").action(async function(opts) {
|
|
966
|
+
try {
|
|
967
|
+
let templateText = opts.text;
|
|
968
|
+
if (opts.file) templateText = await import_node_fs2.promises.readFile(opts.file, "utf8");
|
|
969
|
+
if (!templateText || !templateText.trim()) {
|
|
970
|
+
fatal("Provide the prompt text via --file <path> or --text <text>.");
|
|
971
|
+
}
|
|
972
|
+
const { api, chatbotFlag } = await client(this.optsWithGlobals());
|
|
973
|
+
const id = await resolveChatbotId(api, chatbotFlag);
|
|
974
|
+
const result = await api.post(
|
|
975
|
+
`/api/v1/chatbots/${id}/prompts`,
|
|
976
|
+
{ templateText }
|
|
977
|
+
);
|
|
978
|
+
emit(result, { json: !!this.optsWithGlobals().json });
|
|
979
|
+
process.stderr.write(
|
|
980
|
+
"\nPublished. Live within ~60s for chatbots that fetch their prompt from OpenBat.\n"
|
|
981
|
+
);
|
|
982
|
+
} catch (err) {
|
|
983
|
+
fatal(err instanceof Error ? err.message : String(err));
|
|
984
|
+
}
|
|
985
|
+
});
|
|
986
|
+
cmd.command("activate <versionId>").description("Point the live prompt at an existing version id (roll back/forward)").action(async function(versionId) {
|
|
987
|
+
try {
|
|
988
|
+
const { api, chatbotFlag } = await client(this.optsWithGlobals());
|
|
989
|
+
const id = await resolveChatbotId(api, chatbotFlag);
|
|
990
|
+
const result = await api.post(
|
|
991
|
+
`/api/v1/chatbots/${id}/prompts/activate`,
|
|
992
|
+
{ versionId }
|
|
993
|
+
);
|
|
994
|
+
emit(result, { json: !!this.optsWithGlobals().json });
|
|
995
|
+
} catch (err) {
|
|
996
|
+
fatal(err instanceof Error ? err.message : String(err));
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
cmd.command("kill-switch").description("Toggle the remote prompt kill switch (--on / --off)").option("--on", "Enable: SDK falls back to its hardcoded prompt").option("--off", "Disable: SDK serves the active published prompt again").action(async function(opts) {
|
|
1000
|
+
try {
|
|
1001
|
+
if (!!opts.on === !!opts.off) {
|
|
1002
|
+
fatal("Pass exactly one of --on or --off.");
|
|
1003
|
+
}
|
|
1004
|
+
const enabled = !!opts.on;
|
|
1005
|
+
const { api, chatbotFlag } = await client(this.optsWithGlobals());
|
|
1006
|
+
const id = await resolveChatbotId(api, chatbotFlag);
|
|
1007
|
+
const result = await api.post(
|
|
1008
|
+
`/api/v1/chatbots/${id}/prompts/kill-switch`,
|
|
1009
|
+
{ enabled }
|
|
1010
|
+
);
|
|
1011
|
+
emit(result, { json: !!this.optsWithGlobals().json });
|
|
1012
|
+
} catch (err) {
|
|
1013
|
+
fatal(err instanceof Error ? err.message : String(err));
|
|
1014
|
+
}
|
|
1015
|
+
});
|
|
1016
|
+
return cmd;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// src/commands/login.ts
|
|
1020
|
+
var import_commander6 = require("commander");
|
|
777
1021
|
var import_node_os2 = __toESM(require("os"));
|
|
778
1022
|
var import_node_readline = __toESM(require("readline"));
|
|
779
1023
|
|
|
@@ -916,7 +1160,7 @@ async function runLoopbackServer(opts) {
|
|
|
916
1160
|
// src/commands/login.ts
|
|
917
1161
|
var HOSTNAME = import_node_os2.default.hostname();
|
|
918
1162
|
function loginCommand() {
|
|
919
|
-
return new
|
|
1163
|
+
return new import_commander6.Command("login").description("Sign in via browser and install an API key on this device").option("--device", "Use the device-code flow (for SSH / headless machines)").option(
|
|
920
1164
|
"--use <key>",
|
|
921
1165
|
"Skip the browser; install a PAT plaintext you already have"
|
|
922
1166
|
).action(async function(opts) {
|
|
@@ -1106,9 +1350,9 @@ You have ${chatbots.length} chatbots. Pick one later with \`openbat use <id>\`.
|
|
|
1106
1350
|
}
|
|
1107
1351
|
|
|
1108
1352
|
// src/commands/logout.ts
|
|
1109
|
-
var
|
|
1353
|
+
var import_commander7 = require("commander");
|
|
1110
1354
|
function logoutCommand() {
|
|
1111
|
-
return new
|
|
1355
|
+
return new import_commander7.Command("logout").description("Revoke the stored API key and clear ~/.openbatrc").action(async function() {
|
|
1112
1356
|
try {
|
|
1113
1357
|
const globals = this.optsWithGlobals();
|
|
1114
1358
|
const cfg = await resolveConfig({
|
|
@@ -1143,7 +1387,7 @@ function logoutCommand() {
|
|
|
1143
1387
|
}
|
|
1144
1388
|
|
|
1145
1389
|
// src/commands/org.ts
|
|
1146
|
-
var
|
|
1390
|
+
var import_commander8 = require("commander");
|
|
1147
1391
|
async function client2(globals) {
|
|
1148
1392
|
const cfg = await resolveConfig({
|
|
1149
1393
|
apiKeyFlag: globals.apiKey ?? null,
|
|
@@ -1158,7 +1402,7 @@ async function client2(globals) {
|
|
|
1158
1402
|
return new ApiClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
|
|
1159
1403
|
}
|
|
1160
1404
|
function orgCommand() {
|
|
1161
|
-
const cmd = new
|
|
1405
|
+
const cmd = new import_commander8.Command("org").description(
|
|
1162
1406
|
"Manage the OpenBat tenant org (rename, members, invitations). Requires PAT."
|
|
1163
1407
|
);
|
|
1164
1408
|
cmd.command("list").description("List orgs the current PAT's user belongs to").action(async function() {
|
|
@@ -1266,7 +1510,7 @@ function orgCommand() {
|
|
|
1266
1510
|
}
|
|
1267
1511
|
|
|
1268
1512
|
// src/commands/write.ts
|
|
1269
|
-
var
|
|
1513
|
+
var import_commander9 = require("commander");
|
|
1270
1514
|
async function client3(globals) {
|
|
1271
1515
|
const cfg = await resolveConfig({
|
|
1272
1516
|
apiKeyFlag: globals.apiKey ?? null,
|
|
@@ -1277,6 +1521,15 @@ async function client3(globals) {
|
|
|
1277
1521
|
}
|
|
1278
1522
|
return new ApiClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
|
|
1279
1523
|
}
|
|
1524
|
+
function requireChatbotId(cmd) {
|
|
1525
|
+
const globals = cmd.optsWithGlobals();
|
|
1526
|
+
if (!globals.chatbot) {
|
|
1527
|
+
fatal(
|
|
1528
|
+
"--chatbot <id> is required. Pass it inline or set a default with `openbat use <id>`."
|
|
1529
|
+
);
|
|
1530
|
+
}
|
|
1531
|
+
return globals.chatbot;
|
|
1532
|
+
}
|
|
1280
1533
|
function surfacePlaintext(plaintext, label) {
|
|
1281
1534
|
process.stderr.write(
|
|
1282
1535
|
`
|
|
@@ -1290,7 +1543,7 @@ function surfacePlaintext(plaintext, label) {
|
|
|
1290
1543
|
);
|
|
1291
1544
|
}
|
|
1292
1545
|
function chatbotsCommand() {
|
|
1293
|
-
const cmd = new
|
|
1546
|
+
const cmd = new import_commander9.Command("chatbots").description(
|
|
1294
1547
|
"List, create, delete chatbots in the current scope"
|
|
1295
1548
|
);
|
|
1296
1549
|
cmd.command("list").description("List every chatbot the credential can reach").action(async function() {
|
|
@@ -1338,24 +1591,26 @@ function chatbotsCommand() {
|
|
|
1338
1591
|
return cmd;
|
|
1339
1592
|
}
|
|
1340
1593
|
function webhooksCommand() {
|
|
1341
|
-
const cmd = new
|
|
1342
|
-
cmd.command("list").
|
|
1594
|
+
const cmd = new import_commander9.Command("webhooks").description("Manage webhooks for a chatbot");
|
|
1595
|
+
cmd.command("list").action(async function() {
|
|
1343
1596
|
try {
|
|
1597
|
+
const chatbotId = requireChatbotId(this);
|
|
1344
1598
|
const globals = this.optsWithGlobals();
|
|
1345
1599
|
const c = await client3(globals);
|
|
1346
1600
|
const result = await c.get(
|
|
1347
|
-
`/api/v1/chatbots/${
|
|
1601
|
+
`/api/v1/chatbots/${chatbotId}/webhooks`
|
|
1348
1602
|
);
|
|
1349
1603
|
emit(result.webhooks, { json: !!globals.json });
|
|
1350
1604
|
} catch (err) {
|
|
1351
1605
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1352
1606
|
}
|
|
1353
1607
|
});
|
|
1354
|
-
cmd.command("create").requiredOption("--
|
|
1608
|
+
cmd.command("create").requiredOption("--name <name>").requiredOption("--url <url>").option("--type <type>", "discord | slack | custom", "custom").action(async function(opts) {
|
|
1355
1609
|
try {
|
|
1610
|
+
const chatbotId = requireChatbotId(this);
|
|
1356
1611
|
const globals = this.optsWithGlobals();
|
|
1357
1612
|
const c = await client3(globals);
|
|
1358
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1613
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/webhooks`, {
|
|
1359
1614
|
name: opts.name,
|
|
1360
1615
|
url: opts.url,
|
|
1361
1616
|
type: opts.type
|
|
@@ -1366,11 +1621,12 @@ function webhooksCommand() {
|
|
|
1366
1621
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1367
1622
|
}
|
|
1368
1623
|
});
|
|
1369
|
-
cmd.command("delete").requiredOption("--
|
|
1624
|
+
cmd.command("delete").requiredOption("--webhook <id>", "Webhook id").action(async function(opts) {
|
|
1370
1625
|
try {
|
|
1626
|
+
const chatbotId = requireChatbotId(this);
|
|
1371
1627
|
const globals = this.optsWithGlobals();
|
|
1372
1628
|
const c = await client3(globals);
|
|
1373
|
-
await c.delete(`/api/v1/chatbots/${
|
|
1629
|
+
await c.delete(`/api/v1/chatbots/${chatbotId}/webhooks/${opts.webhook}`);
|
|
1374
1630
|
emit({ ok: true, deleted: opts.webhook }, { json: !!globals.json });
|
|
1375
1631
|
} catch (err) {
|
|
1376
1632
|
fatal(err instanceof Error ? err.message : String(err));
|
|
@@ -1379,16 +1635,17 @@ function webhooksCommand() {
|
|
|
1379
1635
|
return cmd;
|
|
1380
1636
|
}
|
|
1381
1637
|
function settingsCommand() {
|
|
1382
|
-
const cmd = new
|
|
1638
|
+
const cmd = new import_commander9.Command("settings").description(
|
|
1383
1639
|
"Manage chatbot settings + per-chatbot keys"
|
|
1384
1640
|
);
|
|
1385
1641
|
const keys = cmd.command("keys").description("Manage API keys for a chatbot");
|
|
1386
|
-
keys.command("rotate-ingest").
|
|
1642
|
+
keys.command("rotate-ingest").action(async function() {
|
|
1387
1643
|
try {
|
|
1644
|
+
const chatbotId = requireChatbotId(this);
|
|
1388
1645
|
const globals = this.optsWithGlobals();
|
|
1389
1646
|
const c = await client3(globals);
|
|
1390
1647
|
const result = await c.post(
|
|
1391
|
-
`/api/v1/chatbots/${
|
|
1648
|
+
`/api/v1/chatbots/${chatbotId}/keys/ingest/rotate`,
|
|
1392
1649
|
{}
|
|
1393
1650
|
);
|
|
1394
1651
|
surfacePlaintext(result.plaintext, "New ingest key (ob_live_*)");
|
|
@@ -1397,12 +1654,13 @@ function settingsCommand() {
|
|
|
1397
1654
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1398
1655
|
}
|
|
1399
1656
|
});
|
|
1400
|
-
keys.command("generate-read").
|
|
1657
|
+
keys.command("generate-read").action(async function() {
|
|
1401
1658
|
try {
|
|
1659
|
+
const chatbotId = requireChatbotId(this);
|
|
1402
1660
|
const globals = this.optsWithGlobals();
|
|
1403
1661
|
const c = await client3(globals);
|
|
1404
1662
|
const result = await c.post(
|
|
1405
|
-
`/api/v1/chatbots/${
|
|
1663
|
+
`/api/v1/chatbots/${chatbotId}/keys/read`,
|
|
1406
1664
|
{}
|
|
1407
1665
|
);
|
|
1408
1666
|
surfacePlaintext(result.plaintext, "New read key (ob_read_*)");
|
|
@@ -1411,11 +1669,12 @@ function settingsCommand() {
|
|
|
1411
1669
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1412
1670
|
}
|
|
1413
1671
|
});
|
|
1414
|
-
keys.command("generate-admin").requiredOption("--
|
|
1672
|
+
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
1673
|
try {
|
|
1674
|
+
const chatbotId = requireChatbotId(this);
|
|
1416
1675
|
const globals = this.optsWithGlobals();
|
|
1417
1676
|
const c = await client3(globals);
|
|
1418
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1677
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/admin-keys`, {
|
|
1419
1678
|
name: opts.name,
|
|
1420
1679
|
expiresInDays: opts.expiresInDays ? Number(opts.expiresInDays) : void 0
|
|
1421
1680
|
});
|
|
@@ -1425,30 +1684,33 @@ function settingsCommand() {
|
|
|
1425
1684
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1426
1685
|
}
|
|
1427
1686
|
});
|
|
1428
|
-
keys.command("list-admin").
|
|
1687
|
+
keys.command("list-admin").action(async function() {
|
|
1429
1688
|
try {
|
|
1689
|
+
const chatbotId = requireChatbotId(this);
|
|
1430
1690
|
const globals = this.optsWithGlobals();
|
|
1431
1691
|
const c = await client3(globals);
|
|
1432
1692
|
const result = await c.get(
|
|
1433
|
-
`/api/v1/chatbots/${
|
|
1693
|
+
`/api/v1/chatbots/${chatbotId}/admin-keys`
|
|
1434
1694
|
);
|
|
1435
1695
|
emit(result.keys, { json: !!globals.json });
|
|
1436
1696
|
} catch (err) {
|
|
1437
1697
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1438
1698
|
}
|
|
1439
1699
|
});
|
|
1440
|
-
keys.command("revoke-admin").requiredOption("--
|
|
1700
|
+
keys.command("revoke-admin").requiredOption("--key <keyId>", "Admin key id").action(async function(opts) {
|
|
1441
1701
|
try {
|
|
1702
|
+
const chatbotId = requireChatbotId(this);
|
|
1442
1703
|
const globals = this.optsWithGlobals();
|
|
1443
1704
|
const c = await client3(globals);
|
|
1444
|
-
await c.delete(`/api/v1/chatbots/${
|
|
1705
|
+
await c.delete(`/api/v1/chatbots/${chatbotId}/admin-keys/${opts.key}`);
|
|
1445
1706
|
emit({ ok: true, revoked: opts.key }, { json: !!globals.json });
|
|
1446
1707
|
} catch (err) {
|
|
1447
1708
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1448
1709
|
}
|
|
1449
1710
|
});
|
|
1450
|
-
cmd.command("update").description("Patch a chatbot's settings JSONB").
|
|
1711
|
+
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
1712
|
try {
|
|
1713
|
+
const chatbotId = requireChatbotId(this);
|
|
1452
1714
|
const settings = {};
|
|
1453
1715
|
if (opts.description) settings.description = opts.description;
|
|
1454
1716
|
if (opts.websiteUrl) settings.website_url = opts.websiteUrl;
|
|
@@ -1458,7 +1720,7 @@ function settingsCommand() {
|
|
|
1458
1720
|
}
|
|
1459
1721
|
const globals = this.optsWithGlobals();
|
|
1460
1722
|
const c = await client3(globals);
|
|
1461
|
-
await c.patch(`/api/v1/chatbots/${
|
|
1723
|
+
await c.patch(`/api/v1/chatbots/${chatbotId}/settings`, { settings });
|
|
1462
1724
|
emit({ ok: true }, { json: !!globals.json });
|
|
1463
1725
|
} catch (err) {
|
|
1464
1726
|
fatal(err instanceof Error ? err.message : String(err));
|
|
@@ -1467,20 +1729,21 @@ function settingsCommand() {
|
|
|
1467
1729
|
return cmd;
|
|
1468
1730
|
}
|
|
1469
1731
|
function workflowsCommand() {
|
|
1470
|
-
const cmd = new
|
|
1471
|
-
cmd.command("list").
|
|
1732
|
+
const cmd = new import_commander9.Command("workflows").description("Manage workflows");
|
|
1733
|
+
cmd.command("list").action(async function() {
|
|
1472
1734
|
try {
|
|
1735
|
+
const chatbotId = requireChatbotId(this);
|
|
1473
1736
|
const globals = this.optsWithGlobals();
|
|
1474
1737
|
const c = await client3(globals);
|
|
1475
1738
|
const result = await c.get(
|
|
1476
|
-
`/api/v1/chatbots/${
|
|
1739
|
+
`/api/v1/chatbots/${chatbotId}/workflows`
|
|
1477
1740
|
);
|
|
1478
1741
|
emit(result.workflows, { json: !!globals.json });
|
|
1479
1742
|
} catch (err) {
|
|
1480
1743
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1481
1744
|
}
|
|
1482
1745
|
});
|
|
1483
|
-
cmd.command("create").description("Create a workflow from a built-in template").requiredOption("--
|
|
1746
|
+
cmd.command("create").description("Create a workflow from a built-in template").requiredOption("--name <name>").requiredOption(
|
|
1484
1747
|
"--template <name>",
|
|
1485
1748
|
"flag-to-webhook | outcome-to-webhook | sentiment-drop-to-webhook"
|
|
1486
1749
|
).requiredOption(
|
|
@@ -1488,9 +1751,10 @@ function workflowsCommand() {
|
|
|
1488
1751
|
"Flag value / outcome value / sentiment threshold"
|
|
1489
1752
|
).requiredOption("--webhook <id>", "Webhook id to fire").option("--message <tpl>", "Message template (supports {{user.id}}, etc.)").action(async function(opts) {
|
|
1490
1753
|
try {
|
|
1754
|
+
const chatbotId = requireChatbotId(this);
|
|
1491
1755
|
const globals = this.optsWithGlobals();
|
|
1492
1756
|
const c = await client3(globals);
|
|
1493
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1757
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/workflows`, {
|
|
1494
1758
|
name: opts.name,
|
|
1495
1759
|
template: opts.template,
|
|
1496
1760
|
triggerValue: opts.triggerValue,
|
|
@@ -1505,24 +1769,26 @@ function workflowsCommand() {
|
|
|
1505
1769
|
return cmd;
|
|
1506
1770
|
}
|
|
1507
1771
|
function reportsCommand() {
|
|
1508
|
-
const cmd = new
|
|
1509
|
-
cmd.command("list").
|
|
1772
|
+
const cmd = new import_commander9.Command("reports").description("Manage AI reports");
|
|
1773
|
+
cmd.command("list").action(async function() {
|
|
1510
1774
|
try {
|
|
1775
|
+
const chatbotId = requireChatbotId(this);
|
|
1511
1776
|
const globals = this.optsWithGlobals();
|
|
1512
1777
|
const c = await client3(globals);
|
|
1513
1778
|
const result = await c.get(
|
|
1514
|
-
`/api/v1/chatbots/${
|
|
1779
|
+
`/api/v1/chatbots/${chatbotId}/reports`
|
|
1515
1780
|
);
|
|
1516
1781
|
emit(result.reports, { json: !!globals.json });
|
|
1517
1782
|
} catch (err) {
|
|
1518
1783
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1519
1784
|
}
|
|
1520
1785
|
});
|
|
1521
|
-
cmd.command("create").description("Create a new AI report; returns the org-private dashboard URL").
|
|
1786
|
+
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
1787
|
try {
|
|
1788
|
+
const chatbotId = requireChatbotId(this);
|
|
1523
1789
|
const globals = this.optsWithGlobals();
|
|
1524
1790
|
const c = await client3(globals);
|
|
1525
|
-
const result = await c.post(`/api/v1/chatbots/${
|
|
1791
|
+
const result = await c.post(`/api/v1/chatbots/${chatbotId}/reports`, { name: opts.name });
|
|
1526
1792
|
process.stderr.write(
|
|
1527
1793
|
`
|
|
1528
1794
|
Created report. View it (org members only):
|
|
@@ -1541,31 +1807,33 @@ Created report. View it (org members only):
|
|
|
1541
1807
|
return cmd;
|
|
1542
1808
|
}
|
|
1543
1809
|
function analysisCommand() {
|
|
1544
|
-
const cmd = new
|
|
1545
|
-
cmd.command("list").
|
|
1810
|
+
const cmd = new import_commander9.Command("analysis").description("Manage analysis definitions");
|
|
1811
|
+
cmd.command("list").option("--type <t>", "intent | flag | assistant_outcome | assistant_issue").option("--pending", "Include pending suggestions").action(async function(opts) {
|
|
1546
1812
|
try {
|
|
1813
|
+
const chatbotId = requireChatbotId(this);
|
|
1547
1814
|
const globals = this.optsWithGlobals();
|
|
1548
1815
|
const c = await client3(globals);
|
|
1549
1816
|
const qs = new URLSearchParams();
|
|
1550
1817
|
if (opts.type) qs.set("type", opts.type);
|
|
1551
1818
|
if (opts.pending) qs.set("pending", "true");
|
|
1552
1819
|
const result = await c.get(
|
|
1553
|
-
`/api/v1/chatbots/${
|
|
1820
|
+
`/api/v1/chatbots/${chatbotId}/analysis-definitions${qs.size ? `?${qs}` : ""}`
|
|
1554
1821
|
);
|
|
1555
1822
|
emit(result.definitions, { json: !!globals.json });
|
|
1556
1823
|
} catch (err) {
|
|
1557
1824
|
fatal(err instanceof Error ? err.message : String(err));
|
|
1558
1825
|
}
|
|
1559
1826
|
});
|
|
1560
|
-
cmd.command("add").requiredOption(
|
|
1827
|
+
cmd.command("add").requiredOption(
|
|
1561
1828
|
"--type <t>",
|
|
1562
1829
|
"intent | flag | assistant_outcome | assistant_issue"
|
|
1563
1830
|
).requiredOption("--name <slug>", "snake_case slug").requiredOption("--display-name <text>").requiredOption("--description <text>").action(async function(opts) {
|
|
1564
1831
|
try {
|
|
1832
|
+
const chatbotId = requireChatbotId(this);
|
|
1565
1833
|
const globals = this.optsWithGlobals();
|
|
1566
1834
|
const c = await client3(globals);
|
|
1567
1835
|
const result = await c.post(
|
|
1568
|
-
`/api/v1/chatbots/${
|
|
1836
|
+
`/api/v1/chatbots/${chatbotId}/analysis-definitions`,
|
|
1569
1837
|
{
|
|
1570
1838
|
analysisType: opts.type,
|
|
1571
1839
|
name: opts.name,
|
|
@@ -1581,11 +1849,12 @@ function analysisCommand() {
|
|
|
1581
1849
|
return cmd;
|
|
1582
1850
|
}
|
|
1583
1851
|
function usersCommand() {
|
|
1584
|
-
const cmd = new
|
|
1852
|
+
const cmd = new import_commander9.Command("users").description(
|
|
1585
1853
|
"List external users (chatbot customers) with health metrics"
|
|
1586
1854
|
);
|
|
1587
|
-
cmd.command("list").
|
|
1855
|
+
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
1856
|
try {
|
|
1857
|
+
const chatbotId = requireChatbotId(this);
|
|
1589
1858
|
const globals = this.optsWithGlobals();
|
|
1590
1859
|
const c = await client3(globals);
|
|
1591
1860
|
const qs = new URLSearchParams();
|
|
@@ -1600,7 +1869,7 @@ function usersCommand() {
|
|
|
1600
1869
|
if (opts.search) qs.set("search", opts.search);
|
|
1601
1870
|
qs.set("limit", opts.limit);
|
|
1602
1871
|
const result = await c.get(
|
|
1603
|
-
`/api/v1/chatbots/${
|
|
1872
|
+
`/api/v1/chatbots/${chatbotId}/external-users?${qs}`
|
|
1604
1873
|
);
|
|
1605
1874
|
emit(result.users, { json: !!globals.json });
|
|
1606
1875
|
process.stderr.write(`
|
|
@@ -1613,7 +1882,7 @@ Total: ${result.total}
|
|
|
1613
1882
|
return cmd;
|
|
1614
1883
|
}
|
|
1615
1884
|
function sdkCommand() {
|
|
1616
|
-
const cmd = new
|
|
1885
|
+
const cmd = new import_commander9.Command("sdk").description(
|
|
1617
1886
|
"Help install and verify the OpenBat SDK in a target project"
|
|
1618
1887
|
);
|
|
1619
1888
|
cmd.command("install-instructions").description("Print markdown the calling agent can follow").option(
|
|
@@ -1675,18 +1944,22 @@ function sdkCommand() {
|
|
|
1675
1944
|
const out = opts.framework === "vercel-ai-sdk" ? snippetWrapper : snippetNext;
|
|
1676
1945
|
process.stdout.write(out);
|
|
1677
1946
|
});
|
|
1678
|
-
cmd.command("verify").description("Check whether any event has arrived for the chatbot yet").
|
|
1947
|
+
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
1948
|
try {
|
|
1680
1949
|
const globals = this.optsWithGlobals();
|
|
1950
|
+
const chatbotId = globals.chatbot;
|
|
1951
|
+
if (!chatbotId) {
|
|
1952
|
+
fatal("--chatbot <id> is required (also accepts the persisted active chatbot).");
|
|
1953
|
+
}
|
|
1681
1954
|
const c = await client3(globals);
|
|
1682
1955
|
const timeoutSec = Number(opts.timeout);
|
|
1683
1956
|
const deadline = Date.now() + timeoutSec * 1e3;
|
|
1684
1957
|
const params = new URLSearchParams({
|
|
1685
|
-
chatbotId
|
|
1958
|
+
chatbotId,
|
|
1686
1959
|
limit: "1"
|
|
1687
1960
|
});
|
|
1688
1961
|
process.stderr.write(
|
|
1689
|
-
`Waiting for first event on chatbot ${
|
|
1962
|
+
`Waiting for first event on chatbot ${chatbotId} (timeout ${timeoutSec}s)\u2026
|
|
1690
1963
|
`
|
|
1691
1964
|
);
|
|
1692
1965
|
let lastTick = Date.now();
|
|
@@ -1719,10 +1992,10 @@ Timed out after ${timeoutSec}s \u2014 no events yet. Confirm OPENBAT_API_KEY and
|
|
|
1719
1992
|
}
|
|
1720
1993
|
|
|
1721
1994
|
// src/index.ts
|
|
1722
|
-
var program = new
|
|
1995
|
+
var program = new import_commander10.Command();
|
|
1723
1996
|
program.name("openbat").description(
|
|
1724
1997
|
"Query OpenBat chatbot data \u2014 conversations, sentiment, analytics, exports."
|
|
1725
|
-
).version("0.
|
|
1998
|
+
).version("0.3.0").option("--api-key <key>", "Override the stored Read API key (footgun \u2014 leaks into shell history)").option(
|
|
1726
1999
|
"--base-url <url>",
|
|
1727
2000
|
"Override the OpenBat API base URL (defaults to ~/.openbatrc or https://openbat.dev)"
|
|
1728
2001
|
).option(
|
|
@@ -1741,6 +2014,8 @@ program.addCommand(orgCommand());
|
|
|
1741
2014
|
program.addCommand(chatbotCommand());
|
|
1742
2015
|
program.addCommand(chatbotsCommand());
|
|
1743
2016
|
program.addCommand(conversationsCommand());
|
|
2017
|
+
program.addCommand(reviewCommand());
|
|
2018
|
+
program.addCommand(promptsCommand());
|
|
1744
2019
|
program.addCommand(usersCommand());
|
|
1745
2020
|
program.addCommand(settingsCommand());
|
|
1746
2021
|
program.addCommand(webhooksCommand());
|