@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/index.js
CHANGED
|
@@ -26497,8 +26497,8 @@ var init_task_queue_types = __esm({
|
|
|
26497
26497
|
});
|
|
26498
26498
|
|
|
26499
26499
|
// src/code-nav/symbol-index/scheduler/task-queue-store.ts
|
|
26500
|
-
function setSymbolIndexWorkerRunning(
|
|
26501
|
-
symbolIndexWorkerRunning =
|
|
26500
|
+
function setSymbolIndexWorkerRunning(running2) {
|
|
26501
|
+
symbolIndexWorkerRunning = running2;
|
|
26502
26502
|
}
|
|
26503
26503
|
function taskMatchesCurrentPending(task) {
|
|
26504
26504
|
const current = pendingSymbolIndexTasks.get(symbolIndexTaskKey(task.parentPath, task.filePath));
|
|
@@ -29997,12 +29997,32 @@ function attachSdkStdioStderrAuthWatch(options) {
|
|
|
29997
29997
|
|
|
29998
29998
|
// src/agents/acp/clients/sdk/spawn-sdk-stdio-process.ts
|
|
29999
29999
|
import { spawn } from "node:child_process";
|
|
30000
|
+
|
|
30001
|
+
// src/agents/acp/clients/bridge-installed-agent-auth-env.ts
|
|
30002
|
+
var authEnv = /* @__PURE__ */ new Map();
|
|
30003
|
+
function setBridgeInstalledAgentAuthEnv(entries) {
|
|
30004
|
+
authEnv.clear();
|
|
30005
|
+
for (const entry of entries) {
|
|
30006
|
+
const envVar = typeof entry.envVar === "string" ? entry.envVar.trim() : "";
|
|
30007
|
+
const token = typeof entry.token === "string" ? entry.token.trim() : "";
|
|
30008
|
+
if (envVar && token) authEnv.set(envVar, token);
|
|
30009
|
+
}
|
|
30010
|
+
}
|
|
30011
|
+
function bridgeInstalledAgentAuthProcessEnv(base = process.env) {
|
|
30012
|
+
if (authEnv.size === 0) return base;
|
|
30013
|
+
return { ...base, ...Object.fromEntries(authEnv) };
|
|
30014
|
+
}
|
|
30015
|
+
function cursorAgentUsesApiKeyAuth(env = process.env) {
|
|
30016
|
+
return Boolean(env.CURSOR_API_KEY?.trim() || env.CURSOR_AUTH_TOKEN?.trim());
|
|
30017
|
+
}
|
|
30018
|
+
|
|
30019
|
+
// src/agents/acp/clients/sdk/spawn-sdk-stdio-process.ts
|
|
30000
30020
|
function spawnSdkStdioProcess(options) {
|
|
30001
30021
|
const isWindows = process.platform === "win32";
|
|
30002
30022
|
const child = spawn(options.command[0], options.command.slice(1), {
|
|
30003
30023
|
cwd: options.cwd,
|
|
30004
30024
|
stdio: ["pipe", "pipe", "pipe"],
|
|
30005
|
-
env: process.env,
|
|
30025
|
+
env: bridgeInstalledAgentAuthProcessEnv(process.env),
|
|
30006
30026
|
shell: isWindows
|
|
30007
30027
|
});
|
|
30008
30028
|
const stderrCapture = createStderrCapture(child);
|
|
@@ -30586,7 +30606,7 @@ function installBridgeProcessResilience() {
|
|
|
30586
30606
|
}
|
|
30587
30607
|
|
|
30588
30608
|
// src/cli-version.ts
|
|
30589
|
-
var CLI_VERSION = "0.1.
|
|
30609
|
+
var CLI_VERSION = "0.1.74".length > 0 ? "0.1.74" : "0.0.0-dev";
|
|
30590
30610
|
|
|
30591
30611
|
// src/connection/heartbeat/constants.ts
|
|
30592
30612
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -33469,10 +33489,11 @@ function createCursorAcpIncomingLineHandler(deps) {
|
|
|
33469
33489
|
|
|
33470
33490
|
// src/agents/acp/clients/cursor/cursor-json-rpc-acp-transport.ts
|
|
33471
33491
|
function createCursorJsonRpcAcpTransport(deps) {
|
|
33472
|
-
const { send, cancelSessionNotification } = deps;
|
|
33492
|
+
const { send, cancelSessionNotification, skipBrowserAuthenticate } = deps;
|
|
33473
33493
|
return {
|
|
33474
33494
|
initialize: (request) => send("initialize", request),
|
|
33475
33495
|
afterInitialize: async () => {
|
|
33496
|
+
if (skipBrowserAuthenticate) return;
|
|
33476
33497
|
await send("authenticate", { methodId: "cursor_login" });
|
|
33477
33498
|
},
|
|
33478
33499
|
resumeSession: (p) => send("session/resume", p),
|
|
@@ -33581,7 +33602,8 @@ async function initCursorAcpWire(options) {
|
|
|
33581
33602
|
rl.on("line", (line) => incoming.handleLine(line));
|
|
33582
33603
|
const transport = createCursorJsonRpcAcpTransport({
|
|
33583
33604
|
send: wire.send,
|
|
33584
|
-
cancelSessionNotification: wire.cancelSessionNotification
|
|
33605
|
+
cancelSessionNotification: wire.cancelSessionNotification,
|
|
33606
|
+
skipBrowserAuthenticate: options.skipBrowserAuthenticate
|
|
33585
33607
|
});
|
|
33586
33608
|
const established = await bootstrapAcpWireSession(transport, options.sessionCtx, CURSOR_ACP_CLIENT_INFO);
|
|
33587
33609
|
return { wire, transport, established, incoming, pendingRequests: pendingRequests2 };
|
|
@@ -33594,7 +33616,7 @@ function spawnCursorAcpProcess(options) {
|
|
|
33594
33616
|
const child = spawn3(options.command[0], options.command.slice(1), {
|
|
33595
33617
|
cwd: options.cwd,
|
|
33596
33618
|
stdio: ["pipe", "pipe", "pipe"],
|
|
33597
|
-
env: process.env,
|
|
33619
|
+
env: bridgeInstalledAgentAuthProcessEnv(process.env),
|
|
33598
33620
|
shell: isWindows
|
|
33599
33621
|
});
|
|
33600
33622
|
const stderrCapture = createStderrCapture(child);
|
|
@@ -33626,11 +33648,13 @@ async function createCursorAcpClient(options) {
|
|
|
33626
33648
|
onAgentSubprocessExit
|
|
33627
33649
|
} = options;
|
|
33628
33650
|
const dbgFs = process.env.BUILDAUTOMATON_DEBUG_ACP_FS === "1";
|
|
33651
|
+
const spawnEnv = bridgeInstalledAgentAuthProcessEnv(process.env);
|
|
33629
33652
|
const { child, stderrCapture } = spawnCursorAcpProcess({
|
|
33630
33653
|
command,
|
|
33631
33654
|
cwd,
|
|
33632
33655
|
onAgentSubprocessExit
|
|
33633
33656
|
});
|
|
33657
|
+
const skipBrowserAuthenticate = cursorAgentUsesApiKeyAuth(spawnEnv);
|
|
33634
33658
|
const sessionCtx = createCursorAcpSessionContext({
|
|
33635
33659
|
cwd,
|
|
33636
33660
|
mcpServers: options.mcpServers,
|
|
@@ -33653,6 +33677,7 @@ async function createCursorAcpClient(options) {
|
|
|
33653
33677
|
const { wire, transport, established, incoming, pendingRequests: pendingRequests2 } = await initCursorAcpWire({
|
|
33654
33678
|
child,
|
|
33655
33679
|
sessionCtx,
|
|
33680
|
+
skipBrowserAuthenticate,
|
|
33656
33681
|
incomingDeps: { dbgFs, sessionCtx, onSessionUpdate, onRequest }
|
|
33657
33682
|
});
|
|
33658
33683
|
resolve35(
|
|
@@ -34499,6 +34524,7 @@ function extractSessionUpdateMessageText(params) {
|
|
|
34499
34524
|
}
|
|
34500
34525
|
|
|
34501
34526
|
// src/agents/planning/planning-session-turn-buffer.ts
|
|
34527
|
+
var MAX_PLANNING_BUFFER_CHARS = 512 * 1024;
|
|
34502
34528
|
var buffersByRunId = /* @__PURE__ */ new Map();
|
|
34503
34529
|
function registerPlanningSessionTurn(runId) {
|
|
34504
34530
|
buffersByRunId.set(runId, { messageBuffer: "" });
|
|
@@ -34516,7 +34542,10 @@ function capturePlanningSessionUpdate(params) {
|
|
|
34516
34542
|
});
|
|
34517
34543
|
if (bucket !== "message") return false;
|
|
34518
34544
|
const text = extractSessionUpdateMessageText(params.payload);
|
|
34519
|
-
if (text
|
|
34545
|
+
if (text && state.messageBuffer.length < MAX_PLANNING_BUFFER_CHARS) {
|
|
34546
|
+
const room = MAX_PLANNING_BUFFER_CHARS - state.messageBuffer.length;
|
|
34547
|
+
state.messageBuffer += room >= text.length ? text : text.slice(0, room);
|
|
34548
|
+
}
|
|
34520
34549
|
return true;
|
|
34521
34550
|
}
|
|
34522
34551
|
function getPlanningSessionTurnOutput(runId) {
|
|
@@ -36581,11 +36610,30 @@ function closeHttpServer(server) {
|
|
|
36581
36610
|
}
|
|
36582
36611
|
|
|
36583
36612
|
// src/mcp/bridge-access/read-json-body.ts
|
|
36613
|
+
var MAX_JSON_BODY_BYTES = 1024 * 1024;
|
|
36614
|
+
var RequestBodyTooLargeError = class extends Error {
|
|
36615
|
+
constructor() {
|
|
36616
|
+
super(`Request body exceeds ${MAX_JSON_BODY_BYTES} bytes`);
|
|
36617
|
+
}
|
|
36618
|
+
};
|
|
36584
36619
|
function readJsonBody(req) {
|
|
36585
36620
|
return new Promise((resolve35, reject) => {
|
|
36586
36621
|
const chunks = [];
|
|
36587
|
-
|
|
36622
|
+
let total = 0;
|
|
36623
|
+
let tooLarge = false;
|
|
36624
|
+
req.on("data", (chunk) => {
|
|
36625
|
+
if (tooLarge) return;
|
|
36626
|
+
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
36627
|
+
total += buf.length;
|
|
36628
|
+
if (total > MAX_JSON_BODY_BYTES) {
|
|
36629
|
+
tooLarge = true;
|
|
36630
|
+
reject(new RequestBodyTooLargeError());
|
|
36631
|
+
return;
|
|
36632
|
+
}
|
|
36633
|
+
chunks.push(buf);
|
|
36634
|
+
});
|
|
36588
36635
|
req.on("end", () => {
|
|
36636
|
+
if (tooLarge) return;
|
|
36589
36637
|
try {
|
|
36590
36638
|
const raw = Buffer.concat(chunks).toString("utf8").trim();
|
|
36591
36639
|
if (!raw) {
|
|
@@ -36642,7 +36690,7 @@ function createBridgeAccessRequestHandler(registry2) {
|
|
|
36642
36690
|
sendJsonResponse(res, 404, { ok: false, error: "Not found" });
|
|
36643
36691
|
} catch (err) {
|
|
36644
36692
|
const message = err instanceof Error ? err.message : String(err);
|
|
36645
|
-
sendJsonResponse(res, 500, { ok: false, error: message });
|
|
36693
|
+
sendJsonResponse(res, err instanceof RequestBodyTooLargeError ? 413 : 500, { ok: false, error: message });
|
|
36646
36694
|
}
|
|
36647
36695
|
})();
|
|
36648
36696
|
};
|
|
@@ -46916,7 +46964,7 @@ init_yield_to_event_loop();
|
|
|
46916
46964
|
|
|
46917
46965
|
// src/files/read/types.ts
|
|
46918
46966
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
46919
|
-
var READ_RANGE_YIELD_EVERY_BYTES =
|
|
46967
|
+
var READ_RANGE_YIELD_EVERY_BYTES = 64 * 1024;
|
|
46920
46968
|
|
|
46921
46969
|
// src/files/read/guess-mime-type.ts
|
|
46922
46970
|
var MIME_BY_EXT = {
|
|
@@ -48508,6 +48556,7 @@ function buildBridgeUrl(apiUrl, workspaceId, authToken) {
|
|
|
48508
48556
|
var API_TO_BRIDGE_MESSAGE_TYPES = [
|
|
48509
48557
|
"auth_token",
|
|
48510
48558
|
"bridge_identified",
|
|
48559
|
+
"installed_agent_auth_sync",
|
|
48511
48560
|
"ha",
|
|
48512
48561
|
"preview_environments_config",
|
|
48513
48562
|
"preview_environment_control",
|
|
@@ -48596,6 +48645,16 @@ var handleBridgeIdentified = (msg, deps) => {
|
|
|
48596
48645
|
});
|
|
48597
48646
|
};
|
|
48598
48647
|
|
|
48648
|
+
// src/routing/handlers/installed-agent-auth-sync.ts
|
|
48649
|
+
var handleInstalledAgentAuthSync = (msg) => {
|
|
48650
|
+
const entries = Array.isArray(msg.entries) ? msg.entries : [];
|
|
48651
|
+
setBridgeInstalledAgentAuthEnv(
|
|
48652
|
+
entries.filter(
|
|
48653
|
+
(e) => e != null && typeof e === "object" && typeof e.envVar === "string" && typeof e.token === "string"
|
|
48654
|
+
)
|
|
48655
|
+
);
|
|
48656
|
+
};
|
|
48657
|
+
|
|
48599
48658
|
// src/connection/heartbeat/ack.ts
|
|
48600
48659
|
var handleBridgeHeartbeatAck = (msg, deps) => {
|
|
48601
48660
|
const raw = msg.s;
|
|
@@ -48612,6 +48671,9 @@ function dispatchBridgeConnectionMessage(msg, deps) {
|
|
|
48612
48671
|
case "bridge_identified":
|
|
48613
48672
|
handleBridgeIdentified(msg, deps);
|
|
48614
48673
|
break;
|
|
48674
|
+
case "installed_agent_auth_sync":
|
|
48675
|
+
handleInstalledAgentAuthSync(msg, deps);
|
|
48676
|
+
break;
|
|
48615
48677
|
case "ha":
|
|
48616
48678
|
handleBridgeHeartbeatAck(msg, deps);
|
|
48617
48679
|
break;
|
|
@@ -48708,16 +48770,8 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
48708
48770
|
handleBridgeAgentConfig(msg, deps);
|
|
48709
48771
|
};
|
|
48710
48772
|
|
|
48711
|
-
// src/prompt-turn-queue/
|
|
48712
|
-
|
|
48713
|
-
if (!ws) return false;
|
|
48714
|
-
const wireQueues = {};
|
|
48715
|
-
for (const [queueKey, rows] of Object.entries(queues)) {
|
|
48716
|
-
wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
|
|
48717
|
-
}
|
|
48718
|
-
sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
|
|
48719
|
-
return true;
|
|
48720
|
-
}
|
|
48773
|
+
// src/prompt-turn-queue/runner/dispatch-started-prompt-queue-runs.ts
|
|
48774
|
+
init_yield_to_event_loop();
|
|
48721
48775
|
|
|
48722
48776
|
// src/prompt-turn-queue/disk-store.ts
|
|
48723
48777
|
init_cli_database();
|
|
@@ -48809,23 +48863,6 @@ function dispatchLocalPrompt(next, deps) {
|
|
|
48809
48863
|
handleBridgePrompt(msg, deps);
|
|
48810
48864
|
}
|
|
48811
48865
|
|
|
48812
|
-
// src/prompt-turn-queue/runner/queue-selection.ts
|
|
48813
|
-
function pickNextRunnableTurn(turns) {
|
|
48814
|
-
for (const t of turns) {
|
|
48815
|
-
if (t.bridgeServerState === "discarded" || t.bridgeServerState === "stopping") continue;
|
|
48816
|
-
if (t.bridgeServerState === "cancel_requested") continue;
|
|
48817
|
-
if (!isRunnableBridgePromptTurnServerState(t.bridgeServerState)) continue;
|
|
48818
|
-
if (t.lastCliState === "running" || t.lastCliState === "stopped" || t.lastCliState === "failed" || t.lastCliState === "cancelled") {
|
|
48819
|
-
continue;
|
|
48820
|
-
}
|
|
48821
|
-
return t;
|
|
48822
|
-
}
|
|
48823
|
-
return null;
|
|
48824
|
-
}
|
|
48825
|
-
function hasRunningTurn(turns) {
|
|
48826
|
-
return turns.some((t) => t.lastCliState === "running");
|
|
48827
|
-
}
|
|
48828
|
-
|
|
48829
48866
|
// src/prompt-turn-queue/runner/run-id-queue-key-map.ts
|
|
48830
48867
|
var runIdToQueueKey = /* @__PURE__ */ new Map();
|
|
48831
48868
|
function getRunIdQueueKey(runId) {
|
|
@@ -48840,11 +48877,123 @@ function deleteRunIdQueueKey(runId) {
|
|
|
48840
48877
|
return queueKey;
|
|
48841
48878
|
}
|
|
48842
48879
|
function syncRunningTurnQueueKeys(turns, queueKey) {
|
|
48843
|
-
for (const
|
|
48844
|
-
runIdToQueueKey.set(
|
|
48880
|
+
for (const running2 of turns.filter((t) => t.lastCliState === "running")) {
|
|
48881
|
+
runIdToQueueKey.set(running2.turnId, queueKey);
|
|
48882
|
+
}
|
|
48883
|
+
}
|
|
48884
|
+
|
|
48885
|
+
// src/prompt-turn-queue/runner/dispatch-started-prompt-queue-runs.ts
|
|
48886
|
+
async function dispatchStartedPromptQueueRuns(entries, started, deps) {
|
|
48887
|
+
for (const [queueKey] of entries) {
|
|
48888
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
48889
|
+
const running2 = file2?.turns.find((turn) => turn.lastCliState === "running");
|
|
48890
|
+
if (running2 && started.has(running2.turnId) && getRunIdQueueKey(running2.turnId) === queueKey) {
|
|
48891
|
+
dispatchLocalPrompt(running2, deps);
|
|
48892
|
+
}
|
|
48893
|
+
await yieldToEventLoop();
|
|
48894
|
+
}
|
|
48895
|
+
}
|
|
48896
|
+
|
|
48897
|
+
// src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
|
|
48898
|
+
init_yield_to_event_loop();
|
|
48899
|
+
|
|
48900
|
+
// src/prompt-turn-queue/client-report.ts
|
|
48901
|
+
function sendPromptQueueClientReport(ws, queues) {
|
|
48902
|
+
if (!ws) return false;
|
|
48903
|
+
const wireQueues = {};
|
|
48904
|
+
for (const [queueKey, rows] of Object.entries(queues)) {
|
|
48905
|
+
wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
|
|
48906
|
+
}
|
|
48907
|
+
sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
|
|
48908
|
+
return true;
|
|
48909
|
+
}
|
|
48910
|
+
|
|
48911
|
+
// src/prompt-turn-queue/runner/finalize-prompt-turn-on-bridge.ts
|
|
48912
|
+
async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
|
|
48913
|
+
if (!runId) return false;
|
|
48914
|
+
const queueKey = deleteRunIdQueueKey(runId);
|
|
48915
|
+
if (!queueKey) return false;
|
|
48916
|
+
const f = await readPersistedQueue(queueKey);
|
|
48917
|
+
if (!f) return false;
|
|
48918
|
+
const t = f.turns.find((x) => x.turnId === runId);
|
|
48919
|
+
if (!t) return false;
|
|
48920
|
+
t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
|
|
48921
|
+
await writePersistedQueue(f);
|
|
48922
|
+
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
|
|
48923
|
+
return true;
|
|
48924
|
+
}
|
|
48925
|
+
|
|
48926
|
+
// src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
|
|
48927
|
+
async function handlePromptQueueCancellations(entries, deps) {
|
|
48928
|
+
for (const [queueKey] of entries) {
|
|
48929
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
48930
|
+
const turn = file2?.turns.find((row) => row.bridgeServerState === "cancel_requested" && row.lastCliState === "running");
|
|
48931
|
+
if (!turn) {
|
|
48932
|
+
await yieldToEventLoop();
|
|
48933
|
+
continue;
|
|
48934
|
+
}
|
|
48935
|
+
deps.log(`[Queue] Cancellation request received for turn ${turn.turnId.slice(0, 8)}\u2026`);
|
|
48936
|
+
if (await deps.acpManager.cancelRun(turn.turnId)) {
|
|
48937
|
+
await yieldToEventLoop();
|
|
48938
|
+
continue;
|
|
48939
|
+
}
|
|
48940
|
+
deps.log(`[Queue] cancel_requested for ${turn.turnId.slice(0, 8)}\u2026 with no local run; marking cancelled.`);
|
|
48941
|
+
await finalizePromptTurnOnBridge(deps.getWs, turn.turnId, false, { terminalCliState: "cancelled" });
|
|
48942
|
+
const ws = deps.getWs();
|
|
48943
|
+
if (ws && turn.sessionId) {
|
|
48944
|
+
sendWsMessage(ws, {
|
|
48945
|
+
type: "prompt_result",
|
|
48946
|
+
sessionId: turn.sessionId,
|
|
48947
|
+
runId: turn.turnId,
|
|
48948
|
+
success: false,
|
|
48949
|
+
error: "Stopped by user",
|
|
48950
|
+
stopReason: "cancelled"
|
|
48951
|
+
});
|
|
48952
|
+
}
|
|
48953
|
+
await yieldToEventLoop();
|
|
48845
48954
|
}
|
|
48846
48955
|
}
|
|
48847
48956
|
|
|
48957
|
+
// src/prompt-turn-queue/runner/persist-prompt-queue-snapshot.ts
|
|
48958
|
+
init_yield_to_event_loop();
|
|
48959
|
+
async function persistPromptQueueSnapshot(entries) {
|
|
48960
|
+
for (const [queueKey, serverTurns] of entries) {
|
|
48961
|
+
const file2 = await mergeBridgeServerQueueSnapshot(queueKey, serverTurns);
|
|
48962
|
+
await writePersistedQueue(file2);
|
|
48963
|
+
await yieldToEventLoop();
|
|
48964
|
+
}
|
|
48965
|
+
for (const [queueKey] of entries) {
|
|
48966
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
48967
|
+
if (file2) syncRunningTurnQueueKeys(file2.turns, queueKey);
|
|
48968
|
+
await yieldToEventLoop();
|
|
48969
|
+
}
|
|
48970
|
+
}
|
|
48971
|
+
|
|
48972
|
+
// src/prompt-turn-queue/runner/prompt-queue-snapshot-types.ts
|
|
48973
|
+
function promptQueueSnapshotEntries(queues) {
|
|
48974
|
+
return Object.entries(queues).filter((entry) => Array.isArray(entry[1]));
|
|
48975
|
+
}
|
|
48976
|
+
|
|
48977
|
+
// src/prompt-turn-queue/runner/start-prompt-queue-runs.ts
|
|
48978
|
+
init_yield_to_event_loop();
|
|
48979
|
+
|
|
48980
|
+
// src/prompt-turn-queue/runner/queue-selection.ts
|
|
48981
|
+
function pickNextRunnableTurn(turns) {
|
|
48982
|
+
for (const t of turns) {
|
|
48983
|
+
if (t.bridgeServerState === "discarded" || t.bridgeServerState === "stopping") continue;
|
|
48984
|
+
if (t.bridgeServerState === "cancel_requested") continue;
|
|
48985
|
+
if (!isRunnableBridgePromptTurnServerState(t.bridgeServerState)) continue;
|
|
48986
|
+
if (t.lastCliState === "running" || t.lastCliState === "stopped" || t.lastCliState === "failed" || t.lastCliState === "cancelled") {
|
|
48987
|
+
continue;
|
|
48988
|
+
}
|
|
48989
|
+
return t;
|
|
48990
|
+
}
|
|
48991
|
+
return null;
|
|
48992
|
+
}
|
|
48993
|
+
function hasRunningTurn(turns) {
|
|
48994
|
+
return turns.some((t) => t.lastCliState === "running");
|
|
48995
|
+
}
|
|
48996
|
+
|
|
48848
48997
|
// src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
|
|
48849
48998
|
import fs58 from "node:fs";
|
|
48850
48999
|
|
|
@@ -48962,96 +49111,41 @@ async function runLocalRevertBeforeQueuedPrompt(next, deps) {
|
|
|
48962
49111
|
return res.ok;
|
|
48963
49112
|
}
|
|
48964
49113
|
|
|
48965
|
-
// src/prompt-turn-queue/runner/
|
|
48966
|
-
async function
|
|
48967
|
-
if (!runId) return false;
|
|
48968
|
-
const queueKey = deleteRunIdQueueKey(runId);
|
|
48969
|
-
if (!queueKey) return false;
|
|
48970
|
-
const f = await readPersistedQueue(queueKey);
|
|
48971
|
-
if (!f) return false;
|
|
48972
|
-
const t = f.turns.find((x) => x.turnId === runId);
|
|
48973
|
-
if (!t) return false;
|
|
48974
|
-
t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
|
|
48975
|
-
await writePersistedQueue(f);
|
|
48976
|
-
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
|
|
48977
|
-
return true;
|
|
48978
|
-
}
|
|
48979
|
-
|
|
48980
|
-
// src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
|
|
48981
|
-
async function applyPromptQueueStateFromServer(msg, deps) {
|
|
48982
|
-
const raw = msg.queues;
|
|
48983
|
-
if (!raw || typeof raw !== "object") return;
|
|
48984
|
-
const getWs = deps.getWs;
|
|
48985
|
-
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
48986
|
-
if (!Array.isArray(serverTurns)) continue;
|
|
48987
|
-
const file2 = await mergeBridgeServerQueueSnapshot(queueKey, serverTurns);
|
|
48988
|
-
await writePersistedQueue(file2);
|
|
48989
|
-
}
|
|
48990
|
-
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
48991
|
-
if (!Array.isArray(serverTurns)) continue;
|
|
48992
|
-
const file2 = await readPersistedQueue(queueKey);
|
|
48993
|
-
if (!file2) continue;
|
|
48994
|
-
syncRunningTurnQueueKeys(file2.turns, queueKey);
|
|
48995
|
-
}
|
|
48996
|
-
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
48997
|
-
if (!Array.isArray(serverTurns)) continue;
|
|
48998
|
-
const file2 = await readPersistedQueue(queueKey);
|
|
48999
|
-
if (!file2) continue;
|
|
49000
|
-
const cancelRow = file2.turns.find((t) => t.bridgeServerState === "cancel_requested" && t.lastCliState === "running");
|
|
49001
|
-
if (cancelRow) {
|
|
49002
|
-
const localCancelHandled = await deps.acpManager.cancelRun(cancelRow.turnId);
|
|
49003
|
-
if (!localCancelHandled) {
|
|
49004
|
-
deps.log(
|
|
49005
|
-
`[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.`
|
|
49006
|
-
);
|
|
49007
|
-
await finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, { terminalCliState: "cancelled" });
|
|
49008
|
-
const ws = deps.getWs();
|
|
49009
|
-
if (ws && cancelRow.sessionId) {
|
|
49010
|
-
sendWsMessage(ws, {
|
|
49011
|
-
type: "prompt_result",
|
|
49012
|
-
sessionId: cancelRow.sessionId,
|
|
49013
|
-
runId: cancelRow.turnId,
|
|
49014
|
-
success: false,
|
|
49015
|
-
error: "Stopped by user",
|
|
49016
|
-
stopReason: "cancelled"
|
|
49017
|
-
});
|
|
49018
|
-
}
|
|
49019
|
-
}
|
|
49020
|
-
}
|
|
49021
|
-
}
|
|
49114
|
+
// src/prompt-turn-queue/runner/start-prompt-queue-runs.ts
|
|
49115
|
+
async function startPromptQueueRuns(entries, deps) {
|
|
49022
49116
|
const report = {};
|
|
49023
|
-
const
|
|
49024
|
-
for (const [queueKey
|
|
49025
|
-
if (!Array.isArray(serverTurns)) continue;
|
|
49117
|
+
const started = /* @__PURE__ */ new Set();
|
|
49118
|
+
for (const [queueKey] of entries) {
|
|
49026
49119
|
const file2 = await readPersistedQueue(queueKey);
|
|
49027
|
-
if (!file2) continue;
|
|
49028
|
-
if (hasRunningTurn(file2.turns)) continue;
|
|
49120
|
+
if (!file2 || hasRunningTurn(file2.turns)) continue;
|
|
49029
49121
|
const next = pickNextRunnableTurn(file2.turns);
|
|
49030
49122
|
if (!next) continue;
|
|
49031
49123
|
if (!await runLocalRevertBeforeQueuedPrompt(next, deps)) {
|
|
49032
49124
|
next.lastCliState = "failed";
|
|
49033
49125
|
await writePersistedQueue(file2);
|
|
49034
|
-
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: next.turnId, cliState: "failed" }] });
|
|
49126
|
+
sendPromptQueueClientReport(deps.getWs(), { [queueKey]: [{ turnId: next.turnId, cliState: "failed" }] });
|
|
49035
49127
|
continue;
|
|
49036
49128
|
}
|
|
49037
49129
|
next.lastCliState = "running";
|
|
49038
49130
|
await writePersistedQueue(file2);
|
|
49039
49131
|
setRunIdQueueKey(next.turnId, queueKey);
|
|
49040
|
-
|
|
49132
|
+
started.add(next.turnId);
|
|
49041
49133
|
report[queueKey] = [{ turnId: next.turnId, cliState: "running" }];
|
|
49134
|
+
await yieldToEventLoop();
|
|
49042
49135
|
}
|
|
49043
|
-
if (Object.keys(report).length
|
|
49044
|
-
|
|
49045
|
-
|
|
49046
|
-
|
|
49047
|
-
|
|
49048
|
-
|
|
49049
|
-
|
|
49050
|
-
|
|
49051
|
-
|
|
49052
|
-
|
|
49053
|
-
|
|
49054
|
-
|
|
49136
|
+
if (Object.keys(report).length) sendPromptQueueClientReport(deps.getWs(), report);
|
|
49137
|
+
return started;
|
|
49138
|
+
}
|
|
49139
|
+
|
|
49140
|
+
// src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
|
|
49141
|
+
async function applyPromptQueueStateFromServer(msg, deps) {
|
|
49142
|
+
const raw = msg.queues;
|
|
49143
|
+
if (!raw || typeof raw !== "object") return;
|
|
49144
|
+
const entries = promptQueueSnapshotEntries(raw);
|
|
49145
|
+
await persistPromptQueueSnapshot(entries);
|
|
49146
|
+
await handlePromptQueueCancellations(entries, deps);
|
|
49147
|
+
const started = await startPromptQueueRuns(entries, deps);
|
|
49148
|
+
await dispatchStartedPromptQueueRuns(entries, started, deps);
|
|
49055
49149
|
}
|
|
49056
49150
|
|
|
49057
49151
|
// src/agents/acp/from-bridge/bridge-prompt-wiring.ts
|
|
@@ -49317,10 +49411,34 @@ var handlePromptMessage = (msg, deps) => {
|
|
|
49317
49411
|
handleBridgePrompt(msg, deps);
|
|
49318
49412
|
};
|
|
49319
49413
|
|
|
49414
|
+
// src/prompt-turn-queue/runner/serial-prompt-queue-work.ts
|
|
49415
|
+
var running = false;
|
|
49416
|
+
var latestWork = null;
|
|
49417
|
+
async function drain() {
|
|
49418
|
+
while (latestWork) {
|
|
49419
|
+
const work = latestWork;
|
|
49420
|
+
latestWork = null;
|
|
49421
|
+
await work();
|
|
49422
|
+
}
|
|
49423
|
+
}
|
|
49424
|
+
function enqueueLatestPromptQueueStateWork(work) {
|
|
49425
|
+
latestWork = work;
|
|
49426
|
+
if (running) return;
|
|
49427
|
+
running = true;
|
|
49428
|
+
void drain().finally(() => {
|
|
49429
|
+
running = false;
|
|
49430
|
+
if (latestWork) enqueueLatestPromptQueueStateWork(latestWork);
|
|
49431
|
+
});
|
|
49432
|
+
}
|
|
49433
|
+
|
|
49320
49434
|
// src/routing/handlers/prompt-queue-state.ts
|
|
49321
49435
|
var handlePromptQueueStateMessage = (msg, deps) => {
|
|
49322
|
-
|
|
49323
|
-
|
|
49436
|
+
enqueueLatestPromptQueueStateWork(async () => {
|
|
49437
|
+
try {
|
|
49438
|
+
await applyPromptQueueStateFromServer(msg, deps);
|
|
49439
|
+
} catch (err) {
|
|
49440
|
+
deps.log(`[Queue] applyPromptQueueStateFromServer failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
49441
|
+
}
|
|
49324
49442
|
});
|
|
49325
49443
|
};
|
|
49326
49444
|
|
|
@@ -50292,6 +50410,7 @@ function dispatchBridgeMessage(msg, deps) {
|
|
|
50292
50410
|
switch (msg.type) {
|
|
50293
50411
|
case "auth_token":
|
|
50294
50412
|
case "bridge_identified":
|
|
50413
|
+
case "installed_agent_auth_sync":
|
|
50295
50414
|
case "ha":
|
|
50296
50415
|
dispatchBridgeConnectionMessage(msg, deps);
|
|
50297
50416
|
break;
|