@buildautomaton/cli 0.1.73 → 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/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(running) {
26501
- symbolIndexWorkerRunning = running;
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));
@@ -30606,7 +30606,7 @@ function installBridgeProcessResilience() {
30606
30606
  }
30607
30607
 
30608
30608
  // src/cli-version.ts
30609
- var CLI_VERSION = "0.1.73".length > 0 ? "0.1.73" : "0.0.0-dev";
30609
+ var CLI_VERSION = "0.1.74".length > 0 ? "0.1.74" : "0.0.0-dev";
30610
30610
 
30611
30611
  // src/connection/heartbeat/constants.ts
30612
30612
  var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
@@ -34524,6 +34524,7 @@ function extractSessionUpdateMessageText(params) {
34524
34524
  }
34525
34525
 
34526
34526
  // src/agents/planning/planning-session-turn-buffer.ts
34527
+ var MAX_PLANNING_BUFFER_CHARS = 512 * 1024;
34527
34528
  var buffersByRunId = /* @__PURE__ */ new Map();
34528
34529
  function registerPlanningSessionTurn(runId) {
34529
34530
  buffersByRunId.set(runId, { messageBuffer: "" });
@@ -34541,7 +34542,10 @@ function capturePlanningSessionUpdate(params) {
34541
34542
  });
34542
34543
  if (bucket !== "message") return false;
34543
34544
  const text = extractSessionUpdateMessageText(params.payload);
34544
- if (text) state.messageBuffer += 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
+ }
34545
34549
  return true;
34546
34550
  }
34547
34551
  function getPlanningSessionTurnOutput(runId) {
@@ -36606,11 +36610,30 @@ function closeHttpServer(server) {
36606
36610
  }
36607
36611
 
36608
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
+ };
36609
36619
  function readJsonBody(req) {
36610
36620
  return new Promise((resolve35, reject) => {
36611
36621
  const chunks = [];
36612
- req.on("data", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
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
+ });
36613
36635
  req.on("end", () => {
36636
+ if (tooLarge) return;
36614
36637
  try {
36615
36638
  const raw = Buffer.concat(chunks).toString("utf8").trim();
36616
36639
  if (!raw) {
@@ -36667,7 +36690,7 @@ function createBridgeAccessRequestHandler(registry2) {
36667
36690
  sendJsonResponse(res, 404, { ok: false, error: "Not found" });
36668
36691
  } catch (err) {
36669
36692
  const message = err instanceof Error ? err.message : String(err);
36670
- sendJsonResponse(res, 500, { ok: false, error: message });
36693
+ sendJsonResponse(res, err instanceof RequestBodyTooLargeError ? 413 : 500, { ok: false, error: message });
36671
36694
  }
36672
36695
  })();
36673
36696
  };
@@ -46941,7 +46964,7 @@ init_yield_to_event_loop();
46941
46964
 
46942
46965
  // src/files/read/types.ts
46943
46966
  var LINE_CHUNK_SIZE = 64 * 1024;
46944
- var READ_RANGE_YIELD_EVERY_BYTES = 256 * 1024;
46967
+ var READ_RANGE_YIELD_EVERY_BYTES = 64 * 1024;
46945
46968
 
46946
46969
  // src/files/read/guess-mime-type.ts
46947
46970
  var MIME_BY_EXT = {
@@ -48747,16 +48770,8 @@ var handleAgentConfigMessage = (msg, deps) => {
48747
48770
  handleBridgeAgentConfig(msg, deps);
48748
48771
  };
48749
48772
 
48750
- // src/prompt-turn-queue/client-report.ts
48751
- function sendPromptQueueClientReport(ws, queues) {
48752
- if (!ws) return false;
48753
- const wireQueues = {};
48754
- for (const [queueKey, rows] of Object.entries(queues)) {
48755
- wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
48756
- }
48757
- sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
48758
- return true;
48759
- }
48773
+ // src/prompt-turn-queue/runner/dispatch-started-prompt-queue-runs.ts
48774
+ init_yield_to_event_loop();
48760
48775
 
48761
48776
  // src/prompt-turn-queue/disk-store.ts
48762
48777
  init_cli_database();
@@ -48848,23 +48863,6 @@ function dispatchLocalPrompt(next, deps) {
48848
48863
  handleBridgePrompt(msg, deps);
48849
48864
  }
48850
48865
 
48851
- // src/prompt-turn-queue/runner/queue-selection.ts
48852
- function pickNextRunnableTurn(turns) {
48853
- for (const t of turns) {
48854
- if (t.bridgeServerState === "discarded" || t.bridgeServerState === "stopping") continue;
48855
- if (t.bridgeServerState === "cancel_requested") continue;
48856
- if (!isRunnableBridgePromptTurnServerState(t.bridgeServerState)) continue;
48857
- if (t.lastCliState === "running" || t.lastCliState === "stopped" || t.lastCliState === "failed" || t.lastCliState === "cancelled") {
48858
- continue;
48859
- }
48860
- return t;
48861
- }
48862
- return null;
48863
- }
48864
- function hasRunningTurn(turns) {
48865
- return turns.some((t) => t.lastCliState === "running");
48866
- }
48867
-
48868
48866
  // src/prompt-turn-queue/runner/run-id-queue-key-map.ts
48869
48867
  var runIdToQueueKey = /* @__PURE__ */ new Map();
48870
48868
  function getRunIdQueueKey(runId) {
@@ -48879,9 +48877,121 @@ function deleteRunIdQueueKey(runId) {
48879
48877
  return queueKey;
48880
48878
  }
48881
48879
  function syncRunningTurnQueueKeys(turns, queueKey) {
48882
- for (const running of turns.filter((t) => t.lastCliState === "running")) {
48883
- runIdToQueueKey.set(running.turnId, queueKey);
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();
48954
+ }
48955
+ }
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;
48884
48990
  }
48991
+ return null;
48992
+ }
48993
+ function hasRunningTurn(turns) {
48994
+ return turns.some((t) => t.lastCliState === "running");
48885
48995
  }
48886
48996
 
48887
48997
  // src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
@@ -49001,96 +49111,41 @@ async function runLocalRevertBeforeQueuedPrompt(next, deps) {
49001
49111
  return res.ok;
49002
49112
  }
49003
49113
 
49004
- // src/prompt-turn-queue/runner/finalize-prompt-turn-on-bridge.ts
49005
- async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
49006
- if (!runId) return false;
49007
- const queueKey = deleteRunIdQueueKey(runId);
49008
- if (!queueKey) return false;
49009
- const f = await readPersistedQueue(queueKey);
49010
- if (!f) return false;
49011
- const t = f.turns.find((x) => x.turnId === runId);
49012
- if (!t) return false;
49013
- t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
49014
- await writePersistedQueue(f);
49015
- sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
49016
- return true;
49017
- }
49018
-
49019
- // src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
49020
- async function applyPromptQueueStateFromServer(msg, deps) {
49021
- const raw = msg.queues;
49022
- if (!raw || typeof raw !== "object") return;
49023
- const getWs = deps.getWs;
49024
- for (const [queueKey, serverTurns] of Object.entries(raw)) {
49025
- if (!Array.isArray(serverTurns)) continue;
49026
- const file2 = await mergeBridgeServerQueueSnapshot(queueKey, serverTurns);
49027
- await writePersistedQueue(file2);
49028
- }
49029
- for (const [queueKey, serverTurns] of Object.entries(raw)) {
49030
- if (!Array.isArray(serverTurns)) continue;
49031
- const file2 = await readPersistedQueue(queueKey);
49032
- if (!file2) continue;
49033
- syncRunningTurnQueueKeys(file2.turns, queueKey);
49034
- }
49035
- for (const [queueKey, serverTurns] of Object.entries(raw)) {
49036
- if (!Array.isArray(serverTurns)) continue;
49037
- const file2 = await readPersistedQueue(queueKey);
49038
- if (!file2) continue;
49039
- const cancelRow = file2.turns.find((t) => t.bridgeServerState === "cancel_requested" && t.lastCliState === "running");
49040
- if (cancelRow) {
49041
- const localCancelHandled = await deps.acpManager.cancelRun(cancelRow.turnId);
49042
- if (!localCancelHandled) {
49043
- deps.log(
49044
- `[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.`
49045
- );
49046
- await finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, { terminalCliState: "cancelled" });
49047
- const ws = deps.getWs();
49048
- if (ws && cancelRow.sessionId) {
49049
- sendWsMessage(ws, {
49050
- type: "prompt_result",
49051
- sessionId: cancelRow.sessionId,
49052
- runId: cancelRow.turnId,
49053
- success: false,
49054
- error: "Stopped by user",
49055
- stopReason: "cancelled"
49056
- });
49057
- }
49058
- }
49059
- }
49060
- }
49114
+ // src/prompt-turn-queue/runner/start-prompt-queue-runs.ts
49115
+ async function startPromptQueueRuns(entries, deps) {
49061
49116
  const report = {};
49062
- const startedThisTick = /* @__PURE__ */ new Set();
49063
- for (const [queueKey, serverTurns] of Object.entries(raw)) {
49064
- if (!Array.isArray(serverTurns)) continue;
49117
+ const started = /* @__PURE__ */ new Set();
49118
+ for (const [queueKey] of entries) {
49065
49119
  const file2 = await readPersistedQueue(queueKey);
49066
- if (!file2) continue;
49067
- if (hasRunningTurn(file2.turns)) continue;
49120
+ if (!file2 || hasRunningTurn(file2.turns)) continue;
49068
49121
  const next = pickNextRunnableTurn(file2.turns);
49069
49122
  if (!next) continue;
49070
49123
  if (!await runLocalRevertBeforeQueuedPrompt(next, deps)) {
49071
49124
  next.lastCliState = "failed";
49072
49125
  await writePersistedQueue(file2);
49073
- sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: next.turnId, cliState: "failed" }] });
49126
+ sendPromptQueueClientReport(deps.getWs(), { [queueKey]: [{ turnId: next.turnId, cliState: "failed" }] });
49074
49127
  continue;
49075
49128
  }
49076
49129
  next.lastCliState = "running";
49077
49130
  await writePersistedQueue(file2);
49078
49131
  setRunIdQueueKey(next.turnId, queueKey);
49079
- startedThisTick.add(next.turnId);
49132
+ started.add(next.turnId);
49080
49133
  report[queueKey] = [{ turnId: next.turnId, cliState: "running" }];
49134
+ await yieldToEventLoop();
49081
49135
  }
49082
- if (Object.keys(report).length > 0) {
49083
- sendPromptQueueClientReport(getWs(), report);
49084
- }
49085
- for (const [queueKey, serverTurns] of Object.entries(raw)) {
49086
- if (!Array.isArray(serverTurns)) continue;
49087
- const file2 = await readPersistedQueue(queueKey);
49088
- if (!file2) continue;
49089
- const running = file2.turns.find((t) => t.lastCliState === "running");
49090
- if (!running || !startedThisTick.has(running.turnId)) continue;
49091
- if (getRunIdQueueKey(running.turnId) !== queueKey) continue;
49092
- dispatchLocalPrompt(running, deps);
49093
- }
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);
49094
49149
  }
49095
49150
 
49096
49151
  // src/agents/acp/from-bridge/bridge-prompt-wiring.ts
@@ -49356,10 +49411,34 @@ var handlePromptMessage = (msg, deps) => {
49356
49411
  handleBridgePrompt(msg, deps);
49357
49412
  };
49358
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
+
49359
49434
  // src/routing/handlers/prompt-queue-state.ts
49360
49435
  var handlePromptQueueStateMessage = (msg, deps) => {
49361
- void applyPromptQueueStateFromServer(msg, deps).catch((err) => {
49362
- deps.log(`[Queue] applyPromptQueueStateFromServer failed: ${err instanceof Error ? err.message : String(err)}`);
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
+ }
49363
49442
  });
49364
49443
  };
49365
49444