@buildautomaton/cli 0.1.92 → 0.1.94

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 CHANGED
@@ -23755,6 +23755,15 @@ var init_acp = __esm({
23755
23755
  }
23756
23756
  });
23757
23757
 
23758
+ // ../bridge/src/runtime/yield-to-event-loop.ts
23759
+ function yieldToEventLoop() {
23760
+ return new Promise((resolve39) => setImmediate(resolve39));
23761
+ }
23762
+ var init_yield_to_event_loop = __esm({
23763
+ "../bridge/src/runtime/yield-to-event-loop.ts"() {
23764
+ }
23765
+ });
23766
+
23758
23767
  // ../bridge/src/files/index/constants.ts
23759
23768
  import path3 from "node:path";
23760
23769
  import os from "node:os";
@@ -24026,15 +24035,6 @@ var init_activity_tracker = __esm({
24026
24035
  }
24027
24036
  });
24028
24037
 
24029
- // ../bridge/src/runtime/yield-to-event-loop.ts
24030
- function yieldToEventLoop() {
24031
- return new Promise((resolve39) => setImmediate(resolve39));
24032
- }
24033
- var init_yield_to_event_loop = __esm({
24034
- "../bridge/src/runtime/yield-to-event-loop.ts"() {
24035
- }
24036
- });
24037
-
24038
24038
  // ../bridge/src/code-nav/symbol-index/deferred-indexing.ts
24039
24039
  function isSymbolIndexDeferredError(err) {
24040
24040
  return err instanceof SymbolIndexDeferredError;
@@ -24371,6 +24371,7 @@ function resetCodeNavCacheAvailabilityForTests() {
24371
24371
  var initState, initPromise, CodeNavCacheUnavailableError;
24372
24372
  var init_code_nav_cache_availability = __esm({
24373
24373
  "../bridge/src/sqlite/code-nav-cache/code-nav-cache-availability.ts"() {
24374
+ "use strict";
24374
24375
  init_log();
24375
24376
  init_in_flight();
24376
24377
  init_sqlite_errors();
@@ -30448,7 +30449,7 @@ var {
30448
30449
  } = import_index.default;
30449
30450
 
30450
30451
  // src/cli-version.ts
30451
- var CLI_VERSION = "0.1.92".length > 0 ? "0.1.92" : "0.0.0-dev";
30452
+ var CLI_VERSION = "0.1.94".length > 0 ? "0.1.94" : "0.0.0-dev";
30452
30453
 
30453
30454
  // src/cli/defaults.ts
30454
30455
  var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
@@ -30468,6 +30469,12 @@ var wrapper_default = import_websocket.default;
30468
30469
  // ../bridge/src/connection/ws/cli-ws-client.ts
30469
30470
  import https from "node:https";
30470
30471
  var CLI_WEBSOCKET_CLIENT_PING_MS = 25e3;
30472
+ var CLI_WEBSOCKET_HANDSHAKE_TIMEOUT_MS = 15e3;
30473
+ var sharedWssAgent = null;
30474
+ function cliWssAgent() {
30475
+ sharedWssAgent ??= new https.Agent({ rejectUnauthorized: false, keepAlive: true });
30476
+ return sharedWssAgent;
30477
+ }
30471
30478
  function attachWebSocketClientPing(ws, intervalMs) {
30472
30479
  let timer = null;
30473
30480
  function clear() {
@@ -30488,9 +30495,12 @@ function attachWebSocketClientPing(ws, intervalMs) {
30488
30495
  return clear;
30489
30496
  }
30490
30497
  function buildCliWebSocketClientOptions(wsUrl) {
30491
- const wsOptions = { perMessageDeflate: false };
30498
+ const wsOptions = {
30499
+ perMessageDeflate: false,
30500
+ handshakeTimeout: CLI_WEBSOCKET_HANDSHAKE_TIMEOUT_MS
30501
+ };
30492
30502
  if (wsUrl.startsWith("wss://")) {
30493
- wsOptions.agent = new https.Agent({ rejectUnauthorized: false });
30503
+ wsOptions.agent = cliWssAgent();
30494
30504
  }
30495
30505
  return wsOptions;
30496
30506
  }
@@ -30504,6 +30514,15 @@ function safeCloseWebSocket(ws) {
30504
30514
  ws.removeAllListeners();
30505
30515
  return;
30506
30516
  }
30517
+ if (ws.readyState === wrapper_default.CONNECTING) {
30518
+ ws.once("error", () => {
30519
+ });
30520
+ ws.once("close", () => {
30521
+ ws.removeAllListeners();
30522
+ });
30523
+ ws.terminate();
30524
+ return;
30525
+ }
30507
30526
  ws.once("close", () => {
30508
30527
  ws.removeAllListeners();
30509
30528
  });
@@ -35947,6 +35966,24 @@ var RoleLengthWireSchema = external_exports.discriminatedUnion("type", [
35947
35966
  external_exports.object({ type: external_exports.literal("session_count"), max_sessions: MaxSessionsSchema })
35948
35967
  ]);
35949
35968
 
35969
+ // ../types/src/role-access-restrictions.ts
35970
+ var EMPTY_ROLE_ACCESS_RESTRICTIONS = {
35971
+ sessionsOwnAndExplicitOnly: false,
35972
+ bridgesOwnAndExplicitOnly: false,
35973
+ sessionsReadOnlyExceptOwn: false,
35974
+ codeChangesAgentModifiedOnly: false,
35975
+ codeChangesHidden: false
35976
+ };
35977
+ function roleAccessRestrictionsToWire(restrictions) {
35978
+ return {
35979
+ sessions_own_and_explicit_only: restrictions.sessionsOwnAndExplicitOnly,
35980
+ bridges_own_and_explicit_only: restrictions.bridgesOwnAndExplicitOnly,
35981
+ sessions_read_only_except_own: restrictions.sessionsReadOnlyExceptOwn,
35982
+ code_changes_agent_modified_only: restrictions.codeChangesAgentModifiedOnly,
35983
+ code_changes_hidden: restrictions.codeChangesHidden
35984
+ };
35985
+ }
35986
+
35950
35987
  // ../types/src/role-details.ts
35951
35988
  var InitialPeriodDaysSchema = external_exports.number().int().min(ROLE_PERIOD_MIN_DAYS).max(ROLE_PERIOD_MAX_DAYS);
35952
35989
  var AgentSubscriptionIdsSchema = external_exports.array(external_exports.string().min(1)).default([]);
@@ -35956,15 +35993,33 @@ var RoleDetailsSchema = external_exports.object({
35956
35993
  length: RoleLengthSchema.nullable(),
35957
35994
  agentSubscriptionIds: AgentSubscriptionIdsSchema,
35958
35995
  sessionsOwnAndExplicitOnly: BoolFalseSchema,
35959
- bridgesOwnAndExplicitOnly: BoolFalseSchema
35996
+ bridgesOwnAndExplicitOnly: BoolFalseSchema,
35997
+ sessionsReadOnlyExceptOwn: BoolFalseSchema,
35998
+ codeChangesAgentModifiedOnly: BoolFalseSchema,
35999
+ codeChangesHidden: BoolFalseSchema
35960
36000
  });
35961
36001
  var RoleDetailsWireSchema = external_exports.object({
35962
36002
  payment: RolePaymentModelWireSchema.nullable(),
35963
36003
  length: RoleLengthWireSchema.nullable(),
35964
36004
  agent_subscription_ids: AgentSubscriptionIdsSchema,
35965
36005
  sessions_own_and_explicit_only: BoolFalseSchema,
35966
- bridges_own_and_explicit_only: BoolFalseSchema
35967
- });
36006
+ bridges_own_and_explicit_only: BoolFalseSchema,
36007
+ sessions_read_only_except_own: BoolFalseSchema,
36008
+ code_changes_agent_modified_only: BoolFalseSchema,
36009
+ code_changes_hidden: BoolFalseSchema
36010
+ });
36011
+ var EMPTY_ROLE_DETAILS = {
36012
+ payment: null,
36013
+ length: null,
36014
+ agentSubscriptionIds: [],
36015
+ ...EMPTY_ROLE_ACCESS_RESTRICTIONS
36016
+ };
36017
+ var EMPTY_ROLE_DETAILS_WIRE = {
36018
+ payment: null,
36019
+ length: null,
36020
+ agent_subscription_ids: [],
36021
+ ...roleAccessRestrictionsToWire(EMPTY_ROLE_ACCESS_RESTRICTIONS)
36022
+ };
35968
36023
 
35969
36024
  // ../bridge/src/agents/acp/safe-fs-path.ts
35970
36025
  import * as path2 from "node:path";
@@ -36490,7 +36545,25 @@ function spawnSdkStdioProcess(options) {
36490
36545
  return { child, stderrCapture };
36491
36546
  }
36492
36547
 
36548
+ // ../bridge/src/agents/acp/clients/listen-for-acp-client-abort.ts
36549
+ function listenForAcpClientAbort(child, signal, onAbort) {
36550
+ if (!signal) return () => {
36551
+ };
36552
+ const fire = () => {
36553
+ killChildProcessTree(child, "SIGKILL");
36554
+ onAbort();
36555
+ };
36556
+ if (signal.aborted) {
36557
+ fire();
36558
+ return () => {
36559
+ };
36560
+ }
36561
+ signal.addEventListener("abort", fire, { once: true });
36562
+ return () => signal.removeEventListener("abort", fire);
36563
+ }
36564
+
36493
36565
  // ../bridge/src/agents/acp/clients/sdk/sdk-stdio-acp-client.ts
36566
+ init_yield_to_event_loop();
36494
36567
  async function createSdkStdioAcpClient(options) {
36495
36568
  const { PROTOCOL_VERSION: PROTOCOL_VERSION2 } = await Promise.resolve().then(() => (init_acp(), acp_exports));
36496
36569
  const {
@@ -36508,13 +36581,18 @@ async function createSdkStdioAcpClient(options) {
36508
36581
  onAcpConfigOptionsUpdated,
36509
36582
  getActiveConfigOptions,
36510
36583
  afterSessionEstablished,
36511
- createExtNotificationHandler
36584
+ createExtNotificationHandler,
36585
+ signal
36512
36586
  } = options;
36587
+ if (signal?.aborted) {
36588
+ throw new Error("ACP client aborted");
36589
+ }
36513
36590
  const { child, stderrCapture } = spawnSdkStdioProcess({
36514
36591
  command,
36515
36592
  cwd,
36516
36593
  onAgentSubprocessExit
36517
36594
  });
36595
+ await yieldToEventLoop();
36518
36596
  const sessionCtx = createSdkStdioSessionContext({
36519
36597
  cwd,
36520
36598
  mcpServers: options.mcpServers,
@@ -36530,7 +36608,11 @@ async function createSdkStdioAcpClient(options) {
36530
36608
  });
36531
36609
  return new Promise((resolve39, reject) => {
36532
36610
  const init = createSdkStdioInitSettle(child);
36611
+ const stopAbort = listenForAcpClientAbort(child, signal, () => {
36612
+ init.settleReject(reject, new Error("ACP client aborted"));
36613
+ });
36533
36614
  child.on("error", (err) => {
36615
+ stopAbort();
36534
36616
  init.settleReject(reject, new Error(formatSpawnError(err, command[0])));
36535
36617
  });
36536
36618
  attachSdkStdioStderrAuthWatch({
@@ -36564,7 +36646,9 @@ async function createSdkStdioAcpClient(options) {
36564
36646
  killSubprocessAfterCancelMs
36565
36647
  })
36566
36648
  );
36649
+ stopAbort();
36567
36650
  } catch (err) {
36651
+ stopAbort();
36568
36652
  if (init.settled) return;
36569
36653
  init.settleReject(
36570
36654
  reject,
@@ -36836,22 +36920,12 @@ function installBridgeProcessResilience() {
36836
36920
  init_log();
36837
36921
 
36838
36922
  // ../bridge/src/agents/acp/clients/bridge-agent-path.ts
36839
- import { execFileSync } from "node:child_process";
36840
36923
  import { homedir } from "node:os";
36841
36924
  import { join } from "node:path";
36842
36925
  function getBridgeAgentPathEntries(home = process.env.HOME ?? homedir()) {
36843
- const entries = [
36844
- join(home, ".local", "bin"),
36845
- join(home, ".npm-global", "bin"),
36846
- "/usr/local/bin"
36847
- ];
36926
+ const entries = [join(home, ".local", "bin"), join(home, ".npm-global", "bin"), "/usr/local/bin"];
36848
36927
  const prefix = process.env.NPM_CONFIG_PREFIX;
36849
36928
  if (prefix) entries.push(join(prefix, "bin"));
36850
- try {
36851
- const npmBin = execFileSync("npm", ["bin", "-g"], { encoding: "utf8", timeout: 2e3 }).trim();
36852
- if (npmBin) entries.push(npmBin);
36853
- } catch {
36854
- }
36855
36929
  return entries;
36856
36930
  }
36857
36931
  function augmentPath(pathValue, extra) {
@@ -38093,6 +38167,22 @@ function beginDeferredDisconnectForReconnect(options) {
38093
38167
  }
38094
38168
  }
38095
38169
 
38170
+ // ../bridge/src/connection/ws/dispose-previous-bridge-socket.ts
38171
+ function disposePreviousBridgeSocket(ws) {
38172
+ if (!ws) return;
38173
+ ws.removeAllListeners();
38174
+ ws.once("error", () => {
38175
+ });
38176
+ ws.once("close", () => {
38177
+ ws.removeAllListeners();
38178
+ });
38179
+ try {
38180
+ if (ws.readyState === wrapper_default.CONNECTING) ws.terminate();
38181
+ else ws.close();
38182
+ } catch {
38183
+ }
38184
+ }
38185
+
38096
38186
  // ../bridge/src/connection/runtime/close-bridge-connection.ts
38097
38187
  async function closeBridgeConnection(state, acpManager, previewEnvironmentManager, log2) {
38098
38188
  requestCliImmediateShutdown();
@@ -38109,16 +38199,7 @@ async function closeBridgeConnection(state, acpManager, previewEnvironmentManage
38109
38199
  await acpManager.disconnect();
38110
38200
  if (state.currentWs) {
38111
38201
  say("Closing bridge connection to the cloud\u2026");
38112
- state.currentWs.removeAllListeners();
38113
- const wsState = state.currentWs.readyState;
38114
- if (wsState === 1 || wsState === 2) {
38115
- state.currentWs.close();
38116
- } else {
38117
- state.currentWs.on("error", () => {
38118
- });
38119
- state.currentWs.on("close", () => {
38120
- });
38121
- }
38202
+ disposePreviousBridgeSocket(state.currentWs);
38122
38203
  state.currentWs = null;
38123
38204
  }
38124
38205
  if (previewEnvironmentManager) {
@@ -38818,15 +38899,31 @@ function queueCursorCreatePlanRequest(method, id, msg, deps) {
38818
38899
  }
38819
38900
 
38820
38901
  // ../bridge/src/agents/providers/cursor/cursor-incoming-cursor-task.ts
38821
- function buildCursorTaskToolCallUpdate(params) {
38902
+ function asRecord2(v) {
38903
+ return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
38904
+ }
38905
+ function flattenCursorTaskParams(params) {
38906
+ const nested = asRecord2(params.task) ?? asRecord2(params.data) ?? asRecord2(params.payload) ?? asRecord2(params.cursorTask);
38907
+ return nested ? { ...nested, ...params } : params;
38908
+ }
38909
+ function stringField(params, ...keys) {
38910
+ for (const key of keys) {
38911
+ const v = params[key];
38912
+ if (typeof v === "string" && v.trim()) return v.trim();
38913
+ }
38914
+ return void 0;
38915
+ }
38916
+ function buildCursorTaskToolCallUpdate(rawParams) {
38917
+ const params = flattenCursorTaskParams(rawParams);
38822
38918
  const toolCallId = params.toolCallId ?? params.tool_call_id;
38823
38919
  if (typeof toolCallId !== "string" || !toolCallId.trim()) return null;
38824
- const description = typeof params.description === "string" ? params.description.trim() : "";
38920
+ const description = stringField(params, "description");
38825
38921
  const prompt = typeof params.prompt === "string" ? params.prompt : void 0;
38826
38922
  const subagentType = params.subagentType ?? params.subagent_type;
38827
38923
  const model = typeof params.model === "string" ? params.model : void 0;
38828
- const agentId = typeof params.agentId === "string" ? params.agentId : typeof params.agent_id === "string" ? params.agent_id : void 0;
38829
- const durationMs = typeof params.durationMs === "number" ? params.durationMs : typeof params.duration_ms === "number" ? params.duration_ms : void 0;
38924
+ const agentId = stringField(params, "agentId", "agent_id");
38925
+ const rawDuration = params.durationMs ?? params.duration_ms;
38926
+ const durationMs = typeof rawDuration === "number" && Number.isFinite(rawDuration) && rawDuration > 0 ? rawDuration : void 0;
38830
38927
  const isBackground = typeof params.isBackground === "boolean" ? params.isBackground : typeof params.is_background === "boolean" ? params.is_background : typeof params.runInBackground === "boolean" ? params.runInBackground : typeof params.run_in_background === "boolean" ? params.run_in_background : void 0;
38831
38928
  return {
38832
38929
  sessionUpdate: "tool_call_update",
@@ -38995,7 +39092,7 @@ function writeCreatePlanFile(params) {
38995
39092
  }
38996
39093
 
38997
39094
  // ../bridge/src/agents/providers/cursor/enrich-create-plan-rpc-result.ts
38998
- function asRecord2(v) {
39095
+ function asRecord3(v) {
38999
39096
  return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
39000
39097
  }
39001
39098
  function resolveAcceptedPlanMarkdown(outcome, pendingParams) {
@@ -39004,8 +39101,8 @@ function resolveAcceptedPlanMarkdown(outcome, pendingParams) {
39004
39101
  return "";
39005
39102
  }
39006
39103
  function enrichCreatePlanRpcResult(result, pendingParams, cloudSessionId) {
39007
- const root = asRecord2(result);
39008
- const outcome = asRecord2(root?.outcome);
39104
+ const root = asRecord3(result);
39105
+ const outcome = asRecord3(root?.outcome);
39009
39106
  if (!outcome) return result;
39010
39107
  const kind = typeof outcome.outcome === "string" ? outcome.outcome : "";
39011
39108
  if (kind !== "accepted") {
@@ -39296,7 +39393,8 @@ async function createCursorAcpClient(options) {
39296
39393
  onAcpSessionEstablished,
39297
39394
  onAcpConfigOptionsUpdated,
39298
39395
  onAgentSubprocessExit,
39299
- afterSessionEstablished
39396
+ afterSessionEstablished,
39397
+ signal
39300
39398
  } = options;
39301
39399
  const dbgFs = process.env.BUILDAUTOMATON_DEBUG_ACP_FS === "1";
39302
39400
  const spawnEnv = bridgeInstalledAgentAuthProcessEnv(process.env);
@@ -39321,7 +39419,11 @@ async function createCursorAcpClient(options) {
39321
39419
  stderrCapture
39322
39420
  });
39323
39421
  return new Promise((resolve39, reject) => {
39422
+ const stopAbort = listenForAcpClientAbort(child, signal, () => {
39423
+ reject(new Error("ACP client aborted"));
39424
+ });
39324
39425
  child.on("error", (err) => {
39426
+ stopAbort();
39325
39427
  killChildProcessTree(child, "SIGKILL");
39326
39428
  reject(new Error(formatSpawnError(err, command[0])));
39327
39429
  });
@@ -39333,6 +39435,7 @@ async function createCursorAcpClient(options) {
39333
39435
  skipBrowserAuthenticate,
39334
39436
  incomingDeps: { dbgFs, sessionCtx, onSessionUpdate, onRequest }
39335
39437
  });
39438
+ stopAbort();
39336
39439
  resolve39(
39337
39440
  createCursorAcpHandle({
39338
39441
  child,
@@ -39345,6 +39448,7 @@ async function createCursorAcpClient(options) {
39345
39448
  })
39346
39449
  );
39347
39450
  } catch (err) {
39451
+ stopAbort();
39348
39452
  killChildProcessTree(child, "SIGKILL");
39349
39453
  const merged = mergeErrorWithStderr(formatJsonRpcStyleError(err), stderrCapture.getText());
39350
39454
  reject(merged ? new Error(merged) : err instanceof Error ? err : new Error(String(err)));
@@ -39511,7 +39615,7 @@ function getAgentTypeDisplayName(agentType) {
39511
39615
  import { existsSync as existsSync4, statSync } from "node:fs";
39512
39616
 
39513
39617
  // ../bridge/src/git/git-exec.ts
39514
- import { execFile as execFile2, execFileSync as execFileSync2, spawn as spawn4 } from "node:child_process";
39618
+ import { execFile as execFile2, execFileSync, spawn as spawn4 } from "node:child_process";
39515
39619
  import { promisify as promisify3 } from "node:util";
39516
39620
 
39517
39621
  // ../bridge/src/git/git-runtime.ts
@@ -39569,7 +39673,7 @@ init_cli_process_interrupt();
39569
39673
  var execFileAsync2 = promisify3(execFile2);
39570
39674
  var GIT_SYNC_STDIO = ["ignore", "pipe", "pipe"];
39571
39675
  function execGitFileSync(args, options) {
39572
- return execFileSync2("git", args, {
39676
+ return execFileSync("git", args, {
39573
39677
  encoding: "utf8",
39574
39678
  maxBuffer: 10 * 1024 * 1024,
39575
39679
  ...options,
@@ -42137,45 +42241,53 @@ function listCliAgentCapabilityCacheForWorkspace(db, workspaceId) {
42137
42241
  // ../bridge/src/agents/capabilities/probe-agent-capabilities-for-types.ts
42138
42242
  init_cli_database();
42139
42243
 
42244
+ // ../bridge/src/agents/capabilities/agent-capability-warmup-run.ts
42245
+ init_cli_process_interrupt();
42246
+ var warmupEpoch = 0;
42247
+ var probedTypesThisProcess = /* @__PURE__ */ new Set();
42248
+ function cancelInFlightAgentCapabilityWarmup() {
42249
+ warmupEpoch += 1;
42250
+ }
42251
+ function beginAgentCapabilityWarmupRun() {
42252
+ const epoch = warmupEpoch += 1;
42253
+ return () => epoch === warmupEpoch && !isCliImmediateShutdownRequested();
42254
+ }
42255
+ function wasAgentCapabilityTypeProbedThisProcess(agentType) {
42256
+ return probedTypesThisProcess.has(agentType);
42257
+ }
42258
+ function markAgentCapabilityTypeProbedThisProcess(agentType) {
42259
+ probedTypesThisProcess.add(agentType);
42260
+ }
42261
+ function shouldSkipCapabilityProbeThisProcess(agentType) {
42262
+ if (process.env.BUILDAUTOMATON_FORCE_PROBE_ACP_CAPABILITIES === "1") return false;
42263
+ return wasAgentCapabilityTypeProbedThisProcess(agentType);
42264
+ }
42265
+
42140
42266
  // ../bridge/src/agents/capabilities/probe-one-agent-type-for-capabilities.ts
42141
42267
  import * as path35 from "node:path";
42142
42268
  init_cli_database();
42269
+ init_yield_to_event_loop();
42143
42270
  init_cli_process_interrupt();
42271
+ var ACP_CAPABILITY_PROBE_TIMEOUT_MS = 12e3;
42144
42272
  async function probeOneAgentTypeForCapabilities(params) {
42145
42273
  const { agentType, cwd, workspaceId, log: log2, reportAgentCapabilities, bridgeReport = true, shouldContinue } = params;
42146
- const canContinue = () => shouldContinue?.() !== false;
42274
+ const canContinue = () => shouldContinue?.() !== false && !isCliImmediateShutdownRequested();
42147
42275
  if (!canContinue()) return false;
42148
42276
  const resolved = resolveAgentCommand(agentType);
42149
42277
  if (!resolved) return false;
42150
- let sqliteChanged = false;
42151
- const reportedRef = { done: false };
42152
- const tryReport = (co) => {
42153
- if (reportedRef.done) return;
42154
- if (!Array.isArray(co) || co.length === 0) return;
42155
- reportedRef.done = true;
42156
- let changed = false;
42157
- try {
42158
- changed = withCliSqliteSync(
42159
- (db) => upsertCliAgentCapabilityCache(db, {
42160
- workspaceId,
42161
- agentType,
42162
- configOptions: co
42163
- })
42164
- );
42165
- } catch {
42166
- }
42167
- sqliteChanged ||= changed;
42168
- if (bridgeReport && changed) {
42169
- reportAgentCapabilities?.({ agentType, configOptions: co });
42170
- }
42171
- };
42278
+ await yieldToEventLoop();
42279
+ if (!canContinue()) return false;
42280
+ markAgentCapabilityTypeProbedThisProcess(agentType);
42281
+ let pendingCo = null;
42282
+ const ac = new AbortController();
42283
+ const abortTimer = setTimeout(() => ac.abort(), ACP_CAPABILITY_PROBE_TIMEOUT_MS);
42284
+ abortTimer.unref?.();
42285
+ const abortIfStale = setInterval(() => {
42286
+ if (!canContinue()) ac.abort();
42287
+ }, 50);
42288
+ abortIfStale.unref?.();
42172
42289
  let handle = null;
42173
- const killTimer = setTimeout(() => {
42174
- void handle?.disconnectGracefully();
42175
- }, 28e3);
42176
- killTimer.unref?.();
42177
42290
  try {
42178
- if (!canContinue()) return false;
42179
42291
  handle = await resolved.createClient({
42180
42292
  command: resolved.command,
42181
42293
  cwd: path35.resolve(cwd),
@@ -42183,12 +42295,13 @@ async function probeOneAgentTypeForCapabilities(params) {
42183
42295
  sessionMode: "agent",
42184
42296
  persistedAcpSessionId: null,
42185
42297
  agentConfig: null,
42298
+ signal: ac.signal,
42186
42299
  getActiveConfigOptions: () => null,
42187
42300
  onAcpSessionEstablished: (info) => {
42188
- tryReport(info.configOptions ?? null);
42301
+ if (Array.isArray(info.configOptions) && info.configOptions.length > 0) pendingCo = info.configOptions;
42189
42302
  },
42190
42303
  onAcpConfigOptionsUpdated: (co) => {
42191
- tryReport(co);
42304
+ if (Array.isArray(co) && co.length > 0) pendingCo = co;
42192
42305
  },
42193
42306
  onAgentSubprocessExit: () => {
42194
42307
  },
@@ -42201,13 +42314,21 @@ async function probeOneAgentTypeForCapabilities(params) {
42201
42314
  `[Bridge service] Agent capability probe (${agentType}): ${e instanceof Error ? e.message : String(e)}`
42202
42315
  );
42203
42316
  } finally {
42204
- clearTimeout(killTimer);
42317
+ clearTimeout(abortTimer);
42318
+ clearInterval(abortIfStale);
42205
42319
  try {
42206
42320
  await handle?.disconnectGracefully();
42207
42321
  } catch {
42208
42322
  }
42209
42323
  }
42210
- return sqliteChanged;
42324
+ if (!pendingCo || !canContinue()) return false;
42325
+ const configOptions = pendingCo;
42326
+ await yieldToEventLoop();
42327
+ const changed = await withCliSqlite(
42328
+ (db) => upsertCliAgentCapabilityCache(db, { workspaceId, agentType, configOptions })
42329
+ );
42330
+ if (bridgeReport && changed) reportAgentCapabilities?.({ agentType, configOptions });
42331
+ return changed;
42211
42332
  }
42212
42333
 
42213
42334
  // ../bridge/src/agents/capabilities/probe-agent-capabilities-for-types.ts
@@ -42226,9 +42347,10 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
42226
42347
  let changedCount = 0;
42227
42348
  for (let i = 0; i < agentTypes.length; i++) {
42228
42349
  if (!canContinue()) return changedCount;
42229
- if (i > 0) await yieldToEventLoop();
42350
+ await yieldToEventLoop();
42230
42351
  const agentType = agentTypes[i];
42231
42352
  if (!agentType.trim()) continue;
42353
+ if (shouldSkipCapabilityProbeThisProcess(agentType)) continue;
42232
42354
  if (!forceAllTypes) {
42233
42355
  try {
42234
42356
  if (process.env.BUILDAUTOMATON_FORCE_PROBE_ACP_CAPABILITIES !== "1" && await withCliSqlite((db) => hasNonEmptyAgentCapabilityCache(db, workspaceId, agentType))) {
@@ -42254,19 +42376,6 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
42254
42376
  // ../bridge/src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
42255
42377
  init_yield_to_event_loop();
42256
42378
  init_cli_database();
42257
-
42258
- // ../bridge/src/agents/capabilities/agent-capability-warmup-run.ts
42259
- init_cli_process_interrupt();
42260
- var warmupEpoch = 0;
42261
- function cancelInFlightAgentCapabilityWarmup() {
42262
- warmupEpoch += 1;
42263
- }
42264
- function beginAgentCapabilityWarmupRun() {
42265
- const epoch = warmupEpoch += 1;
42266
- return () => epoch === warmupEpoch && !isCliImmediateShutdownRequested();
42267
- }
42268
-
42269
- // ../bridge/src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
42270
42379
  async function warmupAgentCapabilitiesOnConnect(params) {
42271
42380
  const { workspaceId, log: log2, getWs } = params;
42272
42381
  const isCurrent = beginAgentCapabilityWarmupRun();
@@ -42278,8 +42387,7 @@ async function warmupAgentCapabilitiesOnConnect(params) {
42278
42387
  if (!socket || socket.readyState !== wrapper_default.OPEN) return;
42279
42388
  try {
42280
42389
  const rows = await withCliSqlite((db) => listCliAgentCapabilityCacheForWorkspace(db, workspaceId));
42281
- if (!isCurrent()) return;
42282
- if (rows.length === 0) return;
42390
+ if (!isCurrent() || rows.length === 0) return;
42283
42391
  sendWsMessage(socket, {
42284
42392
  type: "agent_capabilities_batch",
42285
42393
  items: rows.map((r) => ({ agentType: r.agentType, configOptions: r.configOptions }))
@@ -42293,46 +42401,30 @@ async function warmupAgentCapabilitiesOnConnect(params) {
42293
42401
  }
42294
42402
  await sendBatchFromCache();
42295
42403
  if (!isCurrent()) return;
42296
- let types = [];
42297
- try {
42298
- types = [...await detectLocalAgentTypes()];
42299
- } catch (e) {
42300
- log2(`[Bridge service] detectLocalAgentTypes failed: ${e instanceof Error ? e.message : String(e)}`);
42301
- }
42302
- if (!isCurrent()) return;
42303
- try {
42304
- const n = await probeAgentCapabilitiesForDetectedTypes({
42305
- agentTypes: types,
42306
- cwd,
42307
- workspaceId,
42308
- log: log2,
42309
- bridgeReport: false,
42310
- forceAllTypes: false,
42311
- shouldContinue: isCurrent
42312
- });
42313
- if (n > 0) await sendBatchFromCache();
42314
- } catch (e) {
42315
- if (e instanceof CliSqliteInterrupted) return;
42316
- log2(`[Bridge service] Agent capability probe (missing cache) failed: ${e instanceof Error ? e.message : String(e)}`);
42317
- }
42318
- if (!isCurrent()) return;
42319
42404
  void (async () => {
42320
42405
  try {
42321
42406
  await yieldToEventLoop();
42322
42407
  if (!isCurrent()) return;
42408
+ let types = [];
42409
+ try {
42410
+ types = [...await detectLocalAgentTypes()];
42411
+ } catch (e) {
42412
+ log2(`[Bridge service] detectLocalAgentTypes failed: ${e instanceof Error ? e.message : String(e)}`);
42413
+ }
42414
+ if (!isCurrent()) return;
42323
42415
  const n = await probeAgentCapabilitiesForDetectedTypes({
42324
42416
  agentTypes: types,
42325
42417
  cwd,
42326
42418
  workspaceId,
42327
42419
  log: log2,
42328
42420
  bridgeReport: false,
42329
- forceAllTypes: true,
42421
+ forceAllTypes: false,
42330
42422
  shouldContinue: isCurrent
42331
42423
  });
42332
42424
  if (n > 0) await sendBatchFromCache();
42333
42425
  } catch (e) {
42334
42426
  if (e instanceof CliSqliteInterrupted) return;
42335
- log2(`[Bridge service] Agent capability lazy refresh failed: ${e instanceof Error ? e.message : String(e)}`);
42427
+ log2(`[Bridge service] Agent capability probe failed: ${e instanceof Error ? e.message : String(e)}`);
42336
42428
  }
42337
42429
  })();
42338
42430
  }
@@ -43744,7 +43836,7 @@ function createBridgeHeartbeatController(params) {
43744
43836
  }
43745
43837
 
43746
43838
  // ../bridge/src/cli/cli-version.ts
43747
- var CLI_VERSION2 = "0.1.92".length > 0 ? "0.1.92" : "0.0.0-dev";
43839
+ var CLI_VERSION2 = "0.1.94".length > 0 ? "0.1.94" : "0.0.0-dev";
43748
43840
 
43749
43841
  // ../bridge/src/connection/identify/send-bridge-identify.ts
43750
43842
  function sendBridgeIdentify(ws, params) {
@@ -53643,7 +53735,6 @@ var handleBridgeIdentified = (msg, deps) => {
53643
53735
  });
53644
53736
  setImmediate(() => {
53645
53737
  void (async () => {
53646
- cancelInFlightAgentCapabilityWarmup();
53647
53738
  try {
53648
53739
  await deps.reportAutoDetectedAgents?.();
53649
53740
  } catch (e) {
@@ -53651,13 +53742,11 @@ var handleBridgeIdentified = (msg, deps) => {
53651
53742
  `[Bridge service] Auto-detect agents failed: ${e instanceof Error ? e.message : String(e)}`
53652
53743
  );
53653
53744
  }
53654
- try {
53655
- await deps.warmupAgentCapabilitiesOnConnect?.();
53656
- } catch (e) {
53745
+ void deps.warmupAgentCapabilitiesOnConnect?.()?.catch((e) => {
53657
53746
  deps.log(
53658
53747
  `[Bridge service] Agent capability warmup failed: ${e instanceof Error ? e.message : String(e)}`
53659
53748
  );
53660
- }
53749
+ });
53661
53750
  })();
53662
53751
  });
53663
53752
  };
@@ -55545,6 +55634,7 @@ function createMainBridgeCloseHandler(params, connect) {
55545
55634
  const { state, logFn, bridgeHeartbeat } = params;
55546
55635
  return (code, reason, closedWs) => {
55547
55636
  if (state.currentWs !== closedWs) return;
55637
+ cancelInFlightAgentCapabilityWarmup();
55548
55638
  bridgeHeartbeat?.stop();
55549
55639
  try {
55550
55640
  state.currentWs = null;
@@ -55672,20 +55762,8 @@ function createMainBridgeWebSocketLifecycle(params) {
55672
55762
  }
55673
55763
  }
55674
55764
  bridgeHeartbeat?.stop();
55675
- const prev = state.currentWs;
55676
- if (prev) {
55677
- prev.removeAllListeners();
55678
- prev.once("error", () => {
55679
- });
55680
- prev.once("close", () => {
55681
- prev.removeAllListeners();
55682
- });
55683
- try {
55684
- prev.close();
55685
- } catch {
55686
- }
55687
- state.currentWs = null;
55688
- }
55765
+ disposePreviousBridgeSocket(state.currentWs);
55766
+ state.currentWs = null;
55689
55767
  try {
55690
55768
  const url2 = plugin.transport.resolveControlPlaneUrl({
55691
55769
  workspaceId,
@@ -56247,7 +56325,7 @@ async function defaultBrowserId() {
56247
56325
  // ../../node_modules/.pnpm/run-applescript@7.1.0/node_modules/run-applescript/index.js
56248
56326
  import process6 from "node:process";
56249
56327
  import { promisify as promisify5 } from "node:util";
56250
- import { execFile as execFile4, execFileSync as execFileSync3 } from "node:child_process";
56328
+ import { execFile as execFile4, execFileSync as execFileSync2 } from "node:child_process";
56251
56329
  var execFileAsync4 = promisify5(execFile4);
56252
56330
  async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
56253
56331
  if (process6.platform !== "darwin") {