clawborrator-cli 0.0.28 → 0.0.30

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-bundled/claw.cjs +112 -45
  2. package/package.json +2 -1
@@ -67595,6 +67595,65 @@ function ts() {
67595
67595
  }
67596
67596
  var markdownEnabled = true;
67597
67597
  var debugMode = false;
67598
+ var statusEnabled = true;
67599
+ var working = false;
67600
+ var rlRef = null;
67601
+ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
67602
+ var spinnerFrame = 0;
67603
+ var spinnerTimer = null;
67604
+ var PROMPT_BASE = `${DIM2}>${RESET2} `;
67605
+ function buildPrompt() {
67606
+ if (!working) return PROMPT_BASE;
67607
+ return `${AMBER}${SPINNER_FRAMES[spinnerFrame]}${RESET2} ${PROMPT_BASE}`;
67608
+ }
67609
+ function refreshPrompt() {
67610
+ if (!rlRef) return;
67611
+ rlRef.setPrompt(buildPrompt());
67612
+ const r = rlRef;
67613
+ if (typeof r._refreshLine === "function") r._refreshLine();
67614
+ else rlRef.prompt(true);
67615
+ }
67616
+ function startWorking() {
67617
+ if (working) return;
67618
+ working = true;
67619
+ if (!statusEnabled || !process.stdout.isTTY) {
67620
+ refreshPrompt();
67621
+ return;
67622
+ }
67623
+ if (spinnerTimer) return;
67624
+ spinnerTimer = setInterval(() => {
67625
+ spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES.length;
67626
+ refreshPrompt();
67627
+ }, 80);
67628
+ refreshPrompt();
67629
+ }
67630
+ function stopWorking() {
67631
+ if (!working) return;
67632
+ working = false;
67633
+ if (spinnerTimer) {
67634
+ clearInterval(spinnerTimer);
67635
+ spinnerTimer = null;
67636
+ }
67637
+ refreshPrompt();
67638
+ }
67639
+ function say(line) {
67640
+ if (!process.stdout.isTTY || !rlRef) {
67641
+ console.log(line);
67642
+ return;
67643
+ }
67644
+ process.stdout.write("\r\x1B[K");
67645
+ console.log(line);
67646
+ refreshPrompt();
67647
+ }
67648
+ function sayErr(line) {
67649
+ if (!process.stdout.isTTY || !rlRef) {
67650
+ console.error(line);
67651
+ return;
67652
+ }
67653
+ process.stdout.write("\r\x1B[K");
67654
+ console.error(line);
67655
+ refreshPrompt();
67656
+ }
67598
67657
  var md = new Marked();
67599
67658
  md.use(markedTerminal({
67600
67659
  width: process.stdout.columns ?? 100,
@@ -67613,17 +67672,18 @@ function renderMarkdown(text) {
67613
67672
  }
67614
67673
  function emitChatLine(prefix, body) {
67615
67674
  if (!body.includes("\n")) {
67616
- console.log(`${prefix} ${body}`);
67675
+ say(`${prefix} ${body}`);
67617
67676
  return;
67618
67677
  }
67619
- console.log(prefix);
67678
+ say(prefix);
67620
67679
  for (const line of body.split("\n")) {
67621
- console.log(` ${line}`);
67680
+ say(` ${line}`);
67622
67681
  }
67623
67682
  }
67624
- var sessionAttach = new Command("attach").description("open a TUI on a session \u2014 see the chat stream, post op-messages").argument("<ref>", "session UUID or @routingName (e.g. @driver)").option("--limit <n>", 'history items to load before the live stream begins. 0 = none. "all" = up to 5000. default 50.', "50").option("--no-op-messages", "exclude op-messages from the history backlog (live ones still arrive once attached)").option("--no-markdown", "render assistant_text and reply payloads as raw text instead of formatted markdown").option("--debug", "after every rendered event, print its full JSON payload (truncated at 2 KB) \u2014 surfaces fields the renderer normally hides (e.g., SubagentStop's last_assistant_message, PreToolUse tool_input details)").action(async (ref, opts) => {
67683
+ var sessionAttach = new Command("attach").description("open a TUI on a session \u2014 see the chat stream, post op-messages").argument("<ref>", "session UUID or @routingName (e.g. @driver)").option("--limit <n>", 'history items to load before the live stream begins. 0 = none. "all" = up to 5000. default 50.', "50").option("--no-op-messages", "exclude op-messages from the history backlog (live ones still arrive once attached)").option("--no-markdown", "render assistant_text and reply payloads as raw text instead of formatted markdown").option("--debug", "after every rendered event, print its full JSON payload (truncated at 2 KB) \u2014 surfaces fields the renderer normally hides (e.g., SubagentStop's last_assistant_message, PreToolUse tool_input details)").option("--no-status", 'disable the animated "claude working" dot at the bottom of the TUI (useful for piped output or rough-ANSI terminals)').action(async (ref, opts) => {
67625
67684
  if (opts.markdown === false) markdownEnabled = false;
67626
67685
  if (opts.debug) debugMode = true;
67686
+ if (opts.status === false) statusEnabled = false;
67627
67687
  const cfg = loadConfig();
67628
67688
  if (!cfg.pat) {
67629
67689
  console.error("error: not logged in. run `claw login`.");
@@ -67706,7 +67766,7 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67706
67766
  let mySubscription = false;
67707
67767
  const pendingPerms = [];
67708
67768
  ws.on("open", () => {
67709
- console.log(`${DIM2}[${ts()}]${RESET2} connected to ${cfg.hubUrl}`);
67769
+ say(`${DIM2}[${ts()}]${RESET2} connected to ${cfg.hubUrl}`);
67710
67770
  const sub = { type: "subscribe", sessionId };
67711
67771
  ws.send(JSON.stringify(sub));
67712
67772
  });
@@ -67726,22 +67786,30 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67726
67786
  printInbound(msg, myLogin);
67727
67787
  if (msg.type === "subscribed") {
67728
67788
  mySubscription = true;
67729
- console.log(`${DIM2}attached as ${BOLD2}${msg.role}${RESET2}${DIM2}. type for prompt \xB7 @other <text> to route \xB7 /m <text> for op-msg \xB7 /y /n on permissions \xB7 /q to quit${RESET2}`);
67789
+ say(`${DIM2}attached as ${BOLD2}${msg.role}${RESET2}${DIM2}. type for prompt \xB7 @other <text> to route \xB7 /m <text> for op-msg \xB7 /y /n on permissions \xB7 /q to quit${RESET2}`);
67730
67790
  }
67731
67791
  });
67732
67792
  ws.on("close", (code, reason) => {
67733
- console.log(`${DIM2}[${ts()}] disconnected (${code}${reason ? ": " + reason.toString() : ""})${RESET2}`);
67793
+ stopWorking();
67794
+ say(`${DIM2}[${ts()}] disconnected (${code}${reason ? ": " + reason.toString() : ""})${RESET2}`);
67734
67795
  process.exit(0);
67735
67796
  });
67736
67797
  ws.on("error", (err) => {
67737
- console.error(`${RED}ws error: ${err.message}${RESET2}`);
67798
+ sayErr(`${RED}ws error: ${err.message}${RESET2}`);
67799
+ });
67800
+ const rl = (0, import_node_readline2.createInterface)({
67801
+ input: process.stdin,
67802
+ output: process.stdout,
67803
+ terminal: process.stdout.isTTY ? true : false,
67804
+ prompt: PROMPT_BASE
67738
67805
  });
67739
- const rl = (0, import_node_readline2.createInterface)({ input: process.stdin, terminal: false });
67806
+ rlRef = rl;
67807
+ if (process.stdout.isTTY) rl.prompt(true);
67740
67808
  rl.on("line", (raw) => {
67741
67809
  const text = raw.trim();
67742
67810
  if (!text) return;
67743
67811
  if (!mySubscription) {
67744
- console.log(`${DIM2}(not subscribed yet \u2014 waiting...)${RESET2}`);
67812
+ say(`${DIM2}(not subscribed yet \u2014 waiting...)${RESET2}`);
67745
67813
  return;
67746
67814
  }
67747
67815
  if (text === "/q" || text === "/quit") {
@@ -67751,7 +67819,7 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67751
67819
  if (text === "/y" || text === "/yes" || text === "/n" || text === "/no") {
67752
67820
  const pending = pendingPerms[pendingPerms.length - 1];
67753
67821
  if (!pending) {
67754
- console.log(`${DIM2}(no pending permission to act on)${RESET2}`);
67822
+ say(`${DIM2}(no pending permission to act on)${RESET2}`);
67755
67823
  return;
67756
67824
  }
67757
67825
  const decision = text === "/y" || text === "/yes" ? "allow" : "deny";
@@ -67768,7 +67836,7 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67768
67836
  if (text === "/m" || text.startsWith("/m ")) {
67769
67837
  const opText = text.slice(2).trim();
67770
67838
  if (!opText) {
67771
- console.log(`${DIM2}usage: /m <text> (sends as op-message; bare text is a prompt)${RESET2}`);
67839
+ say(`${DIM2}usage: /m <text> (sends as op-message; bare text is a prompt)${RESET2}`);
67772
67840
  return;
67773
67841
  }
67774
67842
  const out2 = { type: "op_message", sessionId, text: opText };
@@ -67778,16 +67846,16 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67778
67846
  if (text === "/p" || text.startsWith("/p ")) {
67779
67847
  const promptText = text.slice(2).trim();
67780
67848
  if (!promptText) {
67781
- console.log(`${DIM2}usage: /p <text> (or just type \u2014 bare text is a prompt now)${RESET2}`);
67849
+ say(`${DIM2}usage: /p <text> (or just type \u2014 bare text is a prompt now)${RESET2}`);
67782
67850
  return;
67783
67851
  }
67784
67852
  const out2 = { type: "prompt", sessionId, text: promptText };
67785
67853
  ws.send(JSON.stringify(out2));
67786
- console.log(`${DIM2}[${ts()}]${RESET2} ${AMBER}\u2192 prompt sent${RESET2} ${promptText}`);
67854
+ say(`${DIM2}[${ts()}]${RESET2} ${AMBER}\u2192 prompt sent${RESET2} ${promptText}`);
67787
67855
  return;
67788
67856
  }
67789
67857
  if (text.startsWith("/")) {
67790
- console.log(`${DIM2}unknown slash-command: ${text} (try /m /y /n /q)${RESET2}`);
67858
+ say(`${DIM2}unknown slash-command: ${text} (try /m /y /n /q)${RESET2}`);
67791
67859
  return;
67792
67860
  }
67793
67861
  const xMatch = /^(@[A-Za-z0-9._\-/]+)\s+([\s\S]+)$/.exec(text);
@@ -67795,7 +67863,7 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67795
67863
  const targetRef = xMatch[1];
67796
67864
  const promptText = xMatch[2].trim();
67797
67865
  if (!promptText) {
67798
- console.log(`${DIM2}usage: ${targetRef} <prompt>${RESET2}`);
67866
+ say(`${DIM2}usage: ${targetRef} <prompt>${RESET2}`);
67799
67867
  return;
67800
67868
  }
67801
67869
  (async () => {
@@ -67819,16 +67887,16 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67819
67887
  if (mine.length > 0) candidates = mine;
67820
67888
  }
67821
67889
  if (candidates.length === 0) {
67822
- console.error(`${RED}error: no session ${targetRef} (try \`claw session list\` in another terminal)${RESET2}`);
67890
+ sayErr(`${RED}error: no session ${targetRef} (try \`claw session list\` in another terminal)${RESET2}`);
67823
67891
  return;
67824
67892
  }
67825
67893
  const liveMatches = candidates.filter((c) => c.connected);
67826
67894
  if (liveMatches.length > 1) {
67827
67895
  const usedQualified = targetRef.includes("/");
67828
67896
  const advice = usedQualified ? `'${targetRef}' is ambiguous even within owner \u2014 re-issue using a session UUID:` : `'${targetRef}' is ambiguous \u2014 use the qualified form @owner/slug, or a UUID if the qualified form still collides:`;
67829
- console.error(`${RED}error: ${advice}${RESET2}`);
67897
+ sayErr(`${RED}error: ${advice}${RESET2}`);
67830
67898
  for (const c of liveMatches) {
67831
- console.error(` ${c.id} @${c.startedByLogin}/${(c.routingName ?? "").replace(/^@/, "")} ${DIM2}${c.cwd ?? ""}${RESET2}`);
67899
+ sayErr(` ${c.id} @${c.startedByLogin}/${(c.routingName ?? "").replace(/^@/, "")} ${DIM2}${c.cwd ?? ""}${RESET2}`);
67832
67900
  }
67833
67901
  return;
67834
67902
  }
@@ -67837,23 +67905,19 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67837
67905
  type: "prompt",
67838
67906
  sessionId: match.id,
67839
67907
  text: promptText,
67840
- // Source-session tag so the hub can persist the eventual
67841
- // reply against THIS session's events history and surface
67842
- // it to source Claude via channel notification (the same
67843
- // shape route_to_peer's reply path uses).
67844
67908
  sourceSessionId: sessionId
67845
67909
  };
67846
67910
  ws.send(JSON.stringify(out2));
67847
- console.log(`${DIM2}[${ts()}]${RESET2} ${AMBER}\u2192 prompt \u2192 ${targetRef}${RESET2} ${promptText}`);
67911
+ say(`${DIM2}[${ts()}]${RESET2} ${AMBER}\u2192 prompt \u2192 ${targetRef}${RESET2} ${promptText}`);
67848
67912
  } catch (e) {
67849
- console.error(`${RED}error: ${e?.message ?? String(e)}${RESET2}`);
67913
+ sayErr(`${RED}error: ${e?.message ?? String(e)}${RESET2}`);
67850
67914
  }
67851
67915
  })();
67852
67916
  return;
67853
67917
  }
67854
67918
  const out = { type: "prompt", sessionId, text };
67855
67919
  ws.send(JSON.stringify(out));
67856
- console.log(`${DIM2}[${ts()}]${RESET2} ${AMBER}\u2192 prompt${RESET2} ${text}`);
67920
+ say(`${DIM2}[${ts()}]${RESET2} ${AMBER}\u2192 prompt${RESET2} ${text}`);
67857
67921
  });
67858
67922
  process.on("SIGINT", () => {
67859
67923
  ws.close(1e3, "sigint");
@@ -67868,26 +67932,26 @@ function printInbound(msg, myLogin) {
67868
67932
  break;
67869
67933
  }
67870
67934
  case "op_message": {
67871
- console.log(`${DIM2}[${shortTs(msg.ts)}]${RESET2} ${GREEN}@${msg.authorLogin}${RESET2} ${msg.text}`);
67935
+ say(`${DIM2}[${shortTs(msg.ts)}]${RESET2} ${GREEN}@${msg.authorLogin}${RESET2} ${msg.text}`);
67872
67936
  break;
67873
67937
  }
67874
67938
  case "permission_request": {
67875
- console.log(`${RED}[!] ${shortTs(msg.ts)}${RESET2} approval needed: ${BOLD2}${msg.tool}${RESET2} \u2014 ${msg.inputPreview}`);
67939
+ say(`${RED}[!] ${shortTs(msg.ts)}${RESET2} approval needed: ${BOLD2}${msg.tool}${RESET2} \u2014 ${msg.inputPreview}`);
67876
67940
  break;
67877
67941
  }
67878
67942
  case "permission_resolved": {
67879
67943
  const dec = msg.decision === "allow" ? `${GREEN}allowed${RESET2}` : msg.decision === "deny" ? `${RED}denied${RESET2}` : `${DIM2}expired${RESET2}`;
67880
- console.log(`${DIM2}[${ts()}]${RESET2} permission ${msg.requestId} ${dec} by @${msg.resolverLogin ?? "?"}`);
67944
+ say(`${DIM2}[${ts()}]${RESET2} permission ${msg.requestId} ${dec} by @${msg.resolverLogin ?? "?"}`);
67881
67945
  break;
67882
67946
  }
67883
67947
  case "presence": {
67884
- console.log(`${DIM2}[${ts()}] presence: ${msg.attached.map((l) => "@" + l).join(", ") || "(empty)"}${RESET2}`);
67948
+ say(`${DIM2}[${ts()}] presence: ${msg.attached.map((l) => "@" + l).join(", ") || "(empty)"}${RESET2}`);
67885
67949
  break;
67886
67950
  }
67887
67951
  case "ack":
67888
67952
  break;
67889
67953
  case "error":
67890
- console.error(`${RED}error (${msg.code}): ${msg.message}${RESET2}`);
67954
+ sayErr(`${RED}error (${msg.code}): ${msg.message}${RESET2}`);
67891
67955
  break;
67892
67956
  }
67893
67957
  }
@@ -67913,7 +67977,7 @@ function maybeDebugDump(p) {
67913
67977
  const TRUNC = 2e3;
67914
67978
  if (json.length > TRUNC) json = json.slice(0, TRUNC) + "\n... [truncated, payload was " + json.length + " bytes]";
67915
67979
  for (const line of json.split("\n")) {
67916
- console.log(` ${DIM2}${line}${RESET2}`);
67980
+ say(` ${DIM2}${line}${RESET2}`);
67917
67981
  }
67918
67982
  }
67919
67983
  function renderEvent(ev, myLogin) {
@@ -67930,12 +67994,15 @@ function renderEvent(ev, myLogin) {
67930
67994
  }
67931
67995
  }
67932
67996
  function renderEventBody(ev, ts2, p, myLogin) {
67997
+ if (ev.kind === "chat" && ev.type === "prompt") startWorking();
67998
+ else if (ev.kind === "tail" && ev.type === "PreToolUse") startWorking();
67999
+ else if (ev.kind === "tail" && ev.type === "Stop") stopWorking();
67933
68000
  if (ev.kind === "chat") {
67934
68001
  if (ev.type === "prompt") {
67935
68002
  const text = String(p.text ?? p.prompt ?? "").trim() || JSON.stringify(p).slice(0, 200);
67936
68003
  const source = String(p.source ?? "cli");
67937
68004
  const label = source === "operator" ? `${BOLD2}@${String(p.authorLogin ?? "remote")} \u203A${RESET2}` : `${BOLD2}(cli) \u203A${RESET2}`;
67938
- console.log(`${DIM2}[${ts2}]${RESET2} ${label} ${text}`);
68005
+ say(`${DIM2}[${ts2}]${RESET2} ${label} ${text}`);
67939
68006
  return;
67940
68007
  }
67941
68008
  if (ev.type === "assistant_text") {
@@ -67944,7 +68011,7 @@ function renderEventBody(ev, ts2, p, myLogin) {
67944
68011
  const tag2 = isPlaceholder ? `${DIM2}claude \xB7 thinking${RESET2}` : `${AMBER}claude${RESET2}`;
67945
68012
  const prefix = `${DIM2}[${ts2}]${RESET2} ${tag2}`;
67946
68013
  if (isPlaceholder) {
67947
- console.log(`${prefix} ${DIM2}${text}${RESET2}`);
68014
+ say(`${prefix} ${DIM2}${text}${RESET2}`);
67948
68015
  return;
67949
68016
  }
67950
68017
  emitChatLine(prefix, renderMarkdown(text));
@@ -67956,37 +68023,37 @@ function renderEventBody(ev, ts2, p, myLogin) {
67956
68023
  emitChatLine(`${DIM2}[${ts2}]${RESET2} ${tag2}`, renderMarkdown(text));
67957
68024
  return;
67958
68025
  }
67959
- console.log(`${DIM2}[${ts2}]${RESET2} ${AMBER}[chat:${ev.type}]${RESET2} ${previewPayload(p)}`);
68026
+ say(`${DIM2}[${ts2}]${RESET2} ${AMBER}[chat:${ev.type}]${RESET2} ${previewPayload(p)}`);
67960
68027
  return;
67961
68028
  }
67962
68029
  switch (ev.type) {
67963
68030
  case "PreToolUse": {
67964
68031
  const tool = String(p.tool_name ?? p.toolName ?? p.tool ?? "?");
67965
68032
  const input = renderToolInput(p);
67966
- console.log(`${DIM2}[${ts2}]${RESET2} ${BLUE}\u2192 ${tool}${RESET2} ${DIM2}${input}${RESET2}`);
68033
+ say(`${DIM2}[${ts2}]${RESET2} ${BLUE}\u2192 ${tool}${RESET2} ${DIM2}${input}${RESET2}`);
67967
68034
  return;
67968
68035
  }
67969
68036
  case "PostToolUse": {
67970
68037
  const tool = String(p.tool_name ?? p.toolName ?? p.tool ?? "?");
67971
68038
  const out = stringifyToolResponse(p.tool_response ?? p.toolResponse ?? p.outputPreview ?? p.output);
67972
68039
  const ok = p.ok === false ? `${RED}\u2717${RESET2}` : `${BLUE}\u2713${RESET2}`;
67973
- console.log(`${DIM2}[${ts2}]${RESET2} ${ok} ${tool}${out ? " " + DIM2 + truncate(out, 200) + RESET2 : ""}`);
68040
+ say(`${DIM2}[${ts2}]${RESET2} ${ok} ${tool}${out ? " " + DIM2 + truncate(out, 200) + RESET2 : ""}`);
67974
68041
  return;
67975
68042
  }
67976
68043
  case "PostToolUseFailure": {
67977
68044
  const tool = String(p.tool_name ?? p.toolName ?? p.tool ?? "?");
67978
68045
  const err = stringifyToolResponse(p.error ?? p.message ?? p.tool_response);
67979
- console.log(`${DIM2}[${ts2}]${RESET2} ${RED}\u2717 ${tool}${RESET2} ${RED}${truncate(err, 200)}${RESET2}`);
68046
+ say(`${DIM2}[${ts2}]${RESET2} ${RED}\u2717 ${tool}${RESET2} ${RED}${truncate(err, 200)}${RESET2}`);
67980
68047
  return;
67981
68048
  }
67982
68049
  case "Stop":
67983
- console.log(`${DIM2}[${ts2}] \u2014 turn end \u2014${RESET2}`);
68050
+ say(`${DIM2}[${ts2}] \u2014 turn end \u2014${RESET2}`);
67984
68051
  return;
67985
68052
  case "SessionStart":
67986
- console.log(`${DIM2}[${ts2}] \u25B8 session start${RESET2}`);
68053
+ say(`${DIM2}[${ts2}] \u25B8 session start${RESET2}`);
67987
68054
  return;
67988
68055
  case "SessionEnd":
67989
- console.log(`${DIM2}[${ts2}] \u25C2 session end${RESET2}`);
68056
+ say(`${DIM2}[${ts2}] \u25C2 session end${RESET2}`);
67990
68057
  return;
67991
68058
  case "TaskCreated":
67992
68059
  case "SubagentStart":
@@ -67994,16 +68061,16 @@ function renderEventBody(ev, ts2, p, myLogin) {
67994
68061
  case "TaskCompleted": {
67995
68062
  const which = ev.type;
67996
68063
  const desc = String(p.description ?? p.agentType ?? "");
67997
- console.log(`${DIM2}[${ts2}] ${BLUE}\u21AA ${which}${RESET2}${desc ? " " + desc : ""}`);
68064
+ say(`${DIM2}[${ts2}] ${BLUE}\u21AA ${which}${RESET2}${desc ? " " + desc : ""}`);
67998
68065
  return;
67999
68066
  }
68000
68067
  case "Notification": {
68001
68068
  const msg = String(p.message ?? p.text ?? "").trim();
68002
- console.log(`${DIM2}[${ts2}]${RESET2} ${BOLD2}\u{1F514}${RESET2} ${msg || JSON.stringify(p).slice(0, 200)}`);
68069
+ say(`${DIM2}[${ts2}]${RESET2} ${BOLD2}\u{1F514}${RESET2} ${msg || JSON.stringify(p).slice(0, 200)}`);
68003
68070
  return;
68004
68071
  }
68005
68072
  default:
68006
- console.log(`${DIM2}[${ts2}]${RESET2} ${BLUE}[${ev.type}]${RESET2} ${previewPayload(p)}`);
68073
+ say(`${DIM2}[${ts2}]${RESET2} ${BLUE}[${ev.type}]${RESET2} ${previewPayload(p)}`);
68007
68074
  }
68008
68075
  }
68009
68076
  function stringifyToolResponse(v) {
@@ -68517,7 +68584,7 @@ var webhookCmd = new Command("webhook").description("manage webhook subscription
68517
68584
 
68518
68585
  // src/index.ts
68519
68586
  var program2 = new Command();
68520
- program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.0.28");
68587
+ program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.0.30");
68521
68588
  program2.addCommand(loginCmd);
68522
68589
  program2.addCommand(logoutCmd);
68523
68590
  program2.addCommand(whoamiCmd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawborrator-cli",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
4
4
  "type": "module",
5
5
  "description": "claw — command-line client for clawborrator hub_v1. Manages PATs, channel tokens, sessions, cross-session routing, and webhooks; ships an inline TUI for live multi-operator session attach.",
6
6
  "license": "MIT",
@@ -50,6 +50,7 @@
50
50
  "esbuild": "^0.24.2",
51
51
  "marked": "^14.1.3",
52
52
  "marked-terminal": "^7.2.1",
53
+ "ora": "^8.1.1",
53
54
  "tsx": "^4.19.1",
54
55
  "typescript": "^5.6.2",
55
56
  "ws": "^8.18.0"