@buildautomaton/cli 0.1.30 → 0.1.31

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 CHANGED
@@ -25064,7 +25064,7 @@ var {
25064
25064
  } = import_index.default;
25065
25065
 
25066
25066
  // src/cli-version.ts
25067
- var CLI_VERSION = "0.1.30".length > 0 ? "0.1.30" : "0.0.0-dev";
25067
+ var CLI_VERSION = "0.1.31".length > 0 ? "0.1.31" : "0.0.0-dev";
25068
25068
 
25069
25069
  // src/cli/defaults.ts
25070
25070
  var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
@@ -26991,6 +26991,13 @@ function migrateCliSqlite(db) {
26991
26991
 
26992
26992
  // src/sqlite/cli-database.ts
26993
26993
  var { Database: SqliteDatabase } = sqliteWasm;
26994
+ function applyCliSqliteMemoryPragmas(db) {
26995
+ try {
26996
+ db.run("PRAGMA cache_size = -8192");
26997
+ db.run("PRAGMA temp_store = FILE");
26998
+ } catch {
26999
+ }
27000
+ }
26994
27001
  var openDatabases = /* @__PURE__ */ new Map();
26995
27002
  var processExitCloseRegistered = false;
26996
27003
  function registerProcessExitSqliteClose() {
@@ -27027,6 +27034,7 @@ function getCliDatabase(options) {
27027
27034
  ensureCliSqliteParentDir(sqlitePath);
27028
27035
  const db = new SqliteDatabase(sqlitePath);
27029
27036
  try {
27037
+ applyCliSqliteMemoryPragmas(db);
27030
27038
  migrateCliSqlite(db);
27031
27039
  importCliSqliteLegacyDiskData(db, options?.logLegacyMigration);
27032
27040
  } catch (e) {
@@ -34670,6 +34678,28 @@ function sendGitHeadVsWorkspaceForToolPaths(mergedPaths, sentPaths, send, sessio
34670
34678
  }
34671
34679
  }
34672
34680
 
34681
+ // src/agents/acp/hooks/bridge-on-session-update/send-session-info-title-update.ts
34682
+ function extractSessionInfoTitle(params) {
34683
+ if (!params || typeof params !== "object") return null;
34684
+ const p = params;
34685
+ const title = typeof p.title === "string" ? p.title.trim() : "";
34686
+ return title ? title : null;
34687
+ }
34688
+ function sendSessionInfoTitleUpdate(params) {
34689
+ const title = extractSessionInfoTitle(params.payload);
34690
+ if (!title || !params.runId || !params.send) return;
34691
+ try {
34692
+ params.send({
34693
+ type: "session_title_update",
34694
+ ...params.sessionId ? { sessionId: params.sessionId } : {},
34695
+ runId: params.runId,
34696
+ title
34697
+ });
34698
+ } catch (err) {
34699
+ params.log(`[Bridge service] Session title update send failed: ${errorMessage(err)}`);
34700
+ }
34701
+ }
34702
+
34673
34703
  // src/agents/acp/hooks/bridge-on-session-update/create-bridge-on-session-update.ts
34674
34704
  function createBridgeOnSessionUpdate(opts) {
34675
34705
  const { routing, getSendSessionUpdate, log: log2, sessionParentPath } = opts;
@@ -34685,6 +34715,10 @@ function createBridgeOnSessionUpdate(opts) {
34685
34715
  if (updateKind === "config_option_update") {
34686
34716
  return;
34687
34717
  }
34718
+ if (updateKind === "session_info_update") {
34719
+ sendSessionInfoTitleUpdate({ payload: params, runId, sessionId, send, log: log2 });
34720
+ return;
34721
+ }
34688
34722
  const isCompletedToolCallUpdate = updateKind === "tool_call_update" && isCompletedToolStatus(p.status);
34689
34723
  const toolName = p.toolCall?.name ?? p.tool_call?.name ?? "";
34690
34724
  const isToolUpdate = updateKind === "tool_call" || updateKind === "tool_call_update" || typeof toolName === "string" && toolName.length > 0;
@@ -36418,37 +36452,33 @@ function yieldToEventLoop() {
36418
36452
  // src/files/index/walk-workspace-tree.ts
36419
36453
  import fs25 from "node:fs";
36420
36454
  import path28 from "node:path";
36421
- async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
36455
+ function shouldSkipWorkspaceWalkEntry(name) {
36456
+ return name.startsWith(".");
36457
+ }
36458
+ function walkWorkspaceTreeSync(dir, baseDir, onFile) {
36422
36459
  let names;
36423
36460
  try {
36424
- names = await fs25.promises.readdir(dir);
36461
+ names = fs25.readdirSync(dir);
36425
36462
  } catch {
36426
36463
  return;
36427
36464
  }
36428
36465
  for (const name of names) {
36429
- if (name.startsWith(".")) continue;
36430
- if (state.n > 0 && state.n % INDEX_WORK_YIELD_EVERY === 0) {
36431
- await yieldToEventLoop();
36432
- }
36433
- state.n++;
36466
+ if (shouldSkipWorkspaceWalkEntry(name)) continue;
36434
36467
  const full = path28.join(dir, name);
36435
36468
  let stat3;
36436
36469
  try {
36437
- stat3 = await fs25.promises.stat(full);
36470
+ stat3 = fs25.statSync(full);
36438
36471
  } catch {
36439
36472
  continue;
36440
36473
  }
36441
36474
  const relative5 = path28.relative(baseDir, full).replace(/\\/g, "/");
36442
36475
  if (stat3.isDirectory()) {
36443
- await walkWorkspaceTreeAsync(full, baseDir, out, state);
36476
+ walkWorkspaceTreeSync(full, baseDir, onFile);
36444
36477
  } else if (stat3.isFile()) {
36445
- out.push(relative5);
36478
+ onFile(relative5);
36446
36479
  }
36447
36480
  }
36448
36481
  }
36449
- function createWalkYieldState() {
36450
- return { n: 0 };
36451
- }
36452
36482
 
36453
36483
  // src/files/index/file-index-sqlite-lock.ts
36454
36484
  import fs26 from "node:fs";
@@ -36481,20 +36511,29 @@ function withFileIndexSqliteLock(fn) {
36481
36511
  }
36482
36512
 
36483
36513
  // src/files/index/build-file-index.ts
36484
- function sortPaths(paths) {
36485
- paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
36486
- }
36487
- function persistPathsToSqlite(resolved, paths) {
36514
+ var FILE_INDEX_INSERT_BUFFER = 2048;
36515
+ function persistFileIndexForResolvedCwd(resolved) {
36488
36516
  const db = getCliDatabase();
36489
36517
  const h = getCwdHashForFileIndex(resolved);
36518
+ const buf = [];
36519
+ let pathCount = 0;
36490
36520
  db.run("BEGIN IMMEDIATE");
36491
36521
  try {
36492
36522
  db.run("DELETE FROM file_index_path WHERE cwd_hash = ?", [h]);
36493
36523
  const ins = db.prepare("INSERT INTO file_index_path (cwd_hash, path) VALUES (?, ?)");
36494
36524
  try {
36495
- for (const rel of paths) {
36496
- ins.run([h, rel]);
36497
- }
36525
+ const flushBuf = () => {
36526
+ for (const rel of buf) {
36527
+ ins.run([h, rel]);
36528
+ }
36529
+ pathCount += buf.length;
36530
+ buf.length = 0;
36531
+ };
36532
+ walkWorkspaceTreeSync(resolved, resolved, (rel) => {
36533
+ buf.push(rel);
36534
+ if (buf.length >= FILE_INDEX_INSERT_BUFFER) flushBuf();
36535
+ });
36536
+ flushBuf();
36498
36537
  } finally {
36499
36538
  ins.finalize();
36500
36539
  }
@@ -36506,22 +36545,26 @@ function persistPathsToSqlite(resolved, paths) {
36506
36545
  }
36507
36546
  throw e;
36508
36547
  }
36548
+ return pathCount;
36509
36549
  }
36510
36550
  async function buildFileIndexAsync(cwd) {
36511
36551
  return withFileIndexSqliteLock(async () => {
36512
36552
  const resolved = path29.resolve(cwd);
36513
- const paths = [];
36514
- await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
36515
36553
  await yieldToEventLoop();
36516
- sortPaths(paths);
36517
- persistPathsToSqlite(resolved, paths);
36518
- return { pathCount: paths.length };
36554
+ const pathCount = persistFileIndexForResolvedCwd(resolved);
36555
+ await yieldToEventLoop();
36556
+ return { pathCount };
36519
36557
  });
36520
36558
  }
36521
36559
 
36522
36560
  // src/files/index/ensure-file-index.ts
36523
36561
  import path30 from "node:path";
36524
36562
 
36563
+ // src/files/index/file-index-dependency-path.ts
36564
+ function sqliteExprBridgeFileIndexDependencyRank() {
36565
+ return `CASE WHEN lower(path) = 'node_modules' OR lower(path) LIKE 'node_modules/%' OR lower(path) LIKE '%/node_modules/%' OR lower(path) = 'bower_components' OR lower(path) LIKE 'bower_components/%' OR lower(path) LIKE '%/bower_components/%' THEN 1 ELSE 0 END`;
36566
+ }
36567
+
36525
36568
  // src/files/index/search-file-index.ts
36526
36569
  function escapeLikePattern(fragment) {
36527
36570
  return fragment.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
@@ -36546,8 +36589,9 @@ function searchBridgeFilePaths(resolvedCwd, query, limit = 100) {
36546
36589
  const h = getCwdHashForFileIndex(resolvedCwd);
36547
36590
  const pattern = `%${escapeLikePattern(q)}%`;
36548
36591
  const lim = Math.max(0, Math.min(1e4, Math.floor(limit)));
36592
+ const depRank = sqliteExprBridgeFileIndexDependencyRank();
36549
36593
  const rows = db.all(
36550
- `SELECT path FROM file_index_path WHERE cwd_hash = ? AND lower(path) LIKE ? ESCAPE '\\' LIMIT ?`,
36594
+ `SELECT path FROM file_index_path WHERE cwd_hash = ? AND lower(path) LIKE ? ESCAPE '\\' ORDER BY ${depRank}, path LIMIT ?`,
36551
36595
  [h, pattern, lim]
36552
36596
  );
36553
36597
  return rows.map((r) => String(r.path));
@@ -36572,7 +36616,6 @@ async function ensureFileIndexAsync(cwd) {
36572
36616
  var DEBOUNCE_MS = 900;
36573
36617
  function shouldIgnoreRelative(rel) {
36574
36618
  const n = rel.replace(/\\/g, "/");
36575
- if (n.includes("/node_modules/") || n.startsWith("node_modules/")) return true;
36576
36619
  if (n.includes("/.git/") || n === ".git" || n.startsWith(".git/")) return true;
36577
36620
  if (n.includes("/.buildautomaton/") || n.startsWith(".buildautomaton/")) return true;
36578
36621
  return false;