@buildautomaton/cli 0.1.76 → 0.1.78
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 +330 -220
- package/dist/cli.js.map +4 -4
- package/dist/index.js +330 -220
- 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/index.js
CHANGED
|
@@ -23060,7 +23060,11 @@ var init_migrate_cli_sqlite = __esm({
|
|
|
23060
23060
|
});
|
|
23061
23061
|
|
|
23062
23062
|
// src/sqlite/cli-database.ts
|
|
23063
|
-
|
|
23063
|
+
function closeAllCliSqliteConnections() {
|
|
23064
|
+
legacyImportDoneForPath = null;
|
|
23065
|
+
cliSqlite.closeAllConnections();
|
|
23066
|
+
}
|
|
23067
|
+
var legacyImportDoneForPath, cliSqlite, safeCloseCliSqliteDatabase, openCliSqliteConnection, withCliSqliteSync, withCliSqlite, ensureCliSqliteInitialized;
|
|
23064
23068
|
var init_cli_database = __esm({
|
|
23065
23069
|
"src/sqlite/cli-database.ts"() {
|
|
23066
23070
|
"use strict";
|
|
@@ -23070,16 +23074,19 @@ var init_cli_database = __esm({
|
|
|
23070
23074
|
init_import_cli_legacy_disk_data();
|
|
23071
23075
|
init_migrate_cli_sqlite();
|
|
23072
23076
|
init_sqlite_errors();
|
|
23077
|
+
legacyImportDoneForPath = null;
|
|
23073
23078
|
cliSqlite = createSqliteDatabaseAccess({
|
|
23074
23079
|
getPath: getCliSqlitePath,
|
|
23075
23080
|
ensureParentDir: ensureCliSqliteParentDir,
|
|
23076
23081
|
migrate: migrateCliSqlite,
|
|
23077
23082
|
afterOpen: (db, options) => {
|
|
23083
|
+
const sqlitePath = getCliSqlitePath();
|
|
23084
|
+
if (legacyImportDoneForPath === sqlitePath) return;
|
|
23078
23085
|
importCliSqliteLegacyDiskData(db, options?.logLegacyMigration);
|
|
23086
|
+
legacyImportDoneForPath = sqlitePath;
|
|
23079
23087
|
}
|
|
23080
23088
|
});
|
|
23081
23089
|
safeCloseCliSqliteDatabase = cliSqlite.safeClose;
|
|
23082
|
-
closeAllCliSqliteConnections = cliSqlite.closeAllConnections;
|
|
23083
23090
|
openCliSqliteConnection = cliSqlite.openConnection;
|
|
23084
23091
|
withCliSqliteSync = cliSqlite.withSync;
|
|
23085
23092
|
withCliSqlite = cliSqlite.withAsync;
|
|
@@ -30606,7 +30613,7 @@ function installBridgeProcessResilience() {
|
|
|
30606
30613
|
}
|
|
30607
30614
|
|
|
30608
30615
|
// src/cli-version.ts
|
|
30609
|
-
var CLI_VERSION = "0.1.
|
|
30616
|
+
var CLI_VERSION = "0.1.78".length > 0 ? "0.1.78" : "0.0.0-dev";
|
|
30610
30617
|
|
|
30611
30618
|
// src/connection/heartbeat/constants.ts
|
|
30612
30619
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -33224,9 +33231,12 @@ function cancelPendingCursorPermissionRequests(pendingRequests2, respond) {
|
|
|
33224
33231
|
// src/agents/acp/clients/cursor/create-cursor-acp-handle.ts
|
|
33225
33232
|
function createCursorAcpHandle(options) {
|
|
33226
33233
|
let teardownStarted = false;
|
|
33234
|
+
let cancelFallback = null;
|
|
33227
33235
|
async function disconnectGracefully() {
|
|
33228
33236
|
if (teardownStarted) return;
|
|
33229
33237
|
teardownStarted = true;
|
|
33238
|
+
if (cancelFallback) clearTimeout(cancelFallback);
|
|
33239
|
+
cancelFallback = null;
|
|
33230
33240
|
cancelPendingCursorPermissionRequests(options.pendingRequests, options.wire.respond);
|
|
33231
33241
|
try {
|
|
33232
33242
|
await options.transport.cancelSession(options.sessionId);
|
|
@@ -33252,7 +33262,17 @@ function createCursorAcpHandle(options) {
|
|
|
33252
33262
|
},
|
|
33253
33263
|
async cancel() {
|
|
33254
33264
|
cancelPendingCursorPermissionRequests(options.pendingRequests, options.wire.respond);
|
|
33255
|
-
|
|
33265
|
+
try {
|
|
33266
|
+
await options.transport.cancelSession(options.sessionId);
|
|
33267
|
+
} catch {
|
|
33268
|
+
}
|
|
33269
|
+
if (cancelFallback) return;
|
|
33270
|
+
cancelFallback = setTimeout(() => {
|
|
33271
|
+
if (options.child.exitCode == null && options.child.signalCode == null) {
|
|
33272
|
+
void disconnectGracefully();
|
|
33273
|
+
}
|
|
33274
|
+
}, 5e3);
|
|
33275
|
+
cancelFallback.unref?.();
|
|
33256
33276
|
},
|
|
33257
33277
|
resolveRequest(requestId, result) {
|
|
33258
33278
|
if (options.pendingRequests.has(requestId)) {
|
|
@@ -33807,13 +33827,15 @@ import { existsSync as existsSync4, statSync } from "node:fs";
|
|
|
33807
33827
|
// src/git/get-git-repo-root-sync.ts
|
|
33808
33828
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
33809
33829
|
import * as path27 from "node:path";
|
|
33830
|
+
var GIT_LOOKUP_TIMEOUT_MS = 2e3;
|
|
33810
33831
|
function getGitRepoRootSync(startDir) {
|
|
33811
33832
|
try {
|
|
33812
33833
|
const out = execFileSync3("git", ["rev-parse", "--show-toplevel"], {
|
|
33813
33834
|
cwd: path27.resolve(startDir),
|
|
33814
33835
|
encoding: "utf8",
|
|
33815
33836
|
stdio: ["ignore", "pipe", "ignore"],
|
|
33816
|
-
maxBuffer: 1024 * 1024
|
|
33837
|
+
maxBuffer: 1024 * 1024,
|
|
33838
|
+
timeout: GIT_LOOKUP_TIMEOUT_MS
|
|
33817
33839
|
}).trim();
|
|
33818
33840
|
return out ? path27.resolve(out) : null;
|
|
33819
33841
|
} catch {
|
|
@@ -33825,6 +33847,7 @@ function getGitRepoRootSync(startDir) {
|
|
|
33825
33847
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
33826
33848
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
33827
33849
|
import * as path28 from "node:path";
|
|
33850
|
+
var GIT_FILE_READ_TIMEOUT_MS = 2e3;
|
|
33828
33851
|
function resolveWorkspaceFilePath(sessionParentPath, rawPath) {
|
|
33829
33852
|
const trimmed2 = rawPath.trim();
|
|
33830
33853
|
if (!trimmed2) return null;
|
|
@@ -33886,7 +33909,8 @@ function readGitHeadBlob(sessionParentPath, displayPath) {
|
|
|
33886
33909
|
return execFileSync4("git", ["show", `HEAD:${displayPath}`], {
|
|
33887
33910
|
cwd: execCwd,
|
|
33888
33911
|
encoding: "utf8",
|
|
33889
|
-
maxBuffer: 50 * 1024 * 1024
|
|
33912
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
33913
|
+
timeout: GIT_FILE_READ_TIMEOUT_MS
|
|
33890
33914
|
});
|
|
33891
33915
|
} catch {
|
|
33892
33916
|
return "";
|
|
@@ -33894,6 +33918,7 @@ function readGitHeadBlob(sessionParentPath, displayPath) {
|
|
|
33894
33918
|
}
|
|
33895
33919
|
|
|
33896
33920
|
// src/agents/acp/session-file-change-path-kind.ts
|
|
33921
|
+
var GIT_PATH_KIND_TIMEOUT_MS = 2e3;
|
|
33897
33922
|
function gitHeadPathObjectType(sessionParentPath, displayPath) {
|
|
33898
33923
|
if (!displayPath || displayPath.includes("..")) return null;
|
|
33899
33924
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
@@ -33901,7 +33926,8 @@ function gitHeadPathObjectType(sessionParentPath, displayPath) {
|
|
|
33901
33926
|
try {
|
|
33902
33927
|
return execFileSync5("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
|
|
33903
33928
|
cwd: gitRoot,
|
|
33904
|
-
encoding: "utf8"
|
|
33929
|
+
encoding: "utf8",
|
|
33930
|
+
timeout: GIT_PATH_KIND_TIMEOUT_MS
|
|
33905
33931
|
}).trim();
|
|
33906
33932
|
} catch {
|
|
33907
33933
|
return null;
|
|
@@ -35008,6 +35034,73 @@ function augmentPromptResultAuthFields(agentType, errorText) {
|
|
|
35008
35034
|
return { agentAuthRequired: true, agentType };
|
|
35009
35035
|
}
|
|
35010
35036
|
|
|
35037
|
+
// src/agents/planning/submit-planning-todos-for-turn.ts
|
|
35038
|
+
var PLANNING_TODO_SUBMIT_TIMEOUT_MS = 3e3;
|
|
35039
|
+
async function submitPlanningTodosForTurn(params) {
|
|
35040
|
+
const token = params.getCloudAccessToken();
|
|
35041
|
+
if (!token.trim()) return { ok: false, error: "Missing cloud access token" };
|
|
35042
|
+
const base = params.cloudApiBaseUrl.replace(/\/$/, "");
|
|
35043
|
+
const url2 = `${base}/internal/sessions/todos/submit`;
|
|
35044
|
+
let res;
|
|
35045
|
+
try {
|
|
35046
|
+
res = await fetch(url2, {
|
|
35047
|
+
method: "POST",
|
|
35048
|
+
signal: AbortSignal.timeout(PLANNING_TODO_SUBMIT_TIMEOUT_MS),
|
|
35049
|
+
headers: {
|
|
35050
|
+
Authorization: `Bearer ${token}`,
|
|
35051
|
+
"Content-Type": "application/json"
|
|
35052
|
+
},
|
|
35053
|
+
body: JSON.stringify({
|
|
35054
|
+
sessionId: params.sessionId,
|
|
35055
|
+
turnId: params.turnId,
|
|
35056
|
+
items: params.items
|
|
35057
|
+
})
|
|
35058
|
+
});
|
|
35059
|
+
} catch (error40) {
|
|
35060
|
+
return { ok: false, error: error40 instanceof Error ? error40.message : String(error40) };
|
|
35061
|
+
}
|
|
35062
|
+
if (!res.ok) {
|
|
35063
|
+
const body = await res.json().catch(() => null);
|
|
35064
|
+
return { ok: false, error: body?.error ?? `Planning todo submit failed (${res.status})` };
|
|
35065
|
+
}
|
|
35066
|
+
return { ok: true };
|
|
35067
|
+
}
|
|
35068
|
+
|
|
35069
|
+
// src/agents/planning/maybe-submit-planning-todos-after-agent-success.ts
|
|
35070
|
+
async function maybeSubmitPlanningTodosAfterAgentSuccess(params) {
|
|
35071
|
+
const { sessionId, runId, resultSuccess, output, cloudApiBaseUrl, getCloudAccessToken, log: log2 } = params;
|
|
35072
|
+
const buffered = runId ? getPlanningSessionTurnOutput(runId) : "";
|
|
35073
|
+
const outputFromResult = typeof output === "string" ? output : "";
|
|
35074
|
+
const outputStr = buffered.trim() !== "" ? buffered : outputFromResult;
|
|
35075
|
+
if (!sessionId || !runId || !resultSuccess || outputStr.trim() === "") {
|
|
35076
|
+
return { submitted: false, suppressOutput: false };
|
|
35077
|
+
}
|
|
35078
|
+
if (!cloudApiBaseUrl || !getCloudAccessToken) {
|
|
35079
|
+
return { submitted: false, suppressOutput: false };
|
|
35080
|
+
}
|
|
35081
|
+
const items = parsePlanningTodoAgentJson(outputStr);
|
|
35082
|
+
if (items.length === 0) {
|
|
35083
|
+
return { submitted: false, suppressOutput: false };
|
|
35084
|
+
}
|
|
35085
|
+
const result = await submitPlanningTodosForTurn({
|
|
35086
|
+
sessionId,
|
|
35087
|
+
turnId: runId,
|
|
35088
|
+
items,
|
|
35089
|
+
cloudApiBaseUrl,
|
|
35090
|
+
getCloudAccessToken
|
|
35091
|
+
});
|
|
35092
|
+
if (!result.ok) {
|
|
35093
|
+
log2(`[Agent] Planning todo submit failed: ${result.error}`);
|
|
35094
|
+
return { submitted: false, suppressOutput: false };
|
|
35095
|
+
}
|
|
35096
|
+
if (runId) consumePlanningSessionTurnOutput(runId);
|
|
35097
|
+
log2(`[Agent] Planning session: stored ${items.length} todo(s) via internal API`);
|
|
35098
|
+
return { submitted: true, suppressOutput: true };
|
|
35099
|
+
}
|
|
35100
|
+
|
|
35101
|
+
// src/agents/acp/prompts/report-post-turn-enrichment.ts
|
|
35102
|
+
init_yield_to_event_loop();
|
|
35103
|
+
|
|
35011
35104
|
// src/git/git-runtime.ts
|
|
35012
35105
|
init_cli_process_interrupt();
|
|
35013
35106
|
var activeGitChildProcesses = /* @__PURE__ */ new Set();
|
|
@@ -35370,61 +35463,30 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
35370
35463
|
});
|
|
35371
35464
|
}
|
|
35372
35465
|
|
|
35373
|
-
// src/agents/
|
|
35374
|
-
|
|
35375
|
-
|
|
35376
|
-
|
|
35377
|
-
|
|
35378
|
-
|
|
35379
|
-
|
|
35380
|
-
|
|
35381
|
-
|
|
35382
|
-
|
|
35383
|
-
|
|
35384
|
-
|
|
35385
|
-
|
|
35386
|
-
|
|
35387
|
-
|
|
35388
|
-
|
|
35389
|
-
|
|
35390
|
-
|
|
35391
|
-
|
|
35392
|
-
|
|
35393
|
-
|
|
35394
|
-
}
|
|
35395
|
-
|
|
35396
|
-
}
|
|
35397
|
-
|
|
35398
|
-
// src/agents/planning/maybe-submit-planning-todos-after-agent-success.ts
|
|
35399
|
-
async function maybeSubmitPlanningTodosAfterAgentSuccess(params) {
|
|
35400
|
-
const { sessionId, runId, resultSuccess, output, cloudApiBaseUrl, getCloudAccessToken, log: log2 } = params;
|
|
35401
|
-
const buffered = runId ? getPlanningSessionTurnOutput(runId) : "";
|
|
35402
|
-
const outputFromResult = typeof output === "string" ? output : "";
|
|
35403
|
-
const outputStr = buffered.trim() !== "" ? buffered : outputFromResult;
|
|
35404
|
-
if (!sessionId || !runId || !resultSuccess || outputStr.trim() === "") {
|
|
35405
|
-
return { submitted: false, suppressOutput: false };
|
|
35406
|
-
}
|
|
35407
|
-
if (!cloudApiBaseUrl || !getCloudAccessToken) {
|
|
35408
|
-
return { submitted: false, suppressOutput: false };
|
|
35409
|
-
}
|
|
35410
|
-
const items = parsePlanningTodoAgentJson(outputStr);
|
|
35411
|
-
if (items.length === 0) {
|
|
35412
|
-
return { submitted: false, suppressOutput: false };
|
|
35413
|
-
}
|
|
35414
|
-
const result = await submitPlanningTodosForTurn({
|
|
35415
|
-
sessionId,
|
|
35416
|
-
turnId: runId,
|
|
35417
|
-
items,
|
|
35418
|
-
cloudApiBaseUrl,
|
|
35419
|
-
getCloudAccessToken
|
|
35466
|
+
// src/agents/acp/prompts/report-post-turn-enrichment.ts
|
|
35467
|
+
function reportPostTurnEnrichment(options) {
|
|
35468
|
+
void (async () => {
|
|
35469
|
+
const {
|
|
35470
|
+
sessionId,
|
|
35471
|
+
runId,
|
|
35472
|
+
agentCwd,
|
|
35473
|
+
result,
|
|
35474
|
+
sendSessionUpdate,
|
|
35475
|
+
log: log2
|
|
35476
|
+
} = options;
|
|
35477
|
+
await yieldToEventLoop();
|
|
35478
|
+
if (sessionId && runId && sendSessionUpdate && agentCwd && result.success) {
|
|
35479
|
+
await collectTurnGitDiffFromPreTurnSnapshot({
|
|
35480
|
+
sessionId,
|
|
35481
|
+
runId,
|
|
35482
|
+
agentCwd,
|
|
35483
|
+
sendSessionUpdate,
|
|
35484
|
+
log: log2
|
|
35485
|
+
});
|
|
35486
|
+
}
|
|
35487
|
+
})().catch((error40) => {
|
|
35488
|
+
options.log(`[Agent] Post-turn enrichment failed: ${error40 instanceof Error ? error40.message : String(error40)}`);
|
|
35420
35489
|
});
|
|
35421
|
-
if (!result.ok) {
|
|
35422
|
-
log2(`[Agent] Planning todo submit failed: ${result.error}`);
|
|
35423
|
-
return { submitted: false, suppressOutput: false };
|
|
35424
|
-
}
|
|
35425
|
-
if (runId) consumePlanningSessionTurnOutput(runId);
|
|
35426
|
-
log2(`[Agent] Planning session: stored ${items.length} todo(s) via internal API`);
|
|
35427
|
-
return { submitted: true, suppressOutput: true };
|
|
35428
35490
|
}
|
|
35429
35491
|
|
|
35430
35492
|
// src/agents/acp/prompts/finalize-and-send-prompt-result.ts
|
|
@@ -35444,16 +35506,7 @@ async function finalizeAndSendPromptResult(params) {
|
|
|
35444
35506
|
sendSessionUpdate,
|
|
35445
35507
|
log: log2
|
|
35446
35508
|
} = params;
|
|
35447
|
-
|
|
35448
|
-
await collectTurnGitDiffFromPreTurnSnapshot({
|
|
35449
|
-
sessionId,
|
|
35450
|
-
runId,
|
|
35451
|
-
agentCwd,
|
|
35452
|
-
sendSessionUpdate,
|
|
35453
|
-
log: log2
|
|
35454
|
-
});
|
|
35455
|
-
}
|
|
35456
|
-
const planningTodosSubmit = await maybeSubmitPlanningTodosAfterAgentSuccess({
|
|
35509
|
+
const planningTodosSubmit = isPlanningSession ? await maybeSubmitPlanningTodosAfterAgentSuccess({
|
|
35457
35510
|
sessionId,
|
|
35458
35511
|
runId,
|
|
35459
35512
|
resultSuccess: result.success === true,
|
|
@@ -35461,11 +35514,11 @@ async function finalizeAndSendPromptResult(params) {
|
|
|
35461
35514
|
cloudApiBaseUrl,
|
|
35462
35515
|
getCloudAccessToken,
|
|
35463
35516
|
log: log2
|
|
35464
|
-
});
|
|
35517
|
+
}) : { suppressOutput: false };
|
|
35518
|
+
const planningFallbackOutput = !planningTodosSubmit.suppressOutput && isPlanningSession && runId ? consumePlanningSessionTurnOutput(runId) : "";
|
|
35465
35519
|
const errStr = typeof result.error === "string" ? result.error : void 0;
|
|
35466
35520
|
const resultStop = typeof result.stopReason === "string" ? result.stopReason.trim() : "";
|
|
35467
35521
|
const cancelledByAgent = resultStop.toLowerCase() === "cancelled" || errStr != null && isUserEndedSessionTurnErrorText(errStr);
|
|
35468
|
-
const planningFallbackOutput = !planningTodosSubmit.suppressOutput && isPlanningSession && runId ? consumePlanningSessionTurnOutput(runId) : "";
|
|
35469
35522
|
sendResult({
|
|
35470
35523
|
type: "prompt_result",
|
|
35471
35524
|
id: promptId,
|
|
@@ -35486,6 +35539,14 @@ async function finalizeAndSendPromptResult(params) {
|
|
|
35486
35539
|
);
|
|
35487
35540
|
}
|
|
35488
35541
|
}
|
|
35542
|
+
void reportPostTurnEnrichment({
|
|
35543
|
+
sessionId,
|
|
35544
|
+
runId,
|
|
35545
|
+
agentCwd,
|
|
35546
|
+
result,
|
|
35547
|
+
sendSessionUpdate,
|
|
35548
|
+
log: log2
|
|
35549
|
+
});
|
|
35489
35550
|
}
|
|
35490
35551
|
|
|
35491
35552
|
// src/agents/acp/build-forked-session-agent-prompt.ts
|
|
@@ -35976,6 +36037,7 @@ async function resolveSendPromptImages(params) {
|
|
|
35976
36037
|
}
|
|
35977
36038
|
|
|
35978
36039
|
// src/agents/acp/prompts/send-prompt-to-agent.ts
|
|
36040
|
+
var SLOW_ACP_PROMPT_MS = 5e3;
|
|
35979
36041
|
async function sendPromptToAgent(options) {
|
|
35980
36042
|
const {
|
|
35981
36043
|
handle,
|
|
@@ -36022,7 +36084,12 @@ async function sendPromptToAgent(options) {
|
|
|
36022
36084
|
sendResult(imagesResolved.errorResult);
|
|
36023
36085
|
return;
|
|
36024
36086
|
}
|
|
36087
|
+
const promptStartedAt = Date.now();
|
|
36025
36088
|
const result = await handle.sendPrompt(prepared.agentPromptText, imagesResolved.sendOpts);
|
|
36089
|
+
const promptDurationMs = Date.now() - promptStartedAt;
|
|
36090
|
+
if (promptDurationMs >= SLOW_ACP_PROMPT_MS) {
|
|
36091
|
+
log2(`[Agent] ACP session/prompt completed after ${promptDurationMs}ms.`);
|
|
36092
|
+
}
|
|
36026
36093
|
await finalizeAndSendPromptResult({
|
|
36027
36094
|
result,
|
|
36028
36095
|
sessionId,
|
|
@@ -36034,7 +36101,6 @@ async function sendPromptToAgent(options) {
|
|
|
36034
36101
|
followUpCatalogPromptId,
|
|
36035
36102
|
cloudApiBaseUrl,
|
|
36036
36103
|
getCloudAccessToken,
|
|
36037
|
-
e2ee,
|
|
36038
36104
|
sendResult,
|
|
36039
36105
|
sendSessionUpdate,
|
|
36040
36106
|
log: log2
|
|
@@ -36057,16 +36123,6 @@ async function sendPromptToAgent(options) {
|
|
|
36057
36123
|
}
|
|
36058
36124
|
}
|
|
36059
36125
|
|
|
36060
|
-
// src/agents/acp/manager/get-acp-agent-state.ts
|
|
36061
|
-
function getAcpSessionAgentState(ctx, acpSessionAgentKey) {
|
|
36062
|
-
let state = ctx.acpAgents.get(acpSessionAgentKey);
|
|
36063
|
-
if (!state) {
|
|
36064
|
-
state = createEmptyAcpClientState();
|
|
36065
|
-
ctx.acpAgents.set(acpSessionAgentKey, state);
|
|
36066
|
-
}
|
|
36067
|
-
return state;
|
|
36068
|
-
}
|
|
36069
|
-
|
|
36070
36126
|
// src/agents/acp/manager/handle-pending-prompt-cancel.ts
|
|
36071
36127
|
async function handlePendingPromptCancel(params) {
|
|
36072
36128
|
const { ctx, activeRunId, promptId, sessionId, handle, sendResult } = params;
|
|
@@ -36090,94 +36146,104 @@ async function handlePendingPromptCancel(params) {
|
|
|
36090
36146
|
return true;
|
|
36091
36147
|
}
|
|
36092
36148
|
|
|
36093
|
-
// src/agents/acp/manager/
|
|
36094
|
-
async function
|
|
36095
|
-
const {
|
|
36096
|
-
|
|
36097
|
-
|
|
36098
|
-
sessionId,
|
|
36099
|
-
mode,
|
|
36100
|
-
agentConfig,
|
|
36101
|
-
sessionParentPath,
|
|
36102
|
-
sendResult,
|
|
36103
|
-
sendSessionUpdate,
|
|
36104
|
-
followUpCatalogPromptId,
|
|
36105
|
-
cloudApiBaseUrl,
|
|
36106
|
-
getCloudAccessToken,
|
|
36107
|
-
e2ee,
|
|
36108
|
-
attachments,
|
|
36109
|
-
isNewSession
|
|
36110
|
-
} = opts;
|
|
36111
|
-
const { activeRunId, activeAcpAgentKey, activeAcpSessionAgentKey, preferredForPrompt } = runCtx;
|
|
36112
|
-
const acpAgentState = getAcpSessionAgentState(ctx, activeAcpSessionAgentKey);
|
|
36113
|
-
const handle = await ensureAcpClient({
|
|
36114
|
-
state: acpAgentState,
|
|
36115
|
-
acpAgentKey: activeAcpAgentKey,
|
|
36116
|
-
preferredAgentType: preferredForPrompt,
|
|
36117
|
-
mode,
|
|
36118
|
-
agentConfig: agentConfig ?? null,
|
|
36119
|
-
sessionParentPath,
|
|
36120
|
-
resolveRouting: () => ctx.promptRouting.resolveRouting(activeAcpSessionAgentKey),
|
|
36121
|
-
cloudSessionId: sessionId,
|
|
36122
|
-
bridgeAccessPort: ctx.getBridgeAccessPort(),
|
|
36123
|
-
sendSessionUpdate,
|
|
36124
|
-
sendRequest: sendSessionUpdate,
|
|
36125
|
-
log: ctx.log,
|
|
36126
|
-
reportAgentCapabilities: ctx.reportAgentCapabilities
|
|
36127
|
-
});
|
|
36128
|
-
if (!handle) {
|
|
36129
|
-
const errMsg = acpAgentState.lastAcpStartError || "No agent configured. Register local agents on this bridge in the app.";
|
|
36130
|
-
const evaluated = Boolean(preferredForPrompt && errMsg.trim());
|
|
36131
|
-
const suggestsAuth = evaluated ? localAgentErrorSuggestsAuth(preferredForPrompt, errMsg) : false;
|
|
36132
|
-
const auth = suggestsAuth && preferredForPrompt ? { agentAuthRequired: true, agentType: preferredForPrompt } : {};
|
|
36133
|
-
sendResult({
|
|
36149
|
+
// src/agents/acp/manager/dispatch-acp-prompt.ts
|
|
36150
|
+
async function dispatchAcpPrompt(ctx, runCtx, opts, handle) {
|
|
36151
|
+
const { activeRunId, activeAcpSessionAgentKey, preferredForPrompt } = runCtx;
|
|
36152
|
+
if (!ctx.promptRouting.isRegisteredRun(activeRunId)) {
|
|
36153
|
+
opts.sendResult({
|
|
36134
36154
|
type: "prompt_result",
|
|
36135
|
-
id: promptId,
|
|
36136
|
-
...sessionId ? { sessionId } : {},
|
|
36155
|
+
id: opts.promptId,
|
|
36156
|
+
...opts.sessionId ? { sessionId: opts.sessionId } : {},
|
|
36137
36157
|
runId: activeRunId,
|
|
36138
36158
|
success: false,
|
|
36139
|
-
error:
|
|
36140
|
-
...auth
|
|
36159
|
+
error: "Prompt dispatch was superseded before the agent started."
|
|
36141
36160
|
});
|
|
36142
36161
|
return;
|
|
36143
36162
|
}
|
|
36144
|
-
if (!ctx.promptRouting.isRegisteredRun(activeRunId)) {
|
|
36145
|
-
return;
|
|
36146
|
-
}
|
|
36147
36163
|
const cancelled = await handlePendingPromptCancel({
|
|
36148
36164
|
ctx,
|
|
36149
36165
|
activeRunId,
|
|
36150
|
-
promptId,
|
|
36151
|
-
sessionId,
|
|
36166
|
+
promptId: opts.promptId,
|
|
36167
|
+
sessionId: opts.sessionId,
|
|
36152
36168
|
handle,
|
|
36153
|
-
sendResult
|
|
36169
|
+
sendResult: opts.sendResult
|
|
36154
36170
|
});
|
|
36155
36171
|
if (cancelled) return;
|
|
36156
36172
|
ctx.promptRouting.setStreamingRunId(activeAcpSessionAgentKey, activeRunId);
|
|
36157
36173
|
try {
|
|
36158
36174
|
await sendPromptToAgent({
|
|
36159
36175
|
handle,
|
|
36160
|
-
promptText,
|
|
36161
|
-
promptId,
|
|
36162
|
-
sessionId,
|
|
36176
|
+
promptText: opts.promptText,
|
|
36177
|
+
promptId: opts.promptId,
|
|
36178
|
+
sessionId: opts.sessionId,
|
|
36163
36179
|
runId: activeRunId,
|
|
36164
36180
|
agentType: preferredForPrompt,
|
|
36165
|
-
agentCwd: resolveSessionParentPathForAgentProcess(sessionParentPath),
|
|
36166
|
-
sendResult,
|
|
36167
|
-
sendSessionUpdate,
|
|
36181
|
+
agentCwd: resolveSessionParentPathForAgentProcess(opts.sessionParentPath),
|
|
36182
|
+
sendResult: opts.sendResult,
|
|
36183
|
+
sendSessionUpdate: opts.sendSessionUpdate,
|
|
36168
36184
|
log: ctx.log,
|
|
36169
|
-
followUpCatalogPromptId,
|
|
36170
|
-
cloudApiBaseUrl,
|
|
36171
|
-
getCloudAccessToken,
|
|
36172
|
-
e2ee,
|
|
36173
|
-
attachments,
|
|
36174
|
-
isNewSession
|
|
36185
|
+
followUpCatalogPromptId: opts.followUpCatalogPromptId,
|
|
36186
|
+
cloudApiBaseUrl: opts.cloudApiBaseUrl,
|
|
36187
|
+
getCloudAccessToken: opts.getCloudAccessToken,
|
|
36188
|
+
e2ee: opts.e2ee,
|
|
36189
|
+
attachments: opts.attachments,
|
|
36190
|
+
isNewSession: opts.isNewSession
|
|
36175
36191
|
});
|
|
36176
36192
|
} finally {
|
|
36177
36193
|
ctx.promptRouting.clearStreamingRunId(activeAcpSessionAgentKey, activeRunId);
|
|
36178
36194
|
}
|
|
36179
36195
|
}
|
|
36180
36196
|
|
|
36197
|
+
// src/agents/acp/manager/get-acp-agent-state.ts
|
|
36198
|
+
function getAcpSessionAgentState(ctx, acpSessionAgentKey) {
|
|
36199
|
+
let state = ctx.acpAgents.get(acpSessionAgentKey);
|
|
36200
|
+
if (!state) {
|
|
36201
|
+
state = createEmptyAcpClientState();
|
|
36202
|
+
ctx.acpAgents.set(acpSessionAgentKey, state);
|
|
36203
|
+
}
|
|
36204
|
+
return state;
|
|
36205
|
+
}
|
|
36206
|
+
|
|
36207
|
+
// src/agents/acp/manager/ensure-acp-prompt-client.ts
|
|
36208
|
+
async function ensureAcpPromptClient(ctx, runCtx, opts) {
|
|
36209
|
+
const state = getAcpSessionAgentState(ctx, runCtx.activeAcpSessionAgentKey);
|
|
36210
|
+
const handle = await ensureAcpClient({
|
|
36211
|
+
state,
|
|
36212
|
+
acpAgentKey: runCtx.activeAcpAgentKey,
|
|
36213
|
+
preferredAgentType: runCtx.preferredForPrompt,
|
|
36214
|
+
mode: opts.mode,
|
|
36215
|
+
agentConfig: opts.agentConfig ?? null,
|
|
36216
|
+
sessionParentPath: opts.sessionParentPath,
|
|
36217
|
+
resolveRouting: () => ctx.promptRouting.resolveRouting(runCtx.activeAcpSessionAgentKey),
|
|
36218
|
+
cloudSessionId: opts.sessionId,
|
|
36219
|
+
bridgeAccessPort: ctx.getBridgeAccessPort(),
|
|
36220
|
+
sendSessionUpdate: opts.sendSessionUpdate,
|
|
36221
|
+
sendRequest: opts.sendSessionUpdate,
|
|
36222
|
+
log: ctx.log,
|
|
36223
|
+
reportAgentCapabilities: ctx.reportAgentCapabilities
|
|
36224
|
+
});
|
|
36225
|
+
if (handle) return handle;
|
|
36226
|
+
const error40 = state.lastAcpStartError || "No agent configured. Register local agents on this bridge in the app.";
|
|
36227
|
+
const agentType = runCtx.preferredForPrompt;
|
|
36228
|
+
const requiresAuth = Boolean(agentType && localAgentErrorSuggestsAuth(agentType, error40));
|
|
36229
|
+
opts.sendResult({
|
|
36230
|
+
type: "prompt_result",
|
|
36231
|
+
id: opts.promptId,
|
|
36232
|
+
...opts.sessionId ? { sessionId: opts.sessionId } : {},
|
|
36233
|
+
runId: runCtx.activeRunId,
|
|
36234
|
+
success: false,
|
|
36235
|
+
error: error40,
|
|
36236
|
+
...requiresAuth && agentType ? { agentAuthRequired: true, agentType } : {}
|
|
36237
|
+
});
|
|
36238
|
+
return null;
|
|
36239
|
+
}
|
|
36240
|
+
|
|
36241
|
+
// src/agents/acp/manager/run-acp-prompt.ts
|
|
36242
|
+
async function runAcpPrompt(ctx, runCtx, opts) {
|
|
36243
|
+
const handle = await ensureAcpPromptClient(ctx, runCtx, opts);
|
|
36244
|
+
if (handle) await dispatchAcpPrompt(ctx, runCtx, opts, handle);
|
|
36245
|
+
}
|
|
36246
|
+
|
|
36181
36247
|
// src/agents/acp/manager/handle-prompt.ts
|
|
36182
36248
|
function handlePrompt(ctx, opts) {
|
|
36183
36249
|
const { promptId, sessionId, runId, mode, agentType, agentConfig, sendResult } = opts;
|
|
@@ -46439,9 +46505,13 @@ import * as fs49 from "node:fs";
|
|
|
46439
46505
|
import * as path70 from "node:path";
|
|
46440
46506
|
|
|
46441
46507
|
// src/git/snapshot/git.ts
|
|
46508
|
+
var SNAPSHOT_GIT_TIMEOUT_MS = 5e3;
|
|
46442
46509
|
async function gitStashCreate(repoRoot, log2) {
|
|
46443
46510
|
try {
|
|
46444
|
-
const { stdout } = await execGitFile(["stash", "create"], {
|
|
46511
|
+
const { stdout } = await execGitFile(["stash", "create"], {
|
|
46512
|
+
cwd: repoRoot,
|
|
46513
|
+
timeout: SNAPSHOT_GIT_TIMEOUT_MS
|
|
46514
|
+
});
|
|
46445
46515
|
return stdout.trim();
|
|
46446
46516
|
} catch (e) {
|
|
46447
46517
|
log2(
|
|
@@ -46452,7 +46522,10 @@ async function gitStashCreate(repoRoot, log2) {
|
|
|
46452
46522
|
}
|
|
46453
46523
|
async function gitUntrackedPaths(repoRoot, log2) {
|
|
46454
46524
|
try {
|
|
46455
|
-
const { stdout } = await execGitFile(["ls-files", "--others", "--exclude-standard"], {
|
|
46525
|
+
const { stdout } = await execGitFile(["ls-files", "--others", "--exclude-standard"], {
|
|
46526
|
+
cwd: repoRoot,
|
|
46527
|
+
timeout: SNAPSHOT_GIT_TIMEOUT_MS
|
|
46528
|
+
});
|
|
46456
46529
|
return stdout.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
46457
46530
|
} catch (e) {
|
|
46458
46531
|
log2(
|
|
@@ -48878,9 +48951,6 @@ function setRunIdQueueKey(runId, queueKey) {
|
|
|
48878
48951
|
runIdToQueueKey.set(runId, queueKey);
|
|
48879
48952
|
locallyDispatchedRunIds.add(runId);
|
|
48880
48953
|
}
|
|
48881
|
-
function isLocallyDispatchedRun(runId) {
|
|
48882
|
-
return locallyDispatchedRunIds.has(runId);
|
|
48883
|
-
}
|
|
48884
48954
|
function deleteRunIdQueueKey(runId) {
|
|
48885
48955
|
const queueKey = runIdToQueueKey.get(runId);
|
|
48886
48956
|
runIdToQueueKey.delete(runId);
|
|
@@ -48907,11 +48977,39 @@ async function dispatchStartedPromptQueueRuns(entries, started, deps) {
|
|
|
48907
48977
|
|
|
48908
48978
|
// src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
|
|
48909
48979
|
init_yield_to_event_loop();
|
|
48980
|
+
|
|
48981
|
+
// src/prompt-turn-queue/client-report.ts
|
|
48982
|
+
function sendPromptQueueClientReport(ws, queues) {
|
|
48983
|
+
if (!ws) return false;
|
|
48984
|
+
const wireQueues = {};
|
|
48985
|
+
for (const [queueKey, rows] of Object.entries(queues)) {
|
|
48986
|
+
wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
|
|
48987
|
+
}
|
|
48988
|
+
sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
|
|
48989
|
+
return true;
|
|
48990
|
+
}
|
|
48991
|
+
|
|
48992
|
+
// src/prompt-turn-queue/runner/finalize-prompt-turn-on-bridge.ts
|
|
48993
|
+
async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
|
|
48994
|
+
if (!runId) return false;
|
|
48995
|
+
const queueKey = deleteRunIdQueueKey(runId);
|
|
48996
|
+
if (!queueKey) return false;
|
|
48997
|
+
const f = await readPersistedQueue(queueKey);
|
|
48998
|
+
if (!f) return false;
|
|
48999
|
+
const t = f.turns.find((x) => x.turnId === runId);
|
|
49000
|
+
if (!t) return false;
|
|
49001
|
+
t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
|
|
49002
|
+
await writePersistedQueue(f);
|
|
49003
|
+
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
|
|
49004
|
+
return true;
|
|
49005
|
+
}
|
|
49006
|
+
|
|
49007
|
+
// src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
|
|
48910
49008
|
async function handlePromptQueueCancellations(entries, deps) {
|
|
48911
49009
|
for (const [queueKey] of entries) {
|
|
48912
49010
|
const file2 = await readPersistedQueue(queueKey);
|
|
48913
49011
|
const turn = file2?.turns.find((row) => row.bridgeServerState === "cancel_requested" && row.lastCliState === "running");
|
|
48914
|
-
if (!turn || getRunIdQueueKey(turn.turnId) !== queueKey
|
|
49012
|
+
if (!turn || getRunIdQueueKey(turn.turnId) !== queueKey) {
|
|
48915
49013
|
await yieldToEventLoop();
|
|
48916
49014
|
continue;
|
|
48917
49015
|
}
|
|
@@ -48920,7 +49018,8 @@ async function handlePromptQueueCancellations(entries, deps) {
|
|
|
48920
49018
|
await yieldToEventLoop();
|
|
48921
49019
|
continue;
|
|
48922
49020
|
}
|
|
48923
|
-
deps.log(`[Queue]
|
|
49021
|
+
deps.log(`[Queue] No local ACP run remains for ${turn.turnId.slice(0, 8)}\u2026; reconciling cancelled turn.`);
|
|
49022
|
+
await finalizePromptTurnOnBridge(deps.getWs, turn.turnId, false, { terminalCliState: "cancelled" });
|
|
48924
49023
|
await yieldToEventLoop();
|
|
48925
49024
|
}
|
|
48926
49025
|
}
|
|
@@ -48948,17 +49047,6 @@ function promptQueueSnapshotEntries(queues) {
|
|
|
48948
49047
|
// src/prompt-turn-queue/runner/start-prompt-queue-runs.ts
|
|
48949
49048
|
init_yield_to_event_loop();
|
|
48950
49049
|
|
|
48951
|
-
// src/prompt-turn-queue/client-report.ts
|
|
48952
|
-
function sendPromptQueueClientReport(ws, queues) {
|
|
48953
|
-
if (!ws) return false;
|
|
48954
|
-
const wireQueues = {};
|
|
48955
|
-
for (const [queueKey, rows] of Object.entries(queues)) {
|
|
48956
|
-
wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
|
|
48957
|
-
}
|
|
48958
|
-
sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
|
|
48959
|
-
return true;
|
|
48960
|
-
}
|
|
48961
|
-
|
|
48962
49050
|
// src/prompt-turn-queue/runner/queue-selection.ts
|
|
48963
49051
|
function pickNextRunnableTurn(turns) {
|
|
48964
49052
|
for (const t of turns) {
|
|
@@ -49122,29 +49210,20 @@ async function startPromptQueueRuns(entries, deps) {
|
|
|
49122
49210
|
}
|
|
49123
49211
|
|
|
49124
49212
|
// src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
|
|
49213
|
+
var SLOW_QUEUE_SYNC_MS = 2e3;
|
|
49125
49214
|
async function applyPromptQueueStateFromServer(msg, deps) {
|
|
49126
49215
|
const raw = msg.queues;
|
|
49127
49216
|
if (!raw || typeof raw !== "object") return;
|
|
49217
|
+
const startedAt = Date.now();
|
|
49128
49218
|
const entries = promptQueueSnapshotEntries(raw);
|
|
49129
49219
|
await persistPromptQueueSnapshot(entries);
|
|
49130
49220
|
await handlePromptQueueCancellations(entries, deps);
|
|
49131
49221
|
const started = await startPromptQueueRuns(entries, deps);
|
|
49132
49222
|
await dispatchStartedPromptQueueRuns(entries, started, deps);
|
|
49133
|
-
|
|
49134
|
-
|
|
49135
|
-
|
|
49136
|
-
|
|
49137
|
-
if (!runId) return false;
|
|
49138
|
-
const queueKey = deleteRunIdQueueKey(runId);
|
|
49139
|
-
if (!queueKey) return false;
|
|
49140
|
-
const f = await readPersistedQueue(queueKey);
|
|
49141
|
-
if (!f) return false;
|
|
49142
|
-
const t = f.turns.find((x) => x.turnId === runId);
|
|
49143
|
-
if (!t) return false;
|
|
49144
|
-
t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
|
|
49145
|
-
await writePersistedQueue(f);
|
|
49146
|
-
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
|
|
49147
|
-
return true;
|
|
49223
|
+
const durationMs = Date.now() - startedAt;
|
|
49224
|
+
if (durationMs >= SLOW_QUEUE_SYNC_MS) {
|
|
49225
|
+
deps.log(`[Queue] Queue state sync and dispatch took ${durationMs}ms.`);
|
|
49226
|
+
}
|
|
49148
49227
|
}
|
|
49149
49228
|
|
|
49150
49229
|
// src/agents/acp/from-bridge/bridge-prompt-wiring.ts
|
|
@@ -49221,59 +49300,93 @@ function parseWorktreeBaseBranches(msg) {
|
|
|
49221
49300
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
49222
49301
|
}
|
|
49223
49302
|
|
|
49224
|
-
// src/agents/acp/from-bridge/
|
|
49303
|
+
// src/agents/acp/from-bridge/parse-follow-up-prompt-fields.ts
|
|
49304
|
+
function parseFollowUpFieldsFromPromptMessage(msg) {
|
|
49305
|
+
const value = msg.followUpCatalogPromptId;
|
|
49306
|
+
return {
|
|
49307
|
+
followUpCatalogPromptId: typeof value === "string" && value.trim() !== "" ? value.trim() : null
|
|
49308
|
+
};
|
|
49309
|
+
}
|
|
49310
|
+
|
|
49311
|
+
// src/agents/acp/from-bridge/prepare-bridge-prompt-git-state.ts
|
|
49225
49312
|
import { execFile as execFile8 } from "node:child_process";
|
|
49226
49313
|
import { promisify as promisify9 } from "node:util";
|
|
49314
|
+
|
|
49315
|
+
// src/agents/acp/from-bridge/git-state-preparation-timeout.ts
|
|
49316
|
+
async function awaitGitStatePreparation(options) {
|
|
49317
|
+
const { label, timeoutMs, work, fallback, log: log2 } = options;
|
|
49318
|
+
let timer;
|
|
49319
|
+
try {
|
|
49320
|
+
return await Promise.race([
|
|
49321
|
+
work,
|
|
49322
|
+
new Promise((resolve35) => {
|
|
49323
|
+
timer = setTimeout(() => {
|
|
49324
|
+
log2(`[Agent] ${label} exceeded ${timeoutMs}ms; continuing without it.`);
|
|
49325
|
+
resolve35(fallback);
|
|
49326
|
+
}, timeoutMs);
|
|
49327
|
+
timer.unref?.();
|
|
49328
|
+
})
|
|
49329
|
+
]);
|
|
49330
|
+
} finally {
|
|
49331
|
+
if (timer) clearTimeout(timer);
|
|
49332
|
+
}
|
|
49333
|
+
}
|
|
49334
|
+
|
|
49335
|
+
// src/agents/acp/from-bridge/prepare-bridge-prompt-git-state.ts
|
|
49227
49336
|
var execFileAsync7 = promisify9(execFile8);
|
|
49337
|
+
var GIT_STATE_DISCOVERY_TIMEOUT_MS = 2e3;
|
|
49228
49338
|
async function readGitBranch(cwd) {
|
|
49229
49339
|
try {
|
|
49230
|
-
const { stdout } = await execFileAsync7("git", ["branch", "--show-current"], {
|
|
49231
|
-
|
|
49232
|
-
|
|
49340
|
+
const { stdout } = await execFileAsync7("git", ["branch", "--show-current"], {
|
|
49341
|
+
cwd,
|
|
49342
|
+
maxBuffer: 64 * 1024,
|
|
49343
|
+
timeout: GIT_STATE_DISCOVERY_TIMEOUT_MS
|
|
49344
|
+
});
|
|
49345
|
+
return stdout.trim() || null;
|
|
49233
49346
|
} catch {
|
|
49234
49347
|
return null;
|
|
49235
49348
|
}
|
|
49236
49349
|
}
|
|
49237
|
-
async function
|
|
49350
|
+
async function prepareBridgePromptGitState(params) {
|
|
49238
49351
|
const { getWs, log: log2, sessionWorktreeManager, sessionId, runId, effectiveCwd } = params;
|
|
49239
|
-
const
|
|
49240
|
-
|
|
49352
|
+
const repoCheckoutPaths = await awaitGitStatePreparation({
|
|
49353
|
+
label: "Session worktree discovery",
|
|
49354
|
+
timeoutMs: GIT_STATE_DISCOVERY_TIMEOUT_MS,
|
|
49355
|
+
work: sessionWorktreeManager.ensureRepoCheckoutPathsForSessionAsync(sessionId),
|
|
49356
|
+
fallback: void 0,
|
|
49357
|
+
log: log2
|
|
49358
|
+
});
|
|
49241
49359
|
const repoRoots = await resolveSnapshotRepoRoots({
|
|
49242
49360
|
worktreePaths: repoCheckoutPaths,
|
|
49243
49361
|
fallbackCwd: effectiveCwd,
|
|
49244
49362
|
sessionId: sessionId?.trim() || void 0,
|
|
49245
49363
|
log: log2
|
|
49246
49364
|
});
|
|
49247
|
-
|
|
49248
|
-
|
|
49249
|
-
const
|
|
49250
|
-
|
|
49251
|
-
sendWsMessage(s, {
|
|
49365
|
+
const socket = getWs();
|
|
49366
|
+
if (socket && sessionId) {
|
|
49367
|
+
const usesWorktree = sessionWorktreeManager.usesWorktreeSession(sessionId);
|
|
49368
|
+
sendWsMessage(socket, {
|
|
49252
49369
|
type: "session_git_context_report",
|
|
49253
49370
|
sessionId,
|
|
49254
|
-
cliGitBranch,
|
|
49255
|
-
agentUsesWorktree:
|
|
49256
|
-
sessionParent:
|
|
49257
|
-
sessionParentPath:
|
|
49371
|
+
cliGitBranch: repoRoots.length > 0 ? await readGitBranch(effectiveCwd) : null,
|
|
49372
|
+
agentUsesWorktree: usesWorktree,
|
|
49373
|
+
sessionParent: usesWorktree ? "worktrees_root" : "bridge_root",
|
|
49374
|
+
sessionParentPath: usesWorktree ? sessionWorktreeManager.getIsolatedSessionParentPathForSession(sessionId) ?? effectiveCwd : getBridgeRoot()
|
|
49258
49375
|
});
|
|
49259
49376
|
}
|
|
49260
|
-
if (
|
|
49261
|
-
const
|
|
49262
|
-
sendWsMessage(
|
|
49377
|
+
if (socket && sessionId && runId) {
|
|
49378
|
+
const snapshot = repoRoots.length > 0 ? await capturePreTurnSnapshot({ runId, repoRoots, agentCwd: effectiveCwd, log: log2 }) : { ok: false };
|
|
49379
|
+
sendWsMessage(socket, {
|
|
49263
49380
|
type: "pre_turn_snapshot_report",
|
|
49264
49381
|
sessionId,
|
|
49265
49382
|
turnId: runId,
|
|
49266
|
-
captured:
|
|
49383
|
+
captured: snapshot.ok
|
|
49267
49384
|
});
|
|
49268
49385
|
}
|
|
49269
49386
|
}
|
|
49270
|
-
function parseFollowUpFieldsFromPromptMessage(msg) {
|
|
49271
|
-
const followUpCatalogPromptId = typeof msg.followUpCatalogPromptId === "string" && msg.followUpCatalogPromptId.trim() !== "" ? msg.followUpCatalogPromptId.trim() : null;
|
|
49272
|
-
return { followUpCatalogPromptId };
|
|
49273
|
-
}
|
|
49274
49387
|
|
|
49275
|
-
// src/agents/acp/from-bridge/handle-bridge-prompt/
|
|
49276
|
-
async function
|
|
49388
|
+
// src/agents/acp/from-bridge/handle-bridge-prompt/prepare-git-state-and-run-prompt.ts
|
|
49389
|
+
async function prepareGitStateAndRunPrompt(params) {
|
|
49277
49390
|
const {
|
|
49278
49391
|
deps,
|
|
49279
49392
|
msg,
|
|
@@ -49292,7 +49405,7 @@ async function runPreambleAndPrompt(params) {
|
|
|
49292
49405
|
senders: { sendResult, sendSessionUpdate }
|
|
49293
49406
|
} = params;
|
|
49294
49407
|
const effectiveCwd = resolveSessionParentPathForAgentProcess(resolvedCwd);
|
|
49295
|
-
await
|
|
49408
|
+
await prepareBridgePromptGitState({
|
|
49296
49409
|
getWs,
|
|
49297
49410
|
log: log2,
|
|
49298
49411
|
sessionWorktreeManager,
|
|
@@ -49336,17 +49449,14 @@ function handleBridgePrompt(msg, deps) {
|
|
|
49336
49449
|
log2(
|
|
49337
49450
|
`[Bridge service] Prompt ignored: empty or missing prompt text (session ${typeof msg.sessionId === "string" ? msg.sessionId.slice(0, 8) : "\u2014"}\u2026, run ${typeof msg.runId === "string" ? msg.runId.slice(0, 8) : "\u2014"}\u2026).`
|
|
49338
49451
|
);
|
|
49339
|
-
senders.
|
|
49340
|
-
|
|
49341
|
-
|
|
49342
|
-
|
|
49343
|
-
|
|
49344
|
-
|
|
49345
|
-
|
|
49346
|
-
|
|
49347
|
-
},
|
|
49348
|
-
["error"]
|
|
49349
|
-
);
|
|
49452
|
+
senders.sendResult({
|
|
49453
|
+
type: "prompt_result",
|
|
49454
|
+
...promptId ? { id: promptId } : {},
|
|
49455
|
+
...sessionId ? { sessionId } : {},
|
|
49456
|
+
...runId ? { runId } : {},
|
|
49457
|
+
success: false,
|
|
49458
|
+
error: "Empty or missing prompt text from the bridge; this turn was not sent to the agent."
|
|
49459
|
+
});
|
|
49350
49460
|
return;
|
|
49351
49461
|
}
|
|
49352
49462
|
const isNewSession = msg.isNewSession === true;
|
|
@@ -49366,7 +49476,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
49366
49476
|
sessionParentPath,
|
|
49367
49477
|
...worktreeBaseBranches ? { worktreeBaseBranches } : {}
|
|
49368
49478
|
}).then(
|
|
49369
|
-
(cwd) =>
|
|
49479
|
+
(cwd) => prepareGitStateAndRunPrompt({
|
|
49370
49480
|
deps,
|
|
49371
49481
|
msg,
|
|
49372
49482
|
getWs,
|
|
@@ -49385,7 +49495,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
49385
49495
|
})
|
|
49386
49496
|
).catch((err) => {
|
|
49387
49497
|
log2(`[Agent] Session parent path resolve failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
49388
|
-
void
|
|
49498
|
+
void prepareGitStateAndRunPrompt({
|
|
49389
49499
|
deps,
|
|
49390
49500
|
msg,
|
|
49391
49501
|
getWs,
|