@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/index.js
CHANGED
|
@@ -3691,7 +3691,7 @@ var require_tree_kill = __commonJS({
|
|
|
3691
3691
|
"../../node_modules/.pnpm/tree-kill@1.2.2/node_modules/tree-kill/index.js"(exports, module) {
|
|
3692
3692
|
"use strict";
|
|
3693
3693
|
var childProcess2 = __require("child_process");
|
|
3694
|
-
var
|
|
3694
|
+
var spawn12 = childProcess2.spawn;
|
|
3695
3695
|
var exec = childProcess2.exec;
|
|
3696
3696
|
module.exports = function(pid, signal, callback) {
|
|
3697
3697
|
if (typeof signal === "function" && callback === void 0) {
|
|
@@ -3716,7 +3716,7 @@ var require_tree_kill = __commonJS({
|
|
|
3716
3716
|
break;
|
|
3717
3717
|
case "darwin":
|
|
3718
3718
|
buildProcessTree(pid, tree, pidsToProcess, function(parentPid) {
|
|
3719
|
-
return
|
|
3719
|
+
return spawn12("pgrep", ["-P", parentPid]);
|
|
3720
3720
|
}, function() {
|
|
3721
3721
|
killAll(tree, signal, callback);
|
|
3722
3722
|
});
|
|
@@ -3728,7 +3728,7 @@ var require_tree_kill = __commonJS({
|
|
|
3728
3728
|
// break;
|
|
3729
3729
|
default:
|
|
3730
3730
|
buildProcessTree(pid, tree, pidsToProcess, function(parentPid) {
|
|
3731
|
-
return
|
|
3731
|
+
return spawn12("ps", ["-o", "pid", "--no-headers", "--ppid", parentPid]);
|
|
3732
3732
|
}, function() {
|
|
3733
3733
|
killAll(tree, signal, callback);
|
|
3734
3734
|
});
|
|
@@ -21909,31 +21909,31 @@ function handleWorkerOutMessage(message) {
|
|
|
21909
21909
|
return;
|
|
21910
21910
|
}
|
|
21911
21911
|
if (message.type === "error") {
|
|
21912
|
-
const
|
|
21912
|
+
const pending3 = message.requestId != null ? pendingRequests.get(message.requestId) : void 0;
|
|
21913
21913
|
maybeLogCodeNavCacheWorkerError(message.message);
|
|
21914
|
-
if (
|
|
21914
|
+
if (pending3 != null) {
|
|
21915
21915
|
pendingRequests.delete(message.requestId);
|
|
21916
21916
|
if (isCliImmediateShutdownRequested()) {
|
|
21917
|
-
|
|
21917
|
+
pending3.reject(new CliSqliteInterrupted());
|
|
21918
21918
|
} else {
|
|
21919
|
-
|
|
21919
|
+
pending3.reject(new Error(message.message));
|
|
21920
21920
|
}
|
|
21921
21921
|
}
|
|
21922
21922
|
return;
|
|
21923
21923
|
}
|
|
21924
21924
|
if (!("requestId" in message)) return;
|
|
21925
|
-
const
|
|
21926
|
-
if (
|
|
21925
|
+
const pending2 = pendingRequests.get(message.requestId);
|
|
21926
|
+
if (pending2 == null) return;
|
|
21927
21927
|
pendingRequests.delete(message.requestId);
|
|
21928
|
-
|
|
21928
|
+
pending2.resolve(message);
|
|
21929
21929
|
}
|
|
21930
21930
|
function resetWorkerReadyState() {
|
|
21931
21931
|
workerReady = false;
|
|
21932
21932
|
workerReadyWaiters = [];
|
|
21933
21933
|
}
|
|
21934
21934
|
function rejectAllPendingRequests(error40) {
|
|
21935
|
-
for (const [,
|
|
21936
|
-
|
|
21935
|
+
for (const [, pending2] of pendingRequests) {
|
|
21936
|
+
pending2.reject(error40);
|
|
21937
21937
|
}
|
|
21938
21938
|
pendingRequests.clear();
|
|
21939
21939
|
}
|
|
@@ -22966,14 +22966,14 @@ function legacyCliDiskMigrationIsPending() {
|
|
|
22966
22966
|
return false;
|
|
22967
22967
|
}
|
|
22968
22968
|
function importCliSqliteLegacyDiskData(db, log2) {
|
|
22969
|
-
const
|
|
22970
|
-
if (
|
|
22969
|
+
const pending2 = legacyCliDiskMigrationIsPending();
|
|
22970
|
+
if (pending2 && log2) {
|
|
22971
22971
|
log2("Migrating legacy on-disk CLI data to SQLite\u2026");
|
|
22972
22972
|
}
|
|
22973
22973
|
archiveLegacyFileIndexJsonFiles();
|
|
22974
22974
|
importLegacyAgentSessionsFromDisk(db);
|
|
22975
22975
|
importLegacyPromptQueuesFromDisk(db);
|
|
22976
|
-
if (
|
|
22976
|
+
if (pending2 && log2) {
|
|
22977
22977
|
log2("Legacy on-disk CLI data migration finished.");
|
|
22978
22978
|
}
|
|
22979
22979
|
}
|
|
@@ -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
|
-
|
|
28200
|
+
const disposeClientPing = () => {
|
|
28169
28201
|
clearClientPing?.();
|
|
28170
28202
|
clearClientPing = null;
|
|
28171
|
-
}
|
|
28172
|
-
ws.on("unexpected-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
|
-
|
|
28194
|
-
|
|
28195
|
-
|
|
28196
|
-
|
|
28197
|
-
|
|
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();
|
|
@@ -28219,9 +28239,9 @@ function createWsBridge(options) {
|
|
|
28219
28239
|
return ws;
|
|
28220
28240
|
}
|
|
28221
28241
|
function sendWsMessage(ws, payload) {
|
|
28222
|
-
if (ws.readyState
|
|
28223
|
-
|
|
28224
|
-
|
|
28242
|
+
if (ws.readyState !== wrapper_default.OPEN) return false;
|
|
28243
|
+
ws.send(JSON.stringify(payload));
|
|
28244
|
+
return true;
|
|
28225
28245
|
}
|
|
28226
28246
|
|
|
28227
28247
|
// src/files/cwd/index.ts
|
|
@@ -29352,6 +29372,31 @@ function getAgentModelFromAgentConfig(config2) {
|
|
|
29352
29372
|
var HOUR_MS = 36e5;
|
|
29353
29373
|
var DAY_MS = 24 * HOUR_MS;
|
|
29354
29374
|
|
|
29375
|
+
// ../types/src/hosts/skus.ts
|
|
29376
|
+
function defineHostSku(params) {
|
|
29377
|
+
return structuredClone(params);
|
|
29378
|
+
}
|
|
29379
|
+
var FLY_LEGACY_HOST_SKU = defineHostSku({
|
|
29380
|
+
id: "fly-shared-1x512-1gb",
|
|
29381
|
+
provider: "fly",
|
|
29382
|
+
compute: { cpus: 1, cpuKind: "shared" },
|
|
29383
|
+
memory: { memoryMb: 512 },
|
|
29384
|
+
storage: { storageGb: 1 },
|
|
29385
|
+
monthlyPriceCents: 750
|
|
29386
|
+
});
|
|
29387
|
+
var FLY_DEFAULT_HOST_SKU = defineHostSku({
|
|
29388
|
+
id: "fly-shared-1x1024-1gb",
|
|
29389
|
+
provider: "fly",
|
|
29390
|
+
compute: { cpus: 1, cpuKind: "shared" },
|
|
29391
|
+
memory: { memoryMb: 1024 },
|
|
29392
|
+
storage: { storageGb: 1 },
|
|
29393
|
+
monthlyPriceCents: 1e3
|
|
29394
|
+
});
|
|
29395
|
+
var HOST_SKUS_BY_ID = {
|
|
29396
|
+
[FLY_LEGACY_HOST_SKU.id]: FLY_LEGACY_HOST_SKU,
|
|
29397
|
+
[FLY_DEFAULT_HOST_SKU.id]: FLY_DEFAULT_HOST_SKU
|
|
29398
|
+
};
|
|
29399
|
+
|
|
29355
29400
|
// ../types/src/bridges/agents/types.ts
|
|
29356
29401
|
var INSTALLABLE_BRIDGE_AGENTS = [
|
|
29357
29402
|
{ value: "claude-code", label: "Anthropic Claude Code", tokenLabel: "Anthropic API key", tokenEnvVar: "ANTHROPIC_API_KEY" },
|
|
@@ -29465,11 +29510,11 @@ function createSdkStdioExtNotificationHandler(options) {
|
|
|
29465
29510
|
|
|
29466
29511
|
// src/agents/acp/clients/sdk/sdk-stdio-permission-request-handshake.ts
|
|
29467
29512
|
function awaitSdkStdioPermissionRequestHandshake(params) {
|
|
29468
|
-
const { requestId, paramsRecord, pending, onRequest } = params;
|
|
29513
|
+
const { requestId, paramsRecord, pending: pending2, onRequest } = params;
|
|
29469
29514
|
return new Promise((resolve35) => {
|
|
29470
|
-
|
|
29515
|
+
pending2.set(requestId, { resolve: resolve35, params: paramsRecord });
|
|
29471
29516
|
if (onRequest == null) {
|
|
29472
|
-
|
|
29517
|
+
pending2.delete(requestId);
|
|
29473
29518
|
resolve35({ outcome: { outcome: "denied" } });
|
|
29474
29519
|
return;
|
|
29475
29520
|
}
|
|
@@ -29485,9 +29530,9 @@ function awaitSdkStdioPermissionRequestHandshake(params) {
|
|
|
29485
29530
|
}
|
|
29486
29531
|
|
|
29487
29532
|
// src/agents/acp/clients/sdk/sdk-stdio-permission-pending.ts
|
|
29488
|
-
function resolvePendingSdkStdioPermissionCancellations(
|
|
29489
|
-
for (const [id, entry] of [...
|
|
29490
|
-
|
|
29533
|
+
function resolvePendingSdkStdioPermissionCancellations(pending2) {
|
|
29534
|
+
for (const [id, entry] of [...pending2.entries()]) {
|
|
29535
|
+
pending2.delete(id);
|
|
29491
29536
|
entry.resolve({ outcome: { outcome: "cancelled" } });
|
|
29492
29537
|
}
|
|
29493
29538
|
}
|
|
@@ -30612,14 +30657,8 @@ function installBridgeProcessResilience() {
|
|
|
30612
30657
|
});
|
|
30613
30658
|
}
|
|
30614
30659
|
|
|
30615
|
-
// src/
|
|
30616
|
-
|
|
30617
|
-
|
|
30618
|
-
// src/connection/heartbeat/constants.ts
|
|
30619
|
-
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
30620
|
-
var BRIDGE_HEARTBEAT_SEQ_MAX = 2147483646;
|
|
30621
|
-
var BRIDGE_HEARTBEAT_MISSED_ACKS_BEFORE_RECONNECT = 4;
|
|
30622
|
-
var BRIDGE_HEARTBEAT_RTT_SAMPLE_MAX = 5;
|
|
30660
|
+
// src/auth/pending/run-pending-auth.ts
|
|
30661
|
+
init_log();
|
|
30623
30662
|
|
|
30624
30663
|
// ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
|
|
30625
30664
|
import process7 from "node:process";
|
|
@@ -31174,8 +31213,16 @@ async function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName
|
|
|
31174
31213
|
}
|
|
31175
31214
|
}
|
|
31176
31215
|
|
|
31177
|
-
// src/auth/
|
|
31178
|
-
|
|
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
|
+
}
|
|
31179
31226
|
|
|
31180
31227
|
// src/connection/reconnect/constants.ts
|
|
31181
31228
|
var RECONNECT_QUIET_MS = 2e3;
|
|
@@ -31506,6 +31553,12 @@ function scheduleMainBridgeReconnect(state, connect, log2, closeMeta) {
|
|
|
31506
31553
|
});
|
|
31507
31554
|
}
|
|
31508
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
|
+
|
|
31509
31562
|
// src/connection/reconnect/duplicate-bridge-connection-detect.ts
|
|
31510
31563
|
var BRIDGE_SUPERSEDED_CLOSE_REASON_SNIPPET = "superseded";
|
|
31511
31564
|
var DUPLICATE_BRIDGE_SHORT_SESSION_MS = 25e3;
|
|
@@ -31590,145 +31643,180 @@ function clearFirehoseReconnectQuietOnOpen(ctx, log2) {
|
|
|
31590
31643
|
});
|
|
31591
31644
|
}
|
|
31592
31645
|
|
|
31593
|
-
// src/auth/
|
|
31594
|
-
|
|
31595
|
-
|
|
31596
|
-
|
|
31597
|
-
|
|
31598
|
-
|
|
31599
|
-
|
|
31600
|
-
}
|
|
31601
|
-
|
|
31602
|
-
const { apiUrl, initialWorkspaceId, preferredBridgeName, onAuth } = options;
|
|
31603
|
-
const logFn = options.log ?? log;
|
|
31604
|
-
let ws = null;
|
|
31605
|
-
let reconnectTimeout = null;
|
|
31606
|
-
let keepaliveInterval = null;
|
|
31607
|
-
let browserFallback = null;
|
|
31608
|
-
const connectionId = crypto.randomUUID();
|
|
31609
|
-
let hasOpenedBrowser = false;
|
|
31610
|
-
let resolved = false;
|
|
31611
|
-
let resolveAuth;
|
|
31612
|
-
const authPromise = new Promise((resolve35) => {
|
|
31613
|
-
resolveAuth = resolve35;
|
|
31614
|
-
});
|
|
31615
|
-
let reconnectAttempt = 0;
|
|
31616
|
-
const signInQuiet = createEmptyReconnectQuietSlot();
|
|
31617
|
-
function clearQuietOnOpen() {
|
|
31618
|
-
clearReconnectQuietOnSuccessfulConnection(
|
|
31619
|
-
signInQuiet,
|
|
31620
|
-
logFn,
|
|
31621
|
-
"[Bridge service] Sign-in connection restored."
|
|
31622
|
-
);
|
|
31623
|
-
reconnectAttempt = 0;
|
|
31624
|
-
}
|
|
31625
|
-
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;
|
|
31626
31655
|
beginDeferredDisconnectForReconnect({
|
|
31627
|
-
isClosedByUser: () => resolved,
|
|
31628
|
-
quiet: signInQuiet,
|
|
31656
|
+
isClosedByUser: () => session.resolved,
|
|
31657
|
+
quiet: session.signInQuiet,
|
|
31629
31658
|
code,
|
|
31630
31659
|
reason,
|
|
31631
31660
|
willReconnect: true,
|
|
31632
|
-
log:
|
|
31661
|
+
log: log2,
|
|
31633
31662
|
serviceLabel: "[Bridge service]",
|
|
31634
31663
|
shutdownDetail: "Not reconnecting (shutting down).",
|
|
31635
31664
|
reconnectingDetail: "Waiting for browser sign-in; reconnecting\u2026",
|
|
31636
|
-
shouldAbortQuietWindow: () => ws != null && ws.readyState === wrapper_default.OPEN
|
|
31665
|
+
shouldAbortQuietWindow: () => session.ws != null && session.ws.readyState === wrapper_default.OPEN
|
|
31637
31666
|
});
|
|
31638
|
-
|
|
31639
|
-
|
|
31640
|
-
|
|
31641
|
-
|
|
31642
|
-
|
|
31643
|
-
|
|
31644
|
-
|
|
31645
|
-
if (browserFallback) {
|
|
31646
|
-
clearTimeout(browserFallback);
|
|
31647
|
-
browserFallback = null;
|
|
31648
|
-
}
|
|
31649
|
-
if (keepaliveInterval) {
|
|
31650
|
-
clearInterval(keepaliveInterval);
|
|
31651
|
-
keepaliveInterval = null;
|
|
31652
|
-
}
|
|
31653
|
-
if (ws) {
|
|
31654
|
-
const w = ws;
|
|
31655
|
-
ws = null;
|
|
31656
|
-
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
|
+
);
|
|
31657
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;
|
|
31658
31707
|
}
|
|
31659
|
-
|
|
31660
|
-
|
|
31661
|
-
|
|
31662
|
-
|
|
31663
|
-
|
|
31664
|
-
|
|
31665
|
-
|
|
31666
|
-
|
|
31667
|
-
|
|
31668
|
-
|
|
31669
|
-
|
|
31670
|
-
|
|
31671
|
-
const hb = { t: "h", s: pendingHbSeq };
|
|
31672
|
-
sendWsMessage(ws, hb);
|
|
31673
|
-
}, PENDING_KEEPALIVE_MS);
|
|
31674
|
-
if (browserFallback) {
|
|
31675
|
-
clearTimeout(browserFallback);
|
|
31676
|
-
browserFallback = null;
|
|
31677
|
-
}
|
|
31678
|
-
if (!hasOpenedBrowser) {
|
|
31679
|
-
hasOpenedBrowser = true;
|
|
31680
|
-
void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
31681
|
-
}
|
|
31682
|
-
},
|
|
31683
|
-
onClose: (code, reason) => {
|
|
31684
|
-
if (keepaliveInterval) {
|
|
31685
|
-
clearInterval(keepaliveInterval);
|
|
31686
|
-
keepaliveInterval = null;
|
|
31687
|
-
}
|
|
31688
|
-
if (resolved) return;
|
|
31689
|
-
beginDeferredPendingCloseLog(code, reason);
|
|
31690
|
-
const delay4 = pendingAuthReconnectDelayMs(reconnectAttempt);
|
|
31691
|
-
reconnectAttempt += 1;
|
|
31692
|
-
if (signInQuiet.verboseLogs) {
|
|
31693
|
-
const delayLabel = formatReconnectDelayForLog(delay4);
|
|
31694
|
-
logFn(
|
|
31695
|
-
`[Bridge service] Next sign-in connection attempt in ${delayLabel} (attempt ${reconnectAttempt}).`
|
|
31696
|
-
);
|
|
31697
|
-
}
|
|
31698
|
-
reconnectTimeout = setTimeout(() => {
|
|
31699
|
-
reconnectTimeout = null;
|
|
31700
|
-
connect();
|
|
31701
|
-
}, delay4);
|
|
31702
|
-
},
|
|
31703
|
-
onError: (err) => logCliWebSocketError(logFn, "[Bridge service]", err, "while waiting for sign-in"),
|
|
31704
|
-
onMessage: (data) => {
|
|
31705
|
-
const msg = data;
|
|
31706
|
-
if (msg.type === "auth_token" && typeof msg.token === "string") {
|
|
31707
|
-
resolved = true;
|
|
31708
|
-
const workspaceId = typeof msg.workspaceId === "string" ? msg.workspaceId : "";
|
|
31709
|
-
cleanup();
|
|
31710
|
-
const refreshToken = typeof msg.refreshToken === "string" ? msg.refreshToken : void 0;
|
|
31711
|
-
const result = { workspaceId, token: msg.token, refreshToken };
|
|
31712
|
-
resolveAuth(result);
|
|
31713
|
-
onAuth(result);
|
|
31714
|
-
}
|
|
31715
|
-
}
|
|
31716
|
-
});
|
|
31708
|
+
if (session.browserFallback) {
|
|
31709
|
+
clearTimeout(session.browserFallback);
|
|
31710
|
+
session.browserFallback = null;
|
|
31711
|
+
}
|
|
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);
|
|
31717
31720
|
}
|
|
31718
|
-
|
|
31719
|
-
|
|
31720
|
-
|
|
31721
|
-
|
|
31722
|
-
|
|
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);
|
|
31723
31804
|
}
|
|
31724
31805
|
}, BROWSER_OPEN_FALLBACK_MS);
|
|
31725
|
-
|
|
31806
|
+
connectPendingAuth({
|
|
31807
|
+
session,
|
|
31808
|
+
apiUrl,
|
|
31809
|
+
initialWorkspaceId,
|
|
31810
|
+
preferredBridgeName,
|
|
31811
|
+
onAuth,
|
|
31812
|
+
log: logFn
|
|
31813
|
+
});
|
|
31726
31814
|
return {
|
|
31727
31815
|
close: () => {
|
|
31728
|
-
if (!resolved) resolveAuth(null);
|
|
31729
|
-
|
|
31816
|
+
if (!session.resolved) session.resolveAuth(null);
|
|
31817
|
+
cleanupPendingAuthSession(session);
|
|
31730
31818
|
},
|
|
31731
|
-
authPromise
|
|
31819
|
+
authPromise: session.authPromise
|
|
31732
31820
|
};
|
|
31733
31821
|
}
|
|
31734
31822
|
|
|
@@ -33220,8 +33308,8 @@ function createCursorAcpSessionContext(options) {
|
|
|
33220
33308
|
|
|
33221
33309
|
// src/agents/acp/clients/cursor/cancel-pending-cursor-permission-requests.ts
|
|
33222
33310
|
function cancelPendingCursorPermissionRequests(pendingRequests2, respond) {
|
|
33223
|
-
for (const [reqId,
|
|
33224
|
-
if (
|
|
33311
|
+
for (const [reqId, pending2] of [...pendingRequests2.entries()]) {
|
|
33312
|
+
if (pending2.method === "session/request_permission") {
|
|
33225
33313
|
respond(reqId, { outcome: { outcome: "cancelled" } });
|
|
33226
33314
|
pendingRequests2.delete(reqId);
|
|
33227
33315
|
}
|
|
@@ -33413,8 +33501,8 @@ function handleCursorIncomingPermissionRequest(id, method, msg, deps) {
|
|
|
33413
33501
|
|
|
33414
33502
|
// src/agents/acp/clients/cursor/cursor-incoming-resolve-request.ts
|
|
33415
33503
|
function resolveCursorIncomingRequest(pendingRequests2, respond, requestId, result) {
|
|
33416
|
-
const
|
|
33417
|
-
const payload =
|
|
33504
|
+
const pending2 = pendingRequests2.get(requestId);
|
|
33505
|
+
const payload = pending2?.method === "session/request_permission" ? enrichAcpPermissionRpcResultFromRequestParams(result, pending2.params) : result;
|
|
33418
33506
|
respond(requestId, payload);
|
|
33419
33507
|
pendingRequests2.delete(requestId);
|
|
33420
33508
|
}
|
|
@@ -33552,25 +33640,25 @@ function createCursorJsonRpcInboundRespond(stdin) {
|
|
|
33552
33640
|
|
|
33553
33641
|
// src/agents/acp/clients/cursor/cursor-json-rpc-outbound.ts
|
|
33554
33642
|
function createCursorJsonRpcOutboundPending() {
|
|
33555
|
-
const
|
|
33643
|
+
const pending2 = /* @__PURE__ */ new Map();
|
|
33556
33644
|
let nextId = 1;
|
|
33557
33645
|
function allocateId() {
|
|
33558
33646
|
return nextId++;
|
|
33559
33647
|
}
|
|
33560
33648
|
function register(id, waiter) {
|
|
33561
|
-
|
|
33649
|
+
pending2.set(id, waiter);
|
|
33562
33650
|
}
|
|
33563
33651
|
function settleResponse(id, msg) {
|
|
33564
|
-
const waiter =
|
|
33652
|
+
const waiter = pending2.get(id);
|
|
33565
33653
|
if (!waiter) return false;
|
|
33566
|
-
|
|
33654
|
+
pending2.delete(id);
|
|
33567
33655
|
if (msg.error) waiter.reject(msg.error);
|
|
33568
33656
|
else waiter.resolve(msg.result);
|
|
33569
33657
|
return true;
|
|
33570
33658
|
}
|
|
33571
33659
|
function rejectOnWriteError(id, err) {
|
|
33572
|
-
const waiter =
|
|
33573
|
-
|
|
33660
|
+
const waiter = pending2.get(id);
|
|
33661
|
+
pending2.delete(id);
|
|
33574
33662
|
waiter?.reject(err);
|
|
33575
33663
|
}
|
|
33576
33664
|
return { allocateId, register, settleResponse, rejectOnWriteError };
|
|
@@ -38458,11 +38546,11 @@ function tryConsumeBinaryProxyBody(raw, deps) {
|
|
|
38458
38546
|
if (!PROXY_ID_RE.test(id)) return false;
|
|
38459
38547
|
const body = raw.slice(PROXY_ID_BYTES);
|
|
38460
38548
|
const bodyBytes = body.length > 0 ? new Uint8Array(body) : new Uint8Array(0);
|
|
38461
|
-
const
|
|
38462
|
-
if (
|
|
38549
|
+
const pending2 = deps.pendingProxyBody.get(id);
|
|
38550
|
+
if (pending2) {
|
|
38463
38551
|
deps.pendingProxyBody.delete(id);
|
|
38464
38552
|
deps.startStreamingProxy({
|
|
38465
|
-
...
|
|
38553
|
+
...pending2.pr,
|
|
38466
38554
|
body: bodyBytes.length > 0 ? bodyBytes : void 0
|
|
38467
38555
|
});
|
|
38468
38556
|
return true;
|
|
@@ -38855,9 +38943,9 @@ function processHeartbeatAck(params) {
|
|
|
38855
38943
|
if (awaitingSeq === null) return { awaitingSeq, missed: 0 };
|
|
38856
38944
|
if (!Number.isFinite(seq)) return { awaitingSeq, missed: 0 };
|
|
38857
38945
|
const ack = Math.trunc(seq);
|
|
38858
|
-
const
|
|
38859
|
-
if (ack <
|
|
38860
|
-
if (ack ===
|
|
38946
|
+
const pending2 = awaitingSeq;
|
|
38947
|
+
if (ack < pending2) return { awaitingSeq, missed: 0 };
|
|
38948
|
+
if (ack === pending2) {
|
|
38861
38949
|
recordRtt(Date.now() - sentAtMs);
|
|
38862
38950
|
}
|
|
38863
38951
|
return { awaitingSeq: null, missed: 0 };
|
|
@@ -49226,18 +49314,62 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
49226
49314
|
}
|
|
49227
49315
|
}
|
|
49228
49316
|
|
|
49317
|
+
// src/agents/acp/from-bridge/pending-prompt-results.ts
|
|
49318
|
+
var pending = [];
|
|
49319
|
+
function enqueuePendingPromptResult(message) {
|
|
49320
|
+
const runId = typeof message.runId === "string" ? message.runId : "";
|
|
49321
|
+
if (runId) {
|
|
49322
|
+
const idx = pending.findIndex((m) => m.runId === runId);
|
|
49323
|
+
if (idx >= 0) pending.splice(idx, 1);
|
|
49324
|
+
}
|
|
49325
|
+
pending.push(message);
|
|
49326
|
+
}
|
|
49327
|
+
function flushPendingPromptResults(getWs, encrypt) {
|
|
49328
|
+
if (pending.length === 0) return;
|
|
49329
|
+
const ws = getWs();
|
|
49330
|
+
if (!ws || ws.readyState !== wrapper_default.OPEN) return;
|
|
49331
|
+
const still = [];
|
|
49332
|
+
for (const message of pending) {
|
|
49333
|
+
const wire = encrypt ? encrypt(message) : message;
|
|
49334
|
+
if (!sendWsMessage(ws, wire)) still.push(message);
|
|
49335
|
+
}
|
|
49336
|
+
pending.length = 0;
|
|
49337
|
+
pending.push(...still);
|
|
49338
|
+
}
|
|
49339
|
+
|
|
49340
|
+
// src/agents/acp/from-bridge/send-session-update-wire.ts
|
|
49341
|
+
function sendSessionUpdateWire(getWs, payload, opts) {
|
|
49342
|
+
const s = getWs();
|
|
49343
|
+
if (!s || s.readyState !== wrapper_default.OPEN) {
|
|
49344
|
+
opts.log("[Bridge service] Session update not sent: not connected to the bridge.");
|
|
49345
|
+
return;
|
|
49346
|
+
}
|
|
49347
|
+
const p = payload;
|
|
49348
|
+
const wire = p.type === "session_update" && opts.e2ee ? opts.e2ee.encryptFields(payload, ["payload"]) : p.type === "session_file_change" && opts.e2ee ? opts.e2ee.encryptFields(payload, [
|
|
49349
|
+
"path",
|
|
49350
|
+
"oldText",
|
|
49351
|
+
"newText",
|
|
49352
|
+
"patchContent",
|
|
49353
|
+
"isDirectory",
|
|
49354
|
+
"directoryRemoved"
|
|
49355
|
+
]) : payload;
|
|
49356
|
+
sendWsMessage(s, wire);
|
|
49357
|
+
}
|
|
49358
|
+
|
|
49229
49359
|
// src/agents/acp/from-bridge/bridge-prompt-wiring.ts
|
|
49230
49360
|
function createBridgePromptSenders(deps, getWs) {
|
|
49231
49361
|
const sendBridgeMessage = (message, encryptedFields = []) => {
|
|
49232
49362
|
const s = getWs();
|
|
49233
|
-
if (!s) return false;
|
|
49363
|
+
if (!s || s.readyState !== wrapper_default.OPEN) return false;
|
|
49234
49364
|
const wire = deps.e2ee && encryptedFields.length > 0 ? deps.e2ee.encryptFields(message, encryptedFields) : message;
|
|
49235
|
-
sendWsMessage(s, wire);
|
|
49236
|
-
return true;
|
|
49365
|
+
return sendWsMessage(s, wire);
|
|
49237
49366
|
};
|
|
49238
49367
|
const sendResult = (result) => {
|
|
49239
|
-
const
|
|
49240
|
-
|
|
49368
|
+
const sent = sendBridgeMessage(result, result.type === "prompt_result" ? ["output", "error"] : []);
|
|
49369
|
+
if (!sent && result.type === "prompt_result") {
|
|
49370
|
+
enqueuePendingPromptResult(result);
|
|
49371
|
+
deps.log("[Bridge service] prompt_result deferred until bridge reconnect.");
|
|
49372
|
+
}
|
|
49241
49373
|
if (result.type === "prompt_result") {
|
|
49242
49374
|
const pr = result;
|
|
49243
49375
|
const cancelled = pr.stopReason === "cancelled";
|
|
@@ -49250,24 +49382,11 @@ function createBridgePromptSenders(deps, getWs) {
|
|
|
49250
49382
|
});
|
|
49251
49383
|
}
|
|
49252
49384
|
};
|
|
49253
|
-
|
|
49254
|
-
|
|
49255
|
-
|
|
49256
|
-
|
|
49257
|
-
return;
|
|
49258
|
-
}
|
|
49259
|
-
const p = payload;
|
|
49260
|
-
const wire = p.type === "session_update" && deps.e2ee ? deps.e2ee.encryptFields(payload, ["payload"]) : p.type === "session_file_change" && deps.e2ee ? deps.e2ee.encryptFields(payload, [
|
|
49261
|
-
"path",
|
|
49262
|
-
"oldText",
|
|
49263
|
-
"newText",
|
|
49264
|
-
"patchContent",
|
|
49265
|
-
"isDirectory",
|
|
49266
|
-
"directoryRemoved"
|
|
49267
|
-
]) : payload;
|
|
49268
|
-
sendWsMessage(s, wire);
|
|
49385
|
+
return {
|
|
49386
|
+
sendBridgeMessage,
|
|
49387
|
+
sendResult,
|
|
49388
|
+
sendSessionUpdate: (payload) => sendSessionUpdateWire(getWs, payload, { e2ee: deps.e2ee, log: deps.log })
|
|
49269
49389
|
};
|
|
49270
|
-
return { sendBridgeMessage, sendResult, sendSessionUpdate };
|
|
49271
49390
|
}
|
|
49272
49391
|
|
|
49273
49392
|
// src/agents/acp/from-bridge/handle-bridge-prompt/parse-bridge-attachments.ts
|
|
@@ -49977,25 +50096,59 @@ var handleInstallSkillsMessage = (msg, deps) => {
|
|
|
49977
50096
|
})();
|
|
49978
50097
|
};
|
|
49979
50098
|
|
|
49980
|
-
// src/agents/install/
|
|
49981
|
-
import {
|
|
49982
|
-
import
|
|
49983
|
-
|
|
49984
|
-
|
|
49985
|
-
|
|
49986
|
-
|
|
49987
|
-
|
|
50099
|
+
// src/agents/install/run-streaming-command.ts
|
|
50100
|
+
import { spawn as spawn11 } from "node:child_process";
|
|
50101
|
+
import * as readline3 from "node:readline";
|
|
50102
|
+
function runStreamingCommand(command, args, options) {
|
|
50103
|
+
return new Promise((resolve35, reject) => {
|
|
50104
|
+
const child = spawn11(command, args, {
|
|
50105
|
+
env: options.env,
|
|
50106
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
50107
|
+
});
|
|
50108
|
+
let settled = false;
|
|
50109
|
+
const timer = options.timeoutMs != null ? setTimeout(() => {
|
|
50110
|
+
child.kill("SIGKILL");
|
|
50111
|
+
if (!settled) {
|
|
50112
|
+
settled = true;
|
|
50113
|
+
reject(new Error(`Command timed out after ${options.timeoutMs}ms`));
|
|
50114
|
+
}
|
|
50115
|
+
}, options.timeoutMs) : null;
|
|
50116
|
+
const onLine = (line) => {
|
|
50117
|
+
if (line.length > 0) options.onLine?.(line);
|
|
50118
|
+
};
|
|
50119
|
+
if (child.stdout) {
|
|
50120
|
+
readline3.createInterface({ input: child.stdout, crlfDelay: Infinity }).on("line", onLine);
|
|
50121
|
+
}
|
|
50122
|
+
if (child.stderr) {
|
|
50123
|
+
readline3.createInterface({ input: child.stderr, crlfDelay: Infinity }).on("line", onLine);
|
|
50124
|
+
}
|
|
50125
|
+
child.on("error", (err) => {
|
|
50126
|
+
if (timer) clearTimeout(timer);
|
|
50127
|
+
if (!settled) {
|
|
50128
|
+
settled = true;
|
|
50129
|
+
reject(err);
|
|
50130
|
+
}
|
|
50131
|
+
});
|
|
50132
|
+
child.on("close", (code, signal) => {
|
|
50133
|
+
if (timer) clearTimeout(timer);
|
|
50134
|
+
if (!settled) {
|
|
50135
|
+
settled = true;
|
|
50136
|
+
resolve35({ code, signal });
|
|
50137
|
+
}
|
|
50138
|
+
});
|
|
50139
|
+
});
|
|
49988
50140
|
}
|
|
49989
50141
|
|
|
49990
50142
|
// src/agents/install/commands/run-npm-global-install.ts
|
|
49991
|
-
|
|
49992
|
-
|
|
49993
|
-
const { stdout, stderr } = await execFileAsync8("npm", ["install", "-g", packageName], {
|
|
49994
|
-
timeout: timeoutMs,
|
|
50143
|
+
async function runNpmGlobalInstall(packageName, env, options) {
|
|
50144
|
+
const result = await runStreamingCommand("npm", ["install", "-g", packageName], {
|
|
49995
50145
|
env: bridgeAgentPathEnv(env),
|
|
49996
|
-
|
|
50146
|
+
timeoutMs: options?.timeoutMs ?? 3e5,
|
|
50147
|
+
onLine: options?.onLine
|
|
49997
50148
|
});
|
|
49998
|
-
|
|
50149
|
+
if (result.code !== 0) {
|
|
50150
|
+
throw new Error(`npm install -g ${packageName} failed (exit ${result.code ?? "signal"})`);
|
|
50151
|
+
}
|
|
49999
50152
|
}
|
|
50000
50153
|
|
|
50001
50154
|
// src/agents/install/commands/claude-code.ts
|
|
@@ -50003,11 +50156,12 @@ var claudeCodeInstallCommand = {
|
|
|
50003
50156
|
agentType: "claude-code",
|
|
50004
50157
|
detectCommand: "claude",
|
|
50005
50158
|
async install(ctx) {
|
|
50006
|
-
|
|
50007
|
-
|
|
50008
|
-
|
|
50009
|
-
|
|
50010
|
-
|
|
50159
|
+
ctx.onProgress?.("Installing Anthropic Claude Code");
|
|
50160
|
+
await runNpmGlobalInstall(
|
|
50161
|
+
"@anthropic-ai/claude-code",
|
|
50162
|
+
{ ...ctx.env, ANTHROPIC_API_KEY: ctx.authToken },
|
|
50163
|
+
{ onLine: (line) => ctx.onProgress?.("Installing Anthropic Claude Code", line) }
|
|
50164
|
+
);
|
|
50011
50165
|
}
|
|
50012
50166
|
};
|
|
50013
50167
|
|
|
@@ -50016,34 +50170,34 @@ var codexAcpInstallCommand = {
|
|
|
50016
50170
|
agentType: "codex-acp",
|
|
50017
50171
|
detectCommand: "codex",
|
|
50018
50172
|
async install(ctx) {
|
|
50019
|
-
|
|
50020
|
-
|
|
50021
|
-
|
|
50022
|
-
|
|
50023
|
-
|
|
50173
|
+
ctx.onProgress?.("Installing Codex");
|
|
50174
|
+
await runNpmGlobalInstall(
|
|
50175
|
+
"@openai/codex",
|
|
50176
|
+
{ ...ctx.env, OPENAI_API_KEY: ctx.authToken },
|
|
50177
|
+
{ onLine: (line) => ctx.onProgress?.("Installing Codex", line) }
|
|
50178
|
+
);
|
|
50024
50179
|
}
|
|
50025
50180
|
};
|
|
50026
50181
|
|
|
50027
50182
|
// src/agents/install/commands/cursor-cli.ts
|
|
50028
|
-
import { execFile as execFile10 } from "node:child_process";
|
|
50029
|
-
import { promisify as promisify11 } from "node:util";
|
|
50030
|
-
var execFileAsync9 = promisify11(execFile10);
|
|
50031
50183
|
var cursorCliInstallCommand = {
|
|
50032
50184
|
agentType: "cursor-cli",
|
|
50033
50185
|
detectCommand: "agent",
|
|
50034
50186
|
alternateDetectCommands: ["cursor-agent"],
|
|
50035
50187
|
async install(ctx) {
|
|
50036
|
-
|
|
50188
|
+
ctx.onProgress?.("Installing Cursor CLI");
|
|
50189
|
+
const result = await runStreamingCommand(
|
|
50037
50190
|
"bash",
|
|
50038
50191
|
["-lc", "curl -fsSL https://cursor.com/install | bash"],
|
|
50039
50192
|
{
|
|
50040
|
-
|
|
50193
|
+
timeoutMs: 3e5,
|
|
50041
50194
|
env: { ...bridgeAgentPathEnv(ctx.env), CURSOR_API_KEY: ctx.authToken },
|
|
50042
|
-
|
|
50195
|
+
onLine: (line) => ctx.onProgress?.("Installing Cursor CLI", line)
|
|
50043
50196
|
}
|
|
50044
50197
|
);
|
|
50045
|
-
|
|
50046
|
-
|
|
50198
|
+
if (result.code !== 0) {
|
|
50199
|
+
throw new Error(`Cursor CLI install failed (exit ${result.code ?? "signal"})`);
|
|
50200
|
+
}
|
|
50047
50201
|
}
|
|
50048
50202
|
};
|
|
50049
50203
|
|
|
@@ -50052,11 +50206,12 @@ var opencodeInstallCommand = {
|
|
|
50052
50206
|
agentType: "opencode",
|
|
50053
50207
|
detectCommand: "opencode",
|
|
50054
50208
|
async install(ctx) {
|
|
50055
|
-
|
|
50056
|
-
|
|
50057
|
-
|
|
50058
|
-
|
|
50059
|
-
|
|
50209
|
+
ctx.onProgress?.("Installing OpenCode");
|
|
50210
|
+
await runNpmGlobalInstall(
|
|
50211
|
+
"opencode-ai",
|
|
50212
|
+
{ ...ctx.env, OPENCODE_API_KEY: ctx.authToken },
|
|
50213
|
+
{ onLine: (line) => ctx.onProgress?.("Installing OpenCode", line) }
|
|
50214
|
+
);
|
|
50060
50215
|
}
|
|
50061
50216
|
};
|
|
50062
50217
|
|
|
@@ -50117,25 +50272,47 @@ var handleInstallAgentMessage = (msg, deps) => {
|
|
|
50117
50272
|
if (!processId || !agentId || !tokenId || !agentType || !authToken) return;
|
|
50118
50273
|
void (async () => {
|
|
50119
50274
|
const socket = deps.getWs();
|
|
50120
|
-
|
|
50121
|
-
|
|
50122
|
-
|
|
50123
|
-
|
|
50124
|
-
|
|
50125
|
-
|
|
50126
|
-
|
|
50127
|
-
|
|
50128
|
-
|
|
50129
|
-
|
|
50130
|
-
|
|
50131
|
-
|
|
50275
|
+
let pendingLines = [];
|
|
50276
|
+
let flushTimer = null;
|
|
50277
|
+
const sendProgress = (message, logOutput) => {
|
|
50278
|
+
if (!socket) return;
|
|
50279
|
+
sendWsMessage(socket, {
|
|
50280
|
+
type: "install_agent_progress",
|
|
50281
|
+
processId,
|
|
50282
|
+
agentId,
|
|
50283
|
+
tokenId,
|
|
50284
|
+
agentType,
|
|
50285
|
+
step: "agent_install_package",
|
|
50286
|
+
message,
|
|
50287
|
+
...logOutput ? { logOutput } : {}
|
|
50288
|
+
});
|
|
50289
|
+
};
|
|
50290
|
+
const flushLines = (message) => {
|
|
50291
|
+
if (flushTimer) {
|
|
50292
|
+
clearTimeout(flushTimer);
|
|
50293
|
+
flushTimer = null;
|
|
50132
50294
|
}
|
|
50295
|
+
if (pendingLines.length === 0) return;
|
|
50296
|
+
const logOutput = pendingLines.join("\n");
|
|
50297
|
+
pendingLines = [];
|
|
50298
|
+
sendProgress(message, logOutput);
|
|
50133
50299
|
};
|
|
50134
50300
|
const result = await installLocalAgentOnBridge({
|
|
50135
50301
|
agentType,
|
|
50136
50302
|
authToken,
|
|
50137
|
-
onProgress: (message, logOutput) =>
|
|
50303
|
+
onProgress: (message, logOutput) => {
|
|
50304
|
+
if (logOutput == null) {
|
|
50305
|
+
flushLines(message);
|
|
50306
|
+
sendProgress(message);
|
|
50307
|
+
return;
|
|
50308
|
+
}
|
|
50309
|
+
pendingLines.push(logOutput);
|
|
50310
|
+
if (!flushTimer) {
|
|
50311
|
+
flushTimer = setTimeout(() => flushLines(message), 100);
|
|
50312
|
+
}
|
|
50313
|
+
}
|
|
50138
50314
|
});
|
|
50315
|
+
flushLines("Installing agent packages on the bridge machine.");
|
|
50139
50316
|
if (socket) {
|
|
50140
50317
|
sendWsMessage(socket, {
|
|
50141
50318
|
type: "install_agent_result",
|
|
@@ -50147,9 +50324,7 @@ var handleInstallAgentMessage = (msg, deps) => {
|
|
|
50147
50324
|
error: result.error
|
|
50148
50325
|
});
|
|
50149
50326
|
}
|
|
50150
|
-
if (result.success)
|
|
50151
|
-
await deps.reportAutoDetectedAgents?.();
|
|
50152
|
-
}
|
|
50327
|
+
if (result.success) await deps.reportAutoDetectedAgents?.();
|
|
50153
50328
|
if (!result.success) {
|
|
50154
50329
|
deps.log(`[Bridge service] Install agent failed: ${result.error ?? "unknown"}`);
|
|
50155
50330
|
}
|
|
@@ -50734,6 +50909,10 @@ function createMainBridgeOpenHandler(params) {
|
|
|
50734
50909
|
if (socket) {
|
|
50735
50910
|
sendBridgeIdentify(socket, { identifyReportedPaths, e2ee });
|
|
50736
50911
|
reportGitRepos(getWs, logFn);
|
|
50912
|
+
flushPendingPromptResults(
|
|
50913
|
+
getWs,
|
|
50914
|
+
(message) => e2ee ? e2ee.encryptFields(message, ["output", "error"]) : message
|
|
50915
|
+
);
|
|
50737
50916
|
try {
|
|
50738
50917
|
onBridgeSocketOpen?.();
|
|
50739
50918
|
} catch {
|
|
@@ -50878,7 +51057,7 @@ async function createBridgeConnection(options) {
|
|
|
50878
51057
|
}
|
|
50879
51058
|
|
|
50880
51059
|
// src/e2e-certificates/key-command.ts
|
|
50881
|
-
import * as
|
|
51060
|
+
import * as readline4 from "node:readline";
|
|
50882
51061
|
function installE2eCertificateKeyCommand({
|
|
50883
51062
|
log: log2,
|
|
50884
51063
|
onOpenCertificate,
|
|
@@ -50889,7 +51068,7 @@ function installE2eCertificateKeyCommand({
|
|
|
50889
51068
|
return () => {
|
|
50890
51069
|
};
|
|
50891
51070
|
}
|
|
50892
|
-
|
|
51071
|
+
readline4.emitKeypressEvents(process.stdin);
|
|
50893
51072
|
process.stdin.setRawMode(true);
|
|
50894
51073
|
process.stdin.resume();
|
|
50895
51074
|
const onKeypress = (str, key) => {
|
|
@@ -50930,32 +51109,42 @@ async function openE2eCertificateImportUrl({
|
|
|
50930
51109
|
}
|
|
50931
51110
|
}
|
|
50932
51111
|
|
|
50933
|
-
// src/run-bridge-
|
|
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();
|
|
50934
51135
|
init_cli_process_interrupt();
|
|
50935
|
-
|
|
50936
|
-
async function runConnectedBridge(options, restartWithoutAuth) {
|
|
50937
|
-
const {
|
|
50938
|
-
apiUrl,
|
|
50939
|
-
workspaceId,
|
|
50940
|
-
authToken,
|
|
50941
|
-
refreshToken,
|
|
50942
|
-
justAuthenticated,
|
|
50943
|
-
worktreesRootPath,
|
|
50944
|
-
e2eCertificate
|
|
50945
|
-
} = options;
|
|
50946
|
-
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
50947
|
-
let cleanupKeyCommand;
|
|
50948
|
-
let bridgeClose = null;
|
|
51136
|
+
function installConnectedBridgeSignals(params) {
|
|
50949
51137
|
let shutdownStarted = false;
|
|
50950
51138
|
const onSignal = (kind) => {
|
|
50951
51139
|
requestCliImmediateShutdown();
|
|
50952
51140
|
abortActiveGitChildProcesses();
|
|
50953
|
-
cleanupKeyCommand
|
|
51141
|
+
params.cleanupKeyCommand();
|
|
50954
51142
|
if (shutdownStarted) return;
|
|
50955
51143
|
shutdownStarted = true;
|
|
50956
51144
|
logImmediate(
|
|
50957
51145
|
kind === "interrupt" ? "Keyboard interrupt (Ctrl+C) \u2014 stopping\u2026" : "Stop requested \u2014 shutting down\u2026"
|
|
50958
51146
|
);
|
|
51147
|
+
const bridgeClose = params.getBridgeClose();
|
|
50959
51148
|
if (bridgeClose) {
|
|
50960
51149
|
void bridgeClose().finally(() => process.exit(0));
|
|
50961
51150
|
return;
|
|
@@ -50966,9 +51155,56 @@ async function runConnectedBridge(options, restartWithoutAuth) {
|
|
|
50966
51155
|
const onSigTerm = () => onSignal("stop");
|
|
50967
51156
|
process.on("SIGINT", onSigInt);
|
|
50968
51157
|
process.on("SIGTERM", onSigTerm);
|
|
50969
|
-
|
|
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
|
+
});
|
|
50970
51206
|
try {
|
|
50971
|
-
handle = await createBridgeConnection({
|
|
51207
|
+
const handle = await createBridgeConnection({
|
|
50972
51208
|
apiUrl,
|
|
50973
51209
|
workspaceId,
|
|
50974
51210
|
authToken,
|
|
@@ -50987,41 +51223,40 @@ async function runConnectedBridge(options, restartWithoutAuth) {
|
|
|
50987
51223
|
},
|
|
50988
51224
|
onAuthInvalid: () => {
|
|
50989
51225
|
cleanupKeyCommand?.();
|
|
50990
|
-
|
|
50991
|
-
|
|
50992
|
-
|
|
50993
|
-
|
|
50994
|
-
|
|
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
|
+
})();
|
|
50995
51238
|
}
|
|
50996
51239
|
});
|
|
50997
|
-
|
|
50998
|
-
|
|
50999
|
-
|
|
51000
|
-
|
|
51001
|
-
|
|
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
|
+
});
|
|
51002
51250
|
}
|
|
51251
|
+
} catch (e) {
|
|
51252
|
+
signals.remove();
|
|
51253
|
+
if (e instanceof CliSqliteInterrupted) process.exit(0);
|
|
51003
51254
|
throw e;
|
|
51255
|
+
} finally {
|
|
51256
|
+
resolveHandleReady();
|
|
51004
51257
|
}
|
|
51005
|
-
|
|
51006
|
-
|
|
51007
|
-
let openingCertificate = false;
|
|
51008
|
-
cleanupKeyCommand = installE2eCertificateKeyCommand({
|
|
51009
|
-
log,
|
|
51010
|
-
onInterrupt: onSigInt,
|
|
51011
|
-
onOpenCertificate: () => {
|
|
51012
|
-
if (openingCertificate) return;
|
|
51013
|
-
openingCertificate = true;
|
|
51014
|
-
void openE2eCertificateImportUrl({
|
|
51015
|
-
apiUrl,
|
|
51016
|
-
workspaceId,
|
|
51017
|
-
certificate: e2eCertificate,
|
|
51018
|
-
log
|
|
51019
|
-
}).finally(() => {
|
|
51020
|
-
openingCertificate = false;
|
|
51021
|
-
});
|
|
51022
|
-
}
|
|
51023
|
-
});
|
|
51024
|
-
}
|
|
51258
|
+
await sessionDone;
|
|
51259
|
+
await restartWithoutAuth({ apiUrl, firehoseServerUrl, worktreesRootPath, e2eCertificate });
|
|
51025
51260
|
}
|
|
51026
51261
|
|
|
51027
51262
|
// src/run-bridge.ts
|
|
@@ -51065,12 +51300,16 @@ async function runBridge(options) {
|
|
|
51065
51300
|
process.off("SIGINT", onSigInt);
|
|
51066
51301
|
process.off("SIGTERM", onSigTerm);
|
|
51067
51302
|
handle.close();
|
|
51068
|
-
if (!auth)
|
|
51303
|
+
if (!auth) {
|
|
51304
|
+
log("Sign-in ended before a token was received.");
|
|
51305
|
+
return;
|
|
51306
|
+
}
|
|
51069
51307
|
writeConfigForApi(apiUrl, {
|
|
51070
51308
|
workspaceId: auth.workspaceId,
|
|
51071
51309
|
token: auth.token,
|
|
51072
51310
|
refreshToken: auth.refreshToken
|
|
51073
51311
|
});
|
|
51312
|
+
log("Link established. Connecting with the new token\u2026");
|
|
51074
51313
|
await runBridge({
|
|
51075
51314
|
apiUrl,
|
|
51076
51315
|
workspaceId: auth.workspaceId,
|