@buildautomaton/cli 0.1.30 → 0.1.32
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 +315 -185
- package/dist/cli.js.map +4 -4
- package/dist/index.js +315 -185
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23962,7 +23962,7 @@ function installBridgeProcessResilience() {
|
|
|
23962
23962
|
}
|
|
23963
23963
|
|
|
23964
23964
|
// src/cli-version.ts
|
|
23965
|
-
var CLI_VERSION = "0.1.
|
|
23965
|
+
var CLI_VERSION = "0.1.32".length > 0 ? "0.1.32" : "0.0.0-dev";
|
|
23966
23966
|
|
|
23967
23967
|
// src/connection/heartbeat/constants.ts
|
|
23968
23968
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -25025,6 +25025,11 @@ function runPendingAuth(options) {
|
|
|
25025
25025
|
// src/sqlite/cli-database.ts
|
|
25026
25026
|
import sqliteWasm from "node-sqlite3-wasm";
|
|
25027
25027
|
|
|
25028
|
+
// src/runtime/yield-to-event-loop.ts
|
|
25029
|
+
function yieldToEventLoop() {
|
|
25030
|
+
return new Promise((resolve18) => setImmediate(resolve18));
|
|
25031
|
+
}
|
|
25032
|
+
|
|
25028
25033
|
// src/sqlite/cli-sqlite-paths.ts
|
|
25029
25034
|
import fs7 from "node:fs";
|
|
25030
25035
|
import path5 from "node:path";
|
|
@@ -25317,17 +25322,29 @@ function migrateCliSqlite(db) {
|
|
|
25317
25322
|
|
|
25318
25323
|
// src/sqlite/cli-database.ts
|
|
25319
25324
|
var { Database: SqliteDatabase } = sqliteWasm;
|
|
25320
|
-
var
|
|
25321
|
-
var
|
|
25322
|
-
|
|
25323
|
-
|
|
25324
|
-
|
|
25325
|
-
|
|
25326
|
-
|
|
25327
|
-
|
|
25328
|
-
|
|
25329
|
-
|
|
25330
|
-
}
|
|
25325
|
+
var CLI_SQLITE_SYNC_RETRY_MAX = 40;
|
|
25326
|
+
var CLI_SQLITE_ASYNC_RETRY_MAX = 60;
|
|
25327
|
+
var CLI_SQLITE_ASYNC_BASE_DELAY_MS = 20;
|
|
25328
|
+
function applyCliSqliteConcurrencyPragmas(db) {
|
|
25329
|
+
try {
|
|
25330
|
+
db.exec("PRAGMA journal_mode = WAL");
|
|
25331
|
+
} catch {
|
|
25332
|
+
}
|
|
25333
|
+
try {
|
|
25334
|
+
db.run("PRAGMA synchronous = NORMAL");
|
|
25335
|
+
} catch {
|
|
25336
|
+
}
|
|
25337
|
+
try {
|
|
25338
|
+
db.run("PRAGMA busy_timeout = 8000");
|
|
25339
|
+
} catch {
|
|
25340
|
+
}
|
|
25341
|
+
}
|
|
25342
|
+
function applyCliSqliteMemoryPragmas(db) {
|
|
25343
|
+
try {
|
|
25344
|
+
db.run("PRAGMA cache_size = -8192");
|
|
25345
|
+
db.run("PRAGMA temp_store = FILE");
|
|
25346
|
+
} catch {
|
|
25347
|
+
}
|
|
25331
25348
|
}
|
|
25332
25349
|
function safeCloseCliSqliteDatabase(db) {
|
|
25333
25350
|
if (db == null) return;
|
|
@@ -25337,32 +25354,86 @@ function safeCloseCliSqliteDatabase(db) {
|
|
|
25337
25354
|
}
|
|
25338
25355
|
}
|
|
25339
25356
|
function closeAllCliSqliteConnections() {
|
|
25340
|
-
|
|
25341
|
-
|
|
25357
|
+
}
|
|
25358
|
+
function isCliSqliteLockError(e) {
|
|
25359
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
25360
|
+
const lower = msg.toLowerCase();
|
|
25361
|
+
return lower.includes("database is locked") || lower.includes("sqlite_busy") || lower.includes("sqlite3_busy") || lower.includes("database") && lower.includes("locked");
|
|
25362
|
+
}
|
|
25363
|
+
function syncSleepMs(ms) {
|
|
25364
|
+
if (ms <= 0) return;
|
|
25365
|
+
try {
|
|
25366
|
+
const sab = new SharedArrayBuffer(4);
|
|
25367
|
+
const ia = new Int32Array(sab);
|
|
25368
|
+
Atomics.wait(ia, 0, 0, Math.min(ms, 1e4));
|
|
25369
|
+
} catch {
|
|
25370
|
+
const end = Date.now() + ms;
|
|
25371
|
+
while (Date.now() < end) {
|
|
25372
|
+
}
|
|
25342
25373
|
}
|
|
25343
|
-
openDatabases.clear();
|
|
25344
25374
|
}
|
|
25345
|
-
function
|
|
25375
|
+
function asyncDelayMs(ms) {
|
|
25376
|
+
return new Promise((resolve18) => setTimeout(resolve18, ms));
|
|
25377
|
+
}
|
|
25378
|
+
function openCliSqliteConnection(options) {
|
|
25346
25379
|
const sqlitePath = getCliSqlitePath();
|
|
25347
|
-
const existing = openDatabases.get(sqlitePath);
|
|
25348
|
-
if (existing?.isOpen) return existing;
|
|
25349
|
-
if (existing && !existing.isOpen) {
|
|
25350
|
-
safeCloseCliSqliteDatabase(existing);
|
|
25351
|
-
openDatabases.delete(sqlitePath);
|
|
25352
|
-
}
|
|
25353
25380
|
ensureCliSqliteParentDir(sqlitePath);
|
|
25354
25381
|
const db = new SqliteDatabase(sqlitePath);
|
|
25355
25382
|
try {
|
|
25383
|
+
applyCliSqliteConcurrencyPragmas(db);
|
|
25384
|
+
applyCliSqliteMemoryPragmas(db);
|
|
25356
25385
|
migrateCliSqlite(db);
|
|
25357
25386
|
importCliSqliteLegacyDiskData(db, options?.logLegacyMigration);
|
|
25358
25387
|
} catch (e) {
|
|
25359
25388
|
safeCloseCliSqliteDatabase(db);
|
|
25360
25389
|
throw e;
|
|
25361
25390
|
}
|
|
25362
|
-
openDatabases.set(sqlitePath, db);
|
|
25363
|
-
registerProcessExitSqliteClose();
|
|
25364
25391
|
return db;
|
|
25365
25392
|
}
|
|
25393
|
+
function withCliSqliteSync(fn, options) {
|
|
25394
|
+
for (let attempt = 1; attempt <= CLI_SQLITE_SYNC_RETRY_MAX; attempt++) {
|
|
25395
|
+
let db;
|
|
25396
|
+
try {
|
|
25397
|
+
db = openCliSqliteConnection(options);
|
|
25398
|
+
try {
|
|
25399
|
+
return fn(db);
|
|
25400
|
+
} finally {
|
|
25401
|
+
safeCloseCliSqliteDatabase(db);
|
|
25402
|
+
}
|
|
25403
|
+
} catch (e) {
|
|
25404
|
+
safeCloseCliSqliteDatabase(db);
|
|
25405
|
+
if (!isCliSqliteLockError(e) || attempt === CLI_SQLITE_SYNC_RETRY_MAX) throw e;
|
|
25406
|
+
syncSleepMs(Math.min(500, 12 * attempt));
|
|
25407
|
+
}
|
|
25408
|
+
}
|
|
25409
|
+
throw new Error("withCliSqliteSync: exhausted retries");
|
|
25410
|
+
}
|
|
25411
|
+
async function withCliSqlite(fn, options) {
|
|
25412
|
+
let lastError;
|
|
25413
|
+
for (let attempt = 1; attempt <= CLI_SQLITE_ASYNC_RETRY_MAX; attempt++) {
|
|
25414
|
+
let db;
|
|
25415
|
+
try {
|
|
25416
|
+
db = openCliSqliteConnection(options);
|
|
25417
|
+
try {
|
|
25418
|
+
return await Promise.resolve(fn(db));
|
|
25419
|
+
} finally {
|
|
25420
|
+
safeCloseCliSqliteDatabase(db);
|
|
25421
|
+
}
|
|
25422
|
+
} catch (e) {
|
|
25423
|
+
lastError = e;
|
|
25424
|
+
safeCloseCliSqliteDatabase(db);
|
|
25425
|
+
if (!isCliSqliteLockError(e) || attempt === CLI_SQLITE_ASYNC_RETRY_MAX) throw e;
|
|
25426
|
+
const delayMs = Math.min(600, CLI_SQLITE_ASYNC_BASE_DELAY_MS * attempt);
|
|
25427
|
+
await asyncDelayMs(delayMs);
|
|
25428
|
+
await yieldToEventLoop();
|
|
25429
|
+
}
|
|
25430
|
+
}
|
|
25431
|
+
if (lastError instanceof Error) throw lastError;
|
|
25432
|
+
throw new Error(String(lastError));
|
|
25433
|
+
}
|
|
25434
|
+
async function ensureCliSqliteInitialized(options) {
|
|
25435
|
+
await withCliSqlite(() => void 0, options);
|
|
25436
|
+
}
|
|
25366
25437
|
|
|
25367
25438
|
// src/connection/close-bridge-connection.ts
|
|
25368
25439
|
async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
|
|
@@ -31710,6 +31781,28 @@ function sendGitHeadVsWorkspaceForToolPaths(mergedPaths, sentPaths, send, sessio
|
|
|
31710
31781
|
}
|
|
31711
31782
|
}
|
|
31712
31783
|
|
|
31784
|
+
// src/agents/acp/hooks/bridge-on-session-update/send-session-info-title-update.ts
|
|
31785
|
+
function extractSessionInfoTitle(params) {
|
|
31786
|
+
if (!params || typeof params !== "object") return null;
|
|
31787
|
+
const p = params;
|
|
31788
|
+
const title = typeof p.title === "string" ? p.title.trim() : "";
|
|
31789
|
+
return title ? title : null;
|
|
31790
|
+
}
|
|
31791
|
+
function sendSessionInfoTitleUpdate(params) {
|
|
31792
|
+
const title = extractSessionInfoTitle(params.payload);
|
|
31793
|
+
if (!title || !params.runId || !params.send) return;
|
|
31794
|
+
try {
|
|
31795
|
+
params.send({
|
|
31796
|
+
type: "session_title_update",
|
|
31797
|
+
...params.sessionId ? { sessionId: params.sessionId } : {},
|
|
31798
|
+
runId: params.runId,
|
|
31799
|
+
title
|
|
31800
|
+
});
|
|
31801
|
+
} catch (err) {
|
|
31802
|
+
params.log(`[Bridge service] Session title update send failed: ${errorMessage(err)}`);
|
|
31803
|
+
}
|
|
31804
|
+
}
|
|
31805
|
+
|
|
31713
31806
|
// src/agents/acp/hooks/bridge-on-session-update/create-bridge-on-session-update.ts
|
|
31714
31807
|
function createBridgeOnSessionUpdate(opts) {
|
|
31715
31808
|
const { routing, getSendSessionUpdate, log: log2, sessionParentPath } = opts;
|
|
@@ -31725,6 +31818,10 @@ function createBridgeOnSessionUpdate(opts) {
|
|
|
31725
31818
|
if (updateKind === "config_option_update") {
|
|
31726
31819
|
return;
|
|
31727
31820
|
}
|
|
31821
|
+
if (updateKind === "session_info_update") {
|
|
31822
|
+
sendSessionInfoTitleUpdate({ payload: params, runId, sessionId, send, log: log2 });
|
|
31823
|
+
return;
|
|
31824
|
+
}
|
|
31728
31825
|
const isCompletedToolCallUpdate = updateKind === "tool_call_update" && isCompletedToolStatus(p.status);
|
|
31729
31826
|
const toolName = p.toolCall?.name ?? p.tool_call?.name ?? "";
|
|
31730
31827
|
const isToolUpdate = updateKind === "tool_call" || updateKind === "tool_call_update" || typeof toolName === "string" && toolName.length > 0;
|
|
@@ -31818,56 +31915,80 @@ function sessionKeyForCloudSessionId(cloudSessionId) {
|
|
|
31818
31915
|
}
|
|
31819
31916
|
function readLocalAgentSessionFile(cloudSessionId) {
|
|
31820
31917
|
try {
|
|
31821
|
-
|
|
31822
|
-
|
|
31823
|
-
|
|
31824
|
-
|
|
31825
|
-
|
|
31826
|
-
|
|
31827
|
-
|
|
31828
|
-
|
|
31829
|
-
|
|
31830
|
-
|
|
31831
|
-
|
|
31832
|
-
|
|
31833
|
-
|
|
31834
|
-
|
|
31918
|
+
return withCliSqliteSync((db) => {
|
|
31919
|
+
const key = sessionKeyForCloudSessionId(cloudSessionId);
|
|
31920
|
+
const row = db.get(
|
|
31921
|
+
"SELECT acp_session_id, backend_agent_type, config_options_json, updated_at FROM agent_session WHERE session_key = ?",
|
|
31922
|
+
[key]
|
|
31923
|
+
);
|
|
31924
|
+
if (!row) return null;
|
|
31925
|
+
let configOptions = null;
|
|
31926
|
+
if (row.config_options_json != null && row.config_options_json !== "") {
|
|
31927
|
+
try {
|
|
31928
|
+
const parsed = JSON.parse(row.config_options_json);
|
|
31929
|
+
configOptions = Array.isArray(parsed) ? parsed : null;
|
|
31930
|
+
} catch {
|
|
31931
|
+
configOptions = null;
|
|
31932
|
+
}
|
|
31835
31933
|
}
|
|
31836
|
-
|
|
31837
|
-
|
|
31838
|
-
|
|
31839
|
-
|
|
31840
|
-
|
|
31841
|
-
|
|
31842
|
-
|
|
31843
|
-
};
|
|
31934
|
+
return {
|
|
31935
|
+
v: 1,
|
|
31936
|
+
acpSessionId: row.acp_session_id,
|
|
31937
|
+
backendAgentType: row.backend_agent_type,
|
|
31938
|
+
configOptions,
|
|
31939
|
+
updatedAt: row.updated_at
|
|
31940
|
+
};
|
|
31941
|
+
});
|
|
31844
31942
|
} catch {
|
|
31845
31943
|
return null;
|
|
31846
31944
|
}
|
|
31847
31945
|
}
|
|
31848
31946
|
function writeLocalAgentSessionFile(cloudSessionId, patch) {
|
|
31849
31947
|
try {
|
|
31850
|
-
|
|
31851
|
-
|
|
31852
|
-
|
|
31853
|
-
|
|
31854
|
-
|
|
31855
|
-
|
|
31856
|
-
|
|
31857
|
-
|
|
31858
|
-
|
|
31859
|
-
|
|
31860
|
-
|
|
31861
|
-
|
|
31862
|
-
|
|
31863
|
-
|
|
31864
|
-
|
|
31865
|
-
|
|
31866
|
-
|
|
31867
|
-
|
|
31868
|
-
|
|
31869
|
-
|
|
31870
|
-
|
|
31948
|
+
withCliSqliteSync((db) => {
|
|
31949
|
+
const key = sessionKeyForCloudSessionId(cloudSessionId);
|
|
31950
|
+
const prevRow = db.get(
|
|
31951
|
+
"SELECT acp_session_id, backend_agent_type, config_options_json, updated_at FROM agent_session WHERE session_key = ?",
|
|
31952
|
+
[key]
|
|
31953
|
+
);
|
|
31954
|
+
let prev = null;
|
|
31955
|
+
if (prevRow) {
|
|
31956
|
+
let configOptions = null;
|
|
31957
|
+
if (prevRow.config_options_json != null && prevRow.config_options_json !== "") {
|
|
31958
|
+
try {
|
|
31959
|
+
const parsed = JSON.parse(prevRow.config_options_json);
|
|
31960
|
+
configOptions = Array.isArray(parsed) ? parsed : null;
|
|
31961
|
+
} catch {
|
|
31962
|
+
configOptions = null;
|
|
31963
|
+
}
|
|
31964
|
+
}
|
|
31965
|
+
prev = {
|
|
31966
|
+
v: 1,
|
|
31967
|
+
acpSessionId: prevRow.acp_session_id,
|
|
31968
|
+
backendAgentType: prevRow.backend_agent_type,
|
|
31969
|
+
configOptions,
|
|
31970
|
+
updatedAt: prevRow.updated_at
|
|
31971
|
+
};
|
|
31972
|
+
}
|
|
31973
|
+
const next = {
|
|
31974
|
+
v: 1,
|
|
31975
|
+
acpSessionId: patch.acpSessionId !== void 0 ? patch.acpSessionId : prev?.acpSessionId ?? null,
|
|
31976
|
+
backendAgentType: patch.backendAgentType !== void 0 ? patch.backendAgentType : prev?.backendAgentType ?? null,
|
|
31977
|
+
configOptions: patch.configOptions !== void 0 ? patch.configOptions : prev?.configOptions ?? null,
|
|
31978
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
31979
|
+
};
|
|
31980
|
+
const configJson = next.configOptions != null ? JSON.stringify(next.configOptions) : null;
|
|
31981
|
+
db.run(
|
|
31982
|
+
`INSERT INTO agent_session (session_key, acp_session_id, backend_agent_type, config_options_json, updated_at)
|
|
31983
|
+
VALUES (?, ?, ?, ?, ?)
|
|
31984
|
+
ON CONFLICT(session_key) DO UPDATE SET
|
|
31985
|
+
acp_session_id = excluded.acp_session_id,
|
|
31986
|
+
backend_agent_type = excluded.backend_agent_type,
|
|
31987
|
+
config_options_json = excluded.config_options_json,
|
|
31988
|
+
updated_at = excluded.updated_at`,
|
|
31989
|
+
[key, next.acpSessionId, next.backendAgentType, configJson, next.updatedAt]
|
|
31990
|
+
);
|
|
31991
|
+
});
|
|
31871
31992
|
} catch {
|
|
31872
31993
|
}
|
|
31873
31994
|
}
|
|
@@ -33450,45 +33571,36 @@ function getCwdHashForFileIndex(resolvedCwd) {
|
|
|
33450
33571
|
// src/files/index/build-file-index.ts
|
|
33451
33572
|
import path28 from "node:path";
|
|
33452
33573
|
|
|
33453
|
-
// src/runtime/yield-to-event-loop.ts
|
|
33454
|
-
function yieldToEventLoop() {
|
|
33455
|
-
return new Promise((resolve18) => setImmediate(resolve18));
|
|
33456
|
-
}
|
|
33457
|
-
|
|
33458
33574
|
// src/files/index/walk-workspace-tree.ts
|
|
33459
33575
|
import fs24 from "node:fs";
|
|
33460
33576
|
import path27 from "node:path";
|
|
33461
|
-
|
|
33577
|
+
function shouldSkipWorkspaceWalkEntry(name) {
|
|
33578
|
+
return name.startsWith(".");
|
|
33579
|
+
}
|
|
33580
|
+
function walkWorkspaceTreeSync(dir, baseDir, onFile) {
|
|
33462
33581
|
let names;
|
|
33463
33582
|
try {
|
|
33464
|
-
names =
|
|
33583
|
+
names = fs24.readdirSync(dir);
|
|
33465
33584
|
} catch {
|
|
33466
33585
|
return;
|
|
33467
33586
|
}
|
|
33468
33587
|
for (const name of names) {
|
|
33469
|
-
if (name
|
|
33470
|
-
if (state.n > 0 && state.n % INDEX_WORK_YIELD_EVERY === 0) {
|
|
33471
|
-
await yieldToEventLoop();
|
|
33472
|
-
}
|
|
33473
|
-
state.n++;
|
|
33588
|
+
if (shouldSkipWorkspaceWalkEntry(name)) continue;
|
|
33474
33589
|
const full = path27.join(dir, name);
|
|
33475
33590
|
let stat2;
|
|
33476
33591
|
try {
|
|
33477
|
-
stat2 =
|
|
33592
|
+
stat2 = fs24.statSync(full);
|
|
33478
33593
|
} catch {
|
|
33479
33594
|
continue;
|
|
33480
33595
|
}
|
|
33481
33596
|
const relative5 = path27.relative(baseDir, full).replace(/\\/g, "/");
|
|
33482
33597
|
if (stat2.isDirectory()) {
|
|
33483
|
-
|
|
33598
|
+
walkWorkspaceTreeSync(full, baseDir, onFile);
|
|
33484
33599
|
} else if (stat2.isFile()) {
|
|
33485
|
-
|
|
33600
|
+
onFile(relative5);
|
|
33486
33601
|
}
|
|
33487
33602
|
}
|
|
33488
33603
|
}
|
|
33489
|
-
function createWalkYieldState() {
|
|
33490
|
-
return { n: 0 };
|
|
33491
|
-
}
|
|
33492
33604
|
|
|
33493
33605
|
// src/files/index/file-index-sqlite-lock.ts
|
|
33494
33606
|
import fs25 from "node:fs";
|
|
@@ -33521,80 +33633,98 @@ function withFileIndexSqliteLock(fn) {
|
|
|
33521
33633
|
}
|
|
33522
33634
|
|
|
33523
33635
|
// src/files/index/build-file-index.ts
|
|
33524
|
-
|
|
33525
|
-
|
|
33526
|
-
|
|
33527
|
-
|
|
33528
|
-
|
|
33529
|
-
|
|
33530
|
-
|
|
33531
|
-
try {
|
|
33532
|
-
db.run("DELETE FROM file_index_path WHERE cwd_hash = ?", [h]);
|
|
33533
|
-
const ins = db.prepare("INSERT INTO file_index_path (cwd_hash, path) VALUES (?, ?)");
|
|
33636
|
+
var FILE_INDEX_INSERT_BUFFER = 2048;
|
|
33637
|
+
function persistFileIndexForResolvedCwd(resolved) {
|
|
33638
|
+
return withCliSqliteSync((db) => {
|
|
33639
|
+
const h = getCwdHashForFileIndex(resolved);
|
|
33640
|
+
const buf = [];
|
|
33641
|
+
let pathCount = 0;
|
|
33642
|
+
db.run("BEGIN IMMEDIATE");
|
|
33534
33643
|
try {
|
|
33535
|
-
|
|
33536
|
-
|
|
33644
|
+
db.run("DELETE FROM file_index_path WHERE cwd_hash = ?", [h]);
|
|
33645
|
+
const ins = db.prepare("INSERT INTO file_index_path (cwd_hash, path) VALUES (?, ?)");
|
|
33646
|
+
try {
|
|
33647
|
+
const flushBuf = () => {
|
|
33648
|
+
for (const rel of buf) {
|
|
33649
|
+
ins.run([h, rel]);
|
|
33650
|
+
}
|
|
33651
|
+
pathCount += buf.length;
|
|
33652
|
+
buf.length = 0;
|
|
33653
|
+
};
|
|
33654
|
+
walkWorkspaceTreeSync(resolved, resolved, (rel) => {
|
|
33655
|
+
buf.push(rel);
|
|
33656
|
+
if (buf.length >= FILE_INDEX_INSERT_BUFFER) flushBuf();
|
|
33657
|
+
});
|
|
33658
|
+
flushBuf();
|
|
33659
|
+
} finally {
|
|
33660
|
+
ins.finalize();
|
|
33537
33661
|
}
|
|
33538
|
-
|
|
33539
|
-
|
|
33540
|
-
|
|
33541
|
-
|
|
33542
|
-
|
|
33543
|
-
|
|
33544
|
-
|
|
33545
|
-
} catch {
|
|
33662
|
+
db.run("COMMIT");
|
|
33663
|
+
} catch (e) {
|
|
33664
|
+
try {
|
|
33665
|
+
db.run("ROLLBACK");
|
|
33666
|
+
} catch {
|
|
33667
|
+
}
|
|
33668
|
+
throw e;
|
|
33546
33669
|
}
|
|
33547
|
-
|
|
33548
|
-
}
|
|
33670
|
+
return pathCount;
|
|
33671
|
+
});
|
|
33549
33672
|
}
|
|
33550
33673
|
async function buildFileIndexAsync(cwd) {
|
|
33551
33674
|
return withFileIndexSqliteLock(async () => {
|
|
33552
33675
|
const resolved = path28.resolve(cwd);
|
|
33553
|
-
const paths = [];
|
|
33554
|
-
await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
|
|
33555
33676
|
await yieldToEventLoop();
|
|
33556
|
-
|
|
33557
|
-
|
|
33558
|
-
return { pathCount
|
|
33677
|
+
const pathCount = persistFileIndexForResolvedCwd(resolved);
|
|
33678
|
+
await yieldToEventLoop();
|
|
33679
|
+
return { pathCount };
|
|
33559
33680
|
});
|
|
33560
33681
|
}
|
|
33561
33682
|
|
|
33562
33683
|
// src/files/index/ensure-file-index.ts
|
|
33563
33684
|
import path29 from "node:path";
|
|
33564
33685
|
|
|
33686
|
+
// src/files/index/file-index-dependency-path.ts
|
|
33687
|
+
function sqliteExprBridgeFileIndexDependencyRank() {
|
|
33688
|
+
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`;
|
|
33689
|
+
}
|
|
33690
|
+
|
|
33565
33691
|
// src/files/index/search-file-index.ts
|
|
33566
33692
|
function escapeLikePattern(fragment) {
|
|
33567
33693
|
return fragment.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
33568
33694
|
}
|
|
33569
|
-
function
|
|
33570
|
-
const db = getCliDatabase();
|
|
33695
|
+
function bridgeFileIndexIsPopulatedWithDb(resolvedCwd, db) {
|
|
33571
33696
|
const h = getCwdHashForFileIndex(resolvedCwd);
|
|
33572
33697
|
const row = db.get("SELECT 1 as ok FROM file_index_path WHERE cwd_hash = ? LIMIT 1", [h]);
|
|
33573
33698
|
return row != null;
|
|
33574
33699
|
}
|
|
33575
|
-
function
|
|
33576
|
-
const db = getCliDatabase();
|
|
33700
|
+
function bridgeFileIndexPathCountWithDb(resolvedCwd, db) {
|
|
33577
33701
|
const h = getCwdHashForFileIndex(resolvedCwd);
|
|
33578
33702
|
const row = db.get("SELECT COUNT(*) as c FROM file_index_path WHERE cwd_hash = ?", [h]);
|
|
33579
33703
|
const c = row?.c ?? 0;
|
|
33580
33704
|
return Number(c);
|
|
33581
33705
|
}
|
|
33582
|
-
function
|
|
33706
|
+
function searchBridgeFilePathsWithDb(resolvedCwd, query, limit, db) {
|
|
33583
33707
|
const q = query.trim().toLowerCase();
|
|
33584
33708
|
if (!q) return [];
|
|
33585
|
-
const db = getCliDatabase();
|
|
33586
33709
|
const h = getCwdHashForFileIndex(resolvedCwd);
|
|
33587
33710
|
const pattern = `%${escapeLikePattern(q)}%`;
|
|
33588
33711
|
const lim = Math.max(0, Math.min(1e4, Math.floor(limit)));
|
|
33712
|
+
const depRank = sqliteExprBridgeFileIndexDependencyRank();
|
|
33589
33713
|
const rows = db.all(
|
|
33590
|
-
`SELECT path FROM file_index_path WHERE cwd_hash = ? AND lower(path) LIKE ? ESCAPE '\\' LIMIT ?`,
|
|
33714
|
+
`SELECT path FROM file_index_path WHERE cwd_hash = ? AND lower(path) LIKE ? ESCAPE '\\' ORDER BY ${depRank}, path LIMIT ?`,
|
|
33591
33715
|
[h, pattern, lim]
|
|
33592
33716
|
);
|
|
33593
33717
|
return rows.map((r) => String(r.path));
|
|
33594
33718
|
}
|
|
33719
|
+
async function bridgeFileIndexIsPopulated(resolvedCwd) {
|
|
33720
|
+
return withCliSqlite((db) => bridgeFileIndexIsPopulatedWithDb(resolvedCwd, db));
|
|
33721
|
+
}
|
|
33722
|
+
async function bridgeFileIndexPathCount(resolvedCwd) {
|
|
33723
|
+
return withCliSqlite((db) => bridgeFileIndexPathCountWithDb(resolvedCwd, db));
|
|
33724
|
+
}
|
|
33595
33725
|
async function searchBridgeFilePathsAsync(resolvedCwd, query, limit = 100) {
|
|
33596
33726
|
await yieldToEventLoop();
|
|
33597
|
-
const out =
|
|
33727
|
+
const out = await withCliSqlite((db) => searchBridgeFilePathsWithDb(resolvedCwd, query, limit, db));
|
|
33598
33728
|
if (out.length >= INDEX_WORK_YIELD_EVERY) await yieldToEventLoop();
|
|
33599
33729
|
return out;
|
|
33600
33730
|
}
|
|
@@ -33602,8 +33732,8 @@ async function searchBridgeFilePathsAsync(resolvedCwd, query, limit = 100) {
|
|
|
33602
33732
|
// src/files/index/ensure-file-index.ts
|
|
33603
33733
|
async function ensureFileIndexAsync(cwd) {
|
|
33604
33734
|
const resolved = path29.resolve(cwd);
|
|
33605
|
-
if (bridgeFileIndexIsPopulated(resolved)) {
|
|
33606
|
-
return { fromCache: true, pathCount: bridgeFileIndexPathCount(resolved) };
|
|
33735
|
+
if (await bridgeFileIndexIsPopulated(resolved)) {
|
|
33736
|
+
return { fromCache: true, pathCount: await bridgeFileIndexPathCount(resolved) };
|
|
33607
33737
|
}
|
|
33608
33738
|
return { ...await buildFileIndexAsync(resolved), fromCache: false };
|
|
33609
33739
|
}
|
|
@@ -33612,7 +33742,6 @@ async function ensureFileIndexAsync(cwd) {
|
|
|
33612
33742
|
var DEBOUNCE_MS = 900;
|
|
33613
33743
|
function shouldIgnoreRelative(rel) {
|
|
33614
33744
|
const n = rel.replace(/\\/g, "/");
|
|
33615
|
-
if (n.includes("/node_modules/") || n.startsWith("node_modules/")) return true;
|
|
33616
33745
|
if (n.includes("/.git/") || n === ".git" || n.startsWith(".git/")) return true;
|
|
33617
33746
|
if (n.includes("/.buildautomaton/") || n.startsWith(".buildautomaton/")) return true;
|
|
33618
33747
|
return false;
|
|
@@ -35117,30 +35246,32 @@ var MERGEABLE_SERVER_STATES = /* @__PURE__ */ new Set([
|
|
|
35117
35246
|
"stopping",
|
|
35118
35247
|
"discarded"
|
|
35119
35248
|
]);
|
|
35120
|
-
function readPersistedQueue(queueKey) {
|
|
35121
|
-
|
|
35122
|
-
|
|
35123
|
-
|
|
35124
|
-
|
|
35125
|
-
|
|
35126
|
-
|
|
35127
|
-
|
|
35128
|
-
|
|
35129
|
-
|
|
35130
|
-
|
|
35131
|
-
|
|
35132
|
-
|
|
35249
|
+
async function readPersistedQueue(queueKey) {
|
|
35250
|
+
return withCliSqlite((db) => {
|
|
35251
|
+
const row = db.get("SELECT queue_key, updated_at, turns_json FROM prompt_queue WHERE queue_key = ?", [
|
|
35252
|
+
queueKey
|
|
35253
|
+
]);
|
|
35254
|
+
if (!row) return null;
|
|
35255
|
+
try {
|
|
35256
|
+
const turns = JSON.parse(row.turns_json);
|
|
35257
|
+
if (!Array.isArray(turns)) return null;
|
|
35258
|
+
return { queueKey: row.queue_key, updatedAt: row.updated_at, turns };
|
|
35259
|
+
} catch {
|
|
35260
|
+
return null;
|
|
35261
|
+
}
|
|
35262
|
+
});
|
|
35133
35263
|
}
|
|
35134
|
-
function writePersistedQueue(file2) {
|
|
35135
|
-
|
|
35136
|
-
|
|
35137
|
-
|
|
35138
|
-
|
|
35139
|
-
|
|
35140
|
-
|
|
35264
|
+
async function writePersistedQueue(file2) {
|
|
35265
|
+
await withCliSqlite((db) => {
|
|
35266
|
+
db.run(
|
|
35267
|
+
`INSERT INTO prompt_queue (queue_key, updated_at, turns_json) VALUES (?, ?, ?)
|
|
35268
|
+
ON CONFLICT(queue_key) DO UPDATE SET updated_at = excluded.updated_at, turns_json = excluded.turns_json`,
|
|
35269
|
+
[file2.queueKey, file2.updatedAt, JSON.stringify(file2.turns)]
|
|
35270
|
+
);
|
|
35271
|
+
});
|
|
35141
35272
|
}
|
|
35142
|
-
function mergeServerQueueSnapshot(queueKey, serverTurns) {
|
|
35143
|
-
const prev = readPersistedQueue(queueKey);
|
|
35273
|
+
async function mergeServerQueueSnapshot(queueKey, serverTurns) {
|
|
35274
|
+
const prev = await readPersistedQueue(queueKey);
|
|
35144
35275
|
const turns = [];
|
|
35145
35276
|
for (const raw of serverTurns) {
|
|
35146
35277
|
if (!raw || typeof raw !== "object") continue;
|
|
@@ -35237,12 +35368,12 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35237
35368
|
const getWs = deps.getWs;
|
|
35238
35369
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
35239
35370
|
if (!Array.isArray(serverTurns)) continue;
|
|
35240
|
-
const file2 = mergeServerQueueSnapshot(queueKey, serverTurns);
|
|
35241
|
-
writePersistedQueue(file2);
|
|
35371
|
+
const file2 = await mergeServerQueueSnapshot(queueKey, serverTurns);
|
|
35372
|
+
await writePersistedQueue(file2);
|
|
35242
35373
|
}
|
|
35243
35374
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
35244
35375
|
if (!Array.isArray(serverTurns)) continue;
|
|
35245
|
-
const file2 = readPersistedQueue(queueKey);
|
|
35376
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
35246
35377
|
if (!file2) continue;
|
|
35247
35378
|
for (const running of file2.turns.filter((t) => t.lastClientState === "running")) {
|
|
35248
35379
|
runIdToQueueKey.set(running.turnId, queueKey);
|
|
@@ -35250,7 +35381,7 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35250
35381
|
}
|
|
35251
35382
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
35252
35383
|
if (!Array.isArray(serverTurns)) continue;
|
|
35253
|
-
const file2 = readPersistedQueue(queueKey);
|
|
35384
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
35254
35385
|
if (!file2) continue;
|
|
35255
35386
|
const cancelRow = file2.turns.find((t) => t.serverState === "cancel_requested" && t.lastClientState === "running");
|
|
35256
35387
|
if (cancelRow) {
|
|
@@ -35259,7 +35390,7 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35259
35390
|
deps.log(
|
|
35260
35391
|
`[Queue] server cancel_requested for ${cancelRow.turnId.slice(0, 8)}\u2026 but no local agent run is active (e.g. after CLI restart); marking cancelled and notifying bridge.`
|
|
35261
35392
|
);
|
|
35262
|
-
finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, { terminalClientState: "cancelled" });
|
|
35393
|
+
await finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, { terminalClientState: "cancelled" });
|
|
35263
35394
|
const ws = deps.getWs();
|
|
35264
35395
|
if (ws && cancelRow.sessionId) {
|
|
35265
35396
|
sendWsMessage(ws, {
|
|
@@ -35278,19 +35409,19 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35278
35409
|
const startedThisTick = /* @__PURE__ */ new Set();
|
|
35279
35410
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
35280
35411
|
if (!Array.isArray(serverTurns)) continue;
|
|
35281
|
-
const file2 = readPersistedQueue(queueKey);
|
|
35412
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
35282
35413
|
if (!file2) continue;
|
|
35283
35414
|
if (hasRunningTurn(file2.turns)) continue;
|
|
35284
35415
|
const next = pickNextRunnableTurn(file2.turns);
|
|
35285
35416
|
if (!next) continue;
|
|
35286
35417
|
if (!await runLocalRevertBeforeQueuedPrompt(next, deps)) {
|
|
35287
35418
|
next.lastClientState = "failed";
|
|
35288
|
-
writePersistedQueue(file2);
|
|
35419
|
+
await writePersistedQueue(file2);
|
|
35289
35420
|
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: next.turnId, clientState: "failed" }] });
|
|
35290
35421
|
continue;
|
|
35291
35422
|
}
|
|
35292
35423
|
next.lastClientState = "running";
|
|
35293
|
-
writePersistedQueue(file2);
|
|
35424
|
+
await writePersistedQueue(file2);
|
|
35294
35425
|
runIdToQueueKey.set(next.turnId, queueKey);
|
|
35295
35426
|
startedThisTick.add(next.turnId);
|
|
35296
35427
|
report[queueKey] = [{ turnId: next.turnId, clientState: "running" }];
|
|
@@ -35300,7 +35431,7 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35300
35431
|
}
|
|
35301
35432
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
35302
35433
|
if (!Array.isArray(serverTurns)) continue;
|
|
35303
|
-
const file2 = readPersistedQueue(queueKey);
|
|
35434
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
35304
35435
|
if (!file2) continue;
|
|
35305
35436
|
const running = file2.turns.find((t) => t.lastClientState === "running");
|
|
35306
35437
|
if (!running || !startedThisTick.has(running.turnId)) continue;
|
|
@@ -35308,17 +35439,17 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35308
35439
|
dispatchLocalPrompt(running, deps);
|
|
35309
35440
|
}
|
|
35310
35441
|
}
|
|
35311
|
-
function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
|
|
35442
|
+
async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
|
|
35312
35443
|
if (!runId) return false;
|
|
35313
35444
|
const queueKey = runIdToQueueKey.get(runId);
|
|
35314
35445
|
runIdToQueueKey.delete(runId);
|
|
35315
35446
|
if (!queueKey) return false;
|
|
35316
|
-
const f = readPersistedQueue(queueKey);
|
|
35447
|
+
const f = await readPersistedQueue(queueKey);
|
|
35317
35448
|
if (!f) return false;
|
|
35318
35449
|
const t = f.turns.find((x) => x.turnId === runId);
|
|
35319
35450
|
if (!t) return false;
|
|
35320
35451
|
t.lastClientState = opts?.terminalClientState ?? (success2 ? "stopped" : "failed");
|
|
35321
|
-
writePersistedQueue(f);
|
|
35452
|
+
await writePersistedQueue(f);
|
|
35322
35453
|
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, clientState: t.lastClientState }] });
|
|
35323
35454
|
return true;
|
|
35324
35455
|
}
|
|
@@ -35339,12 +35470,13 @@ function createBridgePromptSenders(deps, getWs) {
|
|
|
35339
35470
|
if (result.type === "prompt_result") {
|
|
35340
35471
|
const pr = result;
|
|
35341
35472
|
const cancelled = pr.stopReason === "cancelled";
|
|
35342
|
-
finalizePromptTurnOnBridge(
|
|
35473
|
+
void finalizePromptTurnOnBridge(
|
|
35343
35474
|
getWs,
|
|
35344
35475
|
typeof pr.runId === "string" ? pr.runId : void 0,
|
|
35345
35476
|
pr.success === true,
|
|
35346
35477
|
cancelled ? { terminalClientState: "cancelled" } : void 0
|
|
35347
|
-
)
|
|
35478
|
+
).catch(() => {
|
|
35479
|
+
});
|
|
35348
35480
|
}
|
|
35349
35481
|
};
|
|
35350
35482
|
const sendSessionUpdate = (payload) => {
|
|
@@ -35903,7 +36035,7 @@ function handleFileBrowserSearch(msg, socket, e2ee) {
|
|
|
35903
36035
|
await yieldToEventLoop();
|
|
35904
36036
|
const q = typeof msg.q === "string" ? msg.q : "";
|
|
35905
36037
|
const cwd = path36.resolve(getBridgeRoot());
|
|
35906
|
-
if (!bridgeFileIndexIsPopulated(cwd)) {
|
|
36038
|
+
if (!await bridgeFileIndexIsPopulated(cwd)) {
|
|
35907
36039
|
const payload2 = {
|
|
35908
36040
|
type: "file_browser_search_response",
|
|
35909
36041
|
id: msg.id,
|
|
@@ -36743,7 +36875,7 @@ import * as path39 from "node:path";
|
|
|
36743
36875
|
// src/agents/capabilities/probe-one-agent-type-for-capabilities.ts
|
|
36744
36876
|
import * as path38 from "node:path";
|
|
36745
36877
|
async function probeOneAgentTypeForCapabilities(params) {
|
|
36746
|
-
const { agentType, cwd, workspaceId, log: log2,
|
|
36878
|
+
const { agentType, cwd, workspaceId, log: log2, reportAgentCapabilities, bridgeReport = true } = params;
|
|
36747
36879
|
const resolved = resolveAgentCommand(agentType);
|
|
36748
36880
|
if (!resolved) return false;
|
|
36749
36881
|
let sqliteChanged = false;
|
|
@@ -36754,11 +36886,13 @@ async function probeOneAgentTypeForCapabilities(params) {
|
|
|
36754
36886
|
reportedRef.done = true;
|
|
36755
36887
|
let changed = false;
|
|
36756
36888
|
try {
|
|
36757
|
-
changed =
|
|
36758
|
-
|
|
36759
|
-
|
|
36760
|
-
|
|
36761
|
-
|
|
36889
|
+
changed = withCliSqliteSync(
|
|
36890
|
+
(db) => upsertCliAgentCapabilityCache(db, {
|
|
36891
|
+
workspaceId,
|
|
36892
|
+
agentType,
|
|
36893
|
+
configOptions: co
|
|
36894
|
+
})
|
|
36895
|
+
);
|
|
36762
36896
|
} catch {
|
|
36763
36897
|
}
|
|
36764
36898
|
sqliteChanged ||= changed;
|
|
@@ -36816,7 +36950,6 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
|
|
|
36816
36950
|
cwd,
|
|
36817
36951
|
workspaceId,
|
|
36818
36952
|
log: log2,
|
|
36819
|
-
getDb,
|
|
36820
36953
|
reportAgentCapabilities,
|
|
36821
36954
|
bridgeReport = true,
|
|
36822
36955
|
forceAllTypes = false
|
|
@@ -36828,7 +36961,7 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
|
|
|
36828
36961
|
if (!agentType.trim()) continue;
|
|
36829
36962
|
if (!forceAllTypes) {
|
|
36830
36963
|
try {
|
|
36831
|
-
if (process.env.BUILDAUTOMATON_FORCE_PROBE_ACP_CAPABILITIES !== "1" &&
|
|
36964
|
+
if (process.env.BUILDAUTOMATON_FORCE_PROBE_ACP_CAPABILITIES !== "1" && await withCliSqlite((db) => hasNonEmptyAgentCapabilityCache(db, workspaceId, agentType))) {
|
|
36832
36965
|
continue;
|
|
36833
36966
|
}
|
|
36834
36967
|
} catch {
|
|
@@ -36839,7 +36972,6 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
|
|
|
36839
36972
|
cwd,
|
|
36840
36973
|
workspaceId,
|
|
36841
36974
|
log: log2,
|
|
36842
|
-
getDb,
|
|
36843
36975
|
reportAgentCapabilities,
|
|
36844
36976
|
bridgeReport
|
|
36845
36977
|
});
|
|
@@ -36850,14 +36982,13 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
|
|
|
36850
36982
|
|
|
36851
36983
|
// src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
|
|
36852
36984
|
async function warmupAgentCapabilitiesOnConnect(params) {
|
|
36853
|
-
const { workspaceId, log: log2,
|
|
36985
|
+
const { workspaceId, log: log2, getWs } = params;
|
|
36854
36986
|
const cwd = path39.resolve(getBridgeRoot());
|
|
36855
|
-
|
|
36856
|
-
function sendBatchFromCache() {
|
|
36987
|
+
async function sendBatchFromCache() {
|
|
36857
36988
|
const socket = getWs();
|
|
36858
36989
|
if (!socket || socket.readyState !== wrapper_default.OPEN) return;
|
|
36859
36990
|
try {
|
|
36860
|
-
const rows = listCliAgentCapabilityCacheForWorkspace(db, workspaceId);
|
|
36991
|
+
const rows = await withCliSqlite((db) => listCliAgentCapabilityCacheForWorkspace(db, workspaceId));
|
|
36861
36992
|
if (rows.length === 0) return;
|
|
36862
36993
|
sendWsMessage(socket, {
|
|
36863
36994
|
type: "agent_capabilities_batch",
|
|
@@ -36869,7 +37000,7 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
36869
37000
|
);
|
|
36870
37001
|
}
|
|
36871
37002
|
}
|
|
36872
|
-
sendBatchFromCache();
|
|
37003
|
+
await sendBatchFromCache();
|
|
36873
37004
|
let types = [];
|
|
36874
37005
|
try {
|
|
36875
37006
|
types = [...await detectLocalAgentTypes()];
|
|
@@ -36882,11 +37013,10 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
36882
37013
|
cwd,
|
|
36883
37014
|
workspaceId,
|
|
36884
37015
|
log: log2,
|
|
36885
|
-
getDb,
|
|
36886
37016
|
bridgeReport: false,
|
|
36887
37017
|
forceAllTypes: false
|
|
36888
37018
|
});
|
|
36889
|
-
if (n > 0) sendBatchFromCache();
|
|
37019
|
+
if (n > 0) await sendBatchFromCache();
|
|
36890
37020
|
} catch (e) {
|
|
36891
37021
|
log2(`[Bridge service] Agent capability probe (missing cache) failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
36892
37022
|
}
|
|
@@ -36898,11 +37028,10 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
36898
37028
|
cwd,
|
|
36899
37029
|
workspaceId,
|
|
36900
37030
|
log: log2,
|
|
36901
|
-
getDb,
|
|
36902
37031
|
bridgeReport: false,
|
|
36903
37032
|
forceAllTypes: true
|
|
36904
37033
|
});
|
|
36905
|
-
if (n > 0) sendBatchFromCache();
|
|
37034
|
+
if (n > 0) await sendBatchFromCache();
|
|
36906
37035
|
} catch (e) {
|
|
36907
37036
|
log2(`[Bridge service] Agent capability lazy refresh failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
36908
37037
|
}
|
|
@@ -36914,7 +37043,7 @@ async function createBridgeConnection(options) {
|
|
|
36914
37043
|
const { apiUrl, workspaceId, justAuthenticated, onAuthInvalid, persistTokens } = options;
|
|
36915
37044
|
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
36916
37045
|
const logFn = options.log ?? log;
|
|
36917
|
-
|
|
37046
|
+
await ensureCliSqliteInitialized({ logLegacyMigration: logFn });
|
|
36918
37047
|
const tokens = {
|
|
36919
37048
|
accessToken: options.authToken,
|
|
36920
37049
|
refreshToken: options.refreshToken
|
|
@@ -36944,11 +37073,13 @@ async function createBridgeConnection(options) {
|
|
|
36944
37073
|
if (!Array.isArray(info.configOptions) || info.configOptions.length === 0) return;
|
|
36945
37074
|
let changed = false;
|
|
36946
37075
|
try {
|
|
36947
|
-
changed =
|
|
36948
|
-
|
|
36949
|
-
|
|
36950
|
-
|
|
36951
|
-
|
|
37076
|
+
changed = withCliSqliteSync(
|
|
37077
|
+
(db) => upsertCliAgentCapabilityCache(db, {
|
|
37078
|
+
workspaceId,
|
|
37079
|
+
agentType: info.agentType,
|
|
37080
|
+
configOptions: info.configOptions
|
|
37081
|
+
})
|
|
37082
|
+
);
|
|
36952
37083
|
} catch {
|
|
36953
37084
|
}
|
|
36954
37085
|
if (!changed) return;
|
|
@@ -37001,7 +37132,6 @@ async function createBridgeConnection(options) {
|
|
|
37001
37132
|
await warmupAgentCapabilitiesOnConnect({
|
|
37002
37133
|
workspaceId,
|
|
37003
37134
|
log: logFn,
|
|
37004
|
-
getDb: getCliDatabase,
|
|
37005
37135
|
getWs
|
|
37006
37136
|
});
|
|
37007
37137
|
},
|