@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/cli.js
CHANGED
|
@@ -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;
|
|
@@ -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.78".length > 0 ? "0.1.78" : "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";
|
|
@@ -36205,9 +36212,12 @@ function cancelPendingCursorPermissionRequests(pendingRequests2, respond) {
|
|
|
36205
36212
|
// src/agents/acp/clients/cursor/create-cursor-acp-handle.ts
|
|
36206
36213
|
function createCursorAcpHandle(options) {
|
|
36207
36214
|
let teardownStarted = false;
|
|
36215
|
+
let cancelFallback = null;
|
|
36208
36216
|
async function disconnectGracefully() {
|
|
36209
36217
|
if (teardownStarted) return;
|
|
36210
36218
|
teardownStarted = true;
|
|
36219
|
+
if (cancelFallback) clearTimeout(cancelFallback);
|
|
36220
|
+
cancelFallback = null;
|
|
36211
36221
|
cancelPendingCursorPermissionRequests(options.pendingRequests, options.wire.respond);
|
|
36212
36222
|
try {
|
|
36213
36223
|
await options.transport.cancelSession(options.sessionId);
|
|
@@ -36233,7 +36243,17 @@ function createCursorAcpHandle(options) {
|
|
|
36233
36243
|
},
|
|
36234
36244
|
async cancel() {
|
|
36235
36245
|
cancelPendingCursorPermissionRequests(options.pendingRequests, options.wire.respond);
|
|
36236
|
-
|
|
36246
|
+
try {
|
|
36247
|
+
await options.transport.cancelSession(options.sessionId);
|
|
36248
|
+
} catch {
|
|
36249
|
+
}
|
|
36250
|
+
if (cancelFallback) return;
|
|
36251
|
+
cancelFallback = setTimeout(() => {
|
|
36252
|
+
if (options.child.exitCode == null && options.child.signalCode == null) {
|
|
36253
|
+
void disconnectGracefully();
|
|
36254
|
+
}
|
|
36255
|
+
}, 5e3);
|
|
36256
|
+
cancelFallback.unref?.();
|
|
36237
36257
|
},
|
|
36238
36258
|
resolveRequest(requestId, result) {
|
|
36239
36259
|
if (options.pendingRequests.has(requestId)) {
|
|
@@ -36788,13 +36808,15 @@ import { existsSync as existsSync4, statSync } from "node:fs";
|
|
|
36788
36808
|
// src/git/get-git-repo-root-sync.ts
|
|
36789
36809
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
36790
36810
|
import * as path28 from "node:path";
|
|
36811
|
+
var GIT_LOOKUP_TIMEOUT_MS = 2e3;
|
|
36791
36812
|
function getGitRepoRootSync(startDir) {
|
|
36792
36813
|
try {
|
|
36793
36814
|
const out = execFileSync3("git", ["rev-parse", "--show-toplevel"], {
|
|
36794
36815
|
cwd: path28.resolve(startDir),
|
|
36795
36816
|
encoding: "utf8",
|
|
36796
36817
|
stdio: ["ignore", "pipe", "ignore"],
|
|
36797
|
-
maxBuffer: 1024 * 1024
|
|
36818
|
+
maxBuffer: 1024 * 1024,
|
|
36819
|
+
timeout: GIT_LOOKUP_TIMEOUT_MS
|
|
36798
36820
|
}).trim();
|
|
36799
36821
|
return out ? path28.resolve(out) : null;
|
|
36800
36822
|
} catch {
|
|
@@ -36806,6 +36828,7 @@ function getGitRepoRootSync(startDir) {
|
|
|
36806
36828
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
36807
36829
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
36808
36830
|
import * as path29 from "node:path";
|
|
36831
|
+
var GIT_FILE_READ_TIMEOUT_MS = 2e3;
|
|
36809
36832
|
function resolveWorkspaceFilePath(sessionParentPath, rawPath) {
|
|
36810
36833
|
const trimmed2 = rawPath.trim();
|
|
36811
36834
|
if (!trimmed2) return null;
|
|
@@ -36867,7 +36890,8 @@ function readGitHeadBlob(sessionParentPath, displayPath) {
|
|
|
36867
36890
|
return execFileSync4("git", ["show", `HEAD:${displayPath}`], {
|
|
36868
36891
|
cwd: execCwd,
|
|
36869
36892
|
encoding: "utf8",
|
|
36870
|
-
maxBuffer: 50 * 1024 * 1024
|
|
36893
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
36894
|
+
timeout: GIT_FILE_READ_TIMEOUT_MS
|
|
36871
36895
|
});
|
|
36872
36896
|
} catch {
|
|
36873
36897
|
return "";
|
|
@@ -36875,6 +36899,7 @@ function readGitHeadBlob(sessionParentPath, displayPath) {
|
|
|
36875
36899
|
}
|
|
36876
36900
|
|
|
36877
36901
|
// src/agents/acp/session-file-change-path-kind.ts
|
|
36902
|
+
var GIT_PATH_KIND_TIMEOUT_MS = 2e3;
|
|
36878
36903
|
function gitHeadPathObjectType(sessionParentPath, displayPath) {
|
|
36879
36904
|
if (!displayPath || displayPath.includes("..")) return null;
|
|
36880
36905
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
@@ -36882,7 +36907,8 @@ function gitHeadPathObjectType(sessionParentPath, displayPath) {
|
|
|
36882
36907
|
try {
|
|
36883
36908
|
return execFileSync5("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
|
|
36884
36909
|
cwd: gitRoot,
|
|
36885
|
-
encoding: "utf8"
|
|
36910
|
+
encoding: "utf8",
|
|
36911
|
+
timeout: GIT_PATH_KIND_TIMEOUT_MS
|
|
36886
36912
|
}).trim();
|
|
36887
36913
|
} catch {
|
|
36888
36914
|
return null;
|
|
@@ -37989,6 +38015,73 @@ function augmentPromptResultAuthFields(agentType, errorText) {
|
|
|
37989
38015
|
return { agentAuthRequired: true, agentType };
|
|
37990
38016
|
}
|
|
37991
38017
|
|
|
38018
|
+
// src/agents/planning/submit-planning-todos-for-turn.ts
|
|
38019
|
+
var PLANNING_TODO_SUBMIT_TIMEOUT_MS = 3e3;
|
|
38020
|
+
async function submitPlanningTodosForTurn(params) {
|
|
38021
|
+
const token = params.getCloudAccessToken();
|
|
38022
|
+
if (!token.trim()) return { ok: false, error: "Missing cloud access token" };
|
|
38023
|
+
const base = params.cloudApiBaseUrl.replace(/\/$/, "");
|
|
38024
|
+
const url2 = `${base}/internal/sessions/todos/submit`;
|
|
38025
|
+
let res;
|
|
38026
|
+
try {
|
|
38027
|
+
res = await fetch(url2, {
|
|
38028
|
+
method: "POST",
|
|
38029
|
+
signal: AbortSignal.timeout(PLANNING_TODO_SUBMIT_TIMEOUT_MS),
|
|
38030
|
+
headers: {
|
|
38031
|
+
Authorization: `Bearer ${token}`,
|
|
38032
|
+
"Content-Type": "application/json"
|
|
38033
|
+
},
|
|
38034
|
+
body: JSON.stringify({
|
|
38035
|
+
sessionId: params.sessionId,
|
|
38036
|
+
turnId: params.turnId,
|
|
38037
|
+
items: params.items
|
|
38038
|
+
})
|
|
38039
|
+
});
|
|
38040
|
+
} catch (error40) {
|
|
38041
|
+
return { ok: false, error: error40 instanceof Error ? error40.message : String(error40) };
|
|
38042
|
+
}
|
|
38043
|
+
if (!res.ok) {
|
|
38044
|
+
const body = await res.json().catch(() => null);
|
|
38045
|
+
return { ok: false, error: body?.error ?? `Planning todo submit failed (${res.status})` };
|
|
38046
|
+
}
|
|
38047
|
+
return { ok: true };
|
|
38048
|
+
}
|
|
38049
|
+
|
|
38050
|
+
// src/agents/planning/maybe-submit-planning-todos-after-agent-success.ts
|
|
38051
|
+
async function maybeSubmitPlanningTodosAfterAgentSuccess(params) {
|
|
38052
|
+
const { sessionId, runId, resultSuccess, output, cloudApiBaseUrl, getCloudAccessToken, log: log2 } = params;
|
|
38053
|
+
const buffered = runId ? getPlanningSessionTurnOutput(runId) : "";
|
|
38054
|
+
const outputFromResult = typeof output === "string" ? output : "";
|
|
38055
|
+
const outputStr = buffered.trim() !== "" ? buffered : outputFromResult;
|
|
38056
|
+
if (!sessionId || !runId || !resultSuccess || outputStr.trim() === "") {
|
|
38057
|
+
return { submitted: false, suppressOutput: false };
|
|
38058
|
+
}
|
|
38059
|
+
if (!cloudApiBaseUrl || !getCloudAccessToken) {
|
|
38060
|
+
return { submitted: false, suppressOutput: false };
|
|
38061
|
+
}
|
|
38062
|
+
const items = parsePlanningTodoAgentJson(outputStr);
|
|
38063
|
+
if (items.length === 0) {
|
|
38064
|
+
return { submitted: false, suppressOutput: false };
|
|
38065
|
+
}
|
|
38066
|
+
const result = await submitPlanningTodosForTurn({
|
|
38067
|
+
sessionId,
|
|
38068
|
+
turnId: runId,
|
|
38069
|
+
items,
|
|
38070
|
+
cloudApiBaseUrl,
|
|
38071
|
+
getCloudAccessToken
|
|
38072
|
+
});
|
|
38073
|
+
if (!result.ok) {
|
|
38074
|
+
log2(`[Agent] Planning todo submit failed: ${result.error}`);
|
|
38075
|
+
return { submitted: false, suppressOutput: false };
|
|
38076
|
+
}
|
|
38077
|
+
if (runId) consumePlanningSessionTurnOutput(runId);
|
|
38078
|
+
log2(`[Agent] Planning session: stored ${items.length} todo(s) via internal API`);
|
|
38079
|
+
return { submitted: true, suppressOutput: true };
|
|
38080
|
+
}
|
|
38081
|
+
|
|
38082
|
+
// src/agents/acp/prompts/report-post-turn-enrichment.ts
|
|
38083
|
+
init_yield_to_event_loop();
|
|
38084
|
+
|
|
37992
38085
|
// src/git/git-runtime.ts
|
|
37993
38086
|
init_cli_process_interrupt();
|
|
37994
38087
|
var activeGitChildProcesses = /* @__PURE__ */ new Set();
|
|
@@ -38351,61 +38444,30 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
38351
38444
|
});
|
|
38352
38445
|
}
|
|
38353
38446
|
|
|
38354
|
-
// src/agents/
|
|
38355
|
-
|
|
38356
|
-
|
|
38357
|
-
|
|
38358
|
-
|
|
38359
|
-
|
|
38360
|
-
|
|
38361
|
-
|
|
38362
|
-
|
|
38363
|
-
|
|
38364
|
-
|
|
38365
|
-
|
|
38366
|
-
|
|
38367
|
-
|
|
38368
|
-
|
|
38369
|
-
|
|
38370
|
-
|
|
38371
|
-
|
|
38372
|
-
|
|
38373
|
-
|
|
38374
|
-
|
|
38375
|
-
}
|
|
38376
|
-
|
|
38377
|
-
}
|
|
38378
|
-
|
|
38379
|
-
// src/agents/planning/maybe-submit-planning-todos-after-agent-success.ts
|
|
38380
|
-
async function maybeSubmitPlanningTodosAfterAgentSuccess(params) {
|
|
38381
|
-
const { sessionId, runId, resultSuccess, output, cloudApiBaseUrl, getCloudAccessToken, log: log2 } = params;
|
|
38382
|
-
const buffered = runId ? getPlanningSessionTurnOutput(runId) : "";
|
|
38383
|
-
const outputFromResult = typeof output === "string" ? output : "";
|
|
38384
|
-
const outputStr = buffered.trim() !== "" ? buffered : outputFromResult;
|
|
38385
|
-
if (!sessionId || !runId || !resultSuccess || outputStr.trim() === "") {
|
|
38386
|
-
return { submitted: false, suppressOutput: false };
|
|
38387
|
-
}
|
|
38388
|
-
if (!cloudApiBaseUrl || !getCloudAccessToken) {
|
|
38389
|
-
return { submitted: false, suppressOutput: false };
|
|
38390
|
-
}
|
|
38391
|
-
const items = parsePlanningTodoAgentJson(outputStr);
|
|
38392
|
-
if (items.length === 0) {
|
|
38393
|
-
return { submitted: false, suppressOutput: false };
|
|
38394
|
-
}
|
|
38395
|
-
const result = await submitPlanningTodosForTurn({
|
|
38396
|
-
sessionId,
|
|
38397
|
-
turnId: runId,
|
|
38398
|
-
items,
|
|
38399
|
-
cloudApiBaseUrl,
|
|
38400
|
-
getCloudAccessToken
|
|
38447
|
+
// src/agents/acp/prompts/report-post-turn-enrichment.ts
|
|
38448
|
+
function reportPostTurnEnrichment(options) {
|
|
38449
|
+
void (async () => {
|
|
38450
|
+
const {
|
|
38451
|
+
sessionId,
|
|
38452
|
+
runId,
|
|
38453
|
+
agentCwd,
|
|
38454
|
+
result,
|
|
38455
|
+
sendSessionUpdate,
|
|
38456
|
+
log: log2
|
|
38457
|
+
} = options;
|
|
38458
|
+
await yieldToEventLoop();
|
|
38459
|
+
if (sessionId && runId && sendSessionUpdate && agentCwd && result.success) {
|
|
38460
|
+
await collectTurnGitDiffFromPreTurnSnapshot({
|
|
38461
|
+
sessionId,
|
|
38462
|
+
runId,
|
|
38463
|
+
agentCwd,
|
|
38464
|
+
sendSessionUpdate,
|
|
38465
|
+
log: log2
|
|
38466
|
+
});
|
|
38467
|
+
}
|
|
38468
|
+
})().catch((error40) => {
|
|
38469
|
+
options.log(`[Agent] Post-turn enrichment failed: ${error40 instanceof Error ? error40.message : String(error40)}`);
|
|
38401
38470
|
});
|
|
38402
|
-
if (!result.ok) {
|
|
38403
|
-
log2(`[Agent] Planning todo submit failed: ${result.error}`);
|
|
38404
|
-
return { submitted: false, suppressOutput: false };
|
|
38405
|
-
}
|
|
38406
|
-
if (runId) consumePlanningSessionTurnOutput(runId);
|
|
38407
|
-
log2(`[Agent] Planning session: stored ${items.length} todo(s) via internal API`);
|
|
38408
|
-
return { submitted: true, suppressOutput: true };
|
|
38409
38471
|
}
|
|
38410
38472
|
|
|
38411
38473
|
// src/agents/acp/prompts/finalize-and-send-prompt-result.ts
|
|
@@ -38425,16 +38487,7 @@ async function finalizeAndSendPromptResult(params) {
|
|
|
38425
38487
|
sendSessionUpdate,
|
|
38426
38488
|
log: log2
|
|
38427
38489
|
} = params;
|
|
38428
|
-
|
|
38429
|
-
await collectTurnGitDiffFromPreTurnSnapshot({
|
|
38430
|
-
sessionId,
|
|
38431
|
-
runId,
|
|
38432
|
-
agentCwd,
|
|
38433
|
-
sendSessionUpdate,
|
|
38434
|
-
log: log2
|
|
38435
|
-
});
|
|
38436
|
-
}
|
|
38437
|
-
const planningTodosSubmit = await maybeSubmitPlanningTodosAfterAgentSuccess({
|
|
38490
|
+
const planningTodosSubmit = isPlanningSession ? await maybeSubmitPlanningTodosAfterAgentSuccess({
|
|
38438
38491
|
sessionId,
|
|
38439
38492
|
runId,
|
|
38440
38493
|
resultSuccess: result.success === true,
|
|
@@ -38442,11 +38495,11 @@ async function finalizeAndSendPromptResult(params) {
|
|
|
38442
38495
|
cloudApiBaseUrl,
|
|
38443
38496
|
getCloudAccessToken,
|
|
38444
38497
|
log: log2
|
|
38445
|
-
});
|
|
38498
|
+
}) : { suppressOutput: false };
|
|
38499
|
+
const planningFallbackOutput = !planningTodosSubmit.suppressOutput && isPlanningSession && runId ? consumePlanningSessionTurnOutput(runId) : "";
|
|
38446
38500
|
const errStr = typeof result.error === "string" ? result.error : void 0;
|
|
38447
38501
|
const resultStop = typeof result.stopReason === "string" ? result.stopReason.trim() : "";
|
|
38448
38502
|
const cancelledByAgent = resultStop.toLowerCase() === "cancelled" || errStr != null && isUserEndedSessionTurnErrorText(errStr);
|
|
38449
|
-
const planningFallbackOutput = !planningTodosSubmit.suppressOutput && isPlanningSession && runId ? consumePlanningSessionTurnOutput(runId) : "";
|
|
38450
38503
|
sendResult({
|
|
38451
38504
|
type: "prompt_result",
|
|
38452
38505
|
id: promptId,
|
|
@@ -38467,6 +38520,14 @@ async function finalizeAndSendPromptResult(params) {
|
|
|
38467
38520
|
);
|
|
38468
38521
|
}
|
|
38469
38522
|
}
|
|
38523
|
+
void reportPostTurnEnrichment({
|
|
38524
|
+
sessionId,
|
|
38525
|
+
runId,
|
|
38526
|
+
agentCwd,
|
|
38527
|
+
result,
|
|
38528
|
+
sendSessionUpdate,
|
|
38529
|
+
log: log2
|
|
38530
|
+
});
|
|
38470
38531
|
}
|
|
38471
38532
|
|
|
38472
38533
|
// src/agents/acp/build-forked-session-agent-prompt.ts
|
|
@@ -38865,6 +38926,7 @@ async function resolveSendPromptImages(params) {
|
|
|
38865
38926
|
}
|
|
38866
38927
|
|
|
38867
38928
|
// src/agents/acp/prompts/send-prompt-to-agent.ts
|
|
38929
|
+
var SLOW_ACP_PROMPT_MS = 5e3;
|
|
38868
38930
|
async function sendPromptToAgent(options) {
|
|
38869
38931
|
const {
|
|
38870
38932
|
handle,
|
|
@@ -38911,7 +38973,12 @@ async function sendPromptToAgent(options) {
|
|
|
38911
38973
|
sendResult(imagesResolved.errorResult);
|
|
38912
38974
|
return;
|
|
38913
38975
|
}
|
|
38976
|
+
const promptStartedAt = Date.now();
|
|
38914
38977
|
const result = await handle.sendPrompt(prepared.agentPromptText, imagesResolved.sendOpts);
|
|
38978
|
+
const promptDurationMs = Date.now() - promptStartedAt;
|
|
38979
|
+
if (promptDurationMs >= SLOW_ACP_PROMPT_MS) {
|
|
38980
|
+
log2(`[Agent] ACP session/prompt completed after ${promptDurationMs}ms.`);
|
|
38981
|
+
}
|
|
38915
38982
|
await finalizeAndSendPromptResult({
|
|
38916
38983
|
result,
|
|
38917
38984
|
sessionId,
|
|
@@ -38923,7 +38990,6 @@ async function sendPromptToAgent(options) {
|
|
|
38923
38990
|
followUpCatalogPromptId,
|
|
38924
38991
|
cloudApiBaseUrl,
|
|
38925
38992
|
getCloudAccessToken,
|
|
38926
|
-
e2ee,
|
|
38927
38993
|
sendResult,
|
|
38928
38994
|
sendSessionUpdate,
|
|
38929
38995
|
log: log2
|
|
@@ -38946,16 +39012,6 @@ async function sendPromptToAgent(options) {
|
|
|
38946
39012
|
}
|
|
38947
39013
|
}
|
|
38948
39014
|
|
|
38949
|
-
// src/agents/acp/manager/get-acp-agent-state.ts
|
|
38950
|
-
function getAcpSessionAgentState(ctx, acpSessionAgentKey) {
|
|
38951
|
-
let state = ctx.acpAgents.get(acpSessionAgentKey);
|
|
38952
|
-
if (!state) {
|
|
38953
|
-
state = createEmptyAcpClientState();
|
|
38954
|
-
ctx.acpAgents.set(acpSessionAgentKey, state);
|
|
38955
|
-
}
|
|
38956
|
-
return state;
|
|
38957
|
-
}
|
|
38958
|
-
|
|
38959
39015
|
// src/agents/acp/manager/handle-pending-prompt-cancel.ts
|
|
38960
39016
|
async function handlePendingPromptCancel(params) {
|
|
38961
39017
|
const { ctx, activeRunId, promptId, sessionId, handle, sendResult } = params;
|
|
@@ -38979,94 +39035,104 @@ async function handlePendingPromptCancel(params) {
|
|
|
38979
39035
|
return true;
|
|
38980
39036
|
}
|
|
38981
39037
|
|
|
38982
|
-
// src/agents/acp/manager/
|
|
38983
|
-
async function
|
|
38984
|
-
const {
|
|
38985
|
-
|
|
38986
|
-
|
|
38987
|
-
sessionId,
|
|
38988
|
-
mode,
|
|
38989
|
-
agentConfig,
|
|
38990
|
-
sessionParentPath,
|
|
38991
|
-
sendResult,
|
|
38992
|
-
sendSessionUpdate,
|
|
38993
|
-
followUpCatalogPromptId,
|
|
38994
|
-
cloudApiBaseUrl,
|
|
38995
|
-
getCloudAccessToken,
|
|
38996
|
-
e2ee,
|
|
38997
|
-
attachments,
|
|
38998
|
-
isNewSession
|
|
38999
|
-
} = opts;
|
|
39000
|
-
const { activeRunId, activeAcpAgentKey, activeAcpSessionAgentKey, preferredForPrompt } = runCtx;
|
|
39001
|
-
const acpAgentState = getAcpSessionAgentState(ctx, activeAcpSessionAgentKey);
|
|
39002
|
-
const handle = await ensureAcpClient({
|
|
39003
|
-
state: acpAgentState,
|
|
39004
|
-
acpAgentKey: activeAcpAgentKey,
|
|
39005
|
-
preferredAgentType: preferredForPrompt,
|
|
39006
|
-
mode,
|
|
39007
|
-
agentConfig: agentConfig ?? null,
|
|
39008
|
-
sessionParentPath,
|
|
39009
|
-
resolveRouting: () => ctx.promptRouting.resolveRouting(activeAcpSessionAgentKey),
|
|
39010
|
-
cloudSessionId: sessionId,
|
|
39011
|
-
bridgeAccessPort: ctx.getBridgeAccessPort(),
|
|
39012
|
-
sendSessionUpdate,
|
|
39013
|
-
sendRequest: sendSessionUpdate,
|
|
39014
|
-
log: ctx.log,
|
|
39015
|
-
reportAgentCapabilities: ctx.reportAgentCapabilities
|
|
39016
|
-
});
|
|
39017
|
-
if (!handle) {
|
|
39018
|
-
const errMsg = acpAgentState.lastAcpStartError || "No agent configured. Register local agents on this bridge in the app.";
|
|
39019
|
-
const evaluated = Boolean(preferredForPrompt && errMsg.trim());
|
|
39020
|
-
const suggestsAuth = evaluated ? localAgentErrorSuggestsAuth(preferredForPrompt, errMsg) : false;
|
|
39021
|
-
const auth = suggestsAuth && preferredForPrompt ? { agentAuthRequired: true, agentType: preferredForPrompt } : {};
|
|
39022
|
-
sendResult({
|
|
39038
|
+
// src/agents/acp/manager/dispatch-acp-prompt.ts
|
|
39039
|
+
async function dispatchAcpPrompt(ctx, runCtx, opts, handle) {
|
|
39040
|
+
const { activeRunId, activeAcpSessionAgentKey, preferredForPrompt } = runCtx;
|
|
39041
|
+
if (!ctx.promptRouting.isRegisteredRun(activeRunId)) {
|
|
39042
|
+
opts.sendResult({
|
|
39023
39043
|
type: "prompt_result",
|
|
39024
|
-
id: promptId,
|
|
39025
|
-
...sessionId ? { sessionId } : {},
|
|
39044
|
+
id: opts.promptId,
|
|
39045
|
+
...opts.sessionId ? { sessionId: opts.sessionId } : {},
|
|
39026
39046
|
runId: activeRunId,
|
|
39027
39047
|
success: false,
|
|
39028
|
-
error:
|
|
39029
|
-
...auth
|
|
39048
|
+
error: "Prompt dispatch was superseded before the agent started."
|
|
39030
39049
|
});
|
|
39031
39050
|
return;
|
|
39032
39051
|
}
|
|
39033
|
-
if (!ctx.promptRouting.isRegisteredRun(activeRunId)) {
|
|
39034
|
-
return;
|
|
39035
|
-
}
|
|
39036
39052
|
const cancelled = await handlePendingPromptCancel({
|
|
39037
39053
|
ctx,
|
|
39038
39054
|
activeRunId,
|
|
39039
|
-
promptId,
|
|
39040
|
-
sessionId,
|
|
39055
|
+
promptId: opts.promptId,
|
|
39056
|
+
sessionId: opts.sessionId,
|
|
39041
39057
|
handle,
|
|
39042
|
-
sendResult
|
|
39058
|
+
sendResult: opts.sendResult
|
|
39043
39059
|
});
|
|
39044
39060
|
if (cancelled) return;
|
|
39045
39061
|
ctx.promptRouting.setStreamingRunId(activeAcpSessionAgentKey, activeRunId);
|
|
39046
39062
|
try {
|
|
39047
39063
|
await sendPromptToAgent({
|
|
39048
39064
|
handle,
|
|
39049
|
-
promptText,
|
|
39050
|
-
promptId,
|
|
39051
|
-
sessionId,
|
|
39065
|
+
promptText: opts.promptText,
|
|
39066
|
+
promptId: opts.promptId,
|
|
39067
|
+
sessionId: opts.sessionId,
|
|
39052
39068
|
runId: activeRunId,
|
|
39053
39069
|
agentType: preferredForPrompt,
|
|
39054
|
-
agentCwd: resolveSessionParentPathForAgentProcess(sessionParentPath),
|
|
39055
|
-
sendResult,
|
|
39056
|
-
sendSessionUpdate,
|
|
39070
|
+
agentCwd: resolveSessionParentPathForAgentProcess(opts.sessionParentPath),
|
|
39071
|
+
sendResult: opts.sendResult,
|
|
39072
|
+
sendSessionUpdate: opts.sendSessionUpdate,
|
|
39057
39073
|
log: ctx.log,
|
|
39058
|
-
followUpCatalogPromptId,
|
|
39059
|
-
cloudApiBaseUrl,
|
|
39060
|
-
getCloudAccessToken,
|
|
39061
|
-
e2ee,
|
|
39062
|
-
attachments,
|
|
39063
|
-
isNewSession
|
|
39074
|
+
followUpCatalogPromptId: opts.followUpCatalogPromptId,
|
|
39075
|
+
cloudApiBaseUrl: opts.cloudApiBaseUrl,
|
|
39076
|
+
getCloudAccessToken: opts.getCloudAccessToken,
|
|
39077
|
+
e2ee: opts.e2ee,
|
|
39078
|
+
attachments: opts.attachments,
|
|
39079
|
+
isNewSession: opts.isNewSession
|
|
39064
39080
|
});
|
|
39065
39081
|
} finally {
|
|
39066
39082
|
ctx.promptRouting.clearStreamingRunId(activeAcpSessionAgentKey, activeRunId);
|
|
39067
39083
|
}
|
|
39068
39084
|
}
|
|
39069
39085
|
|
|
39086
|
+
// src/agents/acp/manager/get-acp-agent-state.ts
|
|
39087
|
+
function getAcpSessionAgentState(ctx, acpSessionAgentKey) {
|
|
39088
|
+
let state = ctx.acpAgents.get(acpSessionAgentKey);
|
|
39089
|
+
if (!state) {
|
|
39090
|
+
state = createEmptyAcpClientState();
|
|
39091
|
+
ctx.acpAgents.set(acpSessionAgentKey, state);
|
|
39092
|
+
}
|
|
39093
|
+
return state;
|
|
39094
|
+
}
|
|
39095
|
+
|
|
39096
|
+
// src/agents/acp/manager/ensure-acp-prompt-client.ts
|
|
39097
|
+
async function ensureAcpPromptClient(ctx, runCtx, opts) {
|
|
39098
|
+
const state = getAcpSessionAgentState(ctx, runCtx.activeAcpSessionAgentKey);
|
|
39099
|
+
const handle = await ensureAcpClient({
|
|
39100
|
+
state,
|
|
39101
|
+
acpAgentKey: runCtx.activeAcpAgentKey,
|
|
39102
|
+
preferredAgentType: runCtx.preferredForPrompt,
|
|
39103
|
+
mode: opts.mode,
|
|
39104
|
+
agentConfig: opts.agentConfig ?? null,
|
|
39105
|
+
sessionParentPath: opts.sessionParentPath,
|
|
39106
|
+
resolveRouting: () => ctx.promptRouting.resolveRouting(runCtx.activeAcpSessionAgentKey),
|
|
39107
|
+
cloudSessionId: opts.sessionId,
|
|
39108
|
+
bridgeAccessPort: ctx.getBridgeAccessPort(),
|
|
39109
|
+
sendSessionUpdate: opts.sendSessionUpdate,
|
|
39110
|
+
sendRequest: opts.sendSessionUpdate,
|
|
39111
|
+
log: ctx.log,
|
|
39112
|
+
reportAgentCapabilities: ctx.reportAgentCapabilities
|
|
39113
|
+
});
|
|
39114
|
+
if (handle) return handle;
|
|
39115
|
+
const error40 = state.lastAcpStartError || "No agent configured. Register local agents on this bridge in the app.";
|
|
39116
|
+
const agentType = runCtx.preferredForPrompt;
|
|
39117
|
+
const requiresAuth = Boolean(agentType && localAgentErrorSuggestsAuth(agentType, error40));
|
|
39118
|
+
opts.sendResult({
|
|
39119
|
+
type: "prompt_result",
|
|
39120
|
+
id: opts.promptId,
|
|
39121
|
+
...opts.sessionId ? { sessionId: opts.sessionId } : {},
|
|
39122
|
+
runId: runCtx.activeRunId,
|
|
39123
|
+
success: false,
|
|
39124
|
+
error: error40,
|
|
39125
|
+
...requiresAuth && agentType ? { agentAuthRequired: true, agentType } : {}
|
|
39126
|
+
});
|
|
39127
|
+
return null;
|
|
39128
|
+
}
|
|
39129
|
+
|
|
39130
|
+
// src/agents/acp/manager/run-acp-prompt.ts
|
|
39131
|
+
async function runAcpPrompt(ctx, runCtx, opts) {
|
|
39132
|
+
const handle = await ensureAcpPromptClient(ctx, runCtx, opts);
|
|
39133
|
+
if (handle) await dispatchAcpPrompt(ctx, runCtx, opts, handle);
|
|
39134
|
+
}
|
|
39135
|
+
|
|
39070
39136
|
// src/agents/acp/manager/handle-prompt.ts
|
|
39071
39137
|
function handlePrompt(ctx, opts) {
|
|
39072
39138
|
const { promptId, sessionId, runId, mode, agentType, agentConfig, sendResult } = opts;
|
|
@@ -49485,9 +49551,13 @@ import * as fs50 from "node:fs";
|
|
|
49485
49551
|
import * as path71 from "node:path";
|
|
49486
49552
|
|
|
49487
49553
|
// src/git/snapshot/git.ts
|
|
49554
|
+
var SNAPSHOT_GIT_TIMEOUT_MS = 5e3;
|
|
49488
49555
|
async function gitStashCreate(repoRoot, log2) {
|
|
49489
49556
|
try {
|
|
49490
|
-
const { stdout } = await execGitFile(["stash", "create"], {
|
|
49557
|
+
const { stdout } = await execGitFile(["stash", "create"], {
|
|
49558
|
+
cwd: repoRoot,
|
|
49559
|
+
timeout: SNAPSHOT_GIT_TIMEOUT_MS
|
|
49560
|
+
});
|
|
49491
49561
|
return stdout.trim();
|
|
49492
49562
|
} catch (e) {
|
|
49493
49563
|
log2(
|
|
@@ -49498,7 +49568,10 @@ async function gitStashCreate(repoRoot, log2) {
|
|
|
49498
49568
|
}
|
|
49499
49569
|
async function gitUntrackedPaths(repoRoot, log2) {
|
|
49500
49570
|
try {
|
|
49501
|
-
const { stdout } = await execGitFile(["ls-files", "--others", "--exclude-standard"], {
|
|
49571
|
+
const { stdout } = await execGitFile(["ls-files", "--others", "--exclude-standard"], {
|
|
49572
|
+
cwd: repoRoot,
|
|
49573
|
+
timeout: SNAPSHOT_GIT_TIMEOUT_MS
|
|
49574
|
+
});
|
|
49502
49575
|
return stdout.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
49503
49576
|
} catch (e) {
|
|
49504
49577
|
log2(
|
|
@@ -51924,9 +51997,6 @@ function setRunIdQueueKey(runId, queueKey) {
|
|
|
51924
51997
|
runIdToQueueKey.set(runId, queueKey);
|
|
51925
51998
|
locallyDispatchedRunIds.add(runId);
|
|
51926
51999
|
}
|
|
51927
|
-
function isLocallyDispatchedRun(runId) {
|
|
51928
|
-
return locallyDispatchedRunIds.has(runId);
|
|
51929
|
-
}
|
|
51930
52000
|
function deleteRunIdQueueKey(runId) {
|
|
51931
52001
|
const queueKey = runIdToQueueKey.get(runId);
|
|
51932
52002
|
runIdToQueueKey.delete(runId);
|
|
@@ -51953,11 +52023,39 @@ async function dispatchStartedPromptQueueRuns(entries, started, deps) {
|
|
|
51953
52023
|
|
|
51954
52024
|
// src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
|
|
51955
52025
|
init_yield_to_event_loop();
|
|
52026
|
+
|
|
52027
|
+
// src/prompt-turn-queue/client-report.ts
|
|
52028
|
+
function sendPromptQueueClientReport(ws, queues) {
|
|
52029
|
+
if (!ws) return false;
|
|
52030
|
+
const wireQueues = {};
|
|
52031
|
+
for (const [queueKey, rows] of Object.entries(queues)) {
|
|
52032
|
+
wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
|
|
52033
|
+
}
|
|
52034
|
+
sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
|
|
52035
|
+
return true;
|
|
52036
|
+
}
|
|
52037
|
+
|
|
52038
|
+
// src/prompt-turn-queue/runner/finalize-prompt-turn-on-bridge.ts
|
|
52039
|
+
async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
|
|
52040
|
+
if (!runId) return false;
|
|
52041
|
+
const queueKey = deleteRunIdQueueKey(runId);
|
|
52042
|
+
if (!queueKey) return false;
|
|
52043
|
+
const f = await readPersistedQueue(queueKey);
|
|
52044
|
+
if (!f) return false;
|
|
52045
|
+
const t = f.turns.find((x) => x.turnId === runId);
|
|
52046
|
+
if (!t) return false;
|
|
52047
|
+
t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
|
|
52048
|
+
await writePersistedQueue(f);
|
|
52049
|
+
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
|
|
52050
|
+
return true;
|
|
52051
|
+
}
|
|
52052
|
+
|
|
52053
|
+
// src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
|
|
51956
52054
|
async function handlePromptQueueCancellations(entries, deps) {
|
|
51957
52055
|
for (const [queueKey] of entries) {
|
|
51958
52056
|
const file2 = await readPersistedQueue(queueKey);
|
|
51959
52057
|
const turn = file2?.turns.find((row) => row.bridgeServerState === "cancel_requested" && row.lastCliState === "running");
|
|
51960
|
-
if (!turn || getRunIdQueueKey(turn.turnId) !== queueKey
|
|
52058
|
+
if (!turn || getRunIdQueueKey(turn.turnId) !== queueKey) {
|
|
51961
52059
|
await yieldToEventLoop();
|
|
51962
52060
|
continue;
|
|
51963
52061
|
}
|
|
@@ -51966,7 +52064,8 @@ async function handlePromptQueueCancellations(entries, deps) {
|
|
|
51966
52064
|
await yieldToEventLoop();
|
|
51967
52065
|
continue;
|
|
51968
52066
|
}
|
|
51969
|
-
deps.log(`[Queue]
|
|
52067
|
+
deps.log(`[Queue] No local ACP run remains for ${turn.turnId.slice(0, 8)}\u2026; reconciling cancelled turn.`);
|
|
52068
|
+
await finalizePromptTurnOnBridge(deps.getWs, turn.turnId, false, { terminalCliState: "cancelled" });
|
|
51970
52069
|
await yieldToEventLoop();
|
|
51971
52070
|
}
|
|
51972
52071
|
}
|
|
@@ -51994,17 +52093,6 @@ function promptQueueSnapshotEntries(queues) {
|
|
|
51994
52093
|
// src/prompt-turn-queue/runner/start-prompt-queue-runs.ts
|
|
51995
52094
|
init_yield_to_event_loop();
|
|
51996
52095
|
|
|
51997
|
-
// src/prompt-turn-queue/client-report.ts
|
|
51998
|
-
function sendPromptQueueClientReport(ws, queues) {
|
|
51999
|
-
if (!ws) return false;
|
|
52000
|
-
const wireQueues = {};
|
|
52001
|
-
for (const [queueKey, rows] of Object.entries(queues)) {
|
|
52002
|
-
wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
|
|
52003
|
-
}
|
|
52004
|
-
sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
|
|
52005
|
-
return true;
|
|
52006
|
-
}
|
|
52007
|
-
|
|
52008
52096
|
// src/prompt-turn-queue/runner/queue-selection.ts
|
|
52009
52097
|
function pickNextRunnableTurn(turns) {
|
|
52010
52098
|
for (const t of turns) {
|
|
@@ -52168,29 +52256,20 @@ async function startPromptQueueRuns(entries, deps) {
|
|
|
52168
52256
|
}
|
|
52169
52257
|
|
|
52170
52258
|
// src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
|
|
52259
|
+
var SLOW_QUEUE_SYNC_MS = 2e3;
|
|
52171
52260
|
async function applyPromptQueueStateFromServer(msg, deps) {
|
|
52172
52261
|
const raw = msg.queues;
|
|
52173
52262
|
if (!raw || typeof raw !== "object") return;
|
|
52263
|
+
const startedAt = Date.now();
|
|
52174
52264
|
const entries = promptQueueSnapshotEntries(raw);
|
|
52175
52265
|
await persistPromptQueueSnapshot(entries);
|
|
52176
52266
|
await handlePromptQueueCancellations(entries, deps);
|
|
52177
52267
|
const started = await startPromptQueueRuns(entries, deps);
|
|
52178
52268
|
await dispatchStartedPromptQueueRuns(entries, started, deps);
|
|
52179
|
-
|
|
52180
|
-
|
|
52181
|
-
|
|
52182
|
-
|
|
52183
|
-
if (!runId) return false;
|
|
52184
|
-
const queueKey = deleteRunIdQueueKey(runId);
|
|
52185
|
-
if (!queueKey) return false;
|
|
52186
|
-
const f = await readPersistedQueue(queueKey);
|
|
52187
|
-
if (!f) return false;
|
|
52188
|
-
const t = f.turns.find((x) => x.turnId === runId);
|
|
52189
|
-
if (!t) return false;
|
|
52190
|
-
t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
|
|
52191
|
-
await writePersistedQueue(f);
|
|
52192
|
-
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
|
|
52193
|
-
return true;
|
|
52269
|
+
const durationMs = Date.now() - startedAt;
|
|
52270
|
+
if (durationMs >= SLOW_QUEUE_SYNC_MS) {
|
|
52271
|
+
deps.log(`[Queue] Queue state sync and dispatch took ${durationMs}ms.`);
|
|
52272
|
+
}
|
|
52194
52273
|
}
|
|
52195
52274
|
|
|
52196
52275
|
// src/agents/acp/from-bridge/bridge-prompt-wiring.ts
|
|
@@ -52267,59 +52346,93 @@ function parseWorktreeBaseBranches(msg) {
|
|
|
52267
52346
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
52268
52347
|
}
|
|
52269
52348
|
|
|
52270
|
-
// src/agents/acp/from-bridge/
|
|
52349
|
+
// src/agents/acp/from-bridge/parse-follow-up-prompt-fields.ts
|
|
52350
|
+
function parseFollowUpFieldsFromPromptMessage(msg) {
|
|
52351
|
+
const value = msg.followUpCatalogPromptId;
|
|
52352
|
+
return {
|
|
52353
|
+
followUpCatalogPromptId: typeof value === "string" && value.trim() !== "" ? value.trim() : null
|
|
52354
|
+
};
|
|
52355
|
+
}
|
|
52356
|
+
|
|
52357
|
+
// src/agents/acp/from-bridge/prepare-bridge-prompt-git-state.ts
|
|
52271
52358
|
import { execFile as execFile8 } from "node:child_process";
|
|
52272
52359
|
import { promisify as promisify9 } from "node:util";
|
|
52360
|
+
|
|
52361
|
+
// src/agents/acp/from-bridge/git-state-preparation-timeout.ts
|
|
52362
|
+
async function awaitGitStatePreparation(options) {
|
|
52363
|
+
const { label, timeoutMs, work, fallback, log: log2 } = options;
|
|
52364
|
+
let timer;
|
|
52365
|
+
try {
|
|
52366
|
+
return await Promise.race([
|
|
52367
|
+
work,
|
|
52368
|
+
new Promise((resolve37) => {
|
|
52369
|
+
timer = setTimeout(() => {
|
|
52370
|
+
log2(`[Agent] ${label} exceeded ${timeoutMs}ms; continuing without it.`);
|
|
52371
|
+
resolve37(fallback);
|
|
52372
|
+
}, timeoutMs);
|
|
52373
|
+
timer.unref?.();
|
|
52374
|
+
})
|
|
52375
|
+
]);
|
|
52376
|
+
} finally {
|
|
52377
|
+
if (timer) clearTimeout(timer);
|
|
52378
|
+
}
|
|
52379
|
+
}
|
|
52380
|
+
|
|
52381
|
+
// src/agents/acp/from-bridge/prepare-bridge-prompt-git-state.ts
|
|
52273
52382
|
var execFileAsync7 = promisify9(execFile8);
|
|
52383
|
+
var GIT_STATE_DISCOVERY_TIMEOUT_MS = 2e3;
|
|
52274
52384
|
async function readGitBranch(cwd) {
|
|
52275
52385
|
try {
|
|
52276
|
-
const { stdout } = await execFileAsync7("git", ["branch", "--show-current"], {
|
|
52277
|
-
|
|
52278
|
-
|
|
52386
|
+
const { stdout } = await execFileAsync7("git", ["branch", "--show-current"], {
|
|
52387
|
+
cwd,
|
|
52388
|
+
maxBuffer: 64 * 1024,
|
|
52389
|
+
timeout: GIT_STATE_DISCOVERY_TIMEOUT_MS
|
|
52390
|
+
});
|
|
52391
|
+
return stdout.trim() || null;
|
|
52279
52392
|
} catch {
|
|
52280
52393
|
return null;
|
|
52281
52394
|
}
|
|
52282
52395
|
}
|
|
52283
|
-
async function
|
|
52396
|
+
async function prepareBridgePromptGitState(params) {
|
|
52284
52397
|
const { getWs, log: log2, sessionWorktreeManager, sessionId, runId, effectiveCwd } = params;
|
|
52285
|
-
const
|
|
52286
|
-
|
|
52398
|
+
const repoCheckoutPaths = await awaitGitStatePreparation({
|
|
52399
|
+
label: "Session worktree discovery",
|
|
52400
|
+
timeoutMs: GIT_STATE_DISCOVERY_TIMEOUT_MS,
|
|
52401
|
+
work: sessionWorktreeManager.ensureRepoCheckoutPathsForSessionAsync(sessionId),
|
|
52402
|
+
fallback: void 0,
|
|
52403
|
+
log: log2
|
|
52404
|
+
});
|
|
52287
52405
|
const repoRoots = await resolveSnapshotRepoRoots({
|
|
52288
52406
|
worktreePaths: repoCheckoutPaths,
|
|
52289
52407
|
fallbackCwd: effectiveCwd,
|
|
52290
52408
|
sessionId: sessionId?.trim() || void 0,
|
|
52291
52409
|
log: log2
|
|
52292
52410
|
});
|
|
52293
|
-
|
|
52294
|
-
|
|
52295
|
-
const
|
|
52296
|
-
|
|
52297
|
-
sendWsMessage(s, {
|
|
52411
|
+
const socket = getWs();
|
|
52412
|
+
if (socket && sessionId) {
|
|
52413
|
+
const usesWorktree = sessionWorktreeManager.usesWorktreeSession(sessionId);
|
|
52414
|
+
sendWsMessage(socket, {
|
|
52298
52415
|
type: "session_git_context_report",
|
|
52299
52416
|
sessionId,
|
|
52300
|
-
cliGitBranch,
|
|
52301
|
-
agentUsesWorktree:
|
|
52302
|
-
sessionParent:
|
|
52303
|
-
sessionParentPath:
|
|
52417
|
+
cliGitBranch: repoRoots.length > 0 ? await readGitBranch(effectiveCwd) : null,
|
|
52418
|
+
agentUsesWorktree: usesWorktree,
|
|
52419
|
+
sessionParent: usesWorktree ? "worktrees_root" : "bridge_root",
|
|
52420
|
+
sessionParentPath: usesWorktree ? sessionWorktreeManager.getIsolatedSessionParentPathForSession(sessionId) ?? effectiveCwd : getBridgeRoot()
|
|
52304
52421
|
});
|
|
52305
52422
|
}
|
|
52306
|
-
if (
|
|
52307
|
-
const
|
|
52308
|
-
sendWsMessage(
|
|
52423
|
+
if (socket && sessionId && runId) {
|
|
52424
|
+
const snapshot = repoRoots.length > 0 ? await capturePreTurnSnapshot({ runId, repoRoots, agentCwd: effectiveCwd, log: log2 }) : { ok: false };
|
|
52425
|
+
sendWsMessage(socket, {
|
|
52309
52426
|
type: "pre_turn_snapshot_report",
|
|
52310
52427
|
sessionId,
|
|
52311
52428
|
turnId: runId,
|
|
52312
|
-
captured:
|
|
52429
|
+
captured: snapshot.ok
|
|
52313
52430
|
});
|
|
52314
52431
|
}
|
|
52315
52432
|
}
|
|
52316
|
-
function parseFollowUpFieldsFromPromptMessage(msg) {
|
|
52317
|
-
const followUpCatalogPromptId = typeof msg.followUpCatalogPromptId === "string" && msg.followUpCatalogPromptId.trim() !== "" ? msg.followUpCatalogPromptId.trim() : null;
|
|
52318
|
-
return { followUpCatalogPromptId };
|
|
52319
|
-
}
|
|
52320
52433
|
|
|
52321
|
-
// src/agents/acp/from-bridge/handle-bridge-prompt/
|
|
52322
|
-
async function
|
|
52434
|
+
// src/agents/acp/from-bridge/handle-bridge-prompt/prepare-git-state-and-run-prompt.ts
|
|
52435
|
+
async function prepareGitStateAndRunPrompt(params) {
|
|
52323
52436
|
const {
|
|
52324
52437
|
deps,
|
|
52325
52438
|
msg,
|
|
@@ -52338,7 +52451,7 @@ async function runPreambleAndPrompt(params) {
|
|
|
52338
52451
|
senders: { sendResult, sendSessionUpdate }
|
|
52339
52452
|
} = params;
|
|
52340
52453
|
const effectiveCwd = resolveSessionParentPathForAgentProcess(resolvedCwd);
|
|
52341
|
-
await
|
|
52454
|
+
await prepareBridgePromptGitState({
|
|
52342
52455
|
getWs,
|
|
52343
52456
|
log: log2,
|
|
52344
52457
|
sessionWorktreeManager,
|
|
@@ -52382,17 +52495,14 @@ function handleBridgePrompt(msg, deps) {
|
|
|
52382
52495
|
log2(
|
|
52383
52496
|
`[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).`
|
|
52384
52497
|
);
|
|
52385
|
-
senders.
|
|
52386
|
-
|
|
52387
|
-
|
|
52388
|
-
|
|
52389
|
-
|
|
52390
|
-
|
|
52391
|
-
|
|
52392
|
-
|
|
52393
|
-
},
|
|
52394
|
-
["error"]
|
|
52395
|
-
);
|
|
52498
|
+
senders.sendResult({
|
|
52499
|
+
type: "prompt_result",
|
|
52500
|
+
...promptId ? { id: promptId } : {},
|
|
52501
|
+
...sessionId ? { sessionId } : {},
|
|
52502
|
+
...runId ? { runId } : {},
|
|
52503
|
+
success: false,
|
|
52504
|
+
error: "Empty or missing prompt text from the bridge; this turn was not sent to the agent."
|
|
52505
|
+
});
|
|
52396
52506
|
return;
|
|
52397
52507
|
}
|
|
52398
52508
|
const isNewSession = msg.isNewSession === true;
|
|
@@ -52412,7 +52522,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
52412
52522
|
sessionParentPath,
|
|
52413
52523
|
...worktreeBaseBranches ? { worktreeBaseBranches } : {}
|
|
52414
52524
|
}).then(
|
|
52415
|
-
(cwd) =>
|
|
52525
|
+
(cwd) => prepareGitStateAndRunPrompt({
|
|
52416
52526
|
deps,
|
|
52417
52527
|
msg,
|
|
52418
52528
|
getWs,
|
|
@@ -52431,7 +52541,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
52431
52541
|
})
|
|
52432
52542
|
).catch((err) => {
|
|
52433
52543
|
log2(`[Agent] Session parent path resolve failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
52434
|
-
void
|
|
52544
|
+
void prepareGitStateAndRunPrompt({
|
|
52435
52545
|
deps,
|
|
52436
52546
|
msg,
|
|
52437
52547
|
getWs,
|