@lesscap/baton-cli 0.2.0 → 0.2.1
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/baton.mjs +48 -4
- package/package.json +1 -1
package/dist/baton.mjs
CHANGED
|
@@ -578,6 +578,7 @@ var sessionsClient = (baseUrl) => {
|
|
|
578
578
|
resume: (id) => request(u(`/sessions/${id}/resume`), { method: "POST" }),
|
|
579
579
|
stop: (id) => request(u(`/sessions/${id}/stop`), { method: "POST" }),
|
|
580
580
|
clear: (id) => request(u(`/sessions/${id}/clear`), { method: "POST" }),
|
|
581
|
+
abort: (id) => request(u(`/sessions/${id}/abort`), { method: "POST" }),
|
|
581
582
|
rename: (id, name) => request(u(`/sessions/${id}/rename`), { method: "POST", body: { name } }),
|
|
582
583
|
listByProject: (projectId) => request(u(`/projects/${projectId}/sessions`), { method: "GET" }),
|
|
583
584
|
get: (id) => request(u(`/sessions/${id}`), { method: "GET" }),
|
|
@@ -1035,6 +1036,22 @@ var resolveSession = async (client, projectId, handle) => {
|
|
|
1035
1036
|
throw new Error(`session "${handle}" not found in project ${projectId}`);
|
|
1036
1037
|
};
|
|
1037
1038
|
|
|
1039
|
+
// src/commands/session/abort.ts
|
|
1040
|
+
var sessionAbortCommand = defineCommand({
|
|
1041
|
+
meta: { name: "abort", description: "interrupt the in-flight turn (like Esc); keeps the session" },
|
|
1042
|
+
args: {
|
|
1043
|
+
session: { type: "positional", required: true, description: "session int id or name" },
|
|
1044
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
1045
|
+
...common
|
|
1046
|
+
},
|
|
1047
|
+
run: async ({ args }) => {
|
|
1048
|
+
const c = clientFor(args);
|
|
1049
|
+
const handle = await resolveSession(c, resolveProjectId(args), args.session);
|
|
1050
|
+
const s = await c.sessions.abort(handle.id);
|
|
1051
|
+
console.log(renderOne(s, fmtSession, Boolean(args.json)));
|
|
1052
|
+
}
|
|
1053
|
+
});
|
|
1054
|
+
|
|
1038
1055
|
// src/commands/session/clear.ts
|
|
1039
1056
|
var sessionClearCommand = defineCommand({
|
|
1040
1057
|
meta: { name: "clear", description: "reset the conversation context (keeps the session + worktree)" },
|
|
@@ -1807,6 +1824,7 @@ var toTurnResult = (message) => {
|
|
|
1807
1824
|
// src/session/runner/turn.ts
|
|
1808
1825
|
var turnTimeoutMs = () => Number(process.env.BATON_TURN_TIMEOUT_MS) || 30 * 6e4;
|
|
1809
1826
|
var TIMEOUT = /* @__PURE__ */ Symbol("turn-timeout");
|
|
1827
|
+
var ABORTED = /* @__PURE__ */ Symbol("turn-aborted");
|
|
1810
1828
|
var finalizeTurn = async (result, worker2, log) => {
|
|
1811
1829
|
if (!result) {
|
|
1812
1830
|
log("[exit] stream ended with no result");
|
|
@@ -1835,7 +1853,7 @@ var buildPrompt = async (config, rawText, attachments, log, fetchImpl) => {
|
|
|
1835
1853
|
log(`[attach] downloaded ${relPaths.length} file(s) \u2192 ${config.worktreePath}/attachments`);
|
|
1836
1854
|
return augmentPrompt(rawText, relPaths, labelAttachments(attachments));
|
|
1837
1855
|
};
|
|
1838
|
-
var runTurn = async (config, worker2, msg, resuming, queryFn, log = (m) => console.log(m), envOverlay, fetchImpl) => {
|
|
1856
|
+
var runTurn = async (config, worker2, msg, resuming, queryFn, log = (m) => console.log(m), envOverlay, fetchImpl, externalSignal) => {
|
|
1839
1857
|
await worker2.emitEvent("turn_start", { messageId: msg.id });
|
|
1840
1858
|
const payload = msg.payload;
|
|
1841
1859
|
const rawText = typeof payload?.text === "string" ? payload.text : "";
|
|
@@ -1858,12 +1876,23 @@ var runTurn = async (config, worker2, msg, resuming, queryFn, log = (m) => conso
|
|
|
1858
1876
|
const timeout = new Promise((resolve) => {
|
|
1859
1877
|
timer = setTimeout(() => resolve(TIMEOUT), ceiling);
|
|
1860
1878
|
});
|
|
1879
|
+
const interrupted = new Promise((resolve) => {
|
|
1880
|
+
if (externalSignal?.aborted) resolve(ABORTED);
|
|
1881
|
+
else externalSignal?.addEventListener("abort", () => resolve(ABORTED), { once: true });
|
|
1882
|
+
});
|
|
1861
1883
|
try {
|
|
1862
1884
|
const messages = startQuery(config, text, resuming, queryFn, abort, log, envOverlay);
|
|
1863
1885
|
const consume = streamSdkEvents(messages, worker2);
|
|
1864
1886
|
void consume.catch(() => {
|
|
1865
1887
|
});
|
|
1866
|
-
const outcome = await Promise.race([consume, timeout]);
|
|
1888
|
+
const outcome = await Promise.race([consume, timeout, interrupted]);
|
|
1889
|
+
if (outcome === ABORTED) {
|
|
1890
|
+
log("[abort] interrupted by user");
|
|
1891
|
+
abort.abort();
|
|
1892
|
+
await worker2.emitEvent("turn_error", { message: "interrupted by user" });
|
|
1893
|
+
await worker2.emitEvent("turn_complete", {});
|
|
1894
|
+
return -1;
|
|
1895
|
+
}
|
|
1867
1896
|
if (outcome === TIMEOUT) {
|
|
1868
1897
|
log(`[watchdog] turn exceeded ${ceiling}ms \u2014 aborting claude`);
|
|
1869
1898
|
abort.abort();
|
|
@@ -1884,7 +1913,7 @@ var runTurn = async (config, worker2, msg, resuming, queryFn, log = (m) => conso
|
|
|
1884
1913
|
};
|
|
1885
1914
|
|
|
1886
1915
|
// src/session/runner.ts
|
|
1887
|
-
var subscribeStream = (url, ESCtor, seen, log, onUserMessage, onReady) => {
|
|
1916
|
+
var subscribeStream = (url, ESCtor, seen, log, onUserMessage, onInterrupt, onReady) => {
|
|
1888
1917
|
const es = new ESCtor(url);
|
|
1889
1918
|
es.onopen = onReady;
|
|
1890
1919
|
es.onmessage = (e) => {
|
|
@@ -1893,6 +1922,8 @@ var subscribeStream = (url, ESCtor, seen, log, onUserMessage, onReady) => {
|
|
|
1893
1922
|
if (seen.has(ev.sequence)) return;
|
|
1894
1923
|
seen.add(ev.sequence);
|
|
1895
1924
|
if (ev.type === "user_message") onUserMessage(ev);
|
|
1925
|
+
else if (ev.type === "system" && ev.payload?.action === "interrupt")
|
|
1926
|
+
onInterrupt();
|
|
1896
1927
|
} catch {
|
|
1897
1928
|
}
|
|
1898
1929
|
};
|
|
@@ -1925,6 +1956,7 @@ var runDaemon = async (config, deps, signal) => {
|
|
|
1925
1956
|
const pendingQueue = [];
|
|
1926
1957
|
let busy = false;
|
|
1927
1958
|
let lastActivity = Date.now();
|
|
1959
|
+
let currentTurn;
|
|
1928
1960
|
const drain = async () => {
|
|
1929
1961
|
if (busy) return;
|
|
1930
1962
|
busy = true;
|
|
@@ -1934,6 +1966,8 @@ var runDaemon = async (config, deps, signal) => {
|
|
|
1934
1966
|
if (!msg) break;
|
|
1935
1967
|
const resuming = state.firstSpawnDone;
|
|
1936
1968
|
log(`\u25B6 msg #${msg.sequence} (${resuming ? "resume" : "first"})`);
|
|
1969
|
+
const turnAbort = new AbortController();
|
|
1970
|
+
currentTurn = turnAbort;
|
|
1937
1971
|
const code = await runTurn(
|
|
1938
1972
|
config,
|
|
1939
1973
|
deps.worker,
|
|
@@ -1942,8 +1976,10 @@ var runDaemon = async (config, deps, signal) => {
|
|
|
1942
1976
|
qf,
|
|
1943
1977
|
log,
|
|
1944
1978
|
deps.env,
|
|
1945
|
-
deps.fetchImpl
|
|
1979
|
+
deps.fetchImpl,
|
|
1980
|
+
turnAbort.signal
|
|
1946
1981
|
);
|
|
1982
|
+
currentTurn = void 0;
|
|
1947
1983
|
state.firstSpawnDone = true;
|
|
1948
1984
|
lastActivity = Date.now();
|
|
1949
1985
|
log(`\u2714 msg #${msg.sequence}${code === 0 ? "" : ` (exit ${code})`}`);
|
|
@@ -1964,6 +2000,13 @@ var runDaemon = async (config, deps, signal) => {
|
|
|
1964
2000
|
pendingQueue.push(ev);
|
|
1965
2001
|
void drain();
|
|
1966
2002
|
},
|
|
2003
|
+
() => {
|
|
2004
|
+
lastActivity = Date.now();
|
|
2005
|
+
if (currentTurn) {
|
|
2006
|
+
log("interrupt \u2014 aborting current turn");
|
|
2007
|
+
currentTurn.abort();
|
|
2008
|
+
}
|
|
2009
|
+
},
|
|
1967
2010
|
// Report active only now that we're subscribed — before this, a message
|
|
1968
2011
|
// sent right after spawn would be missed (no replay on the live stream).
|
|
1969
2012
|
() => {
|
|
@@ -2144,6 +2187,7 @@ var session = defineCommand({
|
|
|
2144
2187
|
resume: sessionResumeCommand,
|
|
2145
2188
|
stop: sessionStopCommand,
|
|
2146
2189
|
clear: sessionClearCommand,
|
|
2190
|
+
abort: sessionAbortCommand,
|
|
2147
2191
|
rename: sessionRenameCommand,
|
|
2148
2192
|
rm: sessionRmCommand,
|
|
2149
2193
|
send: sessionSendCommand,
|