@buildautomaton/cli 0.1.31 → 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 +262 -175
- package/dist/cli.js.map +4 -4
- package/dist/index.js +262 -175
- 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,6 +25322,23 @@ function migrateCliSqlite(db) {
|
|
|
25317
25322
|
|
|
25318
25323
|
// src/sqlite/cli-database.ts
|
|
25319
25324
|
var { Database: SqliteDatabase } = sqliteWasm;
|
|
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
|
+
}
|
|
25320
25342
|
function applyCliSqliteMemoryPragmas(db) {
|
|
25321
25343
|
try {
|
|
25322
25344
|
db.run("PRAGMA cache_size = -8192");
|
|
@@ -25324,18 +25346,6 @@ function applyCliSqliteMemoryPragmas(db) {
|
|
|
25324
25346
|
} catch {
|
|
25325
25347
|
}
|
|
25326
25348
|
}
|
|
25327
|
-
var openDatabases = /* @__PURE__ */ new Map();
|
|
25328
|
-
var processExitCloseRegistered = false;
|
|
25329
|
-
function registerProcessExitSqliteClose() {
|
|
25330
|
-
if (processExitCloseRegistered) return;
|
|
25331
|
-
processExitCloseRegistered = true;
|
|
25332
|
-
process.once("exit", () => {
|
|
25333
|
-
for (const db of openDatabases.values()) {
|
|
25334
|
-
safeCloseCliSqliteDatabase(db);
|
|
25335
|
-
}
|
|
25336
|
-
openDatabases.clear();
|
|
25337
|
-
});
|
|
25338
|
-
}
|
|
25339
25349
|
function safeCloseCliSqliteDatabase(db) {
|
|
25340
25350
|
if (db == null) return;
|
|
25341
25351
|
try {
|
|
@@ -25344,22 +25354,33 @@ function safeCloseCliSqliteDatabase(db) {
|
|
|
25344
25354
|
}
|
|
25345
25355
|
}
|
|
25346
25356
|
function closeAllCliSqliteConnections() {
|
|
25347
|
-
|
|
25348
|
-
|
|
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
|
+
}
|
|
25349
25373
|
}
|
|
25350
|
-
openDatabases.clear();
|
|
25351
25374
|
}
|
|
25352
|
-
function
|
|
25375
|
+
function asyncDelayMs(ms) {
|
|
25376
|
+
return new Promise((resolve18) => setTimeout(resolve18, ms));
|
|
25377
|
+
}
|
|
25378
|
+
function openCliSqliteConnection(options) {
|
|
25353
25379
|
const sqlitePath = getCliSqlitePath();
|
|
25354
|
-
const existing = openDatabases.get(sqlitePath);
|
|
25355
|
-
if (existing?.isOpen) return existing;
|
|
25356
|
-
if (existing && !existing.isOpen) {
|
|
25357
|
-
safeCloseCliSqliteDatabase(existing);
|
|
25358
|
-
openDatabases.delete(sqlitePath);
|
|
25359
|
-
}
|
|
25360
25380
|
ensureCliSqliteParentDir(sqlitePath);
|
|
25361
25381
|
const db = new SqliteDatabase(sqlitePath);
|
|
25362
25382
|
try {
|
|
25383
|
+
applyCliSqliteConcurrencyPragmas(db);
|
|
25363
25384
|
applyCliSqliteMemoryPragmas(db);
|
|
25364
25385
|
migrateCliSqlite(db);
|
|
25365
25386
|
importCliSqliteLegacyDiskData(db, options?.logLegacyMigration);
|
|
@@ -25367,10 +25388,52 @@ function getCliDatabase(options) {
|
|
|
25367
25388
|
safeCloseCliSqliteDatabase(db);
|
|
25368
25389
|
throw e;
|
|
25369
25390
|
}
|
|
25370
|
-
openDatabases.set(sqlitePath, db);
|
|
25371
|
-
registerProcessExitSqliteClose();
|
|
25372
25391
|
return db;
|
|
25373
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
|
+
}
|
|
25374
25437
|
|
|
25375
25438
|
// src/connection/close-bridge-connection.ts
|
|
25376
25439
|
async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
|
|
@@ -31852,56 +31915,80 @@ function sessionKeyForCloudSessionId(cloudSessionId) {
|
|
|
31852
31915
|
}
|
|
31853
31916
|
function readLocalAgentSessionFile(cloudSessionId) {
|
|
31854
31917
|
try {
|
|
31855
|
-
|
|
31856
|
-
|
|
31857
|
-
|
|
31858
|
-
|
|
31859
|
-
|
|
31860
|
-
|
|
31861
|
-
|
|
31862
|
-
|
|
31863
|
-
|
|
31864
|
-
|
|
31865
|
-
|
|
31866
|
-
|
|
31867
|
-
|
|
31868
|
-
|
|
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
|
+
}
|
|
31869
31933
|
}
|
|
31870
|
-
|
|
31871
|
-
|
|
31872
|
-
|
|
31873
|
-
|
|
31874
|
-
|
|
31875
|
-
|
|
31876
|
-
|
|
31877
|
-
};
|
|
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
|
+
});
|
|
31878
31942
|
} catch {
|
|
31879
31943
|
return null;
|
|
31880
31944
|
}
|
|
31881
31945
|
}
|
|
31882
31946
|
function writeLocalAgentSessionFile(cloudSessionId, patch) {
|
|
31883
31947
|
try {
|
|
31884
|
-
|
|
31885
|
-
|
|
31886
|
-
|
|
31887
|
-
|
|
31888
|
-
|
|
31889
|
-
|
|
31890
|
-
|
|
31891
|
-
|
|
31892
|
-
|
|
31893
|
-
|
|
31894
|
-
|
|
31895
|
-
|
|
31896
|
-
|
|
31897
|
-
|
|
31898
|
-
|
|
31899
|
-
|
|
31900
|
-
|
|
31901
|
-
|
|
31902
|
-
|
|
31903
|
-
|
|
31904
|
-
|
|
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
|
+
});
|
|
31905
31992
|
} catch {
|
|
31906
31993
|
}
|
|
31907
31994
|
}
|
|
@@ -33484,11 +33571,6 @@ function getCwdHashForFileIndex(resolvedCwd) {
|
|
|
33484
33571
|
// src/files/index/build-file-index.ts
|
|
33485
33572
|
import path28 from "node:path";
|
|
33486
33573
|
|
|
33487
|
-
// src/runtime/yield-to-event-loop.ts
|
|
33488
|
-
function yieldToEventLoop() {
|
|
33489
|
-
return new Promise((resolve18) => setImmediate(resolve18));
|
|
33490
|
-
}
|
|
33491
|
-
|
|
33492
33574
|
// src/files/index/walk-workspace-tree.ts
|
|
33493
33575
|
import fs24 from "node:fs";
|
|
33494
33576
|
import path27 from "node:path";
|
|
@@ -33553,39 +33635,40 @@ function withFileIndexSqliteLock(fn) {
|
|
|
33553
33635
|
// src/files/index/build-file-index.ts
|
|
33554
33636
|
var FILE_INDEX_INSERT_BUFFER = 2048;
|
|
33555
33637
|
function persistFileIndexForResolvedCwd(resolved) {
|
|
33556
|
-
|
|
33557
|
-
|
|
33558
|
-
|
|
33559
|
-
|
|
33560
|
-
|
|
33561
|
-
try {
|
|
33562
|
-
db.run("DELETE FROM file_index_path WHERE cwd_hash = ?", [h]);
|
|
33563
|
-
const ins = db.prepare("INSERT INTO file_index_path (cwd_hash, path) VALUES (?, ?)");
|
|
33638
|
+
return withCliSqliteSync((db) => {
|
|
33639
|
+
const h = getCwdHashForFileIndex(resolved);
|
|
33640
|
+
const buf = [];
|
|
33641
|
+
let pathCount = 0;
|
|
33642
|
+
db.run("BEGIN IMMEDIATE");
|
|
33564
33643
|
try {
|
|
33565
|
-
|
|
33566
|
-
|
|
33567
|
-
|
|
33568
|
-
|
|
33569
|
-
|
|
33570
|
-
|
|
33571
|
-
|
|
33572
|
-
|
|
33573
|
-
|
|
33574
|
-
|
|
33575
|
-
|
|
33576
|
-
|
|
33577
|
-
|
|
33578
|
-
|
|
33579
|
-
|
|
33580
|
-
|
|
33581
|
-
|
|
33582
|
-
|
|
33583
|
-
db.run("
|
|
33584
|
-
} catch {
|
|
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();
|
|
33661
|
+
}
|
|
33662
|
+
db.run("COMMIT");
|
|
33663
|
+
} catch (e) {
|
|
33664
|
+
try {
|
|
33665
|
+
db.run("ROLLBACK");
|
|
33666
|
+
} catch {
|
|
33667
|
+
}
|
|
33668
|
+
throw e;
|
|
33585
33669
|
}
|
|
33586
|
-
|
|
33587
|
-
}
|
|
33588
|
-
return pathCount;
|
|
33670
|
+
return pathCount;
|
|
33671
|
+
});
|
|
33589
33672
|
}
|
|
33590
33673
|
async function buildFileIndexAsync(cwd) {
|
|
33591
33674
|
return withFileIndexSqliteLock(async () => {
|
|
@@ -33609,23 +33692,20 @@ function sqliteExprBridgeFileIndexDependencyRank() {
|
|
|
33609
33692
|
function escapeLikePattern(fragment) {
|
|
33610
33693
|
return fragment.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
33611
33694
|
}
|
|
33612
|
-
function
|
|
33613
|
-
const db = getCliDatabase();
|
|
33695
|
+
function bridgeFileIndexIsPopulatedWithDb(resolvedCwd, db) {
|
|
33614
33696
|
const h = getCwdHashForFileIndex(resolvedCwd);
|
|
33615
33697
|
const row = db.get("SELECT 1 as ok FROM file_index_path WHERE cwd_hash = ? LIMIT 1", [h]);
|
|
33616
33698
|
return row != null;
|
|
33617
33699
|
}
|
|
33618
|
-
function
|
|
33619
|
-
const db = getCliDatabase();
|
|
33700
|
+
function bridgeFileIndexPathCountWithDb(resolvedCwd, db) {
|
|
33620
33701
|
const h = getCwdHashForFileIndex(resolvedCwd);
|
|
33621
33702
|
const row = db.get("SELECT COUNT(*) as c FROM file_index_path WHERE cwd_hash = ?", [h]);
|
|
33622
33703
|
const c = row?.c ?? 0;
|
|
33623
33704
|
return Number(c);
|
|
33624
33705
|
}
|
|
33625
|
-
function
|
|
33706
|
+
function searchBridgeFilePathsWithDb(resolvedCwd, query, limit, db) {
|
|
33626
33707
|
const q = query.trim().toLowerCase();
|
|
33627
33708
|
if (!q) return [];
|
|
33628
|
-
const db = getCliDatabase();
|
|
33629
33709
|
const h = getCwdHashForFileIndex(resolvedCwd);
|
|
33630
33710
|
const pattern = `%${escapeLikePattern(q)}%`;
|
|
33631
33711
|
const lim = Math.max(0, Math.min(1e4, Math.floor(limit)));
|
|
@@ -33636,9 +33716,15 @@ function searchBridgeFilePaths(resolvedCwd, query, limit = 100) {
|
|
|
33636
33716
|
);
|
|
33637
33717
|
return rows.map((r) => String(r.path));
|
|
33638
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
|
+
}
|
|
33639
33725
|
async function searchBridgeFilePathsAsync(resolvedCwd, query, limit = 100) {
|
|
33640
33726
|
await yieldToEventLoop();
|
|
33641
|
-
const out =
|
|
33727
|
+
const out = await withCliSqlite((db) => searchBridgeFilePathsWithDb(resolvedCwd, query, limit, db));
|
|
33642
33728
|
if (out.length >= INDEX_WORK_YIELD_EVERY) await yieldToEventLoop();
|
|
33643
33729
|
return out;
|
|
33644
33730
|
}
|
|
@@ -33646,8 +33732,8 @@ async function searchBridgeFilePathsAsync(resolvedCwd, query, limit = 100) {
|
|
|
33646
33732
|
// src/files/index/ensure-file-index.ts
|
|
33647
33733
|
async function ensureFileIndexAsync(cwd) {
|
|
33648
33734
|
const resolved = path29.resolve(cwd);
|
|
33649
|
-
if (bridgeFileIndexIsPopulated(resolved)) {
|
|
33650
|
-
return { fromCache: true, pathCount: bridgeFileIndexPathCount(resolved) };
|
|
33735
|
+
if (await bridgeFileIndexIsPopulated(resolved)) {
|
|
33736
|
+
return { fromCache: true, pathCount: await bridgeFileIndexPathCount(resolved) };
|
|
33651
33737
|
}
|
|
33652
33738
|
return { ...await buildFileIndexAsync(resolved), fromCache: false };
|
|
33653
33739
|
}
|
|
@@ -35160,30 +35246,32 @@ var MERGEABLE_SERVER_STATES = /* @__PURE__ */ new Set([
|
|
|
35160
35246
|
"stopping",
|
|
35161
35247
|
"discarded"
|
|
35162
35248
|
]);
|
|
35163
|
-
function readPersistedQueue(queueKey) {
|
|
35164
|
-
|
|
35165
|
-
|
|
35166
|
-
|
|
35167
|
-
|
|
35168
|
-
|
|
35169
|
-
|
|
35170
|
-
|
|
35171
|
-
|
|
35172
|
-
|
|
35173
|
-
|
|
35174
|
-
|
|
35175
|
-
|
|
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
|
+
});
|
|
35176
35263
|
}
|
|
35177
|
-
function writePersistedQueue(file2) {
|
|
35178
|
-
|
|
35179
|
-
|
|
35180
|
-
|
|
35181
|
-
|
|
35182
|
-
|
|
35183
|
-
|
|
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
|
+
});
|
|
35184
35272
|
}
|
|
35185
|
-
function mergeServerQueueSnapshot(queueKey, serverTurns) {
|
|
35186
|
-
const prev = readPersistedQueue(queueKey);
|
|
35273
|
+
async function mergeServerQueueSnapshot(queueKey, serverTurns) {
|
|
35274
|
+
const prev = await readPersistedQueue(queueKey);
|
|
35187
35275
|
const turns = [];
|
|
35188
35276
|
for (const raw of serverTurns) {
|
|
35189
35277
|
if (!raw || typeof raw !== "object") continue;
|
|
@@ -35280,12 +35368,12 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35280
35368
|
const getWs = deps.getWs;
|
|
35281
35369
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
35282
35370
|
if (!Array.isArray(serverTurns)) continue;
|
|
35283
|
-
const file2 = mergeServerQueueSnapshot(queueKey, serverTurns);
|
|
35284
|
-
writePersistedQueue(file2);
|
|
35371
|
+
const file2 = await mergeServerQueueSnapshot(queueKey, serverTurns);
|
|
35372
|
+
await writePersistedQueue(file2);
|
|
35285
35373
|
}
|
|
35286
35374
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
35287
35375
|
if (!Array.isArray(serverTurns)) continue;
|
|
35288
|
-
const file2 = readPersistedQueue(queueKey);
|
|
35376
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
35289
35377
|
if (!file2) continue;
|
|
35290
35378
|
for (const running of file2.turns.filter((t) => t.lastClientState === "running")) {
|
|
35291
35379
|
runIdToQueueKey.set(running.turnId, queueKey);
|
|
@@ -35293,7 +35381,7 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35293
35381
|
}
|
|
35294
35382
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
35295
35383
|
if (!Array.isArray(serverTurns)) continue;
|
|
35296
|
-
const file2 = readPersistedQueue(queueKey);
|
|
35384
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
35297
35385
|
if (!file2) continue;
|
|
35298
35386
|
const cancelRow = file2.turns.find((t) => t.serverState === "cancel_requested" && t.lastClientState === "running");
|
|
35299
35387
|
if (cancelRow) {
|
|
@@ -35302,7 +35390,7 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35302
35390
|
deps.log(
|
|
35303
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.`
|
|
35304
35392
|
);
|
|
35305
|
-
finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, { terminalClientState: "cancelled" });
|
|
35393
|
+
await finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, { terminalClientState: "cancelled" });
|
|
35306
35394
|
const ws = deps.getWs();
|
|
35307
35395
|
if (ws && cancelRow.sessionId) {
|
|
35308
35396
|
sendWsMessage(ws, {
|
|
@@ -35321,19 +35409,19 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35321
35409
|
const startedThisTick = /* @__PURE__ */ new Set();
|
|
35322
35410
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
35323
35411
|
if (!Array.isArray(serverTurns)) continue;
|
|
35324
|
-
const file2 = readPersistedQueue(queueKey);
|
|
35412
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
35325
35413
|
if (!file2) continue;
|
|
35326
35414
|
if (hasRunningTurn(file2.turns)) continue;
|
|
35327
35415
|
const next = pickNextRunnableTurn(file2.turns);
|
|
35328
35416
|
if (!next) continue;
|
|
35329
35417
|
if (!await runLocalRevertBeforeQueuedPrompt(next, deps)) {
|
|
35330
35418
|
next.lastClientState = "failed";
|
|
35331
|
-
writePersistedQueue(file2);
|
|
35419
|
+
await writePersistedQueue(file2);
|
|
35332
35420
|
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: next.turnId, clientState: "failed" }] });
|
|
35333
35421
|
continue;
|
|
35334
35422
|
}
|
|
35335
35423
|
next.lastClientState = "running";
|
|
35336
|
-
writePersistedQueue(file2);
|
|
35424
|
+
await writePersistedQueue(file2);
|
|
35337
35425
|
runIdToQueueKey.set(next.turnId, queueKey);
|
|
35338
35426
|
startedThisTick.add(next.turnId);
|
|
35339
35427
|
report[queueKey] = [{ turnId: next.turnId, clientState: "running" }];
|
|
@@ -35343,7 +35431,7 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35343
35431
|
}
|
|
35344
35432
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
35345
35433
|
if (!Array.isArray(serverTurns)) continue;
|
|
35346
|
-
const file2 = readPersistedQueue(queueKey);
|
|
35434
|
+
const file2 = await readPersistedQueue(queueKey);
|
|
35347
35435
|
if (!file2) continue;
|
|
35348
35436
|
const running = file2.turns.find((t) => t.lastClientState === "running");
|
|
35349
35437
|
if (!running || !startedThisTick.has(running.turnId)) continue;
|
|
@@ -35351,17 +35439,17 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
35351
35439
|
dispatchLocalPrompt(running, deps);
|
|
35352
35440
|
}
|
|
35353
35441
|
}
|
|
35354
|
-
function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
|
|
35442
|
+
async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
|
|
35355
35443
|
if (!runId) return false;
|
|
35356
35444
|
const queueKey = runIdToQueueKey.get(runId);
|
|
35357
35445
|
runIdToQueueKey.delete(runId);
|
|
35358
35446
|
if (!queueKey) return false;
|
|
35359
|
-
const f = readPersistedQueue(queueKey);
|
|
35447
|
+
const f = await readPersistedQueue(queueKey);
|
|
35360
35448
|
if (!f) return false;
|
|
35361
35449
|
const t = f.turns.find((x) => x.turnId === runId);
|
|
35362
35450
|
if (!t) return false;
|
|
35363
35451
|
t.lastClientState = opts?.terminalClientState ?? (success2 ? "stopped" : "failed");
|
|
35364
|
-
writePersistedQueue(f);
|
|
35452
|
+
await writePersistedQueue(f);
|
|
35365
35453
|
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, clientState: t.lastClientState }] });
|
|
35366
35454
|
return true;
|
|
35367
35455
|
}
|
|
@@ -35382,12 +35470,13 @@ function createBridgePromptSenders(deps, getWs) {
|
|
|
35382
35470
|
if (result.type === "prompt_result") {
|
|
35383
35471
|
const pr = result;
|
|
35384
35472
|
const cancelled = pr.stopReason === "cancelled";
|
|
35385
|
-
finalizePromptTurnOnBridge(
|
|
35473
|
+
void finalizePromptTurnOnBridge(
|
|
35386
35474
|
getWs,
|
|
35387
35475
|
typeof pr.runId === "string" ? pr.runId : void 0,
|
|
35388
35476
|
pr.success === true,
|
|
35389
35477
|
cancelled ? { terminalClientState: "cancelled" } : void 0
|
|
35390
|
-
)
|
|
35478
|
+
).catch(() => {
|
|
35479
|
+
});
|
|
35391
35480
|
}
|
|
35392
35481
|
};
|
|
35393
35482
|
const sendSessionUpdate = (payload) => {
|
|
@@ -35946,7 +36035,7 @@ function handleFileBrowserSearch(msg, socket, e2ee) {
|
|
|
35946
36035
|
await yieldToEventLoop();
|
|
35947
36036
|
const q = typeof msg.q === "string" ? msg.q : "";
|
|
35948
36037
|
const cwd = path36.resolve(getBridgeRoot());
|
|
35949
|
-
if (!bridgeFileIndexIsPopulated(cwd)) {
|
|
36038
|
+
if (!await bridgeFileIndexIsPopulated(cwd)) {
|
|
35950
36039
|
const payload2 = {
|
|
35951
36040
|
type: "file_browser_search_response",
|
|
35952
36041
|
id: msg.id,
|
|
@@ -36786,7 +36875,7 @@ import * as path39 from "node:path";
|
|
|
36786
36875
|
// src/agents/capabilities/probe-one-agent-type-for-capabilities.ts
|
|
36787
36876
|
import * as path38 from "node:path";
|
|
36788
36877
|
async function probeOneAgentTypeForCapabilities(params) {
|
|
36789
|
-
const { agentType, cwd, workspaceId, log: log2,
|
|
36878
|
+
const { agentType, cwd, workspaceId, log: log2, reportAgentCapabilities, bridgeReport = true } = params;
|
|
36790
36879
|
const resolved = resolveAgentCommand(agentType);
|
|
36791
36880
|
if (!resolved) return false;
|
|
36792
36881
|
let sqliteChanged = false;
|
|
@@ -36797,11 +36886,13 @@ async function probeOneAgentTypeForCapabilities(params) {
|
|
|
36797
36886
|
reportedRef.done = true;
|
|
36798
36887
|
let changed = false;
|
|
36799
36888
|
try {
|
|
36800
|
-
changed =
|
|
36801
|
-
|
|
36802
|
-
|
|
36803
|
-
|
|
36804
|
-
|
|
36889
|
+
changed = withCliSqliteSync(
|
|
36890
|
+
(db) => upsertCliAgentCapabilityCache(db, {
|
|
36891
|
+
workspaceId,
|
|
36892
|
+
agentType,
|
|
36893
|
+
configOptions: co
|
|
36894
|
+
})
|
|
36895
|
+
);
|
|
36805
36896
|
} catch {
|
|
36806
36897
|
}
|
|
36807
36898
|
sqliteChanged ||= changed;
|
|
@@ -36859,7 +36950,6 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
|
|
|
36859
36950
|
cwd,
|
|
36860
36951
|
workspaceId,
|
|
36861
36952
|
log: log2,
|
|
36862
|
-
getDb,
|
|
36863
36953
|
reportAgentCapabilities,
|
|
36864
36954
|
bridgeReport = true,
|
|
36865
36955
|
forceAllTypes = false
|
|
@@ -36871,7 +36961,7 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
|
|
|
36871
36961
|
if (!agentType.trim()) continue;
|
|
36872
36962
|
if (!forceAllTypes) {
|
|
36873
36963
|
try {
|
|
36874
|
-
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))) {
|
|
36875
36965
|
continue;
|
|
36876
36966
|
}
|
|
36877
36967
|
} catch {
|
|
@@ -36882,7 +36972,6 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
|
|
|
36882
36972
|
cwd,
|
|
36883
36973
|
workspaceId,
|
|
36884
36974
|
log: log2,
|
|
36885
|
-
getDb,
|
|
36886
36975
|
reportAgentCapabilities,
|
|
36887
36976
|
bridgeReport
|
|
36888
36977
|
});
|
|
@@ -36893,14 +36982,13 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
|
|
|
36893
36982
|
|
|
36894
36983
|
// src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
|
|
36895
36984
|
async function warmupAgentCapabilitiesOnConnect(params) {
|
|
36896
|
-
const { workspaceId, log: log2,
|
|
36985
|
+
const { workspaceId, log: log2, getWs } = params;
|
|
36897
36986
|
const cwd = path39.resolve(getBridgeRoot());
|
|
36898
|
-
|
|
36899
|
-
function sendBatchFromCache() {
|
|
36987
|
+
async function sendBatchFromCache() {
|
|
36900
36988
|
const socket = getWs();
|
|
36901
36989
|
if (!socket || socket.readyState !== wrapper_default.OPEN) return;
|
|
36902
36990
|
try {
|
|
36903
|
-
const rows = listCliAgentCapabilityCacheForWorkspace(db, workspaceId);
|
|
36991
|
+
const rows = await withCliSqlite((db) => listCliAgentCapabilityCacheForWorkspace(db, workspaceId));
|
|
36904
36992
|
if (rows.length === 0) return;
|
|
36905
36993
|
sendWsMessage(socket, {
|
|
36906
36994
|
type: "agent_capabilities_batch",
|
|
@@ -36912,7 +37000,7 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
36912
37000
|
);
|
|
36913
37001
|
}
|
|
36914
37002
|
}
|
|
36915
|
-
sendBatchFromCache();
|
|
37003
|
+
await sendBatchFromCache();
|
|
36916
37004
|
let types = [];
|
|
36917
37005
|
try {
|
|
36918
37006
|
types = [...await detectLocalAgentTypes()];
|
|
@@ -36925,11 +37013,10 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
36925
37013
|
cwd,
|
|
36926
37014
|
workspaceId,
|
|
36927
37015
|
log: log2,
|
|
36928
|
-
getDb,
|
|
36929
37016
|
bridgeReport: false,
|
|
36930
37017
|
forceAllTypes: false
|
|
36931
37018
|
});
|
|
36932
|
-
if (n > 0) sendBatchFromCache();
|
|
37019
|
+
if (n > 0) await sendBatchFromCache();
|
|
36933
37020
|
} catch (e) {
|
|
36934
37021
|
log2(`[Bridge service] Agent capability probe (missing cache) failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
36935
37022
|
}
|
|
@@ -36941,11 +37028,10 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
36941
37028
|
cwd,
|
|
36942
37029
|
workspaceId,
|
|
36943
37030
|
log: log2,
|
|
36944
|
-
getDb,
|
|
36945
37031
|
bridgeReport: false,
|
|
36946
37032
|
forceAllTypes: true
|
|
36947
37033
|
});
|
|
36948
|
-
if (n > 0) sendBatchFromCache();
|
|
37034
|
+
if (n > 0) await sendBatchFromCache();
|
|
36949
37035
|
} catch (e) {
|
|
36950
37036
|
log2(`[Bridge service] Agent capability lazy refresh failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
36951
37037
|
}
|
|
@@ -36957,7 +37043,7 @@ async function createBridgeConnection(options) {
|
|
|
36957
37043
|
const { apiUrl, workspaceId, justAuthenticated, onAuthInvalid, persistTokens } = options;
|
|
36958
37044
|
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
36959
37045
|
const logFn = options.log ?? log;
|
|
36960
|
-
|
|
37046
|
+
await ensureCliSqliteInitialized({ logLegacyMigration: logFn });
|
|
36961
37047
|
const tokens = {
|
|
36962
37048
|
accessToken: options.authToken,
|
|
36963
37049
|
refreshToken: options.refreshToken
|
|
@@ -36987,11 +37073,13 @@ async function createBridgeConnection(options) {
|
|
|
36987
37073
|
if (!Array.isArray(info.configOptions) || info.configOptions.length === 0) return;
|
|
36988
37074
|
let changed = false;
|
|
36989
37075
|
try {
|
|
36990
|
-
changed =
|
|
36991
|
-
|
|
36992
|
-
|
|
36993
|
-
|
|
36994
|
-
|
|
37076
|
+
changed = withCliSqliteSync(
|
|
37077
|
+
(db) => upsertCliAgentCapabilityCache(db, {
|
|
37078
|
+
workspaceId,
|
|
37079
|
+
agentType: info.agentType,
|
|
37080
|
+
configOptions: info.configOptions
|
|
37081
|
+
})
|
|
37082
|
+
);
|
|
36995
37083
|
} catch {
|
|
36996
37084
|
}
|
|
36997
37085
|
if (!changed) return;
|
|
@@ -37044,7 +37132,6 @@ async function createBridgeConnection(options) {
|
|
|
37044
37132
|
await warmupAgentCapabilitiesOnConnect({
|
|
37045
37133
|
workspaceId,
|
|
37046
37134
|
log: logFn,
|
|
37047
|
-
getDb: getCliDatabase,
|
|
37048
37135
|
getWs
|
|
37049
37136
|
});
|
|
37050
37137
|
},
|