clawborrator-cli 0.0.51 → 0.0.52

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.
@@ -67615,23 +67615,30 @@ var AmbiguousError = class extends Error {
67615
67615
  }
67616
67616
  code = "CLW_AMBIGUOUS";
67617
67617
  };
67618
- async function pickCandidate(input, candidates) {
67618
+ async function pickCandidate(input, candidates, opts = {}) {
67619
67619
  if (candidates.length === 1) return candidates[0];
67620
67620
  const live = candidates.filter((c) => c.connected);
67621
- if (live.length <= 1) {
67622
- return live[0] ?? candidates[0];
67621
+ let promptSet;
67622
+ if (opts.destructive) {
67623
+ if (candidates.length <= 1) return candidates[0];
67624
+ promptSet = candidates;
67625
+ } else {
67626
+ if (live.length <= 1) return live[0] ?? candidates[0];
67627
+ promptSet = live;
67623
67628
  }
67624
67629
  if (!process.stdin.isTTY || !process.stderr.isTTY) {
67625
- throw new AmbiguousError(live, input);
67630
+ throw new AmbiguousError(promptSet, input);
67626
67631
  }
67627
67632
  process.stderr.write(`${BOLD}'${input}' is ambiguous \u2014 pick a session:${RESET}
67628
67633
  `);
67629
- for (let i = 0; i < live.length; i++) {
67630
- const c = live[i];
67634
+ for (let i = 0; i < promptSet.length; i++) {
67635
+ const c = promptSet[i];
67631
67636
  const qualified = c.routingName ? `@${c.startedByLogin}/${c.routingName.replace(/^@/, "")}` : `(no routing name)`;
67637
+ const status = c.connected ? `${BOLD}\u25CF online${RESET}` : `${DIM}\u25CB offline${RESET}`;
67632
67638
  const cwd = c.cwd ? ` ${DIM}${c.cwd}${RESET}` : "";
67633
67639
  const host = c.host ? ` ${DIM}${c.host}${RESET}` : "";
67634
- process.stderr.write(` ${BOLD}${i + 1}${RESET}. ${qualified}${host}${cwd}
67640
+ const seen = c.lastSeenAt ? ` ${DIM}last seen ${c.lastSeenAt}${RESET}` : "";
67641
+ process.stderr.write(` ${BOLD}${i + 1}${RESET}. ${qualified} ${status}${host}${cwd}${seen}
67635
67642
  `);
67636
67643
  process.stderr.write(` ${DIM}id ${c.id}${RESET}
67637
67644
  `);
@@ -67640,7 +67647,7 @@ async function pickCandidate(input, candidates) {
67640
67647
  `);
67641
67648
  const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stderr });
67642
67649
  const answer = await new Promise((resolve3) => {
67643
- rl.question(`pick [1-${live.length}]: `, resolve3);
67650
+ rl.question(`pick [1-${promptSet.length}]: `, resolve3);
67644
67651
  });
67645
67652
  rl.close();
67646
67653
  const trimmed = answer.trim().toLowerCase();
@@ -67648,10 +67655,10 @@ async function pickCandidate(input, candidates) {
67648
67655
  throw new Error("cancelled");
67649
67656
  }
67650
67657
  const idx = parseInt(trimmed, 10);
67651
- if (!Number.isInteger(idx) || idx < 1 || idx > live.length) {
67658
+ if (!Number.isInteger(idx) || idx < 1 || idx > promptSet.length) {
67652
67659
  throw new Error(`invalid selection '${answer}'`);
67653
67660
  }
67654
- return live[idx - 1];
67661
+ return promptSet[idx - 1];
67655
67662
  }
67656
67663
 
67657
67664
  // src/commands/session-attach.ts
@@ -68330,7 +68337,7 @@ function fmtAgo(iso) {
68330
68337
  return fmtDuration(Date.now() - new Date(iso).getTime());
68331
68338
  }
68332
68339
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
68333
- async function resolveSessionId(idOrName) {
68340
+ async function resolveSessionId(idOrName, opts = {}) {
68334
68341
  if (UUID_RE.test(idOrName)) return idOrName;
68335
68342
  const needle = idOrName.startsWith("@") ? idOrName : "@" + idOrName;
68336
68343
  const slash = needle.indexOf("/");
@@ -68358,7 +68365,7 @@ async function resolveSessionId(idOrName) {
68358
68365
  throw err;
68359
68366
  }
68360
68367
  try {
68361
- const picked = await pickCandidate(idOrName, candidates);
68368
+ const picked = await pickCandidate(idOrName, candidates, { destructive: !!opts.destructive });
68362
68369
  return picked.id;
68363
68370
  } catch (e) {
68364
68371
  if (e instanceof AmbiguousError) {
@@ -68510,16 +68517,17 @@ var sessionPrune = new Command("prune").description("hard-delete duplicate sessi
68510
68517
  }
68511
68518
  if (r.dryRun) console.log("\n(--dry-run \u2014 re-run without it to apply)");
68512
68519
  });
68513
- var sessionDelete = new Command("delete").description("hard-delete a single session \u2014 cascades events / op-messages / shares. Irreversible. Use `archive` for the soft form (auto-resurrects on reconnect).").argument("<ref>", "session UUID or @routingName").option("--hard", "required: confirm you want a permanent delete (no soft form is offered without this flag)").action(async (ref, opts) => {
68520
+ var sessionDelete = new Command("delete").description("hard-delete a single session \u2014 cascades events / op-messages / shares / files (refcount-sweeps blobs). Irreversible. Use `archive` for the soft form (auto-resurrects on reconnect). Prompts if the routing name matches more than one row, even when only one is online \u2014 both are equally permanent to delete.").argument("<ref>", "session UUID or @routingName").option("--hard", "required: confirm you want a permanent delete (no soft form is offered without this flag)").action(async (ref, opts) => {
68514
68521
  if (!opts.hard) {
68515
68522
  console.error("error: hard delete requires --hard. Did you mean `claw session archive <ref>`?");
68516
68523
  process.exit(2);
68517
68524
  }
68518
- const id = await resolveSessionId(ref);
68525
+ const id = await resolveSessionId(ref, { destructive: true });
68519
68526
  const r = await api.delete(
68520
68527
  `/api/v1/sessions/${encodeURIComponent(id)}?hard=true`
68521
68528
  );
68522
- console.log(`\u2717 deleted ${r.sessionId} (events / op-messages / shares cascaded).`);
68529
+ const sweep = r.blobsSwept && r.blobsSwept > 0 ? ` \xB7 swept ${r.blobsSwept} blob${r.blobsSwept === 1 ? "" : "s"} (${r.bytesFreed ?? 0} bytes freed)` : "";
68530
+ console.log(`\u2717 deleted ${r.sessionId} (events / op-messages / shares / files cascaded)${sweep}`);
68523
68531
  });
68524
68532
  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) => {
68525
68533
  const id = await resolveSessionId(ref);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawborrator-cli",
3
- "version": "0.0.51",
3
+ "version": "0.0.52",
4
4
  "type": "module",
5
5
  "description": "claw — command-line client for clawborrator. Attach to remote Claude Code sessions, send prompts, resolve permission gates, route across sessions, manage public agents and webhooks. Auth via GitHub OAuth + PKCE.",
6
6
  "license": "MIT",