@buildautomaton/cli 0.1.79 → 0.1.80

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
@@ -27169,6 +27169,16 @@ async function awaitSymbolIndexWorkerShutdown() {
27169
27169
  await terminateSymbolIndexWorker2();
27170
27170
  }
27171
27171
  }
27172
+ async function clearCliImmediateShutdown() {
27173
+ if (symbolIndexShutdownPromise != null) {
27174
+ try {
27175
+ await symbolIndexShutdownPromise;
27176
+ } catch {
27177
+ }
27178
+ }
27179
+ cliImmediateShutdownRequested = false;
27180
+ symbolIndexShutdownPromise = null;
27181
+ }
27172
27182
  function resetCliImmediateShutdownForTests() {
27173
27183
  cliImmediateShutdownRequested = false;
27174
27184
  symbolIndexShutdownPromise = null;
@@ -28122,6 +28132,29 @@ function safeSendWebSocketBinary(ws, data) {
28122
28132
  }
28123
28133
  }
28124
28134
 
28135
+ // src/connection/create-ws-bridge-options.ts
28136
+ var BRIDGE_AUTH_ERROR_HEADER = "x-bridge-auth-error";
28137
+ var BRIDGE_AUTH_ERROR_TOKEN_INVALID = "token_invalid";
28138
+
28139
+ // src/connection/dispatch-ws-inbound-message.ts
28140
+ function dispatchWsInboundMessage(raw, ws, onMessage, isActiveSocket) {
28141
+ if (isActiveSocket && !isActiveSocket(ws)) return;
28142
+ try {
28143
+ let data;
28144
+ if (typeof raw === "string") {
28145
+ data = JSON.parse(raw);
28146
+ } else if (Buffer.isBuffer(raw) || raw instanceof ArrayBuffer) {
28147
+ const str = Buffer.isBuffer(raw) ? raw.toString("utf8") : Buffer.from(raw).toString("utf8");
28148
+ data = JSON.parse(str);
28149
+ } else {
28150
+ data = raw;
28151
+ }
28152
+ onMessage?.(data, ws);
28153
+ } catch {
28154
+ onMessage?.(raw, ws);
28155
+ }
28156
+ }
28157
+
28125
28158
  // src/connection/parse-compact-heartbeat-ack.ts
28126
28159
  function tryParseCompactHeartbeatAck(raw) {
28127
28160
  let str = null;
@@ -28149,8 +28182,6 @@ function tryParseCompactHeartbeatAck(raw) {
28149
28182
  }
28150
28183
 
28151
28184
  // src/connection/create-ws-bridge.ts
28152
- var BRIDGE_AUTH_ERROR_HEADER = "x-bridge-auth-error";
28153
- var BRIDGE_AUTH_ERROR_TOKEN_INVALID = "token_invalid";
28154
28185
  function createWsBridge(options) {
28155
28186
  const {
28156
28187
  url: url2,
@@ -28161,15 +28192,16 @@ function createWsBridge(options) {
28161
28192
  onAuthInvalid,
28162
28193
  clientPingIntervalMs,
28163
28194
  onCompactHeartbeatAck,
28164
- isActiveSocket
28195
+ isActiveSocket,
28196
+ deferInboundMessages = true
28165
28197
  } = options;
28166
28198
  const ws = new wrapper_default(url2, buildCliWebSocketClientOptions(url2));
28167
28199
  let clearClientPing = null;
28168
- function disposeClientPing() {
28200
+ const disposeClientPing = () => {
28169
28201
  clearClientPing?.();
28170
28202
  clearClientPing = null;
28171
- }
28172
- ws.on("unexpected-response", (request, response) => {
28203
+ };
28204
+ ws.on("unexpected-response", (_request, response) => {
28173
28205
  const status = response?.statusCode ?? 0;
28174
28206
  const headers = response?.headers ?? {};
28175
28207
  const errCode = (headers[BRIDGE_AUTH_ERROR_HEADER] ?? headers["X-Bridge-Auth-Error"] ?? "").toLowerCase();
@@ -28190,23 +28222,11 @@ function createWsBridge(options) {
28190
28222
  onCompactHeartbeatAck?.(ackSeq);
28191
28223
  return;
28192
28224
  }
28193
- setImmediate(() => {
28194
- if (isActiveSocket && !isActiveSocket(ws)) return;
28195
- try {
28196
- let data;
28197
- if (typeof raw === "string") {
28198
- data = JSON.parse(raw);
28199
- } else if (Buffer.isBuffer(raw) || raw instanceof ArrayBuffer) {
28200
- const str = Buffer.isBuffer(raw) ? raw.toString("utf8") : Buffer.from(raw).toString("utf8");
28201
- data = JSON.parse(str);
28202
- } else {
28203
- data = raw;
28204
- }
28205
- onMessage?.(data, ws);
28206
- } catch {
28207
- onMessage?.(raw, ws);
28208
- }
28209
- });
28225
+ if (deferInboundMessages) {
28226
+ setImmediate(() => dispatchWsInboundMessage(raw, ws, onMessage, isActiveSocket));
28227
+ return;
28228
+ }
28229
+ dispatchWsInboundMessage(raw, ws, onMessage, isActiveSocket);
28210
28230
  });
28211
28231
  ws.on("close", (code, reason) => {
28212
28232
  disposeClientPing();
@@ -30637,14 +30657,8 @@ function installBridgeProcessResilience() {
30637
30657
  });
30638
30658
  }
30639
30659
 
30640
- // src/cli-version.ts
30641
- var CLI_VERSION = "0.1.79".length > 0 ? "0.1.79" : "0.0.0-dev";
30642
-
30643
- // src/connection/heartbeat/constants.ts
30644
- var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
30645
- var BRIDGE_HEARTBEAT_SEQ_MAX = 2147483646;
30646
- var BRIDGE_HEARTBEAT_MISSED_ACKS_BEFORE_RECONNECT = 4;
30647
- var BRIDGE_HEARTBEAT_RTT_SAMPLE_MAX = 5;
30660
+ // src/auth/pending/run-pending-auth.ts
30661
+ init_log();
30648
30662
 
30649
30663
  // ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
30650
30664
  import process7 from "node:process";
@@ -31199,8 +31213,16 @@ async function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName
31199
31213
  }
31200
31214
  }
31201
31215
 
31202
- // src/auth/run-pending-auth.ts
31203
- init_log();
31216
+ // src/auth/pending/constants.ts
31217
+ var PENDING_KEEPALIVE_MS = 25e3;
31218
+ var BROWSER_OPEN_FALLBACK_MS = 4e3;
31219
+
31220
+ // src/auth/pending/build-pending-bridge-url.ts
31221
+ function buildPendingBridgeUrl(apiUrl, connectionId) {
31222
+ const base = apiUrl.startsWith("https") ? apiUrl.replace(/^https/, "wss") : apiUrl.replace(/^http/, "ws");
31223
+ const params = new URLSearchParams({ connectionId });
31224
+ return `${base}/ws/bridge/pending?${params.toString()}`;
31225
+ }
31204
31226
 
31205
31227
  // src/connection/reconnect/constants.ts
31206
31228
  var RECONNECT_QUIET_MS = 2e3;
@@ -31531,6 +31553,12 @@ function scheduleMainBridgeReconnect(state, connect, log2, closeMeta) {
31531
31553
  });
31532
31554
  }
31533
31555
 
31556
+ // src/connection/heartbeat/constants.ts
31557
+ var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
31558
+ var BRIDGE_HEARTBEAT_SEQ_MAX = 2147483646;
31559
+ var BRIDGE_HEARTBEAT_MISSED_ACKS_BEFORE_RECONNECT = 4;
31560
+ var BRIDGE_HEARTBEAT_RTT_SAMPLE_MAX = 5;
31561
+
31534
31562
  // src/connection/reconnect/duplicate-bridge-connection-detect.ts
31535
31563
  var BRIDGE_SUPERSEDED_CLOSE_REASON_SNIPPET = "superseded";
31536
31564
  var DUPLICATE_BRIDGE_SHORT_SESSION_MS = 25e3;
@@ -31615,145 +31643,180 @@ function clearFirehoseReconnectQuietOnOpen(ctx, log2) {
31615
31643
  });
31616
31644
  }
31617
31645
 
31618
- // src/auth/run-pending-auth.ts
31619
- var PENDING_KEEPALIVE_MS = 25e3;
31620
- var BROWSER_OPEN_FALLBACK_MS = 4e3;
31621
- function buildPendingBridgeUrl(apiUrl, connectionId) {
31622
- const base = apiUrl.startsWith("https") ? apiUrl.replace(/^https/, "wss") : apiUrl.replace(/^http/, "ws");
31623
- const params = new URLSearchParams({ connectionId });
31624
- return `${base}/ws/bridge/pending?${params.toString()}`;
31625
- }
31626
- function runPendingAuth(options) {
31627
- const { apiUrl, initialWorkspaceId, preferredBridgeName, onAuth } = options;
31628
- const logFn = options.log ?? log;
31629
- let ws = null;
31630
- let reconnectTimeout = null;
31631
- let keepaliveInterval = null;
31632
- let browserFallback = null;
31633
- const connectionId = crypto.randomUUID();
31634
- let hasOpenedBrowser = false;
31635
- let resolved = false;
31636
- let resolveAuth;
31637
- const authPromise = new Promise((resolve35) => {
31638
- resolveAuth = resolve35;
31639
- });
31640
- let reconnectAttempt = 0;
31641
- const signInQuiet = createEmptyReconnectQuietSlot();
31642
- function clearQuietOnOpen() {
31643
- clearReconnectQuietOnSuccessfulConnection(
31644
- signInQuiet,
31645
- logFn,
31646
- "[Bridge service] Sign-in connection restored."
31647
- );
31648
- reconnectAttempt = 0;
31649
- }
31650
- function beginDeferredPendingCloseLog(code, reason) {
31646
+ // src/auth/pending/pending-auth-on-close.ts
31647
+ function createPendingAuthOnClose(params) {
31648
+ const { session, log: log2, connect } = params;
31649
+ return (code, reason) => {
31650
+ if (session.keepaliveInterval) {
31651
+ clearInterval(session.keepaliveInterval);
31652
+ session.keepaliveInterval = null;
31653
+ }
31654
+ if (session.resolved) return;
31651
31655
  beginDeferredDisconnectForReconnect({
31652
- isClosedByUser: () => resolved,
31653
- quiet: signInQuiet,
31656
+ isClosedByUser: () => session.resolved,
31657
+ quiet: session.signInQuiet,
31654
31658
  code,
31655
31659
  reason,
31656
31660
  willReconnect: true,
31657
- log: logFn,
31661
+ log: log2,
31658
31662
  serviceLabel: "[Bridge service]",
31659
31663
  shutdownDetail: "Not reconnecting (shutting down).",
31660
31664
  reconnectingDetail: "Waiting for browser sign-in; reconnecting\u2026",
31661
- shouldAbortQuietWindow: () => ws != null && ws.readyState === wrapper_default.OPEN
31665
+ shouldAbortQuietWindow: () => session.ws != null && session.ws.readyState === wrapper_default.OPEN
31662
31666
  });
31663
- }
31664
- function cleanup() {
31665
- clearReconnectQuietTimer(signInQuiet);
31666
- if (reconnectTimeout) {
31667
- clearTimeout(reconnectTimeout);
31668
- reconnectTimeout = null;
31669
- }
31670
- if (browserFallback) {
31671
- clearTimeout(browserFallback);
31672
- browserFallback = null;
31673
- }
31674
- if (keepaliveInterval) {
31675
- clearInterval(keepaliveInterval);
31676
- keepaliveInterval = null;
31677
- }
31678
- if (ws) {
31679
- const w = ws;
31680
- ws = null;
31681
- safeCloseWebSocket(w);
31667
+ const delay4 = pendingAuthReconnectDelayMs(session.reconnectAttempt);
31668
+ session.reconnectAttempt += 1;
31669
+ if (session.signInQuiet.verboseLogs) {
31670
+ const delayLabel = formatReconnectDelayForLog(delay4);
31671
+ log2(
31672
+ `[Bridge service] Next sign-in connection attempt in ${delayLabel} (attempt ${session.reconnectAttempt}).`
31673
+ );
31682
31674
  }
31675
+ session.reconnectTimeout = setTimeout(() => {
31676
+ session.reconnectTimeout = null;
31677
+ connect();
31678
+ }, delay4);
31679
+ };
31680
+ }
31681
+
31682
+ // src/auth/pending/pending-auth-session.ts
31683
+ function createPendingAuthSession() {
31684
+ let resolveAuth;
31685
+ const authPromise = new Promise((resolve35) => {
31686
+ resolveAuth = resolve35;
31687
+ });
31688
+ return {
31689
+ ws: null,
31690
+ reconnectTimeout: null,
31691
+ keepaliveInterval: null,
31692
+ browserFallback: null,
31693
+ connectionId: crypto.randomUUID(),
31694
+ hasOpenedBrowser: false,
31695
+ resolved: false,
31696
+ resolveAuth,
31697
+ reconnectAttempt: 0,
31698
+ signInQuiet: createEmptyReconnectQuietSlot(),
31699
+ authPromise
31700
+ };
31701
+ }
31702
+ function cleanupPendingAuthSession(session) {
31703
+ clearReconnectQuietTimer(session.signInQuiet);
31704
+ if (session.reconnectTimeout) {
31705
+ clearTimeout(session.reconnectTimeout);
31706
+ session.reconnectTimeout = null;
31683
31707
  }
31684
- function connect() {
31685
- const url2 = buildPendingBridgeUrl(apiUrl, connectionId);
31686
- let pendingHbSeq = -1;
31687
- ws = createWsBridge({
31688
- url: url2,
31689
- onOpen: () => {
31690
- clearQuietOnOpen();
31691
- pendingHbSeq = -1;
31692
- sendWsMessage(ws, { type: "identify", role: "cli", cliVersion: CLI_VERSION });
31693
- keepaliveInterval = setInterval(() => {
31694
- if (resolved || !ws || ws.readyState !== 1) return;
31695
- pendingHbSeq = pendingHbSeq >= BRIDGE_HEARTBEAT_SEQ_MAX ? 0 : pendingHbSeq + 1;
31696
- const hb = { t: "h", s: pendingHbSeq };
31697
- sendWsMessage(ws, hb);
31698
- }, PENDING_KEEPALIVE_MS);
31699
- if (browserFallback) {
31700
- clearTimeout(browserFallback);
31701
- browserFallback = null;
31702
- }
31703
- if (!hasOpenedBrowser) {
31704
- hasOpenedBrowser = true;
31705
- void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
31706
- }
31707
- },
31708
- onClose: (code, reason) => {
31709
- if (keepaliveInterval) {
31710
- clearInterval(keepaliveInterval);
31711
- keepaliveInterval = null;
31712
- }
31713
- if (resolved) return;
31714
- beginDeferredPendingCloseLog(code, reason);
31715
- const delay4 = pendingAuthReconnectDelayMs(reconnectAttempt);
31716
- reconnectAttempt += 1;
31717
- if (signInQuiet.verboseLogs) {
31718
- const delayLabel = formatReconnectDelayForLog(delay4);
31719
- logFn(
31720
- `[Bridge service] Next sign-in connection attempt in ${delayLabel} (attempt ${reconnectAttempt}).`
31721
- );
31722
- }
31723
- reconnectTimeout = setTimeout(() => {
31724
- reconnectTimeout = null;
31725
- connect();
31726
- }, delay4);
31727
- },
31728
- onError: (err) => logCliWebSocketError(logFn, "[Bridge service]", err, "while waiting for sign-in"),
31729
- onMessage: (data) => {
31730
- const msg = data;
31731
- if (msg.type === "auth_token" && typeof msg.token === "string") {
31732
- resolved = true;
31733
- const workspaceId = typeof msg.workspaceId === "string" ? msg.workspaceId : "";
31734
- cleanup();
31735
- const refreshToken = typeof msg.refreshToken === "string" ? msg.refreshToken : void 0;
31736
- const result = { workspaceId, token: msg.token, refreshToken };
31737
- resolveAuth(result);
31738
- onAuth(result);
31739
- }
31740
- }
31741
- });
31708
+ if (session.browserFallback) {
31709
+ clearTimeout(session.browserFallback);
31710
+ session.browserFallback = null;
31742
31711
  }
31743
- browserFallback = setTimeout(() => {
31744
- browserFallback = null;
31745
- if (!hasOpenedBrowser) {
31746
- hasOpenedBrowser = true;
31747
- void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
31712
+ if (session.keepaliveInterval) {
31713
+ clearInterval(session.keepaliveInterval);
31714
+ session.keepaliveInterval = null;
31715
+ }
31716
+ if (session.ws) {
31717
+ const w = session.ws;
31718
+ session.ws = null;
31719
+ safeCloseWebSocket(w);
31720
+ }
31721
+ }
31722
+
31723
+ // src/auth/pending/pending-auth-on-message.ts
31724
+ function createPendingAuthOnMessage(params) {
31725
+ const { session, onAuth } = params;
31726
+ return (data) => {
31727
+ const msg = data;
31728
+ if (msg.type !== "auth_token" || typeof msg.token !== "string") return;
31729
+ session.resolved = true;
31730
+ const workspaceId = typeof msg.workspaceId === "string" ? msg.workspaceId : "";
31731
+ const refreshToken = typeof msg.refreshToken === "string" ? msg.refreshToken : void 0;
31732
+ const result = { workspaceId, token: msg.token, refreshToken };
31733
+ session.resolveAuth(result);
31734
+ onAuth(result);
31735
+ cleanupPendingAuthSession(session);
31736
+ };
31737
+ }
31738
+
31739
+ // src/cli-version.ts
31740
+ var CLI_VERSION = "0.1.80".length > 0 ? "0.1.80" : "0.0.0-dev";
31741
+
31742
+ // src/auth/pending/pending-auth-on-open.ts
31743
+ function createPendingAuthOnOpen(params) {
31744
+ const { session, apiUrl, initialWorkspaceId, preferredBridgeName, log: log2 } = params;
31745
+ let pendingHbSeq = -1;
31746
+ return () => {
31747
+ clearReconnectQuietOnSuccessfulConnection(
31748
+ session.signInQuiet,
31749
+ log2,
31750
+ "[Bridge service] Sign-in connection restored."
31751
+ );
31752
+ session.reconnectAttempt = 0;
31753
+ pendingHbSeq = -1;
31754
+ sendWsMessage(session.ws, { type: "identify", role: "cli", cliVersion: CLI_VERSION });
31755
+ session.keepaliveInterval = setInterval(() => {
31756
+ if (session.resolved || !session.ws || session.ws.readyState !== 1) return;
31757
+ pendingHbSeq = pendingHbSeq >= BRIDGE_HEARTBEAT_SEQ_MAX ? 0 : pendingHbSeq + 1;
31758
+ const hb = { t: "h", s: pendingHbSeq };
31759
+ sendWsMessage(session.ws, hb);
31760
+ }, PENDING_KEEPALIVE_MS);
31761
+ if (session.browserFallback) {
31762
+ clearTimeout(session.browserFallback);
31763
+ session.browserFallback = null;
31764
+ }
31765
+ if (!session.hasOpenedBrowser) {
31766
+ session.hasOpenedBrowser = true;
31767
+ void openBrowser(session.connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, log2);
31768
+ }
31769
+ };
31770
+ }
31771
+
31772
+ // src/auth/pending/connect-pending-auth.ts
31773
+ function connectPendingAuth(params) {
31774
+ const { session, apiUrl, initialWorkspaceId, preferredBridgeName, onAuth, log: log2 } = params;
31775
+ const connect = () => {
31776
+ session.ws = createWsBridge({
31777
+ url: buildPendingBridgeUrl(apiUrl, session.connectionId),
31778
+ deferInboundMessages: false,
31779
+ onOpen: createPendingAuthOnOpen({
31780
+ session,
31781
+ apiUrl,
31782
+ initialWorkspaceId,
31783
+ preferredBridgeName,
31784
+ log: log2
31785
+ }),
31786
+ onClose: createPendingAuthOnClose({ session, log: log2, connect }),
31787
+ onError: (err) => logCliWebSocketError(log2, "[Bridge service]", err, "while waiting for sign-in"),
31788
+ onMessage: createPendingAuthOnMessage({ session, onAuth })
31789
+ });
31790
+ };
31791
+ connect();
31792
+ }
31793
+
31794
+ // src/auth/pending/run-pending-auth.ts
31795
+ function runPendingAuth(options) {
31796
+ const { apiUrl, initialWorkspaceId, preferredBridgeName, onAuth } = options;
31797
+ const logFn = options.log ?? log;
31798
+ const session = createPendingAuthSession();
31799
+ session.browserFallback = setTimeout(() => {
31800
+ session.browserFallback = null;
31801
+ if (!session.hasOpenedBrowser) {
31802
+ session.hasOpenedBrowser = true;
31803
+ void openBrowser(session.connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
31748
31804
  }
31749
31805
  }, BROWSER_OPEN_FALLBACK_MS);
31750
- connect();
31806
+ connectPendingAuth({
31807
+ session,
31808
+ apiUrl,
31809
+ initialWorkspaceId,
31810
+ preferredBridgeName,
31811
+ onAuth,
31812
+ log: logFn
31813
+ });
31751
31814
  return {
31752
31815
  close: () => {
31753
- if (!resolved) resolveAuth(null);
31754
- cleanup();
31816
+ if (!session.resolved) session.resolveAuth(null);
31817
+ cleanupPendingAuthSession(session);
31755
31818
  },
31756
- authPromise
31819
+ authPromise: session.authPromise
31757
31820
  };
31758
31821
  }
31759
31822
 
@@ -51046,32 +51109,42 @@ async function openE2eCertificateImportUrl({
51046
51109
  }
51047
51110
  }
51048
51111
 
51049
- // src/run-bridge-connected.ts
51112
+ // src/run-bridge-e2ee-key-command.ts
51113
+ function installConnectedBridgeE2eeKeyCommand(params) {
51114
+ let openingCertificate = false;
51115
+ return installE2eCertificateKeyCommand({
51116
+ log: params.log,
51117
+ onInterrupt: params.onInterrupt,
51118
+ onOpenCertificate: () => {
51119
+ if (openingCertificate) return;
51120
+ openingCertificate = true;
51121
+ void openE2eCertificateImportUrl({
51122
+ apiUrl: params.apiUrl,
51123
+ workspaceId: params.workspaceId,
51124
+ certificate: params.e2eCertificate,
51125
+ log: params.log
51126
+ }).finally(() => {
51127
+ openingCertificate = false;
51128
+ });
51129
+ }
51130
+ });
51131
+ }
51132
+
51133
+ // src/run-bridge-connected-signals.ts
51134
+ init_log();
51050
51135
  init_cli_process_interrupt();
51051
- init_cli_database();
51052
- async function runConnectedBridge(options, restartWithoutAuth) {
51053
- const {
51054
- apiUrl,
51055
- workspaceId,
51056
- authToken,
51057
- refreshToken,
51058
- justAuthenticated,
51059
- worktreesRootPath,
51060
- e2eCertificate
51061
- } = options;
51062
- const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
51063
- let cleanupKeyCommand;
51064
- let bridgeClose = null;
51136
+ function installConnectedBridgeSignals(params) {
51065
51137
  let shutdownStarted = false;
51066
51138
  const onSignal = (kind) => {
51067
51139
  requestCliImmediateShutdown();
51068
51140
  abortActiveGitChildProcesses();
51069
- cleanupKeyCommand?.();
51141
+ params.cleanupKeyCommand();
51070
51142
  if (shutdownStarted) return;
51071
51143
  shutdownStarted = true;
51072
51144
  logImmediate(
51073
51145
  kind === "interrupt" ? "Keyboard interrupt (Ctrl+C) \u2014 stopping\u2026" : "Stop requested \u2014 shutting down\u2026"
51074
51146
  );
51147
+ const bridgeClose = params.getBridgeClose();
51075
51148
  if (bridgeClose) {
51076
51149
  void bridgeClose().finally(() => process.exit(0));
51077
51150
  return;
@@ -51082,9 +51155,56 @@ async function runConnectedBridge(options, restartWithoutAuth) {
51082
51155
  const onSigTerm = () => onSignal("stop");
51083
51156
  process.on("SIGINT", onSigInt);
51084
51157
  process.on("SIGTERM", onSigTerm);
51085
- let handle;
51158
+ return {
51159
+ onSigInt,
51160
+ remove: () => {
51161
+ process.off("SIGINT", onSigInt);
51162
+ process.off("SIGTERM", onSigTerm);
51163
+ }
51164
+ };
51165
+ }
51166
+
51167
+ // src/run-bridge-on-auth-invalid.ts
51168
+ init_cli_process_interrupt();
51169
+ async function closeBridgeForReauth(params) {
51170
+ params.log("[Bridge service] Access token invalid or revoked; re-authenticating\u2026");
51171
+ clearConfigForApi(params.apiUrl);
51172
+ await params.close();
51173
+ params.removeSignalHandlers();
51174
+ await clearCliImmediateShutdown();
51175
+ params.endConnectedSession();
51176
+ }
51177
+
51178
+ // src/run-bridge-connected.ts
51179
+ init_cli_database();
51180
+ async function runConnectedBridge(options, restartWithoutAuth) {
51181
+ const {
51182
+ apiUrl,
51183
+ workspaceId,
51184
+ authToken,
51185
+ refreshToken,
51186
+ justAuthenticated,
51187
+ worktreesRootPath,
51188
+ e2eCertificate
51189
+ } = options;
51190
+ const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
51191
+ let cleanupKeyCommand;
51192
+ let bridgeClose = null;
51193
+ let endConnectedSession;
51194
+ const sessionDone = new Promise((resolve35) => {
51195
+ endConnectedSession = resolve35;
51196
+ });
51197
+ let resolveHandleReady;
51198
+ const handleReady = new Promise((resolve35) => {
51199
+ resolveHandleReady = resolve35;
51200
+ });
51201
+ const handleRef = { current: null };
51202
+ const signals = installConnectedBridgeSignals({
51203
+ getBridgeClose: () => bridgeClose,
51204
+ cleanupKeyCommand: () => cleanupKeyCommand?.()
51205
+ });
51086
51206
  try {
51087
- handle = await createBridgeConnection({
51207
+ const handle = await createBridgeConnection({
51088
51208
  apiUrl,
51089
51209
  workspaceId,
51090
51210
  authToken,
@@ -51103,41 +51223,40 @@ async function runConnectedBridge(options, restartWithoutAuth) {
51103
51223
  },
51104
51224
  onAuthInvalid: () => {
51105
51225
  cleanupKeyCommand?.();
51106
- log("[Bridge service] Access token invalid or revoked; re-authenticating\u2026");
51107
- clearConfigForApi(apiUrl);
51108
- void handle.close().then(() => {
51109
- void restartWithoutAuth({ apiUrl, firehoseServerUrl, worktreesRootPath, e2eCertificate });
51110
- });
51226
+ void (async () => {
51227
+ await handleReady;
51228
+ await closeBridgeForReauth({
51229
+ apiUrl,
51230
+ log,
51231
+ close: async () => {
51232
+ if (handleRef.current) await handleRef.current.close();
51233
+ },
51234
+ removeSignalHandlers: signals.remove,
51235
+ endConnectedSession
51236
+ });
51237
+ })();
51111
51238
  }
51112
51239
  });
51113
- } catch (e) {
51114
- process.off("SIGINT", onSigInt);
51115
- process.off("SIGTERM", onSigTerm);
51116
- if (e instanceof CliSqliteInterrupted) {
51117
- process.exit(0);
51240
+ handleRef.current = handle;
51241
+ bridgeClose = () => handle.close();
51242
+ if (e2eCertificate) {
51243
+ cleanupKeyCommand = installConnectedBridgeE2eeKeyCommand({
51244
+ apiUrl,
51245
+ workspaceId,
51246
+ e2eCertificate,
51247
+ log,
51248
+ onInterrupt: signals.onSigInt
51249
+ });
51118
51250
  }
51251
+ } catch (e) {
51252
+ signals.remove();
51253
+ if (e instanceof CliSqliteInterrupted) process.exit(0);
51119
51254
  throw e;
51255
+ } finally {
51256
+ resolveHandleReady();
51120
51257
  }
51121
- bridgeClose = () => handle.close();
51122
- if (e2eCertificate) {
51123
- let openingCertificate = false;
51124
- cleanupKeyCommand = installE2eCertificateKeyCommand({
51125
- log,
51126
- onInterrupt: onSigInt,
51127
- onOpenCertificate: () => {
51128
- if (openingCertificate) return;
51129
- openingCertificate = true;
51130
- void openE2eCertificateImportUrl({
51131
- apiUrl,
51132
- workspaceId,
51133
- certificate: e2eCertificate,
51134
- log
51135
- }).finally(() => {
51136
- openingCertificate = false;
51137
- });
51138
- }
51139
- });
51140
- }
51258
+ await sessionDone;
51259
+ await restartWithoutAuth({ apiUrl, firehoseServerUrl, worktreesRootPath, e2eCertificate });
51141
51260
  }
51142
51261
 
51143
51262
  // src/run-bridge.ts
@@ -51181,12 +51300,16 @@ async function runBridge(options) {
51181
51300
  process.off("SIGINT", onSigInt);
51182
51301
  process.off("SIGTERM", onSigTerm);
51183
51302
  handle.close();
51184
- if (!auth) return;
51303
+ if (!auth) {
51304
+ log("Sign-in ended before a token was received.");
51305
+ return;
51306
+ }
51185
51307
  writeConfigForApi(apiUrl, {
51186
51308
  workspaceId: auth.workspaceId,
51187
51309
  token: auth.token,
51188
51310
  refreshToken: auth.refreshToken
51189
51311
  });
51312
+ log("Link established. Connecting with the new token\u2026");
51190
51313
  await runBridge({
51191
51314
  apiUrl,
51192
51315
  workspaceId: auth.workspaceId,