@buildautomaton/cli 0.1.72 → 0.1.74
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/cli.js +237 -118
- package/dist/cli.js.map +4 -4
- package/dist/index.js +237 -118
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -11850,8 +11850,8 @@ var init_task_queue_types = __esm({
|
|
|
11850
11850
|
});
|
|
11851
11851
|
|
|
11852
11852
|
// src/code-nav/symbol-index/scheduler/task-queue-store.ts
|
|
11853
|
-
function setSymbolIndexWorkerRunning(
|
|
11854
|
-
symbolIndexWorkerRunning =
|
|
11853
|
+
function setSymbolIndexWorkerRunning(running2) {
|
|
11854
|
+
symbolIndexWorkerRunning = running2;
|
|
11855
11855
|
}
|
|
11856
11856
|
function taskMatchesCurrentPending(task) {
|
|
11857
11857
|
const current = pendingSymbolIndexTasks.get(symbolIndexTaskKey(task.parentPath, task.filePath));
|
|
@@ -31064,7 +31064,7 @@ var {
|
|
|
31064
31064
|
} = import_index.default;
|
|
31065
31065
|
|
|
31066
31066
|
// src/cli-version.ts
|
|
31067
|
-
var CLI_VERSION = "0.1.
|
|
31067
|
+
var CLI_VERSION = "0.1.74".length > 0 ? "0.1.74" : "0.0.0-dev";
|
|
31068
31068
|
|
|
31069
31069
|
// src/cli/defaults.ts
|
|
31070
31070
|
var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
|
|
@@ -35985,12 +35985,32 @@ function attachSdkStdioStderrAuthWatch(options) {
|
|
|
35985
35985
|
|
|
35986
35986
|
// src/agents/acp/clients/sdk/spawn-sdk-stdio-process.ts
|
|
35987
35987
|
import { spawn } from "node:child_process";
|
|
35988
|
+
|
|
35989
|
+
// src/agents/acp/clients/bridge-installed-agent-auth-env.ts
|
|
35990
|
+
var authEnv = /* @__PURE__ */ new Map();
|
|
35991
|
+
function setBridgeInstalledAgentAuthEnv(entries) {
|
|
35992
|
+
authEnv.clear();
|
|
35993
|
+
for (const entry of entries) {
|
|
35994
|
+
const envVar = typeof entry.envVar === "string" ? entry.envVar.trim() : "";
|
|
35995
|
+
const token = typeof entry.token === "string" ? entry.token.trim() : "";
|
|
35996
|
+
if (envVar && token) authEnv.set(envVar, token);
|
|
35997
|
+
}
|
|
35998
|
+
}
|
|
35999
|
+
function bridgeInstalledAgentAuthProcessEnv(base = process.env) {
|
|
36000
|
+
if (authEnv.size === 0) return base;
|
|
36001
|
+
return { ...base, ...Object.fromEntries(authEnv) };
|
|
36002
|
+
}
|
|
36003
|
+
function cursorAgentUsesApiKeyAuth(env = process.env) {
|
|
36004
|
+
return Boolean(env.CURSOR_API_KEY?.trim() || env.CURSOR_AUTH_TOKEN?.trim());
|
|
36005
|
+
}
|
|
36006
|
+
|
|
36007
|
+
// src/agents/acp/clients/sdk/spawn-sdk-stdio-process.ts
|
|
35988
36008
|
function spawnSdkStdioProcess(options) {
|
|
35989
36009
|
const isWindows = process.platform === "win32";
|
|
35990
36010
|
const child = spawn(options.command[0], options.command.slice(1), {
|
|
35991
36011
|
cwd: options.cwd,
|
|
35992
36012
|
stdio: ["pipe", "pipe", "pipe"],
|
|
35993
|
-
env: process.env,
|
|
36013
|
+
env: bridgeInstalledAgentAuthProcessEnv(process.env),
|
|
35994
36014
|
shell: isWindows
|
|
35995
36015
|
});
|
|
35996
36016
|
const stderrCapture = createStderrCapture(child);
|
|
@@ -36450,10 +36470,11 @@ function createCursorAcpIncomingLineHandler(deps) {
|
|
|
36450
36470
|
|
|
36451
36471
|
// src/agents/acp/clients/cursor/cursor-json-rpc-acp-transport.ts
|
|
36452
36472
|
function createCursorJsonRpcAcpTransport(deps) {
|
|
36453
|
-
const { send, cancelSessionNotification } = deps;
|
|
36473
|
+
const { send, cancelSessionNotification, skipBrowserAuthenticate } = deps;
|
|
36454
36474
|
return {
|
|
36455
36475
|
initialize: (request) => send("initialize", request),
|
|
36456
36476
|
afterInitialize: async () => {
|
|
36477
|
+
if (skipBrowserAuthenticate) return;
|
|
36457
36478
|
await send("authenticate", { methodId: "cursor_login" });
|
|
36458
36479
|
},
|
|
36459
36480
|
resumeSession: (p) => send("session/resume", p),
|
|
@@ -36562,7 +36583,8 @@ async function initCursorAcpWire(options) {
|
|
|
36562
36583
|
rl.on("line", (line) => incoming.handleLine(line));
|
|
36563
36584
|
const transport = createCursorJsonRpcAcpTransport({
|
|
36564
36585
|
send: wire.send,
|
|
36565
|
-
cancelSessionNotification: wire.cancelSessionNotification
|
|
36586
|
+
cancelSessionNotification: wire.cancelSessionNotification,
|
|
36587
|
+
skipBrowserAuthenticate: options.skipBrowserAuthenticate
|
|
36566
36588
|
});
|
|
36567
36589
|
const established = await bootstrapAcpWireSession(transport, options.sessionCtx, CURSOR_ACP_CLIENT_INFO);
|
|
36568
36590
|
return { wire, transport, established, incoming, pendingRequests: pendingRequests2 };
|
|
@@ -36575,7 +36597,7 @@ function spawnCursorAcpProcess(options) {
|
|
|
36575
36597
|
const child = spawn2(options.command[0], options.command.slice(1), {
|
|
36576
36598
|
cwd: options.cwd,
|
|
36577
36599
|
stdio: ["pipe", "pipe", "pipe"],
|
|
36578
|
-
env: process.env,
|
|
36600
|
+
env: bridgeInstalledAgentAuthProcessEnv(process.env),
|
|
36579
36601
|
shell: isWindows
|
|
36580
36602
|
});
|
|
36581
36603
|
const stderrCapture = createStderrCapture(child);
|
|
@@ -36607,11 +36629,13 @@ async function createCursorAcpClient(options) {
|
|
|
36607
36629
|
onAgentSubprocessExit
|
|
36608
36630
|
} = options;
|
|
36609
36631
|
const dbgFs = process.env.BUILDAUTOMATON_DEBUG_ACP_FS === "1";
|
|
36632
|
+
const spawnEnv = bridgeInstalledAgentAuthProcessEnv(process.env);
|
|
36610
36633
|
const { child, stderrCapture } = spawnCursorAcpProcess({
|
|
36611
36634
|
command,
|
|
36612
36635
|
cwd,
|
|
36613
36636
|
onAgentSubprocessExit
|
|
36614
36637
|
});
|
|
36638
|
+
const skipBrowserAuthenticate = cursorAgentUsesApiKeyAuth(spawnEnv);
|
|
36615
36639
|
const sessionCtx = createCursorAcpSessionContext({
|
|
36616
36640
|
cwd,
|
|
36617
36641
|
mcpServers: options.mcpServers,
|
|
@@ -36634,6 +36658,7 @@ async function createCursorAcpClient(options) {
|
|
|
36634
36658
|
const { wire, transport, established, incoming, pendingRequests: pendingRequests2 } = await initCursorAcpWire({
|
|
36635
36659
|
child,
|
|
36636
36660
|
sessionCtx,
|
|
36661
|
+
skipBrowserAuthenticate,
|
|
36637
36662
|
incomingDeps: { dbgFs, sessionCtx, onSessionUpdate, onRequest }
|
|
36638
36663
|
});
|
|
36639
36664
|
resolve37(
|
|
@@ -37480,6 +37505,7 @@ function extractSessionUpdateMessageText(params) {
|
|
|
37480
37505
|
}
|
|
37481
37506
|
|
|
37482
37507
|
// src/agents/planning/planning-session-turn-buffer.ts
|
|
37508
|
+
var MAX_PLANNING_BUFFER_CHARS = 512 * 1024;
|
|
37483
37509
|
var buffersByRunId = /* @__PURE__ */ new Map();
|
|
37484
37510
|
function registerPlanningSessionTurn(runId) {
|
|
37485
37511
|
buffersByRunId.set(runId, { messageBuffer: "" });
|
|
@@ -37497,7 +37523,10 @@ function capturePlanningSessionUpdate(params) {
|
|
|
37497
37523
|
});
|
|
37498
37524
|
if (bucket !== "message") return false;
|
|
37499
37525
|
const text = extractSessionUpdateMessageText(params.payload);
|
|
37500
|
-
if (text
|
|
37526
|
+
if (text && state.messageBuffer.length < MAX_PLANNING_BUFFER_CHARS) {
|
|
37527
|
+
const room = MAX_PLANNING_BUFFER_CHARS - state.messageBuffer.length;
|
|
37528
|
+
state.messageBuffer += room >= text.length ? text : text.slice(0, room);
|
|
37529
|
+
}
|
|
37501
37530
|
return true;
|
|
37502
37531
|
}
|
|
37503
37532
|
function getPlanningSessionTurnOutput(runId) {
|
|
@@ -39391,11 +39420,30 @@ function closeHttpServer(server) {
|
|
|
39391
39420
|
}
|
|
39392
39421
|
|
|
39393
39422
|
// src/mcp/bridge-access/read-json-body.ts
|
|
39423
|
+
var MAX_JSON_BODY_BYTES = 1024 * 1024;
|
|
39424
|
+
var RequestBodyTooLargeError = class extends Error {
|
|
39425
|
+
constructor() {
|
|
39426
|
+
super(`Request body exceeds ${MAX_JSON_BODY_BYTES} bytes`);
|
|
39427
|
+
}
|
|
39428
|
+
};
|
|
39394
39429
|
function readJsonBody(req) {
|
|
39395
39430
|
return new Promise((resolve37, reject) => {
|
|
39396
39431
|
const chunks = [];
|
|
39397
|
-
|
|
39432
|
+
let total = 0;
|
|
39433
|
+
let tooLarge = false;
|
|
39434
|
+
req.on("data", (chunk) => {
|
|
39435
|
+
if (tooLarge) return;
|
|
39436
|
+
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
39437
|
+
total += buf.length;
|
|
39438
|
+
if (total > MAX_JSON_BODY_BYTES) {
|
|
39439
|
+
tooLarge = true;
|
|
39440
|
+
reject(new RequestBodyTooLargeError());
|
|
39441
|
+
return;
|
|
39442
|
+
}
|
|
39443
|
+
chunks.push(buf);
|
|
39444
|
+
});
|
|
39398
39445
|
req.on("end", () => {
|
|
39446
|
+
if (tooLarge) return;
|
|
39399
39447
|
try {
|
|
39400
39448
|
const raw = Buffer.concat(chunks).toString("utf8").trim();
|
|
39401
39449
|
if (!raw) {
|
|
@@ -39452,7 +39500,7 @@ function createBridgeAccessRequestHandler(registry2) {
|
|
|
39452
39500
|
sendJsonResponse(res, 404, { ok: false, error: "Not found" });
|
|
39453
39501
|
} catch (err) {
|
|
39454
39502
|
const message = err instanceof Error ? err.message : String(err);
|
|
39455
|
-
sendJsonResponse(res, 500, { ok: false, error: message });
|
|
39503
|
+
sendJsonResponse(res, err instanceof RequestBodyTooLargeError ? 413 : 500, { ok: false, error: message });
|
|
39456
39504
|
}
|
|
39457
39505
|
})();
|
|
39458
39506
|
};
|
|
@@ -49962,7 +50010,7 @@ init_yield_to_event_loop();
|
|
|
49962
50010
|
|
|
49963
50011
|
// src/files/read/types.ts
|
|
49964
50012
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
49965
|
-
var READ_RANGE_YIELD_EVERY_BYTES =
|
|
50013
|
+
var READ_RANGE_YIELD_EVERY_BYTES = 64 * 1024;
|
|
49966
50014
|
|
|
49967
50015
|
// src/files/read/guess-mime-type.ts
|
|
49968
50016
|
var MIME_BY_EXT = {
|
|
@@ -51554,6 +51602,7 @@ function buildBridgeUrl(apiUrl, workspaceId, authToken) {
|
|
|
51554
51602
|
var API_TO_BRIDGE_MESSAGE_TYPES = [
|
|
51555
51603
|
"auth_token",
|
|
51556
51604
|
"bridge_identified",
|
|
51605
|
+
"installed_agent_auth_sync",
|
|
51557
51606
|
"ha",
|
|
51558
51607
|
"preview_environments_config",
|
|
51559
51608
|
"preview_environment_control",
|
|
@@ -51642,6 +51691,16 @@ var handleBridgeIdentified = (msg, deps) => {
|
|
|
51642
51691
|
});
|
|
51643
51692
|
};
|
|
51644
51693
|
|
|
51694
|
+
// src/routing/handlers/installed-agent-auth-sync.ts
|
|
51695
|
+
var handleInstalledAgentAuthSync = (msg) => {
|
|
51696
|
+
const entries = Array.isArray(msg.entries) ? msg.entries : [];
|
|
51697
|
+
setBridgeInstalledAgentAuthEnv(
|
|
51698
|
+
entries.filter(
|
|
51699
|
+
(e) => e != null && typeof e === "object" && typeof e.envVar === "string" && typeof e.token === "string"
|
|
51700
|
+
)
|
|
51701
|
+
);
|
|
51702
|
+
};
|
|
51703
|
+
|
|
51645
51704
|
// src/connection/heartbeat/ack.ts
|
|
51646
51705
|
var handleBridgeHeartbeatAck = (msg, deps) => {
|
|
51647
51706
|
const raw = msg.s;
|
|
@@ -51658,6 +51717,9 @@ function dispatchBridgeConnectionMessage(msg, deps) {
|
|
|
51658
51717
|
case "bridge_identified":
|
|
51659
51718
|
handleBridgeIdentified(msg, deps);
|
|
51660
51719
|
break;
|
|
51720
|
+
case "installed_agent_auth_sync":
|
|
51721
|
+
handleInstalledAgentAuthSync(msg, deps);
|
|
51722
|
+
break;
|
|
51661
51723
|
case "ha":
|
|
51662
51724
|
handleBridgeHeartbeatAck(msg, deps);
|
|
51663
51725
|
break;
|
|
@@ -51754,16 +51816,8 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
51754
51816
|
handleBridgeAgentConfig(msg, deps);
|
|
51755
51817
|
};
|
|
51756
51818
|
|
|
51757
|
-
// src/prompt-turn-queue/
|
|
51758
|
-
|
|
51759
|
-
if (!ws) return false;
|
|
51760
|
-
const wireQueues = {};
|
|
51761
|
-
for (const [queueKey, rows] of Object.entries(queues)) {
|
|
51762
|
-
wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
|
|
51763
|
-
}
|
|
51764
|
-
sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
|
|
51765
|
-
return true;
|
|
51766
|
-
}
|
|
51819
|
+
// src/prompt-turn-queue/runner/dispatch-started-prompt-queue-runs.ts
|
|
51820
|
+
init_yield_to_event_loop();
|
|
51767
51821
|
|
|
51768
51822
|
// src/prompt-turn-queue/disk-store.ts
|
|
51769
51823
|
init_cli_database();
|
|
@@ -51855,23 +51909,6 @@ function dispatchLocalPrompt(next, deps) {
|
|
|
51855
51909
|
handleBridgePrompt(msg, deps);
|
|
51856
51910
|
}
|
|
51857
51911
|
|
|
51858
|
-
// src/prompt-turn-queue/runner/queue-selection.ts
|
|
51859
|
-
function pickNextRunnableTurn(turns) {
|
|
51860
|
-
for (const t of turns) {
|
|
51861
|
-
if (t.bridgeServerState === "discarded" || t.bridgeServerState === "stopping") continue;
|
|
51862
|
-
if (t.bridgeServerState === "cancel_requested") continue;
|
|
51863
|
-
if (!isRunnableBridgePromptTurnServerState(t.bridgeServerState)) continue;
|
|
51864
|
-
if (t.lastCliState === "running" || t.lastCliState === "stopped" || t.lastCliState === "failed" || t.lastCliState === "cancelled") {
|
|
51865
|
-
continue;
|
|
51866
|
-
}
|
|
51867
|
-
return t;
|
|
51868
|
-
}
|
|
51869
|
-
return null;
|
|
51870
|
-
}
|
|
51871
|
-
function hasRunningTurn(turns) {
|
|
51872
|
-
return turns.some((t) => t.lastCliState === "running");
|
|
51873
|
-
}
|
|
51874
|
-
|
|
51875
51912
|
// src/prompt-turn-queue/runner/run-id-queue-key-map.ts
|
|
51876
51913
|
var runIdToQueueKey = /* @__PURE__ */ new Map();
|
|
51877
51914
|
function getRunIdQueueKey(runId) {
|
|
@@ -51886,11 +51923,123 @@ function deleteRunIdQueueKey(runId) {
|
|
|
51886
51923
|
return queueKey;
|
|
51887
51924
|
}
|
|
51888
51925
|
function syncRunningTurnQueueKeys(turns, queueKey) {
|
|
51889
|
-
for (const
|
|
51890
|
-
runIdToQueueKey.set(
|
|
51926
|
+
for (const running2 of turns.filter((t) => t.lastCliState === "running")) {
|
|
51927
|
+
runIdToQueueKey.set(running2.turnId, queueKey);
|
|
51928
|
+
}
|
|
51929
|
+
}
|
|
51930
|
+
|
|
51931
|
+
// src/prompt-turn-queue/runner/dispatch-started-prompt-queue-runs.ts
|
|
51932
|
+
async function dispatchStartedPromptQueueRuns(entries, started, deps) {
|
|
51933
|
+
for (const [queueKey] of entries) {
|
|
51934
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
51935
|
+
const running2 = file2?.turns.find((turn) => turn.lastCliState === "running");
|
|
51936
|
+
if (running2 && started.has(running2.turnId) && getRunIdQueueKey(running2.turnId) === queueKey) {
|
|
51937
|
+
dispatchLocalPrompt(running2, deps);
|
|
51938
|
+
}
|
|
51939
|
+
await yieldToEventLoop();
|
|
51940
|
+
}
|
|
51941
|
+
}
|
|
51942
|
+
|
|
51943
|
+
// src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
|
|
51944
|
+
init_yield_to_event_loop();
|
|
51945
|
+
|
|
51946
|
+
// src/prompt-turn-queue/client-report.ts
|
|
51947
|
+
function sendPromptQueueClientReport(ws, queues) {
|
|
51948
|
+
if (!ws) return false;
|
|
51949
|
+
const wireQueues = {};
|
|
51950
|
+
for (const [queueKey, rows] of Object.entries(queues)) {
|
|
51951
|
+
wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
|
|
51952
|
+
}
|
|
51953
|
+
sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
|
|
51954
|
+
return true;
|
|
51955
|
+
}
|
|
51956
|
+
|
|
51957
|
+
// src/prompt-turn-queue/runner/finalize-prompt-turn-on-bridge.ts
|
|
51958
|
+
async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
|
|
51959
|
+
if (!runId) return false;
|
|
51960
|
+
const queueKey = deleteRunIdQueueKey(runId);
|
|
51961
|
+
if (!queueKey) return false;
|
|
51962
|
+
const f = await readPersistedQueue(queueKey);
|
|
51963
|
+
if (!f) return false;
|
|
51964
|
+
const t = f.turns.find((x) => x.turnId === runId);
|
|
51965
|
+
if (!t) return false;
|
|
51966
|
+
t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
|
|
51967
|
+
await writePersistedQueue(f);
|
|
51968
|
+
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
|
|
51969
|
+
return true;
|
|
51970
|
+
}
|
|
51971
|
+
|
|
51972
|
+
// src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
|
|
51973
|
+
async function handlePromptQueueCancellations(entries, deps) {
|
|
51974
|
+
for (const [queueKey] of entries) {
|
|
51975
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
51976
|
+
const turn = file2?.turns.find((row) => row.bridgeServerState === "cancel_requested" && row.lastCliState === "running");
|
|
51977
|
+
if (!turn) {
|
|
51978
|
+
await yieldToEventLoop();
|
|
51979
|
+
continue;
|
|
51980
|
+
}
|
|
51981
|
+
deps.log(`[Queue] Cancellation request received for turn ${turn.turnId.slice(0, 8)}\u2026`);
|
|
51982
|
+
if (await deps.acpManager.cancelRun(turn.turnId)) {
|
|
51983
|
+
await yieldToEventLoop();
|
|
51984
|
+
continue;
|
|
51985
|
+
}
|
|
51986
|
+
deps.log(`[Queue] cancel_requested for ${turn.turnId.slice(0, 8)}\u2026 with no local run; marking cancelled.`);
|
|
51987
|
+
await finalizePromptTurnOnBridge(deps.getWs, turn.turnId, false, { terminalCliState: "cancelled" });
|
|
51988
|
+
const ws = deps.getWs();
|
|
51989
|
+
if (ws && turn.sessionId) {
|
|
51990
|
+
sendWsMessage(ws, {
|
|
51991
|
+
type: "prompt_result",
|
|
51992
|
+
sessionId: turn.sessionId,
|
|
51993
|
+
runId: turn.turnId,
|
|
51994
|
+
success: false,
|
|
51995
|
+
error: "Stopped by user",
|
|
51996
|
+
stopReason: "cancelled"
|
|
51997
|
+
});
|
|
51998
|
+
}
|
|
51999
|
+
await yieldToEventLoop();
|
|
51891
52000
|
}
|
|
51892
52001
|
}
|
|
51893
52002
|
|
|
52003
|
+
// src/prompt-turn-queue/runner/persist-prompt-queue-snapshot.ts
|
|
52004
|
+
init_yield_to_event_loop();
|
|
52005
|
+
async function persistPromptQueueSnapshot(entries) {
|
|
52006
|
+
for (const [queueKey, serverTurns] of entries) {
|
|
52007
|
+
const file2 = await mergeBridgeServerQueueSnapshot(queueKey, serverTurns);
|
|
52008
|
+
await writePersistedQueue(file2);
|
|
52009
|
+
await yieldToEventLoop();
|
|
52010
|
+
}
|
|
52011
|
+
for (const [queueKey] of entries) {
|
|
52012
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
52013
|
+
if (file2) syncRunningTurnQueueKeys(file2.turns, queueKey);
|
|
52014
|
+
await yieldToEventLoop();
|
|
52015
|
+
}
|
|
52016
|
+
}
|
|
52017
|
+
|
|
52018
|
+
// src/prompt-turn-queue/runner/prompt-queue-snapshot-types.ts
|
|
52019
|
+
function promptQueueSnapshotEntries(queues) {
|
|
52020
|
+
return Object.entries(queues).filter((entry) => Array.isArray(entry[1]));
|
|
52021
|
+
}
|
|
52022
|
+
|
|
52023
|
+
// src/prompt-turn-queue/runner/start-prompt-queue-runs.ts
|
|
52024
|
+
init_yield_to_event_loop();
|
|
52025
|
+
|
|
52026
|
+
// src/prompt-turn-queue/runner/queue-selection.ts
|
|
52027
|
+
function pickNextRunnableTurn(turns) {
|
|
52028
|
+
for (const t of turns) {
|
|
52029
|
+
if (t.bridgeServerState === "discarded" || t.bridgeServerState === "stopping") continue;
|
|
52030
|
+
if (t.bridgeServerState === "cancel_requested") continue;
|
|
52031
|
+
if (!isRunnableBridgePromptTurnServerState(t.bridgeServerState)) continue;
|
|
52032
|
+
if (t.lastCliState === "running" || t.lastCliState === "stopped" || t.lastCliState === "failed" || t.lastCliState === "cancelled") {
|
|
52033
|
+
continue;
|
|
52034
|
+
}
|
|
52035
|
+
return t;
|
|
52036
|
+
}
|
|
52037
|
+
return null;
|
|
52038
|
+
}
|
|
52039
|
+
function hasRunningTurn(turns) {
|
|
52040
|
+
return turns.some((t) => t.lastCliState === "running");
|
|
52041
|
+
}
|
|
52042
|
+
|
|
51894
52043
|
// src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
|
|
51895
52044
|
import fs59 from "node:fs";
|
|
51896
52045
|
|
|
@@ -52008,96 +52157,41 @@ async function runLocalRevertBeforeQueuedPrompt(next, deps) {
|
|
|
52008
52157
|
return res.ok;
|
|
52009
52158
|
}
|
|
52010
52159
|
|
|
52011
|
-
// src/prompt-turn-queue/runner/
|
|
52012
|
-
async function
|
|
52013
|
-
if (!runId) return false;
|
|
52014
|
-
const queueKey = deleteRunIdQueueKey(runId);
|
|
52015
|
-
if (!queueKey) return false;
|
|
52016
|
-
const f = await readPersistedQueue(queueKey);
|
|
52017
|
-
if (!f) return false;
|
|
52018
|
-
const t = f.turns.find((x) => x.turnId === runId);
|
|
52019
|
-
if (!t) return false;
|
|
52020
|
-
t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
|
|
52021
|
-
await writePersistedQueue(f);
|
|
52022
|
-
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
|
|
52023
|
-
return true;
|
|
52024
|
-
}
|
|
52025
|
-
|
|
52026
|
-
// src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
|
|
52027
|
-
async function applyPromptQueueStateFromServer(msg, deps) {
|
|
52028
|
-
const raw = msg.queues;
|
|
52029
|
-
if (!raw || typeof raw !== "object") return;
|
|
52030
|
-
const getWs = deps.getWs;
|
|
52031
|
-
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
52032
|
-
if (!Array.isArray(serverTurns)) continue;
|
|
52033
|
-
const file2 = await mergeBridgeServerQueueSnapshot(queueKey, serverTurns);
|
|
52034
|
-
await writePersistedQueue(file2);
|
|
52035
|
-
}
|
|
52036
|
-
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
52037
|
-
if (!Array.isArray(serverTurns)) continue;
|
|
52038
|
-
const file2 = await readPersistedQueue(queueKey);
|
|
52039
|
-
if (!file2) continue;
|
|
52040
|
-
syncRunningTurnQueueKeys(file2.turns, queueKey);
|
|
52041
|
-
}
|
|
52042
|
-
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
52043
|
-
if (!Array.isArray(serverTurns)) continue;
|
|
52044
|
-
const file2 = await readPersistedQueue(queueKey);
|
|
52045
|
-
if (!file2) continue;
|
|
52046
|
-
const cancelRow = file2.turns.find((t) => t.bridgeServerState === "cancel_requested" && t.lastCliState === "running");
|
|
52047
|
-
if (cancelRow) {
|
|
52048
|
-
const localCancelHandled = await deps.acpManager.cancelRun(cancelRow.turnId);
|
|
52049
|
-
if (!localCancelHandled) {
|
|
52050
|
-
deps.log(
|
|
52051
|
-
`[Queue] bridge server cancel_requested for ${cancelRow.turnId.slice(0, 8)}\u2026 but no local agent run is active (e.g. after CLI restart); marking cancelled and notifying bridge.`
|
|
52052
|
-
);
|
|
52053
|
-
await finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, { terminalCliState: "cancelled" });
|
|
52054
|
-
const ws = deps.getWs();
|
|
52055
|
-
if (ws && cancelRow.sessionId) {
|
|
52056
|
-
sendWsMessage(ws, {
|
|
52057
|
-
type: "prompt_result",
|
|
52058
|
-
sessionId: cancelRow.sessionId,
|
|
52059
|
-
runId: cancelRow.turnId,
|
|
52060
|
-
success: false,
|
|
52061
|
-
error: "Stopped by user",
|
|
52062
|
-
stopReason: "cancelled"
|
|
52063
|
-
});
|
|
52064
|
-
}
|
|
52065
|
-
}
|
|
52066
|
-
}
|
|
52067
|
-
}
|
|
52160
|
+
// src/prompt-turn-queue/runner/start-prompt-queue-runs.ts
|
|
52161
|
+
async function startPromptQueueRuns(entries, deps) {
|
|
52068
52162
|
const report = {};
|
|
52069
|
-
const
|
|
52070
|
-
for (const [queueKey
|
|
52071
|
-
if (!Array.isArray(serverTurns)) continue;
|
|
52163
|
+
const started = /* @__PURE__ */ new Set();
|
|
52164
|
+
for (const [queueKey] of entries) {
|
|
52072
52165
|
const file2 = await readPersistedQueue(queueKey);
|
|
52073
|
-
if (!file2) continue;
|
|
52074
|
-
if (hasRunningTurn(file2.turns)) continue;
|
|
52166
|
+
if (!file2 || hasRunningTurn(file2.turns)) continue;
|
|
52075
52167
|
const next = pickNextRunnableTurn(file2.turns);
|
|
52076
52168
|
if (!next) continue;
|
|
52077
52169
|
if (!await runLocalRevertBeforeQueuedPrompt(next, deps)) {
|
|
52078
52170
|
next.lastCliState = "failed";
|
|
52079
52171
|
await writePersistedQueue(file2);
|
|
52080
|
-
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: next.turnId, cliState: "failed" }] });
|
|
52172
|
+
sendPromptQueueClientReport(deps.getWs(), { [queueKey]: [{ turnId: next.turnId, cliState: "failed" }] });
|
|
52081
52173
|
continue;
|
|
52082
52174
|
}
|
|
52083
52175
|
next.lastCliState = "running";
|
|
52084
52176
|
await writePersistedQueue(file2);
|
|
52085
52177
|
setRunIdQueueKey(next.turnId, queueKey);
|
|
52086
|
-
|
|
52178
|
+
started.add(next.turnId);
|
|
52087
52179
|
report[queueKey] = [{ turnId: next.turnId, cliState: "running" }];
|
|
52180
|
+
await yieldToEventLoop();
|
|
52088
52181
|
}
|
|
52089
|
-
if (Object.keys(report).length
|
|
52090
|
-
|
|
52091
|
-
|
|
52092
|
-
|
|
52093
|
-
|
|
52094
|
-
|
|
52095
|
-
|
|
52096
|
-
|
|
52097
|
-
|
|
52098
|
-
|
|
52099
|
-
|
|
52100
|
-
|
|
52182
|
+
if (Object.keys(report).length) sendPromptQueueClientReport(deps.getWs(), report);
|
|
52183
|
+
return started;
|
|
52184
|
+
}
|
|
52185
|
+
|
|
52186
|
+
// src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
|
|
52187
|
+
async function applyPromptQueueStateFromServer(msg, deps) {
|
|
52188
|
+
const raw = msg.queues;
|
|
52189
|
+
if (!raw || typeof raw !== "object") return;
|
|
52190
|
+
const entries = promptQueueSnapshotEntries(raw);
|
|
52191
|
+
await persistPromptQueueSnapshot(entries);
|
|
52192
|
+
await handlePromptQueueCancellations(entries, deps);
|
|
52193
|
+
const started = await startPromptQueueRuns(entries, deps);
|
|
52194
|
+
await dispatchStartedPromptQueueRuns(entries, started, deps);
|
|
52101
52195
|
}
|
|
52102
52196
|
|
|
52103
52197
|
// src/agents/acp/from-bridge/bridge-prompt-wiring.ts
|
|
@@ -52363,10 +52457,34 @@ var handlePromptMessage = (msg, deps) => {
|
|
|
52363
52457
|
handleBridgePrompt(msg, deps);
|
|
52364
52458
|
};
|
|
52365
52459
|
|
|
52460
|
+
// src/prompt-turn-queue/runner/serial-prompt-queue-work.ts
|
|
52461
|
+
var running = false;
|
|
52462
|
+
var latestWork = null;
|
|
52463
|
+
async function drain() {
|
|
52464
|
+
while (latestWork) {
|
|
52465
|
+
const work = latestWork;
|
|
52466
|
+
latestWork = null;
|
|
52467
|
+
await work();
|
|
52468
|
+
}
|
|
52469
|
+
}
|
|
52470
|
+
function enqueueLatestPromptQueueStateWork(work) {
|
|
52471
|
+
latestWork = work;
|
|
52472
|
+
if (running) return;
|
|
52473
|
+
running = true;
|
|
52474
|
+
void drain().finally(() => {
|
|
52475
|
+
running = false;
|
|
52476
|
+
if (latestWork) enqueueLatestPromptQueueStateWork(latestWork);
|
|
52477
|
+
});
|
|
52478
|
+
}
|
|
52479
|
+
|
|
52366
52480
|
// src/routing/handlers/prompt-queue-state.ts
|
|
52367
52481
|
var handlePromptQueueStateMessage = (msg, deps) => {
|
|
52368
|
-
|
|
52369
|
-
|
|
52482
|
+
enqueueLatestPromptQueueStateWork(async () => {
|
|
52483
|
+
try {
|
|
52484
|
+
await applyPromptQueueStateFromServer(msg, deps);
|
|
52485
|
+
} catch (err) {
|
|
52486
|
+
deps.log(`[Queue] applyPromptQueueStateFromServer failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
52487
|
+
}
|
|
52370
52488
|
});
|
|
52371
52489
|
};
|
|
52372
52490
|
|
|
@@ -53512,6 +53630,7 @@ function dispatchBridgeMessage(msg, deps) {
|
|
|
53512
53630
|
switch (msg.type) {
|
|
53513
53631
|
case "auth_token":
|
|
53514
53632
|
case "bridge_identified":
|
|
53633
|
+
case "installed_agent_auth_sync":
|
|
53515
53634
|
case "ha":
|
|
53516
53635
|
dispatchBridgeConnectionMessage(msg, deps);
|
|
53517
53636
|
break;
|