clawborrator-cli 0.0.10 → 0.0.12
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.
- package/dist-bundled/claw.cjs +147 -18
- package/package.json +1 -1
package/dist-bundled/claw.cjs
CHANGED
|
@@ -6,9 +6,16 @@ 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
|
+
};
|
|
9
12
|
var __commonJS = (cb, mod) => function __require() {
|
|
10
13
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
14
|
};
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
12
19
|
var __copyProps = (to, from, except, desc) => {
|
|
13
20
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
21
|
for (let key of __getOwnPropNames(from))
|
|
@@ -6635,6 +6642,34 @@ var require_websocket_server = __commonJS({
|
|
|
6635
6642
|
}
|
|
6636
6643
|
});
|
|
6637
6644
|
|
|
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
|
+
|
|
6638
6673
|
// ../node_modules/commander/esm.mjs
|
|
6639
6674
|
var import_index = __toESM(require_commander(), 1);
|
|
6640
6675
|
var {
|
|
@@ -6845,19 +6880,7 @@ var whoamiCmd = new Command("whoami").description("show the currently authentica
|
|
|
6845
6880
|
|
|
6846
6881
|
// src/commands/session-attach.ts
|
|
6847
6882
|
var import_node_readline = require("node:readline");
|
|
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
|
|
6883
|
+
init_wrapper();
|
|
6861
6884
|
var RESET = "\x1B[0m";
|
|
6862
6885
|
var DIM = "\x1B[2m";
|
|
6863
6886
|
var AMBER = "\x1B[33m";
|
|
@@ -6925,7 +6948,7 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
6925
6948
|
printInbound(msg);
|
|
6926
6949
|
if (msg.type === "subscribed") {
|
|
6927
6950
|
mySubscription = true;
|
|
6928
|
-
console.log(`${DIM}attached as ${BOLD}${msg.role}${RESET}${DIM}. type for op-
|
|
6951
|
+
console.log(`${DIM}attached as ${BOLD}${msg.role}${RESET}${DIM}. type for prompt \xB7 /m <text> for op-msg \xB7 /y /n on permissions \xB7 /q to quit${RESET}`);
|
|
6929
6952
|
}
|
|
6930
6953
|
});
|
|
6931
6954
|
ws.on("close", (code, reason) => {
|
|
@@ -6963,12 +6986,34 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
6963
6986
|
ws.send(JSON.stringify(approval));
|
|
6964
6987
|
return;
|
|
6965
6988
|
}
|
|
6989
|
+
if (text === "/m" || text.startsWith("/m ")) {
|
|
6990
|
+
const opText = text.slice(2).trim();
|
|
6991
|
+
if (!opText) {
|
|
6992
|
+
console.log(`${DIM}usage: /m <text> (sends as op-message; bare text is a prompt)${RESET}`);
|
|
6993
|
+
return;
|
|
6994
|
+
}
|
|
6995
|
+
const out2 = { type: "op_message", sessionId, text: opText };
|
|
6996
|
+
ws.send(JSON.stringify(out2));
|
|
6997
|
+
return;
|
|
6998
|
+
}
|
|
6999
|
+
if (text === "/p" || text.startsWith("/p ")) {
|
|
7000
|
+
const promptText = text.slice(2).trim();
|
|
7001
|
+
if (!promptText) {
|
|
7002
|
+
console.log(`${DIM}usage: /p <text> (or just type \u2014 bare text is a prompt now)${RESET}`);
|
|
7003
|
+
return;
|
|
7004
|
+
}
|
|
7005
|
+
const out2 = { type: "prompt", sessionId, text: promptText };
|
|
7006
|
+
ws.send(JSON.stringify(out2));
|
|
7007
|
+
console.log(`${DIM}[${ts()}]${RESET} ${AMBER}\u2192 prompt sent${RESET} ${promptText}`);
|
|
7008
|
+
return;
|
|
7009
|
+
}
|
|
6966
7010
|
if (text.startsWith("/")) {
|
|
6967
|
-
console.log(`${DIM}unknown slash-command: ${text} (try /y /n /q)${RESET}`);
|
|
7011
|
+
console.log(`${DIM}unknown slash-command: ${text} (try /m /y /n /q)${RESET}`);
|
|
6968
7012
|
return;
|
|
6969
7013
|
}
|
|
6970
|
-
const out = { type: "
|
|
7014
|
+
const out = { type: "prompt", sessionId, text };
|
|
6971
7015
|
ws.send(JSON.stringify(out));
|
|
7016
|
+
console.log(`${DIM}[${ts()}]${RESET} ${AMBER}\u2192 prompt${RESET} ${text}`);
|
|
6972
7017
|
});
|
|
6973
7018
|
process.on("SIGINT", () => {
|
|
6974
7019
|
ws.close(1e3, "sigint");
|
|
@@ -7268,7 +7313,91 @@ var sessionMessages = new Command("messages").alias("msgs").description("dump op
|
|
|
7268
7313
|
console.log(`(more \u2014 older: --before ${data.firstId} \xB7 newer: --after ${data.lastId})`);
|
|
7269
7314
|
}
|
|
7270
7315
|
});
|
|
7271
|
-
var
|
|
7316
|
+
var sessionArchive = new Command("archive").description("soft-delete a session (sets archivedAt). Note: register-time reconnect unarchives, so a session whose UUID is still in a project's .claude/clawborrator/session.json will resurrect on its next start.").argument("<ref>", "session UUID or @routingName").action(async (ref) => {
|
|
7317
|
+
const id = await resolveSessionId(ref);
|
|
7318
|
+
const r = await api.post(
|
|
7319
|
+
`/api/v1/sessions/${encodeURIComponent(id)}/archive`,
|
|
7320
|
+
{}
|
|
7321
|
+
);
|
|
7322
|
+
if (r.alreadyArchived) {
|
|
7323
|
+
console.log(`(already archived: ${r.sessionId} at ${r.archivedAt})`);
|
|
7324
|
+
} else {
|
|
7325
|
+
console.log(`\u2713 archived ${r.sessionId} at ${r.archivedAt}`);
|
|
7326
|
+
}
|
|
7327
|
+
});
|
|
7328
|
+
var sessionPrune = new Command("prune").description("hard-delete duplicate session rows that share a routing name. The live (or most-recently-seen) row is kept; the rest are removed along with their events / op-messages / shares (FK cascade). Use --dry-run first if unsure.").option("--dry-run", "show what would be deleted without writing").option("--routing <name>", "narrow to a single routing name (e.g. @driver)").action(async (opts) => {
|
|
7329
|
+
const body = { dryRun: !!opts.dryRun };
|
|
7330
|
+
if (opts.routing) body.routingName = opts.routing.startsWith("@") ? opts.routing : "@" + opts.routing;
|
|
7331
|
+
const r = await api.post(`/api/v1/sessions/prune`, body);
|
|
7332
|
+
if (r.deleted.length === 0) {
|
|
7333
|
+
console.log("nothing to prune (no routing-name duplicates).");
|
|
7334
|
+
return;
|
|
7335
|
+
}
|
|
7336
|
+
const verb = r.dryRun ? "would delete" : "deleted";
|
|
7337
|
+
console.log(`${verb} ${r.deleted.length} duplicate${r.deleted.length === 1 ? "" : "s"}:`);
|
|
7338
|
+
for (const d of r.deleted) {
|
|
7339
|
+
const tag = d.wasArchived ? " [was archived]" : "";
|
|
7340
|
+
console.log(` \u2717 ${d.routingName.padEnd(20)} ${d.sessionId} (last seen ${d.lastSeenAt})${tag}`);
|
|
7341
|
+
}
|
|
7342
|
+
console.log(`keeping:`);
|
|
7343
|
+
for (const k of r.kept) {
|
|
7344
|
+
console.log(` \u2713 ${k.routingName.padEnd(20)} ${k.sessionId}`);
|
|
7345
|
+
}
|
|
7346
|
+
if (r.dryRun) console.log("\n(--dry-run \u2014 re-run without it to apply)");
|
|
7347
|
+
});
|
|
7348
|
+
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) => {
|
|
7349
|
+
if (!opts.hard) {
|
|
7350
|
+
console.error("error: hard delete requires --hard. Did you mean `claw session archive <ref>`?");
|
|
7351
|
+
process.exit(2);
|
|
7352
|
+
}
|
|
7353
|
+
const id = await resolveSessionId(ref);
|
|
7354
|
+
const r = await api.delete(
|
|
7355
|
+
`/api/v1/sessions/${encodeURIComponent(id)}?hard=true`
|
|
7356
|
+
);
|
|
7357
|
+
console.log(`\u2717 deleted ${r.sessionId} (events / op-messages / shares cascaded).`);
|
|
7358
|
+
});
|
|
7359
|
+
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) => {
|
|
7360
|
+
const id = await resolveSessionId(ref);
|
|
7361
|
+
const cfg = loadConfig();
|
|
7362
|
+
if (!cfg.pat) {
|
|
7363
|
+
console.error("error: not logged in. run `claw login`.");
|
|
7364
|
+
process.exit(2);
|
|
7365
|
+
}
|
|
7366
|
+
const wsUrl = cfg.hubUrl.replace(/^http/i, "ws") + "/cli";
|
|
7367
|
+
const WS = (await Promise.resolve().then(() => (init_wrapper(), wrapper_exports))).default;
|
|
7368
|
+
const ws = new WS(wsUrl, { headers: { Authorization: `Bearer ${cfg.pat}` } });
|
|
7369
|
+
let timer = null;
|
|
7370
|
+
await new Promise((resolve3, reject) => {
|
|
7371
|
+
timer = setTimeout(() => {
|
|
7372
|
+
ws.close();
|
|
7373
|
+
reject(new Error("timeout waiting for ack"));
|
|
7374
|
+
}, 1e4);
|
|
7375
|
+
ws.on("open", () => {
|
|
7376
|
+
ws.send(JSON.stringify({ type: "prompt", sessionId: id, text }));
|
|
7377
|
+
});
|
|
7378
|
+
ws.on("message", (data) => {
|
|
7379
|
+
let m;
|
|
7380
|
+
try {
|
|
7381
|
+
m = JSON.parse(data.toString("utf8"));
|
|
7382
|
+
} catch {
|
|
7383
|
+
return;
|
|
7384
|
+
}
|
|
7385
|
+
if (m.type === "ack" && m.ok) {
|
|
7386
|
+
console.log(`\u2713 delivered (chatId=${m.chatId})`);
|
|
7387
|
+
ws.close();
|
|
7388
|
+
resolve3();
|
|
7389
|
+
} else if (m.type === "error") {
|
|
7390
|
+
ws.close();
|
|
7391
|
+
reject(new Error(`${m.code}: ${m.message}`));
|
|
7392
|
+
}
|
|
7393
|
+
});
|
|
7394
|
+
ws.on("error", (err) => reject(err));
|
|
7395
|
+
ws.on("close", () => {
|
|
7396
|
+
if (timer) clearTimeout(timer);
|
|
7397
|
+
});
|
|
7398
|
+
});
|
|
7399
|
+
});
|
|
7400
|
+
var sessionCmd = new Command("session").description("manage Claude Code sessions registered with this hub").addCommand(sessionList).addCommand(sessionInfo).addCommand(sessionAttach).addCommand(sessionEvents).addCommand(sessionMessages).addCommand(sessionArchive).addCommand(sessionPrune).addCommand(sessionPrompt).addCommand(sessionDelete);
|
|
7272
7401
|
|
|
7273
7402
|
// src/commands/token.ts
|
|
7274
7403
|
var import_node_fs2 = require("node:fs");
|
|
@@ -7476,7 +7605,7 @@ var webhookCmd = new Command("webhook").description("manage webhook subscription
|
|
|
7476
7605
|
|
|
7477
7606
|
// src/index.ts
|
|
7478
7607
|
var program2 = new Command();
|
|
7479
|
-
program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.0.
|
|
7608
|
+
program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.0.12");
|
|
7480
7609
|
program2.addCommand(loginCmd);
|
|
7481
7610
|
program2.addCommand(logoutCmd);
|
|
7482
7611
|
program2.addCommand(whoamiCmd);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawborrator-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
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",
|