@buildautomaton/cli 0.1.77 → 0.1.79
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 +355 -166
- package/dist/cli.js.map +4 -4
- package/dist/index.js +355 -166
- package/dist/index.js.map +4 -4
- package/dist/worker.js +5 -2
- package/dist/worker.js.map +2 -2
- 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
|
}
|
|
@@ -8413,7 +8413,11 @@ var init_migrate_cli_sqlite = __esm({
|
|
|
8413
8413
|
});
|
|
8414
8414
|
|
|
8415
8415
|
// src/sqlite/cli-database.ts
|
|
8416
|
-
|
|
8416
|
+
function closeAllCliSqliteConnections() {
|
|
8417
|
+
legacyImportDoneForPath = null;
|
|
8418
|
+
cliSqlite.closeAllConnections();
|
|
8419
|
+
}
|
|
8420
|
+
var legacyImportDoneForPath, cliSqlite, safeCloseCliSqliteDatabase, openCliSqliteConnection, withCliSqliteSync, withCliSqlite, ensureCliSqliteInitialized;
|
|
8417
8421
|
var init_cli_database = __esm({
|
|
8418
8422
|
"src/sqlite/cli-database.ts"() {
|
|
8419
8423
|
"use strict";
|
|
@@ -8423,16 +8427,19 @@ var init_cli_database = __esm({
|
|
|
8423
8427
|
init_import_cli_legacy_disk_data();
|
|
8424
8428
|
init_migrate_cli_sqlite();
|
|
8425
8429
|
init_sqlite_errors();
|
|
8430
|
+
legacyImportDoneForPath = null;
|
|
8426
8431
|
cliSqlite = createSqliteDatabaseAccess({
|
|
8427
8432
|
getPath: getCliSqlitePath,
|
|
8428
8433
|
ensureParentDir: ensureCliSqliteParentDir,
|
|
8429
8434
|
migrate: migrateCliSqlite,
|
|
8430
8435
|
afterOpen: (db, options) => {
|
|
8436
|
+
const sqlitePath = getCliSqlitePath();
|
|
8437
|
+
if (legacyImportDoneForPath === sqlitePath) return;
|
|
8431
8438
|
importCliSqliteLegacyDiskData(db, options?.logLegacyMigration);
|
|
8439
|
+
legacyImportDoneForPath = sqlitePath;
|
|
8432
8440
|
}
|
|
8433
8441
|
});
|
|
8434
8442
|
safeCloseCliSqliteDatabase = cliSqlite.safeClose;
|
|
8435
|
-
closeAllCliSqliteConnections = cliSqlite.closeAllConnections;
|
|
8436
8443
|
openCliSqliteConnection = cliSqlite.openConnection;
|
|
8437
8444
|
withCliSqliteSync = cliSqlite.withSync;
|
|
8438
8445
|
withCliSqlite = cliSqlite.withAsync;
|
|
@@ -16650,7 +16657,7 @@ var require_tree_kill = __commonJS({
|
|
|
16650
16657
|
"../../node_modules/.pnpm/tree-kill@1.2.2/node_modules/tree-kill/index.js"(exports, module) {
|
|
16651
16658
|
"use strict";
|
|
16652
16659
|
var childProcess2 = __require("child_process");
|
|
16653
|
-
var
|
|
16660
|
+
var spawn12 = childProcess2.spawn;
|
|
16654
16661
|
var exec = childProcess2.exec;
|
|
16655
16662
|
module.exports = function(pid, signal, callback) {
|
|
16656
16663
|
if (typeof signal === "function" && callback === void 0) {
|
|
@@ -16675,7 +16682,7 @@ var require_tree_kill = __commonJS({
|
|
|
16675
16682
|
break;
|
|
16676
16683
|
case "darwin":
|
|
16677
16684
|
buildProcessTree(pid, tree, pidsToProcess, function(parentPid) {
|
|
16678
|
-
return
|
|
16685
|
+
return spawn12("pgrep", ["-P", parentPid]);
|
|
16679
16686
|
}, function() {
|
|
16680
16687
|
killAll(tree, signal, callback);
|
|
16681
16688
|
});
|
|
@@ -16687,7 +16694,7 @@ var require_tree_kill = __commonJS({
|
|
|
16687
16694
|
// break;
|
|
16688
16695
|
default:
|
|
16689
16696
|
buildProcessTree(pid, tree, pidsToProcess, function(parentPid) {
|
|
16690
|
-
return
|
|
16697
|
+
return spawn12("ps", ["-o", "pid", "--no-headers", "--ppid", parentPid]);
|
|
16691
16698
|
}, function() {
|
|
16692
16699
|
killAll(tree, signal, callback);
|
|
16693
16700
|
});
|
|
@@ -31064,7 +31071,7 @@ var {
|
|
|
31064
31071
|
} = import_index.default;
|
|
31065
31072
|
|
|
31066
31073
|
// src/cli-version.ts
|
|
31067
|
-
var CLI_VERSION = "0.1.
|
|
31074
|
+
var CLI_VERSION = "0.1.79".length > 0 ? "0.1.79" : "0.0.0-dev";
|
|
31068
31075
|
|
|
31069
31076
|
// src/cli/defaults.ts
|
|
31070
31077
|
var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
|
|
@@ -31691,9 +31698,9 @@ function createWsBridge(options) {
|
|
|
31691
31698
|
return ws;
|
|
31692
31699
|
}
|
|
31693
31700
|
function sendWsMessage(ws, payload) {
|
|
31694
|
-
if (ws.readyState
|
|
31695
|
-
|
|
31696
|
-
|
|
31701
|
+
if (ws.readyState !== wrapper_default.OPEN) return false;
|
|
31702
|
+
ws.send(JSON.stringify(payload));
|
|
31703
|
+
return true;
|
|
31697
31704
|
}
|
|
31698
31705
|
|
|
31699
31706
|
// src/connection/heartbeat/constants.ts
|
|
@@ -34946,6 +34953,31 @@ function getAgentModelFromAgentConfig(config2) {
|
|
|
34946
34953
|
var HOUR_MS = 36e5;
|
|
34947
34954
|
var DAY_MS = 24 * HOUR_MS;
|
|
34948
34955
|
|
|
34956
|
+
// ../types/src/hosts/skus.ts
|
|
34957
|
+
function defineHostSku(params) {
|
|
34958
|
+
return structuredClone(params);
|
|
34959
|
+
}
|
|
34960
|
+
var FLY_LEGACY_HOST_SKU = defineHostSku({
|
|
34961
|
+
id: "fly-shared-1x512-1gb",
|
|
34962
|
+
provider: "fly",
|
|
34963
|
+
compute: { cpus: 1, cpuKind: "shared" },
|
|
34964
|
+
memory: { memoryMb: 512 },
|
|
34965
|
+
storage: { storageGb: 1 },
|
|
34966
|
+
monthlyPriceCents: 750
|
|
34967
|
+
});
|
|
34968
|
+
var FLY_DEFAULT_HOST_SKU = defineHostSku({
|
|
34969
|
+
id: "fly-shared-1x1024-1gb",
|
|
34970
|
+
provider: "fly",
|
|
34971
|
+
compute: { cpus: 1, cpuKind: "shared" },
|
|
34972
|
+
memory: { memoryMb: 1024 },
|
|
34973
|
+
storage: { storageGb: 1 },
|
|
34974
|
+
monthlyPriceCents: 1e3
|
|
34975
|
+
});
|
|
34976
|
+
var HOST_SKUS_BY_ID = {
|
|
34977
|
+
[FLY_LEGACY_HOST_SKU.id]: FLY_LEGACY_HOST_SKU,
|
|
34978
|
+
[FLY_DEFAULT_HOST_SKU.id]: FLY_DEFAULT_HOST_SKU
|
|
34979
|
+
};
|
|
34980
|
+
|
|
34949
34981
|
// ../types/src/bridges/agents/types.ts
|
|
34950
34982
|
var INSTALLABLE_BRIDGE_AGENTS = [
|
|
34951
34983
|
{ value: "claude-code", label: "Anthropic Claude Code", tokenLabel: "Anthropic API key", tokenEnvVar: "ANTHROPIC_API_KEY" },
|
|
@@ -35446,11 +35478,11 @@ function createSdkStdioExtNotificationHandler(options) {
|
|
|
35446
35478
|
|
|
35447
35479
|
// src/agents/acp/clients/sdk/sdk-stdio-permission-request-handshake.ts
|
|
35448
35480
|
function awaitSdkStdioPermissionRequestHandshake(params) {
|
|
35449
|
-
const { requestId, paramsRecord, pending, onRequest } = params;
|
|
35481
|
+
const { requestId, paramsRecord, pending: pending2, onRequest } = params;
|
|
35450
35482
|
return new Promise((resolve37) => {
|
|
35451
|
-
|
|
35483
|
+
pending2.set(requestId, { resolve: resolve37, params: paramsRecord });
|
|
35452
35484
|
if (onRequest == null) {
|
|
35453
|
-
|
|
35485
|
+
pending2.delete(requestId);
|
|
35454
35486
|
resolve37({ outcome: { outcome: "denied" } });
|
|
35455
35487
|
return;
|
|
35456
35488
|
}
|
|
@@ -35466,9 +35498,9 @@ function awaitSdkStdioPermissionRequestHandshake(params) {
|
|
|
35466
35498
|
}
|
|
35467
35499
|
|
|
35468
35500
|
// src/agents/acp/clients/sdk/sdk-stdio-permission-pending.ts
|
|
35469
|
-
function resolvePendingSdkStdioPermissionCancellations(
|
|
35470
|
-
for (const [id, entry] of [...
|
|
35471
|
-
|
|
35501
|
+
function resolvePendingSdkStdioPermissionCancellations(pending2) {
|
|
35502
|
+
for (const [id, entry] of [...pending2.entries()]) {
|
|
35503
|
+
pending2.delete(id);
|
|
35472
35504
|
entry.resolve({ outcome: { outcome: "cancelled" } });
|
|
35473
35505
|
}
|
|
35474
35506
|
}
|
|
@@ -36194,8 +36226,8 @@ function createCursorAcpSessionContext(options) {
|
|
|
36194
36226
|
|
|
36195
36227
|
// src/agents/acp/clients/cursor/cancel-pending-cursor-permission-requests.ts
|
|
36196
36228
|
function cancelPendingCursorPermissionRequests(pendingRequests2, respond) {
|
|
36197
|
-
for (const [reqId,
|
|
36198
|
-
if (
|
|
36229
|
+
for (const [reqId, pending2] of [...pendingRequests2.entries()]) {
|
|
36230
|
+
if (pending2.method === "session/request_permission") {
|
|
36199
36231
|
respond(reqId, { outcome: { outcome: "cancelled" } });
|
|
36200
36232
|
pendingRequests2.delete(reqId);
|
|
36201
36233
|
}
|
|
@@ -36387,8 +36419,8 @@ function handleCursorIncomingPermissionRequest(id, method, msg, deps) {
|
|
|
36387
36419
|
|
|
36388
36420
|
// src/agents/acp/clients/cursor/cursor-incoming-resolve-request.ts
|
|
36389
36421
|
function resolveCursorIncomingRequest(pendingRequests2, respond, requestId, result) {
|
|
36390
|
-
const
|
|
36391
|
-
const payload =
|
|
36422
|
+
const pending2 = pendingRequests2.get(requestId);
|
|
36423
|
+
const payload = pending2?.method === "session/request_permission" ? enrichAcpPermissionRpcResultFromRequestParams(result, pending2.params) : result;
|
|
36392
36424
|
respond(requestId, payload);
|
|
36393
36425
|
pendingRequests2.delete(requestId);
|
|
36394
36426
|
}
|
|
@@ -36526,25 +36558,25 @@ function createCursorJsonRpcInboundRespond(stdin) {
|
|
|
36526
36558
|
|
|
36527
36559
|
// src/agents/acp/clients/cursor/cursor-json-rpc-outbound.ts
|
|
36528
36560
|
function createCursorJsonRpcOutboundPending() {
|
|
36529
|
-
const
|
|
36561
|
+
const pending2 = /* @__PURE__ */ new Map();
|
|
36530
36562
|
let nextId = 1;
|
|
36531
36563
|
function allocateId() {
|
|
36532
36564
|
return nextId++;
|
|
36533
36565
|
}
|
|
36534
36566
|
function register(id, waiter) {
|
|
36535
|
-
|
|
36567
|
+
pending2.set(id, waiter);
|
|
36536
36568
|
}
|
|
36537
36569
|
function settleResponse(id, msg) {
|
|
36538
|
-
const waiter =
|
|
36570
|
+
const waiter = pending2.get(id);
|
|
36539
36571
|
if (!waiter) return false;
|
|
36540
|
-
|
|
36572
|
+
pending2.delete(id);
|
|
36541
36573
|
if (msg.error) waiter.reject(msg.error);
|
|
36542
36574
|
else waiter.resolve(msg.result);
|
|
36543
36575
|
return true;
|
|
36544
36576
|
}
|
|
36545
36577
|
function rejectOnWriteError(id, err) {
|
|
36546
|
-
const waiter =
|
|
36547
|
-
|
|
36578
|
+
const waiter = pending2.get(id);
|
|
36579
|
+
pending2.delete(id);
|
|
36548
36580
|
waiter?.reject(err);
|
|
36549
36581
|
}
|
|
36550
36582
|
return { allocateId, register, settleResponse, rejectOnWriteError };
|
|
@@ -36801,13 +36833,15 @@ import { existsSync as existsSync4, statSync } from "node:fs";
|
|
|
36801
36833
|
// src/git/get-git-repo-root-sync.ts
|
|
36802
36834
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
36803
36835
|
import * as path28 from "node:path";
|
|
36836
|
+
var GIT_LOOKUP_TIMEOUT_MS = 2e3;
|
|
36804
36837
|
function getGitRepoRootSync(startDir) {
|
|
36805
36838
|
try {
|
|
36806
36839
|
const out = execFileSync3("git", ["rev-parse", "--show-toplevel"], {
|
|
36807
36840
|
cwd: path28.resolve(startDir),
|
|
36808
36841
|
encoding: "utf8",
|
|
36809
36842
|
stdio: ["ignore", "pipe", "ignore"],
|
|
36810
|
-
maxBuffer: 1024 * 1024
|
|
36843
|
+
maxBuffer: 1024 * 1024,
|
|
36844
|
+
timeout: GIT_LOOKUP_TIMEOUT_MS
|
|
36811
36845
|
}).trim();
|
|
36812
36846
|
return out ? path28.resolve(out) : null;
|
|
36813
36847
|
} catch {
|
|
@@ -36819,6 +36853,7 @@ function getGitRepoRootSync(startDir) {
|
|
|
36819
36853
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
36820
36854
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
36821
36855
|
import * as path29 from "node:path";
|
|
36856
|
+
var GIT_FILE_READ_TIMEOUT_MS = 2e3;
|
|
36822
36857
|
function resolveWorkspaceFilePath(sessionParentPath, rawPath) {
|
|
36823
36858
|
const trimmed2 = rawPath.trim();
|
|
36824
36859
|
if (!trimmed2) return null;
|
|
@@ -36880,7 +36915,8 @@ function readGitHeadBlob(sessionParentPath, displayPath) {
|
|
|
36880
36915
|
return execFileSync4("git", ["show", `HEAD:${displayPath}`], {
|
|
36881
36916
|
cwd: execCwd,
|
|
36882
36917
|
encoding: "utf8",
|
|
36883
|
-
maxBuffer: 50 * 1024 * 1024
|
|
36918
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
36919
|
+
timeout: GIT_FILE_READ_TIMEOUT_MS
|
|
36884
36920
|
});
|
|
36885
36921
|
} catch {
|
|
36886
36922
|
return "";
|
|
@@ -36888,6 +36924,7 @@ function readGitHeadBlob(sessionParentPath, displayPath) {
|
|
|
36888
36924
|
}
|
|
36889
36925
|
|
|
36890
36926
|
// src/agents/acp/session-file-change-path-kind.ts
|
|
36927
|
+
var GIT_PATH_KIND_TIMEOUT_MS = 2e3;
|
|
36891
36928
|
function gitHeadPathObjectType(sessionParentPath, displayPath) {
|
|
36892
36929
|
if (!displayPath || displayPath.includes("..")) return null;
|
|
36893
36930
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
@@ -36895,7 +36932,8 @@ function gitHeadPathObjectType(sessionParentPath, displayPath) {
|
|
|
36895
36932
|
try {
|
|
36896
36933
|
return execFileSync5("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
|
|
36897
36934
|
cwd: gitRoot,
|
|
36898
|
-
encoding: "utf8"
|
|
36935
|
+
encoding: "utf8",
|
|
36936
|
+
timeout: GIT_PATH_KIND_TIMEOUT_MS
|
|
36899
36937
|
}).trim();
|
|
36900
36938
|
} catch {
|
|
36901
36939
|
return null;
|
|
@@ -38003,23 +38041,30 @@ function augmentPromptResultAuthFields(agentType, errorText) {
|
|
|
38003
38041
|
}
|
|
38004
38042
|
|
|
38005
38043
|
// src/agents/planning/submit-planning-todos-for-turn.ts
|
|
38044
|
+
var PLANNING_TODO_SUBMIT_TIMEOUT_MS = 3e3;
|
|
38006
38045
|
async function submitPlanningTodosForTurn(params) {
|
|
38007
38046
|
const token = params.getCloudAccessToken();
|
|
38008
38047
|
if (!token.trim()) return { ok: false, error: "Missing cloud access token" };
|
|
38009
38048
|
const base = params.cloudApiBaseUrl.replace(/\/$/, "");
|
|
38010
38049
|
const url2 = `${base}/internal/sessions/todos/submit`;
|
|
38011
|
-
|
|
38012
|
-
|
|
38013
|
-
|
|
38014
|
-
|
|
38015
|
-
|
|
38016
|
-
|
|
38017
|
-
|
|
38018
|
-
|
|
38019
|
-
|
|
38020
|
-
|
|
38021
|
-
|
|
38022
|
-
|
|
38050
|
+
let res;
|
|
38051
|
+
try {
|
|
38052
|
+
res = await fetch(url2, {
|
|
38053
|
+
method: "POST",
|
|
38054
|
+
signal: AbortSignal.timeout(PLANNING_TODO_SUBMIT_TIMEOUT_MS),
|
|
38055
|
+
headers: {
|
|
38056
|
+
Authorization: `Bearer ${token}`,
|
|
38057
|
+
"Content-Type": "application/json"
|
|
38058
|
+
},
|
|
38059
|
+
body: JSON.stringify({
|
|
38060
|
+
sessionId: params.sessionId,
|
|
38061
|
+
turnId: params.turnId,
|
|
38062
|
+
items: params.items
|
|
38063
|
+
})
|
|
38064
|
+
});
|
|
38065
|
+
} catch (error40) {
|
|
38066
|
+
return { ok: false, error: error40 instanceof Error ? error40.message : String(error40) };
|
|
38067
|
+
}
|
|
38023
38068
|
if (!res.ok) {
|
|
38024
38069
|
const body = await res.json().catch(() => null);
|
|
38025
38070
|
return { ok: false, error: body?.error ?? `Planning todo submit failed (${res.status})` };
|
|
@@ -38906,6 +38951,7 @@ async function resolveSendPromptImages(params) {
|
|
|
38906
38951
|
}
|
|
38907
38952
|
|
|
38908
38953
|
// src/agents/acp/prompts/send-prompt-to-agent.ts
|
|
38954
|
+
var SLOW_ACP_PROMPT_MS = 5e3;
|
|
38909
38955
|
async function sendPromptToAgent(options) {
|
|
38910
38956
|
const {
|
|
38911
38957
|
handle,
|
|
@@ -38952,7 +38998,12 @@ async function sendPromptToAgent(options) {
|
|
|
38952
38998
|
sendResult(imagesResolved.errorResult);
|
|
38953
38999
|
return;
|
|
38954
39000
|
}
|
|
39001
|
+
const promptStartedAt = Date.now();
|
|
38955
39002
|
const result = await handle.sendPrompt(prepared.agentPromptText, imagesResolved.sendOpts);
|
|
39003
|
+
const promptDurationMs = Date.now() - promptStartedAt;
|
|
39004
|
+
if (promptDurationMs >= SLOW_ACP_PROMPT_MS) {
|
|
39005
|
+
log2(`[Agent] ACP session/prompt completed after ${promptDurationMs}ms.`);
|
|
39006
|
+
}
|
|
38956
39007
|
await finalizeAndSendPromptResult({
|
|
38957
39008
|
result,
|
|
38958
39009
|
sessionId,
|
|
@@ -41478,11 +41529,11 @@ function tryConsumeBinaryProxyBody(raw, deps) {
|
|
|
41478
41529
|
if (!PROXY_ID_RE.test(id)) return false;
|
|
41479
41530
|
const body = raw.slice(PROXY_ID_BYTES);
|
|
41480
41531
|
const bodyBytes = body.length > 0 ? new Uint8Array(body) : new Uint8Array(0);
|
|
41481
|
-
const
|
|
41482
|
-
if (
|
|
41532
|
+
const pending2 = deps.pendingProxyBody.get(id);
|
|
41533
|
+
if (pending2) {
|
|
41483
41534
|
deps.pendingProxyBody.delete(id);
|
|
41484
41535
|
deps.startStreamingProxy({
|
|
41485
|
-
...
|
|
41536
|
+
...pending2.pr,
|
|
41486
41537
|
body: bodyBytes.length > 0 ? bodyBytes : void 0
|
|
41487
41538
|
});
|
|
41488
41539
|
return true;
|
|
@@ -41875,9 +41926,9 @@ function processHeartbeatAck(params) {
|
|
|
41875
41926
|
if (awaitingSeq === null) return { awaitingSeq, missed: 0 };
|
|
41876
41927
|
if (!Number.isFinite(seq)) return { awaitingSeq, missed: 0 };
|
|
41877
41928
|
const ack = Math.trunc(seq);
|
|
41878
|
-
const
|
|
41879
|
-
if (ack <
|
|
41880
|
-
if (ack ===
|
|
41929
|
+
const pending2 = awaitingSeq;
|
|
41930
|
+
if (ack < pending2) return { awaitingSeq, missed: 0 };
|
|
41931
|
+
if (ack === pending2) {
|
|
41881
41932
|
recordRtt(Date.now() - sentAtMs);
|
|
41882
41933
|
}
|
|
41883
41934
|
return { awaitingSeq: null, missed: 0 };
|
|
@@ -49525,9 +49576,13 @@ import * as fs50 from "node:fs";
|
|
|
49525
49576
|
import * as path71 from "node:path";
|
|
49526
49577
|
|
|
49527
49578
|
// src/git/snapshot/git.ts
|
|
49579
|
+
var SNAPSHOT_GIT_TIMEOUT_MS = 5e3;
|
|
49528
49580
|
async function gitStashCreate(repoRoot, log2) {
|
|
49529
49581
|
try {
|
|
49530
|
-
const { stdout } = await execGitFile(["stash", "create"], {
|
|
49582
|
+
const { stdout } = await execGitFile(["stash", "create"], {
|
|
49583
|
+
cwd: repoRoot,
|
|
49584
|
+
timeout: SNAPSHOT_GIT_TIMEOUT_MS
|
|
49585
|
+
});
|
|
49531
49586
|
return stdout.trim();
|
|
49532
49587
|
} catch (e) {
|
|
49533
49588
|
log2(
|
|
@@ -49538,7 +49593,10 @@ async function gitStashCreate(repoRoot, log2) {
|
|
|
49538
49593
|
}
|
|
49539
49594
|
async function gitUntrackedPaths(repoRoot, log2) {
|
|
49540
49595
|
try {
|
|
49541
|
-
const { stdout } = await execGitFile(["ls-files", "--others", "--exclude-standard"], {
|
|
49596
|
+
const { stdout } = await execGitFile(["ls-files", "--others", "--exclude-standard"], {
|
|
49597
|
+
cwd: repoRoot,
|
|
49598
|
+
timeout: SNAPSHOT_GIT_TIMEOUT_MS
|
|
49599
|
+
});
|
|
49542
49600
|
return stdout.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
49543
49601
|
} catch (e) {
|
|
49544
49602
|
log2(
|
|
@@ -52223,28 +52281,78 @@ async function startPromptQueueRuns(entries, deps) {
|
|
|
52223
52281
|
}
|
|
52224
52282
|
|
|
52225
52283
|
// src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
|
|
52284
|
+
var SLOW_QUEUE_SYNC_MS = 2e3;
|
|
52226
52285
|
async function applyPromptQueueStateFromServer(msg, deps) {
|
|
52227
52286
|
const raw = msg.queues;
|
|
52228
52287
|
if (!raw || typeof raw !== "object") return;
|
|
52288
|
+
const startedAt = Date.now();
|
|
52229
52289
|
const entries = promptQueueSnapshotEntries(raw);
|
|
52230
52290
|
await persistPromptQueueSnapshot(entries);
|
|
52231
52291
|
await handlePromptQueueCancellations(entries, deps);
|
|
52232
52292
|
const started = await startPromptQueueRuns(entries, deps);
|
|
52233
52293
|
await dispatchStartedPromptQueueRuns(entries, started, deps);
|
|
52294
|
+
const durationMs = Date.now() - startedAt;
|
|
52295
|
+
if (durationMs >= SLOW_QUEUE_SYNC_MS) {
|
|
52296
|
+
deps.log(`[Queue] Queue state sync and dispatch took ${durationMs}ms.`);
|
|
52297
|
+
}
|
|
52298
|
+
}
|
|
52299
|
+
|
|
52300
|
+
// src/agents/acp/from-bridge/pending-prompt-results.ts
|
|
52301
|
+
var pending = [];
|
|
52302
|
+
function enqueuePendingPromptResult(message) {
|
|
52303
|
+
const runId = typeof message.runId === "string" ? message.runId : "";
|
|
52304
|
+
if (runId) {
|
|
52305
|
+
const idx = pending.findIndex((m) => m.runId === runId);
|
|
52306
|
+
if (idx >= 0) pending.splice(idx, 1);
|
|
52307
|
+
}
|
|
52308
|
+
pending.push(message);
|
|
52309
|
+
}
|
|
52310
|
+
function flushPendingPromptResults(getWs, encrypt) {
|
|
52311
|
+
if (pending.length === 0) return;
|
|
52312
|
+
const ws = getWs();
|
|
52313
|
+
if (!ws || ws.readyState !== wrapper_default.OPEN) return;
|
|
52314
|
+
const still = [];
|
|
52315
|
+
for (const message of pending) {
|
|
52316
|
+
const wire = encrypt ? encrypt(message) : message;
|
|
52317
|
+
if (!sendWsMessage(ws, wire)) still.push(message);
|
|
52318
|
+
}
|
|
52319
|
+
pending.length = 0;
|
|
52320
|
+
pending.push(...still);
|
|
52321
|
+
}
|
|
52322
|
+
|
|
52323
|
+
// src/agents/acp/from-bridge/send-session-update-wire.ts
|
|
52324
|
+
function sendSessionUpdateWire(getWs, payload, opts) {
|
|
52325
|
+
const s = getWs();
|
|
52326
|
+
if (!s || s.readyState !== wrapper_default.OPEN) {
|
|
52327
|
+
opts.log("[Bridge service] Session update not sent: not connected to the bridge.");
|
|
52328
|
+
return;
|
|
52329
|
+
}
|
|
52330
|
+
const p = payload;
|
|
52331
|
+
const wire = p.type === "session_update" && opts.e2ee ? opts.e2ee.encryptFields(payload, ["payload"]) : p.type === "session_file_change" && opts.e2ee ? opts.e2ee.encryptFields(payload, [
|
|
52332
|
+
"path",
|
|
52333
|
+
"oldText",
|
|
52334
|
+
"newText",
|
|
52335
|
+
"patchContent",
|
|
52336
|
+
"isDirectory",
|
|
52337
|
+
"directoryRemoved"
|
|
52338
|
+
]) : payload;
|
|
52339
|
+
sendWsMessage(s, wire);
|
|
52234
52340
|
}
|
|
52235
52341
|
|
|
52236
52342
|
// src/agents/acp/from-bridge/bridge-prompt-wiring.ts
|
|
52237
52343
|
function createBridgePromptSenders(deps, getWs) {
|
|
52238
52344
|
const sendBridgeMessage = (message, encryptedFields = []) => {
|
|
52239
52345
|
const s = getWs();
|
|
52240
|
-
if (!s) return false;
|
|
52346
|
+
if (!s || s.readyState !== wrapper_default.OPEN) return false;
|
|
52241
52347
|
const wire = deps.e2ee && encryptedFields.length > 0 ? deps.e2ee.encryptFields(message, encryptedFields) : message;
|
|
52242
|
-
sendWsMessage(s, wire);
|
|
52243
|
-
return true;
|
|
52348
|
+
return sendWsMessage(s, wire);
|
|
52244
52349
|
};
|
|
52245
52350
|
const sendResult = (result) => {
|
|
52246
|
-
const
|
|
52247
|
-
|
|
52351
|
+
const sent = sendBridgeMessage(result, result.type === "prompt_result" ? ["output", "error"] : []);
|
|
52352
|
+
if (!sent && result.type === "prompt_result") {
|
|
52353
|
+
enqueuePendingPromptResult(result);
|
|
52354
|
+
deps.log("[Bridge service] prompt_result deferred until bridge reconnect.");
|
|
52355
|
+
}
|
|
52248
52356
|
if (result.type === "prompt_result") {
|
|
52249
52357
|
const pr = result;
|
|
52250
52358
|
const cancelled = pr.stopReason === "cancelled";
|
|
@@ -52257,24 +52365,11 @@ function createBridgePromptSenders(deps, getWs) {
|
|
|
52257
52365
|
});
|
|
52258
52366
|
}
|
|
52259
52367
|
};
|
|
52260
|
-
|
|
52261
|
-
|
|
52262
|
-
|
|
52263
|
-
|
|
52264
|
-
return;
|
|
52265
|
-
}
|
|
52266
|
-
const p = payload;
|
|
52267
|
-
const wire = p.type === "session_update" && deps.e2ee ? deps.e2ee.encryptFields(payload, ["payload"]) : p.type === "session_file_change" && deps.e2ee ? deps.e2ee.encryptFields(payload, [
|
|
52268
|
-
"path",
|
|
52269
|
-
"oldText",
|
|
52270
|
-
"newText",
|
|
52271
|
-
"patchContent",
|
|
52272
|
-
"isDirectory",
|
|
52273
|
-
"directoryRemoved"
|
|
52274
|
-
]) : payload;
|
|
52275
|
-
sendWsMessage(s, wire);
|
|
52368
|
+
return {
|
|
52369
|
+
sendBridgeMessage,
|
|
52370
|
+
sendResult,
|
|
52371
|
+
sendSessionUpdate: (payload) => sendSessionUpdateWire(getWs, payload, { e2ee: deps.e2ee, log: deps.log })
|
|
52276
52372
|
};
|
|
52277
|
-
return { sendBridgeMessage, sendResult, sendSessionUpdate };
|
|
52278
52373
|
}
|
|
52279
52374
|
|
|
52280
52375
|
// src/agents/acp/from-bridge/handle-bridge-prompt/parse-bridge-attachments.ts
|
|
@@ -52307,59 +52402,93 @@ function parseWorktreeBaseBranches(msg) {
|
|
|
52307
52402
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
52308
52403
|
}
|
|
52309
52404
|
|
|
52310
|
-
// src/agents/acp/from-bridge/
|
|
52405
|
+
// src/agents/acp/from-bridge/parse-follow-up-prompt-fields.ts
|
|
52406
|
+
function parseFollowUpFieldsFromPromptMessage(msg) {
|
|
52407
|
+
const value = msg.followUpCatalogPromptId;
|
|
52408
|
+
return {
|
|
52409
|
+
followUpCatalogPromptId: typeof value === "string" && value.trim() !== "" ? value.trim() : null
|
|
52410
|
+
};
|
|
52411
|
+
}
|
|
52412
|
+
|
|
52413
|
+
// src/agents/acp/from-bridge/prepare-bridge-prompt-git-state.ts
|
|
52311
52414
|
import { execFile as execFile8 } from "node:child_process";
|
|
52312
52415
|
import { promisify as promisify9 } from "node:util";
|
|
52416
|
+
|
|
52417
|
+
// src/agents/acp/from-bridge/git-state-preparation-timeout.ts
|
|
52418
|
+
async function awaitGitStatePreparation(options) {
|
|
52419
|
+
const { label, timeoutMs, work, fallback, log: log2 } = options;
|
|
52420
|
+
let timer;
|
|
52421
|
+
try {
|
|
52422
|
+
return await Promise.race([
|
|
52423
|
+
work,
|
|
52424
|
+
new Promise((resolve37) => {
|
|
52425
|
+
timer = setTimeout(() => {
|
|
52426
|
+
log2(`[Agent] ${label} exceeded ${timeoutMs}ms; continuing without it.`);
|
|
52427
|
+
resolve37(fallback);
|
|
52428
|
+
}, timeoutMs);
|
|
52429
|
+
timer.unref?.();
|
|
52430
|
+
})
|
|
52431
|
+
]);
|
|
52432
|
+
} finally {
|
|
52433
|
+
if (timer) clearTimeout(timer);
|
|
52434
|
+
}
|
|
52435
|
+
}
|
|
52436
|
+
|
|
52437
|
+
// src/agents/acp/from-bridge/prepare-bridge-prompt-git-state.ts
|
|
52313
52438
|
var execFileAsync7 = promisify9(execFile8);
|
|
52439
|
+
var GIT_STATE_DISCOVERY_TIMEOUT_MS = 2e3;
|
|
52314
52440
|
async function readGitBranch(cwd) {
|
|
52315
52441
|
try {
|
|
52316
|
-
const { stdout } = await execFileAsync7("git", ["branch", "--show-current"], {
|
|
52317
|
-
|
|
52318
|
-
|
|
52442
|
+
const { stdout } = await execFileAsync7("git", ["branch", "--show-current"], {
|
|
52443
|
+
cwd,
|
|
52444
|
+
maxBuffer: 64 * 1024,
|
|
52445
|
+
timeout: GIT_STATE_DISCOVERY_TIMEOUT_MS
|
|
52446
|
+
});
|
|
52447
|
+
return stdout.trim() || null;
|
|
52319
52448
|
} catch {
|
|
52320
52449
|
return null;
|
|
52321
52450
|
}
|
|
52322
52451
|
}
|
|
52323
|
-
async function
|
|
52452
|
+
async function prepareBridgePromptGitState(params) {
|
|
52324
52453
|
const { getWs, log: log2, sessionWorktreeManager, sessionId, runId, effectiveCwd } = params;
|
|
52325
|
-
const
|
|
52326
|
-
|
|
52454
|
+
const repoCheckoutPaths = await awaitGitStatePreparation({
|
|
52455
|
+
label: "Session worktree discovery",
|
|
52456
|
+
timeoutMs: GIT_STATE_DISCOVERY_TIMEOUT_MS,
|
|
52457
|
+
work: sessionWorktreeManager.ensureRepoCheckoutPathsForSessionAsync(sessionId),
|
|
52458
|
+
fallback: void 0,
|
|
52459
|
+
log: log2
|
|
52460
|
+
});
|
|
52327
52461
|
const repoRoots = await resolveSnapshotRepoRoots({
|
|
52328
52462
|
worktreePaths: repoCheckoutPaths,
|
|
52329
52463
|
fallbackCwd: effectiveCwd,
|
|
52330
52464
|
sessionId: sessionId?.trim() || void 0,
|
|
52331
52465
|
log: log2
|
|
52332
52466
|
});
|
|
52333
|
-
|
|
52334
|
-
|
|
52335
|
-
const
|
|
52336
|
-
|
|
52337
|
-
sendWsMessage(s, {
|
|
52467
|
+
const socket = getWs();
|
|
52468
|
+
if (socket && sessionId) {
|
|
52469
|
+
const usesWorktree = sessionWorktreeManager.usesWorktreeSession(sessionId);
|
|
52470
|
+
sendWsMessage(socket, {
|
|
52338
52471
|
type: "session_git_context_report",
|
|
52339
52472
|
sessionId,
|
|
52340
|
-
cliGitBranch,
|
|
52341
|
-
agentUsesWorktree:
|
|
52342
|
-
sessionParent:
|
|
52343
|
-
sessionParentPath:
|
|
52473
|
+
cliGitBranch: repoRoots.length > 0 ? await readGitBranch(effectiveCwd) : null,
|
|
52474
|
+
agentUsesWorktree: usesWorktree,
|
|
52475
|
+
sessionParent: usesWorktree ? "worktrees_root" : "bridge_root",
|
|
52476
|
+
sessionParentPath: usesWorktree ? sessionWorktreeManager.getIsolatedSessionParentPathForSession(sessionId) ?? effectiveCwd : getBridgeRoot()
|
|
52344
52477
|
});
|
|
52345
52478
|
}
|
|
52346
|
-
if (
|
|
52347
|
-
const
|
|
52348
|
-
sendWsMessage(
|
|
52479
|
+
if (socket && sessionId && runId) {
|
|
52480
|
+
const snapshot = repoRoots.length > 0 ? await capturePreTurnSnapshot({ runId, repoRoots, agentCwd: effectiveCwd, log: log2 }) : { ok: false };
|
|
52481
|
+
sendWsMessage(socket, {
|
|
52349
52482
|
type: "pre_turn_snapshot_report",
|
|
52350
52483
|
sessionId,
|
|
52351
52484
|
turnId: runId,
|
|
52352
|
-
captured:
|
|
52485
|
+
captured: snapshot.ok
|
|
52353
52486
|
});
|
|
52354
52487
|
}
|
|
52355
52488
|
}
|
|
52356
|
-
function parseFollowUpFieldsFromPromptMessage(msg) {
|
|
52357
|
-
const followUpCatalogPromptId = typeof msg.followUpCatalogPromptId === "string" && msg.followUpCatalogPromptId.trim() !== "" ? msg.followUpCatalogPromptId.trim() : null;
|
|
52358
|
-
return { followUpCatalogPromptId };
|
|
52359
|
-
}
|
|
52360
52489
|
|
|
52361
|
-
// src/agents/acp/from-bridge/handle-bridge-prompt/
|
|
52362
|
-
async function
|
|
52490
|
+
// src/agents/acp/from-bridge/handle-bridge-prompt/prepare-git-state-and-run-prompt.ts
|
|
52491
|
+
async function prepareGitStateAndRunPrompt(params) {
|
|
52363
52492
|
const {
|
|
52364
52493
|
deps,
|
|
52365
52494
|
msg,
|
|
@@ -52378,7 +52507,7 @@ async function runPreambleAndPrompt(params) {
|
|
|
52378
52507
|
senders: { sendResult, sendSessionUpdate }
|
|
52379
52508
|
} = params;
|
|
52380
52509
|
const effectiveCwd = resolveSessionParentPathForAgentProcess(resolvedCwd);
|
|
52381
|
-
await
|
|
52510
|
+
await prepareBridgePromptGitState({
|
|
52382
52511
|
getWs,
|
|
52383
52512
|
log: log2,
|
|
52384
52513
|
sessionWorktreeManager,
|
|
@@ -52449,7 +52578,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
52449
52578
|
sessionParentPath,
|
|
52450
52579
|
...worktreeBaseBranches ? { worktreeBaseBranches } : {}
|
|
52451
52580
|
}).then(
|
|
52452
|
-
(cwd) =>
|
|
52581
|
+
(cwd) => prepareGitStateAndRunPrompt({
|
|
52453
52582
|
deps,
|
|
52454
52583
|
msg,
|
|
52455
52584
|
getWs,
|
|
@@ -52468,7 +52597,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
52468
52597
|
})
|
|
52469
52598
|
).catch((err) => {
|
|
52470
52599
|
log2(`[Agent] Session parent path resolve failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
52471
|
-
void
|
|
52600
|
+
void prepareGitStateAndRunPrompt({
|
|
52472
52601
|
deps,
|
|
52473
52602
|
msg,
|
|
52474
52603
|
getWs,
|
|
@@ -53124,25 +53253,59 @@ var handleInstallSkillsMessage = (msg, deps) => {
|
|
|
53124
53253
|
})();
|
|
53125
53254
|
};
|
|
53126
53255
|
|
|
53127
|
-
// src/agents/install/
|
|
53128
|
-
import {
|
|
53129
|
-
import
|
|
53130
|
-
|
|
53131
|
-
|
|
53132
|
-
|
|
53133
|
-
|
|
53134
|
-
|
|
53256
|
+
// src/agents/install/run-streaming-command.ts
|
|
53257
|
+
import { spawn as spawn11 } from "node:child_process";
|
|
53258
|
+
import * as readline3 from "node:readline";
|
|
53259
|
+
function runStreamingCommand(command, args, options) {
|
|
53260
|
+
return new Promise((resolve37, reject) => {
|
|
53261
|
+
const child = spawn11(command, args, {
|
|
53262
|
+
env: options.env,
|
|
53263
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
53264
|
+
});
|
|
53265
|
+
let settled = false;
|
|
53266
|
+
const timer = options.timeoutMs != null ? setTimeout(() => {
|
|
53267
|
+
child.kill("SIGKILL");
|
|
53268
|
+
if (!settled) {
|
|
53269
|
+
settled = true;
|
|
53270
|
+
reject(new Error(`Command timed out after ${options.timeoutMs}ms`));
|
|
53271
|
+
}
|
|
53272
|
+
}, options.timeoutMs) : null;
|
|
53273
|
+
const onLine = (line) => {
|
|
53274
|
+
if (line.length > 0) options.onLine?.(line);
|
|
53275
|
+
};
|
|
53276
|
+
if (child.stdout) {
|
|
53277
|
+
readline3.createInterface({ input: child.stdout, crlfDelay: Infinity }).on("line", onLine);
|
|
53278
|
+
}
|
|
53279
|
+
if (child.stderr) {
|
|
53280
|
+
readline3.createInterface({ input: child.stderr, crlfDelay: Infinity }).on("line", onLine);
|
|
53281
|
+
}
|
|
53282
|
+
child.on("error", (err) => {
|
|
53283
|
+
if (timer) clearTimeout(timer);
|
|
53284
|
+
if (!settled) {
|
|
53285
|
+
settled = true;
|
|
53286
|
+
reject(err);
|
|
53287
|
+
}
|
|
53288
|
+
});
|
|
53289
|
+
child.on("close", (code, signal) => {
|
|
53290
|
+
if (timer) clearTimeout(timer);
|
|
53291
|
+
if (!settled) {
|
|
53292
|
+
settled = true;
|
|
53293
|
+
resolve37({ code, signal });
|
|
53294
|
+
}
|
|
53295
|
+
});
|
|
53296
|
+
});
|
|
53135
53297
|
}
|
|
53136
53298
|
|
|
53137
53299
|
// src/agents/install/commands/run-npm-global-install.ts
|
|
53138
|
-
|
|
53139
|
-
|
|
53140
|
-
const { stdout, stderr } = await execFileAsync8("npm", ["install", "-g", packageName], {
|
|
53141
|
-
timeout: timeoutMs,
|
|
53300
|
+
async function runNpmGlobalInstall(packageName, env, options) {
|
|
53301
|
+
const result = await runStreamingCommand("npm", ["install", "-g", packageName], {
|
|
53142
53302
|
env: bridgeAgentPathEnv(env),
|
|
53143
|
-
|
|
53303
|
+
timeoutMs: options?.timeoutMs ?? 3e5,
|
|
53304
|
+
onLine: options?.onLine
|
|
53144
53305
|
});
|
|
53145
|
-
|
|
53306
|
+
if (result.code !== 0) {
|
|
53307
|
+
throw new Error(`npm install -g ${packageName} failed (exit ${result.code ?? "signal"})`);
|
|
53308
|
+
}
|
|
53146
53309
|
}
|
|
53147
53310
|
|
|
53148
53311
|
// src/agents/install/commands/claude-code.ts
|
|
@@ -53150,11 +53313,12 @@ var claudeCodeInstallCommand = {
|
|
|
53150
53313
|
agentType: "claude-code",
|
|
53151
53314
|
detectCommand: "claude",
|
|
53152
53315
|
async install(ctx) {
|
|
53153
|
-
|
|
53154
|
-
|
|
53155
|
-
|
|
53156
|
-
|
|
53157
|
-
|
|
53316
|
+
ctx.onProgress?.("Installing Anthropic Claude Code");
|
|
53317
|
+
await runNpmGlobalInstall(
|
|
53318
|
+
"@anthropic-ai/claude-code",
|
|
53319
|
+
{ ...ctx.env, ANTHROPIC_API_KEY: ctx.authToken },
|
|
53320
|
+
{ onLine: (line) => ctx.onProgress?.("Installing Anthropic Claude Code", line) }
|
|
53321
|
+
);
|
|
53158
53322
|
}
|
|
53159
53323
|
};
|
|
53160
53324
|
|
|
@@ -53163,34 +53327,34 @@ var codexAcpInstallCommand = {
|
|
|
53163
53327
|
agentType: "codex-acp",
|
|
53164
53328
|
detectCommand: "codex",
|
|
53165
53329
|
async install(ctx) {
|
|
53166
|
-
|
|
53167
|
-
|
|
53168
|
-
|
|
53169
|
-
|
|
53170
|
-
|
|
53330
|
+
ctx.onProgress?.("Installing Codex");
|
|
53331
|
+
await runNpmGlobalInstall(
|
|
53332
|
+
"@openai/codex",
|
|
53333
|
+
{ ...ctx.env, OPENAI_API_KEY: ctx.authToken },
|
|
53334
|
+
{ onLine: (line) => ctx.onProgress?.("Installing Codex", line) }
|
|
53335
|
+
);
|
|
53171
53336
|
}
|
|
53172
53337
|
};
|
|
53173
53338
|
|
|
53174
53339
|
// src/agents/install/commands/cursor-cli.ts
|
|
53175
|
-
import { execFile as execFile10 } from "node:child_process";
|
|
53176
|
-
import { promisify as promisify11 } from "node:util";
|
|
53177
|
-
var execFileAsync9 = promisify11(execFile10);
|
|
53178
53340
|
var cursorCliInstallCommand = {
|
|
53179
53341
|
agentType: "cursor-cli",
|
|
53180
53342
|
detectCommand: "agent",
|
|
53181
53343
|
alternateDetectCommands: ["cursor-agent"],
|
|
53182
53344
|
async install(ctx) {
|
|
53183
|
-
|
|
53345
|
+
ctx.onProgress?.("Installing Cursor CLI");
|
|
53346
|
+
const result = await runStreamingCommand(
|
|
53184
53347
|
"bash",
|
|
53185
53348
|
["-lc", "curl -fsSL https://cursor.com/install | bash"],
|
|
53186
53349
|
{
|
|
53187
|
-
|
|
53350
|
+
timeoutMs: 3e5,
|
|
53188
53351
|
env: { ...bridgeAgentPathEnv(ctx.env), CURSOR_API_KEY: ctx.authToken },
|
|
53189
|
-
|
|
53352
|
+
onLine: (line) => ctx.onProgress?.("Installing Cursor CLI", line)
|
|
53190
53353
|
}
|
|
53191
53354
|
);
|
|
53192
|
-
|
|
53193
|
-
|
|
53355
|
+
if (result.code !== 0) {
|
|
53356
|
+
throw new Error(`Cursor CLI install failed (exit ${result.code ?? "signal"})`);
|
|
53357
|
+
}
|
|
53194
53358
|
}
|
|
53195
53359
|
};
|
|
53196
53360
|
|
|
@@ -53199,11 +53363,12 @@ var opencodeInstallCommand = {
|
|
|
53199
53363
|
agentType: "opencode",
|
|
53200
53364
|
detectCommand: "opencode",
|
|
53201
53365
|
async install(ctx) {
|
|
53202
|
-
|
|
53203
|
-
|
|
53204
|
-
|
|
53205
|
-
|
|
53206
|
-
|
|
53366
|
+
ctx.onProgress?.("Installing OpenCode");
|
|
53367
|
+
await runNpmGlobalInstall(
|
|
53368
|
+
"opencode-ai",
|
|
53369
|
+
{ ...ctx.env, OPENCODE_API_KEY: ctx.authToken },
|
|
53370
|
+
{ onLine: (line) => ctx.onProgress?.("Installing OpenCode", line) }
|
|
53371
|
+
);
|
|
53207
53372
|
}
|
|
53208
53373
|
};
|
|
53209
53374
|
|
|
@@ -53264,25 +53429,47 @@ var handleInstallAgentMessage = (msg, deps) => {
|
|
|
53264
53429
|
if (!processId || !agentId || !tokenId || !agentType || !authToken) return;
|
|
53265
53430
|
void (async () => {
|
|
53266
53431
|
const socket = deps.getWs();
|
|
53267
|
-
|
|
53268
|
-
|
|
53269
|
-
|
|
53270
|
-
|
|
53271
|
-
|
|
53272
|
-
|
|
53273
|
-
|
|
53274
|
-
|
|
53275
|
-
|
|
53276
|
-
|
|
53277
|
-
|
|
53278
|
-
|
|
53432
|
+
let pendingLines = [];
|
|
53433
|
+
let flushTimer = null;
|
|
53434
|
+
const sendProgress = (message, logOutput) => {
|
|
53435
|
+
if (!socket) return;
|
|
53436
|
+
sendWsMessage(socket, {
|
|
53437
|
+
type: "install_agent_progress",
|
|
53438
|
+
processId,
|
|
53439
|
+
agentId,
|
|
53440
|
+
tokenId,
|
|
53441
|
+
agentType,
|
|
53442
|
+
step: "agent_install_package",
|
|
53443
|
+
message,
|
|
53444
|
+
...logOutput ? { logOutput } : {}
|
|
53445
|
+
});
|
|
53446
|
+
};
|
|
53447
|
+
const flushLines = (message) => {
|
|
53448
|
+
if (flushTimer) {
|
|
53449
|
+
clearTimeout(flushTimer);
|
|
53450
|
+
flushTimer = null;
|
|
53279
53451
|
}
|
|
53452
|
+
if (pendingLines.length === 0) return;
|
|
53453
|
+
const logOutput = pendingLines.join("\n");
|
|
53454
|
+
pendingLines = [];
|
|
53455
|
+
sendProgress(message, logOutput);
|
|
53280
53456
|
};
|
|
53281
53457
|
const result = await installLocalAgentOnBridge({
|
|
53282
53458
|
agentType,
|
|
53283
53459
|
authToken,
|
|
53284
|
-
onProgress: (message, logOutput) =>
|
|
53460
|
+
onProgress: (message, logOutput) => {
|
|
53461
|
+
if (logOutput == null) {
|
|
53462
|
+
flushLines(message);
|
|
53463
|
+
sendProgress(message);
|
|
53464
|
+
return;
|
|
53465
|
+
}
|
|
53466
|
+
pendingLines.push(logOutput);
|
|
53467
|
+
if (!flushTimer) {
|
|
53468
|
+
flushTimer = setTimeout(() => flushLines(message), 100);
|
|
53469
|
+
}
|
|
53470
|
+
}
|
|
53285
53471
|
});
|
|
53472
|
+
flushLines("Installing agent packages on the bridge machine.");
|
|
53286
53473
|
if (socket) {
|
|
53287
53474
|
sendWsMessage(socket, {
|
|
53288
53475
|
type: "install_agent_result",
|
|
@@ -53294,9 +53481,7 @@ var handleInstallAgentMessage = (msg, deps) => {
|
|
|
53294
53481
|
error: result.error
|
|
53295
53482
|
});
|
|
53296
53483
|
}
|
|
53297
|
-
if (result.success)
|
|
53298
|
-
await deps.reportAutoDetectedAgents?.();
|
|
53299
|
-
}
|
|
53484
|
+
if (result.success) await deps.reportAutoDetectedAgents?.();
|
|
53300
53485
|
if (!result.success) {
|
|
53301
53486
|
deps.log(`[Bridge service] Install agent failed: ${result.error ?? "unknown"}`);
|
|
53302
53487
|
}
|
|
@@ -53881,6 +54066,10 @@ function createMainBridgeOpenHandler(params) {
|
|
|
53881
54066
|
if (socket) {
|
|
53882
54067
|
sendBridgeIdentify(socket, { identifyReportedPaths, e2ee });
|
|
53883
54068
|
reportGitRepos(getWs, logFn);
|
|
54069
|
+
flushPendingPromptResults(
|
|
54070
|
+
getWs,
|
|
54071
|
+
(message) => e2ee ? e2ee.encryptFields(message, ["output", "error"]) : message
|
|
54072
|
+
);
|
|
53884
54073
|
try {
|
|
53885
54074
|
onBridgeSocketOpen?.();
|
|
53886
54075
|
} catch {
|
|
@@ -54025,7 +54214,7 @@ async function createBridgeConnection(options) {
|
|
|
54025
54214
|
}
|
|
54026
54215
|
|
|
54027
54216
|
// src/e2e-certificates/key-command.ts
|
|
54028
|
-
import * as
|
|
54217
|
+
import * as readline4 from "node:readline";
|
|
54029
54218
|
function installE2eCertificateKeyCommand({
|
|
54030
54219
|
log: log2,
|
|
54031
54220
|
onOpenCertificate,
|
|
@@ -54036,7 +54225,7 @@ function installE2eCertificateKeyCommand({
|
|
|
54036
54225
|
return () => {
|
|
54037
54226
|
};
|
|
54038
54227
|
}
|
|
54039
|
-
|
|
54228
|
+
readline4.emitKeypressEvents(process.stdin);
|
|
54040
54229
|
process.stdin.setRawMode(true);
|
|
54041
54230
|
process.stdin.resume();
|
|
54042
54231
|
const onKeypress = (str, key) => {
|