@buildautomaton/cli 0.1.76 → 0.1.77

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
@@ -30606,7 +30606,7 @@ function installBridgeProcessResilience() {
30606
30606
  }
30607
30607
 
30608
30608
  // src/cli-version.ts
30609
- var CLI_VERSION = "0.1.76".length > 0 ? "0.1.76" : "0.0.0-dev";
30609
+ var CLI_VERSION = "0.1.77".length > 0 ? "0.1.77" : "0.0.0-dev";
30610
30610
 
30611
30611
  // src/connection/heartbeat/constants.ts
30612
30612
  var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
@@ -33224,9 +33224,12 @@ function cancelPendingCursorPermissionRequests(pendingRequests2, respond) {
33224
33224
  // src/agents/acp/clients/cursor/create-cursor-acp-handle.ts
33225
33225
  function createCursorAcpHandle(options) {
33226
33226
  let teardownStarted = false;
33227
+ let cancelFallback = null;
33227
33228
  async function disconnectGracefully() {
33228
33229
  if (teardownStarted) return;
33229
33230
  teardownStarted = true;
33231
+ if (cancelFallback) clearTimeout(cancelFallback);
33232
+ cancelFallback = null;
33230
33233
  cancelPendingCursorPermissionRequests(options.pendingRequests, options.wire.respond);
33231
33234
  try {
33232
33235
  await options.transport.cancelSession(options.sessionId);
@@ -33252,7 +33255,17 @@ function createCursorAcpHandle(options) {
33252
33255
  },
33253
33256
  async cancel() {
33254
33257
  cancelPendingCursorPermissionRequests(options.pendingRequests, options.wire.respond);
33255
- await options.transport.cancelSession(options.sessionId);
33258
+ try {
33259
+ await options.transport.cancelSession(options.sessionId);
33260
+ } catch {
33261
+ }
33262
+ if (cancelFallback) return;
33263
+ cancelFallback = setTimeout(() => {
33264
+ if (options.child.exitCode == null && options.child.signalCode == null) {
33265
+ void disconnectGracefully();
33266
+ }
33267
+ }, 5e3);
33268
+ cancelFallback.unref?.();
33256
33269
  },
33257
33270
  resolveRequest(requestId, result) {
33258
33271
  if (options.pendingRequests.has(requestId)) {
@@ -35008,6 +35021,66 @@ function augmentPromptResultAuthFields(agentType, errorText) {
35008
35021
  return { agentAuthRequired: true, agentType };
35009
35022
  }
35010
35023
 
35024
+ // src/agents/planning/submit-planning-todos-for-turn.ts
35025
+ async function submitPlanningTodosForTurn(params) {
35026
+ const token = params.getCloudAccessToken();
35027
+ if (!token.trim()) return { ok: false, error: "Missing cloud access token" };
35028
+ const base = params.cloudApiBaseUrl.replace(/\/$/, "");
35029
+ const url2 = `${base}/internal/sessions/todos/submit`;
35030
+ const res = await fetch(url2, {
35031
+ method: "POST",
35032
+ headers: {
35033
+ Authorization: `Bearer ${token}`,
35034
+ "Content-Type": "application/json"
35035
+ },
35036
+ body: JSON.stringify({
35037
+ sessionId: params.sessionId,
35038
+ turnId: params.turnId,
35039
+ items: params.items
35040
+ })
35041
+ });
35042
+ if (!res.ok) {
35043
+ const body = await res.json().catch(() => null);
35044
+ return { ok: false, error: body?.error ?? `Planning todo submit failed (${res.status})` };
35045
+ }
35046
+ return { ok: true };
35047
+ }
35048
+
35049
+ // src/agents/planning/maybe-submit-planning-todos-after-agent-success.ts
35050
+ async function maybeSubmitPlanningTodosAfterAgentSuccess(params) {
35051
+ const { sessionId, runId, resultSuccess, output, cloudApiBaseUrl, getCloudAccessToken, log: log2 } = params;
35052
+ const buffered = runId ? getPlanningSessionTurnOutput(runId) : "";
35053
+ const outputFromResult = typeof output === "string" ? output : "";
35054
+ const outputStr = buffered.trim() !== "" ? buffered : outputFromResult;
35055
+ if (!sessionId || !runId || !resultSuccess || outputStr.trim() === "") {
35056
+ return { submitted: false, suppressOutput: false };
35057
+ }
35058
+ if (!cloudApiBaseUrl || !getCloudAccessToken) {
35059
+ return { submitted: false, suppressOutput: false };
35060
+ }
35061
+ const items = parsePlanningTodoAgentJson(outputStr);
35062
+ if (items.length === 0) {
35063
+ return { submitted: false, suppressOutput: false };
35064
+ }
35065
+ const result = await submitPlanningTodosForTurn({
35066
+ sessionId,
35067
+ turnId: runId,
35068
+ items,
35069
+ cloudApiBaseUrl,
35070
+ getCloudAccessToken
35071
+ });
35072
+ if (!result.ok) {
35073
+ log2(`[Agent] Planning todo submit failed: ${result.error}`);
35074
+ return { submitted: false, suppressOutput: false };
35075
+ }
35076
+ if (runId) consumePlanningSessionTurnOutput(runId);
35077
+ log2(`[Agent] Planning session: stored ${items.length} todo(s) via internal API`);
35078
+ return { submitted: true, suppressOutput: true };
35079
+ }
35080
+
35081
+ // src/agents/acp/prompts/report-post-turn-enrichment.ts
35082
+ init_yield_to_event_loop();
35083
+
35011
35084
  // src/git/git-runtime.ts
35012
35085
  init_cli_process_interrupt();
35013
35086
  var activeGitChildProcesses = /* @__PURE__ */ new Set();
@@ -35370,61 +35443,30 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
35370
35443
  });
35371
35444
  }
35372
35445
 
35373
- // src/agents/planning/submit-planning-todos-for-turn.ts
35374
- async function submitPlanningTodosForTurn(params) {
35375
- const token = params.getCloudAccessToken();
35376
- if (!token.trim()) return { ok: false, error: "Missing cloud access token" };
35377
- const base = params.cloudApiBaseUrl.replace(/\/$/, "");
35378
- const url2 = `${base}/internal/sessions/todos/submit`;
35379
- const res = await fetch(url2, {
35380
- method: "POST",
35381
- headers: {
35382
- Authorization: `Bearer ${token}`,
35383
- "Content-Type": "application/json"
35384
- },
35385
- body: JSON.stringify({
35386
- sessionId: params.sessionId,
35387
- turnId: params.turnId,
35388
- items: params.items
35389
- })
35390
- });
35391
- if (!res.ok) {
35392
- const body = await res.json().catch(() => null);
35393
- return { ok: false, error: body?.error ?? `Planning todo submit failed (${res.status})` };
35394
- }
35395
- return { ok: true };
35396
- }
35397
-
35398
- // src/agents/planning/maybe-submit-planning-todos-after-agent-success.ts
35399
- async function maybeSubmitPlanningTodosAfterAgentSuccess(params) {
35400
- const { sessionId, runId, resultSuccess, output, cloudApiBaseUrl, getCloudAccessToken, log: log2 } = params;
35401
- const buffered = runId ? getPlanningSessionTurnOutput(runId) : "";
35402
- const outputFromResult = typeof output === "string" ? output : "";
35403
- const outputStr = buffered.trim() !== "" ? buffered : outputFromResult;
35404
- if (!sessionId || !runId || !resultSuccess || outputStr.trim() === "") {
35405
- return { submitted: false, suppressOutput: false };
35406
- }
35407
- if (!cloudApiBaseUrl || !getCloudAccessToken) {
35408
- return { submitted: false, suppressOutput: false };
35409
- }
35410
- const items = parsePlanningTodoAgentJson(outputStr);
35411
- if (items.length === 0) {
35412
- return { submitted: false, suppressOutput: false };
35413
- }
35414
- const result = await submitPlanningTodosForTurn({
35415
- sessionId,
35416
- turnId: runId,
35417
- items,
35418
- cloudApiBaseUrl,
35419
- getCloudAccessToken
35446
+ // src/agents/acp/prompts/report-post-turn-enrichment.ts
35447
+ function reportPostTurnEnrichment(options) {
35448
+ void (async () => {
35449
+ const {
35450
+ sessionId,
35451
+ runId,
35452
+ agentCwd,
35453
+ result,
35454
+ sendSessionUpdate,
35455
+ log: log2
35456
+ } = options;
35457
+ await yieldToEventLoop();
35458
+ if (sessionId && runId && sendSessionUpdate && agentCwd && result.success) {
35459
+ await collectTurnGitDiffFromPreTurnSnapshot({
35460
+ sessionId,
35461
+ runId,
35462
+ agentCwd,
35463
+ sendSessionUpdate,
35464
+ log: log2
35465
+ });
35466
+ }
35467
+ })().catch((error40) => {
35468
+ options.log(`[Agent] Post-turn enrichment failed: ${error40 instanceof Error ? error40.message : String(error40)}`);
35420
35469
  });
35421
- if (!result.ok) {
35422
- log2(`[Agent] Planning todo submit failed: ${result.error}`);
35423
- return { submitted: false, suppressOutput: false };
35424
- }
35425
- if (runId) consumePlanningSessionTurnOutput(runId);
35426
- log2(`[Agent] Planning session: stored ${items.length} todo(s) via internal API`);
35427
- return { submitted: true, suppressOutput: true };
35428
35470
  }
35429
35471
 
35430
35472
  // src/agents/acp/prompts/finalize-and-send-prompt-result.ts
@@ -35444,16 +35486,7 @@ async function finalizeAndSendPromptResult(params) {
35444
35486
  sendSessionUpdate,
35445
35487
  log: log2
35446
35488
  } = params;
35447
- if (sessionId && runId && sendSessionUpdate && agentCwd && result.success) {
35448
- await collectTurnGitDiffFromPreTurnSnapshot({
35449
- sessionId,
35450
- runId,
35451
- agentCwd,
35452
- sendSessionUpdate,
35453
- log: log2
35454
- });
35455
- }
35456
- const planningTodosSubmit = await maybeSubmitPlanningTodosAfterAgentSuccess({
35489
+ const planningTodosSubmit = isPlanningSession ? await maybeSubmitPlanningTodosAfterAgentSuccess({
35457
35490
  sessionId,
35458
35491
  runId,
35459
35492
  resultSuccess: result.success === true,
@@ -35461,11 +35494,11 @@ async function finalizeAndSendPromptResult(params) {
35461
35494
  cloudApiBaseUrl,
35462
35495
  getCloudAccessToken,
35463
35496
  log: log2
35464
- });
35497
+ }) : { suppressOutput: false };
35498
+ const planningFallbackOutput = !planningTodosSubmit.suppressOutput && isPlanningSession && runId ? consumePlanningSessionTurnOutput(runId) : "";
35465
35499
  const errStr = typeof result.error === "string" ? result.error : void 0;
35466
35500
  const resultStop = typeof result.stopReason === "string" ? result.stopReason.trim() : "";
35467
35501
  const cancelledByAgent = resultStop.toLowerCase() === "cancelled" || errStr != null && isUserEndedSessionTurnErrorText(errStr);
35468
- const planningFallbackOutput = !planningTodosSubmit.suppressOutput && isPlanningSession && runId ? consumePlanningSessionTurnOutput(runId) : "";
35469
35502
  sendResult({
35470
35503
  type: "prompt_result",
35471
35504
  id: promptId,
@@ -35486,6 +35519,14 @@ async function finalizeAndSendPromptResult(params) {
35486
35519
  );
35487
35520
  }
35488
35521
  }
35522
+ void reportPostTurnEnrichment({
35523
+ sessionId,
35524
+ runId,
35525
+ agentCwd,
35526
+ result,
35527
+ sendSessionUpdate,
35528
+ log: log2
35529
+ });
35489
35530
  }
35490
35531
 
35491
35532
  // src/agents/acp/build-forked-session-agent-prompt.ts
@@ -36034,7 +36075,6 @@ async function sendPromptToAgent(options) {
36034
36075
  followUpCatalogPromptId,
36035
36076
  cloudApiBaseUrl,
36036
36077
  getCloudAccessToken,
36037
- e2ee,
36038
36078
  sendResult,
36039
36079
  sendSessionUpdate,
36040
36080
  log: log2
@@ -36057,16 +36097,6 @@ async function sendPromptToAgent(options) {
36057
36097
  }
36058
36098
  }
36059
36099
 
36060
- // src/agents/acp/manager/get-acp-agent-state.ts
36061
- function getAcpSessionAgentState(ctx, acpSessionAgentKey) {
36062
- let state = ctx.acpAgents.get(acpSessionAgentKey);
36063
- if (!state) {
36064
- state = createEmptyAcpClientState();
36065
- ctx.acpAgents.set(acpSessionAgentKey, state);
36066
- }
36067
- return state;
36068
- }
36069
-
36070
36100
  // src/agents/acp/manager/handle-pending-prompt-cancel.ts
36071
36101
  async function handlePendingPromptCancel(params) {
36072
36102
  const { ctx, activeRunId, promptId, sessionId, handle, sendResult } = params;
@@ -36090,94 +36120,104 @@ async function handlePendingPromptCancel(params) {
36090
36120
  return true;
36091
36121
  }
36092
36122
 
36093
- // src/agents/acp/manager/run-acp-prompt.ts
36094
- async function runAcpPrompt(ctx, runCtx, opts) {
36095
- const {
36096
- promptText,
36097
- promptId,
36098
- sessionId,
36099
- mode,
36100
- agentConfig,
36101
- sessionParentPath,
36102
- sendResult,
36103
- sendSessionUpdate,
36104
- followUpCatalogPromptId,
36105
- cloudApiBaseUrl,
36106
- getCloudAccessToken,
36107
- e2ee,
36108
- attachments,
36109
- isNewSession
36110
- } = opts;
36111
- const { activeRunId, activeAcpAgentKey, activeAcpSessionAgentKey, preferredForPrompt } = runCtx;
36112
- const acpAgentState = getAcpSessionAgentState(ctx, activeAcpSessionAgentKey);
36113
- const handle = await ensureAcpClient({
36114
- state: acpAgentState,
36115
- acpAgentKey: activeAcpAgentKey,
36116
- preferredAgentType: preferredForPrompt,
36117
- mode,
36118
- agentConfig: agentConfig ?? null,
36119
- sessionParentPath,
36120
- resolveRouting: () => ctx.promptRouting.resolveRouting(activeAcpSessionAgentKey),
36121
- cloudSessionId: sessionId,
36122
- bridgeAccessPort: ctx.getBridgeAccessPort(),
36123
- sendSessionUpdate,
36124
- sendRequest: sendSessionUpdate,
36125
- log: ctx.log,
36126
- reportAgentCapabilities: ctx.reportAgentCapabilities
36127
- });
36128
- if (!handle) {
36129
- const errMsg = acpAgentState.lastAcpStartError || "No agent configured. Register local agents on this bridge in the app.";
36130
- const evaluated = Boolean(preferredForPrompt && errMsg.trim());
36131
- const suggestsAuth = evaluated ? localAgentErrorSuggestsAuth(preferredForPrompt, errMsg) : false;
36132
- const auth = suggestsAuth && preferredForPrompt ? { agentAuthRequired: true, agentType: preferredForPrompt } : {};
36133
- sendResult({
36123
+ // src/agents/acp/manager/dispatch-acp-prompt.ts
36124
+ async function dispatchAcpPrompt(ctx, runCtx, opts, handle) {
36125
+ const { activeRunId, activeAcpSessionAgentKey, preferredForPrompt } = runCtx;
36126
+ if (!ctx.promptRouting.isRegisteredRun(activeRunId)) {
36127
+ opts.sendResult({
36134
36128
  type: "prompt_result",
36135
- id: promptId,
36136
- ...sessionId ? { sessionId } : {},
36129
+ id: opts.promptId,
36130
+ ...opts.sessionId ? { sessionId: opts.sessionId } : {},
36137
36131
  runId: activeRunId,
36138
36132
  success: false,
36139
- error: errMsg,
36140
- ...auth
36133
+ error: "Prompt dispatch was superseded before the agent started."
36141
36134
  });
36142
36135
  return;
36143
36136
  }
36144
- if (!ctx.promptRouting.isRegisteredRun(activeRunId)) {
36145
- return;
36146
- }
36147
36137
  const cancelled = await handlePendingPromptCancel({
36148
36138
  ctx,
36149
36139
  activeRunId,
36150
- promptId,
36151
- sessionId,
36140
+ promptId: opts.promptId,
36141
+ sessionId: opts.sessionId,
36152
36142
  handle,
36153
- sendResult
36143
+ sendResult: opts.sendResult
36154
36144
  });
36155
36145
  if (cancelled) return;
36156
36146
  ctx.promptRouting.setStreamingRunId(activeAcpSessionAgentKey, activeRunId);
36157
36147
  try {
36158
36148
  await sendPromptToAgent({
36159
36149
  handle,
36160
- promptText,
36161
- promptId,
36162
- sessionId,
36150
+ promptText: opts.promptText,
36151
+ promptId: opts.promptId,
36152
+ sessionId: opts.sessionId,
36163
36153
  runId: activeRunId,
36164
36154
  agentType: preferredForPrompt,
36165
- agentCwd: resolveSessionParentPathForAgentProcess(sessionParentPath),
36166
- sendResult,
36167
- sendSessionUpdate,
36155
+ agentCwd: resolveSessionParentPathForAgentProcess(opts.sessionParentPath),
36156
+ sendResult: opts.sendResult,
36157
+ sendSessionUpdate: opts.sendSessionUpdate,
36168
36158
  log: ctx.log,
36169
- followUpCatalogPromptId,
36170
- cloudApiBaseUrl,
36171
- getCloudAccessToken,
36172
- e2ee,
36173
- attachments,
36174
- isNewSession
36159
+ followUpCatalogPromptId: opts.followUpCatalogPromptId,
36160
+ cloudApiBaseUrl: opts.cloudApiBaseUrl,
36161
+ getCloudAccessToken: opts.getCloudAccessToken,
36162
+ e2ee: opts.e2ee,
36163
+ attachments: opts.attachments,
36164
+ isNewSession: opts.isNewSession
36175
36165
  });
36176
36166
  } finally {
36177
36167
  ctx.promptRouting.clearStreamingRunId(activeAcpSessionAgentKey, activeRunId);
36178
36168
  }
36179
36169
  }
36180
36170
 
36171
+ // src/agents/acp/manager/get-acp-agent-state.ts
36172
+ function getAcpSessionAgentState(ctx, acpSessionAgentKey) {
36173
+ let state = ctx.acpAgents.get(acpSessionAgentKey);
36174
+ if (!state) {
36175
+ state = createEmptyAcpClientState();
36176
+ ctx.acpAgents.set(acpSessionAgentKey, state);
36177
+ }
36178
+ return state;
36179
+ }
36180
+
36181
+ // src/agents/acp/manager/ensure-acp-prompt-client.ts
36182
+ async function ensureAcpPromptClient(ctx, runCtx, opts) {
36183
+ const state = getAcpSessionAgentState(ctx, runCtx.activeAcpSessionAgentKey);
36184
+ const handle = await ensureAcpClient({
36185
+ state,
36186
+ acpAgentKey: runCtx.activeAcpAgentKey,
36187
+ preferredAgentType: runCtx.preferredForPrompt,
36188
+ mode: opts.mode,
36189
+ agentConfig: opts.agentConfig ?? null,
36190
+ sessionParentPath: opts.sessionParentPath,
36191
+ resolveRouting: () => ctx.promptRouting.resolveRouting(runCtx.activeAcpSessionAgentKey),
36192
+ cloudSessionId: opts.sessionId,
36193
+ bridgeAccessPort: ctx.getBridgeAccessPort(),
36194
+ sendSessionUpdate: opts.sendSessionUpdate,
36195
+ sendRequest: opts.sendSessionUpdate,
36196
+ log: ctx.log,
36197
+ reportAgentCapabilities: ctx.reportAgentCapabilities
36198
+ });
36199
+ if (handle) return handle;
36200
+ const error40 = state.lastAcpStartError || "No agent configured. Register local agents on this bridge in the app.";
36201
+ const agentType = runCtx.preferredForPrompt;
36202
+ const requiresAuth = Boolean(agentType && localAgentErrorSuggestsAuth(agentType, error40));
36203
+ opts.sendResult({
36204
+ type: "prompt_result",
36205
+ id: opts.promptId,
36206
+ ...opts.sessionId ? { sessionId: opts.sessionId } : {},
36207
+ runId: runCtx.activeRunId,
36208
+ success: false,
36209
+ error: error40,
36210
+ ...requiresAuth && agentType ? { agentAuthRequired: true, agentType } : {}
36211
+ });
36212
+ return null;
36213
+ }
36214
+
36215
+ // src/agents/acp/manager/run-acp-prompt.ts
36216
+ async function runAcpPrompt(ctx, runCtx, opts) {
36217
+ const handle = await ensureAcpPromptClient(ctx, runCtx, opts);
36218
+ if (handle) await dispatchAcpPrompt(ctx, runCtx, opts, handle);
36219
+ }
36220
+
36181
36221
  // src/agents/acp/manager/handle-prompt.ts
36182
36222
  function handlePrompt(ctx, opts) {
36183
36223
  const { promptId, sessionId, runId, mode, agentType, agentConfig, sendResult } = opts;
@@ -48878,9 +48918,6 @@ function setRunIdQueueKey(runId, queueKey) {
48878
48918
  runIdToQueueKey.set(runId, queueKey);
48879
48919
  locallyDispatchedRunIds.add(runId);
48880
48920
  }
48881
- function isLocallyDispatchedRun(runId) {
48882
- return locallyDispatchedRunIds.has(runId);
48883
- }
48884
48921
  function deleteRunIdQueueKey(runId) {
48885
48922
  const queueKey = runIdToQueueKey.get(runId);
48886
48923
  runIdToQueueKey.delete(runId);
@@ -48907,11 +48944,39 @@ async function dispatchStartedPromptQueueRuns(entries, started, deps) {
48907
48944
 
48908
48945
  // src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
48909
48946
  init_yield_to_event_loop();
48947
+
48948
+ // src/prompt-turn-queue/client-report.ts
48949
+ function sendPromptQueueClientReport(ws, queues) {
48950
+ if (!ws) return false;
48951
+ const wireQueues = {};
48952
+ for (const [queueKey, rows] of Object.entries(queues)) {
48953
+ wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
48954
+ }
48955
+ sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
48956
+ return true;
48957
+ }
48958
+
48959
+ // src/prompt-turn-queue/runner/finalize-prompt-turn-on-bridge.ts
48960
+ async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
48961
+ if (!runId) return false;
48962
+ const queueKey = deleteRunIdQueueKey(runId);
48963
+ if (!queueKey) return false;
48964
+ const f = await readPersistedQueue(queueKey);
48965
+ if (!f) return false;
48966
+ const t = f.turns.find((x) => x.turnId === runId);
48967
+ if (!t) return false;
48968
+ t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
48969
+ await writePersistedQueue(f);
48970
+ sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
48971
+ return true;
48972
+ }
48973
+
48974
+ // src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
48910
48975
  async function handlePromptQueueCancellations(entries, deps) {
48911
48976
  for (const [queueKey] of entries) {
48912
48977
  const file2 = await readPersistedQueue(queueKey);
48913
48978
  const turn = file2?.turns.find((row) => row.bridgeServerState === "cancel_requested" && row.lastCliState === "running");
48914
- if (!turn || getRunIdQueueKey(turn.turnId) !== queueKey || !isLocallyDispatchedRun(turn.turnId)) {
48979
+ if (!turn || getRunIdQueueKey(turn.turnId) !== queueKey) {
48915
48980
  await yieldToEventLoop();
48916
48981
  continue;
48917
48982
  }
@@ -48920,7 +48985,8 @@ async function handlePromptQueueCancellations(entries, deps) {
48920
48985
  await yieldToEventLoop();
48921
48986
  continue;
48922
48987
  }
48923
- deps.log(`[Queue] cancel_requested for ${turn.turnId.slice(0, 8)}\u2026 but no local ACP run remains.`);
48988
+ deps.log(`[Queue] No local ACP run remains for ${turn.turnId.slice(0, 8)}\u2026; reconciling cancelled turn.`);
48989
+ await finalizePromptTurnOnBridge(deps.getWs, turn.turnId, false, { terminalCliState: "cancelled" });
48924
48990
  await yieldToEventLoop();
48925
48991
  }
48926
48992
  }
@@ -48948,17 +49014,6 @@ function promptQueueSnapshotEntries(queues) {
48948
49014
  // src/prompt-turn-queue/runner/start-prompt-queue-runs.ts
48949
49015
  init_yield_to_event_loop();
48950
49016
 
48951
- // src/prompt-turn-queue/client-report.ts
48952
- function sendPromptQueueClientReport(ws, queues) {
48953
- if (!ws) return false;
48954
- const wireQueues = {};
48955
- for (const [queueKey, rows] of Object.entries(queues)) {
48956
- wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
48957
- }
48958
- sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
48959
- return true;
48960
- }
48961
-
48962
49017
  // src/prompt-turn-queue/runner/queue-selection.ts
48963
49018
  function pickNextRunnableTurn(turns) {
48964
49019
  for (const t of turns) {
@@ -49132,21 +49187,6 @@ async function applyPromptQueueStateFromServer(msg, deps) {
49132
49187
  await dispatchStartedPromptQueueRuns(entries, started, deps);
49133
49188
  }
49134
49189
 
49135
- // src/prompt-turn-queue/runner/finalize-prompt-turn-on-bridge.ts
49136
- async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
49137
- if (!runId) return false;
49138
- const queueKey = deleteRunIdQueueKey(runId);
49139
- if (!queueKey) return false;
49140
- const f = await readPersistedQueue(queueKey);
49141
- if (!f) return false;
49142
- const t = f.turns.find((x) => x.turnId === runId);
49143
- if (!t) return false;
49144
- t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
49145
- await writePersistedQueue(f);
49146
- sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
49147
- return true;
49148
- }
49149
-
49150
49190
  // src/agents/acp/from-bridge/bridge-prompt-wiring.ts
49151
49191
  function createBridgePromptSenders(deps, getWs) {
49152
49192
  const sendBridgeMessage = (message, encryptedFields = []) => {
@@ -49336,17 +49376,14 @@ function handleBridgePrompt(msg, deps) {
49336
49376
  log2(
49337
49377
  `[Bridge service] Prompt ignored: empty or missing prompt text (session ${typeof msg.sessionId === "string" ? msg.sessionId.slice(0, 8) : "\u2014"}\u2026, run ${typeof msg.runId === "string" ? msg.runId.slice(0, 8) : "\u2014"}\u2026).`
49338
49378
  );
49339
- senders.sendBridgeMessage(
49340
- {
49341
- type: "prompt_result",
49342
- ...promptId ? { id: promptId } : {},
49343
- ...sessionId ? { sessionId } : {},
49344
- ...runId ? { runId } : {},
49345
- success: false,
49346
- error: "Empty or missing prompt text from the bridge; this turn was not sent to the agent."
49347
- },
49348
- ["error"]
49349
- );
49379
+ senders.sendResult({
49380
+ type: "prompt_result",
49381
+ ...promptId ? { id: promptId } : {},
49382
+ ...sessionId ? { sessionId } : {},
49383
+ ...runId ? { runId } : {},
49384
+ success: false,
49385
+ error: "Empty or missing prompt text from the bridge; this turn was not sent to the agent."
49386
+ });
49350
49387
  return;
49351
49388
  }
49352
49389
  const isNewSession = msg.isNewSession === true;