@buildautomaton/cli 0.1.78 → 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/cli.js +703 -464
- package/dist/cli.js.map +4 -4
- package/dist/index.js +561 -322
- package/dist/index.js.map +4 -4
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7262,31 +7262,31 @@ function handleWorkerOutMessage(message) {
|
|
|
7262
7262
|
return;
|
|
7263
7263
|
}
|
|
7264
7264
|
if (message.type === "error") {
|
|
7265
|
-
const
|
|
7265
|
+
const pending3 = message.requestId != null ? pendingRequests.get(message.requestId) : void 0;
|
|
7266
7266
|
maybeLogCodeNavCacheWorkerError(message.message);
|
|
7267
|
-
if (
|
|
7267
|
+
if (pending3 != null) {
|
|
7268
7268
|
pendingRequests.delete(message.requestId);
|
|
7269
7269
|
if (isCliImmediateShutdownRequested()) {
|
|
7270
|
-
|
|
7270
|
+
pending3.reject(new CliSqliteInterrupted());
|
|
7271
7271
|
} else {
|
|
7272
|
-
|
|
7272
|
+
pending3.reject(new Error(message.message));
|
|
7273
7273
|
}
|
|
7274
7274
|
}
|
|
7275
7275
|
return;
|
|
7276
7276
|
}
|
|
7277
7277
|
if (!("requestId" in message)) return;
|
|
7278
|
-
const
|
|
7279
|
-
if (
|
|
7278
|
+
const pending2 = pendingRequests.get(message.requestId);
|
|
7279
|
+
if (pending2 == null) return;
|
|
7280
7280
|
pendingRequests.delete(message.requestId);
|
|
7281
|
-
|
|
7281
|
+
pending2.resolve(message);
|
|
7282
7282
|
}
|
|
7283
7283
|
function resetWorkerReadyState() {
|
|
7284
7284
|
workerReady = false;
|
|
7285
7285
|
workerReadyWaiters = [];
|
|
7286
7286
|
}
|
|
7287
7287
|
function rejectAllPendingRequests(error40) {
|
|
7288
|
-
for (const [,
|
|
7289
|
-
|
|
7288
|
+
for (const [, pending2] of pendingRequests) {
|
|
7289
|
+
pending2.reject(error40);
|
|
7290
7290
|
}
|
|
7291
7291
|
pendingRequests.clear();
|
|
7292
7292
|
}
|
|
@@ -8319,14 +8319,14 @@ function legacyCliDiskMigrationIsPending() {
|
|
|
8319
8319
|
return false;
|
|
8320
8320
|
}
|
|
8321
8321
|
function importCliSqliteLegacyDiskData(db, log2) {
|
|
8322
|
-
const
|
|
8323
|
-
if (
|
|
8322
|
+
const pending2 = legacyCliDiskMigrationIsPending();
|
|
8323
|
+
if (pending2 && log2) {
|
|
8324
8324
|
log2("Migrating legacy on-disk CLI data to SQLite\u2026");
|
|
8325
8325
|
}
|
|
8326
8326
|
archiveLegacyFileIndexJsonFiles();
|
|
8327
8327
|
importLegacyAgentSessionsFromDisk(db);
|
|
8328
8328
|
importLegacyPromptQueuesFromDisk(db);
|
|
8329
|
-
if (
|
|
8329
|
+
if (pending2 && log2) {
|
|
8330
8330
|
log2("Legacy on-disk CLI data migration finished.");
|
|
8331
8331
|
}
|
|
8332
8332
|
}
|
|
@@ -12522,6 +12522,16 @@ async function awaitSymbolIndexWorkerShutdown() {
|
|
|
12522
12522
|
await terminateSymbolIndexWorker2();
|
|
12523
12523
|
}
|
|
12524
12524
|
}
|
|
12525
|
+
async function clearCliImmediateShutdown() {
|
|
12526
|
+
if (symbolIndexShutdownPromise != null) {
|
|
12527
|
+
try {
|
|
12528
|
+
await symbolIndexShutdownPromise;
|
|
12529
|
+
} catch {
|
|
12530
|
+
}
|
|
12531
|
+
}
|
|
12532
|
+
cliImmediateShutdownRequested = false;
|
|
12533
|
+
symbolIndexShutdownPromise = null;
|
|
12534
|
+
}
|
|
12525
12535
|
function resetCliImmediateShutdownForTests() {
|
|
12526
12536
|
cliImmediateShutdownRequested = false;
|
|
12527
12537
|
symbolIndexShutdownPromise = null;
|
|
@@ -16657,7 +16667,7 @@ var require_tree_kill = __commonJS({
|
|
|
16657
16667
|
"../../node_modules/.pnpm/tree-kill@1.2.2/node_modules/tree-kill/index.js"(exports, module) {
|
|
16658
16668
|
"use strict";
|
|
16659
16669
|
var childProcess2 = __require("child_process");
|
|
16660
|
-
var
|
|
16670
|
+
var spawn12 = childProcess2.spawn;
|
|
16661
16671
|
var exec = childProcess2.exec;
|
|
16662
16672
|
module.exports = function(pid, signal, callback) {
|
|
16663
16673
|
if (typeof signal === "function" && callback === void 0) {
|
|
@@ -16682,7 +16692,7 @@ var require_tree_kill = __commonJS({
|
|
|
16682
16692
|
break;
|
|
16683
16693
|
case "darwin":
|
|
16684
16694
|
buildProcessTree(pid, tree, pidsToProcess, function(parentPid) {
|
|
16685
|
-
return
|
|
16695
|
+
return spawn12("pgrep", ["-P", parentPid]);
|
|
16686
16696
|
}, function() {
|
|
16687
16697
|
killAll(tree, signal, callback);
|
|
16688
16698
|
});
|
|
@@ -16694,7 +16704,7 @@ var require_tree_kill = __commonJS({
|
|
|
16694
16704
|
// break;
|
|
16695
16705
|
default:
|
|
16696
16706
|
buildProcessTree(pid, tree, pidsToProcess, function(parentPid) {
|
|
16697
|
-
return
|
|
16707
|
+
return spawn12("ps", ["-o", "pid", "--no-headers", "--ppid", parentPid]);
|
|
16698
16708
|
}, function() {
|
|
16699
16709
|
killAll(tree, signal, callback);
|
|
16700
16710
|
});
|
|
@@ -31071,7 +31081,7 @@ var {
|
|
|
31071
31081
|
} = import_index.default;
|
|
31072
31082
|
|
|
31073
31083
|
// src/cli-version.ts
|
|
31074
|
-
var CLI_VERSION = "0.1.
|
|
31084
|
+
var CLI_VERSION = "0.1.80".length > 0 ? "0.1.80" : "0.0.0-dev";
|
|
31075
31085
|
|
|
31076
31086
|
// src/cli/defaults.ts
|
|
31077
31087
|
var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
|
|
@@ -31533,181 +31543,8 @@ function installBridgeProcessResilience() {
|
|
|
31533
31543
|
});
|
|
31534
31544
|
}
|
|
31535
31545
|
|
|
31536
|
-
//
|
|
31537
|
-
|
|
31538
|
-
var import_receiver = __toESM(require_receiver(), 1);
|
|
31539
|
-
var import_sender = __toESM(require_sender(), 1);
|
|
31540
|
-
var import_websocket = __toESM(require_websocket(), 1);
|
|
31541
|
-
var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
31542
|
-
var wrapper_default = import_websocket.default;
|
|
31543
|
-
|
|
31544
|
-
// src/connection/cli-ws-client.ts
|
|
31545
|
-
import https from "node:https";
|
|
31546
|
-
var CLI_WEBSOCKET_CLIENT_PING_MS = 25e3;
|
|
31547
|
-
function attachWebSocketClientPing(ws, intervalMs) {
|
|
31548
|
-
let timer = null;
|
|
31549
|
-
function clear() {
|
|
31550
|
-
if (timer != null) {
|
|
31551
|
-
clearInterval(timer);
|
|
31552
|
-
timer = null;
|
|
31553
|
-
}
|
|
31554
|
-
}
|
|
31555
|
-
clear();
|
|
31556
|
-
timer = setInterval(() => {
|
|
31557
|
-
if (ws.readyState === wrapper_default.OPEN) {
|
|
31558
|
-
try {
|
|
31559
|
-
ws.ping();
|
|
31560
|
-
} catch {
|
|
31561
|
-
}
|
|
31562
|
-
}
|
|
31563
|
-
}, intervalMs);
|
|
31564
|
-
return clear;
|
|
31565
|
-
}
|
|
31566
|
-
function buildCliWebSocketClientOptions(wsUrl) {
|
|
31567
|
-
const wsOptions = { perMessageDeflate: false };
|
|
31568
|
-
if (wsUrl.startsWith("wss://")) {
|
|
31569
|
-
wsOptions.agent = new https.Agent({ rejectUnauthorized: false });
|
|
31570
|
-
}
|
|
31571
|
-
return wsOptions;
|
|
31572
|
-
}
|
|
31573
|
-
function logCliWebSocketError(log2, serviceLabel, err, detail) {
|
|
31574
|
-
const mid = detail ? ` ${detail}` : "";
|
|
31575
|
-
log2(`${serviceLabel} WebSocket error${mid}: ${err.message}`);
|
|
31576
|
-
}
|
|
31577
|
-
function safeCloseWebSocket(ws) {
|
|
31578
|
-
try {
|
|
31579
|
-
if (ws.readyState === wrapper_default.CLOSED) {
|
|
31580
|
-
ws.removeAllListeners();
|
|
31581
|
-
return;
|
|
31582
|
-
}
|
|
31583
|
-
ws.once("close", () => {
|
|
31584
|
-
ws.removeAllListeners();
|
|
31585
|
-
});
|
|
31586
|
-
ws.close();
|
|
31587
|
-
} catch {
|
|
31588
|
-
try {
|
|
31589
|
-
ws.removeAllListeners();
|
|
31590
|
-
} catch {
|
|
31591
|
-
}
|
|
31592
|
-
}
|
|
31593
|
-
}
|
|
31594
|
-
function safeSendWebSocketBinary(ws, data) {
|
|
31595
|
-
if (ws.readyState !== wrapper_default.OPEN) return false;
|
|
31596
|
-
try {
|
|
31597
|
-
ws.send(data, { binary: true });
|
|
31598
|
-
return true;
|
|
31599
|
-
} catch {
|
|
31600
|
-
return false;
|
|
31601
|
-
}
|
|
31602
|
-
}
|
|
31603
|
-
|
|
31604
|
-
// src/connection/parse-compact-heartbeat-ack.ts
|
|
31605
|
-
function tryParseCompactHeartbeatAck(raw) {
|
|
31606
|
-
let str = null;
|
|
31607
|
-
if (typeof raw === "string") {
|
|
31608
|
-
str = raw;
|
|
31609
|
-
} else if (Buffer.isBuffer(raw)) {
|
|
31610
|
-
str = raw.toString("utf8");
|
|
31611
|
-
} else if (raw instanceof ArrayBuffer) {
|
|
31612
|
-
str = Buffer.from(raw).toString("utf8");
|
|
31613
|
-
} else {
|
|
31614
|
-
return null;
|
|
31615
|
-
}
|
|
31616
|
-
if (str.length > 64 || !str.includes('"ha"')) return null;
|
|
31617
|
-
try {
|
|
31618
|
-
const parsed = JSON.parse(str);
|
|
31619
|
-
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
31620
|
-
const o = parsed;
|
|
31621
|
-
if (o.t !== "ha") return null;
|
|
31622
|
-
const s = o.s;
|
|
31623
|
-
if (typeof s !== "number" || !Number.isFinite(s)) return null;
|
|
31624
|
-
return Math.trunc(s);
|
|
31625
|
-
} catch {
|
|
31626
|
-
return null;
|
|
31627
|
-
}
|
|
31628
|
-
}
|
|
31629
|
-
|
|
31630
|
-
// src/connection/create-ws-bridge.ts
|
|
31631
|
-
var BRIDGE_AUTH_ERROR_HEADER = "x-bridge-auth-error";
|
|
31632
|
-
var BRIDGE_AUTH_ERROR_TOKEN_INVALID = "token_invalid";
|
|
31633
|
-
function createWsBridge(options) {
|
|
31634
|
-
const {
|
|
31635
|
-
url: url2,
|
|
31636
|
-
onMessage,
|
|
31637
|
-
onOpen,
|
|
31638
|
-
onClose,
|
|
31639
|
-
onError: onError2,
|
|
31640
|
-
onAuthInvalid,
|
|
31641
|
-
clientPingIntervalMs,
|
|
31642
|
-
onCompactHeartbeatAck,
|
|
31643
|
-
isActiveSocket
|
|
31644
|
-
} = options;
|
|
31645
|
-
const ws = new wrapper_default(url2, buildCliWebSocketClientOptions(url2));
|
|
31646
|
-
let clearClientPing = null;
|
|
31647
|
-
function disposeClientPing() {
|
|
31648
|
-
clearClientPing?.();
|
|
31649
|
-
clearClientPing = null;
|
|
31650
|
-
}
|
|
31651
|
-
ws.on("unexpected-response", (request, response) => {
|
|
31652
|
-
const status = response?.statusCode ?? 0;
|
|
31653
|
-
const headers = response?.headers ?? {};
|
|
31654
|
-
const errCode = (headers[BRIDGE_AUTH_ERROR_HEADER] ?? headers["X-Bridge-Auth-Error"] ?? "").toLowerCase();
|
|
31655
|
-
if (status === 401 && errCode === BRIDGE_AUTH_ERROR_TOKEN_INVALID) {
|
|
31656
|
-
void Promise.resolve(onAuthInvalid?.());
|
|
31657
|
-
}
|
|
31658
|
-
});
|
|
31659
|
-
ws.on("open", () => {
|
|
31660
|
-
disposeClientPing();
|
|
31661
|
-
if (clientPingIntervalMs != null && clientPingIntervalMs > 0) {
|
|
31662
|
-
clearClientPing = attachWebSocketClientPing(ws, clientPingIntervalMs);
|
|
31663
|
-
}
|
|
31664
|
-
onOpen?.();
|
|
31665
|
-
});
|
|
31666
|
-
ws.on("message", (raw) => {
|
|
31667
|
-
const ackSeq = tryParseCompactHeartbeatAck(raw);
|
|
31668
|
-
if (ackSeq != null) {
|
|
31669
|
-
onCompactHeartbeatAck?.(ackSeq);
|
|
31670
|
-
return;
|
|
31671
|
-
}
|
|
31672
|
-
setImmediate(() => {
|
|
31673
|
-
if (isActiveSocket && !isActiveSocket(ws)) return;
|
|
31674
|
-
try {
|
|
31675
|
-
let data;
|
|
31676
|
-
if (typeof raw === "string") {
|
|
31677
|
-
data = JSON.parse(raw);
|
|
31678
|
-
} else if (Buffer.isBuffer(raw) || raw instanceof ArrayBuffer) {
|
|
31679
|
-
const str = Buffer.isBuffer(raw) ? raw.toString("utf8") : Buffer.from(raw).toString("utf8");
|
|
31680
|
-
data = JSON.parse(str);
|
|
31681
|
-
} else {
|
|
31682
|
-
data = raw;
|
|
31683
|
-
}
|
|
31684
|
-
onMessage?.(data, ws);
|
|
31685
|
-
} catch {
|
|
31686
|
-
onMessage?.(raw, ws);
|
|
31687
|
-
}
|
|
31688
|
-
});
|
|
31689
|
-
});
|
|
31690
|
-
ws.on("close", (code, reason) => {
|
|
31691
|
-
disposeClientPing();
|
|
31692
|
-
onClose?.(code, reason.toString());
|
|
31693
|
-
});
|
|
31694
|
-
ws.on("error", (err) => {
|
|
31695
|
-
disposeClientPing();
|
|
31696
|
-
onError2?.(err);
|
|
31697
|
-
});
|
|
31698
|
-
return ws;
|
|
31699
|
-
}
|
|
31700
|
-
function sendWsMessage(ws, payload) {
|
|
31701
|
-
if (ws.readyState === wrapper_default.OPEN) {
|
|
31702
|
-
ws.send(JSON.stringify(payload));
|
|
31703
|
-
}
|
|
31704
|
-
}
|
|
31705
|
-
|
|
31706
|
-
// src/connection/heartbeat/constants.ts
|
|
31707
|
-
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
31708
|
-
var BRIDGE_HEARTBEAT_SEQ_MAX = 2147483646;
|
|
31709
|
-
var BRIDGE_HEARTBEAT_MISSED_ACKS_BEFORE_RECONNECT = 4;
|
|
31710
|
-
var BRIDGE_HEARTBEAT_RTT_SAMPLE_MAX = 5;
|
|
31546
|
+
// src/auth/pending/run-pending-auth.ts
|
|
31547
|
+
init_log();
|
|
31711
31548
|
|
|
31712
31549
|
// ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
|
|
31713
31550
|
import process7 from "node:process";
|
|
@@ -32262,8 +32099,196 @@ async function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName
|
|
|
32262
32099
|
}
|
|
32263
32100
|
}
|
|
32264
32101
|
|
|
32265
|
-
// src/auth/
|
|
32266
|
-
|
|
32102
|
+
// src/auth/pending/constants.ts
|
|
32103
|
+
var PENDING_KEEPALIVE_MS = 25e3;
|
|
32104
|
+
var BROWSER_OPEN_FALLBACK_MS = 4e3;
|
|
32105
|
+
|
|
32106
|
+
// ../../node_modules/.pnpm/ws@8.19.0/node_modules/ws/wrapper.mjs
|
|
32107
|
+
var import_stream = __toESM(require_stream(), 1);
|
|
32108
|
+
var import_receiver = __toESM(require_receiver(), 1);
|
|
32109
|
+
var import_sender = __toESM(require_sender(), 1);
|
|
32110
|
+
var import_websocket = __toESM(require_websocket(), 1);
|
|
32111
|
+
var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
32112
|
+
var wrapper_default = import_websocket.default;
|
|
32113
|
+
|
|
32114
|
+
// src/connection/cli-ws-client.ts
|
|
32115
|
+
import https from "node:https";
|
|
32116
|
+
var CLI_WEBSOCKET_CLIENT_PING_MS = 25e3;
|
|
32117
|
+
function attachWebSocketClientPing(ws, intervalMs) {
|
|
32118
|
+
let timer = null;
|
|
32119
|
+
function clear() {
|
|
32120
|
+
if (timer != null) {
|
|
32121
|
+
clearInterval(timer);
|
|
32122
|
+
timer = null;
|
|
32123
|
+
}
|
|
32124
|
+
}
|
|
32125
|
+
clear();
|
|
32126
|
+
timer = setInterval(() => {
|
|
32127
|
+
if (ws.readyState === wrapper_default.OPEN) {
|
|
32128
|
+
try {
|
|
32129
|
+
ws.ping();
|
|
32130
|
+
} catch {
|
|
32131
|
+
}
|
|
32132
|
+
}
|
|
32133
|
+
}, intervalMs);
|
|
32134
|
+
return clear;
|
|
32135
|
+
}
|
|
32136
|
+
function buildCliWebSocketClientOptions(wsUrl) {
|
|
32137
|
+
const wsOptions = { perMessageDeflate: false };
|
|
32138
|
+
if (wsUrl.startsWith("wss://")) {
|
|
32139
|
+
wsOptions.agent = new https.Agent({ rejectUnauthorized: false });
|
|
32140
|
+
}
|
|
32141
|
+
return wsOptions;
|
|
32142
|
+
}
|
|
32143
|
+
function logCliWebSocketError(log2, serviceLabel, err, detail) {
|
|
32144
|
+
const mid = detail ? ` ${detail}` : "";
|
|
32145
|
+
log2(`${serviceLabel} WebSocket error${mid}: ${err.message}`);
|
|
32146
|
+
}
|
|
32147
|
+
function safeCloseWebSocket(ws) {
|
|
32148
|
+
try {
|
|
32149
|
+
if (ws.readyState === wrapper_default.CLOSED) {
|
|
32150
|
+
ws.removeAllListeners();
|
|
32151
|
+
return;
|
|
32152
|
+
}
|
|
32153
|
+
ws.once("close", () => {
|
|
32154
|
+
ws.removeAllListeners();
|
|
32155
|
+
});
|
|
32156
|
+
ws.close();
|
|
32157
|
+
} catch {
|
|
32158
|
+
try {
|
|
32159
|
+
ws.removeAllListeners();
|
|
32160
|
+
} catch {
|
|
32161
|
+
}
|
|
32162
|
+
}
|
|
32163
|
+
}
|
|
32164
|
+
function safeSendWebSocketBinary(ws, data) {
|
|
32165
|
+
if (ws.readyState !== wrapper_default.OPEN) return false;
|
|
32166
|
+
try {
|
|
32167
|
+
ws.send(data, { binary: true });
|
|
32168
|
+
return true;
|
|
32169
|
+
} catch {
|
|
32170
|
+
return false;
|
|
32171
|
+
}
|
|
32172
|
+
}
|
|
32173
|
+
|
|
32174
|
+
// src/connection/create-ws-bridge-options.ts
|
|
32175
|
+
var BRIDGE_AUTH_ERROR_HEADER = "x-bridge-auth-error";
|
|
32176
|
+
var BRIDGE_AUTH_ERROR_TOKEN_INVALID = "token_invalid";
|
|
32177
|
+
|
|
32178
|
+
// src/connection/dispatch-ws-inbound-message.ts
|
|
32179
|
+
function dispatchWsInboundMessage(raw, ws, onMessage, isActiveSocket) {
|
|
32180
|
+
if (isActiveSocket && !isActiveSocket(ws)) return;
|
|
32181
|
+
try {
|
|
32182
|
+
let data;
|
|
32183
|
+
if (typeof raw === "string") {
|
|
32184
|
+
data = JSON.parse(raw);
|
|
32185
|
+
} else if (Buffer.isBuffer(raw) || raw instanceof ArrayBuffer) {
|
|
32186
|
+
const str = Buffer.isBuffer(raw) ? raw.toString("utf8") : Buffer.from(raw).toString("utf8");
|
|
32187
|
+
data = JSON.parse(str);
|
|
32188
|
+
} else {
|
|
32189
|
+
data = raw;
|
|
32190
|
+
}
|
|
32191
|
+
onMessage?.(data, ws);
|
|
32192
|
+
} catch {
|
|
32193
|
+
onMessage?.(raw, ws);
|
|
32194
|
+
}
|
|
32195
|
+
}
|
|
32196
|
+
|
|
32197
|
+
// src/connection/parse-compact-heartbeat-ack.ts
|
|
32198
|
+
function tryParseCompactHeartbeatAck(raw) {
|
|
32199
|
+
let str = null;
|
|
32200
|
+
if (typeof raw === "string") {
|
|
32201
|
+
str = raw;
|
|
32202
|
+
} else if (Buffer.isBuffer(raw)) {
|
|
32203
|
+
str = raw.toString("utf8");
|
|
32204
|
+
} else if (raw instanceof ArrayBuffer) {
|
|
32205
|
+
str = Buffer.from(raw).toString("utf8");
|
|
32206
|
+
} else {
|
|
32207
|
+
return null;
|
|
32208
|
+
}
|
|
32209
|
+
if (str.length > 64 || !str.includes('"ha"')) return null;
|
|
32210
|
+
try {
|
|
32211
|
+
const parsed = JSON.parse(str);
|
|
32212
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
32213
|
+
const o = parsed;
|
|
32214
|
+
if (o.t !== "ha") return null;
|
|
32215
|
+
const s = o.s;
|
|
32216
|
+
if (typeof s !== "number" || !Number.isFinite(s)) return null;
|
|
32217
|
+
return Math.trunc(s);
|
|
32218
|
+
} catch {
|
|
32219
|
+
return null;
|
|
32220
|
+
}
|
|
32221
|
+
}
|
|
32222
|
+
|
|
32223
|
+
// src/connection/create-ws-bridge.ts
|
|
32224
|
+
function createWsBridge(options) {
|
|
32225
|
+
const {
|
|
32226
|
+
url: url2,
|
|
32227
|
+
onMessage,
|
|
32228
|
+
onOpen,
|
|
32229
|
+
onClose,
|
|
32230
|
+
onError: onError2,
|
|
32231
|
+
onAuthInvalid,
|
|
32232
|
+
clientPingIntervalMs,
|
|
32233
|
+
onCompactHeartbeatAck,
|
|
32234
|
+
isActiveSocket,
|
|
32235
|
+
deferInboundMessages = true
|
|
32236
|
+
} = options;
|
|
32237
|
+
const ws = new wrapper_default(url2, buildCliWebSocketClientOptions(url2));
|
|
32238
|
+
let clearClientPing = null;
|
|
32239
|
+
const disposeClientPing = () => {
|
|
32240
|
+
clearClientPing?.();
|
|
32241
|
+
clearClientPing = null;
|
|
32242
|
+
};
|
|
32243
|
+
ws.on("unexpected-response", (_request, response) => {
|
|
32244
|
+
const status = response?.statusCode ?? 0;
|
|
32245
|
+
const headers = response?.headers ?? {};
|
|
32246
|
+
const errCode = (headers[BRIDGE_AUTH_ERROR_HEADER] ?? headers["X-Bridge-Auth-Error"] ?? "").toLowerCase();
|
|
32247
|
+
if (status === 401 && errCode === BRIDGE_AUTH_ERROR_TOKEN_INVALID) {
|
|
32248
|
+
void Promise.resolve(onAuthInvalid?.());
|
|
32249
|
+
}
|
|
32250
|
+
});
|
|
32251
|
+
ws.on("open", () => {
|
|
32252
|
+
disposeClientPing();
|
|
32253
|
+
if (clientPingIntervalMs != null && clientPingIntervalMs > 0) {
|
|
32254
|
+
clearClientPing = attachWebSocketClientPing(ws, clientPingIntervalMs);
|
|
32255
|
+
}
|
|
32256
|
+
onOpen?.();
|
|
32257
|
+
});
|
|
32258
|
+
ws.on("message", (raw) => {
|
|
32259
|
+
const ackSeq = tryParseCompactHeartbeatAck(raw);
|
|
32260
|
+
if (ackSeq != null) {
|
|
32261
|
+
onCompactHeartbeatAck?.(ackSeq);
|
|
32262
|
+
return;
|
|
32263
|
+
}
|
|
32264
|
+
if (deferInboundMessages) {
|
|
32265
|
+
setImmediate(() => dispatchWsInboundMessage(raw, ws, onMessage, isActiveSocket));
|
|
32266
|
+
return;
|
|
32267
|
+
}
|
|
32268
|
+
dispatchWsInboundMessage(raw, ws, onMessage, isActiveSocket);
|
|
32269
|
+
});
|
|
32270
|
+
ws.on("close", (code, reason) => {
|
|
32271
|
+
disposeClientPing();
|
|
32272
|
+
onClose?.(code, reason.toString());
|
|
32273
|
+
});
|
|
32274
|
+
ws.on("error", (err) => {
|
|
32275
|
+
disposeClientPing();
|
|
32276
|
+
onError2?.(err);
|
|
32277
|
+
});
|
|
32278
|
+
return ws;
|
|
32279
|
+
}
|
|
32280
|
+
function sendWsMessage(ws, payload) {
|
|
32281
|
+
if (ws.readyState !== wrapper_default.OPEN) return false;
|
|
32282
|
+
ws.send(JSON.stringify(payload));
|
|
32283
|
+
return true;
|
|
32284
|
+
}
|
|
32285
|
+
|
|
32286
|
+
// src/auth/pending/build-pending-bridge-url.ts
|
|
32287
|
+
function buildPendingBridgeUrl(apiUrl, connectionId) {
|
|
32288
|
+
const base = apiUrl.startsWith("https") ? apiUrl.replace(/^https/, "wss") : apiUrl.replace(/^http/, "ws");
|
|
32289
|
+
const params = new URLSearchParams({ connectionId });
|
|
32290
|
+
return `${base}/ws/bridge/pending?${params.toString()}`;
|
|
32291
|
+
}
|
|
32267
32292
|
|
|
32268
32293
|
// src/connection/reconnect/constants.ts
|
|
32269
32294
|
var RECONNECT_QUIET_MS = 2e3;
|
|
@@ -32594,6 +32619,12 @@ function scheduleMainBridgeReconnect(state, connect, log2, closeMeta) {
|
|
|
32594
32619
|
});
|
|
32595
32620
|
}
|
|
32596
32621
|
|
|
32622
|
+
// src/connection/heartbeat/constants.ts
|
|
32623
|
+
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
32624
|
+
var BRIDGE_HEARTBEAT_SEQ_MAX = 2147483646;
|
|
32625
|
+
var BRIDGE_HEARTBEAT_MISSED_ACKS_BEFORE_RECONNECT = 4;
|
|
32626
|
+
var BRIDGE_HEARTBEAT_RTT_SAMPLE_MAX = 5;
|
|
32627
|
+
|
|
32597
32628
|
// src/connection/reconnect/duplicate-bridge-connection-detect.ts
|
|
32598
32629
|
var BRIDGE_SUPERSEDED_CLOSE_REASON_SNIPPET = "superseded";
|
|
32599
32630
|
var DUPLICATE_BRIDGE_SHORT_SESSION_MS = 25e3;
|
|
@@ -32678,145 +32709,177 @@ function clearFirehoseReconnectQuietOnOpen(ctx, log2) {
|
|
|
32678
32709
|
});
|
|
32679
32710
|
}
|
|
32680
32711
|
|
|
32681
|
-
// src/auth/
|
|
32682
|
-
|
|
32683
|
-
|
|
32684
|
-
|
|
32685
|
-
|
|
32686
|
-
|
|
32687
|
-
|
|
32688
|
-
}
|
|
32689
|
-
|
|
32690
|
-
const { apiUrl, initialWorkspaceId, preferredBridgeName, onAuth } = options;
|
|
32691
|
-
const logFn = options.log ?? log;
|
|
32692
|
-
let ws = null;
|
|
32693
|
-
let reconnectTimeout = null;
|
|
32694
|
-
let keepaliveInterval = null;
|
|
32695
|
-
let browserFallback = null;
|
|
32696
|
-
const connectionId = crypto.randomUUID();
|
|
32697
|
-
let hasOpenedBrowser = false;
|
|
32698
|
-
let resolved = false;
|
|
32699
|
-
let resolveAuth;
|
|
32700
|
-
const authPromise = new Promise((resolve37) => {
|
|
32701
|
-
resolveAuth = resolve37;
|
|
32702
|
-
});
|
|
32703
|
-
let reconnectAttempt = 0;
|
|
32704
|
-
const signInQuiet = createEmptyReconnectQuietSlot();
|
|
32705
|
-
function clearQuietOnOpen() {
|
|
32706
|
-
clearReconnectQuietOnSuccessfulConnection(
|
|
32707
|
-
signInQuiet,
|
|
32708
|
-
logFn,
|
|
32709
|
-
"[Bridge service] Sign-in connection restored."
|
|
32710
|
-
);
|
|
32711
|
-
reconnectAttempt = 0;
|
|
32712
|
-
}
|
|
32713
|
-
function beginDeferredPendingCloseLog(code, reason) {
|
|
32712
|
+
// src/auth/pending/pending-auth-on-close.ts
|
|
32713
|
+
function createPendingAuthOnClose(params) {
|
|
32714
|
+
const { session, log: log2, connect } = params;
|
|
32715
|
+
return (code, reason) => {
|
|
32716
|
+
if (session.keepaliveInterval) {
|
|
32717
|
+
clearInterval(session.keepaliveInterval);
|
|
32718
|
+
session.keepaliveInterval = null;
|
|
32719
|
+
}
|
|
32720
|
+
if (session.resolved) return;
|
|
32714
32721
|
beginDeferredDisconnectForReconnect({
|
|
32715
|
-
isClosedByUser: () => resolved,
|
|
32716
|
-
quiet: signInQuiet,
|
|
32722
|
+
isClosedByUser: () => session.resolved,
|
|
32723
|
+
quiet: session.signInQuiet,
|
|
32717
32724
|
code,
|
|
32718
32725
|
reason,
|
|
32719
32726
|
willReconnect: true,
|
|
32720
|
-
log:
|
|
32727
|
+
log: log2,
|
|
32721
32728
|
serviceLabel: "[Bridge service]",
|
|
32722
32729
|
shutdownDetail: "Not reconnecting (shutting down).",
|
|
32723
32730
|
reconnectingDetail: "Waiting for browser sign-in; reconnecting\u2026",
|
|
32724
|
-
shouldAbortQuietWindow: () => ws != null && ws.readyState === wrapper_default.OPEN
|
|
32731
|
+
shouldAbortQuietWindow: () => session.ws != null && session.ws.readyState === wrapper_default.OPEN
|
|
32725
32732
|
});
|
|
32726
|
-
|
|
32727
|
-
|
|
32728
|
-
|
|
32729
|
-
|
|
32730
|
-
|
|
32731
|
-
|
|
32732
|
-
|
|
32733
|
-
if (browserFallback) {
|
|
32734
|
-
clearTimeout(browserFallback);
|
|
32735
|
-
browserFallback = null;
|
|
32736
|
-
}
|
|
32737
|
-
if (keepaliveInterval) {
|
|
32738
|
-
clearInterval(keepaliveInterval);
|
|
32739
|
-
keepaliveInterval = null;
|
|
32740
|
-
}
|
|
32741
|
-
if (ws) {
|
|
32742
|
-
const w = ws;
|
|
32743
|
-
ws = null;
|
|
32744
|
-
safeCloseWebSocket(w);
|
|
32733
|
+
const delay4 = pendingAuthReconnectDelayMs(session.reconnectAttempt);
|
|
32734
|
+
session.reconnectAttempt += 1;
|
|
32735
|
+
if (session.signInQuiet.verboseLogs) {
|
|
32736
|
+
const delayLabel = formatReconnectDelayForLog(delay4);
|
|
32737
|
+
log2(
|
|
32738
|
+
`[Bridge service] Next sign-in connection attempt in ${delayLabel} (attempt ${session.reconnectAttempt}).`
|
|
32739
|
+
);
|
|
32745
32740
|
}
|
|
32741
|
+
session.reconnectTimeout = setTimeout(() => {
|
|
32742
|
+
session.reconnectTimeout = null;
|
|
32743
|
+
connect();
|
|
32744
|
+
}, delay4);
|
|
32745
|
+
};
|
|
32746
|
+
}
|
|
32747
|
+
|
|
32748
|
+
// src/auth/pending/pending-auth-session.ts
|
|
32749
|
+
function createPendingAuthSession() {
|
|
32750
|
+
let resolveAuth;
|
|
32751
|
+
const authPromise = new Promise((resolve37) => {
|
|
32752
|
+
resolveAuth = resolve37;
|
|
32753
|
+
});
|
|
32754
|
+
return {
|
|
32755
|
+
ws: null,
|
|
32756
|
+
reconnectTimeout: null,
|
|
32757
|
+
keepaliveInterval: null,
|
|
32758
|
+
browserFallback: null,
|
|
32759
|
+
connectionId: crypto.randomUUID(),
|
|
32760
|
+
hasOpenedBrowser: false,
|
|
32761
|
+
resolved: false,
|
|
32762
|
+
resolveAuth,
|
|
32763
|
+
reconnectAttempt: 0,
|
|
32764
|
+
signInQuiet: createEmptyReconnectQuietSlot(),
|
|
32765
|
+
authPromise
|
|
32766
|
+
};
|
|
32767
|
+
}
|
|
32768
|
+
function cleanupPendingAuthSession(session) {
|
|
32769
|
+
clearReconnectQuietTimer(session.signInQuiet);
|
|
32770
|
+
if (session.reconnectTimeout) {
|
|
32771
|
+
clearTimeout(session.reconnectTimeout);
|
|
32772
|
+
session.reconnectTimeout = null;
|
|
32746
32773
|
}
|
|
32747
|
-
|
|
32748
|
-
|
|
32749
|
-
|
|
32750
|
-
ws = createWsBridge({
|
|
32751
|
-
url: url2,
|
|
32752
|
-
onOpen: () => {
|
|
32753
|
-
clearQuietOnOpen();
|
|
32754
|
-
pendingHbSeq = -1;
|
|
32755
|
-
sendWsMessage(ws, { type: "identify", role: "cli", cliVersion: CLI_VERSION });
|
|
32756
|
-
keepaliveInterval = setInterval(() => {
|
|
32757
|
-
if (resolved || !ws || ws.readyState !== 1) return;
|
|
32758
|
-
pendingHbSeq = pendingHbSeq >= BRIDGE_HEARTBEAT_SEQ_MAX ? 0 : pendingHbSeq + 1;
|
|
32759
|
-
const hb = { t: "h", s: pendingHbSeq };
|
|
32760
|
-
sendWsMessage(ws, hb);
|
|
32761
|
-
}, PENDING_KEEPALIVE_MS);
|
|
32762
|
-
if (browserFallback) {
|
|
32763
|
-
clearTimeout(browserFallback);
|
|
32764
|
-
browserFallback = null;
|
|
32765
|
-
}
|
|
32766
|
-
if (!hasOpenedBrowser) {
|
|
32767
|
-
hasOpenedBrowser = true;
|
|
32768
|
-
void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
32769
|
-
}
|
|
32770
|
-
},
|
|
32771
|
-
onClose: (code, reason) => {
|
|
32772
|
-
if (keepaliveInterval) {
|
|
32773
|
-
clearInterval(keepaliveInterval);
|
|
32774
|
-
keepaliveInterval = null;
|
|
32775
|
-
}
|
|
32776
|
-
if (resolved) return;
|
|
32777
|
-
beginDeferredPendingCloseLog(code, reason);
|
|
32778
|
-
const delay4 = pendingAuthReconnectDelayMs(reconnectAttempt);
|
|
32779
|
-
reconnectAttempt += 1;
|
|
32780
|
-
if (signInQuiet.verboseLogs) {
|
|
32781
|
-
const delayLabel = formatReconnectDelayForLog(delay4);
|
|
32782
|
-
logFn(
|
|
32783
|
-
`[Bridge service] Next sign-in connection attempt in ${delayLabel} (attempt ${reconnectAttempt}).`
|
|
32784
|
-
);
|
|
32785
|
-
}
|
|
32786
|
-
reconnectTimeout = setTimeout(() => {
|
|
32787
|
-
reconnectTimeout = null;
|
|
32788
|
-
connect();
|
|
32789
|
-
}, delay4);
|
|
32790
|
-
},
|
|
32791
|
-
onError: (err) => logCliWebSocketError(logFn, "[Bridge service]", err, "while waiting for sign-in"),
|
|
32792
|
-
onMessage: (data) => {
|
|
32793
|
-
const msg = data;
|
|
32794
|
-
if (msg.type === "auth_token" && typeof msg.token === "string") {
|
|
32795
|
-
resolved = true;
|
|
32796
|
-
const workspaceId = typeof msg.workspaceId === "string" ? msg.workspaceId : "";
|
|
32797
|
-
cleanup();
|
|
32798
|
-
const refreshToken = typeof msg.refreshToken === "string" ? msg.refreshToken : void 0;
|
|
32799
|
-
const result = { workspaceId, token: msg.token, refreshToken };
|
|
32800
|
-
resolveAuth(result);
|
|
32801
|
-
onAuth(result);
|
|
32802
|
-
}
|
|
32803
|
-
}
|
|
32804
|
-
});
|
|
32774
|
+
if (session.browserFallback) {
|
|
32775
|
+
clearTimeout(session.browserFallback);
|
|
32776
|
+
session.browserFallback = null;
|
|
32805
32777
|
}
|
|
32806
|
-
|
|
32807
|
-
|
|
32808
|
-
|
|
32809
|
-
|
|
32810
|
-
|
|
32778
|
+
if (session.keepaliveInterval) {
|
|
32779
|
+
clearInterval(session.keepaliveInterval);
|
|
32780
|
+
session.keepaliveInterval = null;
|
|
32781
|
+
}
|
|
32782
|
+
if (session.ws) {
|
|
32783
|
+
const w = session.ws;
|
|
32784
|
+
session.ws = null;
|
|
32785
|
+
safeCloseWebSocket(w);
|
|
32786
|
+
}
|
|
32787
|
+
}
|
|
32788
|
+
|
|
32789
|
+
// src/auth/pending/pending-auth-on-message.ts
|
|
32790
|
+
function createPendingAuthOnMessage(params) {
|
|
32791
|
+
const { session, onAuth } = params;
|
|
32792
|
+
return (data) => {
|
|
32793
|
+
const msg = data;
|
|
32794
|
+
if (msg.type !== "auth_token" || typeof msg.token !== "string") return;
|
|
32795
|
+
session.resolved = true;
|
|
32796
|
+
const workspaceId = typeof msg.workspaceId === "string" ? msg.workspaceId : "";
|
|
32797
|
+
const refreshToken = typeof msg.refreshToken === "string" ? msg.refreshToken : void 0;
|
|
32798
|
+
const result = { workspaceId, token: msg.token, refreshToken };
|
|
32799
|
+
session.resolveAuth(result);
|
|
32800
|
+
onAuth(result);
|
|
32801
|
+
cleanupPendingAuthSession(session);
|
|
32802
|
+
};
|
|
32803
|
+
}
|
|
32804
|
+
|
|
32805
|
+
// src/auth/pending/pending-auth-on-open.ts
|
|
32806
|
+
function createPendingAuthOnOpen(params) {
|
|
32807
|
+
const { session, apiUrl, initialWorkspaceId, preferredBridgeName, log: log2 } = params;
|
|
32808
|
+
let pendingHbSeq = -1;
|
|
32809
|
+
return () => {
|
|
32810
|
+
clearReconnectQuietOnSuccessfulConnection(
|
|
32811
|
+
session.signInQuiet,
|
|
32812
|
+
log2,
|
|
32813
|
+
"[Bridge service] Sign-in connection restored."
|
|
32814
|
+
);
|
|
32815
|
+
session.reconnectAttempt = 0;
|
|
32816
|
+
pendingHbSeq = -1;
|
|
32817
|
+
sendWsMessage(session.ws, { type: "identify", role: "cli", cliVersion: CLI_VERSION });
|
|
32818
|
+
session.keepaliveInterval = setInterval(() => {
|
|
32819
|
+
if (session.resolved || !session.ws || session.ws.readyState !== 1) return;
|
|
32820
|
+
pendingHbSeq = pendingHbSeq >= BRIDGE_HEARTBEAT_SEQ_MAX ? 0 : pendingHbSeq + 1;
|
|
32821
|
+
const hb = { t: "h", s: pendingHbSeq };
|
|
32822
|
+
sendWsMessage(session.ws, hb);
|
|
32823
|
+
}, PENDING_KEEPALIVE_MS);
|
|
32824
|
+
if (session.browserFallback) {
|
|
32825
|
+
clearTimeout(session.browserFallback);
|
|
32826
|
+
session.browserFallback = null;
|
|
32827
|
+
}
|
|
32828
|
+
if (!session.hasOpenedBrowser) {
|
|
32829
|
+
session.hasOpenedBrowser = true;
|
|
32830
|
+
void openBrowser(session.connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, log2);
|
|
32831
|
+
}
|
|
32832
|
+
};
|
|
32833
|
+
}
|
|
32834
|
+
|
|
32835
|
+
// src/auth/pending/connect-pending-auth.ts
|
|
32836
|
+
function connectPendingAuth(params) {
|
|
32837
|
+
const { session, apiUrl, initialWorkspaceId, preferredBridgeName, onAuth, log: log2 } = params;
|
|
32838
|
+
const connect = () => {
|
|
32839
|
+
session.ws = createWsBridge({
|
|
32840
|
+
url: buildPendingBridgeUrl(apiUrl, session.connectionId),
|
|
32841
|
+
deferInboundMessages: false,
|
|
32842
|
+
onOpen: createPendingAuthOnOpen({
|
|
32843
|
+
session,
|
|
32844
|
+
apiUrl,
|
|
32845
|
+
initialWorkspaceId,
|
|
32846
|
+
preferredBridgeName,
|
|
32847
|
+
log: log2
|
|
32848
|
+
}),
|
|
32849
|
+
onClose: createPendingAuthOnClose({ session, log: log2, connect }),
|
|
32850
|
+
onError: (err) => logCliWebSocketError(log2, "[Bridge service]", err, "while waiting for sign-in"),
|
|
32851
|
+
onMessage: createPendingAuthOnMessage({ session, onAuth })
|
|
32852
|
+
});
|
|
32853
|
+
};
|
|
32854
|
+
connect();
|
|
32855
|
+
}
|
|
32856
|
+
|
|
32857
|
+
// src/auth/pending/run-pending-auth.ts
|
|
32858
|
+
function runPendingAuth(options) {
|
|
32859
|
+
const { apiUrl, initialWorkspaceId, preferredBridgeName, onAuth } = options;
|
|
32860
|
+
const logFn = options.log ?? log;
|
|
32861
|
+
const session = createPendingAuthSession();
|
|
32862
|
+
session.browserFallback = setTimeout(() => {
|
|
32863
|
+
session.browserFallback = null;
|
|
32864
|
+
if (!session.hasOpenedBrowser) {
|
|
32865
|
+
session.hasOpenedBrowser = true;
|
|
32866
|
+
void openBrowser(session.connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
32811
32867
|
}
|
|
32812
32868
|
}, BROWSER_OPEN_FALLBACK_MS);
|
|
32813
|
-
|
|
32869
|
+
connectPendingAuth({
|
|
32870
|
+
session,
|
|
32871
|
+
apiUrl,
|
|
32872
|
+
initialWorkspaceId,
|
|
32873
|
+
preferredBridgeName,
|
|
32874
|
+
onAuth,
|
|
32875
|
+
log: logFn
|
|
32876
|
+
});
|
|
32814
32877
|
return {
|
|
32815
32878
|
close: () => {
|
|
32816
|
-
if (!resolved) resolveAuth(null);
|
|
32817
|
-
|
|
32879
|
+
if (!session.resolved) session.resolveAuth(null);
|
|
32880
|
+
cleanupPendingAuthSession(session);
|
|
32818
32881
|
},
|
|
32819
|
-
authPromise
|
|
32882
|
+
authPromise: session.authPromise
|
|
32820
32883
|
};
|
|
32821
32884
|
}
|
|
32822
32885
|
|
|
@@ -34953,6 +35016,31 @@ function getAgentModelFromAgentConfig(config2) {
|
|
|
34953
35016
|
var HOUR_MS = 36e5;
|
|
34954
35017
|
var DAY_MS = 24 * HOUR_MS;
|
|
34955
35018
|
|
|
35019
|
+
// ../types/src/hosts/skus.ts
|
|
35020
|
+
function defineHostSku(params) {
|
|
35021
|
+
return structuredClone(params);
|
|
35022
|
+
}
|
|
35023
|
+
var FLY_LEGACY_HOST_SKU = defineHostSku({
|
|
35024
|
+
id: "fly-shared-1x512-1gb",
|
|
35025
|
+
provider: "fly",
|
|
35026
|
+
compute: { cpus: 1, cpuKind: "shared" },
|
|
35027
|
+
memory: { memoryMb: 512 },
|
|
35028
|
+
storage: { storageGb: 1 },
|
|
35029
|
+
monthlyPriceCents: 750
|
|
35030
|
+
});
|
|
35031
|
+
var FLY_DEFAULT_HOST_SKU = defineHostSku({
|
|
35032
|
+
id: "fly-shared-1x1024-1gb",
|
|
35033
|
+
provider: "fly",
|
|
35034
|
+
compute: { cpus: 1, cpuKind: "shared" },
|
|
35035
|
+
memory: { memoryMb: 1024 },
|
|
35036
|
+
storage: { storageGb: 1 },
|
|
35037
|
+
monthlyPriceCents: 1e3
|
|
35038
|
+
});
|
|
35039
|
+
var HOST_SKUS_BY_ID = {
|
|
35040
|
+
[FLY_LEGACY_HOST_SKU.id]: FLY_LEGACY_HOST_SKU,
|
|
35041
|
+
[FLY_DEFAULT_HOST_SKU.id]: FLY_DEFAULT_HOST_SKU
|
|
35042
|
+
};
|
|
35043
|
+
|
|
34956
35044
|
// ../types/src/bridges/agents/types.ts
|
|
34957
35045
|
var INSTALLABLE_BRIDGE_AGENTS = [
|
|
34958
35046
|
{ value: "claude-code", label: "Anthropic Claude Code", tokenLabel: "Anthropic API key", tokenEnvVar: "ANTHROPIC_API_KEY" },
|
|
@@ -35453,11 +35541,11 @@ function createSdkStdioExtNotificationHandler(options) {
|
|
|
35453
35541
|
|
|
35454
35542
|
// src/agents/acp/clients/sdk/sdk-stdio-permission-request-handshake.ts
|
|
35455
35543
|
function awaitSdkStdioPermissionRequestHandshake(params) {
|
|
35456
|
-
const { requestId, paramsRecord, pending, onRequest } = params;
|
|
35544
|
+
const { requestId, paramsRecord, pending: pending2, onRequest } = params;
|
|
35457
35545
|
return new Promise((resolve37) => {
|
|
35458
|
-
|
|
35546
|
+
pending2.set(requestId, { resolve: resolve37, params: paramsRecord });
|
|
35459
35547
|
if (onRequest == null) {
|
|
35460
|
-
|
|
35548
|
+
pending2.delete(requestId);
|
|
35461
35549
|
resolve37({ outcome: { outcome: "denied" } });
|
|
35462
35550
|
return;
|
|
35463
35551
|
}
|
|
@@ -35473,9 +35561,9 @@ function awaitSdkStdioPermissionRequestHandshake(params) {
|
|
|
35473
35561
|
}
|
|
35474
35562
|
|
|
35475
35563
|
// src/agents/acp/clients/sdk/sdk-stdio-permission-pending.ts
|
|
35476
|
-
function resolvePendingSdkStdioPermissionCancellations(
|
|
35477
|
-
for (const [id, entry] of [...
|
|
35478
|
-
|
|
35564
|
+
function resolvePendingSdkStdioPermissionCancellations(pending2) {
|
|
35565
|
+
for (const [id, entry] of [...pending2.entries()]) {
|
|
35566
|
+
pending2.delete(id);
|
|
35479
35567
|
entry.resolve({ outcome: { outcome: "cancelled" } });
|
|
35480
35568
|
}
|
|
35481
35569
|
}
|
|
@@ -36201,8 +36289,8 @@ function createCursorAcpSessionContext(options) {
|
|
|
36201
36289
|
|
|
36202
36290
|
// src/agents/acp/clients/cursor/cancel-pending-cursor-permission-requests.ts
|
|
36203
36291
|
function cancelPendingCursorPermissionRequests(pendingRequests2, respond) {
|
|
36204
|
-
for (const [reqId,
|
|
36205
|
-
if (
|
|
36292
|
+
for (const [reqId, pending2] of [...pendingRequests2.entries()]) {
|
|
36293
|
+
if (pending2.method === "session/request_permission") {
|
|
36206
36294
|
respond(reqId, { outcome: { outcome: "cancelled" } });
|
|
36207
36295
|
pendingRequests2.delete(reqId);
|
|
36208
36296
|
}
|
|
@@ -36394,8 +36482,8 @@ function handleCursorIncomingPermissionRequest(id, method, msg, deps) {
|
|
|
36394
36482
|
|
|
36395
36483
|
// src/agents/acp/clients/cursor/cursor-incoming-resolve-request.ts
|
|
36396
36484
|
function resolveCursorIncomingRequest(pendingRequests2, respond, requestId, result) {
|
|
36397
|
-
const
|
|
36398
|
-
const payload =
|
|
36485
|
+
const pending2 = pendingRequests2.get(requestId);
|
|
36486
|
+
const payload = pending2?.method === "session/request_permission" ? enrichAcpPermissionRpcResultFromRequestParams(result, pending2.params) : result;
|
|
36399
36487
|
respond(requestId, payload);
|
|
36400
36488
|
pendingRequests2.delete(requestId);
|
|
36401
36489
|
}
|
|
@@ -36533,25 +36621,25 @@ function createCursorJsonRpcInboundRespond(stdin) {
|
|
|
36533
36621
|
|
|
36534
36622
|
// src/agents/acp/clients/cursor/cursor-json-rpc-outbound.ts
|
|
36535
36623
|
function createCursorJsonRpcOutboundPending() {
|
|
36536
|
-
const
|
|
36624
|
+
const pending2 = /* @__PURE__ */ new Map();
|
|
36537
36625
|
let nextId = 1;
|
|
36538
36626
|
function allocateId() {
|
|
36539
36627
|
return nextId++;
|
|
36540
36628
|
}
|
|
36541
36629
|
function register(id, waiter) {
|
|
36542
|
-
|
|
36630
|
+
pending2.set(id, waiter);
|
|
36543
36631
|
}
|
|
36544
36632
|
function settleResponse(id, msg) {
|
|
36545
|
-
const waiter =
|
|
36633
|
+
const waiter = pending2.get(id);
|
|
36546
36634
|
if (!waiter) return false;
|
|
36547
|
-
|
|
36635
|
+
pending2.delete(id);
|
|
36548
36636
|
if (msg.error) waiter.reject(msg.error);
|
|
36549
36637
|
else waiter.resolve(msg.result);
|
|
36550
36638
|
return true;
|
|
36551
36639
|
}
|
|
36552
36640
|
function rejectOnWriteError(id, err) {
|
|
36553
|
-
const waiter =
|
|
36554
|
-
|
|
36641
|
+
const waiter = pending2.get(id);
|
|
36642
|
+
pending2.delete(id);
|
|
36555
36643
|
waiter?.reject(err);
|
|
36556
36644
|
}
|
|
36557
36645
|
return { allocateId, register, settleResponse, rejectOnWriteError };
|
|
@@ -41504,11 +41592,11 @@ function tryConsumeBinaryProxyBody(raw, deps) {
|
|
|
41504
41592
|
if (!PROXY_ID_RE.test(id)) return false;
|
|
41505
41593
|
const body = raw.slice(PROXY_ID_BYTES);
|
|
41506
41594
|
const bodyBytes = body.length > 0 ? new Uint8Array(body) : new Uint8Array(0);
|
|
41507
|
-
const
|
|
41508
|
-
if (
|
|
41595
|
+
const pending2 = deps.pendingProxyBody.get(id);
|
|
41596
|
+
if (pending2) {
|
|
41509
41597
|
deps.pendingProxyBody.delete(id);
|
|
41510
41598
|
deps.startStreamingProxy({
|
|
41511
|
-
...
|
|
41599
|
+
...pending2.pr,
|
|
41512
41600
|
body: bodyBytes.length > 0 ? bodyBytes : void 0
|
|
41513
41601
|
});
|
|
41514
41602
|
return true;
|
|
@@ -41901,9 +41989,9 @@ function processHeartbeatAck(params) {
|
|
|
41901
41989
|
if (awaitingSeq === null) return { awaitingSeq, missed: 0 };
|
|
41902
41990
|
if (!Number.isFinite(seq)) return { awaitingSeq, missed: 0 };
|
|
41903
41991
|
const ack = Math.trunc(seq);
|
|
41904
|
-
const
|
|
41905
|
-
if (ack <
|
|
41906
|
-
if (ack ===
|
|
41992
|
+
const pending2 = awaitingSeq;
|
|
41993
|
+
if (ack < pending2) return { awaitingSeq, missed: 0 };
|
|
41994
|
+
if (ack === pending2) {
|
|
41907
41995
|
recordRtt(Date.now() - sentAtMs);
|
|
41908
41996
|
}
|
|
41909
41997
|
return { awaitingSeq: null, missed: 0 };
|
|
@@ -52272,18 +52360,62 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
52272
52360
|
}
|
|
52273
52361
|
}
|
|
52274
52362
|
|
|
52363
|
+
// src/agents/acp/from-bridge/pending-prompt-results.ts
|
|
52364
|
+
var pending = [];
|
|
52365
|
+
function enqueuePendingPromptResult(message) {
|
|
52366
|
+
const runId = typeof message.runId === "string" ? message.runId : "";
|
|
52367
|
+
if (runId) {
|
|
52368
|
+
const idx = pending.findIndex((m) => m.runId === runId);
|
|
52369
|
+
if (idx >= 0) pending.splice(idx, 1);
|
|
52370
|
+
}
|
|
52371
|
+
pending.push(message);
|
|
52372
|
+
}
|
|
52373
|
+
function flushPendingPromptResults(getWs, encrypt) {
|
|
52374
|
+
if (pending.length === 0) return;
|
|
52375
|
+
const ws = getWs();
|
|
52376
|
+
if (!ws || ws.readyState !== wrapper_default.OPEN) return;
|
|
52377
|
+
const still = [];
|
|
52378
|
+
for (const message of pending) {
|
|
52379
|
+
const wire = encrypt ? encrypt(message) : message;
|
|
52380
|
+
if (!sendWsMessage(ws, wire)) still.push(message);
|
|
52381
|
+
}
|
|
52382
|
+
pending.length = 0;
|
|
52383
|
+
pending.push(...still);
|
|
52384
|
+
}
|
|
52385
|
+
|
|
52386
|
+
// src/agents/acp/from-bridge/send-session-update-wire.ts
|
|
52387
|
+
function sendSessionUpdateWire(getWs, payload, opts) {
|
|
52388
|
+
const s = getWs();
|
|
52389
|
+
if (!s || s.readyState !== wrapper_default.OPEN) {
|
|
52390
|
+
opts.log("[Bridge service] Session update not sent: not connected to the bridge.");
|
|
52391
|
+
return;
|
|
52392
|
+
}
|
|
52393
|
+
const p = payload;
|
|
52394
|
+
const wire = p.type === "session_update" && opts.e2ee ? opts.e2ee.encryptFields(payload, ["payload"]) : p.type === "session_file_change" && opts.e2ee ? opts.e2ee.encryptFields(payload, [
|
|
52395
|
+
"path",
|
|
52396
|
+
"oldText",
|
|
52397
|
+
"newText",
|
|
52398
|
+
"patchContent",
|
|
52399
|
+
"isDirectory",
|
|
52400
|
+
"directoryRemoved"
|
|
52401
|
+
]) : payload;
|
|
52402
|
+
sendWsMessage(s, wire);
|
|
52403
|
+
}
|
|
52404
|
+
|
|
52275
52405
|
// src/agents/acp/from-bridge/bridge-prompt-wiring.ts
|
|
52276
52406
|
function createBridgePromptSenders(deps, getWs) {
|
|
52277
52407
|
const sendBridgeMessage = (message, encryptedFields = []) => {
|
|
52278
52408
|
const s = getWs();
|
|
52279
|
-
if (!s) return false;
|
|
52409
|
+
if (!s || s.readyState !== wrapper_default.OPEN) return false;
|
|
52280
52410
|
const wire = deps.e2ee && encryptedFields.length > 0 ? deps.e2ee.encryptFields(message, encryptedFields) : message;
|
|
52281
|
-
sendWsMessage(s, wire);
|
|
52282
|
-
return true;
|
|
52411
|
+
return sendWsMessage(s, wire);
|
|
52283
52412
|
};
|
|
52284
52413
|
const sendResult = (result) => {
|
|
52285
|
-
const
|
|
52286
|
-
|
|
52414
|
+
const sent = sendBridgeMessage(result, result.type === "prompt_result" ? ["output", "error"] : []);
|
|
52415
|
+
if (!sent && result.type === "prompt_result") {
|
|
52416
|
+
enqueuePendingPromptResult(result);
|
|
52417
|
+
deps.log("[Bridge service] prompt_result deferred until bridge reconnect.");
|
|
52418
|
+
}
|
|
52287
52419
|
if (result.type === "prompt_result") {
|
|
52288
52420
|
const pr = result;
|
|
52289
52421
|
const cancelled = pr.stopReason === "cancelled";
|
|
@@ -52296,24 +52428,11 @@ function createBridgePromptSenders(deps, getWs) {
|
|
|
52296
52428
|
});
|
|
52297
52429
|
}
|
|
52298
52430
|
};
|
|
52299
|
-
|
|
52300
|
-
|
|
52301
|
-
|
|
52302
|
-
|
|
52303
|
-
return;
|
|
52304
|
-
}
|
|
52305
|
-
const p = payload;
|
|
52306
|
-
const wire = p.type === "session_update" && deps.e2ee ? deps.e2ee.encryptFields(payload, ["payload"]) : p.type === "session_file_change" && deps.e2ee ? deps.e2ee.encryptFields(payload, [
|
|
52307
|
-
"path",
|
|
52308
|
-
"oldText",
|
|
52309
|
-
"newText",
|
|
52310
|
-
"patchContent",
|
|
52311
|
-
"isDirectory",
|
|
52312
|
-
"directoryRemoved"
|
|
52313
|
-
]) : payload;
|
|
52314
|
-
sendWsMessage(s, wire);
|
|
52431
|
+
return {
|
|
52432
|
+
sendBridgeMessage,
|
|
52433
|
+
sendResult,
|
|
52434
|
+
sendSessionUpdate: (payload) => sendSessionUpdateWire(getWs, payload, { e2ee: deps.e2ee, log: deps.log })
|
|
52315
52435
|
};
|
|
52316
|
-
return { sendBridgeMessage, sendResult, sendSessionUpdate };
|
|
52317
52436
|
}
|
|
52318
52437
|
|
|
52319
52438
|
// src/agents/acp/from-bridge/handle-bridge-prompt/parse-bridge-attachments.ts
|
|
@@ -53197,25 +53316,59 @@ var handleInstallSkillsMessage = (msg, deps) => {
|
|
|
53197
53316
|
})();
|
|
53198
53317
|
};
|
|
53199
53318
|
|
|
53200
|
-
// src/agents/install/
|
|
53201
|
-
import {
|
|
53202
|
-
import
|
|
53203
|
-
|
|
53204
|
-
|
|
53205
|
-
|
|
53206
|
-
|
|
53207
|
-
|
|
53319
|
+
// src/agents/install/run-streaming-command.ts
|
|
53320
|
+
import { spawn as spawn11 } from "node:child_process";
|
|
53321
|
+
import * as readline3 from "node:readline";
|
|
53322
|
+
function runStreamingCommand(command, args, options) {
|
|
53323
|
+
return new Promise((resolve37, reject) => {
|
|
53324
|
+
const child = spawn11(command, args, {
|
|
53325
|
+
env: options.env,
|
|
53326
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
53327
|
+
});
|
|
53328
|
+
let settled = false;
|
|
53329
|
+
const timer = options.timeoutMs != null ? setTimeout(() => {
|
|
53330
|
+
child.kill("SIGKILL");
|
|
53331
|
+
if (!settled) {
|
|
53332
|
+
settled = true;
|
|
53333
|
+
reject(new Error(`Command timed out after ${options.timeoutMs}ms`));
|
|
53334
|
+
}
|
|
53335
|
+
}, options.timeoutMs) : null;
|
|
53336
|
+
const onLine = (line) => {
|
|
53337
|
+
if (line.length > 0) options.onLine?.(line);
|
|
53338
|
+
};
|
|
53339
|
+
if (child.stdout) {
|
|
53340
|
+
readline3.createInterface({ input: child.stdout, crlfDelay: Infinity }).on("line", onLine);
|
|
53341
|
+
}
|
|
53342
|
+
if (child.stderr) {
|
|
53343
|
+
readline3.createInterface({ input: child.stderr, crlfDelay: Infinity }).on("line", onLine);
|
|
53344
|
+
}
|
|
53345
|
+
child.on("error", (err) => {
|
|
53346
|
+
if (timer) clearTimeout(timer);
|
|
53347
|
+
if (!settled) {
|
|
53348
|
+
settled = true;
|
|
53349
|
+
reject(err);
|
|
53350
|
+
}
|
|
53351
|
+
});
|
|
53352
|
+
child.on("close", (code, signal) => {
|
|
53353
|
+
if (timer) clearTimeout(timer);
|
|
53354
|
+
if (!settled) {
|
|
53355
|
+
settled = true;
|
|
53356
|
+
resolve37({ code, signal });
|
|
53357
|
+
}
|
|
53358
|
+
});
|
|
53359
|
+
});
|
|
53208
53360
|
}
|
|
53209
53361
|
|
|
53210
53362
|
// src/agents/install/commands/run-npm-global-install.ts
|
|
53211
|
-
|
|
53212
|
-
|
|
53213
|
-
const { stdout, stderr } = await execFileAsync8("npm", ["install", "-g", packageName], {
|
|
53214
|
-
timeout: timeoutMs,
|
|
53363
|
+
async function runNpmGlobalInstall(packageName, env, options) {
|
|
53364
|
+
const result = await runStreamingCommand("npm", ["install", "-g", packageName], {
|
|
53215
53365
|
env: bridgeAgentPathEnv(env),
|
|
53216
|
-
|
|
53366
|
+
timeoutMs: options?.timeoutMs ?? 3e5,
|
|
53367
|
+
onLine: options?.onLine
|
|
53217
53368
|
});
|
|
53218
|
-
|
|
53369
|
+
if (result.code !== 0) {
|
|
53370
|
+
throw new Error(`npm install -g ${packageName} failed (exit ${result.code ?? "signal"})`);
|
|
53371
|
+
}
|
|
53219
53372
|
}
|
|
53220
53373
|
|
|
53221
53374
|
// src/agents/install/commands/claude-code.ts
|
|
@@ -53223,11 +53376,12 @@ var claudeCodeInstallCommand = {
|
|
|
53223
53376
|
agentType: "claude-code",
|
|
53224
53377
|
detectCommand: "claude",
|
|
53225
53378
|
async install(ctx) {
|
|
53226
|
-
|
|
53227
|
-
|
|
53228
|
-
|
|
53229
|
-
|
|
53230
|
-
|
|
53379
|
+
ctx.onProgress?.("Installing Anthropic Claude Code");
|
|
53380
|
+
await runNpmGlobalInstall(
|
|
53381
|
+
"@anthropic-ai/claude-code",
|
|
53382
|
+
{ ...ctx.env, ANTHROPIC_API_KEY: ctx.authToken },
|
|
53383
|
+
{ onLine: (line) => ctx.onProgress?.("Installing Anthropic Claude Code", line) }
|
|
53384
|
+
);
|
|
53231
53385
|
}
|
|
53232
53386
|
};
|
|
53233
53387
|
|
|
@@ -53236,34 +53390,34 @@ var codexAcpInstallCommand = {
|
|
|
53236
53390
|
agentType: "codex-acp",
|
|
53237
53391
|
detectCommand: "codex",
|
|
53238
53392
|
async install(ctx) {
|
|
53239
|
-
|
|
53240
|
-
|
|
53241
|
-
|
|
53242
|
-
|
|
53243
|
-
|
|
53393
|
+
ctx.onProgress?.("Installing Codex");
|
|
53394
|
+
await runNpmGlobalInstall(
|
|
53395
|
+
"@openai/codex",
|
|
53396
|
+
{ ...ctx.env, OPENAI_API_KEY: ctx.authToken },
|
|
53397
|
+
{ onLine: (line) => ctx.onProgress?.("Installing Codex", line) }
|
|
53398
|
+
);
|
|
53244
53399
|
}
|
|
53245
53400
|
};
|
|
53246
53401
|
|
|
53247
53402
|
// src/agents/install/commands/cursor-cli.ts
|
|
53248
|
-
import { execFile as execFile10 } from "node:child_process";
|
|
53249
|
-
import { promisify as promisify11 } from "node:util";
|
|
53250
|
-
var execFileAsync9 = promisify11(execFile10);
|
|
53251
53403
|
var cursorCliInstallCommand = {
|
|
53252
53404
|
agentType: "cursor-cli",
|
|
53253
53405
|
detectCommand: "agent",
|
|
53254
53406
|
alternateDetectCommands: ["cursor-agent"],
|
|
53255
53407
|
async install(ctx) {
|
|
53256
|
-
|
|
53408
|
+
ctx.onProgress?.("Installing Cursor CLI");
|
|
53409
|
+
const result = await runStreamingCommand(
|
|
53257
53410
|
"bash",
|
|
53258
53411
|
["-lc", "curl -fsSL https://cursor.com/install | bash"],
|
|
53259
53412
|
{
|
|
53260
|
-
|
|
53413
|
+
timeoutMs: 3e5,
|
|
53261
53414
|
env: { ...bridgeAgentPathEnv(ctx.env), CURSOR_API_KEY: ctx.authToken },
|
|
53262
|
-
|
|
53415
|
+
onLine: (line) => ctx.onProgress?.("Installing Cursor CLI", line)
|
|
53263
53416
|
}
|
|
53264
53417
|
);
|
|
53265
|
-
|
|
53266
|
-
|
|
53418
|
+
if (result.code !== 0) {
|
|
53419
|
+
throw new Error(`Cursor CLI install failed (exit ${result.code ?? "signal"})`);
|
|
53420
|
+
}
|
|
53267
53421
|
}
|
|
53268
53422
|
};
|
|
53269
53423
|
|
|
@@ -53272,11 +53426,12 @@ var opencodeInstallCommand = {
|
|
|
53272
53426
|
agentType: "opencode",
|
|
53273
53427
|
detectCommand: "opencode",
|
|
53274
53428
|
async install(ctx) {
|
|
53275
|
-
|
|
53276
|
-
|
|
53277
|
-
|
|
53278
|
-
|
|
53279
|
-
|
|
53429
|
+
ctx.onProgress?.("Installing OpenCode");
|
|
53430
|
+
await runNpmGlobalInstall(
|
|
53431
|
+
"opencode-ai",
|
|
53432
|
+
{ ...ctx.env, OPENCODE_API_KEY: ctx.authToken },
|
|
53433
|
+
{ onLine: (line) => ctx.onProgress?.("Installing OpenCode", line) }
|
|
53434
|
+
);
|
|
53280
53435
|
}
|
|
53281
53436
|
};
|
|
53282
53437
|
|
|
@@ -53337,25 +53492,47 @@ var handleInstallAgentMessage = (msg, deps) => {
|
|
|
53337
53492
|
if (!processId || !agentId || !tokenId || !agentType || !authToken) return;
|
|
53338
53493
|
void (async () => {
|
|
53339
53494
|
const socket = deps.getWs();
|
|
53340
|
-
|
|
53341
|
-
|
|
53342
|
-
|
|
53343
|
-
|
|
53344
|
-
|
|
53345
|
-
|
|
53346
|
-
|
|
53347
|
-
|
|
53348
|
-
|
|
53349
|
-
|
|
53350
|
-
|
|
53351
|
-
|
|
53495
|
+
let pendingLines = [];
|
|
53496
|
+
let flushTimer = null;
|
|
53497
|
+
const sendProgress = (message, logOutput) => {
|
|
53498
|
+
if (!socket) return;
|
|
53499
|
+
sendWsMessage(socket, {
|
|
53500
|
+
type: "install_agent_progress",
|
|
53501
|
+
processId,
|
|
53502
|
+
agentId,
|
|
53503
|
+
tokenId,
|
|
53504
|
+
agentType,
|
|
53505
|
+
step: "agent_install_package",
|
|
53506
|
+
message,
|
|
53507
|
+
...logOutput ? { logOutput } : {}
|
|
53508
|
+
});
|
|
53509
|
+
};
|
|
53510
|
+
const flushLines = (message) => {
|
|
53511
|
+
if (flushTimer) {
|
|
53512
|
+
clearTimeout(flushTimer);
|
|
53513
|
+
flushTimer = null;
|
|
53352
53514
|
}
|
|
53515
|
+
if (pendingLines.length === 0) return;
|
|
53516
|
+
const logOutput = pendingLines.join("\n");
|
|
53517
|
+
pendingLines = [];
|
|
53518
|
+
sendProgress(message, logOutput);
|
|
53353
53519
|
};
|
|
53354
53520
|
const result = await installLocalAgentOnBridge({
|
|
53355
53521
|
agentType,
|
|
53356
53522
|
authToken,
|
|
53357
|
-
onProgress: (message, logOutput) =>
|
|
53523
|
+
onProgress: (message, logOutput) => {
|
|
53524
|
+
if (logOutput == null) {
|
|
53525
|
+
flushLines(message);
|
|
53526
|
+
sendProgress(message);
|
|
53527
|
+
return;
|
|
53528
|
+
}
|
|
53529
|
+
pendingLines.push(logOutput);
|
|
53530
|
+
if (!flushTimer) {
|
|
53531
|
+
flushTimer = setTimeout(() => flushLines(message), 100);
|
|
53532
|
+
}
|
|
53533
|
+
}
|
|
53358
53534
|
});
|
|
53535
|
+
flushLines("Installing agent packages on the bridge machine.");
|
|
53359
53536
|
if (socket) {
|
|
53360
53537
|
sendWsMessage(socket, {
|
|
53361
53538
|
type: "install_agent_result",
|
|
@@ -53367,9 +53544,7 @@ var handleInstallAgentMessage = (msg, deps) => {
|
|
|
53367
53544
|
error: result.error
|
|
53368
53545
|
});
|
|
53369
53546
|
}
|
|
53370
|
-
if (result.success)
|
|
53371
|
-
await deps.reportAutoDetectedAgents?.();
|
|
53372
|
-
}
|
|
53547
|
+
if (result.success) await deps.reportAutoDetectedAgents?.();
|
|
53373
53548
|
if (!result.success) {
|
|
53374
53549
|
deps.log(`[Bridge service] Install agent failed: ${result.error ?? "unknown"}`);
|
|
53375
53550
|
}
|
|
@@ -53954,6 +54129,10 @@ function createMainBridgeOpenHandler(params) {
|
|
|
53954
54129
|
if (socket) {
|
|
53955
54130
|
sendBridgeIdentify(socket, { identifyReportedPaths, e2ee });
|
|
53956
54131
|
reportGitRepos(getWs, logFn);
|
|
54132
|
+
flushPendingPromptResults(
|
|
54133
|
+
getWs,
|
|
54134
|
+
(message) => e2ee ? e2ee.encryptFields(message, ["output", "error"]) : message
|
|
54135
|
+
);
|
|
53957
54136
|
try {
|
|
53958
54137
|
onBridgeSocketOpen?.();
|
|
53959
54138
|
} catch {
|
|
@@ -54098,7 +54277,7 @@ async function createBridgeConnection(options) {
|
|
|
54098
54277
|
}
|
|
54099
54278
|
|
|
54100
54279
|
// src/e2e-certificates/key-command.ts
|
|
54101
|
-
import * as
|
|
54280
|
+
import * as readline4 from "node:readline";
|
|
54102
54281
|
function installE2eCertificateKeyCommand({
|
|
54103
54282
|
log: log2,
|
|
54104
54283
|
onOpenCertificate,
|
|
@@ -54109,7 +54288,7 @@ function installE2eCertificateKeyCommand({
|
|
|
54109
54288
|
return () => {
|
|
54110
54289
|
};
|
|
54111
54290
|
}
|
|
54112
|
-
|
|
54291
|
+
readline4.emitKeypressEvents(process.stdin);
|
|
54113
54292
|
process.stdin.setRawMode(true);
|
|
54114
54293
|
process.stdin.resume();
|
|
54115
54294
|
const onKeypress = (str, key) => {
|
|
@@ -54150,32 +54329,42 @@ async function openE2eCertificateImportUrl({
|
|
|
54150
54329
|
}
|
|
54151
54330
|
}
|
|
54152
54331
|
|
|
54153
|
-
// src/run-bridge-
|
|
54332
|
+
// src/run-bridge-e2ee-key-command.ts
|
|
54333
|
+
function installConnectedBridgeE2eeKeyCommand(params) {
|
|
54334
|
+
let openingCertificate = false;
|
|
54335
|
+
return installE2eCertificateKeyCommand({
|
|
54336
|
+
log: params.log,
|
|
54337
|
+
onInterrupt: params.onInterrupt,
|
|
54338
|
+
onOpenCertificate: () => {
|
|
54339
|
+
if (openingCertificate) return;
|
|
54340
|
+
openingCertificate = true;
|
|
54341
|
+
void openE2eCertificateImportUrl({
|
|
54342
|
+
apiUrl: params.apiUrl,
|
|
54343
|
+
workspaceId: params.workspaceId,
|
|
54344
|
+
certificate: params.e2eCertificate,
|
|
54345
|
+
log: params.log
|
|
54346
|
+
}).finally(() => {
|
|
54347
|
+
openingCertificate = false;
|
|
54348
|
+
});
|
|
54349
|
+
}
|
|
54350
|
+
});
|
|
54351
|
+
}
|
|
54352
|
+
|
|
54353
|
+
// src/run-bridge-connected-signals.ts
|
|
54354
|
+
init_log();
|
|
54154
54355
|
init_cli_process_interrupt();
|
|
54155
|
-
|
|
54156
|
-
async function runConnectedBridge(options, restartWithoutAuth) {
|
|
54157
|
-
const {
|
|
54158
|
-
apiUrl,
|
|
54159
|
-
workspaceId,
|
|
54160
|
-
authToken,
|
|
54161
|
-
refreshToken,
|
|
54162
|
-
justAuthenticated,
|
|
54163
|
-
worktreesRootPath,
|
|
54164
|
-
e2eCertificate
|
|
54165
|
-
} = options;
|
|
54166
|
-
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
54167
|
-
let cleanupKeyCommand;
|
|
54168
|
-
let bridgeClose = null;
|
|
54356
|
+
function installConnectedBridgeSignals(params) {
|
|
54169
54357
|
let shutdownStarted = false;
|
|
54170
54358
|
const onSignal = (kind) => {
|
|
54171
54359
|
requestCliImmediateShutdown();
|
|
54172
54360
|
abortActiveGitChildProcesses();
|
|
54173
|
-
cleanupKeyCommand
|
|
54361
|
+
params.cleanupKeyCommand();
|
|
54174
54362
|
if (shutdownStarted) return;
|
|
54175
54363
|
shutdownStarted = true;
|
|
54176
54364
|
logImmediate(
|
|
54177
54365
|
kind === "interrupt" ? "Keyboard interrupt (Ctrl+C) \u2014 stopping\u2026" : "Stop requested \u2014 shutting down\u2026"
|
|
54178
54366
|
);
|
|
54367
|
+
const bridgeClose = params.getBridgeClose();
|
|
54179
54368
|
if (bridgeClose) {
|
|
54180
54369
|
void bridgeClose().finally(() => process.exit(0));
|
|
54181
54370
|
return;
|
|
@@ -54186,9 +54375,56 @@ async function runConnectedBridge(options, restartWithoutAuth) {
|
|
|
54186
54375
|
const onSigTerm = () => onSignal("stop");
|
|
54187
54376
|
process.on("SIGINT", onSigInt);
|
|
54188
54377
|
process.on("SIGTERM", onSigTerm);
|
|
54189
|
-
|
|
54378
|
+
return {
|
|
54379
|
+
onSigInt,
|
|
54380
|
+
remove: () => {
|
|
54381
|
+
process.off("SIGINT", onSigInt);
|
|
54382
|
+
process.off("SIGTERM", onSigTerm);
|
|
54383
|
+
}
|
|
54384
|
+
};
|
|
54385
|
+
}
|
|
54386
|
+
|
|
54387
|
+
// src/run-bridge-on-auth-invalid.ts
|
|
54388
|
+
init_cli_process_interrupt();
|
|
54389
|
+
async function closeBridgeForReauth(params) {
|
|
54390
|
+
params.log("[Bridge service] Access token invalid or revoked; re-authenticating\u2026");
|
|
54391
|
+
clearConfigForApi(params.apiUrl);
|
|
54392
|
+
await params.close();
|
|
54393
|
+
params.removeSignalHandlers();
|
|
54394
|
+
await clearCliImmediateShutdown();
|
|
54395
|
+
params.endConnectedSession();
|
|
54396
|
+
}
|
|
54397
|
+
|
|
54398
|
+
// src/run-bridge-connected.ts
|
|
54399
|
+
init_cli_database();
|
|
54400
|
+
async function runConnectedBridge(options, restartWithoutAuth) {
|
|
54401
|
+
const {
|
|
54402
|
+
apiUrl,
|
|
54403
|
+
workspaceId,
|
|
54404
|
+
authToken,
|
|
54405
|
+
refreshToken,
|
|
54406
|
+
justAuthenticated,
|
|
54407
|
+
worktreesRootPath,
|
|
54408
|
+
e2eCertificate
|
|
54409
|
+
} = options;
|
|
54410
|
+
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
54411
|
+
let cleanupKeyCommand;
|
|
54412
|
+
let bridgeClose = null;
|
|
54413
|
+
let endConnectedSession;
|
|
54414
|
+
const sessionDone = new Promise((resolve37) => {
|
|
54415
|
+
endConnectedSession = resolve37;
|
|
54416
|
+
});
|
|
54417
|
+
let resolveHandleReady;
|
|
54418
|
+
const handleReady = new Promise((resolve37) => {
|
|
54419
|
+
resolveHandleReady = resolve37;
|
|
54420
|
+
});
|
|
54421
|
+
const handleRef = { current: null };
|
|
54422
|
+
const signals = installConnectedBridgeSignals({
|
|
54423
|
+
getBridgeClose: () => bridgeClose,
|
|
54424
|
+
cleanupKeyCommand: () => cleanupKeyCommand?.()
|
|
54425
|
+
});
|
|
54190
54426
|
try {
|
|
54191
|
-
handle = await createBridgeConnection({
|
|
54427
|
+
const handle = await createBridgeConnection({
|
|
54192
54428
|
apiUrl,
|
|
54193
54429
|
workspaceId,
|
|
54194
54430
|
authToken,
|
|
@@ -54207,41 +54443,40 @@ async function runConnectedBridge(options, restartWithoutAuth) {
|
|
|
54207
54443
|
},
|
|
54208
54444
|
onAuthInvalid: () => {
|
|
54209
54445
|
cleanupKeyCommand?.();
|
|
54210
|
-
|
|
54211
|
-
|
|
54212
|
-
|
|
54213
|
-
|
|
54214
|
-
|
|
54446
|
+
void (async () => {
|
|
54447
|
+
await handleReady;
|
|
54448
|
+
await closeBridgeForReauth({
|
|
54449
|
+
apiUrl,
|
|
54450
|
+
log,
|
|
54451
|
+
close: async () => {
|
|
54452
|
+
if (handleRef.current) await handleRef.current.close();
|
|
54453
|
+
},
|
|
54454
|
+
removeSignalHandlers: signals.remove,
|
|
54455
|
+
endConnectedSession
|
|
54456
|
+
});
|
|
54457
|
+
})();
|
|
54215
54458
|
}
|
|
54216
54459
|
});
|
|
54217
|
-
|
|
54218
|
-
|
|
54219
|
-
|
|
54220
|
-
|
|
54221
|
-
|
|
54460
|
+
handleRef.current = handle;
|
|
54461
|
+
bridgeClose = () => handle.close();
|
|
54462
|
+
if (e2eCertificate) {
|
|
54463
|
+
cleanupKeyCommand = installConnectedBridgeE2eeKeyCommand({
|
|
54464
|
+
apiUrl,
|
|
54465
|
+
workspaceId,
|
|
54466
|
+
e2eCertificate,
|
|
54467
|
+
log,
|
|
54468
|
+
onInterrupt: signals.onSigInt
|
|
54469
|
+
});
|
|
54222
54470
|
}
|
|
54471
|
+
} catch (e) {
|
|
54472
|
+
signals.remove();
|
|
54473
|
+
if (e instanceof CliSqliteInterrupted) process.exit(0);
|
|
54223
54474
|
throw e;
|
|
54475
|
+
} finally {
|
|
54476
|
+
resolveHandleReady();
|
|
54224
54477
|
}
|
|
54225
|
-
|
|
54226
|
-
|
|
54227
|
-
let openingCertificate = false;
|
|
54228
|
-
cleanupKeyCommand = installE2eCertificateKeyCommand({
|
|
54229
|
-
log,
|
|
54230
|
-
onInterrupt: onSigInt,
|
|
54231
|
-
onOpenCertificate: () => {
|
|
54232
|
-
if (openingCertificate) return;
|
|
54233
|
-
openingCertificate = true;
|
|
54234
|
-
void openE2eCertificateImportUrl({
|
|
54235
|
-
apiUrl,
|
|
54236
|
-
workspaceId,
|
|
54237
|
-
certificate: e2eCertificate,
|
|
54238
|
-
log
|
|
54239
|
-
}).finally(() => {
|
|
54240
|
-
openingCertificate = false;
|
|
54241
|
-
});
|
|
54242
|
-
}
|
|
54243
|
-
});
|
|
54244
|
-
}
|
|
54478
|
+
await sessionDone;
|
|
54479
|
+
await restartWithoutAuth({ apiUrl, firehoseServerUrl, worktreesRootPath, e2eCertificate });
|
|
54245
54480
|
}
|
|
54246
54481
|
|
|
54247
54482
|
// src/run-bridge.ts
|
|
@@ -54285,12 +54520,16 @@ async function runBridge(options) {
|
|
|
54285
54520
|
process.off("SIGINT", onSigInt);
|
|
54286
54521
|
process.off("SIGTERM", onSigTerm);
|
|
54287
54522
|
handle.close();
|
|
54288
|
-
if (!auth)
|
|
54523
|
+
if (!auth) {
|
|
54524
|
+
log("Sign-in ended before a token was received.");
|
|
54525
|
+
return;
|
|
54526
|
+
}
|
|
54289
54527
|
writeConfigForApi(apiUrl, {
|
|
54290
54528
|
workspaceId: auth.workspaceId,
|
|
54291
54529
|
token: auth.token,
|
|
54292
54530
|
refreshToken: auth.refreshToken
|
|
54293
54531
|
});
|
|
54532
|
+
log("Link established. Connecting with the new token\u2026");
|
|
54294
54533
|
await runBridge({
|
|
54295
54534
|
apiUrl,
|
|
54296
54535
|
workspaceId: auth.workspaceId,
|