clawborrator-cli 0.0.32 → 0.0.34

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.
@@ -67760,43 +67760,73 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67760
67760
  }
67761
67761
  }
67762
67762
  const wsUrl = cfg.hubUrl.replace(/^http/i, "ws") + "/cli";
67763
- const ws = new wrapper_default(wsUrl, {
67764
- headers: { Authorization: `Bearer ${cfg.pat}` }
67765
- });
67766
67763
  let mySubscription = false;
67767
67764
  const pendingPerms = [];
67768
- ws.on("open", () => {
67769
- say(`${DIM2}[${ts()}]${RESET2} connected to ${cfg.hubUrl}`);
67770
- const sub = { type: "subscribe", sessionId };
67771
- ws.send(JSON.stringify(sub));
67772
- });
67773
- ws.on("message", (data) => {
67774
- let msg;
67775
- try {
67776
- msg = JSON.parse(data.toString("utf8"));
67777
- } catch {
67778
- return;
67779
- }
67780
- if (msg.type === "permission_request") {
67781
- pendingPerms.push({ requestId: msg.requestId, tool: msg.tool, sessionId: msg.sessionId });
67782
- } else if (msg.type === "permission_resolved") {
67783
- const i = pendingPerms.findIndex((p) => p.requestId === msg.requestId);
67784
- if (i >= 0) pendingPerms.splice(i, 1);
67785
- }
67786
- printInbound(msg, myLogin);
67787
- if (msg.type === "subscribed") {
67788
- mySubscription = true;
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}`);
67790
- }
67791
- });
67792
- ws.on("close", (code, reason) => {
67793
- stopWorking();
67794
- say(`${DIM2}[${ts()}] disconnected (${code}${reason ? ": " + reason.toString() : ""})${RESET2}`);
67795
- process.exit(0);
67796
- });
67797
- ws.on("error", (err) => {
67798
- sayErr(`${RED}ws error: ${err.message}${RESET2}`);
67799
- });
67765
+ const BACKOFF = [1e3, 2e3, 5e3, 15e3, 3e4, 6e4];
67766
+ let ws;
67767
+ let stopRequested = false;
67768
+ let reconnectAttempt = 0;
67769
+ let reconnectTimer = null;
67770
+ function connect() {
67771
+ ws = new wrapper_default(wsUrl, { headers: { Authorization: `Bearer ${cfg.pat}` } });
67772
+ ws.on("open", () => {
67773
+ if (reconnectAttempt > 0) {
67774
+ say(`${DIM2}[${ts()}]${RESET2} ${AMBER}reconnected${RESET2} to ${cfg.hubUrl}`);
67775
+ } else {
67776
+ say(`${DIM2}[${ts()}]${RESET2} connected to ${cfg.hubUrl}`);
67777
+ }
67778
+ reconnectAttempt = 0;
67779
+ mySubscription = false;
67780
+ const sub = { type: "subscribe", sessionId };
67781
+ ws.send(JSON.stringify(sub));
67782
+ });
67783
+ ws.on("message", (data) => {
67784
+ let msg;
67785
+ try {
67786
+ msg = JSON.parse(data.toString("utf8"));
67787
+ } catch {
67788
+ return;
67789
+ }
67790
+ if (msg.type === "permission_request") {
67791
+ pendingPerms.push({ requestId: msg.requestId, tool: msg.tool, sessionId: msg.sessionId });
67792
+ } else if (msg.type === "permission_resolved") {
67793
+ const i = pendingPerms.findIndex((p) => p.requestId === msg.requestId);
67794
+ if (i >= 0) pendingPerms.splice(i, 1);
67795
+ }
67796
+ printInbound(msg, myLogin);
67797
+ if (msg.type === "subscribed") {
67798
+ mySubscription = true;
67799
+ 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}`);
67800
+ }
67801
+ if (msg.type === "error" && (msg.code === "auth_failed" || msg.code === "token_revoked")) {
67802
+ stopRequested = true;
67803
+ }
67804
+ });
67805
+ ws.on("close", (code, reason) => {
67806
+ stopWorking();
67807
+ if (stopRequested || code === 1e3) {
67808
+ say(`${DIM2}[${ts()}] disconnected (${code}${reason && reason.length ? ": " + reason.toString() : ""})${RESET2}`);
67809
+ process.exit(0);
67810
+ }
67811
+ if (code === 1008) {
67812
+ sayErr(`${RED}disconnected (${code}): auth rejected \u2014 won't retry${RESET2}`);
67813
+ process.exit(2);
67814
+ }
67815
+ const delay = BACKOFF[Math.min(reconnectAttempt, BACKOFF.length - 1)];
67816
+ reconnectAttempt += 1;
67817
+ say(`${DIM2}[${ts()}] ${AMBER}disconnected${RESET2} (${code}${reason && reason.length ? ": " + reason.toString() : ""})${DIM2} \u2014 reconnecting in ${delay / 1e3}s (attempt ${reconnectAttempt})${RESET2}`);
67818
+ if (reconnectTimer) clearTimeout(reconnectTimer);
67819
+ reconnectTimer = setTimeout(() => {
67820
+ reconnectTimer = null;
67821
+ connect();
67822
+ }, delay);
67823
+ });
67824
+ ws.on("error", (err) => {
67825
+ if (ws.readyState === wrapper_default.CLOSING || ws.readyState === wrapper_default.CLOSED) return;
67826
+ sayErr(`${RED}ws error: ${err.message}${RESET2}`);
67827
+ });
67828
+ }
67829
+ connect();
67800
67830
  const rl = (0, import_node_readline2.createInterface)({
67801
67831
  input: process.stdin,
67802
67832
  output: process.stdout,
@@ -67813,6 +67843,11 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67813
67843
  return;
67814
67844
  }
67815
67845
  if (text === "/q" || text === "/quit") {
67846
+ stopRequested = true;
67847
+ if (reconnectTimer) {
67848
+ clearTimeout(reconnectTimer);
67849
+ reconnectTimer = null;
67850
+ }
67816
67851
  ws.close(1e3, "user quit");
67817
67852
  return;
67818
67853
  }
@@ -67867,7 +67902,8 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67867
67902
  say(`${DIM2}unknown slash-command: ${text} (try /m /y /n /debug /q)${RESET2}`);
67868
67903
  return;
67869
67904
  }
67870
- const xMatch = /^(@[A-Za-z0-9._\-/]+)\s+([\s\S]+)$/.exec(text);
67905
+ const UUID_RE_LOOSE = /^@?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
67906
+ const xMatch = /^(@?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|@[A-Za-z0-9._\-/]+)\s+([\s\S]+)$/i.exec(text);
67871
67907
  if (xMatch) {
67872
67908
  const targetRef = xMatch[1];
67873
67909
  const promptText = xMatch[2].trim();
@@ -67875,6 +67911,19 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67875
67911
  say(`${DIM2}usage: ${targetRef} <prompt>${RESET2}`);
67876
67912
  return;
67877
67913
  }
67914
+ if (UUID_RE_LOOSE.test(targetRef)) {
67915
+ const peerSessionId = targetRef.replace(/^@/, "");
67916
+ const out2 = {
67917
+ type: "prompt",
67918
+ sessionId: peerSessionId,
67919
+ text: promptText,
67920
+ sourceSessionId: sessionId
67921
+ };
67922
+ ws.send(JSON.stringify(out2));
67923
+ say(`${DIM2}[${ts()}]${RESET2} ${AMBER}\u2192 prompt \u2192 ${peerSessionId.slice(0, 8)}\u2026${RESET2} ${promptText}`);
67924
+ startWorking();
67925
+ return;
67926
+ }
67878
67927
  (async () => {
67879
67928
  const needle = targetRef.startsWith("@") ? targetRef : "@" + targetRef;
67880
67929
  const slash = needle.indexOf("/");
@@ -67931,6 +67980,11 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
67931
67980
  startWorking();
67932
67981
  });
67933
67982
  process.on("SIGINT", () => {
67983
+ stopRequested = true;
67984
+ if (reconnectTimer) {
67985
+ clearTimeout(reconnectTimer);
67986
+ reconnectTimer = null;
67987
+ }
67934
67988
  ws.close(1e3, "sigint");
67935
67989
  });
67936
67990
  });
@@ -68595,7 +68649,7 @@ var webhookCmd = new Command("webhook").description("manage webhook subscription
68595
68649
 
68596
68650
  // src/index.ts
68597
68651
  var program2 = new Command();
68598
- program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.0.32");
68652
+ program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.0.34");
68599
68653
  program2.addCommand(loginCmd);
68600
68654
  program2.addCommand(logoutCmd);
68601
68655
  program2.addCommand(whoamiCmd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawborrator-cli",
3
- "version": "0.0.32",
3
+ "version": "0.0.34",
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",