clawborrator-cli 0.0.23 → 0.0.25
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 +154 -47
- package/package.json +1 -1
package/dist-bundled/claw.cjs
CHANGED
|
@@ -6844,7 +6844,7 @@ var whoamiCmd = new Command("whoami").description("show the currently authentica
|
|
|
6844
6844
|
});
|
|
6845
6845
|
|
|
6846
6846
|
// src/commands/session-attach.ts
|
|
6847
|
-
var
|
|
6847
|
+
var import_node_readline2 = require("node:readline");
|
|
6848
6848
|
|
|
6849
6849
|
// ../node_modules/ws/wrapper.mjs
|
|
6850
6850
|
var import_stream = __toESM(require_stream(), 1);
|
|
@@ -6857,18 +6857,70 @@ var import_websocket = __toESM(require_websocket(), 1);
|
|
|
6857
6857
|
var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
6858
6858
|
var wrapper_default = import_websocket.default;
|
|
6859
6859
|
|
|
6860
|
-
// src/
|
|
6860
|
+
// src/util/disambiguate.ts
|
|
6861
|
+
var import_node_readline = require("node:readline");
|
|
6861
6862
|
var RESET = "\x1B[0m";
|
|
6862
6863
|
var DIM = "\x1B[2m";
|
|
6864
|
+
var BOLD = "\x1B[1m";
|
|
6865
|
+
var AmbiguousError = class extends Error {
|
|
6866
|
+
constructor(candidates, input) {
|
|
6867
|
+
super(`ambiguous reference '${input}' \u2014 multiple online sessions match`);
|
|
6868
|
+
this.candidates = candidates;
|
|
6869
|
+
this.input = input;
|
|
6870
|
+
}
|
|
6871
|
+
code = "CLW_AMBIGUOUS";
|
|
6872
|
+
};
|
|
6873
|
+
async function pickCandidate(input, candidates) {
|
|
6874
|
+
if (candidates.length === 1) return candidates[0];
|
|
6875
|
+
const live = candidates.filter((c) => c.connected);
|
|
6876
|
+
if (live.length <= 1) {
|
|
6877
|
+
return live[0] ?? candidates[0];
|
|
6878
|
+
}
|
|
6879
|
+
if (!process.stdin.isTTY || !process.stderr.isTTY) {
|
|
6880
|
+
throw new AmbiguousError(live, input);
|
|
6881
|
+
}
|
|
6882
|
+
process.stderr.write(`${BOLD}'${input}' is ambiguous \u2014 pick a session:${RESET}
|
|
6883
|
+
`);
|
|
6884
|
+
for (let i = 0; i < live.length; i++) {
|
|
6885
|
+
const c = live[i];
|
|
6886
|
+
const qualified = c.routingName ? `@${c.startedByLogin}/${c.routingName.replace(/^@/, "")}` : `(no routing name)`;
|
|
6887
|
+
const cwd = c.cwd ? ` ${DIM}${c.cwd}${RESET}` : "";
|
|
6888
|
+
const host = c.host ? ` ${DIM}${c.host}${RESET}` : "";
|
|
6889
|
+
process.stderr.write(` ${BOLD}${i + 1}${RESET}. ${qualified}${host}${cwd}
|
|
6890
|
+
`);
|
|
6891
|
+
process.stderr.write(` ${DIM}id ${c.id}${RESET}
|
|
6892
|
+
`);
|
|
6893
|
+
}
|
|
6894
|
+
process.stderr.write(` ${BOLD}q${RESET}. cancel
|
|
6895
|
+
`);
|
|
6896
|
+
const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stderr });
|
|
6897
|
+
const answer = await new Promise((resolve3) => {
|
|
6898
|
+
rl.question(`pick [1-${live.length}]: `, resolve3);
|
|
6899
|
+
});
|
|
6900
|
+
rl.close();
|
|
6901
|
+
const trimmed = answer.trim().toLowerCase();
|
|
6902
|
+
if (trimmed === "q" || trimmed === "quit" || trimmed === "") {
|
|
6903
|
+
throw new Error("cancelled");
|
|
6904
|
+
}
|
|
6905
|
+
const idx = parseInt(trimmed, 10);
|
|
6906
|
+
if (!Number.isInteger(idx) || idx < 1 || idx > live.length) {
|
|
6907
|
+
throw new Error(`invalid selection '${answer}'`);
|
|
6908
|
+
}
|
|
6909
|
+
return live[idx - 1];
|
|
6910
|
+
}
|
|
6911
|
+
|
|
6912
|
+
// src/commands/session-attach.ts
|
|
6913
|
+
var RESET2 = "\x1B[0m";
|
|
6914
|
+
var DIM2 = "\x1B[2m";
|
|
6863
6915
|
var AMBER = "\x1B[33m";
|
|
6864
6916
|
var BLUE = "\x1B[36m";
|
|
6865
6917
|
var RED = "\x1B[31m";
|
|
6866
|
-
var
|
|
6918
|
+
var BOLD2 = "\x1B[1m";
|
|
6867
6919
|
var GREEN = "\x1B[32m";
|
|
6868
6920
|
function ts() {
|
|
6869
6921
|
return (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
6870
6922
|
}
|
|
6871
|
-
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)").action(async (ref) => {
|
|
6923
|
+
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)").action(async (ref, opts) => {
|
|
6872
6924
|
const cfg = loadConfig();
|
|
6873
6925
|
if (!cfg.pat) {
|
|
6874
6926
|
console.error("error: not logged in. run `claw login`.");
|
|
@@ -6906,7 +6958,41 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
6906
6958
|
console.error(`error: no session with routing name ${label} (run \`claw session list\` to see what's available)`);
|
|
6907
6959
|
process.exit(2);
|
|
6908
6960
|
}
|
|
6909
|
-
|
|
6961
|
+
try {
|
|
6962
|
+
const picked = await pickCandidate(ref, candidates);
|
|
6963
|
+
sessionId = picked.id;
|
|
6964
|
+
} catch (e) {
|
|
6965
|
+
if (e instanceof AmbiguousError) {
|
|
6966
|
+
console.error(`error: '${ref}' is ambiguous \u2014 multiple online sessions match. Re-run with a UUID or qualified form (e.g. @owner/slug). Candidates:`);
|
|
6967
|
+
for (const c of e.candidates) {
|
|
6968
|
+
console.error(` ${c.id} @${c.startedByLogin}/${(c.routingName ?? "").replace(/^@/, "")} ${c.cwd ?? ""}`);
|
|
6969
|
+
}
|
|
6970
|
+
process.exit(2);
|
|
6971
|
+
}
|
|
6972
|
+
console.error(`error: ${e?.message ?? String(e)}`);
|
|
6973
|
+
process.exit(2);
|
|
6974
|
+
}
|
|
6975
|
+
}
|
|
6976
|
+
const limitArg = String(opts.limit ?? "50").toLowerCase();
|
|
6977
|
+
const historyLimit = limitArg === "all" ? 5e3 : limitArg === "0" ? 0 : Math.max(0, parseInt(limitArg, 10) || 0);
|
|
6978
|
+
if (historyLimit > 0) {
|
|
6979
|
+
const kindsParam = opts.opMessages === false ? "&kinds=event" : "";
|
|
6980
|
+
try {
|
|
6981
|
+
const tl = await api.get(`/api/v1/sessions/${encodeURIComponent(sessionId)}/timeline?limit=${historyLimit}${kindsParam}`);
|
|
6982
|
+
if (tl.items.length > 0) {
|
|
6983
|
+
console.log(`${DIM2}\u2500\u2500\u2500 history (${tl.items.length} item${tl.items.length === 1 ? "" : "s"}) \u2500\u2500\u2500${RESET2}`);
|
|
6984
|
+
for (const item of tl.items) {
|
|
6985
|
+
if (item.kind === "event") {
|
|
6986
|
+
renderEvent(item.event, myLogin);
|
|
6987
|
+
} else {
|
|
6988
|
+
console.log(`${DIM2}[${shortTs(item.ts)}]${RESET2} ${GREEN}@${item.authorLogin}${RESET2} ${item.text}`);
|
|
6989
|
+
}
|
|
6990
|
+
}
|
|
6991
|
+
console.log(`${DIM2}\u2500\u2500\u2500 live \u2500\u2500\u2500${RESET2}`);
|
|
6992
|
+
}
|
|
6993
|
+
} catch (e) {
|
|
6994
|
+
console.error(`${DIM2}(history fetch failed: ${e?.message ?? String(e)} \u2014 continuing live)${RESET2}`);
|
|
6995
|
+
}
|
|
6910
6996
|
}
|
|
6911
6997
|
const wsUrl = cfg.hubUrl.replace(/^http/i, "ws") + "/cli";
|
|
6912
6998
|
const ws = new wrapper_default(wsUrl, {
|
|
@@ -6915,7 +7001,7 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
6915
7001
|
let mySubscription = false;
|
|
6916
7002
|
const pendingPerms = [];
|
|
6917
7003
|
ws.on("open", () => {
|
|
6918
|
-
console.log(`${
|
|
7004
|
+
console.log(`${DIM2}[${ts()}]${RESET2} connected to ${cfg.hubUrl}`);
|
|
6919
7005
|
const sub = { type: "subscribe", sessionId };
|
|
6920
7006
|
ws.send(JSON.stringify(sub));
|
|
6921
7007
|
});
|
|
@@ -6935,22 +7021,22 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
6935
7021
|
printInbound(msg, myLogin);
|
|
6936
7022
|
if (msg.type === "subscribed") {
|
|
6937
7023
|
mySubscription = true;
|
|
6938
|
-
console.log(`${
|
|
7024
|
+
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}`);
|
|
6939
7025
|
}
|
|
6940
7026
|
});
|
|
6941
7027
|
ws.on("close", (code, reason) => {
|
|
6942
|
-
console.log(`${
|
|
7028
|
+
console.log(`${DIM2}[${ts()}] disconnected (${code}${reason ? ": " + reason.toString() : ""})${RESET2}`);
|
|
6943
7029
|
process.exit(0);
|
|
6944
7030
|
});
|
|
6945
7031
|
ws.on("error", (err) => {
|
|
6946
|
-
console.error(`${RED}ws error: ${err.message}${
|
|
7032
|
+
console.error(`${RED}ws error: ${err.message}${RESET2}`);
|
|
6947
7033
|
});
|
|
6948
|
-
const rl = (0,
|
|
7034
|
+
const rl = (0, import_node_readline2.createInterface)({ input: process.stdin, terminal: false });
|
|
6949
7035
|
rl.on("line", (raw) => {
|
|
6950
7036
|
const text = raw.trim();
|
|
6951
7037
|
if (!text) return;
|
|
6952
7038
|
if (!mySubscription) {
|
|
6953
|
-
console.log(`${
|
|
7039
|
+
console.log(`${DIM2}(not subscribed yet \u2014 waiting...)${RESET2}`);
|
|
6954
7040
|
return;
|
|
6955
7041
|
}
|
|
6956
7042
|
if (text === "/q" || text === "/quit") {
|
|
@@ -6960,7 +7046,7 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
6960
7046
|
if (text === "/y" || text === "/yes" || text === "/n" || text === "/no") {
|
|
6961
7047
|
const pending = pendingPerms[pendingPerms.length - 1];
|
|
6962
7048
|
if (!pending) {
|
|
6963
|
-
console.log(`${
|
|
7049
|
+
console.log(`${DIM2}(no pending permission to act on)${RESET2}`);
|
|
6964
7050
|
return;
|
|
6965
7051
|
}
|
|
6966
7052
|
const decision = text === "/y" || text === "/yes" ? "allow" : "deny";
|
|
@@ -6977,7 +7063,7 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
6977
7063
|
if (text === "/m" || text.startsWith("/m ")) {
|
|
6978
7064
|
const opText = text.slice(2).trim();
|
|
6979
7065
|
if (!opText) {
|
|
6980
|
-
console.log(`${
|
|
7066
|
+
console.log(`${DIM2}usage: /m <text> (sends as op-message; bare text is a prompt)${RESET2}`);
|
|
6981
7067
|
return;
|
|
6982
7068
|
}
|
|
6983
7069
|
const out2 = { type: "op_message", sessionId, text: opText };
|
|
@@ -6987,16 +7073,16 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
6987
7073
|
if (text === "/p" || text.startsWith("/p ")) {
|
|
6988
7074
|
const promptText = text.slice(2).trim();
|
|
6989
7075
|
if (!promptText) {
|
|
6990
|
-
console.log(`${
|
|
7076
|
+
console.log(`${DIM2}usage: /p <text> (or just type \u2014 bare text is a prompt now)${RESET2}`);
|
|
6991
7077
|
return;
|
|
6992
7078
|
}
|
|
6993
7079
|
const out2 = { type: "prompt", sessionId, text: promptText };
|
|
6994
7080
|
ws.send(JSON.stringify(out2));
|
|
6995
|
-
console.log(`${
|
|
7081
|
+
console.log(`${DIM2}[${ts()}]${RESET2} ${AMBER}\u2192 prompt sent${RESET2} ${promptText}`);
|
|
6996
7082
|
return;
|
|
6997
7083
|
}
|
|
6998
7084
|
if (text.startsWith("/")) {
|
|
6999
|
-
console.log(`${
|
|
7085
|
+
console.log(`${DIM2}unknown slash-command: ${text} (try /m /y /n /q)${RESET2}`);
|
|
7000
7086
|
return;
|
|
7001
7087
|
}
|
|
7002
7088
|
const xMatch = /^(@[A-Za-z0-9._\-/]+)\s+([\s\S]+)$/.exec(text);
|
|
@@ -7004,7 +7090,7 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
7004
7090
|
const targetRef = xMatch[1];
|
|
7005
7091
|
const promptText = xMatch[2].trim();
|
|
7006
7092
|
if (!promptText) {
|
|
7007
|
-
console.log(`${
|
|
7093
|
+
console.log(`${DIM2}usage: ${targetRef} <prompt>${RESET2}`);
|
|
7008
7094
|
return;
|
|
7009
7095
|
}
|
|
7010
7096
|
(async () => {
|
|
@@ -7028,7 +7114,15 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
7028
7114
|
if (mine.length > 0) candidates = mine;
|
|
7029
7115
|
}
|
|
7030
7116
|
if (candidates.length === 0) {
|
|
7031
|
-
console.error(`${RED}error: no session ${targetRef} (try \`claw session list\` in another terminal)${
|
|
7117
|
+
console.error(`${RED}error: no session ${targetRef} (try \`claw session list\` in another terminal)${RESET2}`);
|
|
7118
|
+
return;
|
|
7119
|
+
}
|
|
7120
|
+
const liveMatches = candidates.filter((c) => c.connected);
|
|
7121
|
+
if (liveMatches.length > 1) {
|
|
7122
|
+
console.error(`${RED}error: '${targetRef}' is ambiguous \u2014 multiple online matches. Use the qualified form:${RESET2}`);
|
|
7123
|
+
for (const c of liveMatches) {
|
|
7124
|
+
console.error(` ${DIM2}${c.id.slice(0, 8)}\u2026${RESET2} @${c.startedByLogin}/${(c.routingName ?? "").replace(/^@/, "")} ${DIM2}${c.cwd ?? ""}${RESET2}`);
|
|
7125
|
+
}
|
|
7032
7126
|
return;
|
|
7033
7127
|
}
|
|
7034
7128
|
const match = candidates[0];
|
|
@@ -7043,16 +7137,16 @@ var sessionAttach = new Command("attach").description("open a TUI on a session \
|
|
|
7043
7137
|
sourceSessionId: sessionId
|
|
7044
7138
|
};
|
|
7045
7139
|
ws.send(JSON.stringify(out2));
|
|
7046
|
-
console.log(`${
|
|
7140
|
+
console.log(`${DIM2}[${ts()}]${RESET2} ${AMBER}\u2192 prompt \u2192 ${targetRef}${RESET2} ${promptText}`);
|
|
7047
7141
|
} catch (e) {
|
|
7048
|
-
console.error(`${RED}error: ${e?.message ?? String(e)}${
|
|
7142
|
+
console.error(`${RED}error: ${e?.message ?? String(e)}${RESET2}`);
|
|
7049
7143
|
}
|
|
7050
7144
|
})();
|
|
7051
7145
|
return;
|
|
7052
7146
|
}
|
|
7053
7147
|
const out = { type: "prompt", sessionId, text };
|
|
7054
7148
|
ws.send(JSON.stringify(out));
|
|
7055
|
-
console.log(`${
|
|
7149
|
+
console.log(`${DIM2}[${ts()}]${RESET2} ${AMBER}\u2192 prompt${RESET2} ${text}`);
|
|
7056
7150
|
});
|
|
7057
7151
|
process.on("SIGINT", () => {
|
|
7058
7152
|
ws.close(1e3, "sigint");
|
|
@@ -7067,26 +7161,26 @@ function printInbound(msg, myLogin) {
|
|
|
7067
7161
|
break;
|
|
7068
7162
|
}
|
|
7069
7163
|
case "op_message": {
|
|
7070
|
-
console.log(`${
|
|
7164
|
+
console.log(`${DIM2}[${shortTs(msg.ts)}]${RESET2} ${GREEN}@${msg.authorLogin}${RESET2} ${msg.text}`);
|
|
7071
7165
|
break;
|
|
7072
7166
|
}
|
|
7073
7167
|
case "permission_request": {
|
|
7074
|
-
console.log(`${RED}[!] ${shortTs(msg.ts)}${
|
|
7168
|
+
console.log(`${RED}[!] ${shortTs(msg.ts)}${RESET2} approval needed: ${BOLD2}${msg.tool}${RESET2} \u2014 ${msg.inputPreview}`);
|
|
7075
7169
|
break;
|
|
7076
7170
|
}
|
|
7077
7171
|
case "permission_resolved": {
|
|
7078
|
-
const dec = msg.decision === "allow" ? `${GREEN}allowed${
|
|
7079
|
-
console.log(`${
|
|
7172
|
+
const dec = msg.decision === "allow" ? `${GREEN}allowed${RESET2}` : msg.decision === "deny" ? `${RED}denied${RESET2}` : `${DIM2}expired${RESET2}`;
|
|
7173
|
+
console.log(`${DIM2}[${ts()}]${RESET2} permission ${msg.requestId} ${dec} by @${msg.resolverLogin ?? "?"}`);
|
|
7080
7174
|
break;
|
|
7081
7175
|
}
|
|
7082
7176
|
case "presence": {
|
|
7083
|
-
console.log(`${
|
|
7177
|
+
console.log(`${DIM2}[${ts()}] presence: ${msg.attached.map((l) => "@" + l).join(", ") || "(empty)"}${RESET2}`);
|
|
7084
7178
|
break;
|
|
7085
7179
|
}
|
|
7086
7180
|
case "ack":
|
|
7087
7181
|
break;
|
|
7088
7182
|
case "error":
|
|
7089
|
-
console.error(`${RED}error (${msg.code}): ${msg.message}${
|
|
7183
|
+
console.error(`${RED}error (${msg.code}): ${msg.message}${RESET2}`);
|
|
7090
7184
|
break;
|
|
7091
7185
|
}
|
|
7092
7186
|
}
|
|
@@ -7109,58 +7203,58 @@ function renderEvent(ev, myLogin) {
|
|
|
7109
7203
|
const text = String(p.text ?? p.prompt ?? "").trim() || JSON.stringify(p).slice(0, 200);
|
|
7110
7204
|
const source = String(p.source ?? "cli");
|
|
7111
7205
|
if (source === "operator" && myLogin && p.authorLogin === myLogin) return;
|
|
7112
|
-
const label = source === "operator" ? `${
|
|
7113
|
-
console.log(`${
|
|
7206
|
+
const label = source === "operator" ? `${BOLD2}@${String(p.authorLogin ?? "remote")} \u203A${RESET2}` : `${BOLD2}(cli) \u203A${RESET2}`;
|
|
7207
|
+
console.log(`${DIM2}[${ts2}]${RESET2} ${label} ${text}`);
|
|
7114
7208
|
return;
|
|
7115
7209
|
}
|
|
7116
7210
|
if (ev.type === "assistant_text") {
|
|
7117
7211
|
const text = String(p.text ?? "").trim();
|
|
7118
7212
|
const isPlaceholder = !!p.placeholder;
|
|
7119
|
-
const tag = isPlaceholder ? `${
|
|
7120
|
-
console.log(`${
|
|
7213
|
+
const tag = isPlaceholder ? `${DIM2}claude \xB7 thinking${RESET2}` : `${AMBER}claude${RESET2}`;
|
|
7214
|
+
console.log(`${DIM2}[${ts2}]${RESET2} ${tag} ${isPlaceholder ? DIM2 + text + RESET2 : text}`);
|
|
7121
7215
|
return;
|
|
7122
7216
|
}
|
|
7123
7217
|
if (ev.type === "reply") {
|
|
7124
7218
|
const text = String(p.text ?? "").trim();
|
|
7125
7219
|
if (p.source === "peer-reply" && p.peerLogin) {
|
|
7126
|
-
console.log(`${
|
|
7220
|
+
console.log(`${DIM2}[${ts2}]${RESET2} ${AMBER}${String(p.peerLogin)} answered${RESET2} ${text}`);
|
|
7127
7221
|
return;
|
|
7128
7222
|
}
|
|
7129
|
-
const tag = p.chatId ? `${AMBER}claude${
|
|
7130
|
-
console.log(`${
|
|
7223
|
+
const tag = p.chatId ? `${AMBER}claude${RESET2} ${DIM2}(reply to ${String(p.chatId).slice(0, 8)})${RESET2}` : `${AMBER}claude${RESET2}`;
|
|
7224
|
+
console.log(`${DIM2}[${ts2}]${RESET2} ${tag} ${text}`);
|
|
7131
7225
|
return;
|
|
7132
7226
|
}
|
|
7133
|
-
console.log(`${
|
|
7227
|
+
console.log(`${DIM2}[${ts2}]${RESET2} ${AMBER}[chat:${ev.type}]${RESET2} ${previewPayload(p)}`);
|
|
7134
7228
|
return;
|
|
7135
7229
|
}
|
|
7136
7230
|
switch (ev.type) {
|
|
7137
7231
|
case "PreToolUse": {
|
|
7138
7232
|
const tool = String(p.tool_name ?? p.toolName ?? p.tool ?? "?");
|
|
7139
7233
|
const input = renderToolInput(p);
|
|
7140
|
-
console.log(`${
|
|
7234
|
+
console.log(`${DIM2}[${ts2}]${RESET2} ${BLUE}\u2192 ${tool}${RESET2} ${DIM2}${input}${RESET2}`);
|
|
7141
7235
|
return;
|
|
7142
7236
|
}
|
|
7143
7237
|
case "PostToolUse": {
|
|
7144
7238
|
const tool = String(p.tool_name ?? p.toolName ?? p.tool ?? "?");
|
|
7145
7239
|
const out = stringifyToolResponse(p.tool_response ?? p.toolResponse ?? p.outputPreview ?? p.output);
|
|
7146
|
-
const ok = p.ok === false ? `${RED}\u2717${
|
|
7147
|
-
console.log(`${
|
|
7240
|
+
const ok = p.ok === false ? `${RED}\u2717${RESET2}` : `${BLUE}\u2713${RESET2}`;
|
|
7241
|
+
console.log(`${DIM2}[${ts2}]${RESET2} ${ok} ${tool}${out ? " " + DIM2 + truncate(out, 200) + RESET2 : ""}`);
|
|
7148
7242
|
return;
|
|
7149
7243
|
}
|
|
7150
7244
|
case "PostToolUseFailure": {
|
|
7151
7245
|
const tool = String(p.tool_name ?? p.toolName ?? p.tool ?? "?");
|
|
7152
7246
|
const err = stringifyToolResponse(p.error ?? p.message ?? p.tool_response);
|
|
7153
|
-
console.log(`${
|
|
7247
|
+
console.log(`${DIM2}[${ts2}]${RESET2} ${RED}\u2717 ${tool}${RESET2} ${RED}${truncate(err, 200)}${RESET2}`);
|
|
7154
7248
|
return;
|
|
7155
7249
|
}
|
|
7156
7250
|
case "Stop":
|
|
7157
|
-
console.log(`${
|
|
7251
|
+
console.log(`${DIM2}[${ts2}] \u2014 turn end \u2014${RESET2}`);
|
|
7158
7252
|
return;
|
|
7159
7253
|
case "SessionStart":
|
|
7160
|
-
console.log(`${
|
|
7254
|
+
console.log(`${DIM2}[${ts2}] \u25B8 session start${RESET2}`);
|
|
7161
7255
|
return;
|
|
7162
7256
|
case "SessionEnd":
|
|
7163
|
-
console.log(`${
|
|
7257
|
+
console.log(`${DIM2}[${ts2}] \u25C2 session end${RESET2}`);
|
|
7164
7258
|
return;
|
|
7165
7259
|
case "TaskCreated":
|
|
7166
7260
|
case "SubagentStart":
|
|
@@ -7168,16 +7262,16 @@ function renderEvent(ev, myLogin) {
|
|
|
7168
7262
|
case "TaskCompleted": {
|
|
7169
7263
|
const which = ev.type;
|
|
7170
7264
|
const desc = String(p.description ?? p.agentType ?? "");
|
|
7171
|
-
console.log(`${
|
|
7265
|
+
console.log(`${DIM2}[${ts2}] ${BLUE}\u21AA ${which}${RESET2}${desc ? " " + desc : ""}`);
|
|
7172
7266
|
return;
|
|
7173
7267
|
}
|
|
7174
7268
|
case "Notification": {
|
|
7175
7269
|
const msg = String(p.message ?? p.text ?? "").trim();
|
|
7176
|
-
console.log(`${
|
|
7270
|
+
console.log(`${DIM2}[${ts2}]${RESET2} ${BOLD2}\u{1F514}${RESET2} ${msg || JSON.stringify(p).slice(0, 200)}`);
|
|
7177
7271
|
return;
|
|
7178
7272
|
}
|
|
7179
7273
|
default:
|
|
7180
|
-
console.log(`${
|
|
7274
|
+
console.log(`${DIM2}[${ts2}]${RESET2} ${BLUE}[${ev.type}]${RESET2} ${previewPayload(p)}`);
|
|
7181
7275
|
}
|
|
7182
7276
|
}
|
|
7183
7277
|
function stringifyToolResponse(v) {
|
|
@@ -7258,7 +7352,20 @@ async function resolveSessionId(idOrName) {
|
|
|
7258
7352
|
err.code = "CLW_NO_ROUTING_MATCH";
|
|
7259
7353
|
throw err;
|
|
7260
7354
|
}
|
|
7261
|
-
|
|
7355
|
+
try {
|
|
7356
|
+
const picked = await pickCandidate(idOrName, candidates);
|
|
7357
|
+
return picked.id;
|
|
7358
|
+
} catch (e) {
|
|
7359
|
+
if (e instanceof AmbiguousError) {
|
|
7360
|
+
const err = new Error(
|
|
7361
|
+
`ambiguous reference '${idOrName}' \u2014 multiple online sessions match. Re-run with a UUID or qualified form. Candidates:
|
|
7362
|
+
` + e.candidates.map((c) => ` ${c.id} @${c.startedByLogin}/${(c.routingName ?? "").replace(/^@/, "")} ${c.cwd ?? ""}`).join("\n")
|
|
7363
|
+
);
|
|
7364
|
+
err.code = "CLW_AMBIGUOUS";
|
|
7365
|
+
throw err;
|
|
7366
|
+
}
|
|
7367
|
+
throw e;
|
|
7368
|
+
}
|
|
7262
7369
|
}
|
|
7263
7370
|
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) => {
|
|
7264
7371
|
const qs = new URLSearchParams();
|
|
@@ -7677,7 +7784,7 @@ var webhookCmd = new Command("webhook").description("manage webhook subscription
|
|
|
7677
7784
|
|
|
7678
7785
|
// src/index.ts
|
|
7679
7786
|
var program2 = new Command();
|
|
7680
|
-
program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.0.
|
|
7787
|
+
program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.0.25");
|
|
7681
7788
|
program2.addCommand(loginCmd);
|
|
7682
7789
|
program2.addCommand(logoutCmd);
|
|
7683
7790
|
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.25",
|
|
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",
|