@adhdev/daemon-core 0.9.82-rc.139 → 0.9.82-rc.140
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-adapters/cli-state-engine.d.ts +9 -0
- package/dist/config/config.d.ts +5 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +255 -140
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +218 -109
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/coordinator-registry.d.ts +25 -0
- package/dist/shared-types.d.ts +5 -0
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +2 -0
- package/src/cli-adapters/cli-state-engine.ts +41 -12
- package/src/cli-adapters/provider-cli-adapter.ts +15 -13
- package/src/commands/cli-manager.ts +4 -0
- package/src/commands/router.ts +13 -4
- package/src/config/config.ts +12 -0
- package/src/index.ts +3 -1
- package/src/mesh/coordinator-registry.ts +75 -0
- package/src/providers/cli-provider-instance.ts +19 -2
- package/src/shared-types.ts +2 -0
- package/src/status/builders.ts +23 -6
package/dist/index.mjs
CHANGED
|
@@ -429,6 +429,7 @@ var config_exports = {};
|
|
|
429
429
|
__export(config_exports, {
|
|
430
430
|
generateMachineId: () => generateMachineId,
|
|
431
431
|
getConfigDir: () => getConfigDir,
|
|
432
|
+
getDaemonDataDir: () => getDaemonDataDir,
|
|
432
433
|
isSetupComplete: () => isSetupComplete,
|
|
433
434
|
isStableMachineId: () => isStableMachineId,
|
|
434
435
|
loadConfig: () => loadConfig,
|
|
@@ -541,6 +542,13 @@ function getConfigDir() {
|
|
|
541
542
|
}
|
|
542
543
|
return dir;
|
|
543
544
|
}
|
|
545
|
+
function getDaemonDataDir() {
|
|
546
|
+
const dir = join2(getConfigDir(), "daemon");
|
|
547
|
+
if (!existsSync2(dir)) {
|
|
548
|
+
mkdirSync(dir, { recursive: true });
|
|
549
|
+
}
|
|
550
|
+
return dir;
|
|
551
|
+
}
|
|
544
552
|
function getConfigPath() {
|
|
545
553
|
return join2(getConfigDir(), "config.json");
|
|
546
554
|
}
|
|
@@ -1297,8 +1305,8 @@ __export(mesh_ledger_exports, {
|
|
|
1297
1305
|
readLedgerEntries: () => readLedgerEntries,
|
|
1298
1306
|
readLedgerSlice: () => readLedgerSlice
|
|
1299
1307
|
});
|
|
1300
|
-
import { appendFileSync, existsSync as
|
|
1301
|
-
import { join as
|
|
1308
|
+
import { appendFileSync, existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync6, statSync as statSync2, renameSync, writeFileSync as writeFileSync4 } from "fs";
|
|
1309
|
+
import { join as join8 } from "path";
|
|
1302
1310
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
1303
1311
|
import { EventEmitter } from "events";
|
|
1304
1312
|
function isIntentionalCleanupStopEntry(entry) {
|
|
@@ -1307,35 +1315,35 @@ function isIntentionalCleanupStopEntry(entry) {
|
|
|
1307
1315
|
return payload.intentional === true && (payload.reason === "operator_cleanup" || payload.intentionalStopReason === "operator_cleanup" || payload.source === "mesh_cleanup_sessions" || payload.source === "mesh_remove_node");
|
|
1308
1316
|
}
|
|
1309
1317
|
function getLedgerDir() {
|
|
1310
|
-
const dir =
|
|
1311
|
-
if (!
|
|
1318
|
+
const dir = join8(getConfigDir(), LEDGER_DIR_NAME);
|
|
1319
|
+
if (!existsSync8(dir)) {
|
|
1312
1320
|
mkdirSync3(dir, { recursive: true, mode: 448 });
|
|
1313
1321
|
}
|
|
1314
1322
|
return dir;
|
|
1315
1323
|
}
|
|
1316
1324
|
function getLedgerPath(meshId) {
|
|
1317
1325
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1318
|
-
return
|
|
1326
|
+
return join8(getLedgerDir(), `${safe}.jsonl`);
|
|
1319
1327
|
}
|
|
1320
1328
|
function getRotatedPath(meshId, index) {
|
|
1321
1329
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1322
|
-
return
|
|
1330
|
+
return join8(getLedgerDir(), `${safe}.${index}.jsonl`);
|
|
1323
1331
|
}
|
|
1324
1332
|
function getArchivePath(meshId) {
|
|
1325
1333
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1326
|
-
return
|
|
1334
|
+
return join8(getLedgerDir(), `${safe}.archive.jsonl`);
|
|
1327
1335
|
}
|
|
1328
1336
|
function getRotatedArchivePath(meshId, index) {
|
|
1329
1337
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1330
|
-
return
|
|
1338
|
+
return join8(getLedgerDir(), `${safe}.archive.${index}.jsonl`);
|
|
1331
1339
|
}
|
|
1332
1340
|
function getArchivedCountsPath(meshId) {
|
|
1333
1341
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1334
|
-
return
|
|
1342
|
+
return join8(getLedgerDir(), `${safe}.archived-counts.json`);
|
|
1335
1343
|
}
|
|
1336
1344
|
function rotateArchiveFile(meshId, archivePath) {
|
|
1337
1345
|
let index = 1;
|
|
1338
|
-
while (
|
|
1346
|
+
while (existsSync8(getRotatedArchivePath(meshId, index))) {
|
|
1339
1347
|
index++;
|
|
1340
1348
|
if (index > 5) break;
|
|
1341
1349
|
}
|
|
@@ -1349,9 +1357,9 @@ function rotateArchiveFile(meshId, archivePath) {
|
|
|
1349
1357
|
}
|
|
1350
1358
|
function readArchivedCounts(meshId) {
|
|
1351
1359
|
const path28 = getArchivedCountsPath(meshId);
|
|
1352
|
-
if (!
|
|
1360
|
+
if (!existsSync8(path28)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
1353
1361
|
try {
|
|
1354
|
-
return JSON.parse(
|
|
1362
|
+
return JSON.parse(readFileSync6(path28, "utf-8"));
|
|
1355
1363
|
} catch {
|
|
1356
1364
|
return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
1357
1365
|
}
|
|
@@ -1367,7 +1375,7 @@ function updateArchivedCounts(meshId, archived) {
|
|
|
1367
1375
|
counts.totalArchived += archived.length;
|
|
1368
1376
|
counts.lastArchivedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1369
1377
|
try {
|
|
1370
|
-
|
|
1378
|
+
writeFileSync4(getArchivedCountsPath(meshId), JSON.stringify(counts), { encoding: "utf-8", mode: 384 });
|
|
1371
1379
|
} catch {
|
|
1372
1380
|
}
|
|
1373
1381
|
}
|
|
@@ -1390,7 +1398,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
1390
1398
|
}
|
|
1391
1399
|
function compactLedger(meshId) {
|
|
1392
1400
|
const filePath = getLedgerPath(meshId);
|
|
1393
|
-
if (!
|
|
1401
|
+
if (!existsSync8(filePath)) return { archivedCount: 0, retainedCount: 0 };
|
|
1394
1402
|
const cutoff = Date.now() - ARCHIVE_TERMINAL_OLDER_THAN_MS;
|
|
1395
1403
|
const entries = readLedgerEntries(meshId);
|
|
1396
1404
|
const keep = [];
|
|
@@ -1405,7 +1413,7 @@ function compactLedger(meshId) {
|
|
|
1405
1413
|
if (archive.length === 0) return { archivedCount: 0, retainedCount: keep.length };
|
|
1406
1414
|
const archivePath = getArchivePath(meshId);
|
|
1407
1415
|
try {
|
|
1408
|
-
if (
|
|
1416
|
+
if (existsSync8(archivePath) && statSync2(archivePath).size > 50 * 1024 * 1024) {
|
|
1409
1417
|
rotateArchiveFile(meshId, archivePath);
|
|
1410
1418
|
}
|
|
1411
1419
|
const archiveLines = archive.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
@@ -1418,7 +1426,7 @@ function compactLedger(meshId) {
|
|
|
1418
1426
|
}
|
|
1419
1427
|
try {
|
|
1420
1428
|
const keepLines = keep.length ? keep.map((e) => JSON.stringify(e)).join("\n") + "\n" : "";
|
|
1421
|
-
|
|
1429
|
+
writeFileSync4(filePath, keepLines, { encoding: "utf-8", mode: 384 });
|
|
1422
1430
|
invalidateLedgerCache(meshId);
|
|
1423
1431
|
} catch (e) {
|
|
1424
1432
|
process.stderr.write(`[adhdev-mesh] Ledger compaction rewrite failed for mesh ${meshId}: ${e?.message || e}
|
|
@@ -1550,7 +1558,7 @@ function appendLedgerEntry(meshId, partial) {
|
|
|
1550
1558
|
...partial
|
|
1551
1559
|
};
|
|
1552
1560
|
const filePath = getLedgerPath(meshId);
|
|
1553
|
-
if (
|
|
1561
|
+
if (existsSync8(filePath)) {
|
|
1554
1562
|
try {
|
|
1555
1563
|
const stat2 = statSync2(filePath);
|
|
1556
1564
|
if (stat2.size >= MAX_FILE_SIZE_BYTES) {
|
|
@@ -1621,10 +1629,10 @@ function appendRemoteLedgerEntries(meshId, entries) {
|
|
|
1621
1629
|
}
|
|
1622
1630
|
function readLedgerFile(meshId) {
|
|
1623
1631
|
const filePath = getLedgerPath(meshId);
|
|
1624
|
-
if (!
|
|
1632
|
+
if (!existsSync8(filePath)) return [];
|
|
1625
1633
|
let content;
|
|
1626
1634
|
try {
|
|
1627
|
-
content =
|
|
1635
|
+
content = readFileSync6(filePath, "utf-8");
|
|
1628
1636
|
} catch {
|
|
1629
1637
|
return [];
|
|
1630
1638
|
}
|
|
@@ -1825,7 +1833,7 @@ function getSessionRecoveryContext(meshId, opts) {
|
|
|
1825
1833
|
}
|
|
1826
1834
|
function rotateLedgerFile(meshId, currentPath) {
|
|
1827
1835
|
let index = 1;
|
|
1828
|
-
while (
|
|
1836
|
+
while (existsSync8(getRotatedPath(meshId, index))) {
|
|
1829
1837
|
index++;
|
|
1830
1838
|
if (index > 10) break;
|
|
1831
1839
|
}
|
|
@@ -1862,8 +1870,8 @@ var init_mesh_ledger = __esm({
|
|
|
1862
1870
|
});
|
|
1863
1871
|
|
|
1864
1872
|
// src/mesh/beads-db.ts
|
|
1865
|
-
import { existsSync as
|
|
1866
|
-
import { dirname as dirname2, join as
|
|
1873
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
|
|
1874
|
+
import { dirname as dirname2, join as join9 } from "path";
|
|
1867
1875
|
import { createRequire } from "module";
|
|
1868
1876
|
function loadDatabaseCtor() {
|
|
1869
1877
|
if (DatabaseCtor) return DatabaseCtor;
|
|
@@ -1875,7 +1883,7 @@ function safeMeshId(meshId) {
|
|
|
1875
1883
|
return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1876
1884
|
}
|
|
1877
1885
|
function legacyQueuePath(meshId) {
|
|
1878
|
-
return
|
|
1886
|
+
return join9(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
|
|
1879
1887
|
}
|
|
1880
1888
|
var DatabaseCtor, BeadsDB;
|
|
1881
1889
|
var init_beads_db = __esm({
|
|
@@ -1894,7 +1902,7 @@ var init_beads_db = __esm({
|
|
|
1894
1902
|
// 50 MB
|
|
1895
1903
|
constructor(dbPath) {
|
|
1896
1904
|
const dir = dirname2(dbPath);
|
|
1897
|
-
if (!
|
|
1905
|
+
if (!existsSync9(dir)) mkdirSync4(dir, { recursive: true });
|
|
1898
1906
|
this.dbPath = dbPath;
|
|
1899
1907
|
this.db = new (loadDatabaseCtor())(dbPath);
|
|
1900
1908
|
this.db.pragma("journal_mode = WAL");
|
|
@@ -1905,7 +1913,7 @@ var init_beads_db = __esm({
|
|
|
1905
1913
|
}
|
|
1906
1914
|
static getInstance() {
|
|
1907
1915
|
if (!this.instance) {
|
|
1908
|
-
this.instance = new _BeadsDB(
|
|
1916
|
+
this.instance = new _BeadsDB(join9(getLedgerDir(), "beads.db"));
|
|
1909
1917
|
}
|
|
1910
1918
|
return this.instance;
|
|
1911
1919
|
}
|
|
@@ -1985,7 +1993,7 @@ var init_beads_db = __esm({
|
|
|
1985
1993
|
this.walWriteCounter = 0;
|
|
1986
1994
|
try {
|
|
1987
1995
|
const walPath = `${this.dbPath}-wal`;
|
|
1988
|
-
if (!
|
|
1996
|
+
if (!existsSync9(walPath)) return;
|
|
1989
1997
|
const size = statSync3(walPath).size;
|
|
1990
1998
|
if (size < _BeadsDB.WAL_MAX_BYTES) return;
|
|
1991
1999
|
process.stderr.write(
|
|
@@ -2002,9 +2010,9 @@ var init_beads_db = __esm({
|
|
|
2002
2010
|
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
2003
2011
|
if (count.count > 0) return;
|
|
2004
2012
|
const path28 = legacyQueuePath(meshId);
|
|
2005
|
-
if (!
|
|
2013
|
+
if (!existsSync9(path28)) return;
|
|
2006
2014
|
try {
|
|
2007
|
-
const entries = JSON.parse(
|
|
2015
|
+
const entries = JSON.parse(readFileSync7(path28, "utf-8"));
|
|
2008
2016
|
if (!Array.isArray(entries)) return;
|
|
2009
2017
|
const insert = this.db.prepare(`
|
|
2010
2018
|
INSERT OR REPLACE INTO mesh_queue (
|
|
@@ -2501,7 +2509,7 @@ var init_mesh_work_queue = __esm({
|
|
|
2501
2509
|
import { exec } from "child_process";
|
|
2502
2510
|
import * as os2 from "os";
|
|
2503
2511
|
import * as path8 from "path";
|
|
2504
|
-
import { existsSync as
|
|
2512
|
+
import { existsSync as existsSync10 } from "fs";
|
|
2505
2513
|
function parseVersion(raw) {
|
|
2506
2514
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
2507
2515
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
@@ -2525,7 +2533,7 @@ function resolveCommandPath(command) {
|
|
|
2525
2533
|
if (isExplicitCommandPath(trimmed)) {
|
|
2526
2534
|
const expanded = expandHome(trimmed);
|
|
2527
2535
|
const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
|
|
2528
|
-
return
|
|
2536
|
+
return existsSync10(candidate) ? candidate : null;
|
|
2529
2537
|
}
|
|
2530
2538
|
return null;
|
|
2531
2539
|
}
|
|
@@ -2912,8 +2920,8 @@ __export(mesh_events_exports, {
|
|
|
2912
2920
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
2913
2921
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
2914
2922
|
});
|
|
2915
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
2916
|
-
import { join as
|
|
2923
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync12, readFileSync as readFileSync8, renameSync as renameSync3, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
2924
|
+
import { join as join12 } from "path";
|
|
2917
2925
|
function getCachedMeshByWorkspace(workspace) {
|
|
2918
2926
|
const now = Date.now();
|
|
2919
2927
|
const cached = meshByWorkspaceCache.get(workspace);
|
|
@@ -2976,18 +2984,18 @@ function getPendingEventsPath(meshId, coordinatorDaemonId) {
|
|
|
2976
2984
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2977
2985
|
if (coordinatorDaemonId) {
|
|
2978
2986
|
const safeDaemon = coordinatorDaemonId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2979
|
-
return
|
|
2987
|
+
return join12(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
|
|
2980
2988
|
}
|
|
2981
|
-
return
|
|
2989
|
+
return join12(getLedgerDir(), `${safe}.pending-events.jsonl`);
|
|
2982
2990
|
}
|
|
2983
2991
|
function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
2984
2992
|
if (!meshId) return [];
|
|
2985
2993
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
2986
2994
|
const events = [];
|
|
2987
2995
|
for (const path28 of paths) {
|
|
2988
|
-
if (!
|
|
2996
|
+
if (!existsSync12(path28)) continue;
|
|
2989
2997
|
try {
|
|
2990
|
-
const raw =
|
|
2998
|
+
const raw = readFileSync8(path28, "utf-8");
|
|
2991
2999
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
2992
3000
|
try {
|
|
2993
3001
|
return [JSON.parse(line)];
|
|
@@ -3066,11 +3074,11 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
3066
3074
|
}
|
|
3067
3075
|
function trimPendingEventsIfNeeded(path28) {
|
|
3068
3076
|
try {
|
|
3069
|
-
if (!
|
|
3077
|
+
if (!existsSync12(path28)) return;
|
|
3070
3078
|
if (statSync5(path28).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
3071
|
-
const lines =
|
|
3079
|
+
const lines = readFileSync8(path28, "utf-8").split("\n").filter(Boolean);
|
|
3072
3080
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
3073
|
-
|
|
3081
|
+
writeFileSync5(path28, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
|
|
3074
3082
|
} catch {
|
|
3075
3083
|
}
|
|
3076
3084
|
}
|
|
@@ -3101,7 +3109,7 @@ function atomicDrainFile(path28) {
|
|
|
3101
3109
|
return null;
|
|
3102
3110
|
}
|
|
3103
3111
|
try {
|
|
3104
|
-
const content =
|
|
3112
|
+
const content = readFileSync8(tmpPath, "utf-8");
|
|
3105
3113
|
try {
|
|
3106
3114
|
unlinkSync2(tmpPath);
|
|
3107
3115
|
} catch {
|
|
@@ -3143,7 +3151,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3143
3151
|
if (!meshId) return;
|
|
3144
3152
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3145
3153
|
for (const path28 of paths) {
|
|
3146
|
-
if (
|
|
3154
|
+
if (existsSync12(path28)) try {
|
|
3147
3155
|
unlinkSync2(path28);
|
|
3148
3156
|
} catch {
|
|
3149
3157
|
}
|
|
@@ -5188,6 +5196,15 @@ var init_cli_state_engine = __esm({
|
|
|
5188
5196
|
// ── Approval ─────────────────────────────────────
|
|
5189
5197
|
lastApprovalResolvedAt = 0;
|
|
5190
5198
|
lastResolvedModalMessage = "";
|
|
5199
|
+
/**
|
|
5200
|
+
* When the engine previously held a modal but the latest parse failed
|
|
5201
|
+
* to extract one, we record the timestamp here and only drop the modal
|
|
5202
|
+
* after the configured `approvalCooldown` to avoid flapping between
|
|
5203
|
+
* waiting_approval and generating on every Claude TUI redraw — that
|
|
5204
|
+
* flapping is what fed auto-approve a fresh modal signature on each
|
|
5205
|
+
* paint and made the engine type "1" repeatedly into the prompt.
|
|
5206
|
+
*/
|
|
5207
|
+
modalLostAt = 0;
|
|
5191
5208
|
approvalExitTimeout = null;
|
|
5192
5209
|
// ── Response tracking ────────────────────────────
|
|
5193
5210
|
responseEpoch = 0;
|
|
@@ -5292,7 +5309,9 @@ var init_cli_state_engine = __esm({
|
|
|
5292
5309
|
} catch {
|
|
5293
5310
|
}
|
|
5294
5311
|
}
|
|
5295
|
-
if (!this.transport.isAlive()
|
|
5312
|
+
if (!this.transport.isAlive()) return;
|
|
5313
|
+
const buttonsValid = Array.isArray(modal?.buttons) && modal.buttons.some((b) => typeof b === "string" && b.trim());
|
|
5314
|
+
if (!modal || !buttonsValid) return;
|
|
5296
5315
|
const currentModalMessage = typeof modal?.message === "string" ? modal.message.trim() : "";
|
|
5297
5316
|
const inCooldown = !!this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
5298
5317
|
if (inCooldown && currentModalMessage === this.lastResolvedModalMessage) return;
|
|
@@ -5642,13 +5661,19 @@ var init_cli_state_engine = __esm({
|
|
|
5642
5661
|
if (!inCooldown) {
|
|
5643
5662
|
if (!modal) {
|
|
5644
5663
|
LOG.warn("CLI", `[${this.provider.type}] detectStatus=waiting_approval but parseApproval returned null; ignoring`);
|
|
5645
|
-
if (this.currentStatus === "waiting_approval") {
|
|
5646
|
-
this.
|
|
5647
|
-
this.
|
|
5648
|
-
this.
|
|
5664
|
+
if (this.currentStatus === "waiting_approval" && this.activeModal) {
|
|
5665
|
+
const lostAt = this.modalLostAt || Date.now();
|
|
5666
|
+
if (!this.modalLostAt) this.modalLostAt = lostAt;
|
|
5667
|
+
if (Date.now() - lostAt >= this.timeouts.approvalCooldown) {
|
|
5668
|
+
this.activeModal = null;
|
|
5669
|
+
this.modalLostAt = 0;
|
|
5670
|
+
this.setStatus("generating", "approval_lost_modal");
|
|
5671
|
+
this.callbacks.onStatusChange();
|
|
5672
|
+
}
|
|
5649
5673
|
}
|
|
5650
5674
|
return;
|
|
5651
5675
|
}
|
|
5676
|
+
this.modalLostAt = 0;
|
|
5652
5677
|
this.isWaitingForResponse = true;
|
|
5653
5678
|
this.setStatus("waiting_approval", "script_detect");
|
|
5654
5679
|
const prev = this.activeModal;
|
|
@@ -6775,19 +6800,12 @@ ${lastSnapshot}`;
|
|
|
6775
6800
|
const liveDetect = this.runDetectStatus(this.recentOutputBuffer || this.terminalScreen.getText());
|
|
6776
6801
|
if (liveDetect === "waiting_approval") {
|
|
6777
6802
|
const liveModal = this.runParseApproval(this.terminalScreen.getText()) || this.runParseApproval(this.recentOutputBuffer);
|
|
6778
|
-
|
|
6803
|
+
const buttonsOk = liveModal && Array.isArray(liveModal.buttons) && liveModal.buttons.some((b) => typeof b === "string" && b.trim());
|
|
6804
|
+
if (liveModal && buttonsOk) {
|
|
6779
6805
|
effectiveModal = liveModal;
|
|
6780
6806
|
if (!this.engine.activeModal) this.engine.activeModal = liveModal;
|
|
6781
|
-
} else {
|
|
6782
|
-
LOG.warn("CLI", `[${this.cliType}] getStatus live re-extract: detect=waiting_approval but parseApproval still null (recentLen=${this.recentOutputBuffer.length} screenLen=${this.terminalScreen.getText().length})`);
|
|
6783
6807
|
}
|
|
6784
|
-
} else if (liveDetect && liveDetect !== "generating" && liveDetect !== "idle") {
|
|
6785
|
-
LOG.warn("CLI", `[${this.cliType}] getStatus live re-extract: detect=${liveDetect} (not waiting_approval)`);
|
|
6786
|
-
} else if (this.engine.currentStatus === "waiting_approval" && liveDetect !== "waiting_approval") {
|
|
6787
|
-
LOG.warn("CLI", `[${this.cliType}] getStatus live re-extract: engine.status=waiting_approval but live detect=${liveDetect}`);
|
|
6788
6808
|
}
|
|
6789
|
-
} else if (!effectiveModal && this.engine.currentStatus === "waiting_approval") {
|
|
6790
|
-
LOG.warn("CLI", `[${this.cliType}] getStatus skipped live re-extract: allowParse=${allowParse} isWaitingForResponse=${this.engine.isWaitingForResponse}`);
|
|
6791
6809
|
}
|
|
6792
6810
|
if (startupDetectedStatus === "waiting_approval" && effectiveModal) {
|
|
6793
6811
|
effectiveStatus = "waiting_approval";
|
|
@@ -7700,7 +7718,8 @@ ${lastSnapshot}`;
|
|
|
7700
7718
|
if (parsedDebugState?.status === "error") {
|
|
7701
7719
|
effectiveStatus = "error";
|
|
7702
7720
|
}
|
|
7703
|
-
|
|
7721
|
+
const debugEffectiveModal = startupModal || this.engine.activeModal;
|
|
7722
|
+
if (startupDetectedStatus === "waiting_approval" && debugEffectiveModal) {
|
|
7704
7723
|
effectiveStatus = "waiting_approval";
|
|
7705
7724
|
}
|
|
7706
7725
|
if (effectiveStatus === "idle" && parsedDebugState?.status === "generating" && !hasFinalAssistant(parsedDebugState)) {
|
|
@@ -9545,9 +9564,58 @@ function getSavedProviderSessions(state, filters) {
|
|
|
9545
9564
|
init_mesh_config();
|
|
9546
9565
|
init_coordinator_prompt();
|
|
9547
9566
|
|
|
9548
|
-
// src/mesh/
|
|
9549
|
-
|
|
9567
|
+
// src/mesh/coordinator-registry.ts
|
|
9568
|
+
init_config();
|
|
9550
9569
|
import { join as join5 } from "path";
|
|
9570
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
9571
|
+
var _registry = /* @__PURE__ */ new Map();
|
|
9572
|
+
function getRegistryPath() {
|
|
9573
|
+
return join5(getDaemonDataDir(), "mesh-coordinators.json");
|
|
9574
|
+
}
|
|
9575
|
+
function loadMeshCoordinatorRegistry() {
|
|
9576
|
+
const path28 = getRegistryPath();
|
|
9577
|
+
if (!existsSync5(path28)) return;
|
|
9578
|
+
try {
|
|
9579
|
+
const raw = JSON.parse(readFileSync3(path28, "utf-8"));
|
|
9580
|
+
if (!Array.isArray(raw)) return;
|
|
9581
|
+
_registry.clear();
|
|
9582
|
+
for (const entry of raw) {
|
|
9583
|
+
if (typeof entry?.sessionId === "string" && typeof entry?.meshId === "string") {
|
|
9584
|
+
_registry.set(entry.sessionId, entry);
|
|
9585
|
+
}
|
|
9586
|
+
}
|
|
9587
|
+
} catch {
|
|
9588
|
+
}
|
|
9589
|
+
}
|
|
9590
|
+
function saveRegistry() {
|
|
9591
|
+
try {
|
|
9592
|
+
writeFileSync3(
|
|
9593
|
+
getRegistryPath(),
|
|
9594
|
+
JSON.stringify([..._registry.values()], null, 2),
|
|
9595
|
+
{ encoding: "utf-8", mode: 384 }
|
|
9596
|
+
);
|
|
9597
|
+
} catch {
|
|
9598
|
+
}
|
|
9599
|
+
}
|
|
9600
|
+
function registerMeshCoordinator(entry) {
|
|
9601
|
+
_registry.set(entry.sessionId, entry);
|
|
9602
|
+
saveRegistry();
|
|
9603
|
+
}
|
|
9604
|
+
function unregisterMeshCoordinator(sessionId) {
|
|
9605
|
+
if (_registry.delete(sessionId)) {
|
|
9606
|
+
saveRegistry();
|
|
9607
|
+
}
|
|
9608
|
+
}
|
|
9609
|
+
function getCoordinatorForSession(sessionId) {
|
|
9610
|
+
return _registry.get(sessionId);
|
|
9611
|
+
}
|
|
9612
|
+
function listCoordinatorsForWorkspace(workspace) {
|
|
9613
|
+
return [..._registry.values()].filter((e) => e.workspace === workspace);
|
|
9614
|
+
}
|
|
9615
|
+
|
|
9616
|
+
// src/mesh/refine-config.ts
|
|
9617
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
|
|
9618
|
+
import { join as join6 } from "path";
|
|
9551
9619
|
import * as yaml from "js-yaml";
|
|
9552
9620
|
var MESH_REFINE_VALIDATION_CATEGORIES = ["typecheck", "test", "lint", "build"];
|
|
9553
9621
|
var MESH_REFINE_CONFIG_LOCATIONS = [
|
|
@@ -9730,10 +9798,10 @@ function loadMeshRefineConfig(mesh, workspace) {
|
|
|
9730
9798
|
return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
|
|
9731
9799
|
}
|
|
9732
9800
|
for (const relative3 of MESH_REFINE_CONFIG_LOCATIONS) {
|
|
9733
|
-
const configPath =
|
|
9734
|
-
if (!
|
|
9801
|
+
const configPath = join6(workspace, relative3);
|
|
9802
|
+
if (!existsSync6(configPath)) continue;
|
|
9735
9803
|
try {
|
|
9736
|
-
const parsed = parseConfigText(configPath,
|
|
9804
|
+
const parsed = parseConfigText(configPath, readFileSync4(configPath, "utf-8"));
|
|
9737
9805
|
const validation = validateMeshRefineConfig(parsed, relative3);
|
|
9738
9806
|
if (!validation.valid) return { source: relative3, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
9739
9807
|
return { config: parsed, source: relative3, sourceType: "repo_file", path: configPath };
|
|
@@ -9749,7 +9817,7 @@ function loadMeshRefineConfig(mesh, workspace) {
|
|
|
9749
9817
|
}
|
|
9750
9818
|
function readPackageScripts(workspace) {
|
|
9751
9819
|
try {
|
|
9752
|
-
const parsed = JSON.parse(
|
|
9820
|
+
const parsed = JSON.parse(readFileSync4(join6(workspace, "package.json"), "utf-8"));
|
|
9753
9821
|
return isRecord(parsed?.scripts) ? parsed.scripts : {};
|
|
9754
9822
|
} catch {
|
|
9755
9823
|
return {};
|
|
@@ -9822,8 +9890,8 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
|
9822
9890
|
}
|
|
9823
9891
|
|
|
9824
9892
|
// src/mesh/worktree-bootstrap-config.ts
|
|
9825
|
-
import { existsSync as
|
|
9826
|
-
import { join as
|
|
9893
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
|
|
9894
|
+
import { join as join7, resolve as pathResolve } from "path";
|
|
9827
9895
|
import { execFile as execFile3 } from "child_process";
|
|
9828
9896
|
import { promisify as promisify3 } from "util";
|
|
9829
9897
|
import * as yaml2 from "js-yaml";
|
|
@@ -9913,10 +9981,10 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
9913
9981
|
return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
|
|
9914
9982
|
}
|
|
9915
9983
|
for (const relative3 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
9916
|
-
const configPath =
|
|
9917
|
-
if (!
|
|
9984
|
+
const configPath = join7(workspace, relative3);
|
|
9985
|
+
if (!existsSync7(configPath)) continue;
|
|
9918
9986
|
try {
|
|
9919
|
-
const parsed = parseConfigText2(configPath,
|
|
9987
|
+
const parsed = parseConfigText2(configPath, readFileSync5(configPath, "utf-8"));
|
|
9920
9988
|
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative3);
|
|
9921
9989
|
if (!validation.valid) return { source: relative3, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
9922
9990
|
return { config: parsed, source: relative3, sourceType: "repo_file", path: configPath };
|
|
@@ -9950,10 +10018,10 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
|
9950
10018
|
staleInputs: loaded.config.staleInputs
|
|
9951
10019
|
};
|
|
9952
10020
|
const staleInputPaths = loaded.config.staleInputs ?? [];
|
|
9953
|
-
const initiallyAbsent = staleInputPaths.filter((p) => !
|
|
10021
|
+
const initiallyAbsent = staleInputPaths.filter((p) => !existsSync7(join7(workspace, p)));
|
|
9954
10022
|
for (const command of validation.commands) {
|
|
9955
10023
|
if (initiallyAbsent.length > 0) {
|
|
9956
|
-
const appearedNow = initiallyAbsent.filter((p) =>
|
|
10024
|
+
const appearedNow = initiallyAbsent.filter((p) => existsSync7(join7(workspace, p)));
|
|
9957
10025
|
if (appearedNow.length > 0) {
|
|
9958
10026
|
state.status = "stale";
|
|
9959
10027
|
state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -11017,8 +11085,8 @@ var P2pRelayFailureError = class extends Error {
|
|
|
11017
11085
|
|
|
11018
11086
|
// src/config/state-store.ts
|
|
11019
11087
|
init_config();
|
|
11020
|
-
import { existsSync as
|
|
11021
|
-
import { join as
|
|
11088
|
+
import { existsSync as existsSync13, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "fs";
|
|
11089
|
+
import { join as join13 } from "path";
|
|
11022
11090
|
var DEFAULT_STATE = {
|
|
11023
11091
|
recentActivity: [],
|
|
11024
11092
|
savedProviderSessions: [],
|
|
@@ -11031,7 +11099,7 @@ function isPlainObject2(value) {
|
|
|
11031
11099
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
11032
11100
|
}
|
|
11033
11101
|
function getStatePath() {
|
|
11034
|
-
return
|
|
11102
|
+
return join13(getConfigDir(), "state.json");
|
|
11035
11103
|
}
|
|
11036
11104
|
function normalizeState(raw) {
|
|
11037
11105
|
const parsed = isPlainObject2(raw) ? raw : {};
|
|
@@ -11067,11 +11135,11 @@ function normalizeState(raw) {
|
|
|
11067
11135
|
}
|
|
11068
11136
|
function loadState() {
|
|
11069
11137
|
const statePath = getStatePath();
|
|
11070
|
-
if (!
|
|
11138
|
+
if (!existsSync13(statePath)) {
|
|
11071
11139
|
return { ...DEFAULT_STATE };
|
|
11072
11140
|
}
|
|
11073
11141
|
try {
|
|
11074
|
-
const raw =
|
|
11142
|
+
const raw = readFileSync9(statePath, "utf-8");
|
|
11075
11143
|
return normalizeState(JSON.parse(raw));
|
|
11076
11144
|
} catch {
|
|
11077
11145
|
return { ...DEFAULT_STATE };
|
|
@@ -11080,7 +11148,7 @@ function loadState() {
|
|
|
11080
11148
|
function saveState(state) {
|
|
11081
11149
|
const statePath = getStatePath();
|
|
11082
11150
|
const normalized = normalizeState(state);
|
|
11083
|
-
|
|
11151
|
+
writeFileSync6(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
11084
11152
|
}
|
|
11085
11153
|
function resetState() {
|
|
11086
11154
|
saveState({ ...DEFAULT_STATE });
|
|
@@ -11089,7 +11157,7 @@ function resetState() {
|
|
|
11089
11157
|
// src/detection/ide-detector.ts
|
|
11090
11158
|
import { exec as exec2 } from "child_process";
|
|
11091
11159
|
import { promisify as promisify4 } from "util";
|
|
11092
|
-
import { existsSync as
|
|
11160
|
+
import { existsSync as existsSync14, statSync as statSync6 } from "fs";
|
|
11093
11161
|
import { platform as platform2, homedir as homedir5 } from "os";
|
|
11094
11162
|
import * as path10 from "path";
|
|
11095
11163
|
var execAsync2 = promisify4(exec2);
|
|
@@ -11114,7 +11182,7 @@ function findCliCommand(command) {
|
|
|
11114
11182
|
if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
11115
11183
|
const candidate = trimmed.startsWith("~") ? path10.join(homedir5(), trimmed.slice(1)) : trimmed;
|
|
11116
11184
|
const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
|
|
11117
|
-
return
|
|
11185
|
+
return existsSync14(resolved) ? resolved : null;
|
|
11118
11186
|
}
|
|
11119
11187
|
const isWin = platform2() === "win32";
|
|
11120
11188
|
const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
|
|
@@ -11124,7 +11192,7 @@ function findCliCommand(command) {
|
|
|
11124
11192
|
for (const ext of exes) {
|
|
11125
11193
|
const fullPath = path10.join(p, trimmed + ext);
|
|
11126
11194
|
try {
|
|
11127
|
-
if (
|
|
11195
|
+
if (existsSync14(fullPath)) {
|
|
11128
11196
|
const stat2 = statSync6(fullPath);
|
|
11129
11197
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
11130
11198
|
return fullPath;
|
|
@@ -11154,9 +11222,9 @@ function checkPathExists(paths) {
|
|
|
11154
11222
|
if (normalized.includes("*")) {
|
|
11155
11223
|
const username = home.split(/[\\/]/).pop() || "";
|
|
11156
11224
|
const resolved = normalized.replace("*", username);
|
|
11157
|
-
if (
|
|
11225
|
+
if (existsSync14(resolved)) return resolved;
|
|
11158
11226
|
} else {
|
|
11159
|
-
if (
|
|
11227
|
+
if (existsSync14(normalized)) return normalized;
|
|
11160
11228
|
}
|
|
11161
11229
|
}
|
|
11162
11230
|
return null;
|
|
@@ -11170,7 +11238,7 @@ async function detectIDEs(providerLoader) {
|
|
|
11170
11238
|
let resolvedCli = cliPath;
|
|
11171
11239
|
if (!resolvedCli && appPath && os22 === "darwin") {
|
|
11172
11240
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
11173
|
-
if (
|
|
11241
|
+
if (existsSync14(bundledCli)) resolvedCli = bundledCli;
|
|
11174
11242
|
}
|
|
11175
11243
|
if (!resolvedCli && appPath && os22 === "win32") {
|
|
11176
11244
|
const { dirname: dirname9 } = await import("path");
|
|
@@ -11183,7 +11251,7 @@ async function detectIDEs(providerLoader) {
|
|
|
11183
11251
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
11184
11252
|
];
|
|
11185
11253
|
for (const c of candidates) {
|
|
11186
|
-
if (
|
|
11254
|
+
if (existsSync14(c)) {
|
|
11187
11255
|
resolvedCli = c;
|
|
11188
11256
|
break;
|
|
11189
11257
|
}
|
|
@@ -16920,7 +16988,7 @@ var ACP_SESSION_CAPABILITIES = [
|
|
|
16920
16988
|
"set_mode",
|
|
16921
16989
|
"set_thought_level"
|
|
16922
16990
|
];
|
|
16923
|
-
function
|
|
16991
|
+
function buildWorkspaceSession(state, cdpManagers, options) {
|
|
16924
16992
|
const profile = options.profile || "full";
|
|
16925
16993
|
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
16926
16994
|
const summaryMetadata = normalizeProviderSummaryMetadata(state.summaryMetadata);
|
|
@@ -16931,7 +16999,10 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
16931
16999
|
const git = getGitSummaryForWorkspace(workspace, options);
|
|
16932
17000
|
const title = activeChat?.title || state.name;
|
|
16933
17001
|
const meshCoordinatorFor = state.settings?.meshCoordinatorFor;
|
|
16934
|
-
const
|
|
17002
|
+
const registryEntry = state.instanceId ? getCoordinatorForSession(state.instanceId) : void 0;
|
|
17003
|
+
const effectiveMeshId = meshCoordinatorFor || registryEntry?.meshId;
|
|
17004
|
+
const coordinator = effectiveMeshId ? { meshId: effectiveMeshId, role: "coordinator" } : void 0;
|
|
17005
|
+
const meshQueueStats = effectiveMeshId ? getMeshQueueStats(effectiveMeshId) : void 0;
|
|
16935
17006
|
return {
|
|
16936
17007
|
id: state.instanceId || state.type,
|
|
16937
17008
|
parentId: null,
|
|
@@ -16955,6 +17026,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
16955
17026
|
errorReason: state.errorReason,
|
|
16956
17027
|
lastUpdated: state.lastUpdated,
|
|
16957
17028
|
settings: state.settings,
|
|
17029
|
+
...coordinator && { coordinator },
|
|
16958
17030
|
...meshQueueStats && { meshQueueStats }
|
|
16959
17031
|
};
|
|
16960
17032
|
}
|
|
@@ -16968,7 +17040,10 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
16968
17040
|
const workspace = parent.workspace || null;
|
|
16969
17041
|
const git = getGitSummaryForWorkspace(workspace, options);
|
|
16970
17042
|
const meshCoordinatorFor = ext.settings?.meshCoordinatorFor;
|
|
16971
|
-
const
|
|
17043
|
+
const registryEntry = ext.instanceId ? getCoordinatorForSession(ext.instanceId) : void 0;
|
|
17044
|
+
const effectiveMeshId = meshCoordinatorFor || registryEntry?.meshId;
|
|
17045
|
+
const coordinator = effectiveMeshId ? { meshId: effectiveMeshId, role: "coordinator" } : void 0;
|
|
17046
|
+
const meshQueueStats = effectiveMeshId ? getMeshQueueStats(effectiveMeshId) : void 0;
|
|
16972
17047
|
return {
|
|
16973
17048
|
id: ext.instanceId || `${parent.instanceId}:${ext.type}`,
|
|
16974
17049
|
parentId: parent.instanceId || parent.type,
|
|
@@ -16992,6 +17067,7 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
16992
17067
|
errorReason: ext.errorReason,
|
|
16993
17068
|
lastUpdated: ext.lastUpdated,
|
|
16994
17069
|
settings: ext.settings,
|
|
17070
|
+
...coordinator && { coordinator },
|
|
16995
17071
|
...meshQueueStats && { meshQueueStats }
|
|
16996
17072
|
};
|
|
16997
17073
|
}
|
|
@@ -17021,7 +17097,10 @@ function buildCliSession(state, options) {
|
|
|
17021
17097
|
const workspace = state.workspace || null;
|
|
17022
17098
|
const git = getGitSummaryForWorkspace(workspace, options);
|
|
17023
17099
|
const meshCoordinatorFor = state.settings?.meshCoordinatorFor;
|
|
17024
|
-
const
|
|
17100
|
+
const registryEntry = state.instanceId ? getCoordinatorForSession(state.instanceId) : void 0;
|
|
17101
|
+
const effectiveMeshId = meshCoordinatorFor || registryEntry?.meshId;
|
|
17102
|
+
const coordinator = effectiveMeshId ? { meshId: effectiveMeshId, role: "coordinator" } : void 0;
|
|
17103
|
+
const meshQueueStats = effectiveMeshId ? getMeshQueueStats(effectiveMeshId) : void 0;
|
|
17025
17104
|
return {
|
|
17026
17105
|
id: state.instanceId,
|
|
17027
17106
|
parentId: null,
|
|
@@ -17061,6 +17140,7 @@ function buildCliSession(state, options) {
|
|
|
17061
17140
|
errorReason: state.errorReason,
|
|
17062
17141
|
lastUpdated: state.lastUpdated,
|
|
17063
17142
|
settings: state.settings,
|
|
17143
|
+
...coordinator && { coordinator },
|
|
17064
17144
|
...meshQueueStats && { meshQueueStats }
|
|
17065
17145
|
};
|
|
17066
17146
|
}
|
|
@@ -17074,7 +17154,10 @@ function buildAcpSession(state, options) {
|
|
|
17074
17154
|
const workspace = state.workspace || null;
|
|
17075
17155
|
const git = getGitSummaryForWorkspace(workspace, options);
|
|
17076
17156
|
const meshCoordinatorFor = state.settings?.meshCoordinatorFor;
|
|
17077
|
-
const
|
|
17157
|
+
const registryEntry = state.instanceId ? getCoordinatorForSession(state.instanceId) : void 0;
|
|
17158
|
+
const effectiveMeshId = meshCoordinatorFor || registryEntry?.meshId;
|
|
17159
|
+
const coordinator = effectiveMeshId ? { meshId: effectiveMeshId, role: "coordinator" } : void 0;
|
|
17160
|
+
const meshQueueStats = effectiveMeshId ? getMeshQueueStats(effectiveMeshId) : void 0;
|
|
17078
17161
|
return {
|
|
17079
17162
|
id: state.instanceId,
|
|
17080
17163
|
parentId: null,
|
|
@@ -17097,6 +17180,7 @@ function buildAcpSession(state, options) {
|
|
|
17097
17180
|
errorReason: state.errorReason,
|
|
17098
17181
|
lastUpdated: state.lastUpdated,
|
|
17099
17182
|
settings: state.settings,
|
|
17183
|
+
...coordinator && { coordinator },
|
|
17100
17184
|
...meshQueueStats && { meshQueueStats }
|
|
17101
17185
|
};
|
|
17102
17186
|
}
|
|
@@ -17106,7 +17190,7 @@ function buildSessionEntries(allStates, cdpManagers, options = {}) {
|
|
|
17106
17190
|
const cliStates = allStates.filter((s) => s.category === "cli");
|
|
17107
17191
|
const acpStates = allStates.filter((s) => s.category === "acp");
|
|
17108
17192
|
for (const state of ideStates) {
|
|
17109
|
-
sessions.push(
|
|
17193
|
+
sessions.push(buildWorkspaceSession(state, cdpManagers, options));
|
|
17110
17194
|
for (const ext of state.extensions) {
|
|
17111
17195
|
if (!shouldIncludeExtensionSession(ext)) continue;
|
|
17112
17196
|
sessions.push(buildExtensionAgentSession(state, ext, options));
|
|
@@ -21626,7 +21710,7 @@ init_config();
|
|
|
21626
21710
|
import * as os13 from "os";
|
|
21627
21711
|
import * as path18 from "path";
|
|
21628
21712
|
import * as crypto4 from "crypto";
|
|
21629
|
-
import { existsSync as
|
|
21713
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11 } from "fs";
|
|
21630
21714
|
import { execFileSync } from "child_process";
|
|
21631
21715
|
import chalk from "chalk";
|
|
21632
21716
|
|
|
@@ -22434,10 +22518,17 @@ var CliProviderInstance = class {
|
|
|
22434
22518
|
return autoApproveActive;
|
|
22435
22519
|
}
|
|
22436
22520
|
const modal = adapterStatus.activeModal;
|
|
22437
|
-
const
|
|
22521
|
+
const buttons = Array.isArray(modal?.buttons) ? modal.buttons.map((b) => String(b || "").trim()).filter(Boolean) : [];
|
|
22522
|
+
if (!modal || buttons.length === 0) {
|
|
22523
|
+
return autoApproveActive;
|
|
22524
|
+
}
|
|
22525
|
+
const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(buttons, this.provider);
|
|
22526
|
+
if (buttonIndex < 0) {
|
|
22527
|
+
return autoApproveActive;
|
|
22528
|
+
}
|
|
22438
22529
|
const signature = [
|
|
22439
22530
|
typeof modal?.message === "string" ? modal.message.trim() : "",
|
|
22440
|
-
|
|
22531
|
+
buttons.join("|"),
|
|
22441
22532
|
buttonIndex
|
|
22442
22533
|
].join("::");
|
|
22443
22534
|
if (!this.autoApproveBusy || signature !== this.lastAutoApprovalSignature) {
|
|
@@ -24340,7 +24431,7 @@ function commandExists(command) {
|
|
|
24340
24431
|
const trimmed = command.trim();
|
|
24341
24432
|
if (!trimmed) return false;
|
|
24342
24433
|
if (isExplicitCommand(trimmed)) {
|
|
24343
|
-
return
|
|
24434
|
+
return existsSync18(expandExecutable(trimmed));
|
|
24344
24435
|
}
|
|
24345
24436
|
try {
|
|
24346
24437
|
execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -24465,7 +24556,7 @@ function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
|
24465
24556
|
mkdirSync10(baseDir, { recursive: true });
|
|
24466
24557
|
const workspaceHash = crypto4.createHash("sha256").update(path18.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
|
|
24467
24558
|
const filePath = path18.join(baseDir, `${workspaceHash}.json`);
|
|
24468
|
-
|
|
24559
|
+
writeFileSync11(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
24469
24560
|
return filePath;
|
|
24470
24561
|
}
|
|
24471
24562
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -24696,6 +24787,7 @@ var DaemonCliManager = class {
|
|
|
24696
24787
|
this.deps.removeAgentTracking(key);
|
|
24697
24788
|
sessionRegistry?.unregisterByInstanceKey(key);
|
|
24698
24789
|
instanceManager?.removeInstance(key);
|
|
24790
|
+
unregisterMeshCoordinator(key);
|
|
24699
24791
|
LOG.info("CLI", `\u{1F9F9} Auto-cleaned ${status.status} CLI: ${cliType}`);
|
|
24700
24792
|
this.deps.onStatusChange();
|
|
24701
24793
|
}
|
|
@@ -24967,6 +25059,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
24967
25059
|
this.deps.removeAgentTracking(key);
|
|
24968
25060
|
this.deps.getSessionRegistry?.()?.unregisterByInstanceKey(key);
|
|
24969
25061
|
this.deps.getInstanceManager()?.removeInstance(key);
|
|
25062
|
+
unregisterMeshCoordinator(key);
|
|
24970
25063
|
LOG.info("CLI", `\u{1F6D1} Agent stopped: ${adapter.cliType} in ${adapter.workingDir}`);
|
|
24971
25064
|
this.deps.onStatusChange();
|
|
24972
25065
|
} else {
|
|
@@ -24975,6 +25068,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
24975
25068
|
this.deps.getSessionRegistry?.()?.unregisterByInstanceKey(key);
|
|
24976
25069
|
im.removeInstance(key);
|
|
24977
25070
|
this.deps.removeAgentTracking(key);
|
|
25071
|
+
unregisterMeshCoordinator(key);
|
|
24978
25072
|
LOG.warn("CLI", `\u{1F9F9} Force-removed orphan entry: ${key}`);
|
|
24979
25073
|
this.deps.onStatusChange();
|
|
24980
25074
|
}
|
|
@@ -27754,7 +27848,7 @@ import * as yaml3 from "js-yaml";
|
|
|
27754
27848
|
// src/commands/mesh-coordinator.ts
|
|
27755
27849
|
import { createHash as createHash4 } from "crypto";
|
|
27756
27850
|
import * as os17 from "os";
|
|
27757
|
-
import { isAbsolute as isAbsolute11, join as
|
|
27851
|
+
import { isAbsolute as isAbsolute11, join as join24, resolve as resolve14 } from "path";
|
|
27758
27852
|
var DEFAULT_SERVER_NAME = "adhdev-mesh";
|
|
27759
27853
|
var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev";
|
|
27760
27854
|
var HERMES_CLI_TYPE = "hermes-cli";
|
|
@@ -27776,7 +27870,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
|
|
|
27776
27870
|
reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
|
|
27777
27871
|
};
|
|
27778
27872
|
}
|
|
27779
|
-
const configPath =
|
|
27873
|
+
const configPath = join24(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
|
|
27780
27874
|
if (!configPath.trim()) {
|
|
27781
27875
|
return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
|
|
27782
27876
|
}
|
|
@@ -27896,14 +27990,14 @@ function resolveHermesCoordinatorHome(meshId, workspace) {
|
|
|
27896
27990
|
const key = `${meshId || "mesh"}
|
|
27897
27991
|
${resolve14(workspace || os17.tmpdir())}`;
|
|
27898
27992
|
const hash = createHash4("sha256").update(key).digest("hex").slice(0, 16);
|
|
27899
|
-
return
|
|
27993
|
+
return join24(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
|
|
27900
27994
|
}
|
|
27901
27995
|
function resolveMcpConfigPath(configPath, workspace) {
|
|
27902
27996
|
const trimmed = configPath.trim();
|
|
27903
27997
|
if (trimmed === "~") return os17.homedir();
|
|
27904
|
-
if (trimmed.startsWith("~/")) return
|
|
27998
|
+
if (trimmed.startsWith("~/")) return join24(os17.homedir(), trimmed.slice(2));
|
|
27905
27999
|
if (isAbsolute11(trimmed)) return trimmed;
|
|
27906
|
-
return
|
|
28000
|
+
return join24(workspace, trimmed);
|
|
27907
28001
|
}
|
|
27908
28002
|
function resolveAdhdevMcpServerLaunch(options) {
|
|
27909
28003
|
const command = resolveAdhdevCommand(options.adhdevMcpCommand);
|
|
@@ -27938,7 +28032,7 @@ init_mesh_host_ownership();
|
|
|
27938
28032
|
|
|
27939
28033
|
// src/mesh/preview-freshness.ts
|
|
27940
28034
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
27941
|
-
import { existsSync as
|
|
28035
|
+
import { existsSync as existsSync21, readFileSync as readFileSync14 } from "fs";
|
|
27942
28036
|
import { resolve as resolve15 } from "path";
|
|
27943
28037
|
var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
|
|
27944
28038
|
function runGit2(repoRoot, args) {
|
|
@@ -27955,9 +28049,9 @@ function runGit2(repoRoot, args) {
|
|
|
27955
28049
|
}
|
|
27956
28050
|
function readRecord3(repoRoot) {
|
|
27957
28051
|
const path28 = resolve15(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
27958
|
-
if (!
|
|
28052
|
+
if (!existsSync21(path28)) return null;
|
|
27959
28053
|
try {
|
|
27960
|
-
const parsed = JSON.parse(
|
|
28054
|
+
const parsed = JSON.parse(readFileSync14(path28, "utf8"));
|
|
27961
28055
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
27962
28056
|
} catch {
|
|
27963
28057
|
return null;
|
|
@@ -33068,11 +33162,15 @@ ${block2}`);
|
|
|
33068
33162
|
return { success: false, error: cliCmdLaunch?.error || "Failed to launch CLI session" };
|
|
33069
33163
|
}
|
|
33070
33164
|
LOG.info("MeshCoordinator", `Launched ${cliType} coordinator (cli_command) for mesh ${meshId}`);
|
|
33165
|
+
const cliCmdSessionId = cliCmdLaunch.sessionId || cliCmdLaunch.id;
|
|
33166
|
+
if (cliCmdSessionId) {
|
|
33167
|
+
registerMeshCoordinator({ meshId, sessionId: cliCmdSessionId, workspace, startedAt: Date.now() });
|
|
33168
|
+
}
|
|
33071
33169
|
try {
|
|
33072
33170
|
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
33073
33171
|
appendLedgerEntry2(meshId, {
|
|
33074
33172
|
kind: "coordinator_started",
|
|
33075
|
-
sessionId:
|
|
33173
|
+
sessionId: cliCmdSessionId,
|
|
33076
33174
|
providerType: cliType,
|
|
33077
33175
|
payload: { workspace }
|
|
33078
33176
|
});
|
|
@@ -33083,7 +33181,7 @@ ${block2}`);
|
|
|
33083
33181
|
meshId,
|
|
33084
33182
|
cliType,
|
|
33085
33183
|
workspace,
|
|
33086
|
-
sessionId:
|
|
33184
|
+
sessionId: cliCmdSessionId,
|
|
33087
33185
|
mcpRegistered: true
|
|
33088
33186
|
};
|
|
33089
33187
|
}
|
|
@@ -33113,7 +33211,7 @@ ${block2}`);
|
|
|
33113
33211
|
workspace
|
|
33114
33212
|
};
|
|
33115
33213
|
}
|
|
33116
|
-
const { existsSync:
|
|
33214
|
+
const { existsSync: existsSync29, readFileSync: readFileSync22, writeFileSync: writeFileSync17, copyFileSync: copyFileSync4, mkdirSync: mkdirSync18 } = await import("fs");
|
|
33117
33215
|
const { dirname: dirname9 } = await import("path");
|
|
33118
33216
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
33119
33217
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -33156,14 +33254,14 @@ ${block2}`);
|
|
|
33156
33254
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
33157
33255
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
33158
33256
|
}
|
|
33159
|
-
const hadExistingMcpConfig =
|
|
33257
|
+
const hadExistingMcpConfig = existsSync29(mcpConfigPath);
|
|
33160
33258
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
33161
33259
|
if (hermesBaseConfig) {
|
|
33162
33260
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
|
|
33163
33261
|
}
|
|
33164
33262
|
if (hadExistingMcpConfig) {
|
|
33165
33263
|
try {
|
|
33166
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
33264
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync22(mcpConfigPath, "utf-8"), configFormat);
|
|
33167
33265
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
33168
33266
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
33169
33267
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -33186,7 +33284,7 @@ ${block2}`);
|
|
|
33186
33284
|
}
|
|
33187
33285
|
};
|
|
33188
33286
|
try {
|
|
33189
|
-
|
|
33287
|
+
writeFileSync17(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
33190
33288
|
} catch (error) {
|
|
33191
33289
|
const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
|
|
33192
33290
|
LOG.error("MeshCoordinator", message);
|
|
@@ -33223,11 +33321,15 @@ ${block2}`);
|
|
|
33223
33321
|
return { success: false, error: launchResult?.error || "Failed to launch CLI session" };
|
|
33224
33322
|
}
|
|
33225
33323
|
LOG.info("MeshCoordinator", `Launched ${cliType} coordinator for mesh ${meshId} in ${workspace}`);
|
|
33324
|
+
const launchSessionId = launchResult.sessionId || launchResult.id;
|
|
33325
|
+
if (launchSessionId) {
|
|
33326
|
+
registerMeshCoordinator({ meshId, sessionId: launchSessionId, workspace, startedAt: Date.now() });
|
|
33327
|
+
}
|
|
33226
33328
|
try {
|
|
33227
33329
|
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
33228
33330
|
appendLedgerEntry2(meshId, {
|
|
33229
33331
|
kind: "coordinator_started",
|
|
33230
|
-
sessionId:
|
|
33332
|
+
sessionId: launchSessionId,
|
|
33231
33333
|
providerType: cliType,
|
|
33232
33334
|
payload: { workspace }
|
|
33233
33335
|
});
|
|
@@ -33238,7 +33340,7 @@ ${block2}`);
|
|
|
33238
33340
|
meshId,
|
|
33239
33341
|
cliType,
|
|
33240
33342
|
workspace,
|
|
33241
|
-
sessionId:
|
|
33343
|
+
sessionId: launchSessionId,
|
|
33242
33344
|
mcpConfigWritten: true
|
|
33243
33345
|
};
|
|
33244
33346
|
} catch (e) {
|
|
@@ -41443,6 +41545,7 @@ init_config();
|
|
|
41443
41545
|
init_mesh_events();
|
|
41444
41546
|
async function initDaemonComponents(config) {
|
|
41445
41547
|
installGlobalInterceptor();
|
|
41548
|
+
loadMeshCoordinatorRegistry();
|
|
41446
41549
|
const appConfig = loadConfig();
|
|
41447
41550
|
const providerSourceMode = appConfig.providerSourceMode || "normal";
|
|
41448
41551
|
const disableUpstream = providerSourceMode === "no-upstream";
|
|
@@ -41799,7 +41902,9 @@ export {
|
|
|
41799
41902
|
getAIExtensions,
|
|
41800
41903
|
getActiveDirectDispatches,
|
|
41801
41904
|
getAvailableIdeIds,
|
|
41905
|
+
getCoordinatorForSession,
|
|
41802
41906
|
getCurrentDaemonLogPath,
|
|
41907
|
+
getDaemonDataDir,
|
|
41803
41908
|
getDaemonLogDir,
|
|
41804
41909
|
getDebugRuntimeConfig,
|
|
41805
41910
|
getGitDiffSummary,
|
|
@@ -41851,10 +41956,12 @@ export {
|
|
|
41851
41956
|
killIdeProcess,
|
|
41852
41957
|
launchIDE,
|
|
41853
41958
|
launchWithCdp,
|
|
41959
|
+
listCoordinatorsForWorkspace,
|
|
41854
41960
|
listHostedCliRuntimes,
|
|
41855
41961
|
listMeshes,
|
|
41856
41962
|
listWorktrees,
|
|
41857
41963
|
loadConfig,
|
|
41964
|
+
loadMeshCoordinatorRegistry,
|
|
41858
41965
|
loadMeshRefineConfig,
|
|
41859
41966
|
loadMeshWorktreeBootstrapConfig,
|
|
41860
41967
|
loadState,
|
|
@@ -41891,6 +41998,7 @@ export {
|
|
|
41891
41998
|
readLedgerSlice,
|
|
41892
41999
|
recordDebugTrace,
|
|
41893
42000
|
registerExtensionProviders,
|
|
42001
|
+
registerMeshCoordinator,
|
|
41894
42002
|
removeNode,
|
|
41895
42003
|
removeWorktree,
|
|
41896
42004
|
requeueTask,
|
|
@@ -41924,6 +42032,7 @@ export {
|
|
|
41924
42032
|
summarizeGitStatus,
|
|
41925
42033
|
syncMeshes,
|
|
41926
42034
|
triggerMeshQueue,
|
|
42035
|
+
unregisterMeshCoordinator,
|
|
41927
42036
|
updateConfig,
|
|
41928
42037
|
updateDirectDispatchStatus,
|
|
41929
42038
|
updateMesh,
|