clawborrator-cli 0.0.21 → 0.0.23

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.
@@ -6,16 +6,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __esm = (fn, res) => function __init() {
10
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
- };
12
9
  var __commonJS = (cb, mod) => function __require() {
13
10
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
14
11
  };
15
- var __export = (target, all) => {
16
- for (var name in all)
17
- __defProp(target, name, { get: all[name], enumerable: true });
18
- };
19
12
  var __copyProps = (to, from, except, desc) => {
20
13
  if (from && typeof from === "object" || typeof from === "function") {
21
14
  for (let key of __getOwnPropNames(from))
@@ -6642,34 +6635,6 @@ var require_websocket_server = __commonJS({
6642
6635
  }
6643
6636
  });
6644
6637
 
6645
- // ../node_modules/ws/wrapper.mjs
6646
- var wrapper_exports = {};
6647
- __export(wrapper_exports, {
6648
- PerMessageDeflate: () => import_permessage_deflate.default,
6649
- Receiver: () => import_receiver.default,
6650
- Sender: () => import_sender.default,
6651
- WebSocket: () => import_websocket.default,
6652
- WebSocketServer: () => import_websocket_server.default,
6653
- createWebSocketStream: () => import_stream.default,
6654
- default: () => wrapper_default,
6655
- extension: () => import_extension.default,
6656
- subprotocol: () => import_subprotocol.default
6657
- });
6658
- var import_stream, import_extension, import_permessage_deflate, import_receiver, import_sender, import_subprotocol, import_websocket, import_websocket_server, wrapper_default;
6659
- var init_wrapper = __esm({
6660
- "../node_modules/ws/wrapper.mjs"() {
6661
- import_stream = __toESM(require_stream(), 1);
6662
- import_extension = __toESM(require_extension(), 1);
6663
- import_permessage_deflate = __toESM(require_permessage_deflate(), 1);
6664
- import_receiver = __toESM(require_receiver(), 1);
6665
- import_sender = __toESM(require_sender(), 1);
6666
- import_subprotocol = __toESM(require_subprotocol(), 1);
6667
- import_websocket = __toESM(require_websocket(), 1);
6668
- import_websocket_server = __toESM(require_websocket_server(), 1);
6669
- wrapper_default = import_websocket.default;
6670
- }
6671
- });
6672
-
6673
6638
  // ../node_modules/commander/esm.mjs
6674
6639
  var import_index = __toESM(require_commander(), 1);
6675
6640
  var {
@@ -6880,7 +6845,19 @@ var whoamiCmd = new Command("whoami").description("show the currently authentica
6880
6845
 
6881
6846
  // src/commands/session-attach.ts
6882
6847
  var import_node_readline = require("node:readline");
6883
- init_wrapper();
6848
+
6849
+ // ../node_modules/ws/wrapper.mjs
6850
+ var import_stream = __toESM(require_stream(), 1);
6851
+ var import_extension = __toESM(require_extension(), 1);
6852
+ var import_permessage_deflate = __toESM(require_permessage_deflate(), 1);
6853
+ var import_receiver = __toESM(require_receiver(), 1);
6854
+ var import_sender = __toESM(require_sender(), 1);
6855
+ var import_subprotocol = __toESM(require_subprotocol(), 1);
6856
+ var import_websocket = __toESM(require_websocket(), 1);
6857
+ var import_websocket_server = __toESM(require_websocket_server(), 1);
6858
+ var wrapper_default = import_websocket.default;
6859
+
6860
+ // src/commands/session-attach.ts
6884
6861
  var RESET = "\x1B[0m";
6885
6862
  var DIM = "\x1B[2m";
6886
6863
  var AMBER = "\x1B[33m";
@@ -6917,15 +6894,19 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
6917
6894
  slug = needle;
6918
6895
  }
6919
6896
  const data = await api.get("/api/v1/sessions");
6920
- const match = data.items.find(
6921
- (s) => s.routingName === slug && (ownerLogin === null || s.startedByLogin === ownerLogin)
6922
- );
6923
- if (!match) {
6897
+ let candidates = data.items.filter((s) => s.routingName === slug);
6898
+ if (ownerLogin !== null) {
6899
+ candidates = candidates.filter((s) => s.startedByLogin === ownerLogin);
6900
+ } else {
6901
+ const mine = candidates.filter((s) => s.role === "owner");
6902
+ if (mine.length > 0) candidates = mine;
6903
+ }
6904
+ if (candidates.length === 0) {
6924
6905
  const label = ownerLogin ? `@${ownerLogin}/${slug.slice(1)}` : slug;
6925
6906
  console.error(`error: no session with routing name ${label} (run \`claw session list\` to see what's available)`);
6926
6907
  process.exit(2);
6927
6908
  }
6928
- sessionId = match.id;
6909
+ sessionId = candidates[0].id;
6929
6910
  }
6930
6911
  const wsUrl = cfg.hubUrl.replace(/^http/i, "ws") + "/cli";
6931
6912
  const ws = new wrapper_default(wsUrl, {
@@ -7039,13 +7020,18 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
7039
7020
  }
7040
7021
  try {
7041
7022
  const data = await api.get("/api/v1/sessions");
7042
- const match = data.items.find(
7043
- (s) => s.routingName === slug && (ownerLogin === null || s.startedByLogin === ownerLogin)
7044
- );
7045
- if (!match) {
7023
+ let candidates = data.items.filter((s) => s.routingName === slug);
7024
+ if (ownerLogin !== null) {
7025
+ candidates = candidates.filter((s) => s.startedByLogin === ownerLogin);
7026
+ } else {
7027
+ const mine = candidates.filter((s) => s.role === "owner");
7028
+ if (mine.length > 0) candidates = mine;
7029
+ }
7030
+ if (candidates.length === 0) {
7046
7031
  console.error(`${RED}error: no session ${targetRef} (try \`claw session list\` in another terminal)${RESET}`);
7047
7032
  return;
7048
7033
  }
7034
+ const match = candidates[0];
7049
7035
  const out2 = {
7050
7036
  type: "prompt",
7051
7037
  sessionId: match.id,
@@ -7258,17 +7244,21 @@ async function resolveSessionId(idOrName) {
7258
7244
  slug = needle;
7259
7245
  }
7260
7246
  const data = await api.get("/api/v1/sessions");
7261
- const match = data.items.find(
7262
- (s) => s.routingName === slug && (ownerLogin === null || s.startedByLogin === ownerLogin)
7263
- );
7264
- if (!match) {
7247
+ let candidates = data.items.filter((s) => s.routingName === slug);
7248
+ if (ownerLogin !== null) {
7249
+ candidates = candidates.filter((s) => s.startedByLogin === ownerLogin);
7250
+ } else {
7251
+ const mine = candidates.filter((s) => s.role === "owner");
7252
+ if (mine.length > 0) candidates = mine;
7253
+ }
7254
+ if (candidates.length === 0) {
7265
7255
  const err = new Error(
7266
7256
  ownerLogin ? `no session @${ownerLogin}/${slug.slice(1)} (run \`claw session list\`)` : `no session with routing name ${slug} (run \`claw session list\`)`
7267
7257
  );
7268
7258
  err.code = "CLW_NO_ROUTING_MATCH";
7269
7259
  throw err;
7270
7260
  }
7271
- return match.id;
7261
+ return candidates[0].id;
7272
7262
  }
7273
7263
  var sessionList = new Command("list").alias("ls").description("list sessions you can see").option("--connected", "only sessions whose channel WS is currently open").option("--all", "include archived sessions").action(async (opts) => {
7274
7264
  const qs = new URLSearchParams();
@@ -7418,46 +7408,13 @@ var sessionDelete = new Command("delete").description("hard-delete a single sess
7418
7408
  );
7419
7409
  console.log(`\u2717 deleted ${r.sessionId} (events / op-messages / shares cascaded).`);
7420
7410
  });
7421
- var sessionPrompt = new Command("prompt").description("send a one-shot prompt to a session's live Claude (lands in the same inbox as cross-session route prompts; receiving Claude must be polling `await_routed_prompt`)").argument("<ref>", "session UUID or @routingName").argument("<text>", "prompt text \u2014 quote multi-word").action(async (ref, text) => {
7411
+ var sessionPrompt = new Command("prompt").description('send a one-shot prompt to a session\'s live Claude. Fire-and-forget \u2014 to find the eventual reply, run `claw session events <ref> --kind=chat --type=reply` (or `claw route <peer> "..."` for ask-mode that blocks for the answer).').argument("<ref>", "session UUID or @routingName").argument("<text>", "prompt text \u2014 quote multi-word").action(async (ref, text) => {
7422
7412
  const id = await resolveSessionId(ref);
7423
- const cfg = loadConfig();
7424
- if (!cfg.pat) {
7425
- console.error("error: not logged in. run `claw login`.");
7426
- process.exit(2);
7427
- }
7428
- const wsUrl = cfg.hubUrl.replace(/^http/i, "ws") + "/cli";
7429
- const WS = (await Promise.resolve().then(() => (init_wrapper(), wrapper_exports))).default;
7430
- const ws = new WS(wsUrl, { headers: { Authorization: `Bearer ${cfg.pat}` } });
7431
- let timer = null;
7432
- await new Promise((resolve3, reject) => {
7433
- timer = setTimeout(() => {
7434
- ws.close();
7435
- reject(new Error("timeout waiting for ack"));
7436
- }, 1e4);
7437
- ws.on("open", () => {
7438
- ws.send(JSON.stringify({ type: "prompt", sessionId: id, text }));
7439
- });
7440
- ws.on("message", (data) => {
7441
- let m;
7442
- try {
7443
- m = JSON.parse(data.toString("utf8"));
7444
- } catch {
7445
- return;
7446
- }
7447
- if (m.type === "ack" && m.ok) {
7448
- console.log(`\u2713 delivered (chatId=${m.chatId})`);
7449
- ws.close();
7450
- resolve3();
7451
- } else if (m.type === "error") {
7452
- ws.close();
7453
- reject(new Error(`${m.code}: ${m.message}`));
7454
- }
7455
- });
7456
- ws.on("error", (err) => reject(err));
7457
- ws.on("close", () => {
7458
- if (timer) clearTimeout(timer);
7459
- });
7460
- });
7413
+ const out = await api.post(
7414
+ `/api/v1/sessions/${encodeURIComponent(id)}/prompt`,
7415
+ { text }
7416
+ );
7417
+ console.log(`\u2713 delivered (chatId=${out.chatId})`);
7461
7418
  });
7462
7419
  var VALID_ROLES = ["viewer", "prompter", "approver"];
7463
7420
  var sessionShareCmd = new Command("share").description("grant another GitHub user access to a session. role defaults to prompter (viewer = read-only events; prompter = + send prompts/op-messages; approver = + resolve permission requests).").argument("<ref>", "session UUID or @routingName").argument("<login>", "GitHub login of the user to share with (with or without leading @)").option("--role <role>", `viewer | prompter | approver`, "prompter").action(async (ref, login, opts) => {
@@ -7620,7 +7577,7 @@ function fmtAgo2(iso) {
7620
7577
  }
7621
7578
 
7622
7579
  // src/commands/peers.ts
7623
- var peersCmd = new Command("peers").description("list your sessions reachable for cross-session routing").action(async () => {
7580
+ var peersCmd = new Command("peers").description("list your sessions reachable for cross-session routing \u2014 own + shared").action(async () => {
7624
7581
  const data = await api.get("/api/v1/peers");
7625
7582
  if (data.peers.length === 0) {
7626
7583
  console.log("no peers (no sessions registered yet)");
@@ -7629,7 +7586,9 @@ var peersCmd = new Command("peers").description("list your sessions reachable fo
7629
7586
  for (const p of data.peers) {
7630
7587
  const dot = p.online ? "\u25CF" : "\u25CB";
7631
7588
  const where = p.cwd ? ` ${p.cwd}` : "";
7632
- console.log(`${dot} ${p.routingName.padEnd(20)} ${p.online ? "online" : "offline"}${where}`);
7589
+ const qualifiedName = `@${p.ownerLogin}/${p.routingName.replace(/^@/, "")}`;
7590
+ const tag = p.mine ? "" : " (shared)";
7591
+ console.log(`${dot} ${qualifiedName.padEnd(28)} ${p.online ? "online " : "offline"}${tag}${where}`);
7633
7592
  }
7634
7593
  });
7635
7594
  var routeCmd = new Command("route").description("send a one-shot prompt to a peer session; ask mode (default) blocks for the reply, tell mode is fire-and-forget").argument("<peer>", "routingName (e.g. @foo, foo, @owner/foo)").argument("<prompt>", "text to send (quote it to keep spaces)").option("--mode <mode>", "ask | tell", "ask").action(async (peer, prompt, opts) => {
@@ -7718,7 +7677,7 @@ var webhookCmd = new Command("webhook").description("manage webhook subscription
7718
7677
 
7719
7678
  // src/index.ts
7720
7679
  var program2 = new Command();
7721
- program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.0.21");
7680
+ program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.0.23");
7722
7681
  program2.addCommand(loginCmd);
7723
7682
  program2.addCommand(logoutCmd);
7724
7683
  program2.addCommand(whoamiCmd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawborrator-cli",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
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",