starkbot-cli 0.1.3 → 0.2.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.
Files changed (2) hide show
  1. package/dist/index.js +171 -42
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -836,28 +836,25 @@ async function connectCommand(opts = {}) {
836
836
  }
837
837
  } catch (err) {
838
838
  spin.fail("Connection failed");
839
- if (err.message?.includes("No CLI gateway token found")) {
840
- printWarning("This instance was provisioned before CLI support \u2014 no gateway token on file.");
841
- console.log(dim(" You can grab your token and domain from the instance dashboard.\n"));
842
- const answers = await inquirer2.prompt([
843
- {
844
- type: "input",
845
- name: "token",
846
- message: "Gateway token:",
847
- validate: (v) => v.trim().length > 0 || "Token is required"
848
- },
849
- {
850
- type: "input",
851
- name: "domain",
852
- message: "Instance domain (e.g. my-bot.starkbot.cloud):",
853
- default: creds.instance_domain || void 0,
854
- validate: (v) => v.trim().length > 0 || "Domain is required"
855
- }
856
- ]);
857
- return connectCommand({ token: answers.token.trim(), domain: answers.domain.trim() });
858
- } else {
859
- printError(err.message);
860
- }
839
+ printWarning("Could not auto-fetch gateway credentials \u2014 you can enter them manually.");
840
+ console.log(dim(` (${err.message})
841
+ `));
842
+ const answers = await inquirer2.prompt([
843
+ {
844
+ type: "input",
845
+ name: "token",
846
+ message: "Gateway token:",
847
+ validate: (v) => v.trim().length > 0 || "Token is required"
848
+ },
849
+ {
850
+ type: "input",
851
+ name: "domain",
852
+ message: "Instance domain (e.g. my-bot.starkbot.cloud):",
853
+ default: creds.instance_domain || void 0,
854
+ validate: (v) => v.trim().length > 0 || "Domain is required"
855
+ }
856
+ ]);
857
+ return connectCommand({ token: answers.token.trim(), domain: answers.domain.trim() });
861
858
  }
862
859
  }
863
860
  var init_connect = __esm({
@@ -870,6 +867,152 @@ var init_connect = __esm({
870
867
  }
871
868
  });
872
869
 
870
+ // src/lib/status.ts
871
+ import ora2 from "ora";
872
+ import chalk2 from "chalk";
873
+ var subtypeColor, toolColor, subagentColor, dimText, StatusTracker;
874
+ var init_status2 = __esm({
875
+ "src/lib/status.ts"() {
876
+ "use strict";
877
+ subtypeColor = chalk2.hex("#7C3AED").bold;
878
+ toolColor = chalk2.yellow;
879
+ subagentColor = chalk2.cyan;
880
+ dimText = chalk2.dim;
881
+ StatusTracker = class {
882
+ spinner;
883
+ activeSubtype = "";
884
+ activeTools = [];
885
+ activeSubagents = /* @__PURE__ */ new Map();
886
+ // label -> subtype
887
+ paused = false;
888
+ constructor() {
889
+ this.spinner = ora2({ color: "magenta", spinner: "dots" });
890
+ }
891
+ handleEvent(event) {
892
+ switch (event.type) {
893
+ case "tool_call":
894
+ this.addTool(event.tool_name ?? "unknown");
895
+ break;
896
+ case "tool_result":
897
+ this.removeTool(event.tool_name ?? "unknown");
898
+ break;
899
+ case "subagent_spawned":
900
+ this.addSubagent(event.label ?? "?", event.agent_subtype);
901
+ break;
902
+ case "subagent_completed":
903
+ case "subagent_failed":
904
+ this.removeSubagent(event.label ?? "?");
905
+ break;
906
+ case "subtype_change":
907
+ this.setSubtype(event.agent_subtype ?? event.label ?? "");
908
+ break;
909
+ case "thinking":
910
+ this.setThinking(event.content);
911
+ break;
912
+ case "task_started":
913
+ if (event.task_name) this.setTask(event.task_name);
914
+ break;
915
+ case "task_completed":
916
+ this.updateSpinner();
917
+ break;
918
+ case "text":
919
+ this.pauseForText();
920
+ if (event.content) process.stdout.write(event.content);
921
+ this.resumeAfterText();
922
+ break;
923
+ case "done":
924
+ this.finish();
925
+ break;
926
+ }
927
+ }
928
+ prefix() {
929
+ if (this.activeSubtype) {
930
+ return `${subtypeColor(`[${this.activeSubtype}]`)} `;
931
+ }
932
+ return "";
933
+ }
934
+ addTool(name) {
935
+ if (!this.activeTools.includes(name)) {
936
+ this.activeTools.push(name);
937
+ }
938
+ this.updateSpinner();
939
+ }
940
+ removeTool(name) {
941
+ this.activeTools = this.activeTools.filter((t) => t !== name);
942
+ this.updateSpinner();
943
+ }
944
+ addSubagent(label, subtype) {
945
+ this.activeSubagents.set(label, subtype ?? "");
946
+ this.updateSpinner();
947
+ }
948
+ removeSubagent(label) {
949
+ this.activeSubagents.delete(label);
950
+ this.updateSpinner();
951
+ }
952
+ setSubtype(subtype) {
953
+ this.activeSubtype = subtype;
954
+ this.updateSpinner();
955
+ }
956
+ setThinking(message) {
957
+ const text = `${this.prefix()}${dimText(message || "thinking...")}`;
958
+ this.ensureSpinning(text);
959
+ }
960
+ setTask(taskName) {
961
+ const text = `${this.prefix()}${dimText(taskName)}`;
962
+ this.ensureSpinning(text);
963
+ }
964
+ updateSpinner() {
965
+ const parts = [];
966
+ for (const [label, subtype] of this.activeSubagents) {
967
+ const st = subtype ? ` (${subtype})` : "";
968
+ parts.push(subagentColor(`subagent "${label}"${st} running`));
969
+ }
970
+ if (this.activeTools.length > 0) {
971
+ const names = this.activeTools.map((t) => toolColor(t)).join(", ");
972
+ parts.push(`calling ${names}`);
973
+ }
974
+ if (parts.length === 0) {
975
+ if (this.spinner.isSpinning && !this.paused) {
976
+ this.spinner.stop();
977
+ }
978
+ return;
979
+ }
980
+ const text = `${this.prefix()}${parts.join(" | ")}`;
981
+ this.ensureSpinning(text);
982
+ }
983
+ ensureSpinning(text) {
984
+ if (this.paused) return;
985
+ if (this.spinner.isSpinning) {
986
+ this.spinner.text = text;
987
+ } else {
988
+ this.spinner.start(text);
989
+ }
990
+ }
991
+ pauseForText() {
992
+ if (this.spinner.isSpinning) {
993
+ this.spinner.stop();
994
+ }
995
+ this.paused = true;
996
+ }
997
+ resumeAfterText() {
998
+ this.paused = false;
999
+ if (this.activeTools.length > 0 || this.activeSubagents.size > 0) {
1000
+ this.updateSpinner();
1001
+ }
1002
+ }
1003
+ finish() {
1004
+ if (this.spinner.isSpinning) {
1005
+ this.spinner.stop();
1006
+ }
1007
+ this.activeTools = [];
1008
+ this.activeSubagents.clear();
1009
+ this.activeSubtype = "";
1010
+ this.paused = false;
1011
+ }
1012
+ };
1013
+ }
1014
+ });
1015
+
873
1016
  // src/commands/chat.ts
874
1017
  var chat_exports = {};
875
1018
  __export(chat_exports, {
@@ -889,31 +1032,15 @@ function requireGateway() {
889
1032
  creds.gateway_token
890
1033
  );
891
1034
  }
892
- function printSseEvent(event) {
893
- switch (event.type) {
894
- case "tool_call": {
895
- const name = event.tool_name ?? "unknown";
896
- process.stdout.write(dim(`[${name}...] `));
897
- break;
898
- }
899
- case "tool_result":
900
- break;
901
- case "text":
902
- if (event.content) {
903
- process.stdout.write(event.content);
904
- }
905
- break;
906
- case "done":
907
- break;
908
- }
909
- }
910
1035
  async function chatOneShotCommand(message) {
911
1036
  const gw = requireGateway();
1037
+ const status = new StatusTracker();
912
1038
  process.stdout.write(`${prefix.agent} `);
913
1039
  try {
914
- await gw.chatStream(message, printSseEvent);
1040
+ await gw.chatStream(message, (event) => status.handleEvent(event));
915
1041
  console.log();
916
1042
  } catch (err) {
1043
+ status.finish();
917
1044
  console.log();
918
1045
  printError(err.message);
919
1046
  process.exit(1);
@@ -1014,7 +1141,8 @@ async function chatReplCommand() {
1014
1141
  }
1015
1142
  process.stdout.write(`${prefix.agent} `);
1016
1143
  try {
1017
- await gw.chatStream(trimmed, printSseEvent);
1144
+ const status = new StatusTracker();
1145
+ await gw.chatStream(trimmed, (event) => status.handleEvent(event));
1018
1146
  console.log();
1019
1147
  } catch (err) {
1020
1148
  console.log();
@@ -1034,6 +1162,7 @@ var init_chat = __esm({
1034
1162
  "use strict";
1035
1163
  init_credentials();
1036
1164
  init_gateway_client();
1165
+ init_status2();
1037
1166
  init_ui();
1038
1167
  }
1039
1168
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starkbot-cli",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "CLI for Starkbot — login, provision, and chat with your bot from the terminal",
5
5
  "type": "module",
6
6
  "bin": {