@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/index.js CHANGED
@@ -20756,6 +20756,15 @@ var init_acp = __esm({
20756
20756
  }
20757
20757
  });
20758
20758
 
20759
+ // ../bridge/src/runtime/yield-to-event-loop.ts
20760
+ function yieldToEventLoop() {
20761
+ return new Promise((resolve36) => setImmediate(resolve36));
20762
+ }
20763
+ var init_yield_to_event_loop = __esm({
20764
+ "../bridge/src/runtime/yield-to-event-loop.ts"() {
20765
+ }
20766
+ });
20767
+
20759
20768
  // ../bridge/src/files/index/constants.ts
20760
20769
  import path3 from "node:path";
20761
20770
  import os from "node:os";
@@ -21027,15 +21036,6 @@ var init_activity_tracker = __esm({
21027
21036
  }
21028
21037
  });
21029
21038
 
21030
- // ../bridge/src/runtime/yield-to-event-loop.ts
21031
- function yieldToEventLoop() {
21032
- return new Promise((resolve36) => setImmediate(resolve36));
21033
- }
21034
- var init_yield_to_event_loop = __esm({
21035
- "../bridge/src/runtime/yield-to-event-loop.ts"() {
21036
- }
21037
- });
21038
-
21039
21039
  // ../bridge/src/code-nav/symbol-index/deferred-indexing.ts
21040
21040
  function isSymbolIndexDeferredError(err) {
21041
21041
  return err instanceof SymbolIndexDeferredError;
@@ -21109,7 +21109,6 @@ var init_idle_yield = __esm({
21109
21109
  // ../bridge/src/files/browser/in-flight.ts
21110
21110
  var init_in_flight = __esm({
21111
21111
  "../bridge/src/files/browser/in-flight.ts"() {
21112
- "use strict";
21113
21112
  init_activity_shared();
21114
21113
  init_activity_types();
21115
21114
  init_activity_tracker();
@@ -27442,6 +27441,12 @@ var wrapper_default = import_websocket.default;
27442
27441
  // ../bridge/src/connection/ws/cli-ws-client.ts
27443
27442
  import https from "node:https";
27444
27443
  var CLI_WEBSOCKET_CLIENT_PING_MS = 25e3;
27444
+ var CLI_WEBSOCKET_HANDSHAKE_TIMEOUT_MS = 15e3;
27445
+ var sharedWssAgent = null;
27446
+ function cliWssAgent() {
27447
+ sharedWssAgent ??= new https.Agent({ rejectUnauthorized: false, keepAlive: true });
27448
+ return sharedWssAgent;
27449
+ }
27445
27450
  function attachWebSocketClientPing(ws, intervalMs) {
27446
27451
  let timer = null;
27447
27452
  function clear() {
@@ -27462,9 +27467,12 @@ function attachWebSocketClientPing(ws, intervalMs) {
27462
27467
  return clear;
27463
27468
  }
27464
27469
  function buildCliWebSocketClientOptions(wsUrl) {
27465
- const wsOptions = { perMessageDeflate: false };
27470
+ const wsOptions = {
27471
+ perMessageDeflate: false,
27472
+ handshakeTimeout: CLI_WEBSOCKET_HANDSHAKE_TIMEOUT_MS
27473
+ };
27466
27474
  if (wsUrl.startsWith("wss://")) {
27467
- wsOptions.agent = new https.Agent({ rejectUnauthorized: false });
27475
+ wsOptions.agent = cliWssAgent();
27468
27476
  }
27469
27477
  return wsOptions;
27470
27478
  }
@@ -27478,6 +27486,15 @@ function safeCloseWebSocket(ws) {
27478
27486
  ws.removeAllListeners();
27479
27487
  return;
27480
27488
  }
27489
+ if (ws.readyState === wrapper_default.CONNECTING) {
27490
+ ws.once("error", () => {
27491
+ });
27492
+ ws.once("close", () => {
27493
+ ws.removeAllListeners();
27494
+ });
27495
+ ws.terminate();
27496
+ return;
27497
+ }
27481
27498
  ws.once("close", () => {
27482
27499
  ws.removeAllListeners();
27483
27500
  });
@@ -27708,7 +27725,7 @@ function formatSpawnError(err, command) {
27708
27725
  }
27709
27726
 
27710
27727
  // ../bridge/src/agents/acp/clients/kill-process-tree.ts
27711
- var import_tree_kill = __toESM(require_tree_kill(), 1);
27728
+ var import_tree_kill = __toESM(require_tree_kill());
27712
27729
  import { promisify } from "node:util";
27713
27730
  var treeKillAsync = promisify(import_tree_kill.default);
27714
27731
  var ACP_PROCESS_TREE_KILL_GRACE_MS = 2500;
@@ -32921,6 +32938,24 @@ var RoleLengthWireSchema = external_exports.discriminatedUnion("type", [
32921
32938
  external_exports.object({ type: external_exports.literal("session_count"), max_sessions: MaxSessionsSchema })
32922
32939
  ]);
32923
32940
 
32941
+ // ../types/src/role-access-restrictions.ts
32942
+ var EMPTY_ROLE_ACCESS_RESTRICTIONS = {
32943
+ sessionsOwnAndExplicitOnly: false,
32944
+ bridgesOwnAndExplicitOnly: false,
32945
+ sessionsReadOnlyExceptOwn: false,
32946
+ codeChangesAgentModifiedOnly: false,
32947
+ codeChangesHidden: false
32948
+ };
32949
+ function roleAccessRestrictionsToWire(restrictions) {
32950
+ return {
32951
+ sessions_own_and_explicit_only: restrictions.sessionsOwnAndExplicitOnly,
32952
+ bridges_own_and_explicit_only: restrictions.bridgesOwnAndExplicitOnly,
32953
+ sessions_read_only_except_own: restrictions.sessionsReadOnlyExceptOwn,
32954
+ code_changes_agent_modified_only: restrictions.codeChangesAgentModifiedOnly,
32955
+ code_changes_hidden: restrictions.codeChangesHidden
32956
+ };
32957
+ }
32958
+
32924
32959
  // ../types/src/role-details.ts
32925
32960
  var InitialPeriodDaysSchema = external_exports.number().int().min(ROLE_PERIOD_MIN_DAYS).max(ROLE_PERIOD_MAX_DAYS);
32926
32961
  var AgentSubscriptionIdsSchema = external_exports.array(external_exports.string().min(1)).default([]);
@@ -32930,15 +32965,33 @@ var RoleDetailsSchema = external_exports.object({
32930
32965
  length: RoleLengthSchema.nullable(),
32931
32966
  agentSubscriptionIds: AgentSubscriptionIdsSchema,
32932
32967
  sessionsOwnAndExplicitOnly: BoolFalseSchema,
32933
- bridgesOwnAndExplicitOnly: BoolFalseSchema
32968
+ bridgesOwnAndExplicitOnly: BoolFalseSchema,
32969
+ sessionsReadOnlyExceptOwn: BoolFalseSchema,
32970
+ codeChangesAgentModifiedOnly: BoolFalseSchema,
32971
+ codeChangesHidden: BoolFalseSchema
32934
32972
  });
32935
32973
  var RoleDetailsWireSchema = external_exports.object({
32936
32974
  payment: RolePaymentModelWireSchema.nullable(),
32937
32975
  length: RoleLengthWireSchema.nullable(),
32938
32976
  agent_subscription_ids: AgentSubscriptionIdsSchema,
32939
32977
  sessions_own_and_explicit_only: BoolFalseSchema,
32940
- bridges_own_and_explicit_only: BoolFalseSchema
32941
- });
32978
+ bridges_own_and_explicit_only: BoolFalseSchema,
32979
+ sessions_read_only_except_own: BoolFalseSchema,
32980
+ code_changes_agent_modified_only: BoolFalseSchema,
32981
+ code_changes_hidden: BoolFalseSchema
32982
+ });
32983
+ var EMPTY_ROLE_DETAILS = {
32984
+ payment: null,
32985
+ length: null,
32986
+ agentSubscriptionIds: [],
32987
+ ...EMPTY_ROLE_ACCESS_RESTRICTIONS
32988
+ };
32989
+ var EMPTY_ROLE_DETAILS_WIRE = {
32990
+ payment: null,
32991
+ length: null,
32992
+ agent_subscription_ids: [],
32993
+ ...roleAccessRestrictionsToWire(EMPTY_ROLE_ACCESS_RESTRICTIONS)
32994
+ };
32942
32995
 
32943
32996
  // ../bridge/src/agents/acp/safe-fs-path.ts
32944
32997
  import * as path2 from "node:path";
@@ -33464,7 +33517,25 @@ function spawnSdkStdioProcess(options) {
33464
33517
  return { child, stderrCapture };
33465
33518
  }
33466
33519
 
33520
+ // ../bridge/src/agents/acp/clients/listen-for-acp-client-abort.ts
33521
+ function listenForAcpClientAbort(child, signal, onAbort) {
33522
+ if (!signal) return () => {
33523
+ };
33524
+ const fire = () => {
33525
+ killChildProcessTree(child, "SIGKILL");
33526
+ onAbort();
33527
+ };
33528
+ if (signal.aborted) {
33529
+ fire();
33530
+ return () => {
33531
+ };
33532
+ }
33533
+ signal.addEventListener("abort", fire, { once: true });
33534
+ return () => signal.removeEventListener("abort", fire);
33535
+ }
33536
+
33467
33537
  // ../bridge/src/agents/acp/clients/sdk/sdk-stdio-acp-client.ts
33538
+ init_yield_to_event_loop();
33468
33539
  async function createSdkStdioAcpClient(options) {
33469
33540
  const { PROTOCOL_VERSION: PROTOCOL_VERSION2 } = await Promise.resolve().then(() => (init_acp(), acp_exports));
33470
33541
  const {
@@ -33482,13 +33553,18 @@ async function createSdkStdioAcpClient(options) {
33482
33553
  onAcpConfigOptionsUpdated,
33483
33554
  getActiveConfigOptions,
33484
33555
  afterSessionEstablished,
33485
- createExtNotificationHandler
33556
+ createExtNotificationHandler,
33557
+ signal
33486
33558
  } = options;
33559
+ if (signal?.aborted) {
33560
+ throw new Error("ACP client aborted");
33561
+ }
33487
33562
  const { child, stderrCapture } = spawnSdkStdioProcess({
33488
33563
  command,
33489
33564
  cwd,
33490
33565
  onAgentSubprocessExit
33491
33566
  });
33567
+ await yieldToEventLoop();
33492
33568
  const sessionCtx = createSdkStdioSessionContext({
33493
33569
  cwd,
33494
33570
  mcpServers: options.mcpServers,
@@ -33504,7 +33580,11 @@ async function createSdkStdioAcpClient(options) {
33504
33580
  });
33505
33581
  return new Promise((resolve36, reject) => {
33506
33582
  const init = createSdkStdioInitSettle(child);
33583
+ const stopAbort = listenForAcpClientAbort(child, signal, () => {
33584
+ init.settleReject(reject, new Error("ACP client aborted"));
33585
+ });
33507
33586
  child.on("error", (err) => {
33587
+ stopAbort();
33508
33588
  init.settleReject(reject, new Error(formatSpawnError(err, command[0])));
33509
33589
  });
33510
33590
  attachSdkStdioStderrAuthWatch({
@@ -33538,7 +33618,9 @@ async function createSdkStdioAcpClient(options) {
33538
33618
  killSubprocessAfterCancelMs
33539
33619
  })
33540
33620
  );
33621
+ stopAbort();
33541
33622
  } catch (err) {
33623
+ stopAbort();
33542
33624
  if (init.settled) return;
33543
33625
  init.settleReject(
33544
33626
  reject,
@@ -33810,22 +33892,12 @@ function installBridgeProcessResilience() {
33810
33892
  init_log();
33811
33893
 
33812
33894
  // ../bridge/src/agents/acp/clients/bridge-agent-path.ts
33813
- import { execFileSync } from "node:child_process";
33814
33895
  import { homedir } from "node:os";
33815
33896
  import { join } from "node:path";
33816
33897
  function getBridgeAgentPathEntries(home = process.env.HOME ?? homedir()) {
33817
- const entries = [
33818
- join(home, ".local", "bin"),
33819
- join(home, ".npm-global", "bin"),
33820
- "/usr/local/bin"
33821
- ];
33898
+ const entries = [join(home, ".local", "bin"), join(home, ".npm-global", "bin"), "/usr/local/bin"];
33822
33899
  const prefix = process.env.NPM_CONFIG_PREFIX;
33823
33900
  if (prefix) entries.push(join(prefix, "bin"));
33824
- try {
33825
- const npmBin = execFileSync("npm", ["bin", "-g"], { encoding: "utf8", timeout: 2e3 }).trim();
33826
- if (npmBin) entries.push(npmBin);
33827
- } catch {
33828
- }
33829
33901
  return entries;
33830
33902
  }
33831
33903
  function augmentPath(pathValue, extra) {
@@ -35067,6 +35139,22 @@ function beginDeferredDisconnectForReconnect(options) {
35067
35139
  }
35068
35140
  }
35069
35141
 
35142
+ // ../bridge/src/connection/ws/dispose-previous-bridge-socket.ts
35143
+ function disposePreviousBridgeSocket(ws) {
35144
+ if (!ws) return;
35145
+ ws.removeAllListeners();
35146
+ ws.once("error", () => {
35147
+ });
35148
+ ws.once("close", () => {
35149
+ ws.removeAllListeners();
35150
+ });
35151
+ try {
35152
+ if (ws.readyState === wrapper_default.CONNECTING) ws.terminate();
35153
+ else ws.close();
35154
+ } catch {
35155
+ }
35156
+ }
35157
+
35070
35158
  // ../bridge/src/connection/runtime/close-bridge-connection.ts
35071
35159
  async function closeBridgeConnection(state, acpManager, previewEnvironmentManager, log2) {
35072
35160
  requestCliImmediateShutdown();
@@ -35083,16 +35171,7 @@ async function closeBridgeConnection(state, acpManager, previewEnvironmentManage
35083
35171
  await acpManager.disconnect();
35084
35172
  if (state.currentWs) {
35085
35173
  say("Closing bridge connection to the cloud\u2026");
35086
- state.currentWs.removeAllListeners();
35087
- const wsState = state.currentWs.readyState;
35088
- if (wsState === 1 || wsState === 2) {
35089
- state.currentWs.close();
35090
- } else {
35091
- state.currentWs.on("error", () => {
35092
- });
35093
- state.currentWs.on("close", () => {
35094
- });
35095
- }
35174
+ disposePreviousBridgeSocket(state.currentWs);
35096
35175
  state.currentWs = null;
35097
35176
  }
35098
35177
  if (previewEnvironmentManager) {
@@ -35792,15 +35871,31 @@ function queueCursorCreatePlanRequest(method, id, msg, deps) {
35792
35871
  }
35793
35872
 
35794
35873
  // ../bridge/src/agents/providers/cursor/cursor-incoming-cursor-task.ts
35795
- function buildCursorTaskToolCallUpdate(params) {
35874
+ function asRecord2(v) {
35875
+ return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
35876
+ }
35877
+ function flattenCursorTaskParams(params) {
35878
+ const nested = asRecord2(params.task) ?? asRecord2(params.data) ?? asRecord2(params.payload) ?? asRecord2(params.cursorTask);
35879
+ return nested ? { ...nested, ...params } : params;
35880
+ }
35881
+ function stringField(params, ...keys) {
35882
+ for (const key of keys) {
35883
+ const v = params[key];
35884
+ if (typeof v === "string" && v.trim()) return v.trim();
35885
+ }
35886
+ return void 0;
35887
+ }
35888
+ function buildCursorTaskToolCallUpdate(rawParams) {
35889
+ const params = flattenCursorTaskParams(rawParams);
35796
35890
  const toolCallId = params.toolCallId ?? params.tool_call_id;
35797
35891
  if (typeof toolCallId !== "string" || !toolCallId.trim()) return null;
35798
- const description = typeof params.description === "string" ? params.description.trim() : "";
35892
+ const description = stringField(params, "description");
35799
35893
  const prompt = typeof params.prompt === "string" ? params.prompt : void 0;
35800
35894
  const subagentType = params.subagentType ?? params.subagent_type;
35801
35895
  const model = typeof params.model === "string" ? params.model : void 0;
35802
- const agentId = typeof params.agentId === "string" ? params.agentId : typeof params.agent_id === "string" ? params.agent_id : void 0;
35803
- const durationMs = typeof params.durationMs === "number" ? params.durationMs : typeof params.duration_ms === "number" ? params.duration_ms : void 0;
35896
+ const agentId = stringField(params, "agentId", "agent_id");
35897
+ const rawDuration = params.durationMs ?? params.duration_ms;
35898
+ const durationMs = typeof rawDuration === "number" && Number.isFinite(rawDuration) && rawDuration > 0 ? rawDuration : void 0;
35804
35899
  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;
35805
35900
  return {
35806
35901
  sessionUpdate: "tool_call_update",
@@ -35969,7 +36064,7 @@ function writeCreatePlanFile(params) {
35969
36064
  }
35970
36065
 
35971
36066
  // ../bridge/src/agents/providers/cursor/enrich-create-plan-rpc-result.ts
35972
- function asRecord2(v) {
36067
+ function asRecord3(v) {
35973
36068
  return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
35974
36069
  }
35975
36070
  function resolveAcceptedPlanMarkdown(outcome, pendingParams) {
@@ -35978,8 +36073,8 @@ function resolveAcceptedPlanMarkdown(outcome, pendingParams) {
35978
36073
  return "";
35979
36074
  }
35980
36075
  function enrichCreatePlanRpcResult(result, pendingParams, cloudSessionId) {
35981
- const root = asRecord2(result);
35982
- const outcome = asRecord2(root?.outcome);
36076
+ const root = asRecord3(result);
36077
+ const outcome = asRecord3(root?.outcome);
35983
36078
  if (!outcome) return result;
35984
36079
  const kind = typeof outcome.outcome === "string" ? outcome.outcome : "";
35985
36080
  if (kind !== "accepted") {
@@ -36270,7 +36365,8 @@ async function createCursorAcpClient(options) {
36270
36365
  onAcpSessionEstablished,
36271
36366
  onAcpConfigOptionsUpdated,
36272
36367
  onAgentSubprocessExit,
36273
- afterSessionEstablished
36368
+ afterSessionEstablished,
36369
+ signal
36274
36370
  } = options;
36275
36371
  const dbgFs = process.env.BUILDAUTOMATON_DEBUG_ACP_FS === "1";
36276
36372
  const spawnEnv = bridgeInstalledAgentAuthProcessEnv(process.env);
@@ -36295,7 +36391,11 @@ async function createCursorAcpClient(options) {
36295
36391
  stderrCapture
36296
36392
  });
36297
36393
  return new Promise((resolve36, reject) => {
36394
+ const stopAbort = listenForAcpClientAbort(child, signal, () => {
36395
+ reject(new Error("ACP client aborted"));
36396
+ });
36298
36397
  child.on("error", (err) => {
36398
+ stopAbort();
36299
36399
  killChildProcessTree(child, "SIGKILL");
36300
36400
  reject(new Error(formatSpawnError(err, command[0])));
36301
36401
  });
@@ -36307,6 +36407,7 @@ async function createCursorAcpClient(options) {
36307
36407
  skipBrowserAuthenticate,
36308
36408
  incomingDeps: { dbgFs, sessionCtx, onSessionUpdate, onRequest }
36309
36409
  });
36410
+ stopAbort();
36310
36411
  resolve36(
36311
36412
  createCursorAcpHandle({
36312
36413
  child,
@@ -36319,6 +36420,7 @@ async function createCursorAcpClient(options) {
36319
36420
  })
36320
36421
  );
36321
36422
  } catch (err) {
36423
+ stopAbort();
36322
36424
  killChildProcessTree(child, "SIGKILL");
36323
36425
  const merged = mergeErrorWithStderr(formatJsonRpcStyleError(err), stderrCapture.getText());
36324
36426
  reject(merged ? new Error(merged) : err instanceof Error ? err : new Error(String(err)));
@@ -36485,7 +36587,7 @@ function getAgentTypeDisplayName(agentType) {
36485
36587
  import { existsSync as existsSync4, statSync } from "node:fs";
36486
36588
 
36487
36589
  // ../bridge/src/git/git-exec.ts
36488
- import { execFile as execFile2, execFileSync as execFileSync2, spawn as spawn4 } from "node:child_process";
36590
+ import { execFile as execFile2, execFileSync, spawn as spawn4 } from "node:child_process";
36489
36591
  import { promisify as promisify3 } from "node:util";
36490
36592
 
36491
36593
  // ../bridge/src/git/git-runtime.ts
@@ -36543,7 +36645,7 @@ init_cli_process_interrupt();
36543
36645
  var execFileAsync2 = promisify3(execFile2);
36544
36646
  var GIT_SYNC_STDIO = ["ignore", "pipe", "pipe"];
36545
36647
  function execGitFileSync(args, options) {
36546
- return execFileSync2("git", args, {
36648
+ return execFileSync("git", args, {
36547
36649
  encoding: "utf8",
36548
36650
  maxBuffer: 10 * 1024 * 1024,
36549
36651
  ...options,
@@ -38931,45 +39033,53 @@ function listCliAgentCapabilityCacheForWorkspace(db, workspaceId) {
38931
39033
  // ../bridge/src/agents/capabilities/probe-agent-capabilities-for-types.ts
38932
39034
  init_cli_database();
38933
39035
 
39036
+ // ../bridge/src/agents/capabilities/agent-capability-warmup-run.ts
39037
+ init_cli_process_interrupt();
39038
+ var warmupEpoch = 0;
39039
+ var probedTypesThisProcess = /* @__PURE__ */ new Set();
39040
+ function cancelInFlightAgentCapabilityWarmup() {
39041
+ warmupEpoch += 1;
39042
+ }
39043
+ function beginAgentCapabilityWarmupRun() {
39044
+ const epoch = warmupEpoch += 1;
39045
+ return () => epoch === warmupEpoch && !isCliImmediateShutdownRequested();
39046
+ }
39047
+ function wasAgentCapabilityTypeProbedThisProcess(agentType) {
39048
+ return probedTypesThisProcess.has(agentType);
39049
+ }
39050
+ function markAgentCapabilityTypeProbedThisProcess(agentType) {
39051
+ probedTypesThisProcess.add(agentType);
39052
+ }
39053
+ function shouldSkipCapabilityProbeThisProcess(agentType) {
39054
+ if (process.env.BUILDAUTOMATON_FORCE_PROBE_ACP_CAPABILITIES === "1") return false;
39055
+ return wasAgentCapabilityTypeProbedThisProcess(agentType);
39056
+ }
39057
+
38934
39058
  // ../bridge/src/agents/capabilities/probe-one-agent-type-for-capabilities.ts
38935
39059
  import * as path34 from "node:path";
38936
39060
  init_cli_database();
39061
+ init_yield_to_event_loop();
38937
39062
  init_cli_process_interrupt();
39063
+ var ACP_CAPABILITY_PROBE_TIMEOUT_MS = 12e3;
38938
39064
  async function probeOneAgentTypeForCapabilities(params) {
38939
39065
  const { agentType, cwd, workspaceId, log: log2, reportAgentCapabilities, bridgeReport = true, shouldContinue } = params;
38940
- const canContinue = () => shouldContinue?.() !== false;
39066
+ const canContinue = () => shouldContinue?.() !== false && !isCliImmediateShutdownRequested();
38941
39067
  if (!canContinue()) return false;
38942
39068
  const resolved = resolveAgentCommand(agentType);
38943
39069
  if (!resolved) return false;
38944
- let sqliteChanged = false;
38945
- const reportedRef = { done: false };
38946
- const tryReport = (co) => {
38947
- if (reportedRef.done) return;
38948
- if (!Array.isArray(co) || co.length === 0) return;
38949
- reportedRef.done = true;
38950
- let changed = false;
38951
- try {
38952
- changed = withCliSqliteSync(
38953
- (db) => upsertCliAgentCapabilityCache(db, {
38954
- workspaceId,
38955
- agentType,
38956
- configOptions: co
38957
- })
38958
- );
38959
- } catch {
38960
- }
38961
- sqliteChanged ||= changed;
38962
- if (bridgeReport && changed) {
38963
- reportAgentCapabilities?.({ agentType, configOptions: co });
38964
- }
38965
- };
39070
+ await yieldToEventLoop();
39071
+ if (!canContinue()) return false;
39072
+ markAgentCapabilityTypeProbedThisProcess(agentType);
39073
+ let pendingCo = null;
39074
+ const ac = new AbortController();
39075
+ const abortTimer = setTimeout(() => ac.abort(), ACP_CAPABILITY_PROBE_TIMEOUT_MS);
39076
+ abortTimer.unref?.();
39077
+ const abortIfStale = setInterval(() => {
39078
+ if (!canContinue()) ac.abort();
39079
+ }, 50);
39080
+ abortIfStale.unref?.();
38966
39081
  let handle = null;
38967
- const killTimer = setTimeout(() => {
38968
- void handle?.disconnectGracefully();
38969
- }, 28e3);
38970
- killTimer.unref?.();
38971
39082
  try {
38972
- if (!canContinue()) return false;
38973
39083
  handle = await resolved.createClient({
38974
39084
  command: resolved.command,
38975
39085
  cwd: path34.resolve(cwd),
@@ -38977,12 +39087,13 @@ async function probeOneAgentTypeForCapabilities(params) {
38977
39087
  sessionMode: "agent",
38978
39088
  persistedAcpSessionId: null,
38979
39089
  agentConfig: null,
39090
+ signal: ac.signal,
38980
39091
  getActiveConfigOptions: () => null,
38981
39092
  onAcpSessionEstablished: (info) => {
38982
- tryReport(info.configOptions ?? null);
39093
+ if (Array.isArray(info.configOptions) && info.configOptions.length > 0) pendingCo = info.configOptions;
38983
39094
  },
38984
39095
  onAcpConfigOptionsUpdated: (co) => {
38985
- tryReport(co);
39096
+ if (Array.isArray(co) && co.length > 0) pendingCo = co;
38986
39097
  },
38987
39098
  onAgentSubprocessExit: () => {
38988
39099
  },
@@ -38995,13 +39106,21 @@ async function probeOneAgentTypeForCapabilities(params) {
38995
39106
  `[Bridge service] Agent capability probe (${agentType}): ${e instanceof Error ? e.message : String(e)}`
38996
39107
  );
38997
39108
  } finally {
38998
- clearTimeout(killTimer);
39109
+ clearTimeout(abortTimer);
39110
+ clearInterval(abortIfStale);
38999
39111
  try {
39000
39112
  await handle?.disconnectGracefully();
39001
39113
  } catch {
39002
39114
  }
39003
39115
  }
39004
- return sqliteChanged;
39116
+ if (!pendingCo || !canContinue()) return false;
39117
+ const configOptions = pendingCo;
39118
+ await yieldToEventLoop();
39119
+ const changed = await withCliSqlite(
39120
+ (db) => upsertCliAgentCapabilityCache(db, { workspaceId, agentType, configOptions })
39121
+ );
39122
+ if (bridgeReport && changed) reportAgentCapabilities?.({ agentType, configOptions });
39123
+ return changed;
39005
39124
  }
39006
39125
 
39007
39126
  // ../bridge/src/agents/capabilities/probe-agent-capabilities-for-types.ts
@@ -39020,9 +39139,10 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
39020
39139
  let changedCount = 0;
39021
39140
  for (let i = 0; i < agentTypes.length; i++) {
39022
39141
  if (!canContinue()) return changedCount;
39023
- if (i > 0) await yieldToEventLoop();
39142
+ await yieldToEventLoop();
39024
39143
  const agentType = agentTypes[i];
39025
39144
  if (!agentType.trim()) continue;
39145
+ if (shouldSkipCapabilityProbeThisProcess(agentType)) continue;
39026
39146
  if (!forceAllTypes) {
39027
39147
  try {
39028
39148
  if (process.env.BUILDAUTOMATON_FORCE_PROBE_ACP_CAPABILITIES !== "1" && await withCliSqlite((db) => hasNonEmptyAgentCapabilityCache(db, workspaceId, agentType))) {
@@ -39048,19 +39168,6 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
39048
39168
  // ../bridge/src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
39049
39169
  init_yield_to_event_loop();
39050
39170
  init_cli_database();
39051
-
39052
- // ../bridge/src/agents/capabilities/agent-capability-warmup-run.ts
39053
- init_cli_process_interrupt();
39054
- var warmupEpoch = 0;
39055
- function cancelInFlightAgentCapabilityWarmup() {
39056
- warmupEpoch += 1;
39057
- }
39058
- function beginAgentCapabilityWarmupRun() {
39059
- const epoch = warmupEpoch += 1;
39060
- return () => epoch === warmupEpoch && !isCliImmediateShutdownRequested();
39061
- }
39062
-
39063
- // ../bridge/src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
39064
39171
  async function warmupAgentCapabilitiesOnConnect(params) {
39065
39172
  const { workspaceId, log: log2, getWs } = params;
39066
39173
  const isCurrent = beginAgentCapabilityWarmupRun();
@@ -39072,8 +39179,7 @@ async function warmupAgentCapabilitiesOnConnect(params) {
39072
39179
  if (!socket || socket.readyState !== wrapper_default.OPEN) return;
39073
39180
  try {
39074
39181
  const rows = await withCliSqlite((db) => listCliAgentCapabilityCacheForWorkspace(db, workspaceId));
39075
- if (!isCurrent()) return;
39076
- if (rows.length === 0) return;
39182
+ if (!isCurrent() || rows.length === 0) return;
39077
39183
  sendWsMessage(socket, {
39078
39184
  type: "agent_capabilities_batch",
39079
39185
  items: rows.map((r) => ({ agentType: r.agentType, configOptions: r.configOptions }))
@@ -39087,46 +39193,30 @@ async function warmupAgentCapabilitiesOnConnect(params) {
39087
39193
  }
39088
39194
  await sendBatchFromCache();
39089
39195
  if (!isCurrent()) return;
39090
- let types = [];
39091
- try {
39092
- types = [...await detectLocalAgentTypes()];
39093
- } catch (e) {
39094
- log2(`[Bridge service] detectLocalAgentTypes failed: ${e instanceof Error ? e.message : String(e)}`);
39095
- }
39096
- if (!isCurrent()) return;
39097
- try {
39098
- const n = await probeAgentCapabilitiesForDetectedTypes({
39099
- agentTypes: types,
39100
- cwd,
39101
- workspaceId,
39102
- log: log2,
39103
- bridgeReport: false,
39104
- forceAllTypes: false,
39105
- shouldContinue: isCurrent
39106
- });
39107
- if (n > 0) await sendBatchFromCache();
39108
- } catch (e) {
39109
- if (e instanceof CliSqliteInterrupted) return;
39110
- log2(`[Bridge service] Agent capability probe (missing cache) failed: ${e instanceof Error ? e.message : String(e)}`);
39111
- }
39112
- if (!isCurrent()) return;
39113
39196
  void (async () => {
39114
39197
  try {
39115
39198
  await yieldToEventLoop();
39116
39199
  if (!isCurrent()) return;
39200
+ let types = [];
39201
+ try {
39202
+ types = [...await detectLocalAgentTypes()];
39203
+ } catch (e) {
39204
+ log2(`[Bridge service] detectLocalAgentTypes failed: ${e instanceof Error ? e.message : String(e)}`);
39205
+ }
39206
+ if (!isCurrent()) return;
39117
39207
  const n = await probeAgentCapabilitiesForDetectedTypes({
39118
39208
  agentTypes: types,
39119
39209
  cwd,
39120
39210
  workspaceId,
39121
39211
  log: log2,
39122
39212
  bridgeReport: false,
39123
- forceAllTypes: true,
39213
+ forceAllTypes: false,
39124
39214
  shouldContinue: isCurrent
39125
39215
  });
39126
39216
  if (n > 0) await sendBatchFromCache();
39127
39217
  } catch (e) {
39128
39218
  if (e instanceof CliSqliteInterrupted) return;
39129
- log2(`[Bridge service] Agent capability lazy refresh failed: ${e instanceof Error ? e.message : String(e)}`);
39219
+ log2(`[Bridge service] Agent capability probe failed: ${e instanceof Error ? e.message : String(e)}`);
39130
39220
  }
39131
39221
  })();
39132
39222
  }
@@ -40538,7 +40628,7 @@ function createBridgeHeartbeatController(params) {
40538
40628
  }
40539
40629
 
40540
40630
  // ../bridge/src/cli/cli-version.ts
40541
- var CLI_VERSION = "0.1.92".length > 0 ? "0.1.92" : "0.0.0-dev";
40631
+ var CLI_VERSION = "0.1.94".length > 0 ? "0.1.94" : "0.0.0-dev";
40542
40632
 
40543
40633
  // ../bridge/src/connection/identify/send-bridge-identify.ts
40544
40634
  function sendBridgeIdentify(ws, params) {
@@ -50437,7 +50527,6 @@ var handleBridgeIdentified = (msg, deps) => {
50437
50527
  });
50438
50528
  setImmediate(() => {
50439
50529
  void (async () => {
50440
- cancelInFlightAgentCapabilityWarmup();
50441
50530
  try {
50442
50531
  await deps.reportAutoDetectedAgents?.();
50443
50532
  } catch (e) {
@@ -50445,13 +50534,11 @@ var handleBridgeIdentified = (msg, deps) => {
50445
50534
  `[Bridge service] Auto-detect agents failed: ${e instanceof Error ? e.message : String(e)}`
50446
50535
  );
50447
50536
  }
50448
- try {
50449
- await deps.warmupAgentCapabilitiesOnConnect?.();
50450
- } catch (e) {
50537
+ void deps.warmupAgentCapabilitiesOnConnect?.()?.catch((e) => {
50451
50538
  deps.log(
50452
50539
  `[Bridge service] Agent capability warmup failed: ${e instanceof Error ? e.message : String(e)}`
50453
50540
  );
50454
- }
50541
+ });
50455
50542
  })();
50456
50543
  });
50457
50544
  };
@@ -52339,6 +52426,7 @@ function createMainBridgeCloseHandler(params, connect) {
52339
52426
  const { state, logFn, bridgeHeartbeat } = params;
52340
52427
  return (code, reason, closedWs) => {
52341
52428
  if (state.currentWs !== closedWs) return;
52429
+ cancelInFlightAgentCapabilityWarmup();
52342
52430
  bridgeHeartbeat?.stop();
52343
52431
  try {
52344
52432
  state.currentWs = null;
@@ -52466,20 +52554,8 @@ function createMainBridgeWebSocketLifecycle(params) {
52466
52554
  }
52467
52555
  }
52468
52556
  bridgeHeartbeat?.stop();
52469
- const prev = state.currentWs;
52470
- if (prev) {
52471
- prev.removeAllListeners();
52472
- prev.once("error", () => {
52473
- });
52474
- prev.once("close", () => {
52475
- prev.removeAllListeners();
52476
- });
52477
- try {
52478
- prev.close();
52479
- } catch {
52480
- }
52481
- state.currentWs = null;
52482
- }
52557
+ disposePreviousBridgeSocket(state.currentWs);
52558
+ state.currentWs = null;
52483
52559
  try {
52484
52560
  const url2 = plugin.transport.resolveControlPlaneUrl({
52485
52561
  workspaceId,
@@ -52976,7 +53052,7 @@ async function defaultBrowserId() {
52976
53052
  // ../../node_modules/.pnpm/run-applescript@7.1.0/node_modules/run-applescript/index.js
52977
53053
  import process6 from "node:process";
52978
53054
  import { promisify as promisify5 } from "node:util";
52979
- import { execFile as execFile4, execFileSync as execFileSync3 } from "node:child_process";
53055
+ import { execFile as execFile4, execFileSync as execFileSync2 } from "node:child_process";
52980
53056
  var execFileAsync4 = promisify5(execFile4);
52981
53057
  async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
52982
53058
  if (process6.platform !== "darwin") {
@@ -53463,7 +53539,7 @@ function createPendingAuthOnMessage(params) {
53463
53539
  }
53464
53540
 
53465
53541
  // src/cli-version.ts
53466
- var CLI_VERSION2 = "0.1.92".length > 0 ? "0.1.92" : "0.0.0-dev";
53542
+ var CLI_VERSION2 = "0.1.94".length > 0 ? "0.1.94" : "0.0.0-dev";
53467
53543
 
53468
53544
  // src/auth/pending/pending-auth-on-open.ts
53469
53545
  function createPendingAuthOnOpen(params) {