@adhdev/daemon-core 0.9.82-rc.66 → 0.9.82-rc.68
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.d.ts +1 -1
- package/dist/index.js +747 -591
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +748 -593
- package/dist/index.mjs.map +1 -1
- package/dist/installer.d.ts +1 -4
- package/dist/launch.d.ts +1 -1
- package/dist/logging/async-batch-writer.d.ts +10 -0
- package/dist/mesh/beads-db.d.ts +18 -0
- package/dist/mesh/mesh-work-queue.d.ts +4 -0
- package/dist/status/reporter.d.ts +2 -0
- package/package.json +3 -1
- package/src/cli-adapters/provider-cli-shared.ts +18 -10
- package/src/commands/mesh-coordinator.ts +13 -143
- package/src/commands/router.ts +5 -3
- package/src/detection/ide-detector.ts +26 -16
- package/src/index.ts +1 -1
- package/src/installer.d.ts +1 -1
- package/src/installer.ts +8 -6
- package/src/launch.d.ts +1 -1
- package/src/launch.ts +37 -28
- package/src/logging/async-batch-writer.ts +55 -0
- package/src/logging/logger.ts +2 -1
- package/src/mesh/beads-db.ts +163 -0
- package/src/mesh/mesh-ledger.ts +1 -1
- package/src/mesh/mesh-work-queue.ts +23 -41
- package/src/providers/ide-provider-instance.ts +17 -3
- package/src/providers/provider-loader.ts +10 -4
- package/src/providers/version-archive.ts +38 -20
- package/src/status/reporter.ts +15 -0
- package/src/system/host-memory.ts +29 -12
package/dist/index.mjs
CHANGED
|
@@ -1268,7 +1268,7 @@ __export(mesh_ledger_exports, {
|
|
|
1268
1268
|
readLedgerEntries: () => readLedgerEntries,
|
|
1269
1269
|
readLedgerSlice: () => readLedgerSlice
|
|
1270
1270
|
});
|
|
1271
|
-
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync4,
|
|
1271
|
+
import { appendFileSync, existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync4, statSync as statSync2, renameSync } from "fs";
|
|
1272
1272
|
import { join as join6 } from "path";
|
|
1273
1273
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
1274
1274
|
import { EventEmitter } from "events";
|
|
@@ -1678,15 +1678,162 @@ var init_mesh_ledger = __esm({
|
|
|
1678
1678
|
}
|
|
1679
1679
|
});
|
|
1680
1680
|
|
|
1681
|
+
// src/mesh/beads-db.ts
|
|
1682
|
+
import Database from "better-sqlite3";
|
|
1683
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync5 } from "fs";
|
|
1684
|
+
import { dirname as dirname2, join as join7 } from "path";
|
|
1685
|
+
function safeMeshId(meshId) {
|
|
1686
|
+
return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1687
|
+
}
|
|
1688
|
+
function legacyQueuePath(meshId) {
|
|
1689
|
+
return join7(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
|
|
1690
|
+
}
|
|
1691
|
+
var BeadsDB;
|
|
1692
|
+
var init_beads_db = __esm({
|
|
1693
|
+
"src/mesh/beads-db.ts"() {
|
|
1694
|
+
"use strict";
|
|
1695
|
+
init_mesh_ledger();
|
|
1696
|
+
BeadsDB = class _BeadsDB {
|
|
1697
|
+
static instance;
|
|
1698
|
+
db;
|
|
1699
|
+
migratedMeshIds = /* @__PURE__ */ new Set();
|
|
1700
|
+
constructor(dbPath) {
|
|
1701
|
+
const dir = dirname2(dbPath);
|
|
1702
|
+
if (!existsSync7(dir)) mkdirSync4(dir, { recursive: true });
|
|
1703
|
+
this.db = new Database(dbPath);
|
|
1704
|
+
this.db.pragma("journal_mode = WAL");
|
|
1705
|
+
this.db.pragma("synchronous = NORMAL");
|
|
1706
|
+
this.db.pragma("foreign_keys = ON");
|
|
1707
|
+
this.db.pragma("busy_timeout = 5000");
|
|
1708
|
+
this.migrate();
|
|
1709
|
+
}
|
|
1710
|
+
static getInstance() {
|
|
1711
|
+
if (!this.instance) {
|
|
1712
|
+
this.instance = new _BeadsDB(join7(getLedgerDir(), "beads.db"));
|
|
1713
|
+
}
|
|
1714
|
+
return this.instance;
|
|
1715
|
+
}
|
|
1716
|
+
static resetForTests() {
|
|
1717
|
+
this.instance?.close();
|
|
1718
|
+
this.instance = void 0;
|
|
1719
|
+
}
|
|
1720
|
+
close() {
|
|
1721
|
+
this.db.close();
|
|
1722
|
+
}
|
|
1723
|
+
transaction(fn) {
|
|
1724
|
+
return this.db.transaction(fn).immediate();
|
|
1725
|
+
}
|
|
1726
|
+
migrate() {
|
|
1727
|
+
this.db.exec(`
|
|
1728
|
+
CREATE TABLE IF NOT EXISTS mesh_queue (
|
|
1729
|
+
id TEXT PRIMARY KEY,
|
|
1730
|
+
mesh_id TEXT NOT NULL,
|
|
1731
|
+
status TEXT NOT NULL,
|
|
1732
|
+
target_node_id TEXT,
|
|
1733
|
+
target_session_id TEXT,
|
|
1734
|
+
assigned_node_id TEXT,
|
|
1735
|
+
assigned_session_id TEXT,
|
|
1736
|
+
created_at TEXT NOT NULL,
|
|
1737
|
+
updated_at TEXT NOT NULL,
|
|
1738
|
+
payload TEXT NOT NULL
|
|
1739
|
+
);
|
|
1740
|
+
|
|
1741
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_queue_mesh_status_created
|
|
1742
|
+
ON mesh_queue(mesh_id, status, created_at);
|
|
1743
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_queue_assignment
|
|
1744
|
+
ON mesh_queue(mesh_id, assigned_node_id, assigned_session_id, status);
|
|
1745
|
+
`);
|
|
1746
|
+
}
|
|
1747
|
+
ensureLegacyQueueMigrated(meshId) {
|
|
1748
|
+
if (this.migratedMeshIds.has(meshId)) return;
|
|
1749
|
+
this.migratedMeshIds.add(meshId);
|
|
1750
|
+
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
1751
|
+
if (count.count > 0) return;
|
|
1752
|
+
const path28 = legacyQueuePath(meshId);
|
|
1753
|
+
if (!existsSync7(path28)) return;
|
|
1754
|
+
try {
|
|
1755
|
+
const entries = JSON.parse(readFileSync5(path28, "utf-8"));
|
|
1756
|
+
if (!Array.isArray(entries)) return;
|
|
1757
|
+
const insert = this.db.prepare(`
|
|
1758
|
+
INSERT OR REPLACE INTO mesh_queue (
|
|
1759
|
+
id, mesh_id, status, target_node_id, target_session_id,
|
|
1760
|
+
assigned_node_id, assigned_session_id, created_at, updated_at, payload
|
|
1761
|
+
) VALUES (
|
|
1762
|
+
@id, @meshId, @status, @targetNodeId, @targetSessionId,
|
|
1763
|
+
@assignedNodeId, @assignedSessionId, @createdAt, @updatedAt, @payload
|
|
1764
|
+
)
|
|
1765
|
+
`);
|
|
1766
|
+
for (const entry of entries) {
|
|
1767
|
+
insert.run(this.toRow(entry));
|
|
1768
|
+
}
|
|
1769
|
+
} catch {
|
|
1770
|
+
return;
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
getQueueEntries(meshId, statuses) {
|
|
1774
|
+
this.ensureLegacyQueueMigrated(meshId);
|
|
1775
|
+
if (statuses?.length) {
|
|
1776
|
+
const placeholders = statuses.map(() => "?").join(", ");
|
|
1777
|
+
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);
|
|
1778
|
+
return rows2.map((row) => JSON.parse(row.payload));
|
|
1779
|
+
}
|
|
1780
|
+
const rows = this.db.prepare("SELECT payload FROM mesh_queue WHERE mesh_id = ? ORDER BY created_at ASC").all(meshId);
|
|
1781
|
+
return rows.map((row) => JSON.parse(row.payload));
|
|
1782
|
+
}
|
|
1783
|
+
getQueueRevision(meshId) {
|
|
1784
|
+
this.ensureLegacyQueueMigrated(meshId);
|
|
1785
|
+
const rows = this.db.prepare("SELECT id, status, updated_at FROM mesh_queue WHERE mesh_id = ? ORDER BY id ASC").all(meshId);
|
|
1786
|
+
return rows.map((row) => `${row.id}:${row.status}:${row.updated_at}`).join("|");
|
|
1787
|
+
}
|
|
1788
|
+
replaceQueue(meshId, queue) {
|
|
1789
|
+
const deleteStmt = this.db.prepare("DELETE FROM mesh_queue WHERE mesh_id = ?");
|
|
1790
|
+
const insert = this.db.prepare(`
|
|
1791
|
+
INSERT INTO mesh_queue (
|
|
1792
|
+
id, mesh_id, status, target_node_id, target_session_id,
|
|
1793
|
+
assigned_node_id, assigned_session_id, created_at, updated_at, payload
|
|
1794
|
+
) VALUES (
|
|
1795
|
+
@id, @meshId, @status, @targetNodeId, @targetSessionId,
|
|
1796
|
+
@assignedNodeId, @assignedSessionId, @createdAt, @updatedAt, @payload
|
|
1797
|
+
)
|
|
1798
|
+
`);
|
|
1799
|
+
deleteStmt.run(meshId);
|
|
1800
|
+
for (const entry of queue) insert.run(this.toRow(entry));
|
|
1801
|
+
}
|
|
1802
|
+
deleteQueue(meshId) {
|
|
1803
|
+
this.db.prepare("DELETE FROM mesh_queue WHERE mesh_id = ?").run(meshId);
|
|
1804
|
+
this.migratedMeshIds.delete(meshId);
|
|
1805
|
+
}
|
|
1806
|
+
toRow(entry) {
|
|
1807
|
+
return {
|
|
1808
|
+
id: entry.id,
|
|
1809
|
+
meshId: entry.meshId,
|
|
1810
|
+
status: entry.status,
|
|
1811
|
+
targetNodeId: entry.targetNodeId ?? null,
|
|
1812
|
+
targetSessionId: entry.targetSessionId ?? null,
|
|
1813
|
+
assignedNodeId: entry.assignedNodeId ?? null,
|
|
1814
|
+
assignedSessionId: entry.assignedSessionId ?? null,
|
|
1815
|
+
createdAt: entry.createdAt,
|
|
1816
|
+
updatedAt: entry.updatedAt,
|
|
1817
|
+
payload: JSON.stringify(entry)
|
|
1818
|
+
};
|
|
1819
|
+
}
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
});
|
|
1823
|
+
|
|
1681
1824
|
// src/mesh/mesh-work-queue.ts
|
|
1682
1825
|
var mesh_work_queue_exports = {};
|
|
1683
1826
|
__export(mesh_work_queue_exports, {
|
|
1684
1827
|
ACTIVE_MESH_QUEUE_STATUSES: () => ACTIVE_MESH_QUEUE_STATUSES,
|
|
1685
1828
|
HISTORICAL_MESH_QUEUE_STATUSES: () => HISTORICAL_MESH_QUEUE_STATUSES,
|
|
1686
1829
|
MESH_TASK_MODES: () => MESH_TASK_MODES,
|
|
1830
|
+
__clearMeshQueueForTests: () => __clearMeshQueueForTests,
|
|
1831
|
+
__replaceMeshQueueForTests: () => __replaceMeshQueueForTests,
|
|
1832
|
+
__resetBeadsDBForTests: () => __resetBeadsDBForTests,
|
|
1687
1833
|
cancelTask: () => cancelTask,
|
|
1688
1834
|
claimNextTask: () => claimNextTask,
|
|
1689
1835
|
enqueueTask: () => enqueueTask,
|
|
1836
|
+
getMeshQueueRevision: () => getMeshQueueRevision,
|
|
1690
1837
|
getMeshQueueStats: () => getMeshQueueStats,
|
|
1691
1838
|
getQueue: () => getQueue,
|
|
1692
1839
|
normalizeMeshTaskMode: () => normalizeMeshTaskMode,
|
|
@@ -1696,8 +1843,6 @@ __export(mesh_work_queue_exports, {
|
|
|
1696
1843
|
updateTaskStatus: () => updateTaskStatus,
|
|
1697
1844
|
validateMeshTaskModeRequest: () => validateMeshTaskModeRequest
|
|
1698
1845
|
});
|
|
1699
|
-
import { existsSync as existsSync7, writeFileSync as writeFileSync3, readFileSync as readFileSync5, openSync, closeSync, unlinkSync } from "fs";
|
|
1700
|
-
import { join as join7 } from "path";
|
|
1701
1846
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
1702
1847
|
function normalizeMeshTaskMode(value) {
|
|
1703
1848
|
if (typeof value !== "string") return void 0;
|
|
@@ -1725,53 +1870,14 @@ function validateMeshTaskModeRequest(mode, message) {
|
|
|
1725
1870
|
]
|
|
1726
1871
|
};
|
|
1727
1872
|
}
|
|
1728
|
-
function
|
|
1729
|
-
|
|
1730
|
-
return join7(getLedgerDir(), `${safe}.queue.json`);
|
|
1731
|
-
}
|
|
1732
|
-
function getLockPath(meshId) {
|
|
1733
|
-
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1734
|
-
return join7(getLedgerDir(), `${safe}.queue.lock`);
|
|
1735
|
-
}
|
|
1736
|
-
function withQueueLock(meshId, fn) {
|
|
1737
|
-
const lockPath = getLockPath(meshId);
|
|
1738
|
-
let fd = -1;
|
|
1739
|
-
for (let i = 0; i < 10; i++) {
|
|
1740
|
-
try {
|
|
1741
|
-
fd = openSync(lockPath, "wx");
|
|
1742
|
-
break;
|
|
1743
|
-
} catch {
|
|
1744
|
-
const deadline = Date.now() + 30;
|
|
1745
|
-
while (Date.now() < deadline) {
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1748
|
-
}
|
|
1749
|
-
try {
|
|
1750
|
-
return fn();
|
|
1751
|
-
} finally {
|
|
1752
|
-
if (fd !== -1) try {
|
|
1753
|
-
closeSync(fd);
|
|
1754
|
-
} catch {
|
|
1755
|
-
}
|
|
1756
|
-
try {
|
|
1757
|
-
unlinkSync(lockPath);
|
|
1758
|
-
} catch {
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1873
|
+
function withQueueLock(_meshId, fn) {
|
|
1874
|
+
return BeadsDB.getInstance().transaction(fn);
|
|
1761
1875
|
}
|
|
1762
1876
|
function readQueue(meshId) {
|
|
1763
|
-
|
|
1764
|
-
if (!existsSync7(path28)) return [];
|
|
1765
|
-
try {
|
|
1766
|
-
const content = readFileSync5(path28, "utf-8");
|
|
1767
|
-
return JSON.parse(content);
|
|
1768
|
-
} catch {
|
|
1769
|
-
return [];
|
|
1770
|
-
}
|
|
1877
|
+
return BeadsDB.getInstance().getQueueEntries(meshId);
|
|
1771
1878
|
}
|
|
1772
1879
|
function writeQueue(meshId, queue) {
|
|
1773
|
-
|
|
1774
|
-
writeFileSync3(path28, JSON.stringify(queue, null, 2), "utf-8");
|
|
1880
|
+
BeadsDB.getInstance().replaceQueue(meshId, queue);
|
|
1775
1881
|
}
|
|
1776
1882
|
function enqueueTask(meshId, message, opts) {
|
|
1777
1883
|
requireMeshHostQueueOwner(opts);
|
|
@@ -1805,6 +1911,9 @@ function getQueue(meshId, opts) {
|
|
|
1805
1911
|
}
|
|
1806
1912
|
return queue;
|
|
1807
1913
|
}
|
|
1914
|
+
function getMeshQueueRevision(meshId) {
|
|
1915
|
+
return BeadsDB.getInstance().getQueueRevision(meshId);
|
|
1916
|
+
}
|
|
1808
1917
|
function claimNextTask(meshId, nodeId, sessionId) {
|
|
1809
1918
|
return withQueueLock(meshId, () => {
|
|
1810
1919
|
const queue = readQueue(meshId);
|
|
@@ -1948,12 +2057,23 @@ function getMeshQueueStats(meshId) {
|
|
|
1948
2057
|
}))
|
|
1949
2058
|
};
|
|
1950
2059
|
}
|
|
2060
|
+
function __replaceMeshQueueForTests(meshId, queue) {
|
|
2061
|
+
BeadsDB.getInstance().transaction(() => {
|
|
2062
|
+
BeadsDB.getInstance().replaceQueue(meshId, queue);
|
|
2063
|
+
});
|
|
2064
|
+
}
|
|
2065
|
+
function __clearMeshQueueForTests(meshId) {
|
|
2066
|
+
BeadsDB.getInstance().deleteQueue(meshId);
|
|
2067
|
+
}
|
|
2068
|
+
function __resetBeadsDBForTests() {
|
|
2069
|
+
BeadsDB.resetForTests();
|
|
2070
|
+
}
|
|
1951
2071
|
var ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES, MESH_TASK_MODES, LIVE_DEBUG_READONLY_FORBIDDEN;
|
|
1952
2072
|
var init_mesh_work_queue = __esm({
|
|
1953
2073
|
"src/mesh/mesh-work-queue.ts"() {
|
|
1954
2074
|
"use strict";
|
|
1955
|
-
init_mesh_ledger();
|
|
1956
2075
|
init_mesh_host_ownership();
|
|
2076
|
+
init_beads_db();
|
|
1957
2077
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
1958
2078
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
1959
2079
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -2101,8 +2221,62 @@ var init_cli_detector = __esm({
|
|
|
2101
2221
|
}
|
|
2102
2222
|
});
|
|
2103
2223
|
|
|
2104
|
-
// src/logging/
|
|
2224
|
+
// src/logging/async-batch-writer.ts
|
|
2105
2225
|
import * as fs2 from "fs";
|
|
2226
|
+
var AsyncBatchWriter;
|
|
2227
|
+
var init_async_batch_writer = __esm({
|
|
2228
|
+
"src/logging/async-batch-writer.ts"() {
|
|
2229
|
+
"use strict";
|
|
2230
|
+
AsyncBatchWriter = class {
|
|
2231
|
+
// Maps filePath -> string buffer
|
|
2232
|
+
static buffers = /* @__PURE__ */ new Map();
|
|
2233
|
+
static writePromises = /* @__PURE__ */ new Map();
|
|
2234
|
+
static flushTimer = null;
|
|
2235
|
+
/**
|
|
2236
|
+
* Queues data to be written to a file asynchronously in a batch.
|
|
2237
|
+
*/
|
|
2238
|
+
static write(filePath, data) {
|
|
2239
|
+
let buf = this.buffers.get(filePath);
|
|
2240
|
+
if (!buf) {
|
|
2241
|
+
buf = [];
|
|
2242
|
+
this.buffers.set(filePath, buf);
|
|
2243
|
+
}
|
|
2244
|
+
buf.push(data);
|
|
2245
|
+
if (!this.flushTimer) {
|
|
2246
|
+
this.flushTimer = setTimeout(() => {
|
|
2247
|
+
this.flushTimer = null;
|
|
2248
|
+
this.flushAll();
|
|
2249
|
+
}, 50);
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
static async flushAll() {
|
|
2253
|
+
const entries = Array.from(this.buffers.entries());
|
|
2254
|
+
this.buffers.clear();
|
|
2255
|
+
for (const [filePath, buffer] of entries) {
|
|
2256
|
+
const dataToWrite = buffer.join("");
|
|
2257
|
+
const doWrite = async () => {
|
|
2258
|
+
try {
|
|
2259
|
+
const prevPromise = this.writePromises.get(filePath);
|
|
2260
|
+
if (prevPromise) await prevPromise;
|
|
2261
|
+
await fs2.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
|
|
2262
|
+
} catch {
|
|
2263
|
+
}
|
|
2264
|
+
};
|
|
2265
|
+
const writePromise = doWrite();
|
|
2266
|
+
this.writePromises.set(filePath, writePromise);
|
|
2267
|
+
writePromise.finally(() => {
|
|
2268
|
+
if (this.writePromises.get(filePath) === writePromise) {
|
|
2269
|
+
this.writePromises.delete(filePath);
|
|
2270
|
+
}
|
|
2271
|
+
});
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
};
|
|
2275
|
+
}
|
|
2276
|
+
});
|
|
2277
|
+
|
|
2278
|
+
// src/logging/logger.ts
|
|
2279
|
+
import * as fs3 from "fs";
|
|
2106
2280
|
import * as path9 from "path";
|
|
2107
2281
|
import * as os3 from "os";
|
|
2108
2282
|
function setLogLevel(level) {
|
|
@@ -2131,7 +2305,7 @@ function checkDateRotation() {
|
|
|
2131
2305
|
}
|
|
2132
2306
|
function cleanOldLogs() {
|
|
2133
2307
|
try {
|
|
2134
|
-
const files =
|
|
2308
|
+
const files = fs3.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
|
|
2135
2309
|
const cutoff = /* @__PURE__ */ new Date();
|
|
2136
2310
|
cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
|
|
2137
2311
|
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
@@ -2139,7 +2313,7 @@ function cleanOldLogs() {
|
|
|
2139
2313
|
const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
2140
2314
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
2141
2315
|
try {
|
|
2142
|
-
|
|
2316
|
+
fs3.unlinkSync(path9.join(LOG_DIR, file));
|
|
2143
2317
|
} catch {
|
|
2144
2318
|
}
|
|
2145
2319
|
}
|
|
@@ -2149,14 +2323,14 @@ function cleanOldLogs() {
|
|
|
2149
2323
|
}
|
|
2150
2324
|
function rotateSizeIfNeeded() {
|
|
2151
2325
|
try {
|
|
2152
|
-
const stat2 =
|
|
2326
|
+
const stat2 = fs3.statSync(currentLogFile);
|
|
2153
2327
|
if (stat2.size > MAX_LOG_SIZE) {
|
|
2154
2328
|
const backup = currentLogFile.replace(".log", ".1.log");
|
|
2155
2329
|
try {
|
|
2156
|
-
|
|
2330
|
+
fs3.unlinkSync(backup);
|
|
2157
2331
|
} catch {
|
|
2158
2332
|
}
|
|
2159
|
-
|
|
2333
|
+
fs3.renameSync(currentLogFile, backup);
|
|
2160
2334
|
}
|
|
2161
2335
|
} catch {
|
|
2162
2336
|
}
|
|
@@ -2167,7 +2341,7 @@ function writeToFile(line) {
|
|
|
2167
2341
|
checkDateRotation();
|
|
2168
2342
|
rotateSizeIfNeeded();
|
|
2169
2343
|
}
|
|
2170
|
-
|
|
2344
|
+
AsyncBatchWriter.write(currentLogFile, line + "\n");
|
|
2171
2345
|
} catch {
|
|
2172
2346
|
}
|
|
2173
2347
|
}
|
|
@@ -2259,6 +2433,7 @@ var LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, c
|
|
|
2259
2433
|
var init_logger = __esm({
|
|
2260
2434
|
"src/logging/logger.ts"() {
|
|
2261
2435
|
"use strict";
|
|
2436
|
+
init_async_batch_writer();
|
|
2262
2437
|
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
2263
2438
|
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
2264
2439
|
currentLevel = "info";
|
|
@@ -2266,7 +2441,7 @@ var init_logger = __esm({
|
|
|
2266
2441
|
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
2267
2442
|
MAX_LOG_DAYS = 7;
|
|
2268
2443
|
try {
|
|
2269
|
-
|
|
2444
|
+
fs3.mkdirSync(LOG_DIR, { recursive: true });
|
|
2270
2445
|
} catch {
|
|
2271
2446
|
}
|
|
2272
2447
|
currentDate = getDateStr();
|
|
@@ -2274,14 +2449,14 @@ var init_logger = __esm({
|
|
|
2274
2449
|
cleanOldLogs();
|
|
2275
2450
|
try {
|
|
2276
2451
|
const oldLog = path9.join(LOG_DIR, "daemon.log");
|
|
2277
|
-
if (
|
|
2278
|
-
const stat2 =
|
|
2452
|
+
if (fs3.existsSync(oldLog)) {
|
|
2453
|
+
const stat2 = fs3.statSync(oldLog);
|
|
2279
2454
|
const oldDate = stat2.mtime.toISOString().slice(0, 10);
|
|
2280
|
-
|
|
2455
|
+
fs3.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
2281
2456
|
}
|
|
2282
2457
|
const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
|
|
2283
|
-
if (
|
|
2284
|
-
|
|
2458
|
+
if (fs3.existsSync(oldLogBackup)) {
|
|
2459
|
+
fs3.unlinkSync(oldLogBackup);
|
|
2285
2460
|
}
|
|
2286
2461
|
} catch {
|
|
2287
2462
|
}
|
|
@@ -2327,7 +2502,7 @@ __export(mesh_events_exports, {
|
|
|
2327
2502
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
2328
2503
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
2329
2504
|
});
|
|
2330
|
-
import { appendFileSync as
|
|
2505
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync10, readFileSync as readFileSync6, unlinkSync as unlinkSync2 } from "fs";
|
|
2331
2506
|
import { join as join10 } from "path";
|
|
2332
2507
|
function readWorkerResultMetadata(event) {
|
|
2333
2508
|
return readRecord(event.workerResult) || readRecord(event.meshWorkerResult) || readRecord(event.structuredResult);
|
|
@@ -2366,7 +2541,7 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
2366
2541
|
LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for refine job ${readRefineJobId(event)}`);
|
|
2367
2542
|
return true;
|
|
2368
2543
|
}
|
|
2369
|
-
|
|
2544
|
+
appendFileSync2(getPendingEventsPath(event.meshId), JSON.stringify(event) + "\n", "utf-8");
|
|
2370
2545
|
return true;
|
|
2371
2546
|
} catch (e) {
|
|
2372
2547
|
LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
@@ -2380,7 +2555,7 @@ function drainPendingMeshCoordinatorEvents(meshId) {
|
|
|
2380
2555
|
try {
|
|
2381
2556
|
const raw = readFileSync6(path28, "utf-8");
|
|
2382
2557
|
try {
|
|
2383
|
-
|
|
2558
|
+
unlinkSync2(path28);
|
|
2384
2559
|
} catch {
|
|
2385
2560
|
}
|
|
2386
2561
|
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
@@ -2415,7 +2590,7 @@ function clearPendingMeshCoordinatorEvents(meshId) {
|
|
|
2415
2590
|
if (!meshId) return;
|
|
2416
2591
|
const path28 = getPendingEventsPath(meshId);
|
|
2417
2592
|
if (existsSync10(path28)) try {
|
|
2418
|
-
|
|
2593
|
+
unlinkSync2(path28);
|
|
2419
2594
|
} catch {
|
|
2420
2595
|
}
|
|
2421
2596
|
}
|
|
@@ -3627,8 +3802,8 @@ var init_pty_transport = __esm({
|
|
|
3627
3802
|
let cwd = options.cwd;
|
|
3628
3803
|
if (cwd) {
|
|
3629
3804
|
try {
|
|
3630
|
-
const
|
|
3631
|
-
const stat2 =
|
|
3805
|
+
const fs17 = __require("fs");
|
|
3806
|
+
const stat2 = fs17.statSync(cwd);
|
|
3632
3807
|
if (!stat2.isDirectory()) cwd = os8.homedir();
|
|
3633
3808
|
} catch {
|
|
3634
3809
|
cwd = os8.homedir();
|
|
@@ -3650,7 +3825,6 @@ var init_pty_transport = __esm({
|
|
|
3650
3825
|
// src/cli-adapters/provider-cli-shared.ts
|
|
3651
3826
|
import * as os9 from "os";
|
|
3652
3827
|
import * as path14 from "path";
|
|
3653
|
-
import { execSync as execSync3 } from "child_process";
|
|
3654
3828
|
function stripAnsi(str) {
|
|
3655
3829
|
return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
3656
3830
|
}
|
|
@@ -3731,27 +3905,35 @@ function findBinary(name) {
|
|
|
3731
3905
|
return path14.isAbsolute(expanded) ? expanded : path14.resolve(expanded);
|
|
3732
3906
|
}
|
|
3733
3907
|
const isWin = os9.platform() === "win32";
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3908
|
+
const paths = (process.env.PATH || "").split(path14.delimiter);
|
|
3909
|
+
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
3910
|
+
for (const p of paths) {
|
|
3911
|
+
if (!p) continue;
|
|
3912
|
+
for (const ext of exes) {
|
|
3913
|
+
const fullPath = path14.join(p, trimmed + ext);
|
|
3914
|
+
try {
|
|
3915
|
+
const fs17 = __require("fs");
|
|
3916
|
+
if (fs17.existsSync(fullPath)) {
|
|
3917
|
+
const stat2 = fs17.statSync(fullPath);
|
|
3918
|
+
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
3919
|
+
return fullPath;
|
|
3920
|
+
}
|
|
3921
|
+
}
|
|
3922
|
+
} catch {
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3744
3925
|
}
|
|
3926
|
+
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
3745
3927
|
}
|
|
3746
3928
|
function isScriptBinary(binaryPath) {
|
|
3747
3929
|
if (!path14.isAbsolute(binaryPath)) return false;
|
|
3748
3930
|
try {
|
|
3749
|
-
const
|
|
3750
|
-
const resolved =
|
|
3931
|
+
const fs17 = __require("fs");
|
|
3932
|
+
const resolved = fs17.realpathSync(binaryPath);
|
|
3751
3933
|
const head = Buffer.alloc(8);
|
|
3752
|
-
const fd =
|
|
3753
|
-
|
|
3754
|
-
|
|
3934
|
+
const fd = fs17.openSync(resolved, "r");
|
|
3935
|
+
fs17.readSync(fd, head, 0, 8, 0);
|
|
3936
|
+
fs17.closeSync(fd);
|
|
3755
3937
|
let i = 0;
|
|
3756
3938
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
3757
3939
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -3762,12 +3944,12 @@ function isScriptBinary(binaryPath) {
|
|
|
3762
3944
|
function looksLikeMachOOrElf(filePath) {
|
|
3763
3945
|
if (!path14.isAbsolute(filePath)) return false;
|
|
3764
3946
|
try {
|
|
3765
|
-
const
|
|
3766
|
-
const resolved =
|
|
3947
|
+
const fs17 = __require("fs");
|
|
3948
|
+
const resolved = fs17.realpathSync(filePath);
|
|
3767
3949
|
const buf = Buffer.alloc(8);
|
|
3768
|
-
const fd =
|
|
3769
|
-
|
|
3770
|
-
|
|
3950
|
+
const fd = fs17.openSync(resolved, "r");
|
|
3951
|
+
fs17.readSync(fd, buf, 0, 8, 0);
|
|
3952
|
+
fs17.closeSync(fd);
|
|
3771
3953
|
let i = 0;
|
|
3772
3954
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
3773
3955
|
const b = buf.subarray(i);
|
|
@@ -9011,7 +9193,7 @@ var P2pRelayFailureError = class extends Error {
|
|
|
9011
9193
|
|
|
9012
9194
|
// src/config/state-store.ts
|
|
9013
9195
|
init_config();
|
|
9014
|
-
import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as
|
|
9196
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
|
|
9015
9197
|
import { join as join11 } from "path";
|
|
9016
9198
|
var DEFAULT_STATE = {
|
|
9017
9199
|
recentActivity: [],
|
|
@@ -9074,17 +9256,19 @@ function loadState() {
|
|
|
9074
9256
|
function saveState(state) {
|
|
9075
9257
|
const statePath = getStatePath();
|
|
9076
9258
|
const normalized = normalizeState(state);
|
|
9077
|
-
|
|
9259
|
+
writeFileSync3(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
9078
9260
|
}
|
|
9079
9261
|
function resetState() {
|
|
9080
9262
|
saveState({ ...DEFAULT_STATE });
|
|
9081
9263
|
}
|
|
9082
9264
|
|
|
9083
9265
|
// src/detection/ide-detector.ts
|
|
9084
|
-
import {
|
|
9085
|
-
import {
|
|
9266
|
+
import { exec as exec2 } from "child_process";
|
|
9267
|
+
import { promisify as promisify3 } from "util";
|
|
9268
|
+
import { existsSync as existsSync12, statSync as statSync4 } from "fs";
|
|
9086
9269
|
import { platform as platform2, homedir as homedir5 } from "os";
|
|
9087
9270
|
import * as path10 from "path";
|
|
9271
|
+
var execAsync2 = promisify3(exec2);
|
|
9088
9272
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
9089
9273
|
var registeredIDEs = /* @__PURE__ */ new Map();
|
|
9090
9274
|
function registerIDEDefinition(def) {
|
|
@@ -9108,24 +9292,33 @@ function findCliCommand(command) {
|
|
|
9108
9292
|
const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
|
|
9109
9293
|
return existsSync12(resolved) ? resolved : null;
|
|
9110
9294
|
}
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9295
|
+
const isWin = platform2() === "win32";
|
|
9296
|
+
const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
|
|
9297
|
+
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
9298
|
+
for (const p of paths) {
|
|
9299
|
+
if (!p) continue;
|
|
9300
|
+
for (const ext of exes) {
|
|
9301
|
+
const fullPath = path10.join(p, trimmed + ext);
|
|
9302
|
+
try {
|
|
9303
|
+
if (existsSync12(fullPath)) {
|
|
9304
|
+
const stat2 = statSync4(fullPath);
|
|
9305
|
+
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
9306
|
+
return fullPath;
|
|
9307
|
+
}
|
|
9308
|
+
}
|
|
9309
|
+
} catch {
|
|
9310
|
+
}
|
|
9311
|
+
}
|
|
9119
9312
|
}
|
|
9313
|
+
return null;
|
|
9120
9314
|
}
|
|
9121
|
-
function getIdeVersion(cliCommand) {
|
|
9315
|
+
async function getIdeVersion(cliCommand) {
|
|
9122
9316
|
try {
|
|
9123
|
-
const
|
|
9317
|
+
const { stdout } = await execAsync2(`"${cliCommand}" --version`, {
|
|
9124
9318
|
encoding: "utf-8",
|
|
9125
|
-
timeout: 1e4
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
return result.split("\n")[0] || null;
|
|
9319
|
+
timeout: 1e4
|
|
9320
|
+
});
|
|
9321
|
+
return stdout.trim().split("\n")[0] || null;
|
|
9129
9322
|
} catch {
|
|
9130
9323
|
return null;
|
|
9131
9324
|
}
|
|
@@ -9173,7 +9366,7 @@ async function detectIDEs(providerLoader) {
|
|
|
9173
9366
|
}
|
|
9174
9367
|
}
|
|
9175
9368
|
const installed = os22 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
9176
|
-
const version = resolvedCli ? getIdeVersion(resolvedCli) : null;
|
|
9369
|
+
const version = resolvedCli ? await getIdeVersion(resolvedCli) : null;
|
|
9177
9370
|
results.push({
|
|
9178
9371
|
id: def.id,
|
|
9179
9372
|
name: def.name,
|
|
@@ -9193,19 +9386,23 @@ init_cli_detector();
|
|
|
9193
9386
|
|
|
9194
9387
|
// src/system/host-memory.ts
|
|
9195
9388
|
import * as os4 from "os";
|
|
9196
|
-
import {
|
|
9197
|
-
|
|
9198
|
-
|
|
9389
|
+
import { exec as exec3 } from "child_process";
|
|
9390
|
+
import { promisify as promisify4 } from "util";
|
|
9391
|
+
var execAsync3 = promisify4(exec3);
|
|
9392
|
+
var cachedDarwinAvail = null;
|
|
9393
|
+
var darwinMemoryInterval = null;
|
|
9394
|
+
async function updateDarwinMemoryCache() {
|
|
9395
|
+
if (os4.platform() !== "darwin") return;
|
|
9199
9396
|
try {
|
|
9200
|
-
const
|
|
9397
|
+
const { stdout } = await execAsync3("vm_stat", {
|
|
9201
9398
|
encoding: "utf-8",
|
|
9202
9399
|
timeout: 4e3,
|
|
9203
9400
|
maxBuffer: 256 * 1024
|
|
9204
9401
|
});
|
|
9205
|
-
const pageSizeMatch =
|
|
9402
|
+
const pageSizeMatch = stdout.match(/page size of (\d+)\s*bytes/i);
|
|
9206
9403
|
const pageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : 4096;
|
|
9207
9404
|
const counts = {};
|
|
9208
|
-
for (const line of
|
|
9405
|
+
for (const line of stdout.split("\n")) {
|
|
9209
9406
|
const m = line.match(/^\s*Pages\s+([^:]+):\s+([\d,]+)\s*\.?/);
|
|
9210
9407
|
if (!m) continue;
|
|
9211
9408
|
const key = m[1].trim().toLowerCase().replace(/\s+/g, "_");
|
|
@@ -9219,18 +9416,24 @@ function parseDarwinAvailableBytes(totalMem) {
|
|
|
9219
9416
|
const fileBacked = counts["file_backed"] ?? 0;
|
|
9220
9417
|
const availPages = free + inactive + speculative + purgeable + fileBacked;
|
|
9221
9418
|
const bytes = availPages * pageSize;
|
|
9222
|
-
|
|
9223
|
-
return Math.min(bytes, totalMem);
|
|
9419
|
+
cachedDarwinAvail = Number.isFinite(bytes) && bytes >= 0 ? Math.min(bytes, os4.totalmem()) : null;
|
|
9224
9420
|
} catch {
|
|
9225
|
-
return null;
|
|
9226
9421
|
}
|
|
9227
9422
|
}
|
|
9228
9423
|
function getHostMemorySnapshot() {
|
|
9424
|
+
if (os4.platform() === "darwin" && !darwinMemoryInterval) {
|
|
9425
|
+
updateDarwinMemoryCache();
|
|
9426
|
+
darwinMemoryInterval = setInterval(updateDarwinMemoryCache, 3e3);
|
|
9427
|
+
darwinMemoryInterval.unref();
|
|
9428
|
+
}
|
|
9229
9429
|
const totalMem = os4.totalmem();
|
|
9230
9430
|
const freeMem = os4.freemem();
|
|
9231
|
-
const
|
|
9232
|
-
|
|
9233
|
-
|
|
9431
|
+
const availableMem = os4.platform() === "darwin" ? cachedDarwinAvail ?? freeMem : freeMem;
|
|
9432
|
+
return {
|
|
9433
|
+
totalMem,
|
|
9434
|
+
freeMem,
|
|
9435
|
+
availableMem
|
|
9436
|
+
};
|
|
9234
9437
|
}
|
|
9235
9438
|
|
|
9236
9439
|
// src/session-host/runtime-surface.ts
|
|
@@ -11595,7 +11798,7 @@ ${cleanBody}`;
|
|
|
11595
11798
|
}
|
|
11596
11799
|
|
|
11597
11800
|
// src/config/chat-history.ts
|
|
11598
|
-
import * as
|
|
11801
|
+
import * as fs4 from "fs";
|
|
11599
11802
|
import * as path11 from "path";
|
|
11600
11803
|
import * as os5 from "os";
|
|
11601
11804
|
var HISTORY_DIR = path11.join(os5.homedir(), ".adhdev", "history");
|
|
@@ -11715,8 +11918,8 @@ function buildSavedHistorySessionSummaryMapFromEntries(entries) {
|
|
|
11715
11918
|
function readPersistedSavedHistorySessionSummaries(dir) {
|
|
11716
11919
|
try {
|
|
11717
11920
|
const filePath = getSavedHistoryIndexFilePath(dir);
|
|
11718
|
-
if (!
|
|
11719
|
-
const raw = JSON.parse(
|
|
11921
|
+
if (!fs4.existsSync(filePath)) return null;
|
|
11922
|
+
const raw = JSON.parse(fs4.readFileSync(filePath, "utf-8"));
|
|
11720
11923
|
if (!raw || raw.version !== SAVED_HISTORY_INDEX_VERSION || !raw.sessions || typeof raw.sessions !== "object") {
|
|
11721
11924
|
return null;
|
|
11722
11925
|
}
|
|
@@ -11743,7 +11946,7 @@ function sanitizeHistoryFileSegment(value) {
|
|
|
11743
11946
|
}
|
|
11744
11947
|
function listHistoryFiles(dir, historySessionId) {
|
|
11745
11948
|
const sanitizedSessionId = historySessionId ? sanitizeHistoryFileSegment(historySessionId) : "";
|
|
11746
|
-
return
|
|
11949
|
+
return fs4.readdirSync(dir).filter((file) => {
|
|
11747
11950
|
if (!file.endsWith(".jsonl")) return false;
|
|
11748
11951
|
if (sanitizedSessionId) {
|
|
11749
11952
|
return file.startsWith(`${sanitizedSessionId}_`);
|
|
@@ -11761,7 +11964,7 @@ function extractSavedHistorySessionIdFromFile(file) {
|
|
|
11761
11964
|
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
11762
11965
|
return new Map(files.map((file) => {
|
|
11763
11966
|
try {
|
|
11764
|
-
const stat2 =
|
|
11967
|
+
const stat2 = fs4.statSync(path11.join(dir, file));
|
|
11765
11968
|
return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
|
|
11766
11969
|
} catch {
|
|
11767
11970
|
return [file, `${file}:missing`];
|
|
@@ -11784,8 +11987,8 @@ function sleepBlocking(ms) {
|
|
|
11784
11987
|
function loadPersistedSavedHistoryIndexFromFile(dir) {
|
|
11785
11988
|
try {
|
|
11786
11989
|
const filePath = getSavedHistoryIndexFilePath(dir);
|
|
11787
|
-
if (!
|
|
11788
|
-
const raw = JSON.parse(
|
|
11990
|
+
if (!fs4.existsSync(filePath)) return /* @__PURE__ */ new Map();
|
|
11991
|
+
const raw = JSON.parse(fs4.readFileSync(filePath, "utf-8"));
|
|
11789
11992
|
if (!raw || raw.version !== SAVED_HISTORY_INDEX_VERSION || !raw.files || typeof raw.files !== "object") {
|
|
11790
11993
|
return /* @__PURE__ */ new Map();
|
|
11791
11994
|
}
|
|
@@ -11807,27 +12010,27 @@ function writePersistedSavedHistoryIndexFile(dir, entries) {
|
|
|
11807
12010
|
files: Object.fromEntries(entries.entries()),
|
|
11808
12011
|
sessions: buildSavedHistorySessionSummaryMapFromEntries(entries)
|
|
11809
12012
|
};
|
|
11810
|
-
|
|
11811
|
-
|
|
12013
|
+
fs4.writeFileSync(tempPath, JSON.stringify(payload), "utf-8");
|
|
12014
|
+
fs4.renameSync(tempPath, filePath);
|
|
11812
12015
|
}
|
|
11813
12016
|
function acquireSavedHistoryIndexLock(dir) {
|
|
11814
12017
|
const lockPath = getSavedHistoryIndexLockPath(dir);
|
|
11815
12018
|
const deadline = Date.now() + SAVED_HISTORY_INDEX_LOCK_WAIT_MS;
|
|
11816
12019
|
while (Date.now() <= deadline) {
|
|
11817
12020
|
try {
|
|
11818
|
-
|
|
12021
|
+
fs4.mkdirSync(lockPath);
|
|
11819
12022
|
return () => {
|
|
11820
12023
|
try {
|
|
11821
|
-
|
|
12024
|
+
fs4.rmSync(lockPath, { recursive: true, force: true });
|
|
11822
12025
|
} catch {
|
|
11823
12026
|
}
|
|
11824
12027
|
};
|
|
11825
12028
|
} catch (error) {
|
|
11826
12029
|
if (error?.code !== "EEXIST") return null;
|
|
11827
12030
|
try {
|
|
11828
|
-
const stat2 =
|
|
12031
|
+
const stat2 = fs4.statSync(lockPath);
|
|
11829
12032
|
if (Date.now() - stat2.mtimeMs > SAVED_HISTORY_INDEX_LOCK_STALE_MS) {
|
|
11830
|
-
|
|
12033
|
+
fs4.rmSync(lockPath, { recursive: true, force: true });
|
|
11831
12034
|
continue;
|
|
11832
12035
|
}
|
|
11833
12036
|
} catch {
|
|
@@ -11874,7 +12077,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
|
|
|
11874
12077
|
}
|
|
11875
12078
|
for (const file of Array.from(currentEntries.keys())) {
|
|
11876
12079
|
if (incomingFiles.has(file)) continue;
|
|
11877
|
-
if (!
|
|
12080
|
+
if (!fs4.existsSync(path11.join(dir, file))) {
|
|
11878
12081
|
currentEntries.delete(file);
|
|
11879
12082
|
}
|
|
11880
12083
|
}
|
|
@@ -11882,14 +12085,14 @@ function savePersistedSavedHistoryIndex(dir, entries) {
|
|
|
11882
12085
|
}
|
|
11883
12086
|
function invalidatePersistedSavedHistoryIndex(agentType, dir) {
|
|
11884
12087
|
try {
|
|
11885
|
-
|
|
12088
|
+
fs4.rmSync(getSavedHistoryIndexFilePath(dir), { force: true });
|
|
11886
12089
|
} catch {
|
|
11887
12090
|
}
|
|
11888
12091
|
savedHistorySessionCache.delete(agentType.replace(/[^a-zA-Z0-9_-]/g, "_"));
|
|
11889
12092
|
}
|
|
11890
12093
|
function buildSavedHistoryIndexFileSignature(dir) {
|
|
11891
12094
|
try {
|
|
11892
|
-
const stat2 =
|
|
12095
|
+
const stat2 = fs4.statSync(getSavedHistoryIndexFilePath(dir));
|
|
11893
12096
|
return `index:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
|
|
11894
12097
|
} catch {
|
|
11895
12098
|
return "index:missing";
|
|
@@ -11897,10 +12100,10 @@ function buildSavedHistoryIndexFileSignature(dir) {
|
|
|
11897
12100
|
}
|
|
11898
12101
|
function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
11899
12102
|
try {
|
|
11900
|
-
const indexStat =
|
|
12103
|
+
const indexStat = fs4.statSync(getSavedHistoryIndexFilePath(dir));
|
|
11901
12104
|
const files = listHistoryFiles(dir);
|
|
11902
12105
|
for (const file of files) {
|
|
11903
|
-
const stat2 =
|
|
12106
|
+
const stat2 = fs4.statSync(path11.join(dir, file));
|
|
11904
12107
|
if (stat2.mtimeMs > indexStat.mtimeMs) return true;
|
|
11905
12108
|
}
|
|
11906
12109
|
return false;
|
|
@@ -11910,7 +12113,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
11910
12113
|
}
|
|
11911
12114
|
function buildSavedHistoryFileSignature(dir, file) {
|
|
11912
12115
|
try {
|
|
11913
|
-
const stat2 =
|
|
12116
|
+
const stat2 = fs4.statSync(path11.join(dir, file));
|
|
11914
12117
|
return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
|
|
11915
12118
|
} catch {
|
|
11916
12119
|
return `${file}:missing`;
|
|
@@ -11991,7 +12194,7 @@ function computeSavedHistoryFileSummary(dir, file) {
|
|
|
11991
12194
|
const historySessionId = extractSavedHistorySessionIdFromFile(file);
|
|
11992
12195
|
if (!historySessionId) return null;
|
|
11993
12196
|
const filePath = path11.join(dir, file);
|
|
11994
|
-
const content =
|
|
12197
|
+
const content = fs4.readFileSync(filePath, "utf-8");
|
|
11995
12198
|
const lines = content.split("\n").filter(Boolean);
|
|
11996
12199
|
let messageCount = 0;
|
|
11997
12200
|
let firstMessageAt = 0;
|
|
@@ -12052,7 +12255,7 @@ function scheduleSavedHistoryBackgroundRefresh(agentType, dir) {
|
|
|
12052
12255
|
savedHistoryBackgroundRefresh.add(key);
|
|
12053
12256
|
setTimeout(() => {
|
|
12054
12257
|
try {
|
|
12055
|
-
if (!
|
|
12258
|
+
if (!fs4.existsSync(dir)) return;
|
|
12056
12259
|
const files = listHistoryFiles(dir);
|
|
12057
12260
|
const fileSignatures = buildSavedHistoryFileSignatureMap(dir, files);
|
|
12058
12261
|
const persistedEntries = loadPersistedSavedHistoryIndex(dir);
|
|
@@ -12198,13 +12401,13 @@ var ChatHistoryWriter = class {
|
|
|
12198
12401
|
}
|
|
12199
12402
|
if (newMessages.length === 0) return;
|
|
12200
12403
|
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
12201
|
-
|
|
12404
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
12202
12405
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
12203
12406
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
12204
12407
|
const fileName = `${filePrefix}${date}.jsonl`;
|
|
12205
12408
|
const filePath = path11.join(dir, fileName);
|
|
12206
12409
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
12207
|
-
|
|
12410
|
+
fs4.appendFileSync(filePath, lines, "utf-8");
|
|
12208
12411
|
updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
|
|
12209
12412
|
const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
|
|
12210
12413
|
if (!historySessionId && messages.length < prevCount * 0.5 && prevCount > 3) {
|
|
@@ -12294,7 +12497,7 @@ var ChatHistoryWriter = class {
|
|
|
12294
12497
|
if (!id || !ws) return;
|
|
12295
12498
|
try {
|
|
12296
12499
|
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
12297
|
-
|
|
12500
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
12298
12501
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
12299
12502
|
const fileName = `${this.sanitize(id)}_${date}.jsonl`;
|
|
12300
12503
|
const filePath = path11.join(dir, fileName);
|
|
@@ -12309,7 +12512,7 @@ var ChatHistoryWriter = class {
|
|
|
12309
12512
|
historySessionId: id,
|
|
12310
12513
|
workspace: ws
|
|
12311
12514
|
};
|
|
12312
|
-
|
|
12515
|
+
fs4.appendFileSync(filePath, JSON.stringify(record) + "\n", "utf-8");
|
|
12313
12516
|
updateSavedHistoryIndexForSessionStart(agentType, dir, fileName, id, ws);
|
|
12314
12517
|
} catch {
|
|
12315
12518
|
}
|
|
@@ -12344,14 +12547,14 @@ var ChatHistoryWriter = class {
|
|
|
12344
12547
|
this.lastSeenCounts.delete(fromDedupKey);
|
|
12345
12548
|
}
|
|
12346
12549
|
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
12347
|
-
if (!
|
|
12550
|
+
if (!fs4.existsSync(dir)) return;
|
|
12348
12551
|
const fromPrefix = `${this.sanitize(fromId)}_`;
|
|
12349
12552
|
const toPrefix = `${this.sanitize(toId)}_`;
|
|
12350
|
-
const files =
|
|
12553
|
+
const files = fs4.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
|
|
12351
12554
|
for (const file of files) {
|
|
12352
12555
|
const sourcePath = path11.join(dir, file);
|
|
12353
12556
|
const targetPath = path11.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
|
|
12354
|
-
const sourceLines =
|
|
12557
|
+
const sourceLines = fs4.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
12355
12558
|
const rewritten = sourceLines.map((line) => {
|
|
12356
12559
|
try {
|
|
12357
12560
|
const parsed = JSON.parse(line);
|
|
@@ -12365,16 +12568,16 @@ var ChatHistoryWriter = class {
|
|
|
12365
12568
|
}
|
|
12366
12569
|
}).filter((line) => !!line);
|
|
12367
12570
|
if (rewritten.length === 0) {
|
|
12368
|
-
|
|
12571
|
+
fs4.unlinkSync(sourcePath);
|
|
12369
12572
|
continue;
|
|
12370
12573
|
}
|
|
12371
|
-
const existing =
|
|
12574
|
+
const existing = fs4.existsSync(targetPath) ? new Set(fs4.readFileSync(targetPath, "utf-8").split("\n").filter(Boolean)) : /* @__PURE__ */ new Set();
|
|
12372
12575
|
const nextLines = rewritten.filter((line) => !existing.has(line));
|
|
12373
12576
|
if (nextLines.length > 0) {
|
|
12374
|
-
|
|
12577
|
+
fs4.appendFileSync(targetPath, `${nextLines.join("\n")}
|
|
12375
12578
|
`, "utf-8");
|
|
12376
12579
|
}
|
|
12377
|
-
|
|
12580
|
+
fs4.unlinkSync(sourcePath);
|
|
12378
12581
|
}
|
|
12379
12582
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
12380
12583
|
} catch {
|
|
@@ -12385,13 +12588,13 @@ var ChatHistoryWriter = class {
|
|
|
12385
12588
|
if (!sessionId) return;
|
|
12386
12589
|
try {
|
|
12387
12590
|
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
12388
|
-
if (!
|
|
12591
|
+
if (!fs4.existsSync(dir)) return;
|
|
12389
12592
|
const prefix = `${this.sanitize(sessionId)}_`;
|
|
12390
|
-
const files =
|
|
12593
|
+
const files = fs4.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
|
|
12391
12594
|
const seen = /* @__PURE__ */ new Set();
|
|
12392
12595
|
for (const file of files) {
|
|
12393
12596
|
const filePath = path11.join(dir, file);
|
|
12394
|
-
const lines =
|
|
12597
|
+
const lines = fs4.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
12395
12598
|
const next = [];
|
|
12396
12599
|
for (const line of lines) {
|
|
12397
12600
|
let parsed = null;
|
|
@@ -12420,10 +12623,10 @@ var ChatHistoryWriter = class {
|
|
|
12420
12623
|
}
|
|
12421
12624
|
const collapsed = collapseReplayAssistantTurns(dedupedAdjacent, historyBehavior);
|
|
12422
12625
|
if (collapsed.length === 0) {
|
|
12423
|
-
|
|
12626
|
+
fs4.unlinkSync(filePath);
|
|
12424
12627
|
continue;
|
|
12425
12628
|
}
|
|
12426
|
-
|
|
12629
|
+
fs4.writeFileSync(filePath, `${collapsed.map((entry) => JSON.stringify(entry)).join("\n")}
|
|
12427
12630
|
`, "utf-8");
|
|
12428
12631
|
}
|
|
12429
12632
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
@@ -12440,18 +12643,18 @@ var ChatHistoryWriter = class {
|
|
|
12440
12643
|
/** Delete history files older than 30 days */
|
|
12441
12644
|
async rotateOldFiles() {
|
|
12442
12645
|
try {
|
|
12443
|
-
if (!
|
|
12646
|
+
if (!fs4.existsSync(HISTORY_DIR)) return;
|
|
12444
12647
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
12445
|
-
const agentDirs =
|
|
12648
|
+
const agentDirs = fs4.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
12446
12649
|
for (const dir of agentDirs) {
|
|
12447
12650
|
const dirPath = path11.join(HISTORY_DIR, dir.name);
|
|
12448
|
-
const files =
|
|
12651
|
+
const files = fs4.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
12449
12652
|
let removedAny = false;
|
|
12450
12653
|
for (const file of files) {
|
|
12451
12654
|
const filePath = path11.join(dirPath, file);
|
|
12452
|
-
const stat2 =
|
|
12655
|
+
const stat2 = fs4.statSync(filePath);
|
|
12453
12656
|
if (stat2.mtimeMs < cutoff) {
|
|
12454
|
-
|
|
12657
|
+
fs4.unlinkSync(filePath);
|
|
12455
12658
|
removedAny = true;
|
|
12456
12659
|
}
|
|
12457
12660
|
}
|
|
@@ -12499,13 +12702,13 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
12499
12702
|
try {
|
|
12500
12703
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
12501
12704
|
const dir = path11.join(HISTORY_DIR, sanitized);
|
|
12502
|
-
if (!
|
|
12705
|
+
if (!fs4.existsSync(dir)) return { messages: [], hasMore: false };
|
|
12503
12706
|
const files = listHistoryFiles(dir, historySessionId);
|
|
12504
12707
|
const allMessages = [];
|
|
12505
12708
|
const seen = /* @__PURE__ */ new Set();
|
|
12506
12709
|
for (const file of files) {
|
|
12507
12710
|
const filePath = path11.join(dir, file);
|
|
12508
|
-
const content =
|
|
12711
|
+
const content = fs4.readFileSync(filePath, "utf-8");
|
|
12509
12712
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
12510
12713
|
for (let i = 0; i < lines.length; i++) {
|
|
12511
12714
|
try {
|
|
@@ -12529,7 +12732,7 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
|
12529
12732
|
try {
|
|
12530
12733
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
12531
12734
|
const dir = path11.join(HISTORY_DIR, sanitized);
|
|
12532
|
-
if (!
|
|
12735
|
+
if (!fs4.existsSync(dir)) {
|
|
12533
12736
|
savedHistorySessionCache.delete(sanitized);
|
|
12534
12737
|
return { sessions: [], hasMore: false };
|
|
12535
12738
|
}
|
|
@@ -12590,10 +12793,10 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
|
12590
12793
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
12591
12794
|
try {
|
|
12592
12795
|
const dir = path11.join(HISTORY_DIR, agentType);
|
|
12593
|
-
if (!
|
|
12796
|
+
if (!fs4.existsSync(dir)) return null;
|
|
12594
12797
|
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
12595
12798
|
for (const file of files) {
|
|
12596
|
-
const lines =
|
|
12799
|
+
const lines = fs4.readFileSync(path11.join(dir, file), "utf-8").split("\n").filter(Boolean);
|
|
12597
12800
|
for (const line of lines) {
|
|
12598
12801
|
try {
|
|
12599
12802
|
const parsed = JSON.parse(line);
|
|
@@ -12614,16 +12817,16 @@ function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
|
12614
12817
|
if (records.length === 0) return false;
|
|
12615
12818
|
try {
|
|
12616
12819
|
const dir = path11.join(HISTORY_DIR, agentType);
|
|
12617
|
-
|
|
12820
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
12618
12821
|
const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
12619
|
-
for (const file of
|
|
12822
|
+
for (const file of fs4.readdirSync(dir)) {
|
|
12620
12823
|
if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
|
|
12621
|
-
|
|
12824
|
+
fs4.unlinkSync(path11.join(dir, file));
|
|
12622
12825
|
}
|
|
12623
12826
|
}
|
|
12624
12827
|
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
12625
12828
|
const filePath = path11.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
12626
|
-
|
|
12829
|
+
fs4.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
|
|
12627
12830
|
`, "utf-8");
|
|
12628
12831
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
12629
12832
|
savedHistorySessionCache.delete(agentType.replace(/[^a-zA-Z0-9_-]/g, "_"));
|
|
@@ -12731,7 +12934,7 @@ function buildNativeSessionSummary(agentType, historySessionId, records, sourceP
|
|
|
12731
12934
|
if (visible.length === 0) return null;
|
|
12732
12935
|
let sourceMtimeMs = 0;
|
|
12733
12936
|
try {
|
|
12734
|
-
sourceMtimeMs =
|
|
12937
|
+
sourceMtimeMs = fs4.statSync(sourcePath).mtimeMs;
|
|
12735
12938
|
} catch {
|
|
12736
12939
|
}
|
|
12737
12940
|
const firstMessageAt = visible[0]?.receivedAt || sourceMtimeMs || Date.now();
|
|
@@ -13504,6 +13707,19 @@ function formatAutoApprovalMessage(modalMessage, buttonLabel) {
|
|
|
13504
13707
|
}
|
|
13505
13708
|
|
|
13506
13709
|
// src/providers/ide-provider-instance.ts
|
|
13710
|
+
async function withTimeout(promise, timeoutMs, label) {
|
|
13711
|
+
let timer = null;
|
|
13712
|
+
try {
|
|
13713
|
+
return await Promise.race([
|
|
13714
|
+
promise,
|
|
13715
|
+
new Promise((_, reject) => {
|
|
13716
|
+
timer = setTimeout(() => reject(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
13717
|
+
})
|
|
13718
|
+
]);
|
|
13719
|
+
} finally {
|
|
13720
|
+
if (timer) clearTimeout(timer);
|
|
13721
|
+
}
|
|
13722
|
+
}
|
|
13507
13723
|
var IdeProviderInstance = class {
|
|
13508
13724
|
type;
|
|
13509
13725
|
category = "ide";
|
|
@@ -13728,7 +13944,7 @@ var IdeProviderInstance = class {
|
|
|
13728
13944
|
if (webviewScript) {
|
|
13729
13945
|
const matchText = this.provider.webviewMatchText;
|
|
13730
13946
|
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
13731
|
-
const webviewRaw = await cdp.evaluateInWebviewFrame(webviewScript, matchFn);
|
|
13947
|
+
const webviewRaw = await withTimeout(cdp.evaluateInWebviewFrame(webviewScript, matchFn), 3e4, "evaluateInWebviewFrame");
|
|
13732
13948
|
if (webviewRaw) {
|
|
13733
13949
|
raw = typeof webviewRaw === "string" ? (() => {
|
|
13734
13950
|
try {
|
|
@@ -13743,7 +13959,7 @@ var IdeProviderInstance = class {
|
|
|
13743
13959
|
if (!raw) {
|
|
13744
13960
|
const readChatScript = this.getReadChatScript();
|
|
13745
13961
|
if (!readChatScript) return;
|
|
13746
|
-
raw = await cdp.evaluate(readChatScript, 3e4);
|
|
13962
|
+
raw = await withTimeout(cdp.evaluate(readChatScript, 3e4), 3e4, "evaluate.readChatScript");
|
|
13747
13963
|
if (typeof raw === "string") {
|
|
13748
13964
|
try {
|
|
13749
13965
|
raw = JSON.parse(raw);
|
|
@@ -14054,7 +14270,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
14054
14270
|
now
|
|
14055
14271
|
);
|
|
14056
14272
|
LOG.info("IdeInstance", `[IdeInstance:${this.type}] autoApprove: executing resolveAction for "${targetButton}"`);
|
|
14057
|
-
let rawResult = await cdp.evaluate(script, 1e4);
|
|
14273
|
+
let rawResult = await withTimeout(cdp.evaluate(script, 1e4), 1e4, "evaluate.autoApprove");
|
|
14058
14274
|
if (typeof rawResult === "string") {
|
|
14059
14275
|
try {
|
|
14060
14276
|
rawResult = JSON.parse(rawResult);
|
|
@@ -15123,7 +15339,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
|
|
|
15123
15339
|
}
|
|
15124
15340
|
|
|
15125
15341
|
// src/commands/chat-commands.ts
|
|
15126
|
-
import * as
|
|
15342
|
+
import * as fs5 from "fs";
|
|
15127
15343
|
import * as os6 from "os";
|
|
15128
15344
|
import * as path12 from "path";
|
|
15129
15345
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
@@ -15696,11 +15912,11 @@ function buildChatDebugBundleSummary(bundle) {
|
|
|
15696
15912
|
function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
|
|
15697
15913
|
const bundleId = createChatDebugBundleId(targetSessionId);
|
|
15698
15914
|
const dir = getChatDebugBundleDir();
|
|
15699
|
-
|
|
15915
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
15700
15916
|
const savedPath = path12.join(dir, `${bundleId}.json`);
|
|
15701
15917
|
const json = `${JSON.stringify(bundle, null, 2)}
|
|
15702
15918
|
`;
|
|
15703
|
-
|
|
15919
|
+
fs5.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
|
|
15704
15920
|
return { bundleId, savedPath, sizeBytes: Buffer.byteLength(json, "utf8") };
|
|
15705
15921
|
}
|
|
15706
15922
|
function isDaemonFileDebugDelivery(args) {
|
|
@@ -16863,7 +17079,7 @@ async function handleResolveAction(h, args) {
|
|
|
16863
17079
|
}
|
|
16864
17080
|
|
|
16865
17081
|
// src/commands/cdp-commands.ts
|
|
16866
|
-
import * as
|
|
17082
|
+
import * as fs6 from "fs";
|
|
16867
17083
|
import * as path13 from "path";
|
|
16868
17084
|
import * as os7 from "os";
|
|
16869
17085
|
var KEY_TO_VK = {
|
|
@@ -17136,7 +17352,7 @@ function resolveSafePath(requestedPath) {
|
|
|
17136
17352
|
return path13.resolve(inputPath);
|
|
17137
17353
|
}
|
|
17138
17354
|
function listDirectoryEntriesSafe(dirPath) {
|
|
17139
|
-
const entries =
|
|
17355
|
+
const entries = fs6.readdirSync(dirPath, { withFileTypes: true });
|
|
17140
17356
|
const files = [];
|
|
17141
17357
|
for (const entry of entries) {
|
|
17142
17358
|
const entryPath = path13.join(dirPath, entry.name);
|
|
@@ -17148,14 +17364,14 @@ function listDirectoryEntriesSafe(dirPath) {
|
|
|
17148
17364
|
if (entry.isFile()) {
|
|
17149
17365
|
let size;
|
|
17150
17366
|
try {
|
|
17151
|
-
size =
|
|
17367
|
+
size = fs6.statSync(entryPath).size;
|
|
17152
17368
|
} catch {
|
|
17153
17369
|
size = void 0;
|
|
17154
17370
|
}
|
|
17155
17371
|
files.push({ name: entry.name, type: "file", size });
|
|
17156
17372
|
continue;
|
|
17157
17373
|
}
|
|
17158
|
-
const stat2 =
|
|
17374
|
+
const stat2 = fs6.statSync(entryPath);
|
|
17159
17375
|
files.push({
|
|
17160
17376
|
name: entry.name,
|
|
17161
17377
|
type: stat2.isDirectory() ? "directory" : "file",
|
|
@@ -17173,7 +17389,7 @@ function listWindowsDriveEntries(excludePath) {
|
|
|
17173
17389
|
const letter = String.fromCharCode(code);
|
|
17174
17390
|
const root = `${letter}:\\`;
|
|
17175
17391
|
try {
|
|
17176
|
-
if (!
|
|
17392
|
+
if (!fs6.existsSync(root)) continue;
|
|
17177
17393
|
if (excluded && root.toLowerCase() === excluded) continue;
|
|
17178
17394
|
drives.push({ name: `${letter}:`, type: "directory", path: root });
|
|
17179
17395
|
} catch {
|
|
@@ -17184,7 +17400,7 @@ function listWindowsDriveEntries(excludePath) {
|
|
|
17184
17400
|
async function handleFileRead(h, args) {
|
|
17185
17401
|
try {
|
|
17186
17402
|
const filePath = resolveSafePath(args?.path);
|
|
17187
|
-
const content =
|
|
17403
|
+
const content = fs6.readFileSync(filePath, "utf-8");
|
|
17188
17404
|
return { success: true, content, path: filePath };
|
|
17189
17405
|
} catch (e) {
|
|
17190
17406
|
return { success: false, error: e.message };
|
|
@@ -17193,8 +17409,8 @@ async function handleFileRead(h, args) {
|
|
|
17193
17409
|
async function handleFileWrite(h, args) {
|
|
17194
17410
|
try {
|
|
17195
17411
|
const filePath = resolveSafePath(args?.path);
|
|
17196
|
-
|
|
17197
|
-
|
|
17412
|
+
fs6.mkdirSync(path13.dirname(filePath), { recursive: true });
|
|
17413
|
+
fs6.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
17198
17414
|
return { success: true, path: filePath };
|
|
17199
17415
|
} catch (e) {
|
|
17200
17416
|
return { success: false, error: e.message };
|
|
@@ -18322,7 +18538,7 @@ init_config();
|
|
|
18322
18538
|
import * as os13 from "os";
|
|
18323
18539
|
import * as path18 from "path";
|
|
18324
18540
|
import * as crypto4 from "crypto";
|
|
18325
|
-
import { existsSync as existsSync16, mkdirSync as
|
|
18541
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync10, writeFileSync as writeFileSync8 } from "fs";
|
|
18326
18542
|
import { execFileSync } from "child_process";
|
|
18327
18543
|
import chalk from "chalk";
|
|
18328
18544
|
|
|
@@ -18330,7 +18546,7 @@ import chalk from "chalk";
|
|
|
18330
18546
|
import * as os12 from "os";
|
|
18331
18547
|
import * as path16 from "path";
|
|
18332
18548
|
import * as crypto3 from "crypto";
|
|
18333
|
-
import * as
|
|
18549
|
+
import * as fs7 from "fs";
|
|
18334
18550
|
import { createRequire } from "module";
|
|
18335
18551
|
init_provider_cli_adapter();
|
|
18336
18552
|
init_logger();
|
|
@@ -18389,9 +18605,9 @@ function materializeImageDataPart(part, index, dir) {
|
|
|
18389
18605
|
if (!part.data) return null;
|
|
18390
18606
|
const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
|
|
18391
18607
|
if (!rawData) return null;
|
|
18392
|
-
|
|
18608
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
18393
18609
|
const filePath = path16.join(dir, safeInputImageBasename(index, part.mimeType));
|
|
18394
|
-
|
|
18610
|
+
fs7.writeFileSync(filePath, Buffer.from(rawData, "base64"));
|
|
18395
18611
|
cleanupStaleMaterializedImages(dir);
|
|
18396
18612
|
return filePath;
|
|
18397
18613
|
}
|
|
@@ -18403,14 +18619,14 @@ function cleanupStaleMaterializedImages(dir) {
|
|
|
18403
18619
|
if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
|
|
18404
18620
|
lastMaterializedImageCleanupAt = now;
|
|
18405
18621
|
try {
|
|
18406
|
-
const entries =
|
|
18622
|
+
const entries = fs7.readdirSync(dir);
|
|
18407
18623
|
for (const entry of entries) {
|
|
18408
18624
|
if (!entry.startsWith("adhdev-input-image-")) continue;
|
|
18409
18625
|
const fullPath = path16.join(dir, entry);
|
|
18410
18626
|
try {
|
|
18411
|
-
const stat2 =
|
|
18627
|
+
const stat2 = fs7.statSync(fullPath);
|
|
18412
18628
|
if (now - stat2.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
|
|
18413
|
-
|
|
18629
|
+
fs7.unlinkSync(fullPath);
|
|
18414
18630
|
}
|
|
18415
18631
|
} catch {
|
|
18416
18632
|
}
|
|
@@ -18649,7 +18865,7 @@ var CliProviderInstance = class {
|
|
|
18649
18865
|
const resolvedDbPath = probe.dbPath.replace(/^~/, os12.homedir());
|
|
18650
18866
|
const now = Date.now();
|
|
18651
18867
|
if (this.cachedSqliteDbMissingUntil > now) return null;
|
|
18652
|
-
if (!
|
|
18868
|
+
if (!fs7.existsSync(resolvedDbPath)) {
|
|
18653
18869
|
this.cachedSqliteDbMissingUntil = now + 1e4;
|
|
18654
18870
|
return null;
|
|
18655
18871
|
}
|
|
@@ -19565,7 +19781,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
19565
19781
|
};
|
|
19566
19782
|
addDir(this.workingDir);
|
|
19567
19783
|
try {
|
|
19568
|
-
addDir(
|
|
19784
|
+
addDir(fs7.realpathSync.native(this.workingDir));
|
|
19569
19785
|
} catch {
|
|
19570
19786
|
}
|
|
19571
19787
|
return Array.from(dirs);
|
|
@@ -20879,10 +21095,10 @@ function hasCliArg(args, flag) {
|
|
|
20879
21095
|
}
|
|
20880
21096
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
20881
21097
|
const baseDir = path18.join(os13.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
20882
|
-
|
|
21098
|
+
mkdirSync10(baseDir, { recursive: true });
|
|
20883
21099
|
const workspaceHash = crypto4.createHash("sha256").update(path18.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
|
|
20884
21100
|
const filePath = path18.join(baseDir, `${workspaceHash}.json`);
|
|
20885
|
-
|
|
21101
|
+
writeFileSync8(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
20886
21102
|
return filePath;
|
|
20887
21103
|
}
|
|
20888
21104
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -21662,13 +21878,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
21662
21878
|
};
|
|
21663
21879
|
|
|
21664
21880
|
// src/launch.ts
|
|
21665
|
-
import {
|
|
21881
|
+
import { exec as exec4, spawn as spawn2 } from "child_process";
|
|
21666
21882
|
import * as net from "net";
|
|
21667
21883
|
import * as os15 from "os";
|
|
21668
21884
|
import * as path20 from "path";
|
|
21669
21885
|
|
|
21670
21886
|
// src/providers/provider-loader.ts
|
|
21671
|
-
import * as
|
|
21887
|
+
import * as fs8 from "fs";
|
|
21672
21888
|
import * as path19 from "path";
|
|
21673
21889
|
import * as os14 from "os";
|
|
21674
21890
|
import * as chokidar from "chokidar";
|
|
@@ -22021,9 +22237,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22021
22237
|
static siblingStderrLogged = /* @__PURE__ */ new Set();
|
|
22022
22238
|
static looksLikeProviderRoot(candidate) {
|
|
22023
22239
|
try {
|
|
22024
|
-
if (!
|
|
22240
|
+
if (!fs8.existsSync(candidate) || !fs8.statSync(candidate).isDirectory()) return false;
|
|
22025
22241
|
return ["ide", "extension", "cli", "acp"].some(
|
|
22026
|
-
(category) =>
|
|
22242
|
+
(category) => fs8.existsSync(path19.join(candidate, category))
|
|
22027
22243
|
);
|
|
22028
22244
|
} catch {
|
|
22029
22245
|
return false;
|
|
@@ -22031,7 +22247,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22031
22247
|
}
|
|
22032
22248
|
static hasProviderRootMarker(candidate) {
|
|
22033
22249
|
try {
|
|
22034
|
-
return
|
|
22250
|
+
return fs8.existsSync(path19.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
22035
22251
|
} catch {
|
|
22036
22252
|
return false;
|
|
22037
22253
|
}
|
|
@@ -22193,7 +22409,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22193
22409
|
this.providers.clear();
|
|
22194
22410
|
this.providerAvailability.clear();
|
|
22195
22411
|
let upstreamCount = 0;
|
|
22196
|
-
if (!this.disableUpstream &&
|
|
22412
|
+
if (!this.disableUpstream && fs8.existsSync(this.upstreamDir)) {
|
|
22197
22413
|
upstreamCount = this.loadDir(this.upstreamDir);
|
|
22198
22414
|
if (upstreamCount > 0) {
|
|
22199
22415
|
this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
|
|
@@ -22201,7 +22417,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22201
22417
|
} else if (this.disableUpstream) {
|
|
22202
22418
|
this.log("Upstream loading disabled (sourceMode=no-upstream)");
|
|
22203
22419
|
}
|
|
22204
|
-
if (
|
|
22420
|
+
if (fs8.existsSync(this.userDir)) {
|
|
22205
22421
|
const userCount = this.loadDir(this.userDir, [".upstream"]);
|
|
22206
22422
|
if (userCount > 0) {
|
|
22207
22423
|
this.log(`Loaded ${userCount} user custom providers (never auto-updated)`);
|
|
@@ -22216,10 +22432,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22216
22432
|
* Check if upstream directory exists and has providers.
|
|
22217
22433
|
*/
|
|
22218
22434
|
hasUpstream() {
|
|
22219
|
-
if (!
|
|
22435
|
+
if (!fs8.existsSync(this.upstreamDir)) return false;
|
|
22220
22436
|
try {
|
|
22221
|
-
return
|
|
22222
|
-
(d) =>
|
|
22437
|
+
return fs8.readdirSync(this.upstreamDir).some(
|
|
22438
|
+
(d) => fs8.statSync(path19.join(this.upstreamDir, d)).isDirectory()
|
|
22223
22439
|
);
|
|
22224
22440
|
} catch {
|
|
22225
22441
|
return false;
|
|
@@ -22717,7 +22933,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22717
22933
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
22718
22934
|
if (providerDir) {
|
|
22719
22935
|
const fullDir = path19.join(providerDir, entry.scriptDir);
|
|
22720
|
-
resolved._resolvedScriptsPath =
|
|
22936
|
+
resolved._resolvedScriptsPath = fs8.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
22721
22937
|
}
|
|
22722
22938
|
matched = true;
|
|
22723
22939
|
}
|
|
@@ -22733,7 +22949,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22733
22949
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
22734
22950
|
if (providerDir) {
|
|
22735
22951
|
const fullDir = path19.join(providerDir, base.defaultScriptDir);
|
|
22736
|
-
resolved._resolvedScriptsPath =
|
|
22952
|
+
resolved._resolvedScriptsPath = fs8.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
22737
22953
|
}
|
|
22738
22954
|
}
|
|
22739
22955
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -22751,7 +22967,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22751
22967
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
22752
22968
|
if (providerDir) {
|
|
22753
22969
|
const fullDir = path19.join(providerDir, dirOverride);
|
|
22754
|
-
resolved._resolvedScriptsPath =
|
|
22970
|
+
resolved._resolvedScriptsPath = fs8.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
22755
22971
|
}
|
|
22756
22972
|
}
|
|
22757
22973
|
} else if (override.scripts) {
|
|
@@ -22768,7 +22984,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22768
22984
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
22769
22985
|
if (providerDir) {
|
|
22770
22986
|
const fullDir = path19.join(providerDir, base.defaultScriptDir);
|
|
22771
|
-
resolved._resolvedScriptsPath =
|
|
22987
|
+
resolved._resolvedScriptsPath = fs8.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
22772
22988
|
}
|
|
22773
22989
|
}
|
|
22774
22990
|
}
|
|
@@ -22801,14 +23017,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22801
23017
|
return null;
|
|
22802
23018
|
}
|
|
22803
23019
|
const dir = path19.join(providerDir, scriptDir);
|
|
22804
|
-
if (!
|
|
23020
|
+
if (!fs8.existsSync(dir)) {
|
|
22805
23021
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
22806
23022
|
return null;
|
|
22807
23023
|
}
|
|
22808
23024
|
const cached = this.scriptsCache.get(dir);
|
|
22809
23025
|
if (cached) return cached;
|
|
22810
23026
|
const scriptsJs = path19.join(dir, "scripts.js");
|
|
22811
|
-
if (
|
|
23027
|
+
if (fs8.existsSync(scriptsJs)) {
|
|
22812
23028
|
try {
|
|
22813
23029
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
22814
23030
|
const loaded = __require(scriptsJs);
|
|
@@ -22829,9 +23045,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22829
23045
|
watch() {
|
|
22830
23046
|
this.stopWatch();
|
|
22831
23047
|
const watchDir = (dir) => {
|
|
22832
|
-
if (!
|
|
23048
|
+
if (!fs8.existsSync(dir)) {
|
|
22833
23049
|
try {
|
|
22834
|
-
|
|
23050
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
22835
23051
|
} catch {
|
|
22836
23052
|
return;
|
|
22837
23053
|
}
|
|
@@ -22844,13 +23060,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22844
23060
|
ignoreInitial: true,
|
|
22845
23061
|
awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 }
|
|
22846
23062
|
});
|
|
23063
|
+
let reloadTimer = null;
|
|
22847
23064
|
const handleChange = (filePath) => {
|
|
22848
23065
|
if (/[\/\\]fixtures[\/\\]/.test(filePath)) {
|
|
22849
23066
|
return;
|
|
22850
23067
|
}
|
|
22851
23068
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
22852
|
-
|
|
22853
|
-
|
|
23069
|
+
if (reloadTimer) clearTimeout(reloadTimer);
|
|
23070
|
+
reloadTimer = setTimeout(() => {
|
|
23071
|
+
this.log(`File changed: ${path19.basename(filePath)}, reloading...`);
|
|
23072
|
+
this.reload();
|
|
23073
|
+
}, 300);
|
|
22854
23074
|
}
|
|
22855
23075
|
};
|
|
22856
23076
|
watcher.on("add", handleChange).on("change", handleChange).on("unlink", handleChange);
|
|
@@ -22903,13 +23123,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22903
23123
|
return { updated: false };
|
|
22904
23124
|
}
|
|
22905
23125
|
const https = __require("https");
|
|
22906
|
-
const {
|
|
23126
|
+
const { exec: exec7 } = __require("child_process");
|
|
23127
|
+
const { promisify: promisify6 } = __require("util");
|
|
23128
|
+
const execAsync5 = promisify6(exec7);
|
|
22907
23129
|
const metaPath = path19.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
22908
23130
|
let prevEtag = "";
|
|
22909
23131
|
let prevTimestamp = 0;
|
|
22910
23132
|
try {
|
|
22911
|
-
if (
|
|
22912
|
-
const meta = JSON.parse(
|
|
23133
|
+
if (fs8.existsSync(metaPath)) {
|
|
23134
|
+
const meta = JSON.parse(fs8.readFileSync(metaPath, "utf-8"));
|
|
22913
23135
|
prevEtag = meta.etag || "";
|
|
22914
23136
|
prevTimestamp = meta.timestamp || 0;
|
|
22915
23137
|
}
|
|
@@ -22967,36 +23189,36 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
22967
23189
|
const tmpTar = path19.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
22968
23190
|
const tmpExtract = path19.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
22969
23191
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
22970
|
-
|
|
22971
|
-
|
|
22972
|
-
const extracted =
|
|
23192
|
+
fs8.mkdirSync(tmpExtract, { recursive: true });
|
|
23193
|
+
await execAsync5(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
23194
|
+
const extracted = fs8.readdirSync(tmpExtract);
|
|
22973
23195
|
const rootDir = extracted.find(
|
|
22974
|
-
(d) =>
|
|
23196
|
+
(d) => fs8.statSync(path19.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
22975
23197
|
);
|
|
22976
23198
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
22977
23199
|
const sourceDir = path19.join(tmpExtract, rootDir);
|
|
22978
23200
|
const backupDir = this.upstreamDir + ".bak";
|
|
22979
|
-
if (
|
|
22980
|
-
if (
|
|
22981
|
-
|
|
23201
|
+
if (fs8.existsSync(this.upstreamDir)) {
|
|
23202
|
+
if (fs8.existsSync(backupDir)) fs8.rmSync(backupDir, { recursive: true, force: true });
|
|
23203
|
+
fs8.renameSync(this.upstreamDir, backupDir);
|
|
22982
23204
|
}
|
|
22983
23205
|
try {
|
|
22984
23206
|
this.copyDirRecursive(sourceDir, this.upstreamDir);
|
|
22985
23207
|
this.writeMeta(metaPath, etag || `ts-${Date.now()}`, Date.now());
|
|
22986
|
-
if (
|
|
23208
|
+
if (fs8.existsSync(backupDir)) fs8.rmSync(backupDir, { recursive: true, force: true });
|
|
22987
23209
|
} catch (e) {
|
|
22988
|
-
if (
|
|
22989
|
-
if (
|
|
22990
|
-
|
|
23210
|
+
if (fs8.existsSync(backupDir)) {
|
|
23211
|
+
if (fs8.existsSync(this.upstreamDir)) fs8.rmSync(this.upstreamDir, { recursive: true, force: true });
|
|
23212
|
+
fs8.renameSync(backupDir, this.upstreamDir);
|
|
22991
23213
|
}
|
|
22992
23214
|
throw e;
|
|
22993
23215
|
}
|
|
22994
23216
|
try {
|
|
22995
|
-
|
|
23217
|
+
fs8.rmSync(tmpTar, { force: true });
|
|
22996
23218
|
} catch {
|
|
22997
23219
|
}
|
|
22998
23220
|
try {
|
|
22999
|
-
|
|
23221
|
+
fs8.rmSync(tmpExtract, { recursive: true, force: true });
|
|
23000
23222
|
} catch {
|
|
23001
23223
|
}
|
|
23002
23224
|
const upstreamCount = this.countProviders(this.upstreamDir);
|
|
@@ -23028,7 +23250,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
23028
23250
|
reject(new Error(`HTTP ${res.statusCode}`));
|
|
23029
23251
|
return;
|
|
23030
23252
|
}
|
|
23031
|
-
const ws =
|
|
23253
|
+
const ws = fs8.createWriteStream(destPath);
|
|
23032
23254
|
res.pipe(ws);
|
|
23033
23255
|
ws.on("finish", () => {
|
|
23034
23256
|
ws.close();
|
|
@@ -23047,22 +23269,22 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
23047
23269
|
}
|
|
23048
23270
|
/** Recursive directory copy */
|
|
23049
23271
|
copyDirRecursive(src, dest) {
|
|
23050
|
-
|
|
23051
|
-
for (const entry of
|
|
23272
|
+
fs8.mkdirSync(dest, { recursive: true });
|
|
23273
|
+
for (const entry of fs8.readdirSync(src, { withFileTypes: true })) {
|
|
23052
23274
|
const srcPath = path19.join(src, entry.name);
|
|
23053
23275
|
const destPath = path19.join(dest, entry.name);
|
|
23054
23276
|
if (entry.isDirectory()) {
|
|
23055
23277
|
this.copyDirRecursive(srcPath, destPath);
|
|
23056
23278
|
} else {
|
|
23057
|
-
|
|
23279
|
+
fs8.copyFileSync(srcPath, destPath);
|
|
23058
23280
|
}
|
|
23059
23281
|
}
|
|
23060
23282
|
}
|
|
23061
23283
|
/** .meta.json save */
|
|
23062
23284
|
writeMeta(metaPath, etag, timestamp) {
|
|
23063
23285
|
try {
|
|
23064
|
-
|
|
23065
|
-
|
|
23286
|
+
fs8.mkdirSync(path19.dirname(metaPath), { recursive: true });
|
|
23287
|
+
fs8.writeFileSync(metaPath, JSON.stringify({
|
|
23066
23288
|
etag,
|
|
23067
23289
|
timestamp,
|
|
23068
23290
|
lastCheck: new Date(timestamp).toISOString(),
|
|
@@ -23073,11 +23295,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
23073
23295
|
}
|
|
23074
23296
|
/** Count provider files (provider.js or provider.json) */
|
|
23075
23297
|
countProviders(dir) {
|
|
23076
|
-
if (!
|
|
23298
|
+
if (!fs8.existsSync(dir)) return 0;
|
|
23077
23299
|
let count = 0;
|
|
23078
23300
|
const scan = (d) => {
|
|
23079
23301
|
try {
|
|
23080
|
-
for (const entry of
|
|
23302
|
+
for (const entry of fs8.readdirSync(d, { withFileTypes: true })) {
|
|
23081
23303
|
if (entry.isDirectory()) scan(path19.join(d, entry.name));
|
|
23082
23304
|
else if (entry.name === "provider.json") count++;
|
|
23083
23305
|
}
|
|
@@ -23304,18 +23526,18 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
23304
23526
|
const cat = provider.category;
|
|
23305
23527
|
const searchRoots = this.getProviderRoots();
|
|
23306
23528
|
for (const root of searchRoots) {
|
|
23307
|
-
if (!
|
|
23529
|
+
if (!fs8.existsSync(root)) continue;
|
|
23308
23530
|
const candidate = this.getProviderDir(root, cat, type);
|
|
23309
|
-
if (
|
|
23531
|
+
if (fs8.existsSync(path19.join(candidate, "provider.json"))) return candidate;
|
|
23310
23532
|
const catDir = path19.join(root, cat);
|
|
23311
|
-
if (
|
|
23533
|
+
if (fs8.existsSync(catDir)) {
|
|
23312
23534
|
try {
|
|
23313
|
-
for (const entry of
|
|
23535
|
+
for (const entry of fs8.readdirSync(catDir, { withFileTypes: true })) {
|
|
23314
23536
|
if (!entry.isDirectory()) continue;
|
|
23315
23537
|
const jsonPath = path19.join(catDir, entry.name, "provider.json");
|
|
23316
|
-
if (
|
|
23538
|
+
if (fs8.existsSync(jsonPath)) {
|
|
23317
23539
|
try {
|
|
23318
|
-
const data = JSON.parse(
|
|
23540
|
+
const data = JSON.parse(fs8.readFileSync(jsonPath, "utf-8"));
|
|
23319
23541
|
if (data.type === type) return path19.join(catDir, entry.name);
|
|
23320
23542
|
} catch {
|
|
23321
23543
|
}
|
|
@@ -23334,7 +23556,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
23334
23556
|
*/
|
|
23335
23557
|
buildScriptWrappersFromDir(dir) {
|
|
23336
23558
|
const scriptsJs = path19.join(dir, "scripts.js");
|
|
23337
|
-
if (
|
|
23559
|
+
if (fs8.existsSync(scriptsJs)) {
|
|
23338
23560
|
try {
|
|
23339
23561
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
23340
23562
|
return __require(scriptsJs);
|
|
@@ -23344,13 +23566,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
23344
23566
|
const toCamel = (name) => name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
23345
23567
|
const result = {};
|
|
23346
23568
|
try {
|
|
23347
|
-
for (const file of
|
|
23569
|
+
for (const file of fs8.readdirSync(dir)) {
|
|
23348
23570
|
if (!file.endsWith(".js")) continue;
|
|
23349
23571
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
23350
23572
|
const filePath = path19.join(dir, file);
|
|
23351
23573
|
result[scriptName] = (...args) => {
|
|
23352
23574
|
try {
|
|
23353
|
-
let content =
|
|
23575
|
+
let content = fs8.readFileSync(filePath, "utf-8");
|
|
23354
23576
|
if (args[0] && typeof args[0] === "object") {
|
|
23355
23577
|
for (const [key, val] of Object.entries(args[0])) {
|
|
23356
23578
|
let v = val;
|
|
@@ -23396,12 +23618,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
23396
23618
|
* Structure: dir/category/agent-name/provider.{json,js}
|
|
23397
23619
|
*/
|
|
23398
23620
|
loadDir(dir, excludeDirs) {
|
|
23399
|
-
if (!
|
|
23621
|
+
if (!fs8.existsSync(dir)) return 0;
|
|
23400
23622
|
let count = 0;
|
|
23401
23623
|
const scan = (d) => {
|
|
23402
23624
|
let entries;
|
|
23403
23625
|
try {
|
|
23404
|
-
entries =
|
|
23626
|
+
entries = fs8.readdirSync(d, { withFileTypes: true });
|
|
23405
23627
|
} catch {
|
|
23406
23628
|
return;
|
|
23407
23629
|
}
|
|
@@ -23409,7 +23631,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
23409
23631
|
if (hasJson) {
|
|
23410
23632
|
const jsonPath = path19.join(d, "provider.json");
|
|
23411
23633
|
try {
|
|
23412
|
-
const raw =
|
|
23634
|
+
const raw = fs8.readFileSync(jsonPath, "utf-8");
|
|
23413
23635
|
const mod = JSON.parse(raw);
|
|
23414
23636
|
if (typeof mod.extensionIdPattern === "string") {
|
|
23415
23637
|
const flags = mod.extensionIdPattern_flags || "";
|
|
@@ -23429,7 +23651,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
23429
23651
|
} else {
|
|
23430
23652
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
23431
23653
|
const scriptsPath = path19.join(d, "scripts.js");
|
|
23432
|
-
if (!hasCompatibility &&
|
|
23654
|
+
if (!hasCompatibility && fs8.existsSync(scriptsPath)) {
|
|
23433
23655
|
try {
|
|
23434
23656
|
delete __require.cache[__require.resolve(scriptsPath)];
|
|
23435
23657
|
const scripts = __require(scriptsPath);
|
|
@@ -23534,6 +23756,14 @@ function findMacAppProcessPids(psOutput, appPaths) {
|
|
|
23534
23756
|
}
|
|
23535
23757
|
|
|
23536
23758
|
// src/launch.ts
|
|
23759
|
+
async function execQuiet(command, options = {}) {
|
|
23760
|
+
return new Promise((resolve16) => {
|
|
23761
|
+
exec4(command, options, (error, stdout) => {
|
|
23762
|
+
if (error) return resolve16("");
|
|
23763
|
+
resolve16(stdout.toString());
|
|
23764
|
+
});
|
|
23765
|
+
});
|
|
23766
|
+
}
|
|
23537
23767
|
var _providerLoader = null;
|
|
23538
23768
|
function getProviderLoader() {
|
|
23539
23769
|
if (!_providerLoader) {
|
|
@@ -23572,11 +23802,11 @@ function escapeForAppleScript(value) {
|
|
|
23572
23802
|
function getIdePathCandidates(ideId) {
|
|
23573
23803
|
return getProviderLoader().getIdePathCandidates(ideId);
|
|
23574
23804
|
}
|
|
23575
|
-
function getMacAppProcessPids(ideId) {
|
|
23805
|
+
async function getMacAppProcessPids(ideId) {
|
|
23576
23806
|
const appPaths = getIdePathCandidates(ideId);
|
|
23577
23807
|
if (appPaths.length === 0) return [];
|
|
23578
23808
|
try {
|
|
23579
|
-
const output =
|
|
23809
|
+
const output = await execQuiet("ps axww -o pid=,args=", {
|
|
23580
23810
|
encoding: "utf-8",
|
|
23581
23811
|
timeout: 3e3,
|
|
23582
23812
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -23586,8 +23816,8 @@ function getMacAppProcessPids(ideId) {
|
|
|
23586
23816
|
return [];
|
|
23587
23817
|
}
|
|
23588
23818
|
}
|
|
23589
|
-
function killMacAppPathProcesses(ideId, signal) {
|
|
23590
|
-
const pids = getMacAppProcessPids(ideId);
|
|
23819
|
+
async function killMacAppPathProcesses(ideId, signal) {
|
|
23820
|
+
const pids = await getMacAppProcessPids(ideId);
|
|
23591
23821
|
let signalled = false;
|
|
23592
23822
|
for (const pid of pids) {
|
|
23593
23823
|
try {
|
|
@@ -23650,68 +23880,68 @@ async function killIdeProcess(ideId) {
|
|
|
23650
23880
|
try {
|
|
23651
23881
|
if (plat === "darwin" && appName) {
|
|
23652
23882
|
try {
|
|
23653
|
-
|
|
23883
|
+
await execQuiet(`osascript -e 'tell application "${escapeForAppleScript(appName)}" to quit' 2>/dev/null`, {
|
|
23654
23884
|
timeout: 5e3
|
|
23655
23885
|
});
|
|
23656
23886
|
} catch {
|
|
23657
23887
|
try {
|
|
23658
|
-
|
|
23888
|
+
await execQuiet(`pkill -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
|
|
23659
23889
|
} catch {
|
|
23660
23890
|
}
|
|
23661
23891
|
}
|
|
23662
|
-
killMacAppPathProcesses(ideId, "SIGTERM");
|
|
23892
|
+
await killMacAppPathProcesses(ideId, "SIGTERM");
|
|
23663
23893
|
} else if (plat === "win32" && winProcesses) {
|
|
23664
23894
|
for (const proc of winProcesses) {
|
|
23665
23895
|
try {
|
|
23666
|
-
|
|
23896
|
+
await execQuiet(`taskkill /IM "${proc}" /F 2>nul`, { timeout: 5e3 });
|
|
23667
23897
|
} catch {
|
|
23668
23898
|
}
|
|
23669
23899
|
}
|
|
23670
23900
|
try {
|
|
23671
23901
|
const exeName = winProcesses[0].replace(".exe", "");
|
|
23672
|
-
|
|
23902
|
+
await execQuiet(`powershell -Command "Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue | Stop-Process -Force"`, {
|
|
23673
23903
|
timeout: 1e4
|
|
23674
23904
|
});
|
|
23675
23905
|
} catch {
|
|
23676
23906
|
}
|
|
23677
23907
|
} else {
|
|
23678
23908
|
try {
|
|
23679
|
-
|
|
23909
|
+
await execQuiet(`pkill -f "${ideId}" 2>/dev/null`);
|
|
23680
23910
|
} catch {
|
|
23681
23911
|
}
|
|
23682
23912
|
}
|
|
23683
23913
|
for (let i = 0; i < 30; i++) {
|
|
23684
23914
|
await new Promise((r) => setTimeout(r, 500));
|
|
23685
|
-
if (!isIdeRunning(ideId)) return true;
|
|
23915
|
+
if (!await isIdeRunning(ideId)) return true;
|
|
23686
23916
|
}
|
|
23687
23917
|
if (plat === "darwin" && appName) {
|
|
23688
23918
|
try {
|
|
23689
|
-
|
|
23919
|
+
await execQuiet(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
|
|
23690
23920
|
} catch {
|
|
23691
23921
|
}
|
|
23692
|
-
killMacAppPathProcesses(ideId, "SIGKILL");
|
|
23922
|
+
await killMacAppPathProcesses(ideId, "SIGKILL");
|
|
23693
23923
|
} else if (plat === "win32" && winProcesses) {
|
|
23694
23924
|
for (const proc of winProcesses) {
|
|
23695
23925
|
try {
|
|
23696
|
-
|
|
23926
|
+
await execQuiet(`taskkill /IM "${proc}" /F 2>nul`);
|
|
23697
23927
|
} catch {
|
|
23698
23928
|
}
|
|
23699
23929
|
}
|
|
23700
23930
|
}
|
|
23701
23931
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
23702
|
-
return !isIdeRunning(ideId);
|
|
23932
|
+
return !await isIdeRunning(ideId);
|
|
23703
23933
|
} catch {
|
|
23704
23934
|
return false;
|
|
23705
23935
|
}
|
|
23706
23936
|
}
|
|
23707
|
-
function isIdeRunning(ideId) {
|
|
23937
|
+
async function isIdeRunning(ideId) {
|
|
23708
23938
|
const plat = os15.platform();
|
|
23709
23939
|
try {
|
|
23710
23940
|
if (plat === "darwin") {
|
|
23711
23941
|
const appName = getMacAppIdentifiers()[ideId];
|
|
23712
|
-
if (!appName) return getMacAppProcessPids(ideId).length > 0;
|
|
23942
|
+
if (!appName) return (await getMacAppProcessPids(ideId)).length > 0;
|
|
23713
23943
|
try {
|
|
23714
|
-
const result =
|
|
23944
|
+
const result = await execQuiet(`pgrep -x "${appName}" 2>/dev/null`, {
|
|
23715
23945
|
encoding: "utf-8",
|
|
23716
23946
|
timeout: 3e3
|
|
23717
23947
|
});
|
|
@@ -23719,7 +23949,7 @@ function isIdeRunning(ideId) {
|
|
|
23719
23949
|
} catch {
|
|
23720
23950
|
}
|
|
23721
23951
|
try {
|
|
23722
|
-
const result =
|
|
23952
|
+
const result = await execQuiet(
|
|
23723
23953
|
`osascript -e 'tell application "System Events" to count (every process whose name is "${escapeForAppleScript(appName)}")'`,
|
|
23724
23954
|
{
|
|
23725
23955
|
encoding: "utf-8",
|
|
@@ -23730,20 +23960,20 @@ function isIdeRunning(ideId) {
|
|
|
23730
23960
|
if (Number.parseInt(result.trim() || "0", 10) > 0) return true;
|
|
23731
23961
|
} catch {
|
|
23732
23962
|
}
|
|
23733
|
-
return getMacAppProcessPids(ideId).length > 0;
|
|
23963
|
+
return (await getMacAppProcessPids(ideId)).length > 0;
|
|
23734
23964
|
} else if (plat === "win32") {
|
|
23735
23965
|
const winProcesses = getWinProcessNames()[ideId];
|
|
23736
23966
|
if (!winProcesses) return false;
|
|
23737
23967
|
for (const proc of winProcesses) {
|
|
23738
23968
|
try {
|
|
23739
|
-
const result =
|
|
23969
|
+
const result = await execQuiet(`tasklist /FI "IMAGENAME eq ${proc}" /NH 2>nul`, { encoding: "utf-8" });
|
|
23740
23970
|
if (result.includes(proc)) return true;
|
|
23741
23971
|
} catch {
|
|
23742
23972
|
}
|
|
23743
23973
|
}
|
|
23744
23974
|
try {
|
|
23745
23975
|
const exeName = winProcesses[0].replace(".exe", "");
|
|
23746
|
-
const result =
|
|
23976
|
+
const result = await execQuiet(
|
|
23747
23977
|
`powershell -Command "(Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue).Count"`,
|
|
23748
23978
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
23749
23979
|
);
|
|
@@ -23752,20 +23982,20 @@ function isIdeRunning(ideId) {
|
|
|
23752
23982
|
}
|
|
23753
23983
|
return false;
|
|
23754
23984
|
} else {
|
|
23755
|
-
const result =
|
|
23985
|
+
const result = await execQuiet(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
|
|
23756
23986
|
return result.trim().length > 0;
|
|
23757
23987
|
}
|
|
23758
23988
|
} catch {
|
|
23759
23989
|
return false;
|
|
23760
23990
|
}
|
|
23761
23991
|
}
|
|
23762
|
-
function detectCurrentWorkspace(ideId) {
|
|
23992
|
+
async function detectCurrentWorkspace(ideId) {
|
|
23763
23993
|
const plat = os15.platform();
|
|
23764
23994
|
if (plat === "darwin") {
|
|
23765
23995
|
try {
|
|
23766
23996
|
const appName = getMacAppIdentifiers()[ideId];
|
|
23767
23997
|
if (!appName) return void 0;
|
|
23768
|
-
const result =
|
|
23998
|
+
const result = await execQuiet(
|
|
23769
23999
|
`lsof -c "${appName}" 2>/dev/null | grep cwd | head -1 | awk '{print $NF}'`,
|
|
23770
24000
|
{ encoding: "utf-8", timeout: 3e3 }
|
|
23771
24001
|
);
|
|
@@ -23775,7 +24005,7 @@ function detectCurrentWorkspace(ideId) {
|
|
|
23775
24005
|
}
|
|
23776
24006
|
} else if (plat === "win32") {
|
|
23777
24007
|
try {
|
|
23778
|
-
const
|
|
24008
|
+
const fs17 = __require("fs");
|
|
23779
24009
|
const appNameMap = getMacAppIdentifiers();
|
|
23780
24010
|
const appName = appNameMap[ideId];
|
|
23781
24011
|
if (appName) {
|
|
@@ -23784,8 +24014,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
23784
24014
|
appName,
|
|
23785
24015
|
"storage.json"
|
|
23786
24016
|
);
|
|
23787
|
-
if (
|
|
23788
|
-
const data = JSON.parse(
|
|
24017
|
+
if (fs17.existsSync(storagePath)) {
|
|
24018
|
+
const data = JSON.parse(fs17.readFileSync(storagePath, "utf-8"));
|
|
23789
24019
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
23790
24020
|
if (workspaces.length > 0) {
|
|
23791
24021
|
const recent = workspaces[0];
|
|
@@ -23852,8 +24082,8 @@ async function launchWithCdp(options = {}) {
|
|
|
23852
24082
|
};
|
|
23853
24083
|
}
|
|
23854
24084
|
}
|
|
23855
|
-
const alreadyRunning = isIdeRunning(targetIde.id);
|
|
23856
|
-
const workspace = options.workspace || (alreadyRunning ? detectCurrentWorkspace(targetIde.id) : void 0);
|
|
24085
|
+
const alreadyRunning = await isIdeRunning(targetIde.id);
|
|
24086
|
+
const workspace = options.workspace || (alreadyRunning ? await detectCurrentWorkspace(targetIde.id) : void 0);
|
|
23857
24087
|
if (alreadyRunning) {
|
|
23858
24088
|
const killed = await killIdeProcess(targetIde.id);
|
|
23859
24089
|
if (!killed) {
|
|
@@ -23969,14 +24199,14 @@ init_cli_detector();
|
|
|
23969
24199
|
init_logger();
|
|
23970
24200
|
|
|
23971
24201
|
// src/logging/command-log.ts
|
|
23972
|
-
import * as
|
|
24202
|
+
import * as fs9 from "fs";
|
|
23973
24203
|
import * as path21 from "path";
|
|
23974
24204
|
import * as os16 from "os";
|
|
23975
24205
|
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");
|
|
23976
24206
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
23977
24207
|
var MAX_DAYS = 7;
|
|
23978
24208
|
try {
|
|
23979
|
-
|
|
24209
|
+
fs9.mkdirSync(LOG_DIR2, { recursive: true });
|
|
23980
24210
|
} catch {
|
|
23981
24211
|
}
|
|
23982
24212
|
var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -24022,7 +24252,7 @@ function checkRotation() {
|
|
|
24022
24252
|
}
|
|
24023
24253
|
function cleanOldFiles() {
|
|
24024
24254
|
try {
|
|
24025
|
-
const files =
|
|
24255
|
+
const files = fs9.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
|
|
24026
24256
|
const cutoff = /* @__PURE__ */ new Date();
|
|
24027
24257
|
cutoff.setDate(cutoff.getDate() - MAX_DAYS);
|
|
24028
24258
|
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
@@ -24030,7 +24260,7 @@ function cleanOldFiles() {
|
|
|
24030
24260
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
24031
24261
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
24032
24262
|
try {
|
|
24033
|
-
|
|
24263
|
+
fs9.unlinkSync(path21.join(LOG_DIR2, file));
|
|
24034
24264
|
} catch {
|
|
24035
24265
|
}
|
|
24036
24266
|
}
|
|
@@ -24040,14 +24270,14 @@ function cleanOldFiles() {
|
|
|
24040
24270
|
}
|
|
24041
24271
|
function checkSize() {
|
|
24042
24272
|
try {
|
|
24043
|
-
const stat2 =
|
|
24273
|
+
const stat2 = fs9.statSync(currentFile);
|
|
24044
24274
|
if (stat2.size > MAX_FILE_SIZE) {
|
|
24045
24275
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
24046
24276
|
try {
|
|
24047
|
-
|
|
24277
|
+
fs9.unlinkSync(backup);
|
|
24048
24278
|
} catch {
|
|
24049
24279
|
}
|
|
24050
|
-
|
|
24280
|
+
fs9.renameSync(currentFile, backup);
|
|
24051
24281
|
}
|
|
24052
24282
|
} catch {
|
|
24053
24283
|
}
|
|
@@ -24080,14 +24310,14 @@ function logCommand(entry) {
|
|
|
24080
24310
|
...entry.error ? { err: entry.error } : {},
|
|
24081
24311
|
...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
|
|
24082
24312
|
});
|
|
24083
|
-
|
|
24313
|
+
fs9.appendFileSync(currentFile, line + "\n");
|
|
24084
24314
|
} catch {
|
|
24085
24315
|
}
|
|
24086
24316
|
}
|
|
24087
24317
|
function getRecentCommands(count = 50) {
|
|
24088
24318
|
try {
|
|
24089
|
-
if (!
|
|
24090
|
-
const content =
|
|
24319
|
+
if (!fs9.existsSync(currentFile)) return [];
|
|
24320
|
+
const content = fs9.readFileSync(currentFile, "utf-8");
|
|
24091
24321
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
24092
24322
|
return lines.slice(-count).map((line) => {
|
|
24093
24323
|
try {
|
|
@@ -24117,14 +24347,11 @@ init_logger();
|
|
|
24117
24347
|
import * as yaml2 from "js-yaml";
|
|
24118
24348
|
|
|
24119
24349
|
// src/commands/mesh-coordinator.ts
|
|
24120
|
-
import { execFileSync as execFileSync2 } from "child_process";
|
|
24121
24350
|
import { createHash as createHash3 } from "crypto";
|
|
24122
|
-
import { existsSync as existsSync19, readdirSync as readdirSync7, realpathSync as realpathSync2 } from "fs";
|
|
24123
|
-
import { createRequire as createRequire2 } from "module";
|
|
24124
24351
|
import * as os17 from "os";
|
|
24125
|
-
import {
|
|
24352
|
+
import { isAbsolute as isAbsolute11, join as join22, resolve as resolve13 } from "path";
|
|
24126
24353
|
var DEFAULT_SERVER_NAME = "adhdev-mesh";
|
|
24127
|
-
var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev
|
|
24354
|
+
var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev";
|
|
24128
24355
|
var HERMES_CLI_TYPE = "hermes-cli";
|
|
24129
24356
|
var HERMES_MCP_CONFIG_PATH = "~/.hermes/config.yaml";
|
|
24130
24357
|
function isHermesProvider(provider, cliType) {
|
|
@@ -24134,8 +24361,7 @@ function isHermesProvider(provider, cliType) {
|
|
|
24134
24361
|
function resolveHermesMeshCoordinatorSetup(options) {
|
|
24135
24362
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
24136
24363
|
meshId: options.meshId,
|
|
24137
|
-
|
|
24138
|
-
adhdevMcpEntryPath: options.adhdevMcpEntryPath,
|
|
24364
|
+
adhdevMcpCommand: options.adhdevMcpCommand,
|
|
24139
24365
|
adhdevMcpTransport: options.adhdevMcpTransport,
|
|
24140
24366
|
adhdevMcpPort: options.adhdevMcpPort
|
|
24141
24367
|
});
|
|
@@ -24166,7 +24392,7 @@ function createHermesManualMeshCoordinatorSetup(meshId, workspace) {
|
|
|
24166
24392
|
requiresRestart: true,
|
|
24167
24393
|
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.",
|
|
24168
24394
|
template: renderMeshCoordinatorTemplate(
|
|
24169
|
-
"mcp_servers:\n {{serverName}}:\n command: {{adhdevMcpCommand}}\n args:\n - --repo-mesh\n - {{meshId}}\n enabled: true\n",
|
|
24395
|
+
"mcp_servers:\n {{serverName}}:\n command: {{adhdevMcpCommand}}\n args:\n - mcp\n - --mode\n - ipc\n - --repo-mesh\n - {{meshId}}\n enabled: true\n",
|
|
24170
24396
|
{
|
|
24171
24397
|
meshId,
|
|
24172
24398
|
workspace,
|
|
@@ -24203,8 +24429,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
24203
24429
|
}
|
|
24204
24430
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
24205
24431
|
meshId,
|
|
24206
|
-
|
|
24207
|
-
adhdevMcpEntryPath: options.adhdevMcpEntryPath,
|
|
24432
|
+
adhdevMcpCommand: options.adhdevMcpCommand,
|
|
24208
24433
|
adhdevMcpTransport: options.adhdevMcpTransport,
|
|
24209
24434
|
adhdevMcpPort: options.adhdevMcpPort
|
|
24210
24435
|
});
|
|
@@ -24276,19 +24501,19 @@ function resolveMcpConfigPath(configPath, workspace) {
|
|
|
24276
24501
|
return join22(workspace, trimmed);
|
|
24277
24502
|
}
|
|
24278
24503
|
function resolveAdhdevMcpServerLaunch(options) {
|
|
24279
|
-
const
|
|
24280
|
-
if (!entryPath) return null;
|
|
24281
|
-
const nodeExecutable = resolveMcpNodeExecutable(options.nodeExecutable);
|
|
24282
|
-
if (!nodeExecutable) return null;
|
|
24504
|
+
const command = resolveAdhdevCommand(options.adhdevMcpCommand);
|
|
24283
24505
|
const transport = resolveMcpTransport(options.adhdevMcpTransport);
|
|
24284
|
-
const args = [
|
|
24506
|
+
const args = ["mcp", "--mode", transport, "--repo-mesh", options.meshId];
|
|
24285
24507
|
const port = resolveMcpPort(options.adhdevMcpPort);
|
|
24286
24508
|
if (port !== void 0) args.push("--port", String(port));
|
|
24287
24509
|
return {
|
|
24288
|
-
command
|
|
24510
|
+
command,
|
|
24289
24511
|
args
|
|
24290
24512
|
};
|
|
24291
24513
|
}
|
|
24514
|
+
function resolveAdhdevCommand(explicitCommand) {
|
|
24515
|
+
return explicitCommand?.trim() || process.env.ADHDEV_COORDINATOR_MCP_COMMAND?.trim() || DEFAULT_ADHDEV_MCP_COMMAND;
|
|
24516
|
+
}
|
|
24292
24517
|
function resolveMcpTransport(explicitTransport) {
|
|
24293
24518
|
if (explicitTransport === "local" || explicitTransport === "ipc") return explicitTransport;
|
|
24294
24519
|
const envTransport = process.env.ADHDEV_COORDINATOR_MCP_TRANSPORT?.trim();
|
|
@@ -24301,109 +24526,6 @@ function resolveMcpPort(explicitPort) {
|
|
|
24301
24526
|
const parsed = Number(raw);
|
|
24302
24527
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
24303
24528
|
}
|
|
24304
|
-
function resolveMcpNodeExecutable(explicitExecutable) {
|
|
24305
|
-
const explicit = explicitExecutable?.trim();
|
|
24306
|
-
if (explicit) return explicit;
|
|
24307
|
-
const candidates = [];
|
|
24308
|
-
const addCandidate = (candidate) => {
|
|
24309
|
-
const trimmed = candidate?.trim();
|
|
24310
|
-
if (!trimmed) return;
|
|
24311
|
-
const normalized = normalizeExistingPath(trimmed) || trimmed;
|
|
24312
|
-
if (!candidates.includes(normalized)) candidates.push(normalized);
|
|
24313
|
-
};
|
|
24314
|
-
addCandidate(process.env.ADHDEV_MCP_NODE_EXECUTABLE);
|
|
24315
|
-
addCandidate(process.env.ADHDEV_NODE_EXECUTABLE);
|
|
24316
|
-
addCandidate(process.env.npm_node_execpath);
|
|
24317
|
-
addNodeCandidatesFromPath(process.env.PATH, addCandidate);
|
|
24318
|
-
addNodeCandidatesFromNvm(os17.homedir(), addCandidate);
|
|
24319
|
-
addCandidate("/opt/homebrew/bin/node");
|
|
24320
|
-
addCandidate("/usr/local/bin/node");
|
|
24321
|
-
addCandidate("/usr/bin/node");
|
|
24322
|
-
addCandidate(process.execPath);
|
|
24323
|
-
for (const candidate of candidates) {
|
|
24324
|
-
if (nodeRuntimeSupportsWebSocket(candidate)) return candidate;
|
|
24325
|
-
}
|
|
24326
|
-
return null;
|
|
24327
|
-
}
|
|
24328
|
-
function addNodeCandidatesFromPath(pathValue, addCandidate) {
|
|
24329
|
-
for (const entry of (pathValue || "").split(":")) {
|
|
24330
|
-
const dir = entry.trim();
|
|
24331
|
-
if (!dir) continue;
|
|
24332
|
-
addCandidate(join22(dir, "node"));
|
|
24333
|
-
}
|
|
24334
|
-
}
|
|
24335
|
-
function addNodeCandidatesFromNvm(homeDir, addCandidate) {
|
|
24336
|
-
const versionsDir = join22(homeDir, ".nvm", "versions", "node");
|
|
24337
|
-
try {
|
|
24338
|
-
const versionDirs = readdirSync7(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
|
|
24339
|
-
for (const versionDir of versionDirs) {
|
|
24340
|
-
addCandidate(join22(versionsDir, versionDir, "bin", "node"));
|
|
24341
|
-
}
|
|
24342
|
-
} catch {
|
|
24343
|
-
}
|
|
24344
|
-
}
|
|
24345
|
-
function compareNodeVersionNamesDescending(a, b) {
|
|
24346
|
-
const parse = (value) => value.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
24347
|
-
const left = parse(a);
|
|
24348
|
-
const right = parse(b);
|
|
24349
|
-
for (let i = 0; i < Math.max(left.length, right.length); i++) {
|
|
24350
|
-
const diff = (right[i] || 0) - (left[i] || 0);
|
|
24351
|
-
if (diff !== 0) return diff;
|
|
24352
|
-
}
|
|
24353
|
-
return b.localeCompare(a);
|
|
24354
|
-
}
|
|
24355
|
-
function nodeRuntimeSupportsWebSocket(nodeExecutable) {
|
|
24356
|
-
try {
|
|
24357
|
-
execFileSync2(nodeExecutable, ["-e", "process.exit(typeof WebSocket === 'function' ? 0 : 42)"], {
|
|
24358
|
-
stdio: "ignore",
|
|
24359
|
-
timeout: 3e3
|
|
24360
|
-
});
|
|
24361
|
-
return true;
|
|
24362
|
-
} catch {
|
|
24363
|
-
return false;
|
|
24364
|
-
}
|
|
24365
|
-
}
|
|
24366
|
-
function resolveAdhdevMcpEntryPath(explicitPath) {
|
|
24367
|
-
const explicit = explicitPath?.trim();
|
|
24368
|
-
if (explicit) return normalizeExistingPath(explicit) || explicit;
|
|
24369
|
-
const envPath = process.env.ADHDEV_MCP_SERVER_PATH?.trim();
|
|
24370
|
-
if (envPath) return normalizeExistingPath(envPath) || envPath;
|
|
24371
|
-
const candidates = [];
|
|
24372
|
-
const addCandidate = (candidate) => {
|
|
24373
|
-
if (!candidates.includes(candidate)) candidates.push(candidate);
|
|
24374
|
-
};
|
|
24375
|
-
const addPackagedCandidates = (baseFile) => {
|
|
24376
|
-
if (!baseFile) return;
|
|
24377
|
-
const realBase = normalizeExistingPath(baseFile) || baseFile;
|
|
24378
|
-
const dir = dirname4(realBase);
|
|
24379
|
-
addCandidate(resolve13(dir, "../vendor/mcp-server/index.js"));
|
|
24380
|
-
addCandidate(resolve13(dir, "../../vendor/mcp-server/index.js"));
|
|
24381
|
-
addCandidate(resolve13(dir, "../../../vendor/mcp-server/index.js"));
|
|
24382
|
-
addCandidate(resolve13(dir, "../../mcp-server/dist/index.js"));
|
|
24383
|
-
addCandidate(resolve13(dir, "../../../mcp-server/dist/index.js"));
|
|
24384
|
-
};
|
|
24385
|
-
addPackagedCandidates(process.argv[1]);
|
|
24386
|
-
for (const candidate of candidates) {
|
|
24387
|
-
const normalized = normalizeExistingPath(candidate);
|
|
24388
|
-
if (normalized) return normalized;
|
|
24389
|
-
}
|
|
24390
|
-
try {
|
|
24391
|
-
const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : join22(process.cwd(), "adhdev-daemon.js");
|
|
24392
|
-
const req = createRequire2(requireBase);
|
|
24393
|
-
const resolvedModule = req.resolve("@adhdev/mcp-server");
|
|
24394
|
-
return normalizeExistingPath(resolvedModule) || resolvedModule;
|
|
24395
|
-
} catch {
|
|
24396
|
-
return null;
|
|
24397
|
-
}
|
|
24398
|
-
}
|
|
24399
|
-
function normalizeExistingPath(filePath) {
|
|
24400
|
-
try {
|
|
24401
|
-
if (!existsSync19(filePath)) return null;
|
|
24402
|
-
return realpathSync2.native(filePath);
|
|
24403
|
-
} catch {
|
|
24404
|
-
return null;
|
|
24405
|
-
}
|
|
24406
|
-
}
|
|
24407
24529
|
|
|
24408
24530
|
// src/commands/router.ts
|
|
24409
24531
|
init_mesh_events();
|
|
@@ -24723,23 +24845,23 @@ function buildStatusSnapshot(options) {
|
|
|
24723
24845
|
}
|
|
24724
24846
|
|
|
24725
24847
|
// src/commands/upgrade-helper.ts
|
|
24726
|
-
import { execFileSync as
|
|
24848
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
24727
24849
|
import { spawn as spawn3 } from "child_process";
|
|
24728
|
-
import * as
|
|
24850
|
+
import * as fs10 from "fs";
|
|
24729
24851
|
import * as os19 from "os";
|
|
24730
24852
|
import * as path22 from "path";
|
|
24731
24853
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
24732
24854
|
function getUpgradeLogPath() {
|
|
24733
24855
|
const home = os19.homedir();
|
|
24734
24856
|
const dir = path22.join(home, ".adhdev");
|
|
24735
|
-
|
|
24857
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
24736
24858
|
return path22.join(dir, "daemon-upgrade.log");
|
|
24737
24859
|
}
|
|
24738
24860
|
function appendUpgradeLog(message) {
|
|
24739
24861
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
24740
24862
|
`;
|
|
24741
24863
|
try {
|
|
24742
|
-
|
|
24864
|
+
fs10.appendFileSync(getUpgradeLogPath(), line, "utf8");
|
|
24743
24865
|
} catch {
|
|
24744
24866
|
}
|
|
24745
24867
|
}
|
|
@@ -24747,12 +24869,12 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
24747
24869
|
const binDir = path22.dirname(nodeExecutable);
|
|
24748
24870
|
if (platform10 === "win32") {
|
|
24749
24871
|
const npmCliPath = path22.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
24750
|
-
if (
|
|
24872
|
+
if (fs10.existsSync(npmCliPath)) {
|
|
24751
24873
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
24752
24874
|
}
|
|
24753
24875
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
24754
24876
|
const candidatePath = path22.join(binDir, candidate);
|
|
24755
|
-
if (
|
|
24877
|
+
if (fs10.existsSync(candidatePath)) {
|
|
24756
24878
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
24757
24879
|
}
|
|
24758
24880
|
}
|
|
@@ -24760,7 +24882,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
24760
24882
|
}
|
|
24761
24883
|
for (const candidate of ["npm"]) {
|
|
24762
24884
|
const candidatePath = path22.join(binDir, candidate);
|
|
24763
|
-
if (
|
|
24885
|
+
if (fs10.existsSync(candidatePath)) {
|
|
24764
24886
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
24765
24887
|
}
|
|
24766
24888
|
}
|
|
@@ -24770,12 +24892,12 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
24770
24892
|
if (!currentCliPath) return null;
|
|
24771
24893
|
let resolvedPath = currentCliPath;
|
|
24772
24894
|
try {
|
|
24773
|
-
resolvedPath =
|
|
24895
|
+
resolvedPath = fs10.realpathSync.native(currentCliPath);
|
|
24774
24896
|
} catch {
|
|
24775
24897
|
}
|
|
24776
24898
|
let currentDir = resolvedPath;
|
|
24777
24899
|
try {
|
|
24778
|
-
if (
|
|
24900
|
+
if (fs10.statSync(resolvedPath).isFile()) {
|
|
24779
24901
|
currentDir = path22.dirname(resolvedPath);
|
|
24780
24902
|
}
|
|
24781
24903
|
} catch {
|
|
@@ -24784,8 +24906,8 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
24784
24906
|
while (true) {
|
|
24785
24907
|
const packageJsonPath = path22.join(currentDir, "package.json");
|
|
24786
24908
|
try {
|
|
24787
|
-
if (
|
|
24788
|
-
const parsed = JSON.parse(
|
|
24909
|
+
if (fs10.existsSync(packageJsonPath)) {
|
|
24910
|
+
const parsed = JSON.parse(fs10.readFileSync(packageJsonPath, "utf8"));
|
|
24789
24911
|
if (parsed?.name === packageName) {
|
|
24790
24912
|
const normalized = currentDir.replace(/\\/g, "/");
|
|
24791
24913
|
return normalized.includes("/node_modules/") ? currentDir : null;
|
|
@@ -24843,7 +24965,7 @@ function getNpmExecOptions(platform10 = process.platform) {
|
|
|
24843
24965
|
}
|
|
24844
24966
|
function execNpmCommandSync(args, options = {}, surface) {
|
|
24845
24967
|
const execOptions = surface?.execOptions || getNpmExecOptions();
|
|
24846
|
-
return
|
|
24968
|
+
return execFileSync2(
|
|
24847
24969
|
surface?.npmExecutable || "npm",
|
|
24848
24970
|
[...surface?.npmArgsPrefix || [], ...args],
|
|
24849
24971
|
{
|
|
@@ -24856,7 +24978,7 @@ function execNpmCommandSync(args, options = {}, surface) {
|
|
|
24856
24978
|
function killPid(pid) {
|
|
24857
24979
|
try {
|
|
24858
24980
|
if (process.platform === "win32") {
|
|
24859
|
-
|
|
24981
|
+
execFileSync2("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
|
|
24860
24982
|
} else {
|
|
24861
24983
|
process.kill(pid, "SIGTERM");
|
|
24862
24984
|
}
|
|
@@ -24868,7 +24990,7 @@ function killPid(pid) {
|
|
|
24868
24990
|
function getWindowsProcessCommandLine(pid) {
|
|
24869
24991
|
const pidFilter = `ProcessId=${pid}`;
|
|
24870
24992
|
try {
|
|
24871
|
-
const psOut =
|
|
24993
|
+
const psOut = execFileSync2("powershell.exe", [
|
|
24872
24994
|
"-NoProfile",
|
|
24873
24995
|
"-NonInteractive",
|
|
24874
24996
|
"-ExecutionPolicy",
|
|
@@ -24880,7 +25002,7 @@ function getWindowsProcessCommandLine(pid) {
|
|
|
24880
25002
|
} catch {
|
|
24881
25003
|
}
|
|
24882
25004
|
try {
|
|
24883
|
-
const wmicOut =
|
|
25005
|
+
const wmicOut = execFileSync2("wmic", [
|
|
24884
25006
|
"process",
|
|
24885
25007
|
"where",
|
|
24886
25008
|
pidFilter,
|
|
@@ -24896,7 +25018,7 @@ function getProcessCommandLine(pid) {
|
|
|
24896
25018
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
24897
25019
|
if (process.platform === "win32") return getWindowsProcessCommandLine(pid);
|
|
24898
25020
|
try {
|
|
24899
|
-
const text =
|
|
25021
|
+
const text = execFileSync2("ps", ["-o", "command=", "-p", String(pid)], {
|
|
24900
25022
|
encoding: "utf8",
|
|
24901
25023
|
timeout: 3e3,
|
|
24902
25024
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -24924,8 +25046,8 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
24924
25046
|
function stopSessionHostProcesses(appName) {
|
|
24925
25047
|
const pidFile = path22.join(os19.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
24926
25048
|
try {
|
|
24927
|
-
if (
|
|
24928
|
-
const pid = Number.parseInt(
|
|
25049
|
+
if (fs10.existsSync(pidFile)) {
|
|
25050
|
+
const pid = Number.parseInt(fs10.readFileSync(pidFile, "utf8").trim(), 10);
|
|
24929
25051
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
24930
25052
|
killPid(pid);
|
|
24931
25053
|
}
|
|
@@ -24933,7 +25055,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
24933
25055
|
} catch {
|
|
24934
25056
|
} finally {
|
|
24935
25057
|
try {
|
|
24936
|
-
|
|
25058
|
+
fs10.unlinkSync(pidFile);
|
|
24937
25059
|
} catch {
|
|
24938
25060
|
}
|
|
24939
25061
|
}
|
|
@@ -24941,7 +25063,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
24941
25063
|
function removeDaemonPidFile() {
|
|
24942
25064
|
const pidFile = path22.join(os19.homedir(), ".adhdev", "daemon.pid");
|
|
24943
25065
|
try {
|
|
24944
|
-
|
|
25066
|
+
fs10.unlinkSync(pidFile);
|
|
24945
25067
|
} catch {
|
|
24946
25068
|
}
|
|
24947
25069
|
}
|
|
@@ -24959,23 +25081,23 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
24959
25081
|
if (pkgName.startsWith("@")) {
|
|
24960
25082
|
const [scope, name] = pkgName.split("/");
|
|
24961
25083
|
const scopeDir = path22.join(npmRoot, scope);
|
|
24962
|
-
if (!
|
|
24963
|
-
for (const entry of
|
|
25084
|
+
if (!fs10.existsSync(scopeDir)) return;
|
|
25085
|
+
for (const entry of fs10.readdirSync(scopeDir)) {
|
|
24964
25086
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
24965
|
-
|
|
25087
|
+
fs10.rmSync(path22.join(scopeDir, entry), { recursive: true, force: true });
|
|
24966
25088
|
appendUpgradeLog(`Removed stale scoped staging dir: ${path22.join(scopeDir, entry)}`);
|
|
24967
25089
|
}
|
|
24968
25090
|
} else {
|
|
24969
|
-
for (const entry of
|
|
25091
|
+
for (const entry of fs10.readdirSync(npmRoot)) {
|
|
24970
25092
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
24971
|
-
|
|
25093
|
+
fs10.rmSync(path22.join(npmRoot, entry), { recursive: true, force: true });
|
|
24972
25094
|
appendUpgradeLog(`Removed stale staging dir: ${path22.join(npmRoot, entry)}`);
|
|
24973
25095
|
}
|
|
24974
25096
|
}
|
|
24975
|
-
if (
|
|
24976
|
-
for (const entry of
|
|
25097
|
+
if (fs10.existsSync(binDir)) {
|
|
25098
|
+
for (const entry of fs10.readdirSync(binDir)) {
|
|
24977
25099
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
24978
|
-
|
|
25100
|
+
fs10.rmSync(path22.join(binDir, entry), { recursive: true, force: true });
|
|
24979
25101
|
appendUpgradeLog(`Removed stale bin staging entry: ${path22.join(binDir, entry)}`);
|
|
24980
25102
|
}
|
|
24981
25103
|
}
|
|
@@ -25012,7 +25134,7 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
25012
25134
|
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
25013
25135
|
const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
|
|
25014
25136
|
appendUpgradeLog(`Installing ${spec}`);
|
|
25015
|
-
const installOutput =
|
|
25137
|
+
const installOutput = execFileSync2(
|
|
25016
25138
|
installCommand.command,
|
|
25017
25139
|
installCommand.args,
|
|
25018
25140
|
{
|
|
@@ -25061,9 +25183,10 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
25061
25183
|
}
|
|
25062
25184
|
|
|
25063
25185
|
// src/commands/router.ts
|
|
25186
|
+
init_mesh_work_queue();
|
|
25064
25187
|
import { homedir as homedir19 } from "os";
|
|
25065
25188
|
import { join as pathJoin, resolve as pathResolve } from "path";
|
|
25066
|
-
import * as
|
|
25189
|
+
import * as fs11 from "fs";
|
|
25067
25190
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
25068
25191
|
var CHANNEL_SERVER_URL = {
|
|
25069
25192
|
stable: "https://api.adhf.dev",
|
|
@@ -25707,7 +25830,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
25707
25830
|
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
25708
25831
|
continue;
|
|
25709
25832
|
}
|
|
25710
|
-
if (
|
|
25833
|
+
if (fs11.existsSync(workspace)) {
|
|
25711
25834
|
try {
|
|
25712
25835
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
25713
25836
|
if (localGit?.isGitRepo) {
|
|
@@ -25874,14 +25997,14 @@ function recordMeshRefineStage(stages, stage, status, startedAt, details) {
|
|
|
25874
25997
|
});
|
|
25875
25998
|
}
|
|
25876
25999
|
async function computeGitPatchId(cwd, fromRef, toRef) {
|
|
25877
|
-
const { execFileSync:
|
|
25878
|
-
const diff =
|
|
26000
|
+
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
26001
|
+
const diff = execFileSync3("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
|
|
25879
26002
|
cwd,
|
|
25880
26003
|
encoding: "utf8",
|
|
25881
26004
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
25882
26005
|
});
|
|
25883
26006
|
if (!diff.trim()) return "";
|
|
25884
|
-
const patchId =
|
|
26007
|
+
const patchId = execFileSync3("git", ["patch-id", "--stable"], {
|
|
25885
26008
|
cwd,
|
|
25886
26009
|
input: diff,
|
|
25887
26010
|
encoding: "utf8",
|
|
@@ -25892,8 +26015,8 @@ async function computeGitPatchId(cwd, fromRef, toRef) {
|
|
|
25892
26015
|
async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead) {
|
|
25893
26016
|
const startedAt = Date.now();
|
|
25894
26017
|
try {
|
|
25895
|
-
const { execFileSync:
|
|
25896
|
-
const git = (args) =>
|
|
26018
|
+
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
26019
|
+
const git = (args) => execFileSync3("git", args, {
|
|
25897
26020
|
cwd: repoRoot,
|
|
25898
26021
|
encoding: "utf8",
|
|
25899
26022
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -25946,8 +26069,8 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree) {
|
|
|
25946
26069
|
const entries = [];
|
|
25947
26070
|
try {
|
|
25948
26071
|
const { execFile: execFile3 } = await import("child_process");
|
|
25949
|
-
const { promisify:
|
|
25950
|
-
const execFileAsync3 =
|
|
26072
|
+
const { promisify: promisify6 } = await import("util");
|
|
26073
|
+
const execFileAsync3 = promisify6(execFile3);
|
|
25951
26074
|
const runGit2 = async (cwd, args) => {
|
|
25952
26075
|
const { stdout } = await execFileAsync3("git", args, {
|
|
25953
26076
|
cwd,
|
|
@@ -25971,7 +26094,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree) {
|
|
|
25971
26094
|
reachable: false
|
|
25972
26095
|
};
|
|
25973
26096
|
try {
|
|
25974
|
-
if (!
|
|
26097
|
+
if (!fs11.existsSync(submodulePath)) {
|
|
25975
26098
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
25976
26099
|
entries.push(entry);
|
|
25977
26100
|
continue;
|
|
@@ -26037,8 +26160,8 @@ function buildMeshRefineValidationPlan(mesh, workspace) {
|
|
|
26037
26160
|
}
|
|
26038
26161
|
async function runMeshRefineValidationGate(mesh, workspace) {
|
|
26039
26162
|
const { execFile: execFile3 } = await import("child_process");
|
|
26040
|
-
const { promisify:
|
|
26041
|
-
const execFileAsync3 =
|
|
26163
|
+
const { promisify: promisify6 } = await import("util");
|
|
26164
|
+
const execFileAsync3 = promisify6(execFile3);
|
|
26042
26165
|
const selection = resolveMeshRefineValidationPlan(mesh, workspace);
|
|
26043
26166
|
const summary = {
|
|
26044
26167
|
status: "skipped",
|
|
@@ -26128,9 +26251,9 @@ function resolveHermesUserHome() {
|
|
|
26128
26251
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
26129
26252
|
const sourceHome = resolveHermesUserHome();
|
|
26130
26253
|
const sourceConfigPath = pathJoin(sourceHome, "config.yaml");
|
|
26131
|
-
if (!
|
|
26254
|
+
if (!fs11.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
26132
26255
|
if (pathResolve(sourceConfigPath) === pathResolve(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
26133
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
26256
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs11.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
26134
26257
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
26135
26258
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
26136
26259
|
}
|
|
@@ -26167,9 +26290,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
|
26167
26290
|
for (const fileName of [".env", "auth.json"]) {
|
|
26168
26291
|
const sourcePath = pathJoin(sourceHome, fileName);
|
|
26169
26292
|
const targetPath = pathJoin(targetHome, fileName);
|
|
26170
|
-
if (!
|
|
26293
|
+
if (!fs11.existsSync(sourcePath)) continue;
|
|
26171
26294
|
try {
|
|
26172
|
-
|
|
26295
|
+
fs11.copyFileSync(sourcePath, targetPath);
|
|
26173
26296
|
} catch (error) {
|
|
26174
26297
|
LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
|
|
26175
26298
|
}
|
|
@@ -26382,6 +26505,7 @@ var DaemonCommandRouter = class {
|
|
|
26382
26505
|
getCachedAggregateMeshStatus(meshId, mesh, options) {
|
|
26383
26506
|
const cached = this.aggregateMeshStatusCache.get(meshId);
|
|
26384
26507
|
if (!cached?.snapshot || cached.snapshot.success !== true || !Array.isArray(cached.snapshot.nodes)) return null;
|
|
26508
|
+
if (cached.queueRevision !== getMeshQueueRevision(meshId)) return null;
|
|
26385
26509
|
let snapshot = this.cloneJsonValue(cached.snapshot);
|
|
26386
26510
|
snapshot = this.hydrateCachedAggregateMeshStatusFromInline(snapshot, mesh, options);
|
|
26387
26511
|
if (shouldRefreshStalePendingAggregate(snapshot, options)) return null;
|
|
@@ -26419,7 +26543,7 @@ var DaemonCommandRouter = class {
|
|
|
26419
26543
|
returnedAt: new Date(builtAt).toISOString()
|
|
26420
26544
|
}
|
|
26421
26545
|
};
|
|
26422
|
-
this.aggregateMeshStatusCache.set(meshId, { builtAt, snapshot: this.cloneJsonValue(next) });
|
|
26546
|
+
this.aggregateMeshStatusCache.set(meshId, { builtAt, snapshot: this.cloneJsonValue(next), queueRevision: getMeshQueueRevision(meshId) });
|
|
26423
26547
|
return next;
|
|
26424
26548
|
}
|
|
26425
26549
|
getCachedInlineMesh(meshId, inlineMesh) {
|
|
@@ -26522,13 +26646,13 @@ var DaemonCommandRouter = class {
|
|
|
26522
26646
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
26523
26647
|
};
|
|
26524
26648
|
}
|
|
26525
|
-
const worktreeExists =
|
|
26649
|
+
const worktreeExists = fs11.existsSync(workspace);
|
|
26526
26650
|
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);
|
|
26527
26651
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
26528
26652
|
if (!worktreeExists) {
|
|
26529
26653
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
26530
26654
|
}
|
|
26531
|
-
if (!repoRoot || !
|
|
26655
|
+
if (!repoRoot || !fs11.existsSync(repoRoot)) {
|
|
26532
26656
|
return {
|
|
26533
26657
|
success: false,
|
|
26534
26658
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -26548,7 +26672,7 @@ var DaemonCommandRouter = class {
|
|
|
26548
26672
|
const normalizePath = (value) => {
|
|
26549
26673
|
const resolved = pathResolve(value);
|
|
26550
26674
|
try {
|
|
26551
|
-
return
|
|
26675
|
+
return fs11.realpathSync(resolved);
|
|
26552
26676
|
} catch {
|
|
26553
26677
|
return resolved;
|
|
26554
26678
|
}
|
|
@@ -26621,8 +26745,8 @@ var DaemonCommandRouter = class {
|
|
|
26621
26745
|
return { allow: true, status: metadataStatus, source: "node_branch_convergence" };
|
|
26622
26746
|
}
|
|
26623
26747
|
const { execFile: execFile3 } = await import("child_process");
|
|
26624
|
-
const { promisify:
|
|
26625
|
-
const execFileAsync3 =
|
|
26748
|
+
const { promisify: promisify6 } = await import("util");
|
|
26749
|
+
const execFileAsync3 = promisify6(execFile3);
|
|
26626
26750
|
const runGit2 = async (gitArgs, cwd) => {
|
|
26627
26751
|
const { stdout } = await execFileAsync3("git", gitArgs, {
|
|
26628
26752
|
cwd,
|
|
@@ -27032,8 +27156,8 @@ var DaemonCommandRouter = class {
|
|
|
27032
27156
|
const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
|
|
27033
27157
|
if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
|
|
27034
27158
|
const { execFile: execFile3 } = await import("child_process");
|
|
27035
|
-
const { promisify:
|
|
27036
|
-
const execFileAsync3 =
|
|
27159
|
+
const { promisify: promisify6 } = await import("util");
|
|
27160
|
+
const execFileAsync3 = promisify6(execFile3);
|
|
27037
27161
|
const resolveStarted = Date.now();
|
|
27038
27162
|
const { stdout: branchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
|
|
27039
27163
|
const branch = branchStdout.trim();
|
|
@@ -27342,8 +27466,8 @@ var DaemonCommandRouter = class {
|
|
|
27342
27466
|
if (sinceTs > 0) {
|
|
27343
27467
|
return { success: true, logs: [], totalBuffered: 0 };
|
|
27344
27468
|
}
|
|
27345
|
-
if (
|
|
27346
|
-
const content =
|
|
27469
|
+
if (fs11.existsSync(LOG_PATH)) {
|
|
27470
|
+
const content = fs11.readFileSync(LOG_PATH, "utf-8");
|
|
27347
27471
|
const allLines = content.split("\n");
|
|
27348
27472
|
const recent = allLines.slice(-count).join("\n");
|
|
27349
27473
|
return { success: true, logs: recent, totalLines: allLines.length };
|
|
@@ -28766,7 +28890,7 @@ ${block2}`);
|
|
|
28766
28890
|
workspace
|
|
28767
28891
|
};
|
|
28768
28892
|
}
|
|
28769
|
-
const { existsSync:
|
|
28893
|
+
const { existsSync: existsSync26, readFileSync: readFileSync19, writeFileSync: writeFileSync14, copyFileSync: copyFileSync4, mkdirSync: mkdirSync18 } = await import("fs");
|
|
28770
28894
|
const { dirname: dirname9 } = await import("path");
|
|
28771
28895
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
28772
28896
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -28802,14 +28926,14 @@ ${block2}`);
|
|
|
28802
28926
|
};
|
|
28803
28927
|
}
|
|
28804
28928
|
try {
|
|
28805
|
-
|
|
28929
|
+
mkdirSync18(dirname9(mcpConfigPath), { recursive: true });
|
|
28806
28930
|
} catch (error) {
|
|
28807
28931
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
28808
28932
|
LOG.error("MeshCoordinator", message);
|
|
28809
28933
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
28810
28934
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
28811
28935
|
}
|
|
28812
|
-
const hadExistingMcpConfig =
|
|
28936
|
+
const hadExistingMcpConfig = existsSync26(mcpConfigPath);
|
|
28813
28937
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
28814
28938
|
if (hermesBaseConfig) {
|
|
28815
28939
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
|
|
@@ -28839,7 +28963,7 @@ ${block2}`);
|
|
|
28839
28963
|
}
|
|
28840
28964
|
};
|
|
28841
28965
|
try {
|
|
28842
|
-
|
|
28966
|
+
writeFileSync14(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
28843
28967
|
} catch (error) {
|
|
28844
28968
|
const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
|
|
28845
28969
|
LOG.error("MeshCoordinator", message);
|
|
@@ -29067,7 +29191,7 @@ ${block2}`);
|
|
|
29067
29191
|
}
|
|
29068
29192
|
}
|
|
29069
29193
|
if (workspace) {
|
|
29070
|
-
if (!
|
|
29194
|
+
if (!fs11.existsSync(workspace)) {
|
|
29071
29195
|
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
29072
29196
|
let remoteProbeApplied = false;
|
|
29073
29197
|
if (inlineTransitGit) {
|
|
@@ -29276,7 +29400,7 @@ ${block2}`);
|
|
|
29276
29400
|
}
|
|
29277
29401
|
}
|
|
29278
29402
|
if (killProcess) {
|
|
29279
|
-
const running = isIdeRunning(ideType);
|
|
29403
|
+
const running = await isIdeRunning(ideType);
|
|
29280
29404
|
if (running) {
|
|
29281
29405
|
LOG.info("StopIDE", `Killing IDE process: ${ideType}`);
|
|
29282
29406
|
const killed = await killIdeProcess(ideType);
|
|
@@ -29302,6 +29426,8 @@ var DaemonStatusReporter = class {
|
|
|
29302
29426
|
lastStatusSentAt = 0;
|
|
29303
29427
|
statusPendingThrottle = false;
|
|
29304
29428
|
lastP2PStatusHash = "";
|
|
29429
|
+
lastP2PStatusSentAt = 0;
|
|
29430
|
+
p2pDebounceTimer = null;
|
|
29305
29431
|
lastServerStatusHash = "";
|
|
29306
29432
|
lastStatusSummary = "";
|
|
29307
29433
|
statusTimer = null;
|
|
@@ -29553,7 +29679,18 @@ var DaemonStatusReporter = class {
|
|
|
29553
29679
|
})() : { ...hashTarget, sessions };
|
|
29554
29680
|
const h = this.simpleHash(JSON.stringify(hashPayload));
|
|
29555
29681
|
if (h !== this.lastP2PStatusHash) {
|
|
29682
|
+
const now = Date.now();
|
|
29683
|
+
if (this.lastP2PStatusSentAt && now - this.lastP2PStatusSentAt < 500) {
|
|
29684
|
+
if (!this.p2pDebounceTimer) {
|
|
29685
|
+
this.p2pDebounceTimer = setTimeout(() => {
|
|
29686
|
+
this.p2pDebounceTimer = null;
|
|
29687
|
+
this.sendUnifiedStatusReport({ reason: "p2p_debounce" });
|
|
29688
|
+
}, 500);
|
|
29689
|
+
}
|
|
29690
|
+
return false;
|
|
29691
|
+
}
|
|
29556
29692
|
this.lastP2PStatusHash = h;
|
|
29693
|
+
this.lastP2PStatusSentAt = now;
|
|
29557
29694
|
this.deps.p2p?.sendStatus(payload);
|
|
29558
29695
|
return true;
|
|
29559
29696
|
}
|
|
@@ -30888,11 +31025,11 @@ var ProviderInstanceManager = class {
|
|
|
30888
31025
|
};
|
|
30889
31026
|
|
|
30890
31027
|
// src/providers/version-archive.ts
|
|
30891
|
-
import * as
|
|
31028
|
+
import * as fs12 from "fs";
|
|
30892
31029
|
import * as path23 from "path";
|
|
30893
31030
|
import * as os20 from "os";
|
|
30894
|
-
import { execSync as execSync5 } from "child_process";
|
|
30895
31031
|
import { platform as platform8 } from "os";
|
|
31032
|
+
import { exec as exec5 } from "child_process";
|
|
30896
31033
|
var ARCHIVE_PATH = path23.join(os20.homedir(), ".adhdev", "version-history.json");
|
|
30897
31034
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
30898
31035
|
var VersionArchive = class {
|
|
@@ -30902,8 +31039,8 @@ var VersionArchive = class {
|
|
|
30902
31039
|
}
|
|
30903
31040
|
load() {
|
|
30904
31041
|
try {
|
|
30905
|
-
if (
|
|
30906
|
-
this.history = JSON.parse(
|
|
31042
|
+
if (fs12.existsSync(ARCHIVE_PATH)) {
|
|
31043
|
+
this.history = JSON.parse(fs12.readFileSync(ARCHIVE_PATH, "utf-8"));
|
|
30907
31044
|
}
|
|
30908
31045
|
} catch {
|
|
30909
31046
|
this.history = {};
|
|
@@ -30940,27 +31077,43 @@ var VersionArchive = class {
|
|
|
30940
31077
|
}
|
|
30941
31078
|
save() {
|
|
30942
31079
|
try {
|
|
30943
|
-
|
|
30944
|
-
|
|
31080
|
+
fs12.mkdirSync(path23.dirname(ARCHIVE_PATH), { recursive: true });
|
|
31081
|
+
fs12.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
30945
31082
|
} catch {
|
|
30946
31083
|
}
|
|
30947
31084
|
}
|
|
30948
31085
|
};
|
|
30949
|
-
function runCommand(cmd, timeout = 1e4) {
|
|
30950
|
-
|
|
30951
|
-
|
|
31086
|
+
async function runCommand(cmd, timeout = 1e4) {
|
|
31087
|
+
return new Promise((resolve16) => {
|
|
31088
|
+
exec5(cmd, {
|
|
30952
31089
|
encoding: "utf-8",
|
|
30953
|
-
timeout
|
|
30954
|
-
|
|
30955
|
-
|
|
30956
|
-
|
|
30957
|
-
|
|
30958
|
-
}
|
|
31090
|
+
timeout
|
|
31091
|
+
}, (error, stdout) => {
|
|
31092
|
+
if (error) return resolve16(null);
|
|
31093
|
+
resolve16(stdout.trim());
|
|
31094
|
+
});
|
|
31095
|
+
});
|
|
30959
31096
|
}
|
|
30960
31097
|
function findBinary2(name) {
|
|
30961
|
-
const
|
|
30962
|
-
const
|
|
30963
|
-
|
|
31098
|
+
const isWin = platform8() === "win32";
|
|
31099
|
+
const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
|
|
31100
|
+
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
31101
|
+
for (const p of paths) {
|
|
31102
|
+
if (!p) continue;
|
|
31103
|
+
for (const ext of exes) {
|
|
31104
|
+
const fullPath = path23.join(p, name + ext);
|
|
31105
|
+
try {
|
|
31106
|
+
if (fs12.existsSync(fullPath)) {
|
|
31107
|
+
const stat2 = fs12.statSync(fullPath);
|
|
31108
|
+
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
31109
|
+
return fullPath;
|
|
31110
|
+
}
|
|
31111
|
+
}
|
|
31112
|
+
} catch {
|
|
31113
|
+
}
|
|
31114
|
+
}
|
|
31115
|
+
}
|
|
31116
|
+
return null;
|
|
30964
31117
|
}
|
|
30965
31118
|
function parseVersion2(raw) {
|
|
30966
31119
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
@@ -30982,13 +31135,13 @@ function getPlatformVersionCommand(versionCommand, currentOs) {
|
|
|
30982
31135
|
}
|
|
30983
31136
|
return void 0;
|
|
30984
31137
|
}
|
|
30985
|
-
function getVersion(binary, versionCommand) {
|
|
31138
|
+
async function getVersion(binary, versionCommand) {
|
|
30986
31139
|
if (versionCommand) {
|
|
30987
|
-
const raw = runCommand(versionCommand);
|
|
31140
|
+
const raw = await runCommand(versionCommand);
|
|
30988
31141
|
return raw ? parseVersion2(raw) : null;
|
|
30989
31142
|
}
|
|
30990
31143
|
for (const flag of ["--version", "-V", "-v"]) {
|
|
30991
|
-
const raw = runCommand(`"${binary}" ${flag}`);
|
|
31144
|
+
const raw = await runCommand(`"${binary}" ${flag}`);
|
|
30992
31145
|
if (raw && raw.length < 500) return parseVersion2(raw);
|
|
30993
31146
|
}
|
|
30994
31147
|
return null;
|
|
@@ -30998,18 +31151,18 @@ function checkPathExists2(paths) {
|
|
|
30998
31151
|
if (p.includes("*")) {
|
|
30999
31152
|
const home = os20.homedir();
|
|
31000
31153
|
const resolved = p.replace(/\*/g, home.split(path23.sep).pop() || "");
|
|
31001
|
-
if (
|
|
31154
|
+
if (fs12.existsSync(resolved)) return resolved;
|
|
31002
31155
|
} else {
|
|
31003
|
-
if (
|
|
31156
|
+
if (fs12.existsSync(p)) return p;
|
|
31004
31157
|
}
|
|
31005
31158
|
}
|
|
31006
31159
|
return null;
|
|
31007
31160
|
}
|
|
31008
|
-
function getMacAppVersion(appPath) {
|
|
31161
|
+
async function getMacAppVersion(appPath) {
|
|
31009
31162
|
if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
31010
31163
|
const plistPath = path23.join(appPath, "Contents", "Info.plist");
|
|
31011
|
-
if (!
|
|
31012
|
-
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
31164
|
+
if (!fs12.existsSync(plistPath)) return null;
|
|
31165
|
+
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
31013
31166
|
return raw || null;
|
|
31014
31167
|
}
|
|
31015
31168
|
async function detectAllVersions(loader, archive) {
|
|
@@ -31034,16 +31187,16 @@ async function detectAllVersions(loader, archive) {
|
|
|
31034
31187
|
let resolvedBin = cliBin;
|
|
31035
31188
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
31036
31189
|
const bundled = path23.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
31037
|
-
if (provider.cli &&
|
|
31190
|
+
if (provider.cli && fs12.existsSync(bundled)) resolvedBin = bundled;
|
|
31038
31191
|
}
|
|
31039
31192
|
info.installed = !!(appPath || resolvedBin);
|
|
31040
31193
|
info.path = appPath || null;
|
|
31041
31194
|
info.binary = resolvedBin || null;
|
|
31042
31195
|
if (resolvedBin) {
|
|
31043
|
-
info.version = getVersion(resolvedBin, versionCommand);
|
|
31196
|
+
info.version = await getVersion(resolvedBin, versionCommand);
|
|
31044
31197
|
}
|
|
31045
31198
|
if (!info.version && appPath) {
|
|
31046
|
-
info.version = getMacAppVersion(appPath);
|
|
31199
|
+
info.version = await getMacAppVersion(appPath);
|
|
31047
31200
|
}
|
|
31048
31201
|
} else if (provider.category === "cli" || provider.category === "acp") {
|
|
31049
31202
|
const bin = provider.binary || provider.spawn?.command || provider.cli || provider.type;
|
|
@@ -31051,7 +31204,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
31051
31204
|
info.installed = !!binPath;
|
|
31052
31205
|
info.binary = binPath || null;
|
|
31053
31206
|
if (binPath) {
|
|
31054
|
-
info.version = getVersion(binPath, versionCommand);
|
|
31207
|
+
info.version = await getVersion(binPath, versionCommand);
|
|
31055
31208
|
}
|
|
31056
31209
|
} else if (provider.category === "extension") {
|
|
31057
31210
|
info.installed = false;
|
|
@@ -31073,7 +31226,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
31073
31226
|
|
|
31074
31227
|
// src/daemon/dev-server.ts
|
|
31075
31228
|
import * as http2 from "http";
|
|
31076
|
-
import * as
|
|
31229
|
+
import * as fs16 from "fs";
|
|
31077
31230
|
import * as path27 from "path";
|
|
31078
31231
|
init_config();
|
|
31079
31232
|
|
|
@@ -31425,7 +31578,7 @@ init_logger();
|
|
|
31425
31578
|
|
|
31426
31579
|
// src/daemon/dev-cdp-handlers.ts
|
|
31427
31580
|
init_logger();
|
|
31428
|
-
import * as
|
|
31581
|
+
import * as fs13 from "fs";
|
|
31429
31582
|
import * as path24 from "path";
|
|
31430
31583
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
31431
31584
|
const body = await ctx.readBody(req);
|
|
@@ -31605,17 +31758,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
31605
31758
|
}
|
|
31606
31759
|
let scriptsPath = "";
|
|
31607
31760
|
const directScripts = path24.join(dir, "scripts.js");
|
|
31608
|
-
if (
|
|
31761
|
+
if (fs13.existsSync(directScripts)) {
|
|
31609
31762
|
scriptsPath = directScripts;
|
|
31610
31763
|
} else {
|
|
31611
31764
|
const scriptsDir = path24.join(dir, "scripts");
|
|
31612
|
-
if (
|
|
31613
|
-
const versions =
|
|
31614
|
-
return
|
|
31765
|
+
if (fs13.existsSync(scriptsDir)) {
|
|
31766
|
+
const versions = fs13.readdirSync(scriptsDir).filter((d) => {
|
|
31767
|
+
return fs13.statSync(path24.join(scriptsDir, d)).isDirectory();
|
|
31615
31768
|
}).sort().reverse();
|
|
31616
31769
|
for (const ver of versions) {
|
|
31617
31770
|
const p = path24.join(scriptsDir, ver, "scripts.js");
|
|
31618
|
-
if (
|
|
31771
|
+
if (fs13.existsSync(p)) {
|
|
31619
31772
|
scriptsPath = p;
|
|
31620
31773
|
break;
|
|
31621
31774
|
}
|
|
@@ -31627,7 +31780,7 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
31627
31780
|
return;
|
|
31628
31781
|
}
|
|
31629
31782
|
try {
|
|
31630
|
-
const source =
|
|
31783
|
+
const source = fs13.readFileSync(scriptsPath, "utf-8");
|
|
31631
31784
|
const hints = {};
|
|
31632
31785
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
31633
31786
|
let match;
|
|
@@ -32442,7 +32595,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
32442
32595
|
}
|
|
32443
32596
|
|
|
32444
32597
|
// src/daemon/dev-cli-debug.ts
|
|
32445
|
-
import * as
|
|
32598
|
+
import * as fs14 from "fs";
|
|
32446
32599
|
import * as path25 from "path";
|
|
32447
32600
|
function slugifyFixtureName(value) {
|
|
32448
32601
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -32458,10 +32611,10 @@ function getCliFixtureDir(ctx, type) {
|
|
|
32458
32611
|
function readCliFixture(ctx, type, name) {
|
|
32459
32612
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
32460
32613
|
const filePath = path25.join(fixtureDir, `${name}.json`);
|
|
32461
|
-
if (!
|
|
32614
|
+
if (!fs14.existsSync(filePath)) {
|
|
32462
32615
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
32463
32616
|
}
|
|
32464
|
-
return JSON.parse(
|
|
32617
|
+
return JSON.parse(fs14.readFileSync(filePath, "utf-8"));
|
|
32465
32618
|
}
|
|
32466
32619
|
function getExerciseTranscriptText(result) {
|
|
32467
32620
|
const parts = [];
|
|
@@ -33197,7 +33350,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
33197
33350
|
return;
|
|
33198
33351
|
}
|
|
33199
33352
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
33200
|
-
|
|
33353
|
+
fs14.mkdirSync(fixtureDir, { recursive: true });
|
|
33201
33354
|
const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
|
|
33202
33355
|
const result = await runCliExerciseInternal(ctx, { ...request, type });
|
|
33203
33356
|
const fixture = {
|
|
@@ -33225,7 +33378,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
33225
33378
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
33226
33379
|
};
|
|
33227
33380
|
const filePath = path25.join(fixtureDir, `${name}.json`);
|
|
33228
|
-
|
|
33381
|
+
fs14.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
33229
33382
|
ctx.json(res, 200, {
|
|
33230
33383
|
saved: true,
|
|
33231
33384
|
name,
|
|
@@ -33243,14 +33396,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
33243
33396
|
async function handleCliFixtureList(ctx, type, _req, res) {
|
|
33244
33397
|
try {
|
|
33245
33398
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
33246
|
-
if (!
|
|
33399
|
+
if (!fs14.existsSync(fixtureDir)) {
|
|
33247
33400
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
33248
33401
|
return;
|
|
33249
33402
|
}
|
|
33250
|
-
const fixtures =
|
|
33403
|
+
const fixtures = fs14.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
33251
33404
|
const fullPath = path25.join(fixtureDir, file);
|
|
33252
33405
|
try {
|
|
33253
|
-
const raw = JSON.parse(
|
|
33406
|
+
const raw = JSON.parse(fs14.readFileSync(fullPath, "utf-8"));
|
|
33254
33407
|
return {
|
|
33255
33408
|
name: raw.name || file.replace(/\.json$/i, ""),
|
|
33256
33409
|
path: fullPath,
|
|
@@ -33383,7 +33536,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
33383
33536
|
}
|
|
33384
33537
|
|
|
33385
33538
|
// src/daemon/dev-auto-implement.ts
|
|
33386
|
-
import * as
|
|
33539
|
+
import * as fs15 from "fs";
|
|
33387
33540
|
import * as path26 from "path";
|
|
33388
33541
|
import * as os21 from "os";
|
|
33389
33542
|
function getAutoImplPid(ctx) {
|
|
@@ -33431,10 +33584,10 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
|
|
|
33431
33584
|
return fallback?.type || null;
|
|
33432
33585
|
}
|
|
33433
33586
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
33434
|
-
if (!
|
|
33435
|
-
const versions =
|
|
33587
|
+
if (!fs15.existsSync(scriptsDir)) return null;
|
|
33588
|
+
const versions = fs15.readdirSync(scriptsDir).filter((d) => {
|
|
33436
33589
|
try {
|
|
33437
|
-
return
|
|
33590
|
+
return fs15.statSync(path26.join(scriptsDir, d)).isDirectory();
|
|
33438
33591
|
} catch {
|
|
33439
33592
|
return false;
|
|
33440
33593
|
}
|
|
@@ -33456,13 +33609,13 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
33456
33609
|
if (!sourceDir) {
|
|
33457
33610
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
33458
33611
|
}
|
|
33459
|
-
if (!
|
|
33460
|
-
|
|
33461
|
-
|
|
33612
|
+
if (!fs15.existsSync(desiredDir)) {
|
|
33613
|
+
fs15.mkdirSync(path26.dirname(desiredDir), { recursive: true });
|
|
33614
|
+
fs15.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
33462
33615
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
33463
33616
|
}
|
|
33464
33617
|
const providerJson = path26.join(desiredDir, "provider.json");
|
|
33465
|
-
if (!
|
|
33618
|
+
if (!fs15.existsSync(providerJson)) {
|
|
33466
33619
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
33467
33620
|
}
|
|
33468
33621
|
return { dir: desiredDir };
|
|
@@ -33470,15 +33623,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
33470
33623
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
33471
33624
|
if (!referenceType) return {};
|
|
33472
33625
|
const refDir = ctx.findProviderDir(referenceType);
|
|
33473
|
-
if (!refDir || !
|
|
33626
|
+
if (!refDir || !fs15.existsSync(refDir)) return {};
|
|
33474
33627
|
const referenceScripts = {};
|
|
33475
33628
|
const scriptsDir = path26.join(refDir, "scripts");
|
|
33476
33629
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
33477
33630
|
if (!latestDir) return referenceScripts;
|
|
33478
|
-
for (const file of
|
|
33631
|
+
for (const file of fs15.readdirSync(latestDir)) {
|
|
33479
33632
|
if (!file.endsWith(".js")) continue;
|
|
33480
33633
|
try {
|
|
33481
|
-
referenceScripts[file] =
|
|
33634
|
+
referenceScripts[file] = fs15.readFileSync(path26.join(latestDir, file), "utf-8");
|
|
33482
33635
|
} catch {
|
|
33483
33636
|
}
|
|
33484
33637
|
}
|
|
@@ -33587,15 +33740,15 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
33587
33740
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
33588
33741
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
33589
33742
|
const tmpDir = path26.join(os21.tmpdir(), "adhdev-autoimpl");
|
|
33590
|
-
if (!
|
|
33743
|
+
if (!fs15.existsSync(tmpDir)) fs15.mkdirSync(tmpDir, { recursive: true });
|
|
33591
33744
|
const promptFile = path26.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
33592
|
-
|
|
33745
|
+
fs15.writeFileSync(promptFile, prompt, "utf-8");
|
|
33593
33746
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
33594
33747
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
33595
33748
|
const spawn4 = agentProvider?.spawn;
|
|
33596
33749
|
if (!spawn4?.command) {
|
|
33597
33750
|
try {
|
|
33598
|
-
|
|
33751
|
+
fs15.unlinkSync(promptFile);
|
|
33599
33752
|
} catch {
|
|
33600
33753
|
}
|
|
33601
33754
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -33697,7 +33850,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
33697
33850
|
} catch {
|
|
33698
33851
|
}
|
|
33699
33852
|
try {
|
|
33700
|
-
|
|
33853
|
+
fs15.unlinkSync(promptFile);
|
|
33701
33854
|
} catch {
|
|
33702
33855
|
}
|
|
33703
33856
|
ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
|
|
@@ -33923,7 +34076,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
33923
34076
|
}
|
|
33924
34077
|
});
|
|
33925
34078
|
try {
|
|
33926
|
-
|
|
34079
|
+
fs15.unlinkSync(promptFile);
|
|
33927
34080
|
} catch {
|
|
33928
34081
|
}
|
|
33929
34082
|
ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -34028,10 +34181,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
34028
34181
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
34029
34182
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
34030
34183
|
lines.push("");
|
|
34031
|
-
for (const file of
|
|
34184
|
+
for (const file of fs15.readdirSync(latestScriptsDir)) {
|
|
34032
34185
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
34033
34186
|
try {
|
|
34034
|
-
const content =
|
|
34187
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
34035
34188
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
34036
34189
|
lines.push("```javascript");
|
|
34037
34190
|
lines.push(content);
|
|
@@ -34041,14 +34194,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
34041
34194
|
}
|
|
34042
34195
|
}
|
|
34043
34196
|
}
|
|
34044
|
-
const refFiles =
|
|
34197
|
+
const refFiles = fs15.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
34045
34198
|
if (refFiles.length > 0) {
|
|
34046
34199
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
34047
34200
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
34048
34201
|
lines.push("");
|
|
34049
34202
|
for (const file of refFiles) {
|
|
34050
34203
|
try {
|
|
34051
|
-
const content =
|
|
34204
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
34052
34205
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
34053
34206
|
lines.push("```javascript");
|
|
34054
34207
|
lines.push(content);
|
|
@@ -34093,7 +34246,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
34093
34246
|
const loadGuide = (name) => {
|
|
34094
34247
|
try {
|
|
34095
34248
|
const p = path26.join(docsDir, name);
|
|
34096
|
-
if (
|
|
34249
|
+
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
34097
34250
|
} catch {
|
|
34098
34251
|
}
|
|
34099
34252
|
return null;
|
|
@@ -34337,11 +34490,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
34337
34490
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
34338
34491
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
34339
34492
|
lines.push("");
|
|
34340
|
-
for (const file of
|
|
34493
|
+
for (const file of fs15.readdirSync(latestScriptsDir)) {
|
|
34341
34494
|
if (!file.endsWith(".js")) continue;
|
|
34342
34495
|
if (!targetFileNames.has(file)) continue;
|
|
34343
34496
|
try {
|
|
34344
|
-
const content =
|
|
34497
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
34345
34498
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
34346
34499
|
lines.push("```javascript");
|
|
34347
34500
|
lines.push(content);
|
|
@@ -34350,14 +34503,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
34350
34503
|
} catch {
|
|
34351
34504
|
}
|
|
34352
34505
|
}
|
|
34353
|
-
const refFiles =
|
|
34506
|
+
const refFiles = fs15.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
34354
34507
|
if (refFiles.length > 0) {
|
|
34355
34508
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
34356
34509
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
34357
34510
|
lines.push("");
|
|
34358
34511
|
for (const file of refFiles) {
|
|
34359
34512
|
try {
|
|
34360
|
-
const content =
|
|
34513
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
34361
34514
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
34362
34515
|
lines.push("```javascript");
|
|
34363
34516
|
lines.push(content);
|
|
@@ -34394,7 +34547,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
34394
34547
|
const loadGuide = (name) => {
|
|
34395
34548
|
try {
|
|
34396
34549
|
const p = path26.join(docsDir, name);
|
|
34397
|
-
if (
|
|
34550
|
+
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
34398
34551
|
} catch {
|
|
34399
34552
|
}
|
|
34400
34553
|
return null;
|
|
@@ -35134,7 +35287,7 @@ var DevServer = class _DevServer {
|
|
|
35134
35287
|
path27.join(process.cwd(), "packages/web-devconsole/dist")
|
|
35135
35288
|
];
|
|
35136
35289
|
for (const dir of candidates) {
|
|
35137
|
-
if (
|
|
35290
|
+
if (fs16.existsSync(path27.join(dir, "index.html"))) return dir;
|
|
35138
35291
|
}
|
|
35139
35292
|
return null;
|
|
35140
35293
|
}
|
|
@@ -35146,7 +35299,7 @@ var DevServer = class _DevServer {
|
|
|
35146
35299
|
}
|
|
35147
35300
|
const htmlPath = path27.join(distDir, "index.html");
|
|
35148
35301
|
try {
|
|
35149
|
-
const html =
|
|
35302
|
+
const html = fs16.readFileSync(htmlPath, "utf-8");
|
|
35150
35303
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
35151
35304
|
res.end(html);
|
|
35152
35305
|
} catch (e) {
|
|
@@ -35176,7 +35329,7 @@ var DevServer = class _DevServer {
|
|
|
35176
35329
|
return;
|
|
35177
35330
|
}
|
|
35178
35331
|
try {
|
|
35179
|
-
const content =
|
|
35332
|
+
const content = fs16.readFileSync(filePath);
|
|
35180
35333
|
const ext = path27.extname(filePath);
|
|
35181
35334
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
35182
35335
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
@@ -35285,14 +35438,14 @@ var DevServer = class _DevServer {
|
|
|
35285
35438
|
const files = [];
|
|
35286
35439
|
const scan = (d, prefix) => {
|
|
35287
35440
|
try {
|
|
35288
|
-
for (const entry of
|
|
35441
|
+
for (const entry of fs16.readdirSync(d, { withFileTypes: true })) {
|
|
35289
35442
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
35290
35443
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
35291
35444
|
if (entry.isDirectory()) {
|
|
35292
35445
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
35293
35446
|
scan(path27.join(d, entry.name), rel);
|
|
35294
35447
|
} else {
|
|
35295
|
-
const stat2 =
|
|
35448
|
+
const stat2 = fs16.statSync(path27.join(d, entry.name));
|
|
35296
35449
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
35297
35450
|
}
|
|
35298
35451
|
}
|
|
@@ -35320,11 +35473,11 @@ var DevServer = class _DevServer {
|
|
|
35320
35473
|
this.json(res, 403, { error: "Forbidden" });
|
|
35321
35474
|
return;
|
|
35322
35475
|
}
|
|
35323
|
-
if (!
|
|
35476
|
+
if (!fs16.existsSync(fullPath) || fs16.statSync(fullPath).isDirectory()) {
|
|
35324
35477
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
35325
35478
|
return;
|
|
35326
35479
|
}
|
|
35327
|
-
const content =
|
|
35480
|
+
const content = fs16.readFileSync(fullPath, "utf-8");
|
|
35328
35481
|
this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
|
|
35329
35482
|
}
|
|
35330
35483
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -35346,9 +35499,9 @@ var DevServer = class _DevServer {
|
|
|
35346
35499
|
return;
|
|
35347
35500
|
}
|
|
35348
35501
|
try {
|
|
35349
|
-
if (
|
|
35350
|
-
|
|
35351
|
-
|
|
35502
|
+
if (fs16.existsSync(fullPath)) fs16.copyFileSync(fullPath, fullPath + ".bak");
|
|
35503
|
+
fs16.mkdirSync(path27.dirname(fullPath), { recursive: true });
|
|
35504
|
+
fs16.writeFileSync(fullPath, content, "utf-8");
|
|
35352
35505
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
35353
35506
|
this.providerLoader.reload();
|
|
35354
35507
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -35365,8 +35518,8 @@ var DevServer = class _DevServer {
|
|
|
35365
35518
|
}
|
|
35366
35519
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
35367
35520
|
const p = path27.join(dir, name);
|
|
35368
|
-
if (
|
|
35369
|
-
const source =
|
|
35521
|
+
if (fs16.existsSync(p)) {
|
|
35522
|
+
const source = fs16.readFileSync(p, "utf-8");
|
|
35370
35523
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
35371
35524
|
return;
|
|
35372
35525
|
}
|
|
@@ -35385,11 +35538,11 @@ var DevServer = class _DevServer {
|
|
|
35385
35538
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
35386
35539
|
return;
|
|
35387
35540
|
}
|
|
35388
|
-
const target =
|
|
35541
|
+
const target = fs16.existsSync(path27.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
35389
35542
|
const targetPath = path27.join(dir, target);
|
|
35390
35543
|
try {
|
|
35391
|
-
if (
|
|
35392
|
-
|
|
35544
|
+
if (fs16.existsSync(targetPath)) fs16.copyFileSync(targetPath, targetPath + ".bak");
|
|
35545
|
+
fs16.writeFileSync(targetPath, source, "utf-8");
|
|
35393
35546
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
35394
35547
|
this.providerLoader.reload();
|
|
35395
35548
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -35534,20 +35687,20 @@ var DevServer = class _DevServer {
|
|
|
35534
35687
|
let targetDir;
|
|
35535
35688
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
35536
35689
|
const jsonPath = path27.join(targetDir, "provider.json");
|
|
35537
|
-
if (
|
|
35690
|
+
if (fs16.existsSync(jsonPath)) {
|
|
35538
35691
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
35539
35692
|
return;
|
|
35540
35693
|
}
|
|
35541
35694
|
try {
|
|
35542
35695
|
const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
|
|
35543
|
-
|
|
35544
|
-
|
|
35696
|
+
fs16.mkdirSync(targetDir, { recursive: true });
|
|
35697
|
+
fs16.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
35545
35698
|
const createdFiles = ["provider.json"];
|
|
35546
35699
|
if (result.files) {
|
|
35547
35700
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
35548
35701
|
const fullPath = path27.join(targetDir, relPath);
|
|
35549
|
-
|
|
35550
|
-
|
|
35702
|
+
fs16.mkdirSync(path27.dirname(fullPath), { recursive: true });
|
|
35703
|
+
fs16.writeFileSync(fullPath, content, "utf-8");
|
|
35551
35704
|
createdFiles.push(relPath);
|
|
35552
35705
|
}
|
|
35553
35706
|
}
|
|
@@ -35596,10 +35749,10 @@ var DevServer = class _DevServer {
|
|
|
35596
35749
|
}
|
|
35597
35750
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
35598
35751
|
getLatestScriptVersionDir(scriptsDir) {
|
|
35599
|
-
if (!
|
|
35600
|
-
const versions =
|
|
35752
|
+
if (!fs16.existsSync(scriptsDir)) return null;
|
|
35753
|
+
const versions = fs16.readdirSync(scriptsDir).filter((d) => {
|
|
35601
35754
|
try {
|
|
35602
|
-
return
|
|
35755
|
+
return fs16.statSync(path27.join(scriptsDir, d)).isDirectory();
|
|
35603
35756
|
} catch {
|
|
35604
35757
|
return false;
|
|
35605
35758
|
}
|
|
@@ -35621,13 +35774,13 @@ var DevServer = class _DevServer {
|
|
|
35621
35774
|
if (!sourceDir) {
|
|
35622
35775
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
35623
35776
|
}
|
|
35624
|
-
if (!
|
|
35625
|
-
|
|
35626
|
-
|
|
35777
|
+
if (!fs16.existsSync(desiredDir)) {
|
|
35778
|
+
fs16.mkdirSync(path27.dirname(desiredDir), { recursive: true });
|
|
35779
|
+
fs16.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
35627
35780
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
35628
35781
|
}
|
|
35629
35782
|
const providerJson = path27.join(desiredDir, "provider.json");
|
|
35630
|
-
if (!
|
|
35783
|
+
if (!fs16.existsSync(providerJson)) {
|
|
35631
35784
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
35632
35785
|
}
|
|
35633
35786
|
return { dir: desiredDir };
|
|
@@ -35670,10 +35823,10 @@ var DevServer = class _DevServer {
|
|
|
35670
35823
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
35671
35824
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
35672
35825
|
lines.push("");
|
|
35673
|
-
for (const file of
|
|
35826
|
+
for (const file of fs16.readdirSync(latestScriptsDir)) {
|
|
35674
35827
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
35675
35828
|
try {
|
|
35676
|
-
const content =
|
|
35829
|
+
const content = fs16.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
35677
35830
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
35678
35831
|
lines.push("```javascript");
|
|
35679
35832
|
lines.push(content);
|
|
@@ -35683,14 +35836,14 @@ var DevServer = class _DevServer {
|
|
|
35683
35836
|
}
|
|
35684
35837
|
}
|
|
35685
35838
|
}
|
|
35686
|
-
const refFiles =
|
|
35839
|
+
const refFiles = fs16.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
35687
35840
|
if (refFiles.length > 0) {
|
|
35688
35841
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
35689
35842
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
35690
35843
|
lines.push("");
|
|
35691
35844
|
for (const file of refFiles) {
|
|
35692
35845
|
try {
|
|
35693
|
-
const content =
|
|
35846
|
+
const content = fs16.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
35694
35847
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
35695
35848
|
lines.push("```javascript");
|
|
35696
35849
|
lines.push(content);
|
|
@@ -35735,7 +35888,7 @@ var DevServer = class _DevServer {
|
|
|
35735
35888
|
const loadGuide = (name) => {
|
|
35736
35889
|
try {
|
|
35737
35890
|
const p = path27.join(docsDir, name);
|
|
35738
|
-
if (
|
|
35891
|
+
if (fs16.existsSync(p)) return fs16.readFileSync(p, "utf-8");
|
|
35739
35892
|
} catch {
|
|
35740
35893
|
}
|
|
35741
35894
|
return null;
|
|
@@ -35916,11 +36069,11 @@ var DevServer = class _DevServer {
|
|
|
35916
36069
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
35917
36070
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
35918
36071
|
lines.push("");
|
|
35919
|
-
for (const file of
|
|
36072
|
+
for (const file of fs16.readdirSync(latestScriptsDir)) {
|
|
35920
36073
|
if (!file.endsWith(".js")) continue;
|
|
35921
36074
|
if (!targetFileNames.has(file)) continue;
|
|
35922
36075
|
try {
|
|
35923
|
-
const content =
|
|
36076
|
+
const content = fs16.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
35924
36077
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
35925
36078
|
lines.push("```javascript");
|
|
35926
36079
|
lines.push(content);
|
|
@@ -35929,14 +36082,14 @@ var DevServer = class _DevServer {
|
|
|
35929
36082
|
} catch {
|
|
35930
36083
|
}
|
|
35931
36084
|
}
|
|
35932
|
-
const refFiles =
|
|
36085
|
+
const refFiles = fs16.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
35933
36086
|
if (refFiles.length > 0) {
|
|
35934
36087
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
35935
36088
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
35936
36089
|
lines.push("");
|
|
35937
36090
|
for (const file of refFiles) {
|
|
35938
36091
|
try {
|
|
35939
|
-
const content =
|
|
36092
|
+
const content = fs16.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
35940
36093
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
35941
36094
|
lines.push("```javascript");
|
|
35942
36095
|
lines.push(content);
|
|
@@ -35973,7 +36126,7 @@ var DevServer = class _DevServer {
|
|
|
35973
36126
|
const loadGuide = (name) => {
|
|
35974
36127
|
try {
|
|
35975
36128
|
const p = path27.join(docsDir, name);
|
|
35976
|
-
if (
|
|
36129
|
+
if (fs16.existsSync(p)) return fs16.readFileSync(p, "utf-8");
|
|
35977
36130
|
} catch {
|
|
35978
36131
|
}
|
|
35979
36132
|
return null;
|
|
@@ -36755,7 +36908,8 @@ function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
|
|
|
36755
36908
|
}
|
|
36756
36909
|
|
|
36757
36910
|
// src/installer.ts
|
|
36758
|
-
import {
|
|
36911
|
+
import { exec as exec6 } from "child_process";
|
|
36912
|
+
import { promisify as promisify5 } from "util";
|
|
36759
36913
|
var EXTENSION_CATALOG = [
|
|
36760
36914
|
// AI Agent extensions
|
|
36761
36915
|
{
|
|
@@ -36842,15 +36996,15 @@ var EXTENSION_CATALOG = [
|
|
|
36842
36996
|
apiKeyName: "OpenAI/Anthropic API key"
|
|
36843
36997
|
}
|
|
36844
36998
|
];
|
|
36845
|
-
|
|
36999
|
+
var execAsync4 = promisify5(exec6);
|
|
37000
|
+
async function isExtensionInstalled(ide, marketplaceId) {
|
|
36846
37001
|
if (!ide.cliCommand) return false;
|
|
36847
37002
|
try {
|
|
36848
|
-
const
|
|
37003
|
+
const { stdout } = await execAsync4(`"${ide.cliCommand}" --list-extensions`, {
|
|
36849
37004
|
encoding: "utf-8",
|
|
36850
|
-
timeout: 15e3
|
|
36851
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
37005
|
+
timeout: 15e3
|
|
36852
37006
|
});
|
|
36853
|
-
const installed =
|
|
37007
|
+
const installed = stdout.trim().split("\n").map((e) => e.trim().toLowerCase());
|
|
36854
37008
|
return installed.includes(marketplaceId.toLowerCase());
|
|
36855
37009
|
} catch {
|
|
36856
37010
|
return false;
|
|
@@ -36866,7 +37020,7 @@ async function installExtension(ide, extension) {
|
|
|
36866
37020
|
error: `No CLI command found for ${ide.displayName}. Please install it manually.`
|
|
36867
37021
|
};
|
|
36868
37022
|
}
|
|
36869
|
-
const alreadyInstalled = isExtensionInstalled(ide, extension.marketplaceId);
|
|
37023
|
+
const alreadyInstalled = await isExtensionInstalled(ide, extension.marketplaceId);
|
|
36870
37024
|
if (alreadyInstalled) {
|
|
36871
37025
|
return {
|
|
36872
37026
|
extensionId: extension.id,
|
|
@@ -36882,11 +37036,11 @@ async function installExtension(ide, extension) {
|
|
|
36882
37036
|
const res = await fetch(extension.vsixUrl);
|
|
36883
37037
|
if (res.ok) {
|
|
36884
37038
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
36885
|
-
const
|
|
36886
|
-
|
|
37039
|
+
const fs17 = await import("fs");
|
|
37040
|
+
fs17.writeFileSync(vsixPath, buffer);
|
|
36887
37041
|
return new Promise((resolve16) => {
|
|
36888
37042
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
36889
|
-
|
|
37043
|
+
exec6(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
36890
37044
|
resolve16({
|
|
36891
37045
|
extensionId: extension.id,
|
|
36892
37046
|
marketplaceId: extension.marketplaceId,
|
|
@@ -36902,7 +37056,7 @@ async function installExtension(ide, extension) {
|
|
|
36902
37056
|
}
|
|
36903
37057
|
return new Promise((resolve16) => {
|
|
36904
37058
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
36905
|
-
|
|
37059
|
+
exec6(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
|
|
36906
37060
|
if (error) {
|
|
36907
37061
|
resolve16({
|
|
36908
37062
|
extensionId: extension.id,
|
|
@@ -36939,7 +37093,7 @@ function launchIDE(ide, workspacePath) {
|
|
|
36939
37093
|
if (!ide.cliCommand) return false;
|
|
36940
37094
|
try {
|
|
36941
37095
|
const args = workspacePath ? `"${workspacePath}"` : "";
|
|
36942
|
-
|
|
37096
|
+
exec6(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
|
|
36943
37097
|
return true;
|
|
36944
37098
|
} catch {
|
|
36945
37099
|
return false;
|
|
@@ -37374,6 +37528,7 @@ export {
|
|
|
37374
37528
|
getLogLevel,
|
|
37375
37529
|
getMesh,
|
|
37376
37530
|
getMeshByRepo,
|
|
37531
|
+
getMeshQueueRevision,
|
|
37377
37532
|
getMeshQueueStats,
|
|
37378
37533
|
getNpmExecOptions,
|
|
37379
37534
|
getPendingMeshCoordinatorEvents,
|