@buildautomaton/cli 0.1.77 → 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/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
- var cliSqlite, safeCloseCliSqliteDatabase, closeAllCliSqliteConnections, openCliSqliteConnection, withCliSqliteSync, withCliSqlite, ensureCliSqliteInitialized;
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.77".length > 0 ? "0.1.77" : "0.0.0-dev";
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;
@@ -33820,13 +33827,15 @@ import { existsSync as existsSync4, statSync } from "node:fs";
33820
33827
  // src/git/get-git-repo-root-sync.ts
33821
33828
  import { execFileSync as execFileSync3 } from "node:child_process";
33822
33829
  import * as path27 from "node:path";
33830
+ var GIT_LOOKUP_TIMEOUT_MS = 2e3;
33823
33831
  function getGitRepoRootSync(startDir) {
33824
33832
  try {
33825
33833
  const out = execFileSync3("git", ["rev-parse", "--show-toplevel"], {
33826
33834
  cwd: path27.resolve(startDir),
33827
33835
  encoding: "utf8",
33828
33836
  stdio: ["ignore", "pipe", "ignore"],
33829
- maxBuffer: 1024 * 1024
33837
+ maxBuffer: 1024 * 1024,
33838
+ timeout: GIT_LOOKUP_TIMEOUT_MS
33830
33839
  }).trim();
33831
33840
  return out ? path27.resolve(out) : null;
33832
33841
  } catch {
@@ -33838,6 +33847,7 @@ function getGitRepoRootSync(startDir) {
33838
33847
  import { execFileSync as execFileSync4 } from "node:child_process";
33839
33848
  import { readFileSync as readFileSync4 } from "node:fs";
33840
33849
  import * as path28 from "node:path";
33850
+ var GIT_FILE_READ_TIMEOUT_MS = 2e3;
33841
33851
  function resolveWorkspaceFilePath(sessionParentPath, rawPath) {
33842
33852
  const trimmed2 = rawPath.trim();
33843
33853
  if (!trimmed2) return null;
@@ -33899,7 +33909,8 @@ function readGitHeadBlob(sessionParentPath, displayPath) {
33899
33909
  return execFileSync4("git", ["show", `HEAD:${displayPath}`], {
33900
33910
  cwd: execCwd,
33901
33911
  encoding: "utf8",
33902
- maxBuffer: 50 * 1024 * 1024
33912
+ maxBuffer: 50 * 1024 * 1024,
33913
+ timeout: GIT_FILE_READ_TIMEOUT_MS
33903
33914
  });
33904
33915
  } catch {
33905
33916
  return "";
@@ -33907,6 +33918,7 @@ function readGitHeadBlob(sessionParentPath, displayPath) {
33907
33918
  }
33908
33919
 
33909
33920
  // src/agents/acp/session-file-change-path-kind.ts
33921
+ var GIT_PATH_KIND_TIMEOUT_MS = 2e3;
33910
33922
  function gitHeadPathObjectType(sessionParentPath, displayPath) {
33911
33923
  if (!displayPath || displayPath.includes("..")) return null;
33912
33924
  const gitRoot = getGitRepoRootSync(sessionParentPath);
@@ -33914,7 +33926,8 @@ function gitHeadPathObjectType(sessionParentPath, displayPath) {
33914
33926
  try {
33915
33927
  return execFileSync5("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
33916
33928
  cwd: gitRoot,
33917
- encoding: "utf8"
33929
+ encoding: "utf8",
33930
+ timeout: GIT_PATH_KIND_TIMEOUT_MS
33918
33931
  }).trim();
33919
33932
  } catch {
33920
33933
  return null;
@@ -35022,23 +35035,30 @@ function augmentPromptResultAuthFields(agentType, errorText) {
35022
35035
  }
35023
35036
 
35024
35037
  // src/agents/planning/submit-planning-todos-for-turn.ts
35038
+ var PLANNING_TODO_SUBMIT_TIMEOUT_MS = 3e3;
35025
35039
  async function submitPlanningTodosForTurn(params) {
35026
35040
  const token = params.getCloudAccessToken();
35027
35041
  if (!token.trim()) return { ok: false, error: "Missing cloud access token" };
35028
35042
  const base = params.cloudApiBaseUrl.replace(/\/$/, "");
35029
35043
  const url2 = `${base}/internal/sessions/todos/submit`;
35030
- const res = await fetch(url2, {
35031
- method: "POST",
35032
- headers: {
35033
- Authorization: `Bearer ${token}`,
35034
- "Content-Type": "application/json"
35035
- },
35036
- body: JSON.stringify({
35037
- sessionId: params.sessionId,
35038
- turnId: params.turnId,
35039
- items: params.items
35040
- })
35041
- });
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
+ }
35042
35062
  if (!res.ok) {
35043
35063
  const body = await res.json().catch(() => null);
35044
35064
  return { ok: false, error: body?.error ?? `Planning todo submit failed (${res.status})` };
@@ -36017,6 +36037,7 @@ async function resolveSendPromptImages(params) {
36017
36037
  }
36018
36038
 
36019
36039
  // src/agents/acp/prompts/send-prompt-to-agent.ts
36040
+ var SLOW_ACP_PROMPT_MS = 5e3;
36020
36041
  async function sendPromptToAgent(options) {
36021
36042
  const {
36022
36043
  handle,
@@ -36063,7 +36084,12 @@ async function sendPromptToAgent(options) {
36063
36084
  sendResult(imagesResolved.errorResult);
36064
36085
  return;
36065
36086
  }
36087
+ const promptStartedAt = Date.now();
36066
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
+ }
36067
36093
  await finalizeAndSendPromptResult({
36068
36094
  result,
36069
36095
  sessionId,
@@ -46479,9 +46505,13 @@ import * as fs49 from "node:fs";
46479
46505
  import * as path70 from "node:path";
46480
46506
 
46481
46507
  // src/git/snapshot/git.ts
46508
+ var SNAPSHOT_GIT_TIMEOUT_MS = 5e3;
46482
46509
  async function gitStashCreate(repoRoot, log2) {
46483
46510
  try {
46484
- const { stdout } = await execGitFile(["stash", "create"], { cwd: repoRoot });
46511
+ const { stdout } = await execGitFile(["stash", "create"], {
46512
+ cwd: repoRoot,
46513
+ timeout: SNAPSHOT_GIT_TIMEOUT_MS
46514
+ });
46485
46515
  return stdout.trim();
46486
46516
  } catch (e) {
46487
46517
  log2(
@@ -46492,7 +46522,10 @@ async function gitStashCreate(repoRoot, log2) {
46492
46522
  }
46493
46523
  async function gitUntrackedPaths(repoRoot, log2) {
46494
46524
  try {
46495
- const { stdout } = await execGitFile(["ls-files", "--others", "--exclude-standard"], { cwd: repoRoot });
46525
+ const { stdout } = await execGitFile(["ls-files", "--others", "--exclude-standard"], {
46526
+ cwd: repoRoot,
46527
+ timeout: SNAPSHOT_GIT_TIMEOUT_MS
46528
+ });
46496
46529
  return stdout.split("\n").map((l) => l.trim()).filter(Boolean);
46497
46530
  } catch (e) {
46498
46531
  log2(
@@ -49177,14 +49210,20 @@ async function startPromptQueueRuns(entries, deps) {
49177
49210
  }
49178
49211
 
49179
49212
  // src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
49213
+ var SLOW_QUEUE_SYNC_MS = 2e3;
49180
49214
  async function applyPromptQueueStateFromServer(msg, deps) {
49181
49215
  const raw = msg.queues;
49182
49216
  if (!raw || typeof raw !== "object") return;
49217
+ const startedAt = Date.now();
49183
49218
  const entries = promptQueueSnapshotEntries(raw);
49184
49219
  await persistPromptQueueSnapshot(entries);
49185
49220
  await handlePromptQueueCancellations(entries, deps);
49186
49221
  const started = await startPromptQueueRuns(entries, deps);
49187
49222
  await dispatchStartedPromptQueueRuns(entries, started, deps);
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
+ }
49188
49227
  }
49189
49228
 
49190
49229
  // src/agents/acp/from-bridge/bridge-prompt-wiring.ts
@@ -49261,59 +49300,93 @@ function parseWorktreeBaseBranches(msg) {
49261
49300
  return Object.keys(out).length > 0 ? out : void 0;
49262
49301
  }
49263
49302
 
49264
- // src/agents/acp/from-bridge/bridge-prompt-preamble.ts
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
49265
49312
  import { execFile as execFile8 } from "node:child_process";
49266
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
49267
49336
  var execFileAsync7 = promisify9(execFile8);
49337
+ var GIT_STATE_DISCOVERY_TIMEOUT_MS = 2e3;
49268
49338
  async function readGitBranch(cwd) {
49269
49339
  try {
49270
- const { stdout } = await execFileAsync7("git", ["branch", "--show-current"], { cwd, maxBuffer: 64 * 1024 });
49271
- const b = stdout.trim();
49272
- return b || null;
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;
49273
49346
  } catch {
49274
49347
  return null;
49275
49348
  }
49276
49349
  }
49277
- async function runBridgePromptPreamble(params) {
49350
+ async function prepareBridgePromptGitState(params) {
49278
49351
  const { getWs, log: log2, sessionWorktreeManager, sessionId, runId, effectiveCwd } = params;
49279
- const s = getWs();
49280
- const repoCheckoutPaths = await sessionWorktreeManager.ensureRepoCheckoutPathsForSessionAsync(sessionId);
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
+ });
49281
49359
  const repoRoots = await resolveSnapshotRepoRoots({
49282
49360
  worktreePaths: repoCheckoutPaths,
49283
49361
  fallbackCwd: effectiveCwd,
49284
49362
  sessionId: sessionId?.trim() || void 0,
49285
49363
  log: log2
49286
49364
  });
49287
- if (s && sessionId) {
49288
- const usesWt = sessionWorktreeManager.usesWorktreeSession(sessionId);
49289
- const cliGitBranch = repoRoots.length > 0 ? await readGitBranch(effectiveCwd) : null;
49290
- const isolatedSessionParentPath = sessionWorktreeManager.getIsolatedSessionParentPathForSession(sessionId);
49291
- sendWsMessage(s, {
49365
+ const socket = getWs();
49366
+ if (socket && sessionId) {
49367
+ const usesWorktree = sessionWorktreeManager.usesWorktreeSession(sessionId);
49368
+ sendWsMessage(socket, {
49292
49369
  type: "session_git_context_report",
49293
49370
  sessionId,
49294
- cliGitBranch,
49295
- agentUsesWorktree: usesWt,
49296
- sessionParent: usesWt ? "worktrees_root" : "bridge_root",
49297
- sessionParentPath: usesWt ? isolatedSessionParentPath ?? effectiveCwd : getBridgeRoot()
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()
49298
49375
  });
49299
49376
  }
49300
- if (s && sessionId && runId) {
49301
- const cap = repoRoots.length > 0 ? await capturePreTurnSnapshot({ runId, repoRoots, agentCwd: effectiveCwd, log: log2 }) : { ok: false, error: "No git repos" };
49302
- sendWsMessage(s, {
49377
+ if (socket && sessionId && runId) {
49378
+ const snapshot = repoRoots.length > 0 ? await capturePreTurnSnapshot({ runId, repoRoots, agentCwd: effectiveCwd, log: log2 }) : { ok: false };
49379
+ sendWsMessage(socket, {
49303
49380
  type: "pre_turn_snapshot_report",
49304
49381
  sessionId,
49305
49382
  turnId: runId,
49306
- captured: cap.ok
49383
+ captured: snapshot.ok
49307
49384
  });
49308
49385
  }
49309
49386
  }
49310
- function parseFollowUpFieldsFromPromptMessage(msg) {
49311
- const followUpCatalogPromptId = typeof msg.followUpCatalogPromptId === "string" && msg.followUpCatalogPromptId.trim() !== "" ? msg.followUpCatalogPromptId.trim() : null;
49312
- return { followUpCatalogPromptId };
49313
- }
49314
49387
 
49315
- // src/agents/acp/from-bridge/handle-bridge-prompt/run-preamble-and-prompt.ts
49316
- async function runPreambleAndPrompt(params) {
49388
+ // src/agents/acp/from-bridge/handle-bridge-prompt/prepare-git-state-and-run-prompt.ts
49389
+ async function prepareGitStateAndRunPrompt(params) {
49317
49390
  const {
49318
49391
  deps,
49319
49392
  msg,
@@ -49332,7 +49405,7 @@ async function runPreambleAndPrompt(params) {
49332
49405
  senders: { sendResult, sendSessionUpdate }
49333
49406
  } = params;
49334
49407
  const effectiveCwd = resolveSessionParentPathForAgentProcess(resolvedCwd);
49335
- await runBridgePromptPreamble({
49408
+ await prepareBridgePromptGitState({
49336
49409
  getWs,
49337
49410
  log: log2,
49338
49411
  sessionWorktreeManager,
@@ -49403,7 +49476,7 @@ function handleBridgePrompt(msg, deps) {
49403
49476
  sessionParentPath,
49404
49477
  ...worktreeBaseBranches ? { worktreeBaseBranches } : {}
49405
49478
  }).then(
49406
- (cwd) => runPreambleAndPrompt({
49479
+ (cwd) => prepareGitStateAndRunPrompt({
49407
49480
  deps,
49408
49481
  msg,
49409
49482
  getWs,
@@ -49422,7 +49495,7 @@ function handleBridgePrompt(msg, deps) {
49422
49495
  })
49423
49496
  ).catch((err) => {
49424
49497
  log2(`[Agent] Session parent path resolve failed: ${err instanceof Error ? err.message : String(err)}`);
49425
- void runPreambleAndPrompt({
49498
+ void prepareGitStateAndRunPrompt({
49426
49499
  deps,
49427
49500
  msg,
49428
49501
  getWs,