@adhdev/daemon-core 0.9.82-rc.66 → 0.9.82-rc.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1683,15 +1683,162 @@ var init_mesh_ledger = __esm({
1683
1683
  }
1684
1684
  });
1685
1685
 
1686
+ // src/mesh/beads-db.ts
1687
+ function safeMeshId(meshId) {
1688
+ return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
1689
+ }
1690
+ function legacyQueuePath(meshId) {
1691
+ return (0, import_path5.join)(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
1692
+ }
1693
+ var import_better_sqlite3, import_fs5, import_path5, BeadsDB;
1694
+ var init_beads_db = __esm({
1695
+ "src/mesh/beads-db.ts"() {
1696
+ "use strict";
1697
+ import_better_sqlite3 = __toESM(require("better-sqlite3"));
1698
+ import_fs5 = require("fs");
1699
+ import_path5 = require("path");
1700
+ init_mesh_ledger();
1701
+ BeadsDB = class _BeadsDB {
1702
+ static instance;
1703
+ db;
1704
+ migratedMeshIds = /* @__PURE__ */ new Set();
1705
+ constructor(dbPath) {
1706
+ const dir = (0, import_path5.dirname)(dbPath);
1707
+ if (!(0, import_fs5.existsSync)(dir)) (0, import_fs5.mkdirSync)(dir, { recursive: true });
1708
+ this.db = new import_better_sqlite3.default(dbPath);
1709
+ this.db.pragma("journal_mode = WAL");
1710
+ this.db.pragma("synchronous = NORMAL");
1711
+ this.db.pragma("foreign_keys = ON");
1712
+ this.db.pragma("busy_timeout = 5000");
1713
+ this.migrate();
1714
+ }
1715
+ static getInstance() {
1716
+ if (!this.instance) {
1717
+ this.instance = new _BeadsDB((0, import_path5.join)(getLedgerDir(), "beads.db"));
1718
+ }
1719
+ return this.instance;
1720
+ }
1721
+ static resetForTests() {
1722
+ this.instance?.close();
1723
+ this.instance = void 0;
1724
+ }
1725
+ close() {
1726
+ this.db.close();
1727
+ }
1728
+ transaction(fn) {
1729
+ return this.db.transaction(fn).immediate();
1730
+ }
1731
+ migrate() {
1732
+ this.db.exec(`
1733
+ CREATE TABLE IF NOT EXISTS mesh_queue (
1734
+ id TEXT PRIMARY KEY,
1735
+ mesh_id TEXT NOT NULL,
1736
+ status TEXT NOT NULL,
1737
+ target_node_id TEXT,
1738
+ target_session_id TEXT,
1739
+ assigned_node_id TEXT,
1740
+ assigned_session_id TEXT,
1741
+ created_at TEXT NOT NULL,
1742
+ updated_at TEXT NOT NULL,
1743
+ payload TEXT NOT NULL
1744
+ );
1745
+
1746
+ CREATE INDEX IF NOT EXISTS idx_mesh_queue_mesh_status_created
1747
+ ON mesh_queue(mesh_id, status, created_at);
1748
+ CREATE INDEX IF NOT EXISTS idx_mesh_queue_assignment
1749
+ ON mesh_queue(mesh_id, assigned_node_id, assigned_session_id, status);
1750
+ `);
1751
+ }
1752
+ ensureLegacyQueueMigrated(meshId) {
1753
+ if (this.migratedMeshIds.has(meshId)) return;
1754
+ this.migratedMeshIds.add(meshId);
1755
+ const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
1756
+ if (count.count > 0) return;
1757
+ const path28 = legacyQueuePath(meshId);
1758
+ if (!(0, import_fs5.existsSync)(path28)) return;
1759
+ try {
1760
+ const entries = JSON.parse((0, import_fs5.readFileSync)(path28, "utf-8"));
1761
+ if (!Array.isArray(entries)) return;
1762
+ const insert = this.db.prepare(`
1763
+ INSERT OR REPLACE INTO mesh_queue (
1764
+ id, mesh_id, status, target_node_id, target_session_id,
1765
+ assigned_node_id, assigned_session_id, created_at, updated_at, payload
1766
+ ) VALUES (
1767
+ @id, @meshId, @status, @targetNodeId, @targetSessionId,
1768
+ @assignedNodeId, @assignedSessionId, @createdAt, @updatedAt, @payload
1769
+ )
1770
+ `);
1771
+ for (const entry of entries) {
1772
+ insert.run(this.toRow(entry));
1773
+ }
1774
+ } catch {
1775
+ return;
1776
+ }
1777
+ }
1778
+ getQueueEntries(meshId, statuses) {
1779
+ this.ensureLegacyQueueMigrated(meshId);
1780
+ if (statuses?.length) {
1781
+ const placeholders = statuses.map(() => "?").join(", ");
1782
+ const rows2 = this.db.prepare(`SELECT payload FROM mesh_queue WHERE mesh_id = ? AND status IN (${placeholders}) ORDER BY created_at ASC`).all(meshId, ...statuses);
1783
+ return rows2.map((row) => JSON.parse(row.payload));
1784
+ }
1785
+ const rows = this.db.prepare("SELECT payload FROM mesh_queue WHERE mesh_id = ? ORDER BY created_at ASC").all(meshId);
1786
+ return rows.map((row) => JSON.parse(row.payload));
1787
+ }
1788
+ getQueueRevision(meshId) {
1789
+ this.ensureLegacyQueueMigrated(meshId);
1790
+ const rows = this.db.prepare("SELECT id, status, updated_at FROM mesh_queue WHERE mesh_id = ? ORDER BY id ASC").all(meshId);
1791
+ return rows.map((row) => `${row.id}:${row.status}:${row.updated_at}`).join("|");
1792
+ }
1793
+ replaceQueue(meshId, queue) {
1794
+ const deleteStmt = this.db.prepare("DELETE FROM mesh_queue WHERE mesh_id = ?");
1795
+ const insert = this.db.prepare(`
1796
+ INSERT INTO mesh_queue (
1797
+ id, mesh_id, status, target_node_id, target_session_id,
1798
+ assigned_node_id, assigned_session_id, created_at, updated_at, payload
1799
+ ) VALUES (
1800
+ @id, @meshId, @status, @targetNodeId, @targetSessionId,
1801
+ @assignedNodeId, @assignedSessionId, @createdAt, @updatedAt, @payload
1802
+ )
1803
+ `);
1804
+ deleteStmt.run(meshId);
1805
+ for (const entry of queue) insert.run(this.toRow(entry));
1806
+ }
1807
+ deleteQueue(meshId) {
1808
+ this.db.prepare("DELETE FROM mesh_queue WHERE mesh_id = ?").run(meshId);
1809
+ this.migratedMeshIds.delete(meshId);
1810
+ }
1811
+ toRow(entry) {
1812
+ return {
1813
+ id: entry.id,
1814
+ meshId: entry.meshId,
1815
+ status: entry.status,
1816
+ targetNodeId: entry.targetNodeId ?? null,
1817
+ targetSessionId: entry.targetSessionId ?? null,
1818
+ assignedNodeId: entry.assignedNodeId ?? null,
1819
+ assignedSessionId: entry.assignedSessionId ?? null,
1820
+ createdAt: entry.createdAt,
1821
+ updatedAt: entry.updatedAt,
1822
+ payload: JSON.stringify(entry)
1823
+ };
1824
+ }
1825
+ };
1826
+ }
1827
+ });
1828
+
1686
1829
  // src/mesh/mesh-work-queue.ts
1687
1830
  var mesh_work_queue_exports = {};
1688
1831
  __export(mesh_work_queue_exports, {
1689
1832
  ACTIVE_MESH_QUEUE_STATUSES: () => ACTIVE_MESH_QUEUE_STATUSES,
1690
1833
  HISTORICAL_MESH_QUEUE_STATUSES: () => HISTORICAL_MESH_QUEUE_STATUSES,
1691
1834
  MESH_TASK_MODES: () => MESH_TASK_MODES,
1835
+ __clearMeshQueueForTests: () => __clearMeshQueueForTests,
1836
+ __replaceMeshQueueForTests: () => __replaceMeshQueueForTests,
1837
+ __resetBeadsDBForTests: () => __resetBeadsDBForTests,
1692
1838
  cancelTask: () => cancelTask,
1693
1839
  claimNextTask: () => claimNextTask,
1694
1840
  enqueueTask: () => enqueueTask,
1841
+ getMeshQueueRevision: () => getMeshQueueRevision,
1695
1842
  getMeshQueueStats: () => getMeshQueueStats,
1696
1843
  getQueue: () => getQueue,
1697
1844
  normalizeMeshTaskMode: () => normalizeMeshTaskMode,
@@ -1727,53 +1874,14 @@ function validateMeshTaskModeRequest(mode, message) {
1727
1874
  ]
1728
1875
  };
1729
1876
  }
1730
- function getQueuePath(meshId) {
1731
- const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
1732
- return (0, import_path5.join)(getLedgerDir(), `${safe}.queue.json`);
1733
- }
1734
- function getLockPath(meshId) {
1735
- const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
1736
- return (0, import_path5.join)(getLedgerDir(), `${safe}.queue.lock`);
1737
- }
1738
- function withQueueLock(meshId, fn) {
1739
- const lockPath = getLockPath(meshId);
1740
- let fd = -1;
1741
- for (let i = 0; i < 10; i++) {
1742
- try {
1743
- fd = (0, import_fs5.openSync)(lockPath, "wx");
1744
- break;
1745
- } catch {
1746
- const deadline = Date.now() + 30;
1747
- while (Date.now() < deadline) {
1748
- }
1749
- }
1750
- }
1751
- try {
1752
- return fn();
1753
- } finally {
1754
- if (fd !== -1) try {
1755
- (0, import_fs5.closeSync)(fd);
1756
- } catch {
1757
- }
1758
- try {
1759
- (0, import_fs5.unlinkSync)(lockPath);
1760
- } catch {
1761
- }
1762
- }
1877
+ function withQueueLock(_meshId, fn) {
1878
+ return BeadsDB.getInstance().transaction(fn);
1763
1879
  }
1764
1880
  function readQueue(meshId) {
1765
- const path28 = getQueuePath(meshId);
1766
- if (!(0, import_fs5.existsSync)(path28)) return [];
1767
- try {
1768
- const content = (0, import_fs5.readFileSync)(path28, "utf-8");
1769
- return JSON.parse(content);
1770
- } catch {
1771
- return [];
1772
- }
1881
+ return BeadsDB.getInstance().getQueueEntries(meshId);
1773
1882
  }
1774
1883
  function writeQueue(meshId, queue) {
1775
- const path28 = getQueuePath(meshId);
1776
- (0, import_fs5.writeFileSync)(path28, JSON.stringify(queue, null, 2), "utf-8");
1884
+ BeadsDB.getInstance().replaceQueue(meshId, queue);
1777
1885
  }
1778
1886
  function enqueueTask(meshId, message, opts) {
1779
1887
  requireMeshHostQueueOwner(opts);
@@ -1807,6 +1915,9 @@ function getQueue(meshId, opts) {
1807
1915
  }
1808
1916
  return queue;
1809
1917
  }
1918
+ function getMeshQueueRevision(meshId) {
1919
+ return BeadsDB.getInstance().getQueueRevision(meshId);
1920
+ }
1810
1921
  function claimNextTask(meshId, nodeId, sessionId) {
1811
1922
  return withQueueLock(meshId, () => {
1812
1923
  const queue = readQueue(meshId);
@@ -1950,15 +2061,24 @@ function getMeshQueueStats(meshId) {
1950
2061
  }))
1951
2062
  };
1952
2063
  }
1953
- var import_fs5, import_path5, import_crypto5, ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES, MESH_TASK_MODES, LIVE_DEBUG_READONLY_FORBIDDEN;
2064
+ function __replaceMeshQueueForTests(meshId, queue) {
2065
+ BeadsDB.getInstance().transaction(() => {
2066
+ BeadsDB.getInstance().replaceQueue(meshId, queue);
2067
+ });
2068
+ }
2069
+ function __clearMeshQueueForTests(meshId) {
2070
+ BeadsDB.getInstance().deleteQueue(meshId);
2071
+ }
2072
+ function __resetBeadsDBForTests() {
2073
+ BeadsDB.resetForTests();
2074
+ }
2075
+ var import_crypto5, ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES, MESH_TASK_MODES, LIVE_DEBUG_READONLY_FORBIDDEN;
1954
2076
  var init_mesh_work_queue = __esm({
1955
2077
  "src/mesh/mesh-work-queue.ts"() {
1956
2078
  "use strict";
1957
- import_fs5 = require("fs");
1958
- import_path5 = require("path");
1959
2079
  import_crypto5 = require("crypto");
1960
- init_mesh_ledger();
1961
2080
  init_mesh_host_ownership();
2081
+ init_beads_db();
1962
2082
  ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
1963
2083
  HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
1964
2084
  MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
@@ -2107,6 +2227,60 @@ var init_cli_detector = __esm({
2107
2227
  }
2108
2228
  });
2109
2229
 
2230
+ // src/logging/async-batch-writer.ts
2231
+ var fs2, AsyncBatchWriter;
2232
+ var init_async_batch_writer = __esm({
2233
+ "src/logging/async-batch-writer.ts"() {
2234
+ "use strict";
2235
+ fs2 = __toESM(require("fs"));
2236
+ AsyncBatchWriter = class {
2237
+ // Maps filePath -> string buffer
2238
+ static buffers = /* @__PURE__ */ new Map();
2239
+ static writePromises = /* @__PURE__ */ new Map();
2240
+ static flushTimer = null;
2241
+ /**
2242
+ * Queues data to be written to a file asynchronously in a batch.
2243
+ */
2244
+ static write(filePath, data) {
2245
+ let buf = this.buffers.get(filePath);
2246
+ if (!buf) {
2247
+ buf = [];
2248
+ this.buffers.set(filePath, buf);
2249
+ }
2250
+ buf.push(data);
2251
+ if (!this.flushTimer) {
2252
+ this.flushTimer = setTimeout(() => {
2253
+ this.flushTimer = null;
2254
+ this.flushAll();
2255
+ }, 50);
2256
+ }
2257
+ }
2258
+ static async flushAll() {
2259
+ const entries = Array.from(this.buffers.entries());
2260
+ this.buffers.clear();
2261
+ for (const [filePath, buffer] of entries) {
2262
+ const dataToWrite = buffer.join("");
2263
+ const doWrite = async () => {
2264
+ try {
2265
+ const prevPromise = this.writePromises.get(filePath);
2266
+ if (prevPromise) await prevPromise;
2267
+ await fs2.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
2268
+ } catch {
2269
+ }
2270
+ };
2271
+ const writePromise = doWrite();
2272
+ this.writePromises.set(filePath, writePromise);
2273
+ writePromise.finally(() => {
2274
+ if (this.writePromises.get(filePath) === writePromise) {
2275
+ this.writePromises.delete(filePath);
2276
+ }
2277
+ });
2278
+ }
2279
+ }
2280
+ };
2281
+ }
2282
+ });
2283
+
2110
2284
  // src/logging/logger.ts
2111
2285
  function setLogLevel(level) {
2112
2286
  currentLevel = level;
@@ -2134,7 +2308,7 @@ function checkDateRotation() {
2134
2308
  }
2135
2309
  function cleanOldLogs() {
2136
2310
  try {
2137
- const files = fs2.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
2311
+ const files = fs3.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
2138
2312
  const cutoff = /* @__PURE__ */ new Date();
2139
2313
  cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
2140
2314
  const cutoffStr = cutoff.toISOString().slice(0, 10);
@@ -2142,7 +2316,7 @@ function cleanOldLogs() {
2142
2316
  const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
2143
2317
  if (dateMatch && dateMatch[1] < cutoffStr) {
2144
2318
  try {
2145
- fs2.unlinkSync(path9.join(LOG_DIR, file));
2319
+ fs3.unlinkSync(path9.join(LOG_DIR, file));
2146
2320
  } catch {
2147
2321
  }
2148
2322
  }
@@ -2152,14 +2326,14 @@ function cleanOldLogs() {
2152
2326
  }
2153
2327
  function rotateSizeIfNeeded() {
2154
2328
  try {
2155
- const stat2 = fs2.statSync(currentLogFile);
2329
+ const stat2 = fs3.statSync(currentLogFile);
2156
2330
  if (stat2.size > MAX_LOG_SIZE) {
2157
2331
  const backup = currentLogFile.replace(".log", ".1.log");
2158
2332
  try {
2159
- fs2.unlinkSync(backup);
2333
+ fs3.unlinkSync(backup);
2160
2334
  } catch {
2161
2335
  }
2162
- fs2.renameSync(currentLogFile, backup);
2336
+ fs3.renameSync(currentLogFile, backup);
2163
2337
  }
2164
2338
  } catch {
2165
2339
  }
@@ -2170,7 +2344,7 @@ function writeToFile(line) {
2170
2344
  checkDateRotation();
2171
2345
  rotateSizeIfNeeded();
2172
2346
  }
2173
- fs2.appendFileSync(currentLogFile, line + "\n");
2347
+ AsyncBatchWriter.write(currentLogFile, line + "\n");
2174
2348
  } catch {
2175
2349
  }
2176
2350
  }
@@ -2258,13 +2432,14 @@ function installGlobalInterceptor() {
2258
2432
  writeToFile(`Log file: ${currentLogFile}`);
2259
2433
  writeToFile(`Log level: ${currentLevel}`);
2260
2434
  }
2261
- var fs2, path9, os3, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
2435
+ var fs3, path9, os3, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
2262
2436
  var init_logger = __esm({
2263
2437
  "src/logging/logger.ts"() {
2264
2438
  "use strict";
2265
- fs2 = __toESM(require("fs"));
2439
+ fs3 = __toESM(require("fs"));
2266
2440
  path9 = __toESM(require("path"));
2267
2441
  os3 = __toESM(require("os"));
2442
+ init_async_batch_writer();
2268
2443
  LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
2269
2444
  LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
2270
2445
  currentLevel = "info";
@@ -2272,7 +2447,7 @@ var init_logger = __esm({
2272
2447
  MAX_LOG_SIZE = 5 * 1024 * 1024;
2273
2448
  MAX_LOG_DAYS = 7;
2274
2449
  try {
2275
- fs2.mkdirSync(LOG_DIR, { recursive: true });
2450
+ fs3.mkdirSync(LOG_DIR, { recursive: true });
2276
2451
  } catch {
2277
2452
  }
2278
2453
  currentDate = getDateStr();
@@ -2280,14 +2455,14 @@ var init_logger = __esm({
2280
2455
  cleanOldLogs();
2281
2456
  try {
2282
2457
  const oldLog = path9.join(LOG_DIR, "daemon.log");
2283
- if (fs2.existsSync(oldLog)) {
2284
- const stat2 = fs2.statSync(oldLog);
2458
+ if (fs3.existsSync(oldLog)) {
2459
+ const stat2 = fs3.statSync(oldLog);
2285
2460
  const oldDate = stat2.mtime.toISOString().slice(0, 10);
2286
- fs2.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
2461
+ fs3.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
2287
2462
  }
2288
2463
  const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
2289
- if (fs2.existsSync(oldLogBackup)) {
2290
- fs2.unlinkSync(oldLogBackup);
2464
+ if (fs3.existsSync(oldLogBackup)) {
2465
+ fs3.unlinkSync(oldLogBackup);
2291
2466
  }
2292
2467
  } catch {
2293
2468
  }
@@ -3630,8 +3805,8 @@ var init_pty_transport = __esm({
3630
3805
  let cwd = options.cwd;
3631
3806
  if (cwd) {
3632
3807
  try {
3633
- const fs16 = require("fs");
3634
- const stat2 = fs16.statSync(cwd);
3808
+ const fs17 = require("fs");
3809
+ const stat2 = fs17.statSync(cwd);
3635
3810
  if (!stat2.isDirectory()) cwd = os8.homedir();
3636
3811
  } catch {
3637
3812
  cwd = os8.homedir();
@@ -3731,27 +3906,35 @@ function findBinary(name) {
3731
3906
  return path14.isAbsolute(expanded) ? expanded : path14.resolve(expanded);
3732
3907
  }
3733
3908
  const isWin = os9.platform() === "win32";
3734
- try {
3735
- const cmd = isWin ? `where ${trimmed}` : `which ${trimmed}`;
3736
- return (0, import_child_process4.execSync)(cmd, {
3737
- encoding: "utf-8",
3738
- timeout: 5e3,
3739
- stdio: ["pipe", "pipe", "pipe"],
3740
- ...isWin ? { windowsHide: true } : {}
3741
- }).trim().split("\n")[0].trim();
3742
- } catch {
3743
- return isWin ? `${trimmed}.cmd` : trimmed;
3909
+ const paths = (process.env.PATH || "").split(path14.delimiter);
3910
+ const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
3911
+ for (const p of paths) {
3912
+ if (!p) continue;
3913
+ for (const ext of exes) {
3914
+ const fullPath = path14.join(p, trimmed + ext);
3915
+ try {
3916
+ const fs17 = require("fs");
3917
+ if (fs17.existsSync(fullPath)) {
3918
+ const stat2 = fs17.statSync(fullPath);
3919
+ if (stat2.isFile() && (isWin || stat2.mode & 73)) {
3920
+ return fullPath;
3921
+ }
3922
+ }
3923
+ } catch {
3924
+ }
3925
+ }
3744
3926
  }
3927
+ return isWin ? `${trimmed}.cmd` : trimmed;
3745
3928
  }
3746
3929
  function isScriptBinary(binaryPath) {
3747
3930
  if (!path14.isAbsolute(binaryPath)) return false;
3748
3931
  try {
3749
- const fs16 = require("fs");
3750
- const resolved = fs16.realpathSync(binaryPath);
3932
+ const fs17 = require("fs");
3933
+ const resolved = fs17.realpathSync(binaryPath);
3751
3934
  const head = Buffer.alloc(8);
3752
- const fd = fs16.openSync(resolved, "r");
3753
- fs16.readSync(fd, head, 0, 8, 0);
3754
- fs16.closeSync(fd);
3935
+ const fd = fs17.openSync(resolved, "r");
3936
+ fs17.readSync(fd, head, 0, 8, 0);
3937
+ fs17.closeSync(fd);
3755
3938
  let i = 0;
3756
3939
  if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
3757
3940
  return head[i] === 35 && head[i + 1] === 33;
@@ -3762,12 +3945,12 @@ function isScriptBinary(binaryPath) {
3762
3945
  function looksLikeMachOOrElf(filePath) {
3763
3946
  if (!path14.isAbsolute(filePath)) return false;
3764
3947
  try {
3765
- const fs16 = require("fs");
3766
- const resolved = fs16.realpathSync(filePath);
3948
+ const fs17 = require("fs");
3949
+ const resolved = fs17.realpathSync(filePath);
3767
3950
  const buf = Buffer.alloc(8);
3768
- const fd = fs16.openSync(resolved, "r");
3769
- fs16.readSync(fd, buf, 0, 8, 0);
3770
- fs16.closeSync(fd);
3951
+ const fd = fs17.openSync(resolved, "r");
3952
+ fs17.readSync(fd, buf, 0, 8, 0);
3953
+ fs17.closeSync(fd);
3771
3954
  let i = 0;
3772
3955
  if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
3773
3956
  const b = buf.subarray(i);
@@ -3849,13 +4032,12 @@ function normalizeCliProviderForRuntime(raw) {
3849
4032
  }
3850
4033
  };
3851
4034
  }
3852
- var os9, path14, import_child_process4, TerminalTranscriptAccumulator, buildCliSpawnEnv;
4035
+ var os9, path14, TerminalTranscriptAccumulator, buildCliSpawnEnv;
3853
4036
  var init_provider_cli_shared = __esm({
3854
4037
  "src/cli-adapters/provider-cli-shared.ts"() {
3855
4038
  "use strict";
3856
4039
  os9 = __toESM(require("os"));
3857
4040
  path14 = __toESM(require("path"));
3858
- import_child_process4 = require("child_process");
3859
4041
  init_spawn_env();
3860
4042
  TerminalTranscriptAccumulator = class {
3861
4043
  lines = [[]];
@@ -6459,6 +6641,7 @@ __export(index_exports, {
6459
6641
  getLogLevel: () => getLogLevel,
6460
6642
  getMesh: () => getMesh,
6461
6643
  getMeshByRepo: () => getMeshByRepo,
6644
+ getMeshQueueRevision: () => getMeshQueueRevision,
6462
6645
  getMeshQueueStats: () => getMeshQueueStats,
6463
6646
  getNpmExecOptions: () => getNpmExecOptions,
6464
6647
  getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
@@ -9339,9 +9522,11 @@ function resetState() {
9339
9522
 
9340
9523
  // src/detection/ide-detector.ts
9341
9524
  var import_child_process2 = require("child_process");
9525
+ var import_util = require("util");
9342
9526
  var import_fs9 = require("fs");
9343
9527
  var import_os2 = require("os");
9344
9528
  var path10 = __toESM(require("path"));
9529
+ var execAsync2 = (0, import_util.promisify)(import_child_process2.exec);
9345
9530
  var BUILTIN_IDE_DEFINITIONS = [];
9346
9531
  var registeredIDEs = /* @__PURE__ */ new Map();
9347
9532
  function registerIDEDefinition(def) {
@@ -9365,24 +9550,33 @@ function findCliCommand(command) {
9365
9550
  const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
9366
9551
  return (0, import_fs9.existsSync)(resolved) ? resolved : null;
9367
9552
  }
9368
- try {
9369
- const result = (0, import_child_process2.execSync)(
9370
- (0, import_os2.platform)() === "win32" ? `where ${trimmed}` : `which ${trimmed}`,
9371
- { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }
9372
- ).trim();
9373
- return result.split("\n")[0] || null;
9374
- } catch {
9375
- return null;
9553
+ const isWin = (0, import_os2.platform)() === "win32";
9554
+ const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
9555
+ const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
9556
+ for (const p of paths) {
9557
+ if (!p) continue;
9558
+ for (const ext of exes) {
9559
+ const fullPath = path10.join(p, trimmed + ext);
9560
+ try {
9561
+ if ((0, import_fs9.existsSync)(fullPath)) {
9562
+ const stat2 = (0, import_fs9.statSync)(fullPath);
9563
+ if (stat2.isFile() && (isWin || stat2.mode & 73)) {
9564
+ return fullPath;
9565
+ }
9566
+ }
9567
+ } catch {
9568
+ }
9569
+ }
9376
9570
  }
9571
+ return null;
9377
9572
  }
9378
- function getIdeVersion(cliCommand) {
9573
+ async function getIdeVersion(cliCommand) {
9379
9574
  try {
9380
- const result = (0, import_child_process2.execSync)(`"${cliCommand}" --version`, {
9575
+ const { stdout } = await execAsync2(`"${cliCommand}" --version`, {
9381
9576
  encoding: "utf-8",
9382
- timeout: 1e4,
9383
- stdio: ["pipe", "pipe", "pipe"]
9384
- }).trim();
9385
- return result.split("\n")[0] || null;
9577
+ timeout: 1e4
9578
+ });
9579
+ return stdout.trim().split("\n")[0] || null;
9386
9580
  } catch {
9387
9581
  return null;
9388
9582
  }
@@ -9430,7 +9624,7 @@ async function detectIDEs(providerLoader) {
9430
9624
  }
9431
9625
  }
9432
9626
  const installed = os22 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
9433
- const version = resolvedCli ? getIdeVersion(resolvedCli) : null;
9627
+ const version = resolvedCli ? await getIdeVersion(resolvedCli) : null;
9434
9628
  results.push({
9435
9629
  id: def.id,
9436
9630
  name: def.name,
@@ -9451,18 +9645,22 @@ init_cli_detector();
9451
9645
  // src/system/host-memory.ts
9452
9646
  var os4 = __toESM(require("os"));
9453
9647
  var import_child_process3 = require("child_process");
9454
- function parseDarwinAvailableBytes(totalMem) {
9455
- if (os4.platform() !== "darwin") return null;
9648
+ var import_util2 = require("util");
9649
+ var execAsync3 = (0, import_util2.promisify)(import_child_process3.exec);
9650
+ var cachedDarwinAvail = null;
9651
+ var darwinMemoryInterval = null;
9652
+ async function updateDarwinMemoryCache() {
9653
+ if (os4.platform() !== "darwin") return;
9456
9654
  try {
9457
- const out = (0, import_child_process3.execSync)("vm_stat", {
9655
+ const { stdout } = await execAsync3("vm_stat", {
9458
9656
  encoding: "utf-8",
9459
9657
  timeout: 4e3,
9460
9658
  maxBuffer: 256 * 1024
9461
9659
  });
9462
- const pageSizeMatch = out.match(/page size of (\d+)\s*bytes/i);
9660
+ const pageSizeMatch = stdout.match(/page size of (\d+)\s*bytes/i);
9463
9661
  const pageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : 4096;
9464
9662
  const counts = {};
9465
- for (const line of out.split("\n")) {
9663
+ for (const line of stdout.split("\n")) {
9466
9664
  const m = line.match(/^\s*Pages\s+([^:]+):\s+([\d,]+)\s*\.?/);
9467
9665
  if (!m) continue;
9468
9666
  const key = m[1].trim().toLowerCase().replace(/\s+/g, "_");
@@ -9476,18 +9674,24 @@ function parseDarwinAvailableBytes(totalMem) {
9476
9674
  const fileBacked = counts["file_backed"] ?? 0;
9477
9675
  const availPages = free + inactive + speculative + purgeable + fileBacked;
9478
9676
  const bytes = availPages * pageSize;
9479
- if (!Number.isFinite(bytes) || bytes < 0) return null;
9480
- return Math.min(bytes, totalMem);
9677
+ cachedDarwinAvail = Number.isFinite(bytes) && bytes >= 0 ? Math.min(bytes, os4.totalmem()) : null;
9481
9678
  } catch {
9482
- return null;
9483
9679
  }
9484
9680
  }
9485
9681
  function getHostMemorySnapshot() {
9682
+ if (os4.platform() === "darwin" && !darwinMemoryInterval) {
9683
+ updateDarwinMemoryCache();
9684
+ darwinMemoryInterval = setInterval(updateDarwinMemoryCache, 3e3);
9685
+ darwinMemoryInterval.unref();
9686
+ }
9486
9687
  const totalMem = os4.totalmem();
9487
9688
  const freeMem = os4.freemem();
9488
- const darwinAvail = parseDarwinAvailableBytes(totalMem);
9489
- const availableMem = darwinAvail != null ? darwinAvail : freeMem;
9490
- return { totalMem, freeMem, availableMem };
9689
+ const availableMem = os4.platform() === "darwin" ? cachedDarwinAvail ?? freeMem : freeMem;
9690
+ return {
9691
+ totalMem,
9692
+ freeMem,
9693
+ availableMem
9694
+ };
9491
9695
  }
9492
9696
 
9493
9697
  // src/session-host/runtime-surface.ts
@@ -11852,7 +12056,7 @@ ${cleanBody}`;
11852
12056
  }
11853
12057
 
11854
12058
  // src/config/chat-history.ts
11855
- var fs3 = __toESM(require("fs"));
12059
+ var fs4 = __toESM(require("fs"));
11856
12060
  var path11 = __toESM(require("path"));
11857
12061
  var os5 = __toESM(require("os"));
11858
12062
  var HISTORY_DIR = path11.join(os5.homedir(), ".adhdev", "history");
@@ -11972,8 +12176,8 @@ function buildSavedHistorySessionSummaryMapFromEntries(entries) {
11972
12176
  function readPersistedSavedHistorySessionSummaries(dir) {
11973
12177
  try {
11974
12178
  const filePath = getSavedHistoryIndexFilePath(dir);
11975
- if (!fs3.existsSync(filePath)) return null;
11976
- const raw = JSON.parse(fs3.readFileSync(filePath, "utf-8"));
12179
+ if (!fs4.existsSync(filePath)) return null;
12180
+ const raw = JSON.parse(fs4.readFileSync(filePath, "utf-8"));
11977
12181
  if (!raw || raw.version !== SAVED_HISTORY_INDEX_VERSION || !raw.sessions || typeof raw.sessions !== "object") {
11978
12182
  return null;
11979
12183
  }
@@ -12000,7 +12204,7 @@ function sanitizeHistoryFileSegment(value) {
12000
12204
  }
12001
12205
  function listHistoryFiles(dir, historySessionId) {
12002
12206
  const sanitizedSessionId = historySessionId ? sanitizeHistoryFileSegment(historySessionId) : "";
12003
- return fs3.readdirSync(dir).filter((file) => {
12207
+ return fs4.readdirSync(dir).filter((file) => {
12004
12208
  if (!file.endsWith(".jsonl")) return false;
12005
12209
  if (sanitizedSessionId) {
12006
12210
  return file.startsWith(`${sanitizedSessionId}_`);
@@ -12018,7 +12222,7 @@ function extractSavedHistorySessionIdFromFile(file) {
12018
12222
  function buildSavedHistoryFileSignatureMap(dir, files) {
12019
12223
  return new Map(files.map((file) => {
12020
12224
  try {
12021
- const stat2 = fs3.statSync(path11.join(dir, file));
12225
+ const stat2 = fs4.statSync(path11.join(dir, file));
12022
12226
  return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
12023
12227
  } catch {
12024
12228
  return [file, `${file}:missing`];
@@ -12041,8 +12245,8 @@ function sleepBlocking(ms) {
12041
12245
  function loadPersistedSavedHistoryIndexFromFile(dir) {
12042
12246
  try {
12043
12247
  const filePath = getSavedHistoryIndexFilePath(dir);
12044
- if (!fs3.existsSync(filePath)) return /* @__PURE__ */ new Map();
12045
- const raw = JSON.parse(fs3.readFileSync(filePath, "utf-8"));
12248
+ if (!fs4.existsSync(filePath)) return /* @__PURE__ */ new Map();
12249
+ const raw = JSON.parse(fs4.readFileSync(filePath, "utf-8"));
12046
12250
  if (!raw || raw.version !== SAVED_HISTORY_INDEX_VERSION || !raw.files || typeof raw.files !== "object") {
12047
12251
  return /* @__PURE__ */ new Map();
12048
12252
  }
@@ -12064,27 +12268,27 @@ function writePersistedSavedHistoryIndexFile(dir, entries) {
12064
12268
  files: Object.fromEntries(entries.entries()),
12065
12269
  sessions: buildSavedHistorySessionSummaryMapFromEntries(entries)
12066
12270
  };
12067
- fs3.writeFileSync(tempPath, JSON.stringify(payload), "utf-8");
12068
- fs3.renameSync(tempPath, filePath);
12271
+ fs4.writeFileSync(tempPath, JSON.stringify(payload), "utf-8");
12272
+ fs4.renameSync(tempPath, filePath);
12069
12273
  }
12070
12274
  function acquireSavedHistoryIndexLock(dir) {
12071
12275
  const lockPath = getSavedHistoryIndexLockPath(dir);
12072
12276
  const deadline = Date.now() + SAVED_HISTORY_INDEX_LOCK_WAIT_MS;
12073
12277
  while (Date.now() <= deadline) {
12074
12278
  try {
12075
- fs3.mkdirSync(lockPath);
12279
+ fs4.mkdirSync(lockPath);
12076
12280
  return () => {
12077
12281
  try {
12078
- fs3.rmSync(lockPath, { recursive: true, force: true });
12282
+ fs4.rmSync(lockPath, { recursive: true, force: true });
12079
12283
  } catch {
12080
12284
  }
12081
12285
  };
12082
12286
  } catch (error) {
12083
12287
  if (error?.code !== "EEXIST") return null;
12084
12288
  try {
12085
- const stat2 = fs3.statSync(lockPath);
12289
+ const stat2 = fs4.statSync(lockPath);
12086
12290
  if (Date.now() - stat2.mtimeMs > SAVED_HISTORY_INDEX_LOCK_STALE_MS) {
12087
- fs3.rmSync(lockPath, { recursive: true, force: true });
12291
+ fs4.rmSync(lockPath, { recursive: true, force: true });
12088
12292
  continue;
12089
12293
  }
12090
12294
  } catch {
@@ -12131,7 +12335,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
12131
12335
  }
12132
12336
  for (const file of Array.from(currentEntries.keys())) {
12133
12337
  if (incomingFiles.has(file)) continue;
12134
- if (!fs3.existsSync(path11.join(dir, file))) {
12338
+ if (!fs4.existsSync(path11.join(dir, file))) {
12135
12339
  currentEntries.delete(file);
12136
12340
  }
12137
12341
  }
@@ -12139,14 +12343,14 @@ function savePersistedSavedHistoryIndex(dir, entries) {
12139
12343
  }
12140
12344
  function invalidatePersistedSavedHistoryIndex(agentType, dir) {
12141
12345
  try {
12142
- fs3.rmSync(getSavedHistoryIndexFilePath(dir), { force: true });
12346
+ fs4.rmSync(getSavedHistoryIndexFilePath(dir), { force: true });
12143
12347
  } catch {
12144
12348
  }
12145
12349
  savedHistorySessionCache.delete(agentType.replace(/[^a-zA-Z0-9_-]/g, "_"));
12146
12350
  }
12147
12351
  function buildSavedHistoryIndexFileSignature(dir) {
12148
12352
  try {
12149
- const stat2 = fs3.statSync(getSavedHistoryIndexFilePath(dir));
12353
+ const stat2 = fs4.statSync(getSavedHistoryIndexFilePath(dir));
12150
12354
  return `index:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
12151
12355
  } catch {
12152
12356
  return "index:missing";
@@ -12154,10 +12358,10 @@ function buildSavedHistoryIndexFileSignature(dir) {
12154
12358
  }
12155
12359
  function historyDirectoryHasFilesNewerThanIndex(dir) {
12156
12360
  try {
12157
- const indexStat = fs3.statSync(getSavedHistoryIndexFilePath(dir));
12361
+ const indexStat = fs4.statSync(getSavedHistoryIndexFilePath(dir));
12158
12362
  const files = listHistoryFiles(dir);
12159
12363
  for (const file of files) {
12160
- const stat2 = fs3.statSync(path11.join(dir, file));
12364
+ const stat2 = fs4.statSync(path11.join(dir, file));
12161
12365
  if (stat2.mtimeMs > indexStat.mtimeMs) return true;
12162
12366
  }
12163
12367
  return false;
@@ -12167,7 +12371,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
12167
12371
  }
12168
12372
  function buildSavedHistoryFileSignature(dir, file) {
12169
12373
  try {
12170
- const stat2 = fs3.statSync(path11.join(dir, file));
12374
+ const stat2 = fs4.statSync(path11.join(dir, file));
12171
12375
  return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
12172
12376
  } catch {
12173
12377
  return `${file}:missing`;
@@ -12248,7 +12452,7 @@ function computeSavedHistoryFileSummary(dir, file) {
12248
12452
  const historySessionId = extractSavedHistorySessionIdFromFile(file);
12249
12453
  if (!historySessionId) return null;
12250
12454
  const filePath = path11.join(dir, file);
12251
- const content = fs3.readFileSync(filePath, "utf-8");
12455
+ const content = fs4.readFileSync(filePath, "utf-8");
12252
12456
  const lines = content.split("\n").filter(Boolean);
12253
12457
  let messageCount = 0;
12254
12458
  let firstMessageAt = 0;
@@ -12309,7 +12513,7 @@ function scheduleSavedHistoryBackgroundRefresh(agentType, dir) {
12309
12513
  savedHistoryBackgroundRefresh.add(key);
12310
12514
  setTimeout(() => {
12311
12515
  try {
12312
- if (!fs3.existsSync(dir)) return;
12516
+ if (!fs4.existsSync(dir)) return;
12313
12517
  const files = listHistoryFiles(dir);
12314
12518
  const fileSignatures = buildSavedHistoryFileSignatureMap(dir, files);
12315
12519
  const persistedEntries = loadPersistedSavedHistoryIndex(dir);
@@ -12455,13 +12659,13 @@ var ChatHistoryWriter = class {
12455
12659
  }
12456
12660
  if (newMessages.length === 0) return;
12457
12661
  const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
12458
- fs3.mkdirSync(dir, { recursive: true });
12662
+ fs4.mkdirSync(dir, { recursive: true });
12459
12663
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
12460
12664
  const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
12461
12665
  const fileName = `${filePrefix}${date}.jsonl`;
12462
12666
  const filePath = path11.join(dir, fileName);
12463
12667
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
12464
- fs3.appendFileSync(filePath, lines, "utf-8");
12668
+ fs4.appendFileSync(filePath, lines, "utf-8");
12465
12669
  updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
12466
12670
  const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
12467
12671
  if (!historySessionId && messages.length < prevCount * 0.5 && prevCount > 3) {
@@ -12551,7 +12755,7 @@ var ChatHistoryWriter = class {
12551
12755
  if (!id || !ws) return;
12552
12756
  try {
12553
12757
  const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
12554
- fs3.mkdirSync(dir, { recursive: true });
12758
+ fs4.mkdirSync(dir, { recursive: true });
12555
12759
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
12556
12760
  const fileName = `${this.sanitize(id)}_${date}.jsonl`;
12557
12761
  const filePath = path11.join(dir, fileName);
@@ -12566,7 +12770,7 @@ var ChatHistoryWriter = class {
12566
12770
  historySessionId: id,
12567
12771
  workspace: ws
12568
12772
  };
12569
- fs3.appendFileSync(filePath, JSON.stringify(record) + "\n", "utf-8");
12773
+ fs4.appendFileSync(filePath, JSON.stringify(record) + "\n", "utf-8");
12570
12774
  updateSavedHistoryIndexForSessionStart(agentType, dir, fileName, id, ws);
12571
12775
  } catch {
12572
12776
  }
@@ -12601,14 +12805,14 @@ var ChatHistoryWriter = class {
12601
12805
  this.lastSeenCounts.delete(fromDedupKey);
12602
12806
  }
12603
12807
  const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
12604
- if (!fs3.existsSync(dir)) return;
12808
+ if (!fs4.existsSync(dir)) return;
12605
12809
  const fromPrefix = `${this.sanitize(fromId)}_`;
12606
12810
  const toPrefix = `${this.sanitize(toId)}_`;
12607
- const files = fs3.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
12811
+ const files = fs4.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
12608
12812
  for (const file of files) {
12609
12813
  const sourcePath = path11.join(dir, file);
12610
12814
  const targetPath = path11.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
12611
- const sourceLines = fs3.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
12815
+ const sourceLines = fs4.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
12612
12816
  const rewritten = sourceLines.map((line) => {
12613
12817
  try {
12614
12818
  const parsed = JSON.parse(line);
@@ -12622,16 +12826,16 @@ var ChatHistoryWriter = class {
12622
12826
  }
12623
12827
  }).filter((line) => !!line);
12624
12828
  if (rewritten.length === 0) {
12625
- fs3.unlinkSync(sourcePath);
12829
+ fs4.unlinkSync(sourcePath);
12626
12830
  continue;
12627
12831
  }
12628
- const existing = fs3.existsSync(targetPath) ? new Set(fs3.readFileSync(targetPath, "utf-8").split("\n").filter(Boolean)) : /* @__PURE__ */ new Set();
12832
+ const existing = fs4.existsSync(targetPath) ? new Set(fs4.readFileSync(targetPath, "utf-8").split("\n").filter(Boolean)) : /* @__PURE__ */ new Set();
12629
12833
  const nextLines = rewritten.filter((line) => !existing.has(line));
12630
12834
  if (nextLines.length > 0) {
12631
- fs3.appendFileSync(targetPath, `${nextLines.join("\n")}
12835
+ fs4.appendFileSync(targetPath, `${nextLines.join("\n")}
12632
12836
  `, "utf-8");
12633
12837
  }
12634
- fs3.unlinkSync(sourcePath);
12838
+ fs4.unlinkSync(sourcePath);
12635
12839
  }
12636
12840
  invalidatePersistedSavedHistoryIndex(agentType, dir);
12637
12841
  } catch {
@@ -12642,13 +12846,13 @@ var ChatHistoryWriter = class {
12642
12846
  if (!sessionId) return;
12643
12847
  try {
12644
12848
  const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
12645
- if (!fs3.existsSync(dir)) return;
12849
+ if (!fs4.existsSync(dir)) return;
12646
12850
  const prefix = `${this.sanitize(sessionId)}_`;
12647
- const files = fs3.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
12851
+ const files = fs4.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
12648
12852
  const seen = /* @__PURE__ */ new Set();
12649
12853
  for (const file of files) {
12650
12854
  const filePath = path11.join(dir, file);
12651
- const lines = fs3.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
12855
+ const lines = fs4.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
12652
12856
  const next = [];
12653
12857
  for (const line of lines) {
12654
12858
  let parsed = null;
@@ -12677,10 +12881,10 @@ var ChatHistoryWriter = class {
12677
12881
  }
12678
12882
  const collapsed = collapseReplayAssistantTurns(dedupedAdjacent, historyBehavior);
12679
12883
  if (collapsed.length === 0) {
12680
- fs3.unlinkSync(filePath);
12884
+ fs4.unlinkSync(filePath);
12681
12885
  continue;
12682
12886
  }
12683
- fs3.writeFileSync(filePath, `${collapsed.map((entry) => JSON.stringify(entry)).join("\n")}
12887
+ fs4.writeFileSync(filePath, `${collapsed.map((entry) => JSON.stringify(entry)).join("\n")}
12684
12888
  `, "utf-8");
12685
12889
  }
12686
12890
  invalidatePersistedSavedHistoryIndex(agentType, dir);
@@ -12697,18 +12901,18 @@ var ChatHistoryWriter = class {
12697
12901
  /** Delete history files older than 30 days */
12698
12902
  async rotateOldFiles() {
12699
12903
  try {
12700
- if (!fs3.existsSync(HISTORY_DIR)) return;
12904
+ if (!fs4.existsSync(HISTORY_DIR)) return;
12701
12905
  const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
12702
- const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
12906
+ const agentDirs = fs4.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
12703
12907
  for (const dir of agentDirs) {
12704
12908
  const dirPath = path11.join(HISTORY_DIR, dir.name);
12705
- const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
12909
+ const files = fs4.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
12706
12910
  let removedAny = false;
12707
12911
  for (const file of files) {
12708
12912
  const filePath = path11.join(dirPath, file);
12709
- const stat2 = fs3.statSync(filePath);
12913
+ const stat2 = fs4.statSync(filePath);
12710
12914
  if (stat2.mtimeMs < cutoff) {
12711
- fs3.unlinkSync(filePath);
12915
+ fs4.unlinkSync(filePath);
12712
12916
  removedAny = true;
12713
12917
  }
12714
12918
  }
@@ -12756,13 +12960,13 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
12756
12960
  try {
12757
12961
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
12758
12962
  const dir = path11.join(HISTORY_DIR, sanitized);
12759
- if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
12963
+ if (!fs4.existsSync(dir)) return { messages: [], hasMore: false };
12760
12964
  const files = listHistoryFiles(dir, historySessionId);
12761
12965
  const allMessages = [];
12762
12966
  const seen = /* @__PURE__ */ new Set();
12763
12967
  for (const file of files) {
12764
12968
  const filePath = path11.join(dir, file);
12765
- const content = fs3.readFileSync(filePath, "utf-8");
12969
+ const content = fs4.readFileSync(filePath, "utf-8");
12766
12970
  const lines = content.trim().split("\n").filter(Boolean);
12767
12971
  for (let i = 0; i < lines.length; i++) {
12768
12972
  try {
@@ -12786,7 +12990,7 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
12786
12990
  try {
12787
12991
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
12788
12992
  const dir = path11.join(HISTORY_DIR, sanitized);
12789
- if (!fs3.existsSync(dir)) {
12993
+ if (!fs4.existsSync(dir)) {
12790
12994
  savedHistorySessionCache.delete(sanitized);
12791
12995
  return { sessions: [], hasMore: false };
12792
12996
  }
@@ -12847,10 +13051,10 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
12847
13051
  function readExistingSessionStartRecord(agentType, historySessionId) {
12848
13052
  try {
12849
13053
  const dir = path11.join(HISTORY_DIR, agentType);
12850
- if (!fs3.existsSync(dir)) return null;
13054
+ if (!fs4.existsSync(dir)) return null;
12851
13055
  const files = listHistoryFiles(dir, historySessionId).sort();
12852
13056
  for (const file of files) {
12853
- const lines = fs3.readFileSync(path11.join(dir, file), "utf-8").split("\n").filter(Boolean);
13057
+ const lines = fs4.readFileSync(path11.join(dir, file), "utf-8").split("\n").filter(Boolean);
12854
13058
  for (const line of lines) {
12855
13059
  try {
12856
13060
  const parsed = JSON.parse(line);
@@ -12871,16 +13075,16 @@ function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
12871
13075
  if (records.length === 0) return false;
12872
13076
  try {
12873
13077
  const dir = path11.join(HISTORY_DIR, agentType);
12874
- fs3.mkdirSync(dir, { recursive: true });
13078
+ fs4.mkdirSync(dir, { recursive: true });
12875
13079
  const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
12876
- for (const file of fs3.readdirSync(dir)) {
13080
+ for (const file of fs4.readdirSync(dir)) {
12877
13081
  if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
12878
- fs3.unlinkSync(path11.join(dir, file));
13082
+ fs4.unlinkSync(path11.join(dir, file));
12879
13083
  }
12880
13084
  }
12881
13085
  const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
12882
13086
  const filePath = path11.join(dir, `${prefix}${targetDate}.jsonl`);
12883
- fs3.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
13087
+ fs4.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
12884
13088
  `, "utf-8");
12885
13089
  invalidatePersistedSavedHistoryIndex(agentType, dir);
12886
13090
  savedHistorySessionCache.delete(agentType.replace(/[^a-zA-Z0-9_-]/g, "_"));
@@ -12988,7 +13192,7 @@ function buildNativeSessionSummary(agentType, historySessionId, records, sourceP
12988
13192
  if (visible.length === 0) return null;
12989
13193
  let sourceMtimeMs = 0;
12990
13194
  try {
12991
- sourceMtimeMs = fs3.statSync(sourcePath).mtimeMs;
13195
+ sourceMtimeMs = fs4.statSync(sourcePath).mtimeMs;
12992
13196
  } catch {
12993
13197
  }
12994
13198
  const firstMessageAt = visible[0]?.receivedAt || sourceMtimeMs || Date.now();
@@ -13761,6 +13965,19 @@ function formatAutoApprovalMessage(modalMessage, buttonLabel) {
13761
13965
  }
13762
13966
 
13763
13967
  // src/providers/ide-provider-instance.ts
13968
+ async function withTimeout(promise, timeoutMs, label) {
13969
+ let timer = null;
13970
+ try {
13971
+ return await Promise.race([
13972
+ promise,
13973
+ new Promise((_, reject) => {
13974
+ timer = setTimeout(() => reject(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
13975
+ })
13976
+ ]);
13977
+ } finally {
13978
+ if (timer) clearTimeout(timer);
13979
+ }
13980
+ }
13764
13981
  var IdeProviderInstance = class {
13765
13982
  type;
13766
13983
  category = "ide";
@@ -13985,7 +14202,7 @@ var IdeProviderInstance = class {
13985
14202
  if (webviewScript) {
13986
14203
  const matchText = this.provider.webviewMatchText;
13987
14204
  const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
13988
- const webviewRaw = await cdp.evaluateInWebviewFrame(webviewScript, matchFn);
14205
+ const webviewRaw = await withTimeout(cdp.evaluateInWebviewFrame(webviewScript, matchFn), 3e4, "evaluateInWebviewFrame");
13989
14206
  if (webviewRaw) {
13990
14207
  raw = typeof webviewRaw === "string" ? (() => {
13991
14208
  try {
@@ -14000,7 +14217,7 @@ var IdeProviderInstance = class {
14000
14217
  if (!raw) {
14001
14218
  const readChatScript = this.getReadChatScript();
14002
14219
  if (!readChatScript) return;
14003
- raw = await cdp.evaluate(readChatScript, 3e4);
14220
+ raw = await withTimeout(cdp.evaluate(readChatScript, 3e4), 3e4, "evaluate.readChatScript");
14004
14221
  if (typeof raw === "string") {
14005
14222
  try {
14006
14223
  raw = JSON.parse(raw);
@@ -14311,7 +14528,7 @@ ${effect.notification.body || ""}`.trim();
14311
14528
  now
14312
14529
  );
14313
14530
  LOG.info("IdeInstance", `[IdeInstance:${this.type}] autoApprove: executing resolveAction for "${targetButton}"`);
14314
- let rawResult = await cdp.evaluate(script, 1e4);
14531
+ let rawResult = await withTimeout(cdp.evaluate(script, 1e4), 1e4, "evaluate.autoApprove");
14315
14532
  if (typeof rawResult === "string") {
14316
14533
  try {
14317
14534
  rawResult = JSON.parse(rawResult);
@@ -15380,7 +15597,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
15380
15597
  }
15381
15598
 
15382
15599
  // src/commands/chat-commands.ts
15383
- var fs4 = __toESM(require("fs"));
15600
+ var fs5 = __toESM(require("fs"));
15384
15601
  var os6 = __toESM(require("os"));
15385
15602
  var path12 = __toESM(require("path"));
15386
15603
  var import_node_crypto = require("crypto");
@@ -15953,11 +16170,11 @@ function buildChatDebugBundleSummary(bundle) {
15953
16170
  function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
15954
16171
  const bundleId = createChatDebugBundleId(targetSessionId);
15955
16172
  const dir = getChatDebugBundleDir();
15956
- fs4.mkdirSync(dir, { recursive: true });
16173
+ fs5.mkdirSync(dir, { recursive: true });
15957
16174
  const savedPath = path12.join(dir, `${bundleId}.json`);
15958
16175
  const json = `${JSON.stringify(bundle, null, 2)}
15959
16176
  `;
15960
- fs4.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
16177
+ fs5.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
15961
16178
  return { bundleId, savedPath, sizeBytes: Buffer.byteLength(json, "utf8") };
15962
16179
  }
15963
16180
  function isDaemonFileDebugDelivery(args) {
@@ -17120,7 +17337,7 @@ async function handleResolveAction(h, args) {
17120
17337
  }
17121
17338
 
17122
17339
  // src/commands/cdp-commands.ts
17123
- var fs5 = __toESM(require("fs"));
17340
+ var fs6 = __toESM(require("fs"));
17124
17341
  var path13 = __toESM(require("path"));
17125
17342
  var os7 = __toESM(require("os"));
17126
17343
  var KEY_TO_VK = {
@@ -17393,7 +17610,7 @@ function resolveSafePath(requestedPath) {
17393
17610
  return path13.resolve(inputPath);
17394
17611
  }
17395
17612
  function listDirectoryEntriesSafe(dirPath) {
17396
- const entries = fs5.readdirSync(dirPath, { withFileTypes: true });
17613
+ const entries = fs6.readdirSync(dirPath, { withFileTypes: true });
17397
17614
  const files = [];
17398
17615
  for (const entry of entries) {
17399
17616
  const entryPath = path13.join(dirPath, entry.name);
@@ -17405,14 +17622,14 @@ function listDirectoryEntriesSafe(dirPath) {
17405
17622
  if (entry.isFile()) {
17406
17623
  let size;
17407
17624
  try {
17408
- size = fs5.statSync(entryPath).size;
17625
+ size = fs6.statSync(entryPath).size;
17409
17626
  } catch {
17410
17627
  size = void 0;
17411
17628
  }
17412
17629
  files.push({ name: entry.name, type: "file", size });
17413
17630
  continue;
17414
17631
  }
17415
- const stat2 = fs5.statSync(entryPath);
17632
+ const stat2 = fs6.statSync(entryPath);
17416
17633
  files.push({
17417
17634
  name: entry.name,
17418
17635
  type: stat2.isDirectory() ? "directory" : "file",
@@ -17430,7 +17647,7 @@ function listWindowsDriveEntries(excludePath) {
17430
17647
  const letter = String.fromCharCode(code);
17431
17648
  const root = `${letter}:\\`;
17432
17649
  try {
17433
- if (!fs5.existsSync(root)) continue;
17650
+ if (!fs6.existsSync(root)) continue;
17434
17651
  if (excluded && root.toLowerCase() === excluded) continue;
17435
17652
  drives.push({ name: `${letter}:`, type: "directory", path: root });
17436
17653
  } catch {
@@ -17441,7 +17658,7 @@ function listWindowsDriveEntries(excludePath) {
17441
17658
  async function handleFileRead(h, args) {
17442
17659
  try {
17443
17660
  const filePath = resolveSafePath(args?.path);
17444
- const content = fs5.readFileSync(filePath, "utf-8");
17661
+ const content = fs6.readFileSync(filePath, "utf-8");
17445
17662
  return { success: true, content, path: filePath };
17446
17663
  } catch (e) {
17447
17664
  return { success: false, error: e.message };
@@ -17450,8 +17667,8 @@ async function handleFileRead(h, args) {
17450
17667
  async function handleFileWrite(h, args) {
17451
17668
  try {
17452
17669
  const filePath = resolveSafePath(args?.path);
17453
- fs5.mkdirSync(path13.dirname(filePath), { recursive: true });
17454
- fs5.writeFileSync(filePath, args?.content || "", "utf-8");
17670
+ fs6.mkdirSync(path13.dirname(filePath), { recursive: true });
17671
+ fs6.writeFileSync(filePath, args?.content || "", "utf-8");
17455
17672
  return { success: true, path: filePath };
17456
17673
  } catch (e) {
17457
17674
  return { success: false, error: e.message };
@@ -18577,7 +18794,7 @@ var os13 = __toESM(require("os"));
18577
18794
  var path18 = __toESM(require("path"));
18578
18795
  var crypto4 = __toESM(require("crypto"));
18579
18796
  var import_fs10 = require("fs");
18580
- var import_child_process6 = require("child_process");
18797
+ var import_child_process5 = require("child_process");
18581
18798
  var import_chalk = __toESM(require("chalk"));
18582
18799
  init_provider_cli_adapter();
18583
18800
  init_cli_detector();
@@ -18587,7 +18804,7 @@ init_config();
18587
18804
  var os12 = __toESM(require("os"));
18588
18805
  var path16 = __toESM(require("path"));
18589
18806
  var crypto3 = __toESM(require("crypto"));
18590
- var fs6 = __toESM(require("fs"));
18807
+ var fs7 = __toESM(require("fs"));
18591
18808
  var import_node_module = require("module");
18592
18809
  init_provider_cli_adapter();
18593
18810
  init_logger();
@@ -18646,9 +18863,9 @@ function materializeImageDataPart(part, index, dir) {
18646
18863
  if (!part.data) return null;
18647
18864
  const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
18648
18865
  if (!rawData) return null;
18649
- fs6.mkdirSync(dir, { recursive: true });
18866
+ fs7.mkdirSync(dir, { recursive: true });
18650
18867
  const filePath = path16.join(dir, safeInputImageBasename(index, part.mimeType));
18651
- fs6.writeFileSync(filePath, Buffer.from(rawData, "base64"));
18868
+ fs7.writeFileSync(filePath, Buffer.from(rawData, "base64"));
18652
18869
  cleanupStaleMaterializedImages(dir);
18653
18870
  return filePath;
18654
18871
  }
@@ -18660,14 +18877,14 @@ function cleanupStaleMaterializedImages(dir) {
18660
18877
  if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
18661
18878
  lastMaterializedImageCleanupAt = now;
18662
18879
  try {
18663
- const entries = fs6.readdirSync(dir);
18880
+ const entries = fs7.readdirSync(dir);
18664
18881
  for (const entry of entries) {
18665
18882
  if (!entry.startsWith("adhdev-input-image-")) continue;
18666
18883
  const fullPath = path16.join(dir, entry);
18667
18884
  try {
18668
- const stat2 = fs6.statSync(fullPath);
18885
+ const stat2 = fs7.statSync(fullPath);
18669
18886
  if (now - stat2.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
18670
- fs6.unlinkSync(fullPath);
18887
+ fs7.unlinkSync(fullPath);
18671
18888
  }
18672
18889
  } catch {
18673
18890
  }
@@ -18906,7 +19123,7 @@ var CliProviderInstance = class {
18906
19123
  const resolvedDbPath = probe.dbPath.replace(/^~/, os12.homedir());
18907
19124
  const now = Date.now();
18908
19125
  if (this.cachedSqliteDbMissingUntil > now) return null;
18909
- if (!fs6.existsSync(resolvedDbPath)) {
19126
+ if (!fs7.existsSync(resolvedDbPath)) {
18910
19127
  this.cachedSqliteDbMissingUntil = now + 1e4;
18911
19128
  return null;
18912
19129
  }
@@ -19822,7 +20039,7 @@ ${effect.notification.body || ""}`.trim();
19822
20039
  };
19823
20040
  addDir(this.workingDir);
19824
20041
  try {
19825
- addDir(fs6.realpathSync.native(this.workingDir));
20042
+ addDir(fs7.realpathSync.native(this.workingDir));
19826
20043
  } catch {
19827
20044
  }
19828
20045
  return Array.from(dirs);
@@ -19861,7 +20078,7 @@ ${effect.notification.body || ""}`.trim();
19861
20078
  // src/providers/acp-provider-instance.ts
19862
20079
  var path17 = __toESM(require("path"));
19863
20080
  var import_stream = require("stream");
19864
- var import_child_process5 = require("child_process");
20081
+ var import_child_process4 = require("child_process");
19865
20082
  var import_sdk = require("@agentclientprotocol/sdk");
19866
20083
  init_logger();
19867
20084
  function getPromptCapabilityFlags(agentCapabilities) {
@@ -20378,7 +20595,7 @@ var AcpProviderInstance = class {
20378
20595
  this.errorMessage = null;
20379
20596
  this.errorReason = null;
20380
20597
  this.stderrBuffer = [];
20381
- this.process = (0, import_child_process5.spawn)(command, args, {
20598
+ this.process = (0, import_child_process4.spawn)(command, args, {
20382
20599
  cwd: this.workingDir,
20383
20600
  env,
20384
20601
  stdio: ["pipe", "pipe", "pipe"],
@@ -21105,7 +21322,7 @@ function commandExists(command) {
21105
21322
  return (0, import_fs10.existsSync)(expandExecutable(trimmed));
21106
21323
  }
21107
21324
  try {
21108
- (0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
21325
+ (0, import_child_process5.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
21109
21326
  stdio: "ignore",
21110
21327
  ...process.platform === "win32" ? { windowsHide: true } : {}
21111
21328
  });
@@ -21914,13 +22131,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
21914
22131
  };
21915
22132
 
21916
22133
  // src/launch.ts
21917
- var import_child_process7 = require("child_process");
22134
+ var import_child_process6 = require("child_process");
21918
22135
  var net = __toESM(require("net"));
21919
22136
  var os15 = __toESM(require("os"));
21920
22137
  var path20 = __toESM(require("path"));
21921
22138
 
21922
22139
  // src/providers/provider-loader.ts
21923
- var fs7 = __toESM(require("fs"));
22140
+ var fs8 = __toESM(require("fs"));
21924
22141
  var path19 = __toESM(require("path"));
21925
22142
  var os14 = __toESM(require("os"));
21926
22143
  var chokidar = __toESM(require("chokidar"));
@@ -22273,9 +22490,9 @@ var ProviderLoader = class _ProviderLoader {
22273
22490
  static siblingStderrLogged = /* @__PURE__ */ new Set();
22274
22491
  static looksLikeProviderRoot(candidate) {
22275
22492
  try {
22276
- if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
22493
+ if (!fs8.existsSync(candidate) || !fs8.statSync(candidate).isDirectory()) return false;
22277
22494
  return ["ide", "extension", "cli", "acp"].some(
22278
- (category) => fs7.existsSync(path19.join(candidate, category))
22495
+ (category) => fs8.existsSync(path19.join(candidate, category))
22279
22496
  );
22280
22497
  } catch {
22281
22498
  return false;
@@ -22283,7 +22500,7 @@ var ProviderLoader = class _ProviderLoader {
22283
22500
  }
22284
22501
  static hasProviderRootMarker(candidate) {
22285
22502
  try {
22286
- return fs7.existsSync(path19.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
22503
+ return fs8.existsSync(path19.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
22287
22504
  } catch {
22288
22505
  return false;
22289
22506
  }
@@ -22445,7 +22662,7 @@ var ProviderLoader = class _ProviderLoader {
22445
22662
  this.providers.clear();
22446
22663
  this.providerAvailability.clear();
22447
22664
  let upstreamCount = 0;
22448
- if (!this.disableUpstream && fs7.existsSync(this.upstreamDir)) {
22665
+ if (!this.disableUpstream && fs8.existsSync(this.upstreamDir)) {
22449
22666
  upstreamCount = this.loadDir(this.upstreamDir);
22450
22667
  if (upstreamCount > 0) {
22451
22668
  this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
@@ -22453,7 +22670,7 @@ var ProviderLoader = class _ProviderLoader {
22453
22670
  } else if (this.disableUpstream) {
22454
22671
  this.log("Upstream loading disabled (sourceMode=no-upstream)");
22455
22672
  }
22456
- if (fs7.existsSync(this.userDir)) {
22673
+ if (fs8.existsSync(this.userDir)) {
22457
22674
  const userCount = this.loadDir(this.userDir, [".upstream"]);
22458
22675
  if (userCount > 0) {
22459
22676
  this.log(`Loaded ${userCount} user custom providers (never auto-updated)`);
@@ -22468,10 +22685,10 @@ var ProviderLoader = class _ProviderLoader {
22468
22685
  * Check if upstream directory exists and has providers.
22469
22686
  */
22470
22687
  hasUpstream() {
22471
- if (!fs7.existsSync(this.upstreamDir)) return false;
22688
+ if (!fs8.existsSync(this.upstreamDir)) return false;
22472
22689
  try {
22473
- return fs7.readdirSync(this.upstreamDir).some(
22474
- (d) => fs7.statSync(path19.join(this.upstreamDir, d)).isDirectory()
22690
+ return fs8.readdirSync(this.upstreamDir).some(
22691
+ (d) => fs8.statSync(path19.join(this.upstreamDir, d)).isDirectory()
22475
22692
  );
22476
22693
  } catch {
22477
22694
  return false;
@@ -22969,7 +23186,7 @@ var ProviderLoader = class _ProviderLoader {
22969
23186
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
22970
23187
  if (providerDir) {
22971
23188
  const fullDir = path19.join(providerDir, entry.scriptDir);
22972
- resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
23189
+ resolved._resolvedScriptsPath = fs8.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
22973
23190
  }
22974
23191
  matched = true;
22975
23192
  }
@@ -22985,7 +23202,7 @@ var ProviderLoader = class _ProviderLoader {
22985
23202
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
22986
23203
  if (providerDir) {
22987
23204
  const fullDir = path19.join(providerDir, base.defaultScriptDir);
22988
- resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
23205
+ resolved._resolvedScriptsPath = fs8.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
22989
23206
  }
22990
23207
  }
22991
23208
  resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
@@ -23003,7 +23220,7 @@ var ProviderLoader = class _ProviderLoader {
23003
23220
  resolved._resolvedScriptsSource = `versions:${range}`;
23004
23221
  if (providerDir) {
23005
23222
  const fullDir = path19.join(providerDir, dirOverride);
23006
- resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
23223
+ resolved._resolvedScriptsPath = fs8.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
23007
23224
  }
23008
23225
  }
23009
23226
  } else if (override.scripts) {
@@ -23020,7 +23237,7 @@ var ProviderLoader = class _ProviderLoader {
23020
23237
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
23021
23238
  if (providerDir) {
23022
23239
  const fullDir = path19.join(providerDir, base.defaultScriptDir);
23023
- resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
23240
+ resolved._resolvedScriptsPath = fs8.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
23024
23241
  }
23025
23242
  }
23026
23243
  }
@@ -23053,14 +23270,14 @@ var ProviderLoader = class _ProviderLoader {
23053
23270
  return null;
23054
23271
  }
23055
23272
  const dir = path19.join(providerDir, scriptDir);
23056
- if (!fs7.existsSync(dir)) {
23273
+ if (!fs8.existsSync(dir)) {
23057
23274
  this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
23058
23275
  return null;
23059
23276
  }
23060
23277
  const cached = this.scriptsCache.get(dir);
23061
23278
  if (cached) return cached;
23062
23279
  const scriptsJs = path19.join(dir, "scripts.js");
23063
- if (fs7.existsSync(scriptsJs)) {
23280
+ if (fs8.existsSync(scriptsJs)) {
23064
23281
  try {
23065
23282
  delete require.cache[require.resolve(scriptsJs)];
23066
23283
  const loaded = require(scriptsJs);
@@ -23081,9 +23298,9 @@ var ProviderLoader = class _ProviderLoader {
23081
23298
  watch() {
23082
23299
  this.stopWatch();
23083
23300
  const watchDir = (dir) => {
23084
- if (!fs7.existsSync(dir)) {
23301
+ if (!fs8.existsSync(dir)) {
23085
23302
  try {
23086
- fs7.mkdirSync(dir, { recursive: true });
23303
+ fs8.mkdirSync(dir, { recursive: true });
23087
23304
  } catch {
23088
23305
  return;
23089
23306
  }
@@ -23096,13 +23313,17 @@ var ProviderLoader = class _ProviderLoader {
23096
23313
  ignoreInitial: true,
23097
23314
  awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 }
23098
23315
  });
23316
+ let reloadTimer = null;
23099
23317
  const handleChange = (filePath) => {
23100
23318
  if (/[\/\\]fixtures[\/\\]/.test(filePath)) {
23101
23319
  return;
23102
23320
  }
23103
23321
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
23104
- this.log(`File changed: ${path19.basename(filePath)}, reloading...`);
23105
- this.reload();
23322
+ if (reloadTimer) clearTimeout(reloadTimer);
23323
+ reloadTimer = setTimeout(() => {
23324
+ this.log(`File changed: ${path19.basename(filePath)}, reloading...`);
23325
+ this.reload();
23326
+ }, 300);
23106
23327
  }
23107
23328
  };
23108
23329
  watcher.on("add", handleChange).on("change", handleChange).on("unlink", handleChange);
@@ -23155,13 +23376,15 @@ var ProviderLoader = class _ProviderLoader {
23155
23376
  return { updated: false };
23156
23377
  }
23157
23378
  const https = require("https");
23158
- const { execSync: execSync7 } = require("child_process");
23379
+ const { exec: exec7 } = require("child_process");
23380
+ const { promisify: promisify6 } = require("util");
23381
+ const execAsync5 = promisify6(exec7);
23159
23382
  const metaPath = path19.join(this.upstreamDir, _ProviderLoader.META_FILE);
23160
23383
  let prevEtag = "";
23161
23384
  let prevTimestamp = 0;
23162
23385
  try {
23163
- if (fs7.existsSync(metaPath)) {
23164
- const meta = JSON.parse(fs7.readFileSync(metaPath, "utf-8"));
23386
+ if (fs8.existsSync(metaPath)) {
23387
+ const meta = JSON.parse(fs8.readFileSync(metaPath, "utf-8"));
23165
23388
  prevEtag = meta.etag || "";
23166
23389
  prevTimestamp = meta.timestamp || 0;
23167
23390
  }
@@ -23219,36 +23442,36 @@ var ProviderLoader = class _ProviderLoader {
23219
23442
  const tmpTar = path19.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
23220
23443
  const tmpExtract = path19.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
23221
23444
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
23222
- fs7.mkdirSync(tmpExtract, { recursive: true });
23223
- execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
23224
- const extracted = fs7.readdirSync(tmpExtract);
23445
+ fs8.mkdirSync(tmpExtract, { recursive: true });
23446
+ await execAsync5(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
23447
+ const extracted = fs8.readdirSync(tmpExtract);
23225
23448
  const rootDir = extracted.find(
23226
- (d) => fs7.statSync(path19.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
23449
+ (d) => fs8.statSync(path19.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
23227
23450
  );
23228
23451
  if (!rootDir) throw new Error("Unexpected tarball structure");
23229
23452
  const sourceDir = path19.join(tmpExtract, rootDir);
23230
23453
  const backupDir = this.upstreamDir + ".bak";
23231
- if (fs7.existsSync(this.upstreamDir)) {
23232
- if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
23233
- fs7.renameSync(this.upstreamDir, backupDir);
23454
+ if (fs8.existsSync(this.upstreamDir)) {
23455
+ if (fs8.existsSync(backupDir)) fs8.rmSync(backupDir, { recursive: true, force: true });
23456
+ fs8.renameSync(this.upstreamDir, backupDir);
23234
23457
  }
23235
23458
  try {
23236
23459
  this.copyDirRecursive(sourceDir, this.upstreamDir);
23237
23460
  this.writeMeta(metaPath, etag || `ts-${Date.now()}`, Date.now());
23238
- if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
23461
+ if (fs8.existsSync(backupDir)) fs8.rmSync(backupDir, { recursive: true, force: true });
23239
23462
  } catch (e) {
23240
- if (fs7.existsSync(backupDir)) {
23241
- if (fs7.existsSync(this.upstreamDir)) fs7.rmSync(this.upstreamDir, { recursive: true, force: true });
23242
- fs7.renameSync(backupDir, this.upstreamDir);
23463
+ if (fs8.existsSync(backupDir)) {
23464
+ if (fs8.existsSync(this.upstreamDir)) fs8.rmSync(this.upstreamDir, { recursive: true, force: true });
23465
+ fs8.renameSync(backupDir, this.upstreamDir);
23243
23466
  }
23244
23467
  throw e;
23245
23468
  }
23246
23469
  try {
23247
- fs7.rmSync(tmpTar, { force: true });
23470
+ fs8.rmSync(tmpTar, { force: true });
23248
23471
  } catch {
23249
23472
  }
23250
23473
  try {
23251
- fs7.rmSync(tmpExtract, { recursive: true, force: true });
23474
+ fs8.rmSync(tmpExtract, { recursive: true, force: true });
23252
23475
  } catch {
23253
23476
  }
23254
23477
  const upstreamCount = this.countProviders(this.upstreamDir);
@@ -23280,7 +23503,7 @@ var ProviderLoader = class _ProviderLoader {
23280
23503
  reject(new Error(`HTTP ${res.statusCode}`));
23281
23504
  return;
23282
23505
  }
23283
- const ws = fs7.createWriteStream(destPath);
23506
+ const ws = fs8.createWriteStream(destPath);
23284
23507
  res.pipe(ws);
23285
23508
  ws.on("finish", () => {
23286
23509
  ws.close();
@@ -23299,22 +23522,22 @@ var ProviderLoader = class _ProviderLoader {
23299
23522
  }
23300
23523
  /** Recursive directory copy */
23301
23524
  copyDirRecursive(src, dest) {
23302
- fs7.mkdirSync(dest, { recursive: true });
23303
- for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
23525
+ fs8.mkdirSync(dest, { recursive: true });
23526
+ for (const entry of fs8.readdirSync(src, { withFileTypes: true })) {
23304
23527
  const srcPath = path19.join(src, entry.name);
23305
23528
  const destPath = path19.join(dest, entry.name);
23306
23529
  if (entry.isDirectory()) {
23307
23530
  this.copyDirRecursive(srcPath, destPath);
23308
23531
  } else {
23309
- fs7.copyFileSync(srcPath, destPath);
23532
+ fs8.copyFileSync(srcPath, destPath);
23310
23533
  }
23311
23534
  }
23312
23535
  }
23313
23536
  /** .meta.json save */
23314
23537
  writeMeta(metaPath, etag, timestamp) {
23315
23538
  try {
23316
- fs7.mkdirSync(path19.dirname(metaPath), { recursive: true });
23317
- fs7.writeFileSync(metaPath, JSON.stringify({
23539
+ fs8.mkdirSync(path19.dirname(metaPath), { recursive: true });
23540
+ fs8.writeFileSync(metaPath, JSON.stringify({
23318
23541
  etag,
23319
23542
  timestamp,
23320
23543
  lastCheck: new Date(timestamp).toISOString(),
@@ -23325,11 +23548,11 @@ var ProviderLoader = class _ProviderLoader {
23325
23548
  }
23326
23549
  /** Count provider files (provider.js or provider.json) */
23327
23550
  countProviders(dir) {
23328
- if (!fs7.existsSync(dir)) return 0;
23551
+ if (!fs8.existsSync(dir)) return 0;
23329
23552
  let count = 0;
23330
23553
  const scan = (d) => {
23331
23554
  try {
23332
- for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
23555
+ for (const entry of fs8.readdirSync(d, { withFileTypes: true })) {
23333
23556
  if (entry.isDirectory()) scan(path19.join(d, entry.name));
23334
23557
  else if (entry.name === "provider.json") count++;
23335
23558
  }
@@ -23556,18 +23779,18 @@ var ProviderLoader = class _ProviderLoader {
23556
23779
  const cat = provider.category;
23557
23780
  const searchRoots = this.getProviderRoots();
23558
23781
  for (const root of searchRoots) {
23559
- if (!fs7.existsSync(root)) continue;
23782
+ if (!fs8.existsSync(root)) continue;
23560
23783
  const candidate = this.getProviderDir(root, cat, type);
23561
- if (fs7.existsSync(path19.join(candidate, "provider.json"))) return candidate;
23784
+ if (fs8.existsSync(path19.join(candidate, "provider.json"))) return candidate;
23562
23785
  const catDir = path19.join(root, cat);
23563
- if (fs7.existsSync(catDir)) {
23786
+ if (fs8.existsSync(catDir)) {
23564
23787
  try {
23565
- for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
23788
+ for (const entry of fs8.readdirSync(catDir, { withFileTypes: true })) {
23566
23789
  if (!entry.isDirectory()) continue;
23567
23790
  const jsonPath = path19.join(catDir, entry.name, "provider.json");
23568
- if (fs7.existsSync(jsonPath)) {
23791
+ if (fs8.existsSync(jsonPath)) {
23569
23792
  try {
23570
- const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
23793
+ const data = JSON.parse(fs8.readFileSync(jsonPath, "utf-8"));
23571
23794
  if (data.type === type) return path19.join(catDir, entry.name);
23572
23795
  } catch {
23573
23796
  }
@@ -23586,7 +23809,7 @@ var ProviderLoader = class _ProviderLoader {
23586
23809
  */
23587
23810
  buildScriptWrappersFromDir(dir) {
23588
23811
  const scriptsJs = path19.join(dir, "scripts.js");
23589
- if (fs7.existsSync(scriptsJs)) {
23812
+ if (fs8.existsSync(scriptsJs)) {
23590
23813
  try {
23591
23814
  delete require.cache[require.resolve(scriptsJs)];
23592
23815
  return require(scriptsJs);
@@ -23596,13 +23819,13 @@ var ProviderLoader = class _ProviderLoader {
23596
23819
  const toCamel = (name) => name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
23597
23820
  const result = {};
23598
23821
  try {
23599
- for (const file of fs7.readdirSync(dir)) {
23822
+ for (const file of fs8.readdirSync(dir)) {
23600
23823
  if (!file.endsWith(".js")) continue;
23601
23824
  const scriptName = toCamel(file.replace(".js", ""));
23602
23825
  const filePath = path19.join(dir, file);
23603
23826
  result[scriptName] = (...args) => {
23604
23827
  try {
23605
- let content = fs7.readFileSync(filePath, "utf-8");
23828
+ let content = fs8.readFileSync(filePath, "utf-8");
23606
23829
  if (args[0] && typeof args[0] === "object") {
23607
23830
  for (const [key, val] of Object.entries(args[0])) {
23608
23831
  let v = val;
@@ -23648,12 +23871,12 @@ var ProviderLoader = class _ProviderLoader {
23648
23871
  * Structure: dir/category/agent-name/provider.{json,js}
23649
23872
  */
23650
23873
  loadDir(dir, excludeDirs) {
23651
- if (!fs7.existsSync(dir)) return 0;
23874
+ if (!fs8.existsSync(dir)) return 0;
23652
23875
  let count = 0;
23653
23876
  const scan = (d) => {
23654
23877
  let entries;
23655
23878
  try {
23656
- entries = fs7.readdirSync(d, { withFileTypes: true });
23879
+ entries = fs8.readdirSync(d, { withFileTypes: true });
23657
23880
  } catch {
23658
23881
  return;
23659
23882
  }
@@ -23661,7 +23884,7 @@ var ProviderLoader = class _ProviderLoader {
23661
23884
  if (hasJson) {
23662
23885
  const jsonPath = path19.join(d, "provider.json");
23663
23886
  try {
23664
- const raw = fs7.readFileSync(jsonPath, "utf-8");
23887
+ const raw = fs8.readFileSync(jsonPath, "utf-8");
23665
23888
  const mod = JSON.parse(raw);
23666
23889
  if (typeof mod.extensionIdPattern === "string") {
23667
23890
  const flags = mod.extensionIdPattern_flags || "";
@@ -23681,7 +23904,7 @@ var ProviderLoader = class _ProviderLoader {
23681
23904
  } else {
23682
23905
  const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
23683
23906
  const scriptsPath = path19.join(d, "scripts.js");
23684
- if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
23907
+ if (!hasCompatibility && fs8.existsSync(scriptsPath)) {
23685
23908
  try {
23686
23909
  delete require.cache[require.resolve(scriptsPath)];
23687
23910
  const scripts = require(scriptsPath);
@@ -23786,6 +24009,14 @@ function findMacAppProcessPids(psOutput, appPaths) {
23786
24009
  }
23787
24010
 
23788
24011
  // src/launch.ts
24012
+ async function execQuiet(command, options = {}) {
24013
+ return new Promise((resolve16) => {
24014
+ (0, import_child_process6.exec)(command, options, (error, stdout) => {
24015
+ if (error) return resolve16("");
24016
+ resolve16(stdout.toString());
24017
+ });
24018
+ });
24019
+ }
23789
24020
  var _providerLoader = null;
23790
24021
  function getProviderLoader() {
23791
24022
  if (!_providerLoader) {
@@ -23824,11 +24055,11 @@ function escapeForAppleScript(value) {
23824
24055
  function getIdePathCandidates(ideId) {
23825
24056
  return getProviderLoader().getIdePathCandidates(ideId);
23826
24057
  }
23827
- function getMacAppProcessPids(ideId) {
24058
+ async function getMacAppProcessPids(ideId) {
23828
24059
  const appPaths = getIdePathCandidates(ideId);
23829
24060
  if (appPaths.length === 0) return [];
23830
24061
  try {
23831
- const output = (0, import_child_process7.execSync)("ps axww -o pid=,args=", {
24062
+ const output = await execQuiet("ps axww -o pid=,args=", {
23832
24063
  encoding: "utf-8",
23833
24064
  timeout: 3e3,
23834
24065
  stdio: ["pipe", "pipe", "pipe"]
@@ -23838,8 +24069,8 @@ function getMacAppProcessPids(ideId) {
23838
24069
  return [];
23839
24070
  }
23840
24071
  }
23841
- function killMacAppPathProcesses(ideId, signal) {
23842
- const pids = getMacAppProcessPids(ideId);
24072
+ async function killMacAppPathProcesses(ideId, signal) {
24073
+ const pids = await getMacAppProcessPids(ideId);
23843
24074
  let signalled = false;
23844
24075
  for (const pid of pids) {
23845
24076
  try {
@@ -23902,68 +24133,68 @@ async function killIdeProcess(ideId) {
23902
24133
  try {
23903
24134
  if (plat === "darwin" && appName) {
23904
24135
  try {
23905
- (0, import_child_process7.execSync)(`osascript -e 'tell application "${escapeForAppleScript(appName)}" to quit' 2>/dev/null`, {
24136
+ await execQuiet(`osascript -e 'tell application "${escapeForAppleScript(appName)}" to quit' 2>/dev/null`, {
23906
24137
  timeout: 5e3
23907
24138
  });
23908
24139
  } catch {
23909
24140
  try {
23910
- (0, import_child_process7.execSync)(`pkill -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
24141
+ await execQuiet(`pkill -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
23911
24142
  } catch {
23912
24143
  }
23913
24144
  }
23914
- killMacAppPathProcesses(ideId, "SIGTERM");
24145
+ await killMacAppPathProcesses(ideId, "SIGTERM");
23915
24146
  } else if (plat === "win32" && winProcesses) {
23916
24147
  for (const proc of winProcesses) {
23917
24148
  try {
23918
- (0, import_child_process7.execSync)(`taskkill /IM "${proc}" /F 2>nul`, { timeout: 5e3 });
24149
+ await execQuiet(`taskkill /IM "${proc}" /F 2>nul`, { timeout: 5e3 });
23919
24150
  } catch {
23920
24151
  }
23921
24152
  }
23922
24153
  try {
23923
24154
  const exeName = winProcesses[0].replace(".exe", "");
23924
- (0, import_child_process7.execSync)(`powershell -Command "Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue | Stop-Process -Force"`, {
24155
+ await execQuiet(`powershell -Command "Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue | Stop-Process -Force"`, {
23925
24156
  timeout: 1e4
23926
24157
  });
23927
24158
  } catch {
23928
24159
  }
23929
24160
  } else {
23930
24161
  try {
23931
- (0, import_child_process7.execSync)(`pkill -f "${ideId}" 2>/dev/null`);
24162
+ await execQuiet(`pkill -f "${ideId}" 2>/dev/null`);
23932
24163
  } catch {
23933
24164
  }
23934
24165
  }
23935
24166
  for (let i = 0; i < 30; i++) {
23936
24167
  await new Promise((r) => setTimeout(r, 500));
23937
- if (!isIdeRunning(ideId)) return true;
24168
+ if (!await isIdeRunning(ideId)) return true;
23938
24169
  }
23939
24170
  if (plat === "darwin" && appName) {
23940
24171
  try {
23941
- (0, import_child_process7.execSync)(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
24172
+ await execQuiet(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
23942
24173
  } catch {
23943
24174
  }
23944
- killMacAppPathProcesses(ideId, "SIGKILL");
24175
+ await killMacAppPathProcesses(ideId, "SIGKILL");
23945
24176
  } else if (plat === "win32" && winProcesses) {
23946
24177
  for (const proc of winProcesses) {
23947
24178
  try {
23948
- (0, import_child_process7.execSync)(`taskkill /IM "${proc}" /F 2>nul`);
24179
+ await execQuiet(`taskkill /IM "${proc}" /F 2>nul`);
23949
24180
  } catch {
23950
24181
  }
23951
24182
  }
23952
24183
  }
23953
24184
  await new Promise((r) => setTimeout(r, 2e3));
23954
- return !isIdeRunning(ideId);
24185
+ return !await isIdeRunning(ideId);
23955
24186
  } catch {
23956
24187
  return false;
23957
24188
  }
23958
24189
  }
23959
- function isIdeRunning(ideId) {
24190
+ async function isIdeRunning(ideId) {
23960
24191
  const plat = os15.platform();
23961
24192
  try {
23962
24193
  if (plat === "darwin") {
23963
24194
  const appName = getMacAppIdentifiers()[ideId];
23964
- if (!appName) return getMacAppProcessPids(ideId).length > 0;
24195
+ if (!appName) return (await getMacAppProcessPids(ideId)).length > 0;
23965
24196
  try {
23966
- const result = (0, import_child_process7.execSync)(`pgrep -x "${appName}" 2>/dev/null`, {
24197
+ const result = await execQuiet(`pgrep -x "${appName}" 2>/dev/null`, {
23967
24198
  encoding: "utf-8",
23968
24199
  timeout: 3e3
23969
24200
  });
@@ -23971,7 +24202,7 @@ function isIdeRunning(ideId) {
23971
24202
  } catch {
23972
24203
  }
23973
24204
  try {
23974
- const result = (0, import_child_process7.execSync)(
24205
+ const result = await execQuiet(
23975
24206
  `osascript -e 'tell application "System Events" to count (every process whose name is "${escapeForAppleScript(appName)}")'`,
23976
24207
  {
23977
24208
  encoding: "utf-8",
@@ -23982,20 +24213,20 @@ function isIdeRunning(ideId) {
23982
24213
  if (Number.parseInt(result.trim() || "0", 10) > 0) return true;
23983
24214
  } catch {
23984
24215
  }
23985
- return getMacAppProcessPids(ideId).length > 0;
24216
+ return (await getMacAppProcessPids(ideId)).length > 0;
23986
24217
  } else if (plat === "win32") {
23987
24218
  const winProcesses = getWinProcessNames()[ideId];
23988
24219
  if (!winProcesses) return false;
23989
24220
  for (const proc of winProcesses) {
23990
24221
  try {
23991
- const result = (0, import_child_process7.execSync)(`tasklist /FI "IMAGENAME eq ${proc}" /NH 2>nul`, { encoding: "utf-8" });
24222
+ const result = await execQuiet(`tasklist /FI "IMAGENAME eq ${proc}" /NH 2>nul`, { encoding: "utf-8" });
23992
24223
  if (result.includes(proc)) return true;
23993
24224
  } catch {
23994
24225
  }
23995
24226
  }
23996
24227
  try {
23997
24228
  const exeName = winProcesses[0].replace(".exe", "");
23998
- const result = (0, import_child_process7.execSync)(
24229
+ const result = await execQuiet(
23999
24230
  `powershell -Command "(Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue).Count"`,
24000
24231
  { encoding: "utf-8", timeout: 5e3 }
24001
24232
  );
@@ -24004,20 +24235,20 @@ function isIdeRunning(ideId) {
24004
24235
  }
24005
24236
  return false;
24006
24237
  } else {
24007
- const result = (0, import_child_process7.execSync)(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
24238
+ const result = await execQuiet(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
24008
24239
  return result.trim().length > 0;
24009
24240
  }
24010
24241
  } catch {
24011
24242
  return false;
24012
24243
  }
24013
24244
  }
24014
- function detectCurrentWorkspace(ideId) {
24245
+ async function detectCurrentWorkspace(ideId) {
24015
24246
  const plat = os15.platform();
24016
24247
  if (plat === "darwin") {
24017
24248
  try {
24018
24249
  const appName = getMacAppIdentifiers()[ideId];
24019
24250
  if (!appName) return void 0;
24020
- const result = (0, import_child_process7.execSync)(
24251
+ const result = await execQuiet(
24021
24252
  `lsof -c "${appName}" 2>/dev/null | grep cwd | head -1 | awk '{print $NF}'`,
24022
24253
  { encoding: "utf-8", timeout: 3e3 }
24023
24254
  );
@@ -24027,7 +24258,7 @@ function detectCurrentWorkspace(ideId) {
24027
24258
  }
24028
24259
  } else if (plat === "win32") {
24029
24260
  try {
24030
- const fs16 = require("fs");
24261
+ const fs17 = require("fs");
24031
24262
  const appNameMap = getMacAppIdentifiers();
24032
24263
  const appName = appNameMap[ideId];
24033
24264
  if (appName) {
@@ -24036,8 +24267,8 @@ function detectCurrentWorkspace(ideId) {
24036
24267
  appName,
24037
24268
  "storage.json"
24038
24269
  );
24039
- if (fs16.existsSync(storagePath)) {
24040
- const data = JSON.parse(fs16.readFileSync(storagePath, "utf-8"));
24270
+ if (fs17.existsSync(storagePath)) {
24271
+ const data = JSON.parse(fs17.readFileSync(storagePath, "utf-8"));
24041
24272
  const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
24042
24273
  if (workspaces.length > 0) {
24043
24274
  const recent = workspaces[0];
@@ -24104,8 +24335,8 @@ async function launchWithCdp(options = {}) {
24104
24335
  };
24105
24336
  }
24106
24337
  }
24107
- const alreadyRunning = isIdeRunning(targetIde.id);
24108
- const workspace = options.workspace || (alreadyRunning ? detectCurrentWorkspace(targetIde.id) : void 0);
24338
+ const alreadyRunning = await isIdeRunning(targetIde.id);
24339
+ const workspace = options.workspace || (alreadyRunning ? await detectCurrentWorkspace(targetIde.id) : void 0);
24109
24340
  if (alreadyRunning) {
24110
24341
  const killed = await killIdeProcess(targetIde.id);
24111
24342
  if (!killed) {
@@ -24180,10 +24411,10 @@ async function launchMacOS(ide, port, workspace, newWindow) {
24180
24411
  const canUseAppLauncher = !!appName;
24181
24412
  const useAppLauncher = preferredMethod === "app" ? canUseAppLauncher : preferredMethod === "cli" ? false : !canUseCli && canUseAppLauncher;
24182
24413
  if (!useAppLauncher && ide.cliCommand) {
24183
- (0, import_child_process7.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore", windowsHide: true }).unref();
24414
+ (0, import_child_process6.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore", windowsHide: true }).unref();
24184
24415
  } else if (appName) {
24185
24416
  const openArgs = ["-a", appName, "--args", ...args];
24186
- (0, import_child_process7.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
24417
+ (0, import_child_process6.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
24187
24418
  } else {
24188
24419
  throw new Error(`No app identifier or CLI for ${ide.displayName}`);
24189
24420
  }
@@ -24209,7 +24440,7 @@ async function launchLinux(ide, port, workspace, newWindow) {
24209
24440
  const args = ["--remote-debugging-port=" + port];
24210
24441
  if (newWindow) args.push("--new-window");
24211
24442
  if (workspace) args.push(workspace);
24212
- (0, import_child_process7.spawn)(cli, args, { detached: true, stdio: "ignore", windowsHide: true }).unref();
24443
+ (0, import_child_process6.spawn)(cli, args, { detached: true, stdio: "ignore", windowsHide: true }).unref();
24213
24444
  }
24214
24445
  function getAvailableIdeIds() {
24215
24446
  return getProviderLoader().getAvailableIdeTypes();
@@ -24221,14 +24452,14 @@ init_cli_detector();
24221
24452
  init_logger();
24222
24453
 
24223
24454
  // src/logging/command-log.ts
24224
- var fs8 = __toESM(require("fs"));
24455
+ var fs9 = __toESM(require("fs"));
24225
24456
  var path21 = __toESM(require("path"));
24226
24457
  var os16 = __toESM(require("os"));
24227
24458
  var LOG_DIR2 = process.platform === "win32" ? path21.join(process.env.LOCALAPPDATA || process.env.APPDATA || path21.join(os16.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path21.join(os16.homedir(), "Library", "Logs", "adhdev") : path21.join(os16.homedir(), ".local", "share", "adhdev", "logs");
24228
24459
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
24229
24460
  var MAX_DAYS = 7;
24230
24461
  try {
24231
- fs8.mkdirSync(LOG_DIR2, { recursive: true });
24462
+ fs9.mkdirSync(LOG_DIR2, { recursive: true });
24232
24463
  } catch {
24233
24464
  }
24234
24465
  var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
@@ -24274,7 +24505,7 @@ function checkRotation() {
24274
24505
  }
24275
24506
  function cleanOldFiles() {
24276
24507
  try {
24277
- const files = fs8.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
24508
+ const files = fs9.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
24278
24509
  const cutoff = /* @__PURE__ */ new Date();
24279
24510
  cutoff.setDate(cutoff.getDate() - MAX_DAYS);
24280
24511
  const cutoffStr = cutoff.toISOString().slice(0, 10);
@@ -24282,7 +24513,7 @@ function cleanOldFiles() {
24282
24513
  const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
24283
24514
  if (dateMatch && dateMatch[1] < cutoffStr) {
24284
24515
  try {
24285
- fs8.unlinkSync(path21.join(LOG_DIR2, file));
24516
+ fs9.unlinkSync(path21.join(LOG_DIR2, file));
24286
24517
  } catch {
24287
24518
  }
24288
24519
  }
@@ -24292,14 +24523,14 @@ function cleanOldFiles() {
24292
24523
  }
24293
24524
  function checkSize() {
24294
24525
  try {
24295
- const stat2 = fs8.statSync(currentFile);
24526
+ const stat2 = fs9.statSync(currentFile);
24296
24527
  if (stat2.size > MAX_FILE_SIZE) {
24297
24528
  const backup = currentFile.replace(".jsonl", ".1.jsonl");
24298
24529
  try {
24299
- fs8.unlinkSync(backup);
24530
+ fs9.unlinkSync(backup);
24300
24531
  } catch {
24301
24532
  }
24302
- fs8.renameSync(currentFile, backup);
24533
+ fs9.renameSync(currentFile, backup);
24303
24534
  }
24304
24535
  } catch {
24305
24536
  }
@@ -24332,14 +24563,14 @@ function logCommand(entry) {
24332
24563
  ...entry.error ? { err: entry.error } : {},
24333
24564
  ...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
24334
24565
  });
24335
- fs8.appendFileSync(currentFile, line + "\n");
24566
+ fs9.appendFileSync(currentFile, line + "\n");
24336
24567
  } catch {
24337
24568
  }
24338
24569
  }
24339
24570
  function getRecentCommands(count = 50) {
24340
24571
  try {
24341
- if (!fs8.existsSync(currentFile)) return [];
24342
- const content = fs8.readFileSync(currentFile, "utf-8");
24572
+ if (!fs9.existsSync(currentFile)) return [];
24573
+ const content = fs9.readFileSync(currentFile, "utf-8");
24343
24574
  const lines = content.trim().split("\n").filter(Boolean);
24344
24575
  return lines.slice(-count).map((line) => {
24345
24576
  try {
@@ -24369,14 +24600,11 @@ var yaml2 = __toESM(require("js-yaml"));
24369
24600
  init_logger();
24370
24601
 
24371
24602
  // src/commands/mesh-coordinator.ts
24372
- var import_node_child_process3 = require("child_process");
24373
24603
  var import_node_crypto2 = require("crypto");
24374
- var import_node_fs3 = require("fs");
24375
- var import_node_module2 = require("module");
24376
24604
  var os17 = __toESM(require("os"));
24377
24605
  var import_node_path = require("path");
24378
24606
  var DEFAULT_SERVER_NAME = "adhdev-mesh";
24379
- var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev-mcp";
24607
+ var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev";
24380
24608
  var HERMES_CLI_TYPE = "hermes-cli";
24381
24609
  var HERMES_MCP_CONFIG_PATH = "~/.hermes/config.yaml";
24382
24610
  function isHermesProvider(provider, cliType) {
@@ -24386,8 +24614,7 @@ function isHermesProvider(provider, cliType) {
24386
24614
  function resolveHermesMeshCoordinatorSetup(options) {
24387
24615
  const mcpServer = resolveAdhdevMcpServerLaunch({
24388
24616
  meshId: options.meshId,
24389
- nodeExecutable: options.nodeExecutable,
24390
- adhdevMcpEntryPath: options.adhdevMcpEntryPath,
24617
+ adhdevMcpCommand: options.adhdevMcpCommand,
24391
24618
  adhdevMcpTransport: options.adhdevMcpTransport,
24392
24619
  adhdevMcpPort: options.adhdevMcpPort
24393
24620
  });
@@ -24418,7 +24645,7 @@ function createHermesManualMeshCoordinatorSetup(meshId, workspace) {
24418
24645
  requiresRestart: true,
24419
24646
  instructions: "Hermes CLI does not auto-import repo-local .mcp.json. Add this MCP server to Hermes config under mcp_servers, then start a fresh Hermes session.",
24420
24647
  template: renderMeshCoordinatorTemplate(
24421
- "mcp_servers:\n {{serverName}}:\n command: {{adhdevMcpCommand}}\n args:\n - --repo-mesh\n - {{meshId}}\n enabled: true\n",
24648
+ "mcp_servers:\n {{serverName}}:\n command: {{adhdevMcpCommand}}\n args:\n - mcp\n - --mode\n - ipc\n - --repo-mesh\n - {{meshId}}\n enabled: true\n",
24422
24649
  {
24423
24650
  meshId,
24424
24651
  workspace,
@@ -24455,8 +24682,7 @@ function resolveMeshCoordinatorSetup(options) {
24455
24682
  }
24456
24683
  const mcpServer = resolveAdhdevMcpServerLaunch({
24457
24684
  meshId,
24458
- nodeExecutable: options.nodeExecutable,
24459
- adhdevMcpEntryPath: options.adhdevMcpEntryPath,
24685
+ adhdevMcpCommand: options.adhdevMcpCommand,
24460
24686
  adhdevMcpTransport: options.adhdevMcpTransport,
24461
24687
  adhdevMcpPort: options.adhdevMcpPort
24462
24688
  });
@@ -24528,19 +24754,19 @@ function resolveMcpConfigPath(configPath, workspace) {
24528
24754
  return (0, import_node_path.join)(workspace, trimmed);
24529
24755
  }
24530
24756
  function resolveAdhdevMcpServerLaunch(options) {
24531
- const entryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
24532
- if (!entryPath) return null;
24533
- const nodeExecutable = resolveMcpNodeExecutable(options.nodeExecutable);
24534
- if (!nodeExecutable) return null;
24757
+ const command = resolveAdhdevCommand(options.adhdevMcpCommand);
24535
24758
  const transport = resolveMcpTransport(options.adhdevMcpTransport);
24536
- const args = [entryPath, "--mode", transport, "--repo-mesh", options.meshId];
24759
+ const args = ["mcp", "--mode", transport, "--repo-mesh", options.meshId];
24537
24760
  const port = resolveMcpPort(options.adhdevMcpPort);
24538
24761
  if (port !== void 0) args.push("--port", String(port));
24539
24762
  return {
24540
- command: nodeExecutable,
24763
+ command,
24541
24764
  args
24542
24765
  };
24543
24766
  }
24767
+ function resolveAdhdevCommand(explicitCommand) {
24768
+ return explicitCommand?.trim() || process.env.ADHDEV_COORDINATOR_MCP_COMMAND?.trim() || DEFAULT_ADHDEV_MCP_COMMAND;
24769
+ }
24544
24770
  function resolveMcpTransport(explicitTransport) {
24545
24771
  if (explicitTransport === "local" || explicitTransport === "ipc") return explicitTransport;
24546
24772
  const envTransport = process.env.ADHDEV_COORDINATOR_MCP_TRANSPORT?.trim();
@@ -24553,109 +24779,6 @@ function resolveMcpPort(explicitPort) {
24553
24779
  const parsed = Number(raw);
24554
24780
  return Number.isInteger(parsed) && parsed > 0 ? parsed : void 0;
24555
24781
  }
24556
- function resolveMcpNodeExecutable(explicitExecutable) {
24557
- const explicit = explicitExecutable?.trim();
24558
- if (explicit) return explicit;
24559
- const candidates = [];
24560
- const addCandidate = (candidate) => {
24561
- const trimmed = candidate?.trim();
24562
- if (!trimmed) return;
24563
- const normalized = normalizeExistingPath(trimmed) || trimmed;
24564
- if (!candidates.includes(normalized)) candidates.push(normalized);
24565
- };
24566
- addCandidate(process.env.ADHDEV_MCP_NODE_EXECUTABLE);
24567
- addCandidate(process.env.ADHDEV_NODE_EXECUTABLE);
24568
- addCandidate(process.env.npm_node_execpath);
24569
- addNodeCandidatesFromPath(process.env.PATH, addCandidate);
24570
- addNodeCandidatesFromNvm(os17.homedir(), addCandidate);
24571
- addCandidate("/opt/homebrew/bin/node");
24572
- addCandidate("/usr/local/bin/node");
24573
- addCandidate("/usr/bin/node");
24574
- addCandidate(process.execPath);
24575
- for (const candidate of candidates) {
24576
- if (nodeRuntimeSupportsWebSocket(candidate)) return candidate;
24577
- }
24578
- return null;
24579
- }
24580
- function addNodeCandidatesFromPath(pathValue, addCandidate) {
24581
- for (const entry of (pathValue || "").split(":")) {
24582
- const dir = entry.trim();
24583
- if (!dir) continue;
24584
- addCandidate((0, import_node_path.join)(dir, "node"));
24585
- }
24586
- }
24587
- function addNodeCandidatesFromNvm(homeDir, addCandidate) {
24588
- const versionsDir = (0, import_node_path.join)(homeDir, ".nvm", "versions", "node");
24589
- try {
24590
- const versionDirs = (0, import_node_fs3.readdirSync)(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
24591
- for (const versionDir of versionDirs) {
24592
- addCandidate((0, import_node_path.join)(versionsDir, versionDir, "bin", "node"));
24593
- }
24594
- } catch {
24595
- }
24596
- }
24597
- function compareNodeVersionNamesDescending(a, b) {
24598
- const parse = (value) => value.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10) || 0);
24599
- const left = parse(a);
24600
- const right = parse(b);
24601
- for (let i = 0; i < Math.max(left.length, right.length); i++) {
24602
- const diff = (right[i] || 0) - (left[i] || 0);
24603
- if (diff !== 0) return diff;
24604
- }
24605
- return b.localeCompare(a);
24606
- }
24607
- function nodeRuntimeSupportsWebSocket(nodeExecutable) {
24608
- try {
24609
- (0, import_node_child_process3.execFileSync)(nodeExecutable, ["-e", "process.exit(typeof WebSocket === 'function' ? 0 : 42)"], {
24610
- stdio: "ignore",
24611
- timeout: 3e3
24612
- });
24613
- return true;
24614
- } catch {
24615
- return false;
24616
- }
24617
- }
24618
- function resolveAdhdevMcpEntryPath(explicitPath) {
24619
- const explicit = explicitPath?.trim();
24620
- if (explicit) return normalizeExistingPath(explicit) || explicit;
24621
- const envPath = process.env.ADHDEV_MCP_SERVER_PATH?.trim();
24622
- if (envPath) return normalizeExistingPath(envPath) || envPath;
24623
- const candidates = [];
24624
- const addCandidate = (candidate) => {
24625
- if (!candidates.includes(candidate)) candidates.push(candidate);
24626
- };
24627
- const addPackagedCandidates = (baseFile) => {
24628
- if (!baseFile) return;
24629
- const realBase = normalizeExistingPath(baseFile) || baseFile;
24630
- const dir = (0, import_node_path.dirname)(realBase);
24631
- addCandidate((0, import_node_path.resolve)(dir, "../vendor/mcp-server/index.js"));
24632
- addCandidate((0, import_node_path.resolve)(dir, "../../vendor/mcp-server/index.js"));
24633
- addCandidate((0, import_node_path.resolve)(dir, "../../../vendor/mcp-server/index.js"));
24634
- addCandidate((0, import_node_path.resolve)(dir, "../../mcp-server/dist/index.js"));
24635
- addCandidate((0, import_node_path.resolve)(dir, "../../../mcp-server/dist/index.js"));
24636
- };
24637
- addPackagedCandidates(process.argv[1]);
24638
- for (const candidate of candidates) {
24639
- const normalized = normalizeExistingPath(candidate);
24640
- if (normalized) return normalized;
24641
- }
24642
- try {
24643
- const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : (0, import_node_path.join)(process.cwd(), "adhdev-daemon.js");
24644
- const req = (0, import_node_module2.createRequire)(requireBase);
24645
- const resolvedModule = req.resolve("@adhdev/mcp-server");
24646
- return normalizeExistingPath(resolvedModule) || resolvedModule;
24647
- } catch {
24648
- return null;
24649
- }
24650
- }
24651
- function normalizeExistingPath(filePath) {
24652
- try {
24653
- if (!(0, import_node_fs3.existsSync)(filePath)) return null;
24654
- return import_node_fs3.realpathSync.native(filePath);
24655
- } catch {
24656
- return null;
24657
- }
24658
- }
24659
24782
 
24660
24783
  // src/commands/router.ts
24661
24784
  init_mesh_events();
@@ -24975,23 +25098,23 @@ function buildStatusSnapshot(options) {
24975
25098
  }
24976
25099
 
24977
25100
  // src/commands/upgrade-helper.ts
25101
+ var import_child_process7 = require("child_process");
24978
25102
  var import_child_process8 = require("child_process");
24979
- var import_child_process9 = require("child_process");
24980
- var fs9 = __toESM(require("fs"));
25103
+ var fs10 = __toESM(require("fs"));
24981
25104
  var os19 = __toESM(require("os"));
24982
25105
  var path22 = __toESM(require("path"));
24983
25106
  var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
24984
25107
  function getUpgradeLogPath() {
24985
25108
  const home = os19.homedir();
24986
25109
  const dir = path22.join(home, ".adhdev");
24987
- fs9.mkdirSync(dir, { recursive: true });
25110
+ fs10.mkdirSync(dir, { recursive: true });
24988
25111
  return path22.join(dir, "daemon-upgrade.log");
24989
25112
  }
24990
25113
  function appendUpgradeLog(message) {
24991
25114
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
24992
25115
  `;
24993
25116
  try {
24994
- fs9.appendFileSync(getUpgradeLogPath(), line, "utf8");
25117
+ fs10.appendFileSync(getUpgradeLogPath(), line, "utf8");
24995
25118
  } catch {
24996
25119
  }
24997
25120
  }
@@ -24999,12 +25122,12 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
24999
25122
  const binDir = path22.dirname(nodeExecutable);
25000
25123
  if (platform10 === "win32") {
25001
25124
  const npmCliPath = path22.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
25002
- if (fs9.existsSync(npmCliPath)) {
25125
+ if (fs10.existsSync(npmCliPath)) {
25003
25126
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
25004
25127
  }
25005
25128
  for (const candidate of ["npm.exe", "npm"]) {
25006
25129
  const candidatePath = path22.join(binDir, candidate);
25007
- if (fs9.existsSync(candidatePath)) {
25130
+ if (fs10.existsSync(candidatePath)) {
25008
25131
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
25009
25132
  }
25010
25133
  }
@@ -25012,7 +25135,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
25012
25135
  }
25013
25136
  for (const candidate of ["npm"]) {
25014
25137
  const candidatePath = path22.join(binDir, candidate);
25015
- if (fs9.existsSync(candidatePath)) {
25138
+ if (fs10.existsSync(candidatePath)) {
25016
25139
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
25017
25140
  }
25018
25141
  }
@@ -25022,12 +25145,12 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
25022
25145
  if (!currentCliPath) return null;
25023
25146
  let resolvedPath = currentCliPath;
25024
25147
  try {
25025
- resolvedPath = fs9.realpathSync.native(currentCliPath);
25148
+ resolvedPath = fs10.realpathSync.native(currentCliPath);
25026
25149
  } catch {
25027
25150
  }
25028
25151
  let currentDir = resolvedPath;
25029
25152
  try {
25030
- if (fs9.statSync(resolvedPath).isFile()) {
25153
+ if (fs10.statSync(resolvedPath).isFile()) {
25031
25154
  currentDir = path22.dirname(resolvedPath);
25032
25155
  }
25033
25156
  } catch {
@@ -25036,8 +25159,8 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
25036
25159
  while (true) {
25037
25160
  const packageJsonPath = path22.join(currentDir, "package.json");
25038
25161
  try {
25039
- if (fs9.existsSync(packageJsonPath)) {
25040
- const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
25162
+ if (fs10.existsSync(packageJsonPath)) {
25163
+ const parsed = JSON.parse(fs10.readFileSync(packageJsonPath, "utf8"));
25041
25164
  if (parsed?.name === packageName) {
25042
25165
  const normalized = currentDir.replace(/\\/g, "/");
25043
25166
  return normalized.includes("/node_modules/") ? currentDir : null;
@@ -25095,7 +25218,7 @@ function getNpmExecOptions(platform10 = process.platform) {
25095
25218
  }
25096
25219
  function execNpmCommandSync(args, options = {}, surface) {
25097
25220
  const execOptions = surface?.execOptions || getNpmExecOptions();
25098
- return (0, import_child_process8.execFileSync)(
25221
+ return (0, import_child_process7.execFileSync)(
25099
25222
  surface?.npmExecutable || "npm",
25100
25223
  [...surface?.npmArgsPrefix || [], ...args],
25101
25224
  {
@@ -25108,7 +25231,7 @@ function execNpmCommandSync(args, options = {}, surface) {
25108
25231
  function killPid(pid) {
25109
25232
  try {
25110
25233
  if (process.platform === "win32") {
25111
- (0, import_child_process8.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
25234
+ (0, import_child_process7.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
25112
25235
  } else {
25113
25236
  process.kill(pid, "SIGTERM");
25114
25237
  }
@@ -25120,7 +25243,7 @@ function killPid(pid) {
25120
25243
  function getWindowsProcessCommandLine(pid) {
25121
25244
  const pidFilter = `ProcessId=${pid}`;
25122
25245
  try {
25123
- const psOut = (0, import_child_process8.execFileSync)("powershell.exe", [
25246
+ const psOut = (0, import_child_process7.execFileSync)("powershell.exe", [
25124
25247
  "-NoProfile",
25125
25248
  "-NonInteractive",
25126
25249
  "-ExecutionPolicy",
@@ -25132,7 +25255,7 @@ function getWindowsProcessCommandLine(pid) {
25132
25255
  } catch {
25133
25256
  }
25134
25257
  try {
25135
- const wmicOut = (0, import_child_process8.execFileSync)("wmic", [
25258
+ const wmicOut = (0, import_child_process7.execFileSync)("wmic", [
25136
25259
  "process",
25137
25260
  "where",
25138
25261
  pidFilter,
@@ -25148,7 +25271,7 @@ function getProcessCommandLine(pid) {
25148
25271
  if (!Number.isFinite(pid) || pid <= 0) return null;
25149
25272
  if (process.platform === "win32") return getWindowsProcessCommandLine(pid);
25150
25273
  try {
25151
- const text = (0, import_child_process8.execFileSync)("ps", ["-o", "command=", "-p", String(pid)], {
25274
+ const text = (0, import_child_process7.execFileSync)("ps", ["-o", "command=", "-p", String(pid)], {
25152
25275
  encoding: "utf8",
25153
25276
  timeout: 3e3,
25154
25277
  stdio: ["ignore", "pipe", "ignore"]
@@ -25176,8 +25299,8 @@ async function waitForPidExit(pid, timeoutMs) {
25176
25299
  function stopSessionHostProcesses(appName) {
25177
25300
  const pidFile = path22.join(os19.homedir(), ".adhdev", `${appName}-session-host.pid`);
25178
25301
  try {
25179
- if (fs9.existsSync(pidFile)) {
25180
- const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
25302
+ if (fs10.existsSync(pidFile)) {
25303
+ const pid = Number.parseInt(fs10.readFileSync(pidFile, "utf8").trim(), 10);
25181
25304
  if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
25182
25305
  killPid(pid);
25183
25306
  }
@@ -25185,7 +25308,7 @@ function stopSessionHostProcesses(appName) {
25185
25308
  } catch {
25186
25309
  } finally {
25187
25310
  try {
25188
- fs9.unlinkSync(pidFile);
25311
+ fs10.unlinkSync(pidFile);
25189
25312
  } catch {
25190
25313
  }
25191
25314
  }
@@ -25193,7 +25316,7 @@ function stopSessionHostProcesses(appName) {
25193
25316
  function removeDaemonPidFile() {
25194
25317
  const pidFile = path22.join(os19.homedir(), ".adhdev", "daemon.pid");
25195
25318
  try {
25196
- fs9.unlinkSync(pidFile);
25319
+ fs10.unlinkSync(pidFile);
25197
25320
  } catch {
25198
25321
  }
25199
25322
  }
@@ -25211,30 +25334,30 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
25211
25334
  if (pkgName.startsWith("@")) {
25212
25335
  const [scope, name] = pkgName.split("/");
25213
25336
  const scopeDir = path22.join(npmRoot, scope);
25214
- if (!fs9.existsSync(scopeDir)) return;
25215
- for (const entry of fs9.readdirSync(scopeDir)) {
25337
+ if (!fs10.existsSync(scopeDir)) return;
25338
+ for (const entry of fs10.readdirSync(scopeDir)) {
25216
25339
  if (!entry.startsWith(`.${name}-`)) continue;
25217
- fs9.rmSync(path22.join(scopeDir, entry), { recursive: true, force: true });
25340
+ fs10.rmSync(path22.join(scopeDir, entry), { recursive: true, force: true });
25218
25341
  appendUpgradeLog(`Removed stale scoped staging dir: ${path22.join(scopeDir, entry)}`);
25219
25342
  }
25220
25343
  } else {
25221
- for (const entry of fs9.readdirSync(npmRoot)) {
25344
+ for (const entry of fs10.readdirSync(npmRoot)) {
25222
25345
  if (!entry.startsWith(`.${pkgName}-`)) continue;
25223
- fs9.rmSync(path22.join(npmRoot, entry), { recursive: true, force: true });
25346
+ fs10.rmSync(path22.join(npmRoot, entry), { recursive: true, force: true });
25224
25347
  appendUpgradeLog(`Removed stale staging dir: ${path22.join(npmRoot, entry)}`);
25225
25348
  }
25226
25349
  }
25227
- if (fs9.existsSync(binDir)) {
25228
- for (const entry of fs9.readdirSync(binDir)) {
25350
+ if (fs10.existsSync(binDir)) {
25351
+ for (const entry of fs10.readdirSync(binDir)) {
25229
25352
  if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
25230
- fs9.rmSync(path22.join(binDir, entry), { recursive: true, force: true });
25353
+ fs10.rmSync(path22.join(binDir, entry), { recursive: true, force: true });
25231
25354
  appendUpgradeLog(`Removed stale bin staging entry: ${path22.join(binDir, entry)}`);
25232
25355
  }
25233
25356
  }
25234
25357
  }
25235
25358
  function spawnDetachedDaemonUpgradeHelper(payload) {
25236
25359
  const env = { ...process.env, [UPGRADE_HELPER_ENV]: JSON.stringify(payload) };
25237
- const child = (0, import_child_process9.spawn)(process.execPath, process.argv.slice(1), {
25360
+ const child = (0, import_child_process8.spawn)(process.execPath, process.argv.slice(1), {
25238
25361
  detached: true,
25239
25362
  stdio: "ignore",
25240
25363
  windowsHide: true,
@@ -25264,7 +25387,7 @@ async function runDaemonUpgradeHelper(payload) {
25264
25387
  cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
25265
25388
  const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
25266
25389
  appendUpgradeLog(`Installing ${spec}`);
25267
- const installOutput = (0, import_child_process8.execFileSync)(
25390
+ const installOutput = (0, import_child_process7.execFileSync)(
25268
25391
  installCommand.command,
25269
25392
  installCommand.args,
25270
25393
  {
@@ -25286,7 +25409,7 @@ async function runDaemonUpgradeHelper(payload) {
25286
25409
  const env = { ...process.env };
25287
25410
  delete env[UPGRADE_HELPER_ENV];
25288
25411
  appendUpgradeLog(`Restarting daemon with args: ${restartArgv.join(" ")}`);
25289
- const child = (0, import_child_process9.spawn)(process.execPath, restartArgv, {
25412
+ const child = (0, import_child_process8.spawn)(process.execPath, restartArgv, {
25290
25413
  detached: true,
25291
25414
  stdio: "ignore",
25292
25415
  windowsHide: true,
@@ -25313,9 +25436,10 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
25313
25436
  }
25314
25437
 
25315
25438
  // src/commands/router.ts
25439
+ init_mesh_work_queue();
25316
25440
  var import_os3 = require("os");
25317
25441
  var import_path8 = require("path");
25318
- var fs10 = __toESM(require("fs"));
25442
+ var fs11 = __toESM(require("fs"));
25319
25443
  var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
25320
25444
  var CHANNEL_SERVER_URL = {
25321
25445
  stable: "https://api.adhf.dev",
@@ -25959,7 +26083,7 @@ async function hydrateInlineMeshDirectTruth(args) {
25959
26083
  if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
25960
26084
  continue;
25961
26085
  }
25962
- if (fs10.existsSync(workspace)) {
26086
+ if (fs11.existsSync(workspace)) {
25963
26087
  try {
25964
26088
  const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
25965
26089
  if (localGit?.isGitRepo) {
@@ -26126,14 +26250,14 @@ function recordMeshRefineStage(stages, stage, status, startedAt, details) {
26126
26250
  });
26127
26251
  }
26128
26252
  async function computeGitPatchId(cwd, fromRef, toRef) {
26129
- const { execFileSync: execFileSync4 } = await import("child_process");
26130
- const diff = execFileSync4("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
26253
+ const { execFileSync: execFileSync3 } = await import("child_process");
26254
+ const diff = execFileSync3("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
26131
26255
  cwd,
26132
26256
  encoding: "utf8",
26133
26257
  maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
26134
26258
  });
26135
26259
  if (!diff.trim()) return "";
26136
- const patchId = execFileSync4("git", ["patch-id", "--stable"], {
26260
+ const patchId = execFileSync3("git", ["patch-id", "--stable"], {
26137
26261
  cwd,
26138
26262
  input: diff,
26139
26263
  encoding: "utf8",
@@ -26144,8 +26268,8 @@ async function computeGitPatchId(cwd, fromRef, toRef) {
26144
26268
  async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead) {
26145
26269
  const startedAt = Date.now();
26146
26270
  try {
26147
- const { execFileSync: execFileSync4 } = await import("child_process");
26148
- const git = (args) => execFileSync4("git", args, {
26271
+ const { execFileSync: execFileSync3 } = await import("child_process");
26272
+ const git = (args) => execFileSync3("git", args, {
26149
26273
  cwd: repoRoot,
26150
26274
  encoding: "utf8",
26151
26275
  maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
@@ -26198,8 +26322,8 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree) {
26198
26322
  const entries = [];
26199
26323
  try {
26200
26324
  const { execFile: execFile3 } = await import("child_process");
26201
- const { promisify: promisify3 } = await import("util");
26202
- const execFileAsync3 = promisify3(execFile3);
26325
+ const { promisify: promisify6 } = await import("util");
26326
+ const execFileAsync3 = promisify6(execFile3);
26203
26327
  const runGit2 = async (cwd, args) => {
26204
26328
  const { stdout } = await execFileAsync3("git", args, {
26205
26329
  cwd,
@@ -26223,7 +26347,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree) {
26223
26347
  reachable: false
26224
26348
  };
26225
26349
  try {
26226
- if (!fs10.existsSync(submodulePath)) {
26350
+ if (!fs11.existsSync(submodulePath)) {
26227
26351
  entry.error = `Submodule checkout missing at ${gitlink.path}`;
26228
26352
  entries.push(entry);
26229
26353
  continue;
@@ -26289,8 +26413,8 @@ function buildMeshRefineValidationPlan(mesh, workspace) {
26289
26413
  }
26290
26414
  async function runMeshRefineValidationGate(mesh, workspace) {
26291
26415
  const { execFile: execFile3 } = await import("child_process");
26292
- const { promisify: promisify3 } = await import("util");
26293
- const execFileAsync3 = promisify3(execFile3);
26416
+ const { promisify: promisify6 } = await import("util");
26417
+ const execFileAsync3 = promisify6(execFile3);
26294
26418
  const selection = resolveMeshRefineValidationPlan(mesh, workspace);
26295
26419
  const summary = {
26296
26420
  status: "skipped",
@@ -26380,9 +26504,9 @@ function resolveHermesUserHome() {
26380
26504
  function loadHermesCoordinatorBaseConfig(targetConfigPath) {
26381
26505
  const sourceHome = resolveHermesUserHome();
26382
26506
  const sourceConfigPath = (0, import_path8.join)(sourceHome, "config.yaml");
26383
- if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
26507
+ if (!fs11.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
26384
26508
  if ((0, import_path8.resolve)(sourceConfigPath) === (0, import_path8.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
26385
- const parsed = parseMeshCoordinatorMcpConfig(fs10.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
26509
+ const parsed = parseMeshCoordinatorMcpConfig(fs11.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
26386
26510
  const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
26387
26511
  return { config: baseConfig, sourceHome, sourceConfigPath };
26388
26512
  }
@@ -26419,9 +26543,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
26419
26543
  for (const fileName of [".env", "auth.json"]) {
26420
26544
  const sourcePath = (0, import_path8.join)(sourceHome, fileName);
26421
26545
  const targetPath = (0, import_path8.join)(targetHome, fileName);
26422
- if (!fs10.existsSync(sourcePath)) continue;
26546
+ if (!fs11.existsSync(sourcePath)) continue;
26423
26547
  try {
26424
- fs10.copyFileSync(sourcePath, targetPath);
26548
+ fs11.copyFileSync(sourcePath, targetPath);
26425
26549
  } catch (error) {
26426
26550
  LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
26427
26551
  }
@@ -26634,6 +26758,7 @@ var DaemonCommandRouter = class {
26634
26758
  getCachedAggregateMeshStatus(meshId, mesh, options) {
26635
26759
  const cached = this.aggregateMeshStatusCache.get(meshId);
26636
26760
  if (!cached?.snapshot || cached.snapshot.success !== true || !Array.isArray(cached.snapshot.nodes)) return null;
26761
+ if (cached.queueRevision !== getMeshQueueRevision(meshId)) return null;
26637
26762
  let snapshot = this.cloneJsonValue(cached.snapshot);
26638
26763
  snapshot = this.hydrateCachedAggregateMeshStatusFromInline(snapshot, mesh, options);
26639
26764
  if (shouldRefreshStalePendingAggregate(snapshot, options)) return null;
@@ -26671,7 +26796,7 @@ var DaemonCommandRouter = class {
26671
26796
  returnedAt: new Date(builtAt).toISOString()
26672
26797
  }
26673
26798
  };
26674
- this.aggregateMeshStatusCache.set(meshId, { builtAt, snapshot: this.cloneJsonValue(next) });
26799
+ this.aggregateMeshStatusCache.set(meshId, { builtAt, snapshot: this.cloneJsonValue(next), queueRevision: getMeshQueueRevision(meshId) });
26675
26800
  return next;
26676
26801
  }
26677
26802
  getCachedInlineMesh(meshId, inlineMesh) {
@@ -26774,13 +26899,13 @@ var DaemonCommandRouter = class {
26774
26899
  recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
26775
26900
  };
26776
26901
  }
26777
- const worktreeExists = fs10.existsSync(workspace);
26902
+ const worktreeExists = fs11.existsSync(workspace);
26778
26903
  const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => n.id === args.node.clonedFromNodeId || n.nodeId === args.node.clonedFromNodeId) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
26779
26904
  const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
26780
26905
  if (!worktreeExists) {
26781
26906
  return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
26782
26907
  }
26783
- if (!repoRoot || !fs10.existsSync(repoRoot)) {
26908
+ if (!repoRoot || !fs11.existsSync(repoRoot)) {
26784
26909
  return {
26785
26910
  success: false,
26786
26911
  code: "mesh_worktree_cleanup_missing_source_repo",
@@ -26800,7 +26925,7 @@ var DaemonCommandRouter = class {
26800
26925
  const normalizePath = (value) => {
26801
26926
  const resolved = (0, import_path8.resolve)(value);
26802
26927
  try {
26803
- return fs10.realpathSync(resolved);
26928
+ return fs11.realpathSync(resolved);
26804
26929
  } catch {
26805
26930
  return resolved;
26806
26931
  }
@@ -26873,8 +26998,8 @@ var DaemonCommandRouter = class {
26873
26998
  return { allow: true, status: metadataStatus, source: "node_branch_convergence" };
26874
26999
  }
26875
27000
  const { execFile: execFile3 } = await import("child_process");
26876
- const { promisify: promisify3 } = await import("util");
26877
- const execFileAsync3 = promisify3(execFile3);
27001
+ const { promisify: promisify6 } = await import("util");
27002
+ const execFileAsync3 = promisify6(execFile3);
26878
27003
  const runGit2 = async (gitArgs, cwd) => {
26879
27004
  const { stdout } = await execFileAsync3("git", gitArgs, {
26880
27005
  cwd,
@@ -27284,8 +27409,8 @@ var DaemonCommandRouter = class {
27284
27409
  const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
27285
27410
  if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
27286
27411
  const { execFile: execFile3 } = await import("child_process");
27287
- const { promisify: promisify3 } = await import("util");
27288
- const execFileAsync3 = promisify3(execFile3);
27412
+ const { promisify: promisify6 } = await import("util");
27413
+ const execFileAsync3 = promisify6(execFile3);
27289
27414
  const resolveStarted = Date.now();
27290
27415
  const { stdout: branchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
27291
27416
  const branch = branchStdout.trim();
@@ -27594,8 +27719,8 @@ var DaemonCommandRouter = class {
27594
27719
  if (sinceTs > 0) {
27595
27720
  return { success: true, logs: [], totalBuffered: 0 };
27596
27721
  }
27597
- if (fs10.existsSync(LOG_PATH)) {
27598
- const content = fs10.readFileSync(LOG_PATH, "utf-8");
27722
+ if (fs11.existsSync(LOG_PATH)) {
27723
+ const content = fs11.readFileSync(LOG_PATH, "utf-8");
27599
27724
  const allLines = content.split("\n");
27600
27725
  const recent = allLines.slice(-count).join("\n");
27601
27726
  return { success: true, logs: recent, totalLines: allLines.length };
@@ -29018,7 +29143,7 @@ ${block2}`);
29018
29143
  workspace
29019
29144
  };
29020
29145
  }
29021
- const { existsSync: existsSync27, readFileSync: readFileSync19, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
29146
+ const { existsSync: existsSync26, readFileSync: readFileSync19, writeFileSync: writeFileSync14, copyFileSync: copyFileSync4, mkdirSync: mkdirSync18 } = await import("fs");
29022
29147
  const { dirname: dirname9 } = await import("path");
29023
29148
  const mcpConfigPath = coordinatorSetup.configPath;
29024
29149
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -29054,14 +29179,14 @@ ${block2}`);
29054
29179
  };
29055
29180
  }
29056
29181
  try {
29057
- mkdirSync17(dirname9(mcpConfigPath), { recursive: true });
29182
+ mkdirSync18(dirname9(mcpConfigPath), { recursive: true });
29058
29183
  } catch (error) {
29059
29184
  const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
29060
29185
  LOG.error("MeshCoordinator", message);
29061
29186
  if (hermesManualFallback) return returnManualFallback(message);
29062
29187
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
29063
29188
  }
29064
- const hadExistingMcpConfig = existsSync27(mcpConfigPath);
29189
+ const hadExistingMcpConfig = existsSync26(mcpConfigPath);
29065
29190
  let existingMcpConfig = hermesBaseConfig?.config || {};
29066
29191
  if (hermesBaseConfig) {
29067
29192
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
@@ -29091,7 +29216,7 @@ ${block2}`);
29091
29216
  }
29092
29217
  };
29093
29218
  try {
29094
- writeFileSync15(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
29219
+ writeFileSync14(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
29095
29220
  } catch (error) {
29096
29221
  const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
29097
29222
  LOG.error("MeshCoordinator", message);
@@ -29319,7 +29444,7 @@ ${block2}`);
29319
29444
  }
29320
29445
  }
29321
29446
  if (workspace) {
29322
- if (!fs10.existsSync(workspace)) {
29447
+ if (!fs11.existsSync(workspace)) {
29323
29448
  const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
29324
29449
  let remoteProbeApplied = false;
29325
29450
  if (inlineTransitGit) {
@@ -29528,7 +29653,7 @@ ${block2}`);
29528
29653
  }
29529
29654
  }
29530
29655
  if (killProcess) {
29531
- const running = isIdeRunning(ideType);
29656
+ const running = await isIdeRunning(ideType);
29532
29657
  if (running) {
29533
29658
  LOG.info("StopIDE", `Killing IDE process: ${ideType}`);
29534
29659
  const killed = await killIdeProcess(ideType);
@@ -29554,6 +29679,8 @@ var DaemonStatusReporter = class {
29554
29679
  lastStatusSentAt = 0;
29555
29680
  statusPendingThrottle = false;
29556
29681
  lastP2PStatusHash = "";
29682
+ lastP2PStatusSentAt = 0;
29683
+ p2pDebounceTimer = null;
29557
29684
  lastServerStatusHash = "";
29558
29685
  lastStatusSummary = "";
29559
29686
  statusTimer = null;
@@ -29805,7 +29932,18 @@ var DaemonStatusReporter = class {
29805
29932
  })() : { ...hashTarget, sessions };
29806
29933
  const h = this.simpleHash(JSON.stringify(hashPayload));
29807
29934
  if (h !== this.lastP2PStatusHash) {
29935
+ const now = Date.now();
29936
+ if (this.lastP2PStatusSentAt && now - this.lastP2PStatusSentAt < 500) {
29937
+ if (!this.p2pDebounceTimer) {
29938
+ this.p2pDebounceTimer = setTimeout(() => {
29939
+ this.p2pDebounceTimer = null;
29940
+ this.sendUnifiedStatusReport({ reason: "p2p_debounce" });
29941
+ }, 500);
29942
+ }
29943
+ return false;
29944
+ }
29808
29945
  this.lastP2PStatusHash = h;
29946
+ this.lastP2PStatusSentAt = now;
29809
29947
  this.deps.p2p?.sendStatus(payload);
29810
29948
  return true;
29811
29949
  }
@@ -31140,11 +31278,11 @@ var ProviderInstanceManager = class {
31140
31278
  };
31141
31279
 
31142
31280
  // src/providers/version-archive.ts
31143
- var fs11 = __toESM(require("fs"));
31281
+ var fs12 = __toESM(require("fs"));
31144
31282
  var path23 = __toESM(require("path"));
31145
31283
  var os20 = __toESM(require("os"));
31146
- var import_child_process10 = require("child_process");
31147
31284
  var import_os4 = require("os");
31285
+ var import_child_process9 = require("child_process");
31148
31286
  var ARCHIVE_PATH = path23.join(os20.homedir(), ".adhdev", "version-history.json");
31149
31287
  var MAX_ENTRIES_PER_PROVIDER = 20;
31150
31288
  var VersionArchive = class {
@@ -31154,8 +31292,8 @@ var VersionArchive = class {
31154
31292
  }
31155
31293
  load() {
31156
31294
  try {
31157
- if (fs11.existsSync(ARCHIVE_PATH)) {
31158
- this.history = JSON.parse(fs11.readFileSync(ARCHIVE_PATH, "utf-8"));
31295
+ if (fs12.existsSync(ARCHIVE_PATH)) {
31296
+ this.history = JSON.parse(fs12.readFileSync(ARCHIVE_PATH, "utf-8"));
31159
31297
  }
31160
31298
  } catch {
31161
31299
  this.history = {};
@@ -31192,27 +31330,43 @@ var VersionArchive = class {
31192
31330
  }
31193
31331
  save() {
31194
31332
  try {
31195
- fs11.mkdirSync(path23.dirname(ARCHIVE_PATH), { recursive: true });
31196
- fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
31333
+ fs12.mkdirSync(path23.dirname(ARCHIVE_PATH), { recursive: true });
31334
+ fs12.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
31197
31335
  } catch {
31198
31336
  }
31199
31337
  }
31200
31338
  };
31201
- function runCommand(cmd, timeout = 1e4) {
31202
- try {
31203
- return (0, import_child_process10.execSync)(cmd, {
31339
+ async function runCommand(cmd, timeout = 1e4) {
31340
+ return new Promise((resolve16) => {
31341
+ (0, import_child_process9.exec)(cmd, {
31204
31342
  encoding: "utf-8",
31205
- timeout,
31206
- stdio: ["pipe", "pipe", "pipe"]
31207
- }).trim();
31208
- } catch {
31209
- return null;
31210
- }
31343
+ timeout
31344
+ }, (error, stdout) => {
31345
+ if (error) return resolve16(null);
31346
+ resolve16(stdout.trim());
31347
+ });
31348
+ });
31211
31349
  }
31212
31350
  function findBinary2(name) {
31213
- const cmd = (0, import_os4.platform)() === "win32" ? `where ${name}` : `which ${name}`;
31214
- const result = runCommand(cmd, 5e3);
31215
- return result ? result.split("\n")[0] : null;
31351
+ const isWin = (0, import_os4.platform)() === "win32";
31352
+ const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
31353
+ const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
31354
+ for (const p of paths) {
31355
+ if (!p) continue;
31356
+ for (const ext of exes) {
31357
+ const fullPath = path23.join(p, name + ext);
31358
+ try {
31359
+ if (fs12.existsSync(fullPath)) {
31360
+ const stat2 = fs12.statSync(fullPath);
31361
+ if (stat2.isFile() && (isWin || stat2.mode & 73)) {
31362
+ return fullPath;
31363
+ }
31364
+ }
31365
+ } catch {
31366
+ }
31367
+ }
31368
+ }
31369
+ return null;
31216
31370
  }
31217
31371
  function parseVersion2(raw) {
31218
31372
  const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
@@ -31234,13 +31388,13 @@ function getPlatformVersionCommand(versionCommand, currentOs) {
31234
31388
  }
31235
31389
  return void 0;
31236
31390
  }
31237
- function getVersion(binary, versionCommand) {
31391
+ async function getVersion(binary, versionCommand) {
31238
31392
  if (versionCommand) {
31239
- const raw = runCommand(versionCommand);
31393
+ const raw = await runCommand(versionCommand);
31240
31394
  return raw ? parseVersion2(raw) : null;
31241
31395
  }
31242
31396
  for (const flag of ["--version", "-V", "-v"]) {
31243
- const raw = runCommand(`"${binary}" ${flag}`);
31397
+ const raw = await runCommand(`"${binary}" ${flag}`);
31244
31398
  if (raw && raw.length < 500) return parseVersion2(raw);
31245
31399
  }
31246
31400
  return null;
@@ -31250,18 +31404,18 @@ function checkPathExists2(paths) {
31250
31404
  if (p.includes("*")) {
31251
31405
  const home = os20.homedir();
31252
31406
  const resolved = p.replace(/\*/g, home.split(path23.sep).pop() || "");
31253
- if (fs11.existsSync(resolved)) return resolved;
31407
+ if (fs12.existsSync(resolved)) return resolved;
31254
31408
  } else {
31255
- if (fs11.existsSync(p)) return p;
31409
+ if (fs12.existsSync(p)) return p;
31256
31410
  }
31257
31411
  }
31258
31412
  return null;
31259
31413
  }
31260
- function getMacAppVersion(appPath) {
31414
+ async function getMacAppVersion(appPath) {
31261
31415
  if ((0, import_os4.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
31262
31416
  const plistPath = path23.join(appPath, "Contents", "Info.plist");
31263
- if (!fs11.existsSync(plistPath)) return null;
31264
- const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
31417
+ if (!fs12.existsSync(plistPath)) return null;
31418
+ const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
31265
31419
  return raw || null;
31266
31420
  }
31267
31421
  async function detectAllVersions(loader, archive) {
@@ -31286,16 +31440,16 @@ async function detectAllVersions(loader, archive) {
31286
31440
  let resolvedBin = cliBin;
31287
31441
  if (!resolvedBin && appPath && currentOs === "darwin") {
31288
31442
  const bundled = path23.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
31289
- if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
31443
+ if (provider.cli && fs12.existsSync(bundled)) resolvedBin = bundled;
31290
31444
  }
31291
31445
  info.installed = !!(appPath || resolvedBin);
31292
31446
  info.path = appPath || null;
31293
31447
  info.binary = resolvedBin || null;
31294
31448
  if (resolvedBin) {
31295
- info.version = getVersion(resolvedBin, versionCommand);
31449
+ info.version = await getVersion(resolvedBin, versionCommand);
31296
31450
  }
31297
31451
  if (!info.version && appPath) {
31298
- info.version = getMacAppVersion(appPath);
31452
+ info.version = await getMacAppVersion(appPath);
31299
31453
  }
31300
31454
  } else if (provider.category === "cli" || provider.category === "acp") {
31301
31455
  const bin = provider.binary || provider.spawn?.command || provider.cli || provider.type;
@@ -31303,7 +31457,7 @@ async function detectAllVersions(loader, archive) {
31303
31457
  info.installed = !!binPath;
31304
31458
  info.binary = binPath || null;
31305
31459
  if (binPath) {
31306
- info.version = getVersion(binPath, versionCommand);
31460
+ info.version = await getVersion(binPath, versionCommand);
31307
31461
  }
31308
31462
  } else if (provider.category === "extension") {
31309
31463
  info.installed = false;
@@ -31325,7 +31479,7 @@ async function detectAllVersions(loader, archive) {
31325
31479
 
31326
31480
  // src/daemon/dev-server.ts
31327
31481
  var http2 = __toESM(require("http"));
31328
- var fs15 = __toESM(require("fs"));
31482
+ var fs16 = __toESM(require("fs"));
31329
31483
  var path27 = __toESM(require("path"));
31330
31484
  init_config();
31331
31485
 
@@ -31676,7 +31830,7 @@ async (params) => {
31676
31830
  init_logger();
31677
31831
 
31678
31832
  // src/daemon/dev-cdp-handlers.ts
31679
- var fs12 = __toESM(require("fs"));
31833
+ var fs13 = __toESM(require("fs"));
31680
31834
  var path24 = __toESM(require("path"));
31681
31835
  init_logger();
31682
31836
  async function handleCdpEvaluate(ctx, req, res) {
@@ -31857,17 +32011,17 @@ async function handleScriptHints(ctx, type, _req, res) {
31857
32011
  }
31858
32012
  let scriptsPath = "";
31859
32013
  const directScripts = path24.join(dir, "scripts.js");
31860
- if (fs12.existsSync(directScripts)) {
32014
+ if (fs13.existsSync(directScripts)) {
31861
32015
  scriptsPath = directScripts;
31862
32016
  } else {
31863
32017
  const scriptsDir = path24.join(dir, "scripts");
31864
- if (fs12.existsSync(scriptsDir)) {
31865
- const versions = fs12.readdirSync(scriptsDir).filter((d) => {
31866
- return fs12.statSync(path24.join(scriptsDir, d)).isDirectory();
32018
+ if (fs13.existsSync(scriptsDir)) {
32019
+ const versions = fs13.readdirSync(scriptsDir).filter((d) => {
32020
+ return fs13.statSync(path24.join(scriptsDir, d)).isDirectory();
31867
32021
  }).sort().reverse();
31868
32022
  for (const ver of versions) {
31869
32023
  const p = path24.join(scriptsDir, ver, "scripts.js");
31870
- if (fs12.existsSync(p)) {
32024
+ if (fs13.existsSync(p)) {
31871
32025
  scriptsPath = p;
31872
32026
  break;
31873
32027
  }
@@ -31879,7 +32033,7 @@ async function handleScriptHints(ctx, type, _req, res) {
31879
32033
  return;
31880
32034
  }
31881
32035
  try {
31882
- const source = fs12.readFileSync(scriptsPath, "utf-8");
32036
+ const source = fs13.readFileSync(scriptsPath, "utf-8");
31883
32037
  const hints = {};
31884
32038
  const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
31885
32039
  let match;
@@ -32694,7 +32848,7 @@ async function handleDomContext(ctx, type, req, res) {
32694
32848
  }
32695
32849
 
32696
32850
  // src/daemon/dev-cli-debug.ts
32697
- var fs13 = __toESM(require("fs"));
32851
+ var fs14 = __toESM(require("fs"));
32698
32852
  var path25 = __toESM(require("path"));
32699
32853
  function slugifyFixtureName(value) {
32700
32854
  const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
@@ -32710,10 +32864,10 @@ function getCliFixtureDir(ctx, type) {
32710
32864
  function readCliFixture(ctx, type, name) {
32711
32865
  const fixtureDir = getCliFixtureDir(ctx, type);
32712
32866
  const filePath = path25.join(fixtureDir, `${name}.json`);
32713
- if (!fs13.existsSync(filePath)) {
32867
+ if (!fs14.existsSync(filePath)) {
32714
32868
  throw new Error(`Fixture not found: ${filePath}`);
32715
32869
  }
32716
- return JSON.parse(fs13.readFileSync(filePath, "utf-8"));
32870
+ return JSON.parse(fs14.readFileSync(filePath, "utf-8"));
32717
32871
  }
32718
32872
  function getExerciseTranscriptText(result) {
32719
32873
  const parts = [];
@@ -33449,7 +33603,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
33449
33603
  return;
33450
33604
  }
33451
33605
  const fixtureDir = getCliFixtureDir(ctx, type);
33452
- fs13.mkdirSync(fixtureDir, { recursive: true });
33606
+ fs14.mkdirSync(fixtureDir, { recursive: true });
33453
33607
  const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
33454
33608
  const result = await runCliExerciseInternal(ctx, { ...request, type });
33455
33609
  const fixture = {
@@ -33477,7 +33631,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
33477
33631
  notes: typeof body?.notes === "string" ? body.notes : void 0
33478
33632
  };
33479
33633
  const filePath = path25.join(fixtureDir, `${name}.json`);
33480
- fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
33634
+ fs14.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
33481
33635
  ctx.json(res, 200, {
33482
33636
  saved: true,
33483
33637
  name,
@@ -33495,14 +33649,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
33495
33649
  async function handleCliFixtureList(ctx, type, _req, res) {
33496
33650
  try {
33497
33651
  const fixtureDir = getCliFixtureDir(ctx, type);
33498
- if (!fs13.existsSync(fixtureDir)) {
33652
+ if (!fs14.existsSync(fixtureDir)) {
33499
33653
  ctx.json(res, 200, { fixtures: [], count: 0 });
33500
33654
  return;
33501
33655
  }
33502
- const fixtures = fs13.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
33656
+ const fixtures = fs14.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
33503
33657
  const fullPath = path25.join(fixtureDir, file);
33504
33658
  try {
33505
- const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
33659
+ const raw = JSON.parse(fs14.readFileSync(fullPath, "utf-8"));
33506
33660
  return {
33507
33661
  name: raw.name || file.replace(/\.json$/i, ""),
33508
33662
  path: fullPath,
@@ -33635,7 +33789,7 @@ async function handleCliRaw(ctx, req, res) {
33635
33789
  }
33636
33790
 
33637
33791
  // src/daemon/dev-auto-implement.ts
33638
- var fs14 = __toESM(require("fs"));
33792
+ var fs15 = __toESM(require("fs"));
33639
33793
  var path26 = __toESM(require("path"));
33640
33794
  var os21 = __toESM(require("os"));
33641
33795
  function getAutoImplPid(ctx) {
@@ -33683,10 +33837,10 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
33683
33837
  return fallback?.type || null;
33684
33838
  }
33685
33839
  function getLatestScriptVersionDir(scriptsDir) {
33686
- if (!fs14.existsSync(scriptsDir)) return null;
33687
- const versions = fs14.readdirSync(scriptsDir).filter((d) => {
33840
+ if (!fs15.existsSync(scriptsDir)) return null;
33841
+ const versions = fs15.readdirSync(scriptsDir).filter((d) => {
33688
33842
  try {
33689
- return fs14.statSync(path26.join(scriptsDir, d)).isDirectory();
33843
+ return fs15.statSync(path26.join(scriptsDir, d)).isDirectory();
33690
33844
  } catch {
33691
33845
  return false;
33692
33846
  }
@@ -33708,13 +33862,13 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
33708
33862
  if (!sourceDir) {
33709
33863
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
33710
33864
  }
33711
- if (!fs14.existsSync(desiredDir)) {
33712
- fs14.mkdirSync(path26.dirname(desiredDir), { recursive: true });
33713
- fs14.cpSync(sourceDir, desiredDir, { recursive: true });
33865
+ if (!fs15.existsSync(desiredDir)) {
33866
+ fs15.mkdirSync(path26.dirname(desiredDir), { recursive: true });
33867
+ fs15.cpSync(sourceDir, desiredDir, { recursive: true });
33714
33868
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
33715
33869
  }
33716
33870
  const providerJson = path26.join(desiredDir, "provider.json");
33717
- if (!fs14.existsSync(providerJson)) {
33871
+ if (!fs15.existsSync(providerJson)) {
33718
33872
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
33719
33873
  }
33720
33874
  return { dir: desiredDir };
@@ -33722,15 +33876,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
33722
33876
  function loadAutoImplReferenceScripts(ctx, referenceType) {
33723
33877
  if (!referenceType) return {};
33724
33878
  const refDir = ctx.findProviderDir(referenceType);
33725
- if (!refDir || !fs14.existsSync(refDir)) return {};
33879
+ if (!refDir || !fs15.existsSync(refDir)) return {};
33726
33880
  const referenceScripts = {};
33727
33881
  const scriptsDir = path26.join(refDir, "scripts");
33728
33882
  const latestDir = getLatestScriptVersionDir(scriptsDir);
33729
33883
  if (!latestDir) return referenceScripts;
33730
- for (const file of fs14.readdirSync(latestDir)) {
33884
+ for (const file of fs15.readdirSync(latestDir)) {
33731
33885
  if (!file.endsWith(".js")) continue;
33732
33886
  try {
33733
- referenceScripts[file] = fs14.readFileSync(path26.join(latestDir, file), "utf-8");
33887
+ referenceScripts[file] = fs15.readFileSync(path26.join(latestDir, file), "utf-8");
33734
33888
  } catch {
33735
33889
  }
33736
33890
  }
@@ -33839,15 +33993,15 @@ async function handleAutoImplement(ctx, type, req, res) {
33839
33993
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
33840
33994
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
33841
33995
  const tmpDir = path26.join(os21.tmpdir(), "adhdev-autoimpl");
33842
- if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
33996
+ if (!fs15.existsSync(tmpDir)) fs15.mkdirSync(tmpDir, { recursive: true });
33843
33997
  const promptFile = path26.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
33844
- fs14.writeFileSync(promptFile, prompt, "utf-8");
33998
+ fs15.writeFileSync(promptFile, prompt, "utf-8");
33845
33999
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
33846
34000
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
33847
34001
  const spawn4 = agentProvider?.spawn;
33848
34002
  if (!spawn4?.command) {
33849
34003
  try {
33850
- fs14.unlinkSync(promptFile);
34004
+ fs15.unlinkSync(promptFile);
33851
34005
  } catch {
33852
34006
  }
33853
34007
  ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
@@ -33949,7 +34103,7 @@ async function handleAutoImplement(ctx, type, req, res) {
33949
34103
  } catch {
33950
34104
  }
33951
34105
  try {
33952
- fs14.unlinkSync(promptFile);
34106
+ fs15.unlinkSync(promptFile);
33953
34107
  } catch {
33954
34108
  }
33955
34109
  ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
@@ -34175,7 +34329,7 @@ async function handleAutoImplement(ctx, type, req, res) {
34175
34329
  }
34176
34330
  });
34177
34331
  try {
34178
- fs14.unlinkSync(promptFile);
34332
+ fs15.unlinkSync(promptFile);
34179
34333
  } catch {
34180
34334
  }
34181
34335
  ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
@@ -34280,10 +34434,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
34280
34434
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
34281
34435
  lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
34282
34436
  lines.push("");
34283
- for (const file of fs14.readdirSync(latestScriptsDir)) {
34437
+ for (const file of fs15.readdirSync(latestScriptsDir)) {
34284
34438
  if (file.endsWith(".js") && targetFileNames.has(file)) {
34285
34439
  try {
34286
- const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
34440
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
34287
34441
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
34288
34442
  lines.push("```javascript");
34289
34443
  lines.push(content);
@@ -34293,14 +34447,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
34293
34447
  }
34294
34448
  }
34295
34449
  }
34296
- const refFiles = fs14.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
34450
+ const refFiles = fs15.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
34297
34451
  if (refFiles.length > 0) {
34298
34452
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
34299
34453
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
34300
34454
  lines.push("");
34301
34455
  for (const file of refFiles) {
34302
34456
  try {
34303
- const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
34457
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
34304
34458
  lines.push(`### \`${file}\` \u{1F512}`);
34305
34459
  lines.push("```javascript");
34306
34460
  lines.push(content);
@@ -34345,7 +34499,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
34345
34499
  const loadGuide = (name) => {
34346
34500
  try {
34347
34501
  const p = path26.join(docsDir, name);
34348
- if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
34502
+ if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
34349
34503
  } catch {
34350
34504
  }
34351
34505
  return null;
@@ -34589,11 +34743,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
34589
34743
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
34590
34744
  lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
34591
34745
  lines.push("");
34592
- for (const file of fs14.readdirSync(latestScriptsDir)) {
34746
+ for (const file of fs15.readdirSync(latestScriptsDir)) {
34593
34747
  if (!file.endsWith(".js")) continue;
34594
34748
  if (!targetFileNames.has(file)) continue;
34595
34749
  try {
34596
- const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
34750
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
34597
34751
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
34598
34752
  lines.push("```javascript");
34599
34753
  lines.push(content);
@@ -34602,14 +34756,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
34602
34756
  } catch {
34603
34757
  }
34604
34758
  }
34605
- const refFiles = fs14.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
34759
+ const refFiles = fs15.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
34606
34760
  if (refFiles.length > 0) {
34607
34761
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
34608
34762
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
34609
34763
  lines.push("");
34610
34764
  for (const file of refFiles) {
34611
34765
  try {
34612
- const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
34766
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
34613
34767
  lines.push(`### \`${file}\` \u{1F512}`);
34614
34768
  lines.push("```javascript");
34615
34769
  lines.push(content);
@@ -34646,7 +34800,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
34646
34800
  const loadGuide = (name) => {
34647
34801
  try {
34648
34802
  const p = path26.join(docsDir, name);
34649
- if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
34803
+ if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
34650
34804
  } catch {
34651
34805
  }
34652
34806
  return null;
@@ -35386,7 +35540,7 @@ var DevServer = class _DevServer {
35386
35540
  path27.join(process.cwd(), "packages/web-devconsole/dist")
35387
35541
  ];
35388
35542
  for (const dir of candidates) {
35389
- if (fs15.existsSync(path27.join(dir, "index.html"))) return dir;
35543
+ if (fs16.existsSync(path27.join(dir, "index.html"))) return dir;
35390
35544
  }
35391
35545
  return null;
35392
35546
  }
@@ -35398,7 +35552,7 @@ var DevServer = class _DevServer {
35398
35552
  }
35399
35553
  const htmlPath = path27.join(distDir, "index.html");
35400
35554
  try {
35401
- const html = fs15.readFileSync(htmlPath, "utf-8");
35555
+ const html = fs16.readFileSync(htmlPath, "utf-8");
35402
35556
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
35403
35557
  res.end(html);
35404
35558
  } catch (e) {
@@ -35428,7 +35582,7 @@ var DevServer = class _DevServer {
35428
35582
  return;
35429
35583
  }
35430
35584
  try {
35431
- const content = fs15.readFileSync(filePath);
35585
+ const content = fs16.readFileSync(filePath);
35432
35586
  const ext = path27.extname(filePath);
35433
35587
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
35434
35588
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
@@ -35537,14 +35691,14 @@ var DevServer = class _DevServer {
35537
35691
  const files = [];
35538
35692
  const scan = (d, prefix) => {
35539
35693
  try {
35540
- for (const entry of fs15.readdirSync(d, { withFileTypes: true })) {
35694
+ for (const entry of fs16.readdirSync(d, { withFileTypes: true })) {
35541
35695
  if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
35542
35696
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
35543
35697
  if (entry.isDirectory()) {
35544
35698
  files.push({ path: rel, size: 0, type: "dir" });
35545
35699
  scan(path27.join(d, entry.name), rel);
35546
35700
  } else {
35547
- const stat2 = fs15.statSync(path27.join(d, entry.name));
35701
+ const stat2 = fs16.statSync(path27.join(d, entry.name));
35548
35702
  files.push({ path: rel, size: stat2.size, type: "file" });
35549
35703
  }
35550
35704
  }
@@ -35572,11 +35726,11 @@ var DevServer = class _DevServer {
35572
35726
  this.json(res, 403, { error: "Forbidden" });
35573
35727
  return;
35574
35728
  }
35575
- if (!fs15.existsSync(fullPath) || fs15.statSync(fullPath).isDirectory()) {
35729
+ if (!fs16.existsSync(fullPath) || fs16.statSync(fullPath).isDirectory()) {
35576
35730
  this.json(res, 404, { error: `File not found: ${filePath}` });
35577
35731
  return;
35578
35732
  }
35579
- const content = fs15.readFileSync(fullPath, "utf-8");
35733
+ const content = fs16.readFileSync(fullPath, "utf-8");
35580
35734
  this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
35581
35735
  }
35582
35736
  /** POST /api/providers/:type/file — write a file { path, content } */
@@ -35598,9 +35752,9 @@ var DevServer = class _DevServer {
35598
35752
  return;
35599
35753
  }
35600
35754
  try {
35601
- if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
35602
- fs15.mkdirSync(path27.dirname(fullPath), { recursive: true });
35603
- fs15.writeFileSync(fullPath, content, "utf-8");
35755
+ if (fs16.existsSync(fullPath)) fs16.copyFileSync(fullPath, fullPath + ".bak");
35756
+ fs16.mkdirSync(path27.dirname(fullPath), { recursive: true });
35757
+ fs16.writeFileSync(fullPath, content, "utf-8");
35604
35758
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
35605
35759
  this.providerLoader.reload();
35606
35760
  this.json(res, 200, { saved: true, path: filePath, chars: content.length });
@@ -35617,8 +35771,8 @@ var DevServer = class _DevServer {
35617
35771
  }
35618
35772
  for (const name of ["scripts.js", "provider.json"]) {
35619
35773
  const p = path27.join(dir, name);
35620
- if (fs15.existsSync(p)) {
35621
- const source = fs15.readFileSync(p, "utf-8");
35774
+ if (fs16.existsSync(p)) {
35775
+ const source = fs16.readFileSync(p, "utf-8");
35622
35776
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
35623
35777
  return;
35624
35778
  }
@@ -35637,11 +35791,11 @@ var DevServer = class _DevServer {
35637
35791
  this.json(res, 404, { error: `Provider not found: ${type}` });
35638
35792
  return;
35639
35793
  }
35640
- const target = fs15.existsSync(path27.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
35794
+ const target = fs16.existsSync(path27.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
35641
35795
  const targetPath = path27.join(dir, target);
35642
35796
  try {
35643
- if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
35644
- fs15.writeFileSync(targetPath, source, "utf-8");
35797
+ if (fs16.existsSync(targetPath)) fs16.copyFileSync(targetPath, targetPath + ".bak");
35798
+ fs16.writeFileSync(targetPath, source, "utf-8");
35645
35799
  this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
35646
35800
  this.providerLoader.reload();
35647
35801
  this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
@@ -35786,20 +35940,20 @@ var DevServer = class _DevServer {
35786
35940
  let targetDir;
35787
35941
  targetDir = this.providerLoader.getUserProviderDir(category, type);
35788
35942
  const jsonPath = path27.join(targetDir, "provider.json");
35789
- if (fs15.existsSync(jsonPath)) {
35943
+ if (fs16.existsSync(jsonPath)) {
35790
35944
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
35791
35945
  return;
35792
35946
  }
35793
35947
  try {
35794
35948
  const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
35795
- fs15.mkdirSync(targetDir, { recursive: true });
35796
- fs15.writeFileSync(jsonPath, result["provider.json"], "utf-8");
35949
+ fs16.mkdirSync(targetDir, { recursive: true });
35950
+ fs16.writeFileSync(jsonPath, result["provider.json"], "utf-8");
35797
35951
  const createdFiles = ["provider.json"];
35798
35952
  if (result.files) {
35799
35953
  for (const [relPath, content] of Object.entries(result.files)) {
35800
35954
  const fullPath = path27.join(targetDir, relPath);
35801
- fs15.mkdirSync(path27.dirname(fullPath), { recursive: true });
35802
- fs15.writeFileSync(fullPath, content, "utf-8");
35955
+ fs16.mkdirSync(path27.dirname(fullPath), { recursive: true });
35956
+ fs16.writeFileSync(fullPath, content, "utf-8");
35803
35957
  createdFiles.push(relPath);
35804
35958
  }
35805
35959
  }
@@ -35848,10 +36002,10 @@ var DevServer = class _DevServer {
35848
36002
  }
35849
36003
  // ─── Phase 2: Auto-Implement Backend ───
35850
36004
  getLatestScriptVersionDir(scriptsDir) {
35851
- if (!fs15.existsSync(scriptsDir)) return null;
35852
- const versions = fs15.readdirSync(scriptsDir).filter((d) => {
36005
+ if (!fs16.existsSync(scriptsDir)) return null;
36006
+ const versions = fs16.readdirSync(scriptsDir).filter((d) => {
35853
36007
  try {
35854
- return fs15.statSync(path27.join(scriptsDir, d)).isDirectory();
36008
+ return fs16.statSync(path27.join(scriptsDir, d)).isDirectory();
35855
36009
  } catch {
35856
36010
  return false;
35857
36011
  }
@@ -35873,13 +36027,13 @@ var DevServer = class _DevServer {
35873
36027
  if (!sourceDir) {
35874
36028
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
35875
36029
  }
35876
- if (!fs15.existsSync(desiredDir)) {
35877
- fs15.mkdirSync(path27.dirname(desiredDir), { recursive: true });
35878
- fs15.cpSync(sourceDir, desiredDir, { recursive: true });
36030
+ if (!fs16.existsSync(desiredDir)) {
36031
+ fs16.mkdirSync(path27.dirname(desiredDir), { recursive: true });
36032
+ fs16.cpSync(sourceDir, desiredDir, { recursive: true });
35879
36033
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
35880
36034
  }
35881
36035
  const providerJson = path27.join(desiredDir, "provider.json");
35882
- if (!fs15.existsSync(providerJson)) {
36036
+ if (!fs16.existsSync(providerJson)) {
35883
36037
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
35884
36038
  }
35885
36039
  return { dir: desiredDir };
@@ -35922,10 +36076,10 @@ var DevServer = class _DevServer {
35922
36076
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
35923
36077
  lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
35924
36078
  lines.push("");
35925
- for (const file of fs15.readdirSync(latestScriptsDir)) {
36079
+ for (const file of fs16.readdirSync(latestScriptsDir)) {
35926
36080
  if (file.endsWith(".js") && targetFileNames.has(file)) {
35927
36081
  try {
35928
- const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
36082
+ const content = fs16.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
35929
36083
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
35930
36084
  lines.push("```javascript");
35931
36085
  lines.push(content);
@@ -35935,14 +36089,14 @@ var DevServer = class _DevServer {
35935
36089
  }
35936
36090
  }
35937
36091
  }
35938
- const refFiles = fs15.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
36092
+ const refFiles = fs16.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
35939
36093
  if (refFiles.length > 0) {
35940
36094
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
35941
36095
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
35942
36096
  lines.push("");
35943
36097
  for (const file of refFiles) {
35944
36098
  try {
35945
- const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
36099
+ const content = fs16.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
35946
36100
  lines.push(`### \`${file}\` \u{1F512}`);
35947
36101
  lines.push("```javascript");
35948
36102
  lines.push(content);
@@ -35987,7 +36141,7 @@ var DevServer = class _DevServer {
35987
36141
  const loadGuide = (name) => {
35988
36142
  try {
35989
36143
  const p = path27.join(docsDir, name);
35990
- if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
36144
+ if (fs16.existsSync(p)) return fs16.readFileSync(p, "utf-8");
35991
36145
  } catch {
35992
36146
  }
35993
36147
  return null;
@@ -36168,11 +36322,11 @@ var DevServer = class _DevServer {
36168
36322
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
36169
36323
  lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
36170
36324
  lines.push("");
36171
- for (const file of fs15.readdirSync(latestScriptsDir)) {
36325
+ for (const file of fs16.readdirSync(latestScriptsDir)) {
36172
36326
  if (!file.endsWith(".js")) continue;
36173
36327
  if (!targetFileNames.has(file)) continue;
36174
36328
  try {
36175
- const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
36329
+ const content = fs16.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
36176
36330
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
36177
36331
  lines.push("```javascript");
36178
36332
  lines.push(content);
@@ -36181,14 +36335,14 @@ var DevServer = class _DevServer {
36181
36335
  } catch {
36182
36336
  }
36183
36337
  }
36184
- const refFiles = fs15.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
36338
+ const refFiles = fs16.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
36185
36339
  if (refFiles.length > 0) {
36186
36340
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
36187
36341
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
36188
36342
  lines.push("");
36189
36343
  for (const file of refFiles) {
36190
36344
  try {
36191
- const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
36345
+ const content = fs16.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
36192
36346
  lines.push(`### \`${file}\` \u{1F512}`);
36193
36347
  lines.push("```javascript");
36194
36348
  lines.push(content);
@@ -36225,7 +36379,7 @@ var DevServer = class _DevServer {
36225
36379
  const loadGuide = (name) => {
36226
36380
  try {
36227
36381
  const p = path27.join(docsDir, name);
36228
- if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
36382
+ if (fs16.existsSync(p)) return fs16.readFileSync(p, "utf-8");
36229
36383
  } catch {
36230
36384
  }
36231
36385
  return null;
@@ -37002,7 +37156,8 @@ function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
37002
37156
  }
37003
37157
 
37004
37158
  // src/installer.ts
37005
- var import_child_process11 = require("child_process");
37159
+ var import_child_process10 = require("child_process");
37160
+ var import_util3 = require("util");
37006
37161
  var EXTENSION_CATALOG = [
37007
37162
  // AI Agent extensions
37008
37163
  {
@@ -37089,15 +37244,15 @@ var EXTENSION_CATALOG = [
37089
37244
  apiKeyName: "OpenAI/Anthropic API key"
37090
37245
  }
37091
37246
  ];
37092
- function isExtensionInstalled(ide, marketplaceId) {
37247
+ var execAsync4 = (0, import_util3.promisify)(import_child_process10.exec);
37248
+ async function isExtensionInstalled(ide, marketplaceId) {
37093
37249
  if (!ide.cliCommand) return false;
37094
37250
  try {
37095
- const result = (0, import_child_process11.execSync)(`"${ide.cliCommand}" --list-extensions`, {
37251
+ const { stdout } = await execAsync4(`"${ide.cliCommand}" --list-extensions`, {
37096
37252
  encoding: "utf-8",
37097
- timeout: 15e3,
37098
- stdio: ["pipe", "pipe", "pipe"]
37253
+ timeout: 15e3
37099
37254
  });
37100
- const installed = result.trim().split("\n").map((e) => e.trim().toLowerCase());
37255
+ const installed = stdout.trim().split("\n").map((e) => e.trim().toLowerCase());
37101
37256
  return installed.includes(marketplaceId.toLowerCase());
37102
37257
  } catch {
37103
37258
  return false;
@@ -37113,7 +37268,7 @@ async function installExtension(ide, extension) {
37113
37268
  error: `No CLI command found for ${ide.displayName}. Please install it manually.`
37114
37269
  };
37115
37270
  }
37116
- const alreadyInstalled = isExtensionInstalled(ide, extension.marketplaceId);
37271
+ const alreadyInstalled = await isExtensionInstalled(ide, extension.marketplaceId);
37117
37272
  if (alreadyInstalled) {
37118
37273
  return {
37119
37274
  extensionId: extension.id,
@@ -37129,11 +37284,11 @@ async function installExtension(ide, extension) {
37129
37284
  const res = await fetch(extension.vsixUrl);
37130
37285
  if (res.ok) {
37131
37286
  const buffer = Buffer.from(await res.arrayBuffer());
37132
- const fs16 = await import("fs");
37133
- fs16.writeFileSync(vsixPath, buffer);
37287
+ const fs17 = await import("fs");
37288
+ fs17.writeFileSync(vsixPath, buffer);
37134
37289
  return new Promise((resolve16) => {
37135
37290
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
37136
- (0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
37291
+ (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
37137
37292
  resolve16({
37138
37293
  extensionId: extension.id,
37139
37294
  marketplaceId: extension.marketplaceId,
@@ -37149,7 +37304,7 @@ async function installExtension(ide, extension) {
37149
37304
  }
37150
37305
  return new Promise((resolve16) => {
37151
37306
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
37152
- (0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
37307
+ (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
37153
37308
  if (error) {
37154
37309
  resolve16({
37155
37310
  extensionId: extension.id,
@@ -37186,7 +37341,7 @@ function launchIDE(ide, workspacePath) {
37186
37341
  if (!ide.cliCommand) return false;
37187
37342
  try {
37188
37343
  const args = workspacePath ? `"${workspacePath}"` : "";
37189
- (0, import_child_process11.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
37344
+ (0, import_child_process10.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
37190
37345
  return true;
37191
37346
  } catch {
37192
37347
  return false;
@@ -37622,6 +37777,7 @@ async function shutdownDaemonComponents(components) {
37622
37777
  getLogLevel,
37623
37778
  getMesh,
37624
37779
  getMeshByRepo,
37780
+ getMeshQueueRevision,
37625
37781
  getMeshQueueStats,
37626
37782
  getNpmExecOptions,
37627
37783
  getPendingMeshCoordinatorEvents,