@adhdev/daemon-core 0.9.82-rc.332 → 0.9.82-rc.334
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/commands/router.d.ts +10 -0
- package/dist/index.js +709 -589
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +698 -578
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-runtime-store.d.ts +18 -1
- package/dist/mesh/mesh-work-queue.d.ts +1 -0
- package/dist/mesh/refine-config.d.ts +1 -0
- package/dist/system/load-better-sqlite3.d.ts +21 -0
- package/package.json +2 -2
- package/src/commands/router.ts +65 -10
- package/src/mesh/mesh-events-coordinator.ts +4 -0
- package/src/mesh/mesh-runtime-store.ts +61 -13
- package/src/mesh/mesh-work-queue.ts +18 -4
- package/src/mesh/refine-config.ts +23 -3
- package/src/mesh/worktree-bootstrap-config.ts +6 -1
- package/src/providers/native-history/hermes-cli-transcript.ts +2 -2
- package/src/providers/spec/native-history-executor.ts +2 -2
- package/src/system/load-better-sqlite3.ts +68 -0
package/dist/index.js
CHANGED
|
@@ -316,10 +316,10 @@ function readInjected(value) {
|
|
|
316
316
|
}
|
|
317
317
|
function getDaemonBuildInfo() {
|
|
318
318
|
if (cached) return cached;
|
|
319
|
-
const commit = readInjected(true ? "
|
|
320
|
-
const commitShort = readInjected(true ? "
|
|
321
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
322
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
319
|
+
const commit = readInjected(true ? "9e5ae5d2814077a6bf9e982b17066ca2051da97b" : void 0) ?? "unknown";
|
|
320
|
+
const commitShort = readInjected(true ? "9e5ae5d2" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
321
|
+
const version = readInjected(true ? "0.9.82-rc.334" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
322
|
+
const builtAt = readInjected(true ? "2026-06-20T03:55:49.426Z" : void 0);
|
|
323
323
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
324
324
|
return cached;
|
|
325
325
|
}
|
|
@@ -587,10 +587,10 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
587
587
|
} catch (error) {
|
|
588
588
|
const gitError = error instanceof GitCommandError ? error : new GitCommandError("git_command_failed", "Failed to read Git status", { cause: error });
|
|
589
589
|
if (isTransientGitFailure(gitError)) {
|
|
590
|
-
const
|
|
591
|
-
if (
|
|
590
|
+
const cached3 = lastKnownGoodStatus.get(workspace);
|
|
591
|
+
if (cached3) {
|
|
592
592
|
return {
|
|
593
|
-
...
|
|
593
|
+
...cached3,
|
|
594
594
|
lastCheckedAt,
|
|
595
595
|
upstreamStatus: "unavailable",
|
|
596
596
|
error: gitError.stderr || gitError.message,
|
|
@@ -713,9 +713,9 @@ function resolveChangeImpactConfigForRepo(repoRoot, options) {
|
|
|
713
713
|
return { config: null, sourceKey: "no-repo-root" };
|
|
714
714
|
}
|
|
715
715
|
const loaded = loadChangeImpactConfig(repoRoot);
|
|
716
|
-
const
|
|
717
|
-
if (
|
|
718
|
-
return { config:
|
|
716
|
+
const cached3 = changeImpactConfigCache.get(repoRoot);
|
|
717
|
+
if (cached3 && cached3.sourceKey === loaded.sourceKey) {
|
|
718
|
+
return { config: cached3.config, sourceKey: loaded.sourceKey };
|
|
719
719
|
}
|
|
720
720
|
const config = loaded.sourceType === "repo_file" ? loaded.config ?? null : null;
|
|
721
721
|
changeImpactConfigCache.set(repoRoot, { sourceKey: loaded.sourceKey, config });
|
|
@@ -2541,6 +2541,47 @@ Follow these recovery rules:
|
|
|
2541
2541
|
}
|
|
2542
2542
|
});
|
|
2543
2543
|
|
|
2544
|
+
// src/system/load-better-sqlite3.ts
|
|
2545
|
+
function loadBetterSqlite3() {
|
|
2546
|
+
if (cached2) return cached2;
|
|
2547
|
+
const errors = [];
|
|
2548
|
+
if (typeof require === "function") {
|
|
2549
|
+
try {
|
|
2550
|
+
cached2 = require("better-sqlite3");
|
|
2551
|
+
return cached2;
|
|
2552
|
+
} catch (e) {
|
|
2553
|
+
errors.push(e);
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
try {
|
|
2557
|
+
const metaUrl = typeof import_meta?.url === "string" ? import_meta.url : void 0;
|
|
2558
|
+
if (metaUrl) {
|
|
2559
|
+
cached2 = (0, import_module.createRequire)(metaUrl)("better-sqlite3");
|
|
2560
|
+
return cached2;
|
|
2561
|
+
}
|
|
2562
|
+
} catch (e) {
|
|
2563
|
+
errors.push(e);
|
|
2564
|
+
}
|
|
2565
|
+
try {
|
|
2566
|
+
cached2 = (0, import_module.createRequire)(`${process.cwd()}/__adhdev_better_sqlite3_loader__.js`)(
|
|
2567
|
+
"better-sqlite3"
|
|
2568
|
+
);
|
|
2569
|
+
return cached2;
|
|
2570
|
+
} catch (e) {
|
|
2571
|
+
errors.push(e);
|
|
2572
|
+
}
|
|
2573
|
+
const detail = errors.map((e) => e instanceof Error ? e.message : String(e)).join("; ");
|
|
2574
|
+
throw new Error(`Failed to load better-sqlite3: ${detail}`);
|
|
2575
|
+
}
|
|
2576
|
+
var import_module, import_meta, cached2;
|
|
2577
|
+
var init_load_better_sqlite3 = __esm({
|
|
2578
|
+
"src/system/load-better-sqlite3.ts"() {
|
|
2579
|
+
"use strict";
|
|
2580
|
+
import_module = require("module");
|
|
2581
|
+
import_meta = {};
|
|
2582
|
+
}
|
|
2583
|
+
});
|
|
2584
|
+
|
|
2544
2585
|
// src/mesh/mesh-ledger.ts
|
|
2545
2586
|
var mesh_ledger_exports = {};
|
|
2546
2587
|
__export(mesh_ledger_exports, {
|
|
@@ -2970,8 +3011,8 @@ function readLedgerFromStore(meshId) {
|
|
|
2970
3011
|
}
|
|
2971
3012
|
function getCachedRawEntries(meshId) {
|
|
2972
3013
|
const now = Date.now();
|
|
2973
|
-
const
|
|
2974
|
-
if (
|
|
3014
|
+
const cached3 = ledgerReadCache.get(meshId);
|
|
3015
|
+
if (cached3 && now - cached3.cachedAt < LEDGER_CACHE_TTL_MS) return cached3.entries;
|
|
2975
3016
|
let entries;
|
|
2976
3017
|
try {
|
|
2977
3018
|
entries = readLedgerFromStore(meshId);
|
|
@@ -3219,6 +3260,297 @@ var init_mesh_ledger = __esm({
|
|
|
3219
3260
|
}
|
|
3220
3261
|
});
|
|
3221
3262
|
|
|
3263
|
+
// src/logging/async-batch-writer.ts
|
|
3264
|
+
var fs3, AsyncBatchWriter;
|
|
3265
|
+
var init_async_batch_writer = __esm({
|
|
3266
|
+
"src/logging/async-batch-writer.ts"() {
|
|
3267
|
+
"use strict";
|
|
3268
|
+
fs3 = __toESM(require("fs"));
|
|
3269
|
+
AsyncBatchWriter = class {
|
|
3270
|
+
// Maps filePath -> string buffer
|
|
3271
|
+
static buffers = /* @__PURE__ */ new Map();
|
|
3272
|
+
static writePromises = /* @__PURE__ */ new Map();
|
|
3273
|
+
static flushTimer = null;
|
|
3274
|
+
/**
|
|
3275
|
+
* Queues data to be written to a file asynchronously in a batch.
|
|
3276
|
+
*/
|
|
3277
|
+
static write(filePath, data) {
|
|
3278
|
+
let buf = this.buffers.get(filePath);
|
|
3279
|
+
if (!buf) {
|
|
3280
|
+
buf = [];
|
|
3281
|
+
this.buffers.set(filePath, buf);
|
|
3282
|
+
}
|
|
3283
|
+
buf.push(data);
|
|
3284
|
+
if (!this.flushTimer) {
|
|
3285
|
+
this.flushTimer = setTimeout(() => {
|
|
3286
|
+
this.flushTimer = null;
|
|
3287
|
+
this.flushAll();
|
|
3288
|
+
}, 50);
|
|
3289
|
+
}
|
|
3290
|
+
}
|
|
3291
|
+
static async flushAll() {
|
|
3292
|
+
const entries = Array.from(this.buffers.entries());
|
|
3293
|
+
this.buffers.clear();
|
|
3294
|
+
for (const [filePath, buffer] of entries) {
|
|
3295
|
+
const dataToWrite = buffer.join("");
|
|
3296
|
+
const doWrite = async () => {
|
|
3297
|
+
try {
|
|
3298
|
+
const prevPromise = this.writePromises.get(filePath);
|
|
3299
|
+
if (prevPromise) await prevPromise;
|
|
3300
|
+
await fs3.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
|
|
3301
|
+
} catch {
|
|
3302
|
+
}
|
|
3303
|
+
};
|
|
3304
|
+
const writePromise = doWrite();
|
|
3305
|
+
this.writePromises.set(filePath, writePromise);
|
|
3306
|
+
writePromise.finally(() => {
|
|
3307
|
+
if (this.writePromises.get(filePath) === writePromise) {
|
|
3308
|
+
this.writePromises.delete(filePath);
|
|
3309
|
+
}
|
|
3310
|
+
});
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
3313
|
+
};
|
|
3314
|
+
}
|
|
3315
|
+
});
|
|
3316
|
+
|
|
3317
|
+
// src/logging/logger.ts
|
|
3318
|
+
var logger_exports = {};
|
|
3319
|
+
__export(logger_exports, {
|
|
3320
|
+
LOG: () => LOG,
|
|
3321
|
+
LOG_DIR_PATH: () => LOG_DIR_PATH,
|
|
3322
|
+
LOG_PATH: () => LOG_PATH,
|
|
3323
|
+
daemonLog: () => daemonLog,
|
|
3324
|
+
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
3325
|
+
getDaemonLogDir: () => getDaemonLogDir,
|
|
3326
|
+
getLogBufferSize: () => getLogBufferSize,
|
|
3327
|
+
getLogLevel: () => getLogLevel,
|
|
3328
|
+
getLogPath: () => getLogPath,
|
|
3329
|
+
getRecentLogs: () => getRecentLogs,
|
|
3330
|
+
installGlobalInterceptor: () => installGlobalInterceptor,
|
|
3331
|
+
setLogLevel: () => setLogLevel
|
|
3332
|
+
});
|
|
3333
|
+
function setLogLevel(level) {
|
|
3334
|
+
currentLevel = level;
|
|
3335
|
+
daemonLog("Logger", `Log level set to: ${level}`, "info");
|
|
3336
|
+
}
|
|
3337
|
+
function getLogLevel() {
|
|
3338
|
+
return currentLevel;
|
|
3339
|
+
}
|
|
3340
|
+
function getDateStr() {
|
|
3341
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3342
|
+
}
|
|
3343
|
+
function getDaemonLogDir() {
|
|
3344
|
+
return LOG_DIR;
|
|
3345
|
+
}
|
|
3346
|
+
function getCurrentDaemonLogPath(date = /* @__PURE__ */ new Date()) {
|
|
3347
|
+
return path9.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
|
|
3348
|
+
}
|
|
3349
|
+
function checkDateRotation() {
|
|
3350
|
+
const today = getDateStr();
|
|
3351
|
+
if (today !== currentDate) {
|
|
3352
|
+
currentDate = today;
|
|
3353
|
+
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
3354
|
+
cleanOldLogs();
|
|
3355
|
+
}
|
|
3356
|
+
}
|
|
3357
|
+
function cleanOldLogs() {
|
|
3358
|
+
try {
|
|
3359
|
+
const files = fs4.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
|
|
3360
|
+
const cutoff = /* @__PURE__ */ new Date();
|
|
3361
|
+
cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
|
|
3362
|
+
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
3363
|
+
for (const file of files) {
|
|
3364
|
+
const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
3365
|
+
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
3366
|
+
try {
|
|
3367
|
+
fs4.unlinkSync(path9.join(LOG_DIR, file));
|
|
3368
|
+
} catch {
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
} catch {
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
function rotateSizeIfNeeded() {
|
|
3376
|
+
try {
|
|
3377
|
+
const stat2 = fs4.statSync(currentLogFile);
|
|
3378
|
+
if (stat2.size > MAX_LOG_SIZE) {
|
|
3379
|
+
const backup = currentLogFile.replace(".log", ".1.log");
|
|
3380
|
+
try {
|
|
3381
|
+
fs4.unlinkSync(backup);
|
|
3382
|
+
} catch {
|
|
3383
|
+
}
|
|
3384
|
+
fs4.renameSync(currentLogFile, backup);
|
|
3385
|
+
}
|
|
3386
|
+
} catch {
|
|
3387
|
+
}
|
|
3388
|
+
}
|
|
3389
|
+
function writeToFile(line) {
|
|
3390
|
+
try {
|
|
3391
|
+
if (++writeCount % 1e3 === 0) {
|
|
3392
|
+
checkDateRotation();
|
|
3393
|
+
rotateSizeIfNeeded();
|
|
3394
|
+
}
|
|
3395
|
+
AsyncBatchWriter.write(currentLogFile, line + "\n");
|
|
3396
|
+
} catch {
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
function getRecentLogs(count = 50, minLevel = "info") {
|
|
3400
|
+
const minNum = LEVEL_NUM[minLevel];
|
|
3401
|
+
const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
|
|
3402
|
+
return filtered.slice(-count);
|
|
3403
|
+
}
|
|
3404
|
+
function getLogBufferSize() {
|
|
3405
|
+
return ringBuffer.length;
|
|
3406
|
+
}
|
|
3407
|
+
function ts() {
|
|
3408
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
3409
|
+
}
|
|
3410
|
+
function fullTs() {
|
|
3411
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3412
|
+
}
|
|
3413
|
+
function daemonLog(category, msg, level = "info") {
|
|
3414
|
+
const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
|
|
3415
|
+
const label = LEVEL_LABEL[level];
|
|
3416
|
+
const line = `[${ts()}] [${label}] [${category}] ${msg}`;
|
|
3417
|
+
if (!shouldOutput) return;
|
|
3418
|
+
writeToFile(line);
|
|
3419
|
+
ringBuffer.push({ ts: Date.now(), level, category, message: msg });
|
|
3420
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3421
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3422
|
+
}
|
|
3423
|
+
origConsoleLog(line);
|
|
3424
|
+
}
|
|
3425
|
+
function installGlobalInterceptor() {
|
|
3426
|
+
if (interceptorInstalled) return;
|
|
3427
|
+
interceptorInstalled = true;
|
|
3428
|
+
const stripAnsi4 = (str) => str.replace(/\x1B\[[0-9;]*m/g, "");
|
|
3429
|
+
const isDaemonLogLine = (msg) => /\[(DBG|INF|WRN|ERR)\]/.test(msg);
|
|
3430
|
+
console.log = (...args) => {
|
|
3431
|
+
origConsoleLog(...args);
|
|
3432
|
+
try {
|
|
3433
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
3434
|
+
const clean = stripAnsi4(msg);
|
|
3435
|
+
if (isDaemonLogLine(clean)) return;
|
|
3436
|
+
const line = clean.startsWith("[20") ? clean : `[${fullTs()}] ${clean}`;
|
|
3437
|
+
writeToFile(line);
|
|
3438
|
+
const catMatch = clean.match(/\[([^\]]+)\]/);
|
|
3439
|
+
ringBuffer.push({
|
|
3440
|
+
ts: Date.now(),
|
|
3441
|
+
level: "info",
|
|
3442
|
+
category: catMatch?.[1] || "System",
|
|
3443
|
+
message: clean
|
|
3444
|
+
});
|
|
3445
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3446
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3447
|
+
}
|
|
3448
|
+
} catch {
|
|
3449
|
+
}
|
|
3450
|
+
};
|
|
3451
|
+
console.error = (...args) => {
|
|
3452
|
+
origConsoleError(...args);
|
|
3453
|
+
try {
|
|
3454
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
3455
|
+
const clean = stripAnsi4(msg);
|
|
3456
|
+
if (isDaemonLogLine(clean)) return;
|
|
3457
|
+
const line = `[${fullTs()}] [ERROR] ${clean}`;
|
|
3458
|
+
writeToFile(line);
|
|
3459
|
+
ringBuffer.push({ ts: Date.now(), level: "error", category: "System", message: clean });
|
|
3460
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3461
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3462
|
+
}
|
|
3463
|
+
} catch {
|
|
3464
|
+
}
|
|
3465
|
+
};
|
|
3466
|
+
console.warn = (...args) => {
|
|
3467
|
+
origConsoleWarn(...args);
|
|
3468
|
+
try {
|
|
3469
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
3470
|
+
const clean = stripAnsi4(msg);
|
|
3471
|
+
if (isDaemonLogLine(clean)) return;
|
|
3472
|
+
const line = `[${fullTs()}] [WARN] ${clean}`;
|
|
3473
|
+
writeToFile(line);
|
|
3474
|
+
ringBuffer.push({ ts: Date.now(), level: "warn", category: "System", message: clean });
|
|
3475
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3476
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3477
|
+
}
|
|
3478
|
+
} catch {
|
|
3479
|
+
}
|
|
3480
|
+
};
|
|
3481
|
+
writeToFile(`
|
|
3482
|
+
=== ADHDev Daemon started at ${fullTs()} ===`);
|
|
3483
|
+
writeToFile(`Log file: ${currentLogFile}`);
|
|
3484
|
+
writeToFile(`Log level: ${currentLevel}`);
|
|
3485
|
+
}
|
|
3486
|
+
function getLogPath() {
|
|
3487
|
+
return currentLogFile;
|
|
3488
|
+
}
|
|
3489
|
+
var fs4, path9, os3, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, LOG_DIR_PATH;
|
|
3490
|
+
var init_logger = __esm({
|
|
3491
|
+
"src/logging/logger.ts"() {
|
|
3492
|
+
"use strict";
|
|
3493
|
+
fs4 = __toESM(require("fs"));
|
|
3494
|
+
path9 = __toESM(require("path"));
|
|
3495
|
+
os3 = __toESM(require("os"));
|
|
3496
|
+
init_async_batch_writer();
|
|
3497
|
+
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
3498
|
+
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
3499
|
+
currentLevel = "info";
|
|
3500
|
+
LOG_DIR = process.platform === "win32" ? path9.join(process.env.LOCALAPPDATA || process.env.APPDATA || path9.join(os3.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path9.join(os3.homedir(), "Library", "Logs", "adhdev") : path9.join(os3.homedir(), ".local", "share", "adhdev", "logs");
|
|
3501
|
+
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
3502
|
+
MAX_LOG_DAYS = 7;
|
|
3503
|
+
try {
|
|
3504
|
+
fs4.mkdirSync(LOG_DIR, { recursive: true });
|
|
3505
|
+
} catch {
|
|
3506
|
+
}
|
|
3507
|
+
currentDate = getDateStr();
|
|
3508
|
+
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
3509
|
+
cleanOldLogs();
|
|
3510
|
+
try {
|
|
3511
|
+
const oldLog = path9.join(LOG_DIR, "daemon.log");
|
|
3512
|
+
if (fs4.existsSync(oldLog)) {
|
|
3513
|
+
const stat2 = fs4.statSync(oldLog);
|
|
3514
|
+
const oldDate = stat2.mtime.toISOString().slice(0, 10);
|
|
3515
|
+
fs4.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
3516
|
+
}
|
|
3517
|
+
const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
|
|
3518
|
+
if (fs4.existsSync(oldLogBackup)) {
|
|
3519
|
+
fs4.unlinkSync(oldLogBackup);
|
|
3520
|
+
}
|
|
3521
|
+
} catch {
|
|
3522
|
+
}
|
|
3523
|
+
writeCount = 0;
|
|
3524
|
+
RING_BUFFER_SIZE = 200;
|
|
3525
|
+
ringBuffer = [];
|
|
3526
|
+
origConsoleLog = console.log.bind(console);
|
|
3527
|
+
origConsoleError = console.error.bind(console);
|
|
3528
|
+
origConsoleWarn = console.warn.bind(console);
|
|
3529
|
+
LOG = {
|
|
3530
|
+
debug: (category, msg) => daemonLog(category, msg, "debug"),
|
|
3531
|
+
info: (category, msg) => daemonLog(category, msg, "info"),
|
|
3532
|
+
warn: (category, msg) => daemonLog(category, msg, "warn"),
|
|
3533
|
+
error: (category, msg) => daemonLog(category, msg, "error"),
|
|
3534
|
+
/**
|
|
3535
|
+
* Create a scoped logger for a specific component.
|
|
3536
|
+
* Category is baked in so callers only pass the message.
|
|
3537
|
+
*/
|
|
3538
|
+
forComponent(category) {
|
|
3539
|
+
return {
|
|
3540
|
+
debug: (msg) => daemonLog(category, msg, "debug"),
|
|
3541
|
+
info: (msg) => daemonLog(category, msg, "info"),
|
|
3542
|
+
warn: (msg) => daemonLog(category, msg, "warn"),
|
|
3543
|
+
error: (msg) => daemonLog(category, msg, "error"),
|
|
3544
|
+
asLogFn: (level = "info") => (msg) => daemonLog(category, msg, level)
|
|
3545
|
+
};
|
|
3546
|
+
}
|
|
3547
|
+
};
|
|
3548
|
+
interceptorInstalled = false;
|
|
3549
|
+
LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
3550
|
+
LOG_DIR_PATH = LOG_DIR;
|
|
3551
|
+
}
|
|
3552
|
+
});
|
|
3553
|
+
|
|
3222
3554
|
// src/mesh/mesh-work-queue.ts
|
|
3223
3555
|
var mesh_work_queue_exports = {};
|
|
3224
3556
|
__export(mesh_work_queue_exports, {
|
|
@@ -3683,11 +4015,18 @@ function requeueTask(meshId, taskId, opts) {
|
|
|
3683
4015
|
}
|
|
3684
4016
|
function updateSessionTaskStatus(meshId, sessionId, status, opts) {
|
|
3685
4017
|
return withQueueLock(meshId, () => {
|
|
4018
|
+
const store = MeshRuntimeStore.getInstance();
|
|
3686
4019
|
const occurredAtIso = opts?.occurredAt ? new Date(opts.occurredAt).toISOString() : void 0;
|
|
3687
|
-
const entry =
|
|
3688
|
-
if (!entry)
|
|
4020
|
+
const entry = store.findAssignedBySession(meshId, sessionId, occurredAtIso, opts?.taskId);
|
|
4021
|
+
if (!entry) {
|
|
4022
|
+
const assignedRows = store.getActiveAssignmentDetails(meshId).filter((r) => r.sessionId === sessionId);
|
|
4023
|
+
if (assignedRows.length > 0) {
|
|
4024
|
+
LOG.warn("MeshQueue", `No assigned queue row matched completion for mesh ${meshId} session ${sessionId} (taskId=${opts?.taskId ?? "none"}, occurredAt=${occurredAtIso ?? "none"}); ${assignedRows.length} assigned row(s) exist: ${assignedRows.map((r) => r.id).join(",")}`);
|
|
4025
|
+
}
|
|
4026
|
+
return null;
|
|
4027
|
+
}
|
|
3689
4028
|
entry.status = status;
|
|
3690
|
-
|
|
4029
|
+
store.updateQueueEntry(entry);
|
|
3691
4030
|
if (DEPENDENCY_FAILURE_TERMINALS.has(status)) propagateDependencyFailure(meshId, entry.id);
|
|
3692
4031
|
return entry;
|
|
3693
4032
|
});
|
|
@@ -3796,6 +4135,7 @@ var init_mesh_work_queue = __esm({
|
|
|
3796
4135
|
init_repo_mesh_types();
|
|
3797
4136
|
init_mesh_runtime_store();
|
|
3798
4137
|
init_mesh_config();
|
|
4138
|
+
init_logger();
|
|
3799
4139
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
3800
4140
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
3801
4141
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -3854,8 +4194,7 @@ var init_mesh_work_queue = __esm({
|
|
|
3854
4194
|
// src/mesh/mesh-runtime-store.ts
|
|
3855
4195
|
function loadDatabaseCtor() {
|
|
3856
4196
|
if (DatabaseCtor) return DatabaseCtor;
|
|
3857
|
-
|
|
3858
|
-
DatabaseCtor = runtimeRequire("better-sqlite3");
|
|
4197
|
+
DatabaseCtor = loadBetterSqlite3();
|
|
3859
4198
|
return DatabaseCtor;
|
|
3860
4199
|
}
|
|
3861
4200
|
function safeMeshId(meshId) {
|
|
@@ -3882,16 +4221,15 @@ function meshRuntimeStorePath() {
|
|
|
3882
4221
|
}
|
|
3883
4222
|
return nextPath;
|
|
3884
4223
|
}
|
|
3885
|
-
var import_fs5, import_path5,
|
|
4224
|
+
var import_fs5, import_path5, DatabaseCtor, MeshRuntimeStore;
|
|
3886
4225
|
var init_mesh_runtime_store = __esm({
|
|
3887
4226
|
"src/mesh/mesh-runtime-store.ts"() {
|
|
3888
4227
|
"use strict";
|
|
3889
4228
|
import_fs5 = require("fs");
|
|
3890
4229
|
import_path5 = require("path");
|
|
3891
|
-
|
|
4230
|
+
init_load_better_sqlite3();
|
|
3892
4231
|
init_mesh_ledger();
|
|
3893
4232
|
init_mesh_work_queue();
|
|
3894
|
-
import_meta = {};
|
|
3895
4233
|
MeshRuntimeStore = class _MeshRuntimeStore {
|
|
3896
4234
|
static instance;
|
|
3897
4235
|
db;
|
|
@@ -4456,12 +4794,51 @@ var init_mesh_runtime_store = __esm({
|
|
|
4456
4794
|
return { id, nodeId: r.assigned_node_id ?? void 0, sessionId: r.assigned_session_id ?? void 0, message };
|
|
4457
4795
|
});
|
|
4458
4796
|
}
|
|
4459
|
-
|
|
4797
|
+
/**
|
|
4798
|
+
* Resolve the `assigned` queue row a completion event belongs to.
|
|
4799
|
+
*
|
|
4800
|
+
* Clock-skew safety (C2): a completion event's `occurredAtIso` carries the
|
|
4801
|
+
* REMOTE WORKER's clock, while `updated_at` carries the COORDINATOR's clock
|
|
4802
|
+
* (set at assignment and re-bumped on every mutation). For a remote node,
|
|
4803
|
+
* coordinator-clock > worker-clock skew used to make an `updated_at <= occurredAt`
|
|
4804
|
+
* filter return nothing, stranding the finished task as `assigned` forever.
|
|
4805
|
+
*
|
|
4806
|
+
* We therefore NEVER filter completion-matching on the mutable `updated_at`:
|
|
4807
|
+
* 1. If `taskId` is given, match the exact `assigned` row by id (no time filter).
|
|
4808
|
+
* 2. Otherwise a session holds at most one `assigned` task — match it without a
|
|
4809
|
+
* time filter. If several exist (shouldn't normally), disambiguate by the
|
|
4810
|
+
* IMMUTABLE `dispatchTimestamp`: latest `dispatchTimestamp <= occurredAt`,
|
|
4811
|
+
* and if skew makes ALL of them later than `occurredAt`, fall back to the
|
|
4812
|
+
* most-recent `dispatchTimestamp` rather than returning null.
|
|
4813
|
+
*/
|
|
4814
|
+
findAssignedBySession(meshId, sessionId, occurredAtIso, taskId) {
|
|
4460
4815
|
this.ensureLegacyQueueMigrated(meshId);
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4816
|
+
if (taskId) {
|
|
4817
|
+
const row = this.db.prepare(
|
|
4818
|
+
`SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned' AND id = ? LIMIT 1`
|
|
4819
|
+
).get(meshId, sessionId, taskId);
|
|
4820
|
+
if (row) return JSON.parse(row.payload);
|
|
4821
|
+
}
|
|
4822
|
+
const rows = this.db.prepare(
|
|
4823
|
+
`SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned'`
|
|
4824
|
+
).all(meshId, sessionId);
|
|
4825
|
+
if (rows.length === 0) return null;
|
|
4826
|
+
const entries = rows.map((r) => {
|
|
4827
|
+
try {
|
|
4828
|
+
return JSON.parse(r.payload);
|
|
4829
|
+
} catch {
|
|
4830
|
+
return null;
|
|
4831
|
+
}
|
|
4832
|
+
}).filter((e) => e !== null);
|
|
4833
|
+
if (entries.length === 0) return null;
|
|
4834
|
+
if (entries.length === 1) return entries[0];
|
|
4835
|
+
const orderKey = (e) => e.dispatchTimestamp ?? e.updatedAt ?? "";
|
|
4836
|
+
const byDispatchDesc = [...entries].sort((a, b) => orderKey(b).localeCompare(orderKey(a)));
|
|
4837
|
+
if (occurredAtIso) {
|
|
4838
|
+
const atOrBefore = byDispatchDesc.find((e) => orderKey(e) <= occurredAtIso);
|
|
4839
|
+
if (atOrBefore) return atOrBefore;
|
|
4840
|
+
}
|
|
4841
|
+
return byDispatchDesc[0];
|
|
4465
4842
|
}
|
|
4466
4843
|
toRow(entry) {
|
|
4467
4844
|
return {
|
|
@@ -5717,297 +6094,6 @@ var init_mesh_review_inbox = __esm({
|
|
|
5717
6094
|
}
|
|
5718
6095
|
});
|
|
5719
6096
|
|
|
5720
|
-
// src/logging/async-batch-writer.ts
|
|
5721
|
-
var fs3, AsyncBatchWriter;
|
|
5722
|
-
var init_async_batch_writer = __esm({
|
|
5723
|
-
"src/logging/async-batch-writer.ts"() {
|
|
5724
|
-
"use strict";
|
|
5725
|
-
fs3 = __toESM(require("fs"));
|
|
5726
|
-
AsyncBatchWriter = class {
|
|
5727
|
-
// Maps filePath -> string buffer
|
|
5728
|
-
static buffers = /* @__PURE__ */ new Map();
|
|
5729
|
-
static writePromises = /* @__PURE__ */ new Map();
|
|
5730
|
-
static flushTimer = null;
|
|
5731
|
-
/**
|
|
5732
|
-
* Queues data to be written to a file asynchronously in a batch.
|
|
5733
|
-
*/
|
|
5734
|
-
static write(filePath, data) {
|
|
5735
|
-
let buf = this.buffers.get(filePath);
|
|
5736
|
-
if (!buf) {
|
|
5737
|
-
buf = [];
|
|
5738
|
-
this.buffers.set(filePath, buf);
|
|
5739
|
-
}
|
|
5740
|
-
buf.push(data);
|
|
5741
|
-
if (!this.flushTimer) {
|
|
5742
|
-
this.flushTimer = setTimeout(() => {
|
|
5743
|
-
this.flushTimer = null;
|
|
5744
|
-
this.flushAll();
|
|
5745
|
-
}, 50);
|
|
5746
|
-
}
|
|
5747
|
-
}
|
|
5748
|
-
static async flushAll() {
|
|
5749
|
-
const entries = Array.from(this.buffers.entries());
|
|
5750
|
-
this.buffers.clear();
|
|
5751
|
-
for (const [filePath, buffer] of entries) {
|
|
5752
|
-
const dataToWrite = buffer.join("");
|
|
5753
|
-
const doWrite = async () => {
|
|
5754
|
-
try {
|
|
5755
|
-
const prevPromise = this.writePromises.get(filePath);
|
|
5756
|
-
if (prevPromise) await prevPromise;
|
|
5757
|
-
await fs3.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
|
|
5758
|
-
} catch {
|
|
5759
|
-
}
|
|
5760
|
-
};
|
|
5761
|
-
const writePromise = doWrite();
|
|
5762
|
-
this.writePromises.set(filePath, writePromise);
|
|
5763
|
-
writePromise.finally(() => {
|
|
5764
|
-
if (this.writePromises.get(filePath) === writePromise) {
|
|
5765
|
-
this.writePromises.delete(filePath);
|
|
5766
|
-
}
|
|
5767
|
-
});
|
|
5768
|
-
}
|
|
5769
|
-
}
|
|
5770
|
-
};
|
|
5771
|
-
}
|
|
5772
|
-
});
|
|
5773
|
-
|
|
5774
|
-
// src/logging/logger.ts
|
|
5775
|
-
var logger_exports = {};
|
|
5776
|
-
__export(logger_exports, {
|
|
5777
|
-
LOG: () => LOG,
|
|
5778
|
-
LOG_DIR_PATH: () => LOG_DIR_PATH,
|
|
5779
|
-
LOG_PATH: () => LOG_PATH,
|
|
5780
|
-
daemonLog: () => daemonLog,
|
|
5781
|
-
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
5782
|
-
getDaemonLogDir: () => getDaemonLogDir,
|
|
5783
|
-
getLogBufferSize: () => getLogBufferSize,
|
|
5784
|
-
getLogLevel: () => getLogLevel,
|
|
5785
|
-
getLogPath: () => getLogPath,
|
|
5786
|
-
getRecentLogs: () => getRecentLogs,
|
|
5787
|
-
installGlobalInterceptor: () => installGlobalInterceptor,
|
|
5788
|
-
setLogLevel: () => setLogLevel
|
|
5789
|
-
});
|
|
5790
|
-
function setLogLevel(level) {
|
|
5791
|
-
currentLevel = level;
|
|
5792
|
-
daemonLog("Logger", `Log level set to: ${level}`, "info");
|
|
5793
|
-
}
|
|
5794
|
-
function getLogLevel() {
|
|
5795
|
-
return currentLevel;
|
|
5796
|
-
}
|
|
5797
|
-
function getDateStr() {
|
|
5798
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5799
|
-
}
|
|
5800
|
-
function getDaemonLogDir() {
|
|
5801
|
-
return LOG_DIR;
|
|
5802
|
-
}
|
|
5803
|
-
function getCurrentDaemonLogPath(date = /* @__PURE__ */ new Date()) {
|
|
5804
|
-
return path9.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
|
|
5805
|
-
}
|
|
5806
|
-
function checkDateRotation() {
|
|
5807
|
-
const today = getDateStr();
|
|
5808
|
-
if (today !== currentDate) {
|
|
5809
|
-
currentDate = today;
|
|
5810
|
-
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
5811
|
-
cleanOldLogs();
|
|
5812
|
-
}
|
|
5813
|
-
}
|
|
5814
|
-
function cleanOldLogs() {
|
|
5815
|
-
try {
|
|
5816
|
-
const files = fs4.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
|
|
5817
|
-
const cutoff = /* @__PURE__ */ new Date();
|
|
5818
|
-
cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
|
|
5819
|
-
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
5820
|
-
for (const file of files) {
|
|
5821
|
-
const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
5822
|
-
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
5823
|
-
try {
|
|
5824
|
-
fs4.unlinkSync(path9.join(LOG_DIR, file));
|
|
5825
|
-
} catch {
|
|
5826
|
-
}
|
|
5827
|
-
}
|
|
5828
|
-
}
|
|
5829
|
-
} catch {
|
|
5830
|
-
}
|
|
5831
|
-
}
|
|
5832
|
-
function rotateSizeIfNeeded() {
|
|
5833
|
-
try {
|
|
5834
|
-
const stat2 = fs4.statSync(currentLogFile);
|
|
5835
|
-
if (stat2.size > MAX_LOG_SIZE) {
|
|
5836
|
-
const backup = currentLogFile.replace(".log", ".1.log");
|
|
5837
|
-
try {
|
|
5838
|
-
fs4.unlinkSync(backup);
|
|
5839
|
-
} catch {
|
|
5840
|
-
}
|
|
5841
|
-
fs4.renameSync(currentLogFile, backup);
|
|
5842
|
-
}
|
|
5843
|
-
} catch {
|
|
5844
|
-
}
|
|
5845
|
-
}
|
|
5846
|
-
function writeToFile(line) {
|
|
5847
|
-
try {
|
|
5848
|
-
if (++writeCount % 1e3 === 0) {
|
|
5849
|
-
checkDateRotation();
|
|
5850
|
-
rotateSizeIfNeeded();
|
|
5851
|
-
}
|
|
5852
|
-
AsyncBatchWriter.write(currentLogFile, line + "\n");
|
|
5853
|
-
} catch {
|
|
5854
|
-
}
|
|
5855
|
-
}
|
|
5856
|
-
function getRecentLogs(count = 50, minLevel = "info") {
|
|
5857
|
-
const minNum = LEVEL_NUM[minLevel];
|
|
5858
|
-
const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
|
|
5859
|
-
return filtered.slice(-count);
|
|
5860
|
-
}
|
|
5861
|
-
function getLogBufferSize() {
|
|
5862
|
-
return ringBuffer.length;
|
|
5863
|
-
}
|
|
5864
|
-
function ts() {
|
|
5865
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
5866
|
-
}
|
|
5867
|
-
function fullTs() {
|
|
5868
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
5869
|
-
}
|
|
5870
|
-
function daemonLog(category, msg, level = "info") {
|
|
5871
|
-
const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
|
|
5872
|
-
const label = LEVEL_LABEL[level];
|
|
5873
|
-
const line = `[${ts()}] [${label}] [${category}] ${msg}`;
|
|
5874
|
-
if (!shouldOutput) return;
|
|
5875
|
-
writeToFile(line);
|
|
5876
|
-
ringBuffer.push({ ts: Date.now(), level, category, message: msg });
|
|
5877
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5878
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5879
|
-
}
|
|
5880
|
-
origConsoleLog(line);
|
|
5881
|
-
}
|
|
5882
|
-
function installGlobalInterceptor() {
|
|
5883
|
-
if (interceptorInstalled) return;
|
|
5884
|
-
interceptorInstalled = true;
|
|
5885
|
-
const stripAnsi4 = (str) => str.replace(/\x1B\[[0-9;]*m/g, "");
|
|
5886
|
-
const isDaemonLogLine = (msg) => /\[(DBG|INF|WRN|ERR)\]/.test(msg);
|
|
5887
|
-
console.log = (...args) => {
|
|
5888
|
-
origConsoleLog(...args);
|
|
5889
|
-
try {
|
|
5890
|
-
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
5891
|
-
const clean = stripAnsi4(msg);
|
|
5892
|
-
if (isDaemonLogLine(clean)) return;
|
|
5893
|
-
const line = clean.startsWith("[20") ? clean : `[${fullTs()}] ${clean}`;
|
|
5894
|
-
writeToFile(line);
|
|
5895
|
-
const catMatch = clean.match(/\[([^\]]+)\]/);
|
|
5896
|
-
ringBuffer.push({
|
|
5897
|
-
ts: Date.now(),
|
|
5898
|
-
level: "info",
|
|
5899
|
-
category: catMatch?.[1] || "System",
|
|
5900
|
-
message: clean
|
|
5901
|
-
});
|
|
5902
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5903
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5904
|
-
}
|
|
5905
|
-
} catch {
|
|
5906
|
-
}
|
|
5907
|
-
};
|
|
5908
|
-
console.error = (...args) => {
|
|
5909
|
-
origConsoleError(...args);
|
|
5910
|
-
try {
|
|
5911
|
-
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
5912
|
-
const clean = stripAnsi4(msg);
|
|
5913
|
-
if (isDaemonLogLine(clean)) return;
|
|
5914
|
-
const line = `[${fullTs()}] [ERROR] ${clean}`;
|
|
5915
|
-
writeToFile(line);
|
|
5916
|
-
ringBuffer.push({ ts: Date.now(), level: "error", category: "System", message: clean });
|
|
5917
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5918
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5919
|
-
}
|
|
5920
|
-
} catch {
|
|
5921
|
-
}
|
|
5922
|
-
};
|
|
5923
|
-
console.warn = (...args) => {
|
|
5924
|
-
origConsoleWarn(...args);
|
|
5925
|
-
try {
|
|
5926
|
-
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
5927
|
-
const clean = stripAnsi4(msg);
|
|
5928
|
-
if (isDaemonLogLine(clean)) return;
|
|
5929
|
-
const line = `[${fullTs()}] [WARN] ${clean}`;
|
|
5930
|
-
writeToFile(line);
|
|
5931
|
-
ringBuffer.push({ ts: Date.now(), level: "warn", category: "System", message: clean });
|
|
5932
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5933
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5934
|
-
}
|
|
5935
|
-
} catch {
|
|
5936
|
-
}
|
|
5937
|
-
};
|
|
5938
|
-
writeToFile(`
|
|
5939
|
-
=== ADHDev Daemon started at ${fullTs()} ===`);
|
|
5940
|
-
writeToFile(`Log file: ${currentLogFile}`);
|
|
5941
|
-
writeToFile(`Log level: ${currentLevel}`);
|
|
5942
|
-
}
|
|
5943
|
-
function getLogPath() {
|
|
5944
|
-
return currentLogFile;
|
|
5945
|
-
}
|
|
5946
|
-
var fs4, path9, os3, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, LOG_DIR_PATH;
|
|
5947
|
-
var init_logger = __esm({
|
|
5948
|
-
"src/logging/logger.ts"() {
|
|
5949
|
-
"use strict";
|
|
5950
|
-
fs4 = __toESM(require("fs"));
|
|
5951
|
-
path9 = __toESM(require("path"));
|
|
5952
|
-
os3 = __toESM(require("os"));
|
|
5953
|
-
init_async_batch_writer();
|
|
5954
|
-
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
5955
|
-
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
5956
|
-
currentLevel = "info";
|
|
5957
|
-
LOG_DIR = process.platform === "win32" ? path9.join(process.env.LOCALAPPDATA || process.env.APPDATA || path9.join(os3.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path9.join(os3.homedir(), "Library", "Logs", "adhdev") : path9.join(os3.homedir(), ".local", "share", "adhdev", "logs");
|
|
5958
|
-
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
5959
|
-
MAX_LOG_DAYS = 7;
|
|
5960
|
-
try {
|
|
5961
|
-
fs4.mkdirSync(LOG_DIR, { recursive: true });
|
|
5962
|
-
} catch {
|
|
5963
|
-
}
|
|
5964
|
-
currentDate = getDateStr();
|
|
5965
|
-
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
5966
|
-
cleanOldLogs();
|
|
5967
|
-
try {
|
|
5968
|
-
const oldLog = path9.join(LOG_DIR, "daemon.log");
|
|
5969
|
-
if (fs4.existsSync(oldLog)) {
|
|
5970
|
-
const stat2 = fs4.statSync(oldLog);
|
|
5971
|
-
const oldDate = stat2.mtime.toISOString().slice(0, 10);
|
|
5972
|
-
fs4.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
5973
|
-
}
|
|
5974
|
-
const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
|
|
5975
|
-
if (fs4.existsSync(oldLogBackup)) {
|
|
5976
|
-
fs4.unlinkSync(oldLogBackup);
|
|
5977
|
-
}
|
|
5978
|
-
} catch {
|
|
5979
|
-
}
|
|
5980
|
-
writeCount = 0;
|
|
5981
|
-
RING_BUFFER_SIZE = 200;
|
|
5982
|
-
ringBuffer = [];
|
|
5983
|
-
origConsoleLog = console.log.bind(console);
|
|
5984
|
-
origConsoleError = console.error.bind(console);
|
|
5985
|
-
origConsoleWarn = console.warn.bind(console);
|
|
5986
|
-
LOG = {
|
|
5987
|
-
debug: (category, msg) => daemonLog(category, msg, "debug"),
|
|
5988
|
-
info: (category, msg) => daemonLog(category, msg, "info"),
|
|
5989
|
-
warn: (category, msg) => daemonLog(category, msg, "warn"),
|
|
5990
|
-
error: (category, msg) => daemonLog(category, msg, "error"),
|
|
5991
|
-
/**
|
|
5992
|
-
* Create a scoped logger for a specific component.
|
|
5993
|
-
* Category is baked in so callers only pass the message.
|
|
5994
|
-
*/
|
|
5995
|
-
forComponent(category) {
|
|
5996
|
-
return {
|
|
5997
|
-
debug: (msg) => daemonLog(category, msg, "debug"),
|
|
5998
|
-
info: (msg) => daemonLog(category, msg, "info"),
|
|
5999
|
-
warn: (msg) => daemonLog(category, msg, "warn"),
|
|
6000
|
-
error: (msg) => daemonLog(category, msg, "error"),
|
|
6001
|
-
asLogFn: (level = "info") => (msg) => daemonLog(category, msg, level)
|
|
6002
|
-
};
|
|
6003
|
-
}
|
|
6004
|
-
};
|
|
6005
|
-
interceptorInstalled = false;
|
|
6006
|
-
LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
6007
|
-
LOG_DIR_PATH = LOG_DIR;
|
|
6008
|
-
}
|
|
6009
|
-
});
|
|
6010
|
-
|
|
6011
6097
|
// src/commands/mesh-coordinator.ts
|
|
6012
6098
|
var mesh_coordinator_exports = {};
|
|
6013
6099
|
__export(mesh_coordinator_exports, {
|
|
@@ -6409,6 +6495,59 @@ var init_mesh_coordinator = __esm({
|
|
|
6409
6495
|
}
|
|
6410
6496
|
});
|
|
6411
6497
|
|
|
6498
|
+
// src/cli-adapters/resolve-executable.ts
|
|
6499
|
+
function resolveWin32GlobalBin(trimmed) {
|
|
6500
|
+
if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
|
|
6501
|
+
return null;
|
|
6502
|
+
}
|
|
6503
|
+
const extraDirs = [];
|
|
6504
|
+
if (process.env.APPDATA) extraDirs.push(path10.join(process.env.APPDATA, "npm"));
|
|
6505
|
+
try {
|
|
6506
|
+
extraDirs.push(path10.dirname(process.execPath));
|
|
6507
|
+
} catch {
|
|
6508
|
+
}
|
|
6509
|
+
for (const dir of extraDirs) {
|
|
6510
|
+
if (!dir) continue;
|
|
6511
|
+
for (const ext of WIN_EXEC_EXT) {
|
|
6512
|
+
const full = path10.join(dir, trimmed + ext);
|
|
6513
|
+
if ((0, import_fs8.existsSync)(full)) return full;
|
|
6514
|
+
}
|
|
6515
|
+
}
|
|
6516
|
+
return null;
|
|
6517
|
+
}
|
|
6518
|
+
function resolveWin32Executable(command) {
|
|
6519
|
+
if (process.platform !== "win32") return command;
|
|
6520
|
+
const trimmed = (command || "").trim();
|
|
6521
|
+
if (!trimmed) return command;
|
|
6522
|
+
if (path10.isAbsolute(trimmed) && (0, import_fs8.existsSync)(trimmed)) return trimmed;
|
|
6523
|
+
try {
|
|
6524
|
+
const out = (0, import_child_process.execFileSync)("where", [trimmed], {
|
|
6525
|
+
encoding: "utf8",
|
|
6526
|
+
windowsHide: true
|
|
6527
|
+
}).trim();
|
|
6528
|
+
if (out) {
|
|
6529
|
+
const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
6530
|
+
const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path10.extname(m).toLowerCase()));
|
|
6531
|
+
return direct || matches[0] || command;
|
|
6532
|
+
}
|
|
6533
|
+
} catch {
|
|
6534
|
+
}
|
|
6535
|
+
const globalBin = resolveWin32GlobalBin(trimmed);
|
|
6536
|
+
if (globalBin) return globalBin;
|
|
6537
|
+
return command;
|
|
6538
|
+
}
|
|
6539
|
+
var import_child_process, import_fs8, path10, DIRECT_EXEC_EXT, WIN_EXEC_EXT;
|
|
6540
|
+
var init_resolve_executable = __esm({
|
|
6541
|
+
"src/cli-adapters/resolve-executable.ts"() {
|
|
6542
|
+
"use strict";
|
|
6543
|
+
import_child_process = require("child_process");
|
|
6544
|
+
import_fs8 = require("fs");
|
|
6545
|
+
path10 = __toESM(require("path"));
|
|
6546
|
+
DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
|
|
6547
|
+
WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
|
|
6548
|
+
}
|
|
6549
|
+
});
|
|
6550
|
+
|
|
6412
6551
|
// src/mesh/mesh-fast-forward.ts
|
|
6413
6552
|
async function fastForwardMeshNode(args) {
|
|
6414
6553
|
const workspace = typeof args.workspace === "string" ? args.workspace.trim() : "";
|
|
@@ -7932,9 +8071,9 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
7932
8071
|
const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
7933
8072
|
const events = [];
|
|
7934
8073
|
for (const path42 of paths) {
|
|
7935
|
-
if (!(0,
|
|
8074
|
+
if (!(0, import_fs10.existsSync)(path42)) continue;
|
|
7936
8075
|
try {
|
|
7937
|
-
const raw = (0,
|
|
8076
|
+
const raw = (0, import_fs10.readFileSync)(path42, "utf-8");
|
|
7938
8077
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
7939
8078
|
try {
|
|
7940
8079
|
return [JSON.parse(line)];
|
|
@@ -8009,11 +8148,11 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
8009
8148
|
}
|
|
8010
8149
|
function trimPendingEventsIfNeeded(path42) {
|
|
8011
8150
|
try {
|
|
8012
|
-
if (!(0,
|
|
8013
|
-
if ((0,
|
|
8014
|
-
const lines = (0,
|
|
8151
|
+
if (!(0, import_fs10.existsSync)(path42)) return;
|
|
8152
|
+
if ((0, import_fs10.statSync)(path42).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
8153
|
+
const lines = (0, import_fs10.readFileSync)(path42, "utf-8").split("\n").filter(Boolean);
|
|
8015
8154
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
8016
|
-
(0,
|
|
8155
|
+
(0, import_fs10.writeFileSync)(path42, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
|
|
8017
8156
|
} catch {
|
|
8018
8157
|
}
|
|
8019
8158
|
}
|
|
@@ -8042,7 +8181,7 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
8042
8181
|
}
|
|
8043
8182
|
const path42 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
|
|
8044
8183
|
trimPendingEventsIfNeeded(path42);
|
|
8045
|
-
(0,
|
|
8184
|
+
(0, import_fs10.appendFileSync)(path42, JSON.stringify(event) + "\n", "utf-8");
|
|
8046
8185
|
return true;
|
|
8047
8186
|
} catch (e) {
|
|
8048
8187
|
LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
@@ -8052,20 +8191,20 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
8052
8191
|
function atomicDrainFile(path42) {
|
|
8053
8192
|
const tmpPath = `${path42}.draining`;
|
|
8054
8193
|
try {
|
|
8055
|
-
(0,
|
|
8194
|
+
(0, import_fs10.renameSync)(path42, tmpPath);
|
|
8056
8195
|
} catch {
|
|
8057
8196
|
return null;
|
|
8058
8197
|
}
|
|
8059
8198
|
try {
|
|
8060
|
-
const content = (0,
|
|
8199
|
+
const content = (0, import_fs10.readFileSync)(tmpPath, "utf-8");
|
|
8061
8200
|
try {
|
|
8062
|
-
(0,
|
|
8201
|
+
(0, import_fs10.unlinkSync)(tmpPath);
|
|
8063
8202
|
} catch {
|
|
8064
8203
|
}
|
|
8065
8204
|
return content;
|
|
8066
8205
|
} catch {
|
|
8067
8206
|
try {
|
|
8068
|
-
(0,
|
|
8207
|
+
(0, import_fs10.unlinkSync)(tmpPath);
|
|
8069
8208
|
} catch {
|
|
8070
8209
|
}
|
|
8071
8210
|
return null;
|
|
@@ -8074,16 +8213,16 @@ function atomicDrainFile(path42) {
|
|
|
8074
8213
|
function selectiveDrainFile(path42, predicate) {
|
|
8075
8214
|
const tmpPath = `${path42}.draining`;
|
|
8076
8215
|
try {
|
|
8077
|
-
(0,
|
|
8216
|
+
(0, import_fs10.renameSync)(path42, tmpPath);
|
|
8078
8217
|
} catch {
|
|
8079
8218
|
return [];
|
|
8080
8219
|
}
|
|
8081
8220
|
let content;
|
|
8082
8221
|
try {
|
|
8083
|
-
content = (0,
|
|
8222
|
+
content = (0, import_fs10.readFileSync)(tmpPath, "utf-8");
|
|
8084
8223
|
} catch {
|
|
8085
8224
|
try {
|
|
8086
|
-
(0,
|
|
8225
|
+
(0, import_fs10.unlinkSync)(tmpPath);
|
|
8087
8226
|
} catch {
|
|
8088
8227
|
}
|
|
8089
8228
|
return [];
|
|
@@ -8106,12 +8245,12 @@ function selectiveDrainFile(path42, predicate) {
|
|
|
8106
8245
|
}
|
|
8107
8246
|
try {
|
|
8108
8247
|
if (keptLines.length > 0) {
|
|
8109
|
-
(0,
|
|
8248
|
+
(0, import_fs10.writeFileSync)(path42, keptLines.join("\n") + "\n", "utf-8");
|
|
8110
8249
|
}
|
|
8111
|
-
(0,
|
|
8250
|
+
(0, import_fs10.unlinkSync)(tmpPath);
|
|
8112
8251
|
} catch {
|
|
8113
8252
|
try {
|
|
8114
|
-
if ((0,
|
|
8253
|
+
if ((0, import_fs10.existsSync)(tmpPath) && !(0, import_fs10.existsSync)(path42)) (0, import_fs10.renameSync)(tmpPath, path42);
|
|
8115
8254
|
} catch {
|
|
8116
8255
|
}
|
|
8117
8256
|
return [];
|
|
@@ -8205,17 +8344,17 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
8205
8344
|
}
|
|
8206
8345
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
8207
8346
|
for (const path42 of paths) {
|
|
8208
|
-
if ((0,
|
|
8209
|
-
(0,
|
|
8347
|
+
if ((0, import_fs10.existsSync)(path42)) try {
|
|
8348
|
+
(0, import_fs10.unlinkSync)(path42);
|
|
8210
8349
|
} catch {
|
|
8211
8350
|
}
|
|
8212
8351
|
}
|
|
8213
8352
|
}
|
|
8214
|
-
var
|
|
8353
|
+
var import_fs10, import_path9, import_crypto7, REFINE_TERMINAL_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
|
|
8215
8354
|
var init_mesh_events_pending = __esm({
|
|
8216
8355
|
"src/mesh/mesh-events-pending.ts"() {
|
|
8217
8356
|
"use strict";
|
|
8218
|
-
|
|
8357
|
+
import_fs10 = require("fs");
|
|
8219
8358
|
import_path9 = require("path");
|
|
8220
8359
|
import_crypto7 = require("crypto");
|
|
8221
8360
|
init_logger();
|
|
@@ -8710,24 +8849,24 @@ function buildCliScreenSnapshot(text) {
|
|
|
8710
8849
|
function findBinary(name) {
|
|
8711
8850
|
const trimmed = String(name || "").trim();
|
|
8712
8851
|
if (!trimmed) return trimmed;
|
|
8713
|
-
const expanded = trimmed.startsWith("~") ?
|
|
8714
|
-
if (
|
|
8715
|
-
return
|
|
8852
|
+
const expanded = trimmed.startsWith("~") ? path11.join(os5.homedir(), trimmed.slice(1)) : trimmed;
|
|
8853
|
+
if (path11.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
8854
|
+
return path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
|
|
8716
8855
|
}
|
|
8717
8856
|
const isWin = os5.platform() === "win32";
|
|
8718
|
-
const paths = (process.env.PATH || "").split(
|
|
8857
|
+
const paths = (process.env.PATH || "").split(path11.delimiter);
|
|
8719
8858
|
const extraDirs = [];
|
|
8720
8859
|
if (isWin) {
|
|
8721
|
-
if (process.env.APPDATA) extraDirs.push(
|
|
8860
|
+
if (process.env.APPDATA) extraDirs.push(path11.join(process.env.APPDATA, "npm"));
|
|
8722
8861
|
try {
|
|
8723
|
-
extraDirs.push(
|
|
8862
|
+
extraDirs.push(path11.dirname(process.execPath));
|
|
8724
8863
|
} catch {
|
|
8725
8864
|
}
|
|
8726
8865
|
} else {
|
|
8727
|
-
extraDirs.push(
|
|
8866
|
+
extraDirs.push(path11.join(os5.homedir(), ".npm-global", "bin"));
|
|
8728
8867
|
extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
|
|
8729
8868
|
try {
|
|
8730
|
-
extraDirs.push(
|
|
8869
|
+
extraDirs.push(path11.dirname(process.execPath));
|
|
8731
8870
|
} catch {
|
|
8732
8871
|
}
|
|
8733
8872
|
}
|
|
@@ -8736,7 +8875,7 @@ function findBinary(name) {
|
|
|
8736
8875
|
for (const p of searchDirs) {
|
|
8737
8876
|
if (!p) continue;
|
|
8738
8877
|
for (const ext of exes) {
|
|
8739
|
-
const fullPath =
|
|
8878
|
+
const fullPath = path11.join(p, trimmed + ext);
|
|
8740
8879
|
try {
|
|
8741
8880
|
const fs32 = require("fs");
|
|
8742
8881
|
if (fs32.existsSync(fullPath)) {
|
|
@@ -8752,7 +8891,7 @@ function findBinary(name) {
|
|
|
8752
8891
|
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
8753
8892
|
}
|
|
8754
8893
|
function isScriptBinary(binaryPath) {
|
|
8755
|
-
if (!
|
|
8894
|
+
if (!path11.isAbsolute(binaryPath)) return false;
|
|
8756
8895
|
try {
|
|
8757
8896
|
const fs32 = require("fs");
|
|
8758
8897
|
const resolved = fs32.realpathSync(binaryPath);
|
|
@@ -8768,7 +8907,7 @@ function isScriptBinary(binaryPath) {
|
|
|
8768
8907
|
}
|
|
8769
8908
|
}
|
|
8770
8909
|
function looksLikeMachOOrElf(filePath) {
|
|
8771
|
-
if (!
|
|
8910
|
+
if (!path11.isAbsolute(filePath)) return false;
|
|
8772
8911
|
try {
|
|
8773
8912
|
const fs32 = require("fs");
|
|
8774
8913
|
const resolved = fs32.realpathSync(filePath);
|
|
@@ -8857,12 +8996,12 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
8857
8996
|
}
|
|
8858
8997
|
};
|
|
8859
8998
|
}
|
|
8860
|
-
var os5,
|
|
8999
|
+
var os5, path11, TerminalTranscriptAccumulator, buildCliSpawnEnv;
|
|
8861
9000
|
var init_provider_cli_shared = __esm({
|
|
8862
9001
|
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
8863
9002
|
"use strict";
|
|
8864
9003
|
os5 = __toESM(require("os"));
|
|
8865
|
-
|
|
9004
|
+
path11 = __toESM(require("path"));
|
|
8866
9005
|
init_spawn_env();
|
|
8867
9006
|
TerminalTranscriptAccumulator = class {
|
|
8868
9007
|
lines = [[]];
|
|
@@ -9036,19 +9175,19 @@ function shellQuote(value) {
|
|
|
9036
9175
|
function expandHome(value) {
|
|
9037
9176
|
const trimmed = value.trim();
|
|
9038
9177
|
if (!trimmed.startsWith("~")) return trimmed;
|
|
9039
|
-
return
|
|
9178
|
+
return path12.join(os6.homedir(), trimmed.slice(1));
|
|
9040
9179
|
}
|
|
9041
9180
|
function isExplicitCommandPath(command) {
|
|
9042
9181
|
const trimmed = command.trim();
|
|
9043
|
-
return
|
|
9182
|
+
return path12.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
9044
9183
|
}
|
|
9045
9184
|
function resolveCommandPath(command) {
|
|
9046
9185
|
const trimmed = command.trim();
|
|
9047
9186
|
if (!trimmed) return null;
|
|
9048
9187
|
if (isExplicitCommandPath(trimmed)) {
|
|
9049
9188
|
const expanded = expandHome(trimmed);
|
|
9050
|
-
const candidate =
|
|
9051
|
-
return (0,
|
|
9189
|
+
const candidate = path12.isAbsolute(expanded) ? expanded : path12.resolve(expanded);
|
|
9190
|
+
return (0, import_fs11.existsSync)(candidate) ? candidate : null;
|
|
9052
9191
|
}
|
|
9053
9192
|
return null;
|
|
9054
9193
|
}
|
|
@@ -9058,12 +9197,12 @@ async function resolveDetectionPath(command, whichCmd) {
|
|
|
9058
9197
|
const whichResult = await execAsync(`${whichCmd} ${shellQuote(command)}`);
|
|
9059
9198
|
if (whichResult) return whichResult.split("\n")[0];
|
|
9060
9199
|
const resolved = findBinary(command);
|
|
9061
|
-
if (
|
|
9200
|
+
if (path12.isAbsolute(resolved) && (0, import_fs11.existsSync)(resolved)) return resolved;
|
|
9062
9201
|
return null;
|
|
9063
9202
|
}
|
|
9064
9203
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
9065
9204
|
return new Promise((resolve24) => {
|
|
9066
|
-
const child = (0,
|
|
9205
|
+
const child = (0, import_child_process2.exec)(cmd, {
|
|
9067
9206
|
encoding: "utf-8",
|
|
9068
9207
|
timeout: timeoutMs,
|
|
9069
9208
|
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
@@ -9153,14 +9292,14 @@ async function detectCLI(cliId, providerLoader, options) {
|
|
|
9153
9292
|
const all = await detectCLIs(providerLoader, options);
|
|
9154
9293
|
return all.find((c) => c.id === resolvedId && c.installed) || null;
|
|
9155
9294
|
}
|
|
9156
|
-
var
|
|
9295
|
+
var import_child_process2, os6, path12, import_fs11;
|
|
9157
9296
|
var init_cli_detector = __esm({
|
|
9158
9297
|
"src/detection/cli-detector.ts"() {
|
|
9159
9298
|
"use strict";
|
|
9160
|
-
|
|
9299
|
+
import_child_process2 = require("child_process");
|
|
9161
9300
|
os6 = __toESM(require("os"));
|
|
9162
|
-
|
|
9163
|
-
|
|
9301
|
+
path12 = __toESM(require("path"));
|
|
9302
|
+
import_fs11 = require("fs");
|
|
9164
9303
|
init_provider_cli_shared();
|
|
9165
9304
|
}
|
|
9166
9305
|
});
|
|
@@ -9418,8 +9557,8 @@ function resolveCoordinatorDrainDaemonIds(components) {
|
|
|
9418
9557
|
}
|
|
9419
9558
|
function getCachedMeshByWorkspace(workspace) {
|
|
9420
9559
|
const now = Date.now();
|
|
9421
|
-
const
|
|
9422
|
-
if (
|
|
9560
|
+
const cached3 = meshByWorkspaceCache.get(workspace);
|
|
9561
|
+
if (cached3 && now - cached3.cachedAt < MESH_WORKSPACE_CACHE_TTL_MS) return cached3.mesh;
|
|
9423
9562
|
const mesh = getMeshByRepo(workspace);
|
|
9424
9563
|
meshByWorkspaceCache.set(workspace, { mesh, cachedAt: now });
|
|
9425
9564
|
return mesh;
|
|
@@ -10195,7 +10334,7 @@ async function maybeAutoFastForwardIdleNode(components, args) {
|
|
|
10195
10334
|
const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
|
|
10196
10335
|
const workspace = readNonEmptyString2(node?.workspace);
|
|
10197
10336
|
if (!workspace) return;
|
|
10198
|
-
if (!(0,
|
|
10337
|
+
if (!(0, import_fs12.existsSync)(workspace)) return;
|
|
10199
10338
|
const policy = resolveAutoFastForwardPolicy(mesh);
|
|
10200
10339
|
if (!policy.enabled) return;
|
|
10201
10340
|
if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId, args.sessionId)) return;
|
|
@@ -10394,8 +10533,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
10394
10533
|
}
|
|
10395
10534
|
}
|
|
10396
10535
|
function markSessionTerminal(sessionId, outcome, occurredAtMs) {
|
|
10536
|
+
const eventTaskId = readNonEmptyString2(args.metadataEvent.taskId) || void 0;
|
|
10397
10537
|
const task = updateSessionTaskStatus(args.meshId, sessionId, outcome, {
|
|
10398
|
-
occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0
|
|
10538
|
+
occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0,
|
|
10539
|
+
taskId: eventTaskId
|
|
10399
10540
|
});
|
|
10400
10541
|
updateDirectDispatchStatus(args.meshId, sessionId, outcome);
|
|
10401
10542
|
markSessionDeliveriesTerminal(args.meshId, sessionId, outcome);
|
|
@@ -10806,11 +10947,11 @@ function setupMeshEventForwarding(components) {
|
|
|
10806
10947
|
});
|
|
10807
10948
|
});
|
|
10808
10949
|
}
|
|
10809
|
-
var
|
|
10950
|
+
var import_fs12, REMOTE_IDLE_SESSION_TTL_MS, meshByWorkspaceCache, MESH_WORKSPACE_CACHE_TTL_MS, IDLE_AUTO_FAST_FORWARD_THROTTLE_MS, idleAutoFastForwardLastAttempt, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS, AUTO_LAUNCH_AWAIT_CLAIM_MS, lastAutoLaunchLedgerKey, AUTO_LAUNCH_LEDGER_DEDUP_MAX, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, MESH_FORCE_INJECT_EVENTS;
|
|
10810
10951
|
var init_mesh_events_coordinator = __esm({
|
|
10811
10952
|
"src/mesh/mesh-events-coordinator.ts"() {
|
|
10812
10953
|
"use strict";
|
|
10813
|
-
|
|
10954
|
+
import_fs12 = require("fs");
|
|
10814
10955
|
init_config();
|
|
10815
10956
|
init_mesh_config();
|
|
10816
10957
|
init_cli_detector();
|
|
@@ -12692,16 +12833,16 @@ __export(external_sources_exports, {
|
|
|
12692
12833
|
sourcesProviding: () => sourcesProviding
|
|
12693
12834
|
});
|
|
12694
12835
|
function adhdevDir() {
|
|
12695
|
-
return
|
|
12836
|
+
return path18.join(os11.homedir(), ".adhdev");
|
|
12696
12837
|
}
|
|
12697
12838
|
function externalRoot() {
|
|
12698
|
-
return
|
|
12839
|
+
return path18.join(adhdevDir(), "external");
|
|
12699
12840
|
}
|
|
12700
12841
|
function sourcesFilePath() {
|
|
12701
|
-
return
|
|
12842
|
+
return path18.join(adhdevDir(), SOURCES_FILENAME);
|
|
12702
12843
|
}
|
|
12703
12844
|
function activeFilePath() {
|
|
12704
|
-
return
|
|
12845
|
+
return path18.join(adhdevDir(), ACTIVE_FILENAME);
|
|
12705
12846
|
}
|
|
12706
12847
|
function ensureAdhdevDir() {
|
|
12707
12848
|
const d = adhdevDir();
|
|
@@ -12768,7 +12909,7 @@ function inventoryExternalSources() {
|
|
|
12768
12909
|
for (const sourceEntry of entries) {
|
|
12769
12910
|
if (!sourceEntry.isDirectory()) continue;
|
|
12770
12911
|
const sourceName = sourceEntry.name;
|
|
12771
|
-
const sourceDir =
|
|
12912
|
+
const sourceDir = path18.join(root, sourceName);
|
|
12772
12913
|
const providers = {};
|
|
12773
12914
|
let categoryEntries;
|
|
12774
12915
|
try {
|
|
@@ -12779,7 +12920,7 @@ function inventoryExternalSources() {
|
|
|
12779
12920
|
for (const categoryEntry of categoryEntries) {
|
|
12780
12921
|
if (!categoryEntry.isDirectory()) continue;
|
|
12781
12922
|
const category = categoryEntry.name;
|
|
12782
|
-
const categoryDir =
|
|
12923
|
+
const categoryDir = path18.join(sourceDir, category);
|
|
12783
12924
|
let typeEntries;
|
|
12784
12925
|
try {
|
|
12785
12926
|
typeEntries = fs9.readdirSync(categoryDir, { withFileTypes: true });
|
|
@@ -12789,9 +12930,9 @@ function inventoryExternalSources() {
|
|
|
12789
12930
|
const types = [];
|
|
12790
12931
|
for (const typeEntry of typeEntries) {
|
|
12791
12932
|
if (!typeEntry.isDirectory()) continue;
|
|
12792
|
-
const typeDir =
|
|
12793
|
-
const hasV1 = fs9.existsSync(
|
|
12794
|
-
const hasV0 = fs9.existsSync(
|
|
12933
|
+
const typeDir = path18.join(categoryDir, typeEntry.name);
|
|
12934
|
+
const hasV1 = fs9.existsSync(path18.join(typeDir, "provider.v1.json"));
|
|
12935
|
+
const hasV0 = fs9.existsSync(path18.join(typeDir, "provider.json"));
|
|
12795
12936
|
if (hasV1 || hasV0) types.push(typeEntry.name);
|
|
12796
12937
|
}
|
|
12797
12938
|
if (types.length > 0) providers[category] = types;
|
|
@@ -12814,13 +12955,13 @@ function resolveActiveSource(category, type, activeFile) {
|
|
|
12814
12955
|
}
|
|
12815
12956
|
return { source: candidates[0], ambiguous: true, candidates };
|
|
12816
12957
|
}
|
|
12817
|
-
var fs9, os11,
|
|
12958
|
+
var fs9, os11, path18, SOURCES_FILENAME, ACTIVE_FILENAME;
|
|
12818
12959
|
var init_external_sources = __esm({
|
|
12819
12960
|
"src/providers/external-sources.ts"() {
|
|
12820
12961
|
"use strict";
|
|
12821
12962
|
fs9 = __toESM(require("fs"));
|
|
12822
12963
|
os11 = __toESM(require("os"));
|
|
12823
|
-
|
|
12964
|
+
path18 = __toESM(require("path"));
|
|
12824
12965
|
SOURCES_FILENAME = "providers-sources.json";
|
|
12825
12966
|
ACTIVE_FILENAME = "providers-active.json";
|
|
12826
12967
|
}
|
|
@@ -12998,59 +13139,6 @@ var init_terminal_screen = __esm({
|
|
|
12998
13139
|
}
|
|
12999
13140
|
});
|
|
13000
13141
|
|
|
13001
|
-
// src/cli-adapters/resolve-executable.ts
|
|
13002
|
-
function resolveWin32GlobalBin(trimmed) {
|
|
13003
|
-
if (path18.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
|
|
13004
|
-
return null;
|
|
13005
|
-
}
|
|
13006
|
-
const extraDirs = [];
|
|
13007
|
-
if (process.env.APPDATA) extraDirs.push(path18.join(process.env.APPDATA, "npm"));
|
|
13008
|
-
try {
|
|
13009
|
-
extraDirs.push(path18.dirname(process.execPath));
|
|
13010
|
-
} catch {
|
|
13011
|
-
}
|
|
13012
|
-
for (const dir of extraDirs) {
|
|
13013
|
-
if (!dir) continue;
|
|
13014
|
-
for (const ext of WIN_EXEC_EXT) {
|
|
13015
|
-
const full = path18.join(dir, trimmed + ext);
|
|
13016
|
-
if ((0, import_fs14.existsSync)(full)) return full;
|
|
13017
|
-
}
|
|
13018
|
-
}
|
|
13019
|
-
return null;
|
|
13020
|
-
}
|
|
13021
|
-
function resolveWin32Executable(command) {
|
|
13022
|
-
if (process.platform !== "win32") return command;
|
|
13023
|
-
const trimmed = (command || "").trim();
|
|
13024
|
-
if (!trimmed) return command;
|
|
13025
|
-
if (path18.isAbsolute(trimmed) && (0, import_fs14.existsSync)(trimmed)) return trimmed;
|
|
13026
|
-
try {
|
|
13027
|
-
const out = (0, import_child_process4.execFileSync)("where", [trimmed], {
|
|
13028
|
-
encoding: "utf8",
|
|
13029
|
-
windowsHide: true
|
|
13030
|
-
}).trim();
|
|
13031
|
-
if (out) {
|
|
13032
|
-
const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
13033
|
-
const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path18.extname(m).toLowerCase()));
|
|
13034
|
-
return direct || matches[0] || command;
|
|
13035
|
-
}
|
|
13036
|
-
} catch {
|
|
13037
|
-
}
|
|
13038
|
-
const globalBin = resolveWin32GlobalBin(trimmed);
|
|
13039
|
-
if (globalBin) return globalBin;
|
|
13040
|
-
return command;
|
|
13041
|
-
}
|
|
13042
|
-
var import_child_process4, import_fs14, path18, DIRECT_EXEC_EXT, WIN_EXEC_EXT;
|
|
13043
|
-
var init_resolve_executable = __esm({
|
|
13044
|
-
"src/cli-adapters/resolve-executable.ts"() {
|
|
13045
|
-
"use strict";
|
|
13046
|
-
import_child_process4 = require("child_process");
|
|
13047
|
-
import_fs14 = require("fs");
|
|
13048
|
-
path18 = __toESM(require("path"));
|
|
13049
|
-
DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
|
|
13050
|
-
WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
|
|
13051
|
-
}
|
|
13052
|
-
});
|
|
13053
|
-
|
|
13054
13142
|
// src/cli-adapters/pty-transport.ts
|
|
13055
13143
|
var pty_transport_exports = {};
|
|
13056
13144
|
__export(pty_transport_exports, {
|
|
@@ -15265,10 +15353,10 @@ ${lastSnapshot}`;
|
|
|
15265
15353
|
return this.accumulatedRawBuffer.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
15266
15354
|
}
|
|
15267
15355
|
getFreshParsedStatusCache() {
|
|
15268
|
-
const
|
|
15356
|
+
const cached3 = this.parsedStatusCache;
|
|
15269
15357
|
const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
|
|
15270
|
-
if (
|
|
15271
|
-
return
|
|
15358
|
+
if (cached3 && cached3.responseBuffer === this.responseBuffer && cached3.currentTurnScope === this.engine.currentTurnScope && cached3.recentOutputBuffer === this.recentOutputBuffer && cached3.accumulatedBuffer === this.accumulatedBuffer && cached3.accumulatedRawBufferKey === accumulatedRawBufferKey && cached3.screenText === this.lastScreenText && cached3.currentStatus === this.engine.currentStatus && cached3.activeModal === this.engine.activeModal && cached3.cliName === this.cliName) {
|
|
15359
|
+
return cached3.result;
|
|
15272
15360
|
}
|
|
15273
15361
|
return null;
|
|
15274
15362
|
}
|
|
@@ -15730,10 +15818,10 @@ ${lastSnapshot}`;
|
|
|
15730
15818
|
getScriptParsedStatus() {
|
|
15731
15819
|
const screenText = this.readTerminalScreenText();
|
|
15732
15820
|
const parseScreenText = this.getParseScreenText(screenText);
|
|
15733
|
-
const
|
|
15821
|
+
const cached3 = this.parsedStatusCache;
|
|
15734
15822
|
const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
|
|
15735
|
-
if (!this.providerOwnsTranscript() &&
|
|
15736
|
-
return
|
|
15823
|
+
if (!this.providerOwnsTranscript() && cached3 && cached3.responseBuffer === this.responseBuffer && cached3.currentTurnScope === this.engine.currentTurnScope && cached3.recentOutputBuffer === this.recentOutputBuffer && cached3.accumulatedBuffer === this.accumulatedBuffer && cached3.accumulatedRawBufferKey === accumulatedRawBufferKey && cached3.screenText === parseScreenText && cached3.currentStatus === this.engine.currentStatus && cached3.activeModal === this.engine.activeModal && cached3.cliName === this.cliName) {
|
|
15824
|
+
return cached3.result;
|
|
15737
15825
|
}
|
|
15738
15826
|
const parsed = this.runParseSession();
|
|
15739
15827
|
if (!parsed || !Array.isArray(parsed.messages)) {
|
|
@@ -19754,13 +19842,20 @@ var MESH_REFINE_CONFIG_SCHEMA = {
|
|
|
19754
19842
|
function isMeshConfigRecord(value) {
|
|
19755
19843
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
19756
19844
|
}
|
|
19845
|
+
var SHELL_METACHAR_RE = /[;&|<>`$\n\r'"]/;
|
|
19846
|
+
var SAFE_TOKEN_RE = /^[A-Za-z0-9_@./:=+-]+$/;
|
|
19847
|
+
var SAFE_WIN32_EXEC_TOKEN_RE = /^[A-Za-z0-9_@./:=+\\-]+$/;
|
|
19757
19848
|
function tokenizeCommandString(command) {
|
|
19758
19849
|
const trimmed = command.trim();
|
|
19759
19850
|
if (!trimmed) return null;
|
|
19760
|
-
if (
|
|
19851
|
+
if (SHELL_METACHAR_RE.test(trimmed)) return null;
|
|
19761
19852
|
const tokens = trimmed.split(/\s+/).filter(Boolean);
|
|
19762
19853
|
if (!tokens.length) return null;
|
|
19763
|
-
|
|
19854
|
+
const isWin32 = process.platform === "win32";
|
|
19855
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
19856
|
+
const re = isWin32 && i === 0 ? SAFE_WIN32_EXEC_TOKEN_RE : SAFE_TOKEN_RE;
|
|
19857
|
+
if (!re.test(tokens[i])) return null;
|
|
19858
|
+
}
|
|
19764
19859
|
return tokens;
|
|
19765
19860
|
}
|
|
19766
19861
|
function validateCategory(value) {
|
|
@@ -19970,12 +20065,13 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
|
19970
20065
|
}
|
|
19971
20066
|
|
|
19972
20067
|
// src/mesh/worktree-bootstrap-config.ts
|
|
19973
|
-
var
|
|
20068
|
+
var import_fs9 = require("fs");
|
|
19974
20069
|
var import_path8 = require("path");
|
|
19975
20070
|
var import_node_child_process3 = require("child_process");
|
|
19976
20071
|
var import_node_crypto2 = require("crypto");
|
|
19977
20072
|
var import_node_util3 = require("util");
|
|
19978
20073
|
var yaml3 = __toESM(require("js-yaml"));
|
|
20074
|
+
init_resolve_executable();
|
|
19979
20075
|
var MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS = [
|
|
19980
20076
|
".adhdev/worktree_bootstrap.json",
|
|
19981
20077
|
".adhdev/worktree_bootstrap.yaml",
|
|
@@ -20063,9 +20159,9 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
20063
20159
|
}
|
|
20064
20160
|
for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
20065
20161
|
const configPath = (0, import_path8.join)(workspace, relative5);
|
|
20066
|
-
if (!(0,
|
|
20162
|
+
if (!(0, import_fs9.existsSync)(configPath)) continue;
|
|
20067
20163
|
try {
|
|
20068
|
-
const parsed = parseConfigText3(configPath, (0,
|
|
20164
|
+
const parsed = parseConfigText3(configPath, (0, import_fs9.readFileSync)(configPath, "utf-8"));
|
|
20069
20165
|
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
|
|
20070
20166
|
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
20071
20167
|
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
@@ -20080,7 +20176,7 @@ function computeStaleInputsDigest(workspace, staleInputs) {
|
|
|
20080
20176
|
for (const relative5 of staleInputs ?? []) {
|
|
20081
20177
|
const filePath = (0, import_path8.join)(workspace, relative5);
|
|
20082
20178
|
try {
|
|
20083
|
-
digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0,
|
|
20179
|
+
digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0, import_fs9.readFileSync)(filePath)).digest("hex");
|
|
20084
20180
|
} catch {
|
|
20085
20181
|
digest[relative5] = "absent";
|
|
20086
20182
|
}
|
|
@@ -20150,10 +20246,10 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
|
20150
20246
|
staleInputs: loaded.config.staleInputs
|
|
20151
20247
|
};
|
|
20152
20248
|
const staleInputPaths = loaded.config.staleInputs ?? [];
|
|
20153
|
-
const initiallyAbsent = staleInputPaths.filter((p) => !(0,
|
|
20249
|
+
const initiallyAbsent = staleInputPaths.filter((p) => !(0, import_fs9.existsSync)((0, import_path8.join)(workspace, p)));
|
|
20154
20250
|
for (const command of validation.commands) {
|
|
20155
20251
|
if (initiallyAbsent.length > 0) {
|
|
20156
|
-
const appearedNow = initiallyAbsent.filter((p) => (0,
|
|
20252
|
+
const appearedNow = initiallyAbsent.filter((p) => (0, import_fs9.existsSync)((0, import_path8.join)(workspace, p)));
|
|
20157
20253
|
if (appearedNow.length > 0) {
|
|
20158
20254
|
state.status = "stale";
|
|
20159
20255
|
state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -20164,8 +20260,9 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
|
20164
20260
|
const cwd = command.cwd ? (0, import_path8.resolve)(workspace, command.cwd) : workspace;
|
|
20165
20261
|
const startedAt = Date.now();
|
|
20166
20262
|
state.lastCommand = command.displayCommand;
|
|
20263
|
+
const resolvedCommand = resolveWin32Executable(command.command);
|
|
20167
20264
|
try {
|
|
20168
|
-
const result = await execFileAsync4(
|
|
20265
|
+
const result = await execFileAsync4(resolvedCommand, command.args, {
|
|
20169
20266
|
cwd,
|
|
20170
20267
|
encoding: "utf8",
|
|
20171
20268
|
timeout: command.timeoutMs || DEFAULT_TIMEOUT_MS2,
|
|
@@ -20400,7 +20497,7 @@ var P2pRelayFailureError = class extends Error {
|
|
|
20400
20497
|
};
|
|
20401
20498
|
|
|
20402
20499
|
// src/config/state-store.ts
|
|
20403
|
-
var
|
|
20500
|
+
var import_fs13 = require("fs");
|
|
20404
20501
|
var import_path10 = require("path");
|
|
20405
20502
|
init_config();
|
|
20406
20503
|
var DEFAULT_STATE = {
|
|
@@ -20451,11 +20548,11 @@ function normalizeState(raw) {
|
|
|
20451
20548
|
}
|
|
20452
20549
|
function loadState() {
|
|
20453
20550
|
const statePath = getStatePath();
|
|
20454
|
-
if (!(0,
|
|
20551
|
+
if (!(0, import_fs13.existsSync)(statePath)) {
|
|
20455
20552
|
return { ...DEFAULT_STATE };
|
|
20456
20553
|
}
|
|
20457
20554
|
try {
|
|
20458
|
-
const raw = (0,
|
|
20555
|
+
const raw = (0, import_fs13.readFileSync)(statePath, "utf-8");
|
|
20459
20556
|
return normalizeState(JSON.parse(raw));
|
|
20460
20557
|
} catch {
|
|
20461
20558
|
return { ...DEFAULT_STATE };
|
|
@@ -20464,28 +20561,28 @@ function loadState() {
|
|
|
20464
20561
|
function saveState(state) {
|
|
20465
20562
|
const statePath = getStatePath();
|
|
20466
20563
|
const normalized = normalizeState(state);
|
|
20467
|
-
(0,
|
|
20564
|
+
(0, import_fs13.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
20468
20565
|
}
|
|
20469
20566
|
function resetState() {
|
|
20470
20567
|
saveState({ ...DEFAULT_STATE });
|
|
20471
20568
|
}
|
|
20472
20569
|
|
|
20473
20570
|
// src/detection/ide-detector.ts
|
|
20474
|
-
var
|
|
20571
|
+
var import_child_process3 = require("child_process");
|
|
20475
20572
|
var import_util = require("util");
|
|
20476
|
-
var
|
|
20573
|
+
var import_fs14 = require("fs");
|
|
20477
20574
|
var import_os2 = require("os");
|
|
20478
|
-
var
|
|
20575
|
+
var path14 = __toESM(require("path"));
|
|
20479
20576
|
|
|
20480
20577
|
// src/detection/win32-ide-version.ts
|
|
20481
20578
|
var fs5 = __toESM(require("fs"));
|
|
20482
|
-
var
|
|
20579
|
+
var path13 = __toESM(require("path"));
|
|
20483
20580
|
function manifestCandidates(exeDir) {
|
|
20484
20581
|
return [
|
|
20485
|
-
|
|
20486
|
-
|
|
20582
|
+
path13.join(exeDir, "resources", "app", "product.json"),
|
|
20583
|
+
path13.join(exeDir, "resources", "app", "package.json"),
|
|
20487
20584
|
// Some packagings keep product.json one level up.
|
|
20488
|
-
|
|
20585
|
+
path13.join(exeDir, "product.json")
|
|
20489
20586
|
];
|
|
20490
20587
|
}
|
|
20491
20588
|
function parseVersionFromManifest(raw) {
|
|
@@ -20503,9 +20600,9 @@ function readWin32IdeVersionFromDisk(exePath) {
|
|
|
20503
20600
|
if (!exePath) return null;
|
|
20504
20601
|
let exeDir;
|
|
20505
20602
|
try {
|
|
20506
|
-
exeDir = fs5.statSync(exePath).isDirectory() ? exePath :
|
|
20603
|
+
exeDir = fs5.statSync(exePath).isDirectory() ? exePath : path13.dirname(exePath);
|
|
20507
20604
|
} catch {
|
|
20508
|
-
exeDir =
|
|
20605
|
+
exeDir = path13.dirname(exePath);
|
|
20509
20606
|
}
|
|
20510
20607
|
for (const candidate of manifestCandidates(exeDir)) {
|
|
20511
20608
|
try {
|
|
@@ -20519,7 +20616,7 @@ function readWin32IdeVersionFromDisk(exePath) {
|
|
|
20519
20616
|
}
|
|
20520
20617
|
function isKnownWin32GuiExe(binPath, win32ProcessNames) {
|
|
20521
20618
|
if (!binPath) return false;
|
|
20522
|
-
const base =
|
|
20619
|
+
const base = path13.win32.basename(binPath).toLowerCase();
|
|
20523
20620
|
if (!base.endsWith(".exe")) return false;
|
|
20524
20621
|
for (const names of Object.values(win32ProcessNames)) {
|
|
20525
20622
|
for (const name of names) {
|
|
@@ -20532,7 +20629,7 @@ function isKnownWin32GuiExe(binPath, win32ProcessNames) {
|
|
|
20532
20629
|
}
|
|
20533
20630
|
|
|
20534
20631
|
// src/detection/ide-detector.ts
|
|
20535
|
-
var execAsync2 = (0, import_util.promisify)(
|
|
20632
|
+
var execAsync2 = (0, import_util.promisify)(import_child_process3.exec);
|
|
20536
20633
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
20537
20634
|
var registeredIDEs = /* @__PURE__ */ new Map();
|
|
20538
20635
|
function registerIDEDefinition(def) {
|
|
@@ -20551,10 +20648,10 @@ function getMergedDefinitions() {
|
|
|
20551
20648
|
function findCliCommand(command) {
|
|
20552
20649
|
const trimmed = String(command || "").trim();
|
|
20553
20650
|
if (!trimmed) return null;
|
|
20554
|
-
if (
|
|
20555
|
-
const candidate = trimmed.startsWith("~") ?
|
|
20556
|
-
const resolved =
|
|
20557
|
-
return (0,
|
|
20651
|
+
if (path14.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
20652
|
+
const candidate = trimmed.startsWith("~") ? path14.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
|
|
20653
|
+
const resolved = path14.isAbsolute(candidate) ? candidate : path14.resolve(candidate);
|
|
20654
|
+
return (0, import_fs14.existsSync)(resolved) ? resolved : null;
|
|
20558
20655
|
}
|
|
20559
20656
|
const isWin = (0, import_os2.platform)() === "win32";
|
|
20560
20657
|
const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
|
|
@@ -20562,10 +20659,10 @@ function findCliCommand(command) {
|
|
|
20562
20659
|
for (const p of paths) {
|
|
20563
20660
|
if (!p) continue;
|
|
20564
20661
|
for (const ext of exes) {
|
|
20565
|
-
const fullPath =
|
|
20662
|
+
const fullPath = path14.join(p, trimmed + ext);
|
|
20566
20663
|
try {
|
|
20567
|
-
if ((0,
|
|
20568
|
-
const stat2 = (0,
|
|
20664
|
+
if ((0, import_fs14.existsSync)(fullPath)) {
|
|
20665
|
+
const stat2 = (0, import_fs14.statSync)(fullPath);
|
|
20569
20666
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
20570
20667
|
return fullPath;
|
|
20571
20668
|
}
|
|
@@ -20579,13 +20676,13 @@ function findCliCommand(command) {
|
|
|
20579
20676
|
function checkPathExists(paths) {
|
|
20580
20677
|
const home = (0, import_os2.homedir)();
|
|
20581
20678
|
for (const p of paths) {
|
|
20582
|
-
const normalized = p.startsWith("~") ?
|
|
20679
|
+
const normalized = p.startsWith("~") ? path14.join(home, p.slice(1)) : p;
|
|
20583
20680
|
if (normalized.includes("*")) {
|
|
20584
20681
|
const username = home.split(/[\\/]/).pop() || "";
|
|
20585
20682
|
const resolved = normalized.replace("*", username);
|
|
20586
|
-
if ((0,
|
|
20683
|
+
if ((0, import_fs14.existsSync)(resolved)) return resolved;
|
|
20587
20684
|
} else {
|
|
20588
|
-
if ((0,
|
|
20685
|
+
if ((0, import_fs14.existsSync)(normalized)) return normalized;
|
|
20589
20686
|
}
|
|
20590
20687
|
}
|
|
20591
20688
|
return null;
|
|
@@ -20599,7 +20696,7 @@ async function detectIDEs(providerLoader) {
|
|
|
20599
20696
|
let resolvedCli = cliPath;
|
|
20600
20697
|
if (!resolvedCli && appPath && os30 === "darwin") {
|
|
20601
20698
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
20602
|
-
if ((0,
|
|
20699
|
+
if ((0, import_fs14.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
20603
20700
|
}
|
|
20604
20701
|
if (!resolvedCli && appPath && os30 === "win32") {
|
|
20605
20702
|
const { dirname: dirname17 } = await import("path");
|
|
@@ -20612,7 +20709,7 @@ async function detectIDEs(providerLoader) {
|
|
|
20612
20709
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
20613
20710
|
];
|
|
20614
20711
|
for (const c of candidates) {
|
|
20615
|
-
if ((0,
|
|
20712
|
+
if ((0, import_fs14.existsSync)(c)) {
|
|
20616
20713
|
resolvedCli = c;
|
|
20617
20714
|
break;
|
|
20618
20715
|
}
|
|
@@ -20639,9 +20736,9 @@ init_cli_detector();
|
|
|
20639
20736
|
|
|
20640
20737
|
// src/system/host-memory.ts
|
|
20641
20738
|
var os7 = __toESM(require("os"));
|
|
20642
|
-
var
|
|
20739
|
+
var import_child_process4 = require("child_process");
|
|
20643
20740
|
var import_util2 = require("util");
|
|
20644
|
-
var execAsync3 = (0, import_util2.promisify)(
|
|
20741
|
+
var execAsync3 = (0, import_util2.promisify)(import_child_process4.exec);
|
|
20645
20742
|
var cachedDarwinAvail = null;
|
|
20646
20743
|
var darwinMemoryInterval = null;
|
|
20647
20744
|
async function updateDarwinMemoryCache() {
|
|
@@ -22470,10 +22567,10 @@ ${cleanBody}`;
|
|
|
22470
22567
|
|
|
22471
22568
|
// src/config/chat-history.ts
|
|
22472
22569
|
var fs6 = __toESM(require("fs"));
|
|
22473
|
-
var
|
|
22570
|
+
var path15 = __toESM(require("path"));
|
|
22474
22571
|
var os8 = __toESM(require("os"));
|
|
22475
22572
|
init_chat_message_normalization();
|
|
22476
|
-
var HISTORY_DIR =
|
|
22573
|
+
var HISTORY_DIR = path15.join(os8.homedir(), ".adhdev", "history");
|
|
22477
22574
|
var RETAIN_DAYS = 30;
|
|
22478
22575
|
var SAVED_HISTORY_INDEX_VERSION = 1;
|
|
22479
22576
|
var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
|
|
@@ -22489,11 +22586,11 @@ var savedHistoryRollupInFlight = /* @__PURE__ */ new Set();
|
|
|
22489
22586
|
var BOUNDED_TAIL_CACHE_MAX_ENTRIES = 64;
|
|
22490
22587
|
var boundedTailReadCache = /* @__PURE__ */ new Map();
|
|
22491
22588
|
function readBoundedTailCache(key, signature) {
|
|
22492
|
-
const
|
|
22493
|
-
if (!
|
|
22589
|
+
const cached3 = boundedTailReadCache.get(key);
|
|
22590
|
+
if (!cached3 || cached3.signature !== signature) return null;
|
|
22494
22591
|
boundedTailReadCache.delete(key);
|
|
22495
|
-
boundedTailReadCache.set(key,
|
|
22496
|
-
return
|
|
22592
|
+
boundedTailReadCache.set(key, cached3);
|
|
22593
|
+
return cached3.result;
|
|
22497
22594
|
}
|
|
22498
22595
|
function writeBoundedTailCache(key, signature, result) {
|
|
22499
22596
|
boundedTailReadCache.delete(key);
|
|
@@ -22659,7 +22756,7 @@ function extractSavedHistorySessionIdFromFile(file) {
|
|
|
22659
22756
|
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
22660
22757
|
return new Map(files.map((file) => {
|
|
22661
22758
|
try {
|
|
22662
|
-
const stat2 = fs6.statSync(
|
|
22759
|
+
const stat2 = fs6.statSync(path15.join(dir, file));
|
|
22663
22760
|
return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
|
|
22664
22761
|
} catch {
|
|
22665
22762
|
return [file, `${file}:missing`];
|
|
@@ -22670,7 +22767,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
|
|
|
22670
22767
|
return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
|
|
22671
22768
|
}
|
|
22672
22769
|
function getSavedHistoryIndexFilePath(dir) {
|
|
22673
|
-
return
|
|
22770
|
+
return path15.join(dir, SAVED_HISTORY_INDEX_FILE);
|
|
22674
22771
|
}
|
|
22675
22772
|
function getSavedHistoryIndexLockPath(dir) {
|
|
22676
22773
|
return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
|
|
@@ -22772,7 +22869,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
|
|
|
22772
22869
|
}
|
|
22773
22870
|
for (const file of Array.from(currentEntries.keys())) {
|
|
22774
22871
|
if (incomingFiles.has(file)) continue;
|
|
22775
|
-
if (!fs6.existsSync(
|
|
22872
|
+
if (!fs6.existsSync(path15.join(dir, file))) {
|
|
22776
22873
|
currentEntries.delete(file);
|
|
22777
22874
|
}
|
|
22778
22875
|
}
|
|
@@ -22798,7 +22895,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
22798
22895
|
const indexStat = fs6.statSync(getSavedHistoryIndexFilePath(dir));
|
|
22799
22896
|
const files = listHistoryFiles(dir);
|
|
22800
22897
|
for (const file of files) {
|
|
22801
|
-
const stat2 = fs6.statSync(
|
|
22898
|
+
const stat2 = fs6.statSync(path15.join(dir, file));
|
|
22802
22899
|
if (stat2.mtimeMs > indexStat.mtimeMs) return true;
|
|
22803
22900
|
}
|
|
22804
22901
|
return false;
|
|
@@ -22808,14 +22905,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
22808
22905
|
}
|
|
22809
22906
|
function buildSavedHistoryFileSignature(dir, file) {
|
|
22810
22907
|
try {
|
|
22811
|
-
const stat2 = fs6.statSync(
|
|
22908
|
+
const stat2 = fs6.statSync(path15.join(dir, file));
|
|
22812
22909
|
return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
|
|
22813
22910
|
} catch {
|
|
22814
22911
|
return `${file}:missing`;
|
|
22815
22912
|
}
|
|
22816
22913
|
}
|
|
22817
22914
|
function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
|
|
22818
|
-
const filePath =
|
|
22915
|
+
const filePath = path15.join(dir, file);
|
|
22819
22916
|
const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
|
|
22820
22917
|
const currentEntry = entries.get(file) || null;
|
|
22821
22918
|
const nextSummary = updater(currentEntry?.summary || null);
|
|
@@ -22888,7 +22985,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
|
|
|
22888
22985
|
function computeSavedHistoryFileSummary(dir, file) {
|
|
22889
22986
|
const historySessionId = extractSavedHistorySessionIdFromFile(file);
|
|
22890
22987
|
if (!historySessionId) return null;
|
|
22891
|
-
const filePath =
|
|
22988
|
+
const filePath = path15.join(dir, file);
|
|
22892
22989
|
const content = fs6.readFileSync(filePath, "utf-8");
|
|
22893
22990
|
const lines = content.split("\n").filter(Boolean);
|
|
22894
22991
|
let messageCount = 0;
|
|
@@ -22975,11 +23072,11 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
|
|
|
22975
23072
|
const summaryBySessionId = /* @__PURE__ */ new Map();
|
|
22976
23073
|
const nextPersistedEntries = /* @__PURE__ */ new Map();
|
|
22977
23074
|
for (const file of files.slice().sort()) {
|
|
22978
|
-
const filePath =
|
|
23075
|
+
const filePath = path15.join(dir, file);
|
|
22979
23076
|
const signature = fileSignatures.get(file) || `${file}:missing`;
|
|
22980
|
-
const
|
|
23077
|
+
const cached3 = savedHistoryFileSummaryCache.get(filePath);
|
|
22981
23078
|
const persisted = persistedEntries.get(file);
|
|
22982
|
-
const reusableEntry =
|
|
23079
|
+
const reusableEntry = cached3?.signature === signature ? cached3 : persisted?.signature === signature ? persisted : null;
|
|
22983
23080
|
const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(dir, file);
|
|
22984
23081
|
const nextEntry = reusableEntry || {
|
|
22985
23082
|
signature,
|
|
@@ -23095,12 +23192,12 @@ var ChatHistoryWriter = class {
|
|
|
23095
23192
|
});
|
|
23096
23193
|
}
|
|
23097
23194
|
if (newMessages.length === 0) return;
|
|
23098
|
-
const dir =
|
|
23195
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
23099
23196
|
fs6.mkdirSync(dir, { recursive: true });
|
|
23100
23197
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
23101
23198
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
23102
23199
|
const fileName = `${filePrefix}${date}.jsonl`;
|
|
23103
|
-
const filePath =
|
|
23200
|
+
const filePath = path15.join(dir, fileName);
|
|
23104
23201
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
23105
23202
|
fs6.appendFileSync(filePath, lines, "utf-8");
|
|
23106
23203
|
updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
|
|
@@ -23191,11 +23288,11 @@ var ChatHistoryWriter = class {
|
|
|
23191
23288
|
const ws = String(workspace || "").trim();
|
|
23192
23289
|
if (!id || !ws) return;
|
|
23193
23290
|
try {
|
|
23194
|
-
const dir =
|
|
23291
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
23195
23292
|
fs6.mkdirSync(dir, { recursive: true });
|
|
23196
23293
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
23197
23294
|
const fileName = `${this.sanitize(id)}_${date}.jsonl`;
|
|
23198
|
-
const filePath =
|
|
23295
|
+
const filePath = path15.join(dir, fileName);
|
|
23199
23296
|
const record = {
|
|
23200
23297
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
23201
23298
|
receivedAt: Date.now(),
|
|
@@ -23241,14 +23338,14 @@ var ChatHistoryWriter = class {
|
|
|
23241
23338
|
this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
|
|
23242
23339
|
this.lastSeenCounts.delete(fromDedupKey);
|
|
23243
23340
|
}
|
|
23244
|
-
const dir =
|
|
23341
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
23245
23342
|
if (!fs6.existsSync(dir)) return;
|
|
23246
23343
|
const fromPrefix = `${this.sanitize(fromId)}_`;
|
|
23247
23344
|
const toPrefix = `${this.sanitize(toId)}_`;
|
|
23248
23345
|
const files = fs6.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
|
|
23249
23346
|
for (const file of files) {
|
|
23250
|
-
const sourcePath =
|
|
23251
|
-
const targetPath =
|
|
23347
|
+
const sourcePath = path15.join(dir, file);
|
|
23348
|
+
const targetPath = path15.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
|
|
23252
23349
|
const sourceLines = fs6.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
23253
23350
|
const rewritten = sourceLines.map((line) => {
|
|
23254
23351
|
try {
|
|
@@ -23282,13 +23379,13 @@ var ChatHistoryWriter = class {
|
|
|
23282
23379
|
const sessionId = String(historySessionId || "").trim();
|
|
23283
23380
|
if (!sessionId) return;
|
|
23284
23381
|
try {
|
|
23285
|
-
const dir =
|
|
23382
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
23286
23383
|
if (!fs6.existsSync(dir)) return;
|
|
23287
23384
|
const prefix = `${this.sanitize(sessionId)}_`;
|
|
23288
23385
|
const files = fs6.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
|
|
23289
23386
|
const seen = /* @__PURE__ */ new Set();
|
|
23290
23387
|
for (const file of files) {
|
|
23291
|
-
const filePath =
|
|
23388
|
+
const filePath = path15.join(dir, file);
|
|
23292
23389
|
const lines = fs6.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
23293
23390
|
const next = [];
|
|
23294
23391
|
for (const line of lines) {
|
|
@@ -23342,11 +23439,11 @@ var ChatHistoryWriter = class {
|
|
|
23342
23439
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
23343
23440
|
const agentDirs = fs6.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
23344
23441
|
for (const dir of agentDirs) {
|
|
23345
|
-
const dirPath =
|
|
23442
|
+
const dirPath = path15.join(HISTORY_DIR, dir.name);
|
|
23346
23443
|
const files = fs6.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
23347
23444
|
let removedAny = false;
|
|
23348
23445
|
for (const file of files) {
|
|
23349
|
-
const filePath =
|
|
23446
|
+
const filePath = path15.join(dirPath, file);
|
|
23350
23447
|
const stat2 = fs6.statSync(filePath);
|
|
23351
23448
|
if (stat2.mtimeMs < cutoff) {
|
|
23352
23449
|
fs6.unlinkSync(filePath);
|
|
@@ -23475,16 +23572,16 @@ function readFileTailLines(filePath, needed) {
|
|
|
23475
23572
|
incrementalTailCache.delete(filePath);
|
|
23476
23573
|
return { lines: [], coversWholeFile: true };
|
|
23477
23574
|
}
|
|
23478
|
-
const
|
|
23479
|
-
if (
|
|
23480
|
-
if (
|
|
23575
|
+
const cached3 = incrementalTailCache.get(filePath);
|
|
23576
|
+
if (cached3) {
|
|
23577
|
+
if (cached3.size === size && cached3.mtimeMs === mtimeMs) {
|
|
23481
23578
|
incrementalTailCache.delete(filePath);
|
|
23482
|
-
incrementalTailCache.set(filePath,
|
|
23483
|
-
if (
|
|
23484
|
-
return { lines:
|
|
23579
|
+
incrementalTailCache.set(filePath, cached3);
|
|
23580
|
+
if (cached3.coversWholeFile || cached3.lines.length >= needed) {
|
|
23581
|
+
return { lines: cached3.lines, coversWholeFile: cached3.coversWholeFile };
|
|
23485
23582
|
}
|
|
23486
|
-
} else if (size >
|
|
23487
|
-
const incremental = tryIncrementalTailGrowth(filePath,
|
|
23583
|
+
} else if (size > cached3.size) {
|
|
23584
|
+
const incremental = tryIncrementalTailGrowth(filePath, cached3, size, mtimeMs, needed);
|
|
23488
23585
|
if (incremental) return { lines: incremental.lines, coversWholeFile: incremental.coversWholeFile };
|
|
23489
23586
|
}
|
|
23490
23587
|
incrementalTailCache.delete(filePath);
|
|
@@ -23510,22 +23607,22 @@ function readFileTailLines(filePath, needed) {
|
|
|
23510
23607
|
storeIncrementalTailCache(filePath, result.size, result.mtimeMs, result.lines, result.coversWholeFile);
|
|
23511
23608
|
return { lines: result.lines, coversWholeFile: result.coversWholeFile };
|
|
23512
23609
|
}
|
|
23513
|
-
function tryIncrementalTailGrowth(filePath,
|
|
23610
|
+
function tryIncrementalTailGrowth(filePath, cached3, size, mtimeMs, needed) {
|
|
23514
23611
|
const fd = fs6.openSync(filePath, "r");
|
|
23515
23612
|
try {
|
|
23516
|
-
if (
|
|
23613
|
+
if (cached3.size > 0) {
|
|
23517
23614
|
const boundary = Buffer.alloc(1);
|
|
23518
|
-
fs6.readSync(fd, boundary, 0, 1,
|
|
23615
|
+
fs6.readSync(fd, boundary, 0, 1, cached3.size - 1);
|
|
23519
23616
|
if (boundary[0] !== 10) return null;
|
|
23520
23617
|
}
|
|
23521
|
-
const appendedLength = size -
|
|
23618
|
+
const appendedLength = size - cached3.size;
|
|
23522
23619
|
const appended = Buffer.alloc(appendedLength);
|
|
23523
|
-
fs6.readSync(fd, appended, 0, appendedLength,
|
|
23620
|
+
fs6.readSync(fd, appended, 0, appendedLength, cached3.size);
|
|
23524
23621
|
const newLines = appended.toString("utf-8").split("\n");
|
|
23525
23622
|
if (newLines.length && newLines[newLines.length - 1] === "") newLines.pop();
|
|
23526
|
-
const merged =
|
|
23623
|
+
const merged = cached3.lines.concat(newLines);
|
|
23527
23624
|
const trimmed = merged.length > TAIL_LINES_RETAINED ? merged.slice(merged.length - TAIL_LINES_RETAINED) : merged;
|
|
23528
|
-
const coversWholeFile =
|
|
23625
|
+
const coversWholeFile = cached3.coversWholeFile && trimmed.length === merged.length;
|
|
23529
23626
|
storeIncrementalTailCache(filePath, size, mtimeMs, trimmed, coversWholeFile);
|
|
23530
23627
|
if (coversWholeFile || trimmed.length >= needed) {
|
|
23531
23628
|
return { lines: trimmed, coversWholeFile };
|
|
@@ -23549,7 +23646,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
|
|
|
23549
23646
|
const seen = /* @__PURE__ */ new Set();
|
|
23550
23647
|
let readAllFiles = true;
|
|
23551
23648
|
for (let f = 0; f < files.length; f++) {
|
|
23552
|
-
const filePath =
|
|
23649
|
+
const filePath = path15.join(dir, files[f]);
|
|
23553
23650
|
const remaining = Math.max(0, needed - collected.length);
|
|
23554
23651
|
const perFileNeeded = Math.min(needed, remaining + BOUNDED_TAIL_SLACK);
|
|
23555
23652
|
const { lines, coversWholeFile } = readFileTailLines(filePath, perFileNeeded);
|
|
@@ -23582,7 +23679,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
|
|
|
23582
23679
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
23583
23680
|
try {
|
|
23584
23681
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
23585
|
-
const dir =
|
|
23682
|
+
const dir = path15.join(HISTORY_DIR, sanitized);
|
|
23586
23683
|
if (!fs6.existsSync(dir)) return { messages: [], hasMore: false };
|
|
23587
23684
|
const files = listHistoryFiles(dir, historySessionId);
|
|
23588
23685
|
const bounded = isBoundedTailRequest(limit, offset, excludeRecentCount);
|
|
@@ -23590,8 +23687,8 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
23590
23687
|
const fileSignatures = buildSavedHistoryFileSignatureMap(dir, files);
|
|
23591
23688
|
const cacheKey = `${sanitized}\0${historySessionId || ""}\0${offset}\0${limit}\0${excludeRecentCount}\0${historyBehavior?.collapseConsecutiveAssistantTurns ? "1" : "0"}`;
|
|
23592
23689
|
const signature = buildSavedHistoryCacheSignature(files, fileSignatures);
|
|
23593
|
-
const
|
|
23594
|
-
if (
|
|
23690
|
+
const cached3 = readBoundedTailCache(cacheKey, signature);
|
|
23691
|
+
if (cached3) return cached3;
|
|
23595
23692
|
const numericLimit = Math.max(1, Number(limit));
|
|
23596
23693
|
const numericOffset = Math.max(0, Number(offset));
|
|
23597
23694
|
const numericExclude = Math.max(0, Number(excludeRecentCount));
|
|
@@ -23605,7 +23702,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
23605
23702
|
const allMessages = [];
|
|
23606
23703
|
const seen = /* @__PURE__ */ new Set();
|
|
23607
23704
|
for (const file of files) {
|
|
23608
|
-
const filePath =
|
|
23705
|
+
const filePath = path15.join(dir, file);
|
|
23609
23706
|
const content = fs6.readFileSync(filePath, "utf-8");
|
|
23610
23707
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
23611
23708
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -23629,28 +23726,28 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
23629
23726
|
function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
23630
23727
|
try {
|
|
23631
23728
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
23632
|
-
const dir =
|
|
23729
|
+
const dir = path15.join(HISTORY_DIR, sanitized);
|
|
23633
23730
|
if (!fs6.existsSync(dir)) {
|
|
23634
23731
|
savedHistorySessionCache.delete(sanitized);
|
|
23635
23732
|
return { sessions: [], hasMore: false };
|
|
23636
23733
|
}
|
|
23637
|
-
const
|
|
23734
|
+
const cached3 = savedHistorySessionCache.get(sanitized);
|
|
23638
23735
|
const offset = Math.max(0, options.offset || 0);
|
|
23639
23736
|
const limit = Math.max(1, options.limit || 30);
|
|
23640
23737
|
const indexSignature = buildSavedHistoryIndexFileSignature(dir);
|
|
23641
23738
|
let cacheWasInvalidated = false;
|
|
23642
|
-
if (
|
|
23643
|
-
const cacheLooksPersisted =
|
|
23644
|
-
const cacheStillValid = cacheLooksPersisted ?
|
|
23739
|
+
if (cached3) {
|
|
23740
|
+
const cacheLooksPersisted = cached3.signature.startsWith("index:");
|
|
23741
|
+
const cacheStillValid = cacheLooksPersisted ? cached3.signature === indexSignature : (() => {
|
|
23645
23742
|
const files2 = listHistoryFiles(dir);
|
|
23646
23743
|
const fileSignatures2 = buildSavedHistoryFileSignatureMap(dir, files2);
|
|
23647
|
-
return
|
|
23744
|
+
return cached3.signature === buildSavedHistoryCacheSignature(files2, fileSignatures2);
|
|
23648
23745
|
})();
|
|
23649
23746
|
if (cacheStillValid) {
|
|
23650
|
-
const sliced2 =
|
|
23747
|
+
const sliced2 = cached3.summaries.slice(offset, offset + limit);
|
|
23651
23748
|
return {
|
|
23652
23749
|
sessions: sliced2,
|
|
23653
|
-
hasMore:
|
|
23750
|
+
hasMore: cached3.summaries.length > offset + limit
|
|
23654
23751
|
};
|
|
23655
23752
|
}
|
|
23656
23753
|
cacheWasInvalidated = true;
|
|
@@ -23690,11 +23787,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
|
23690
23787
|
}
|
|
23691
23788
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
23692
23789
|
try {
|
|
23693
|
-
const dir =
|
|
23790
|
+
const dir = path15.join(HISTORY_DIR, agentType);
|
|
23694
23791
|
if (!fs6.existsSync(dir)) return null;
|
|
23695
23792
|
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
23696
23793
|
for (const file of files) {
|
|
23697
|
-
const lines = fs6.readFileSync(
|
|
23794
|
+
const lines = fs6.readFileSync(path15.join(dir, file), "utf-8").split("\n").filter(Boolean);
|
|
23698
23795
|
for (const line of lines) {
|
|
23699
23796
|
try {
|
|
23700
23797
|
const parsed = JSON.parse(line);
|
|
@@ -23714,16 +23811,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
|
23714
23811
|
function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
23715
23812
|
if (records.length === 0) return false;
|
|
23716
23813
|
try {
|
|
23717
|
-
const dir =
|
|
23814
|
+
const dir = path15.join(HISTORY_DIR, agentType);
|
|
23718
23815
|
fs6.mkdirSync(dir, { recursive: true });
|
|
23719
23816
|
const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
23720
23817
|
for (const file of fs6.readdirSync(dir)) {
|
|
23721
23818
|
if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
|
|
23722
|
-
fs6.unlinkSync(
|
|
23819
|
+
fs6.unlinkSync(path15.join(dir, file));
|
|
23723
23820
|
}
|
|
23724
23821
|
}
|
|
23725
23822
|
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
23726
|
-
const filePath =
|
|
23823
|
+
const filePath = path15.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
23727
23824
|
fs6.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
|
|
23728
23825
|
`, "utf-8");
|
|
23729
23826
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
@@ -26328,7 +26425,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
|
|
|
26328
26425
|
// src/commands/chat-commands.ts
|
|
26329
26426
|
var fs7 = __toESM(require("fs"));
|
|
26330
26427
|
var os9 = __toESM(require("os"));
|
|
26331
|
-
var
|
|
26428
|
+
var path16 = __toESM(require("path"));
|
|
26332
26429
|
var import_node_crypto3 = require("crypto");
|
|
26333
26430
|
init_contracts();
|
|
26334
26431
|
init_logger();
|
|
@@ -27379,7 +27476,7 @@ function readExactRuntimeMirrorMessages(args) {
|
|
|
27379
27476
|
function normalizeComparableWorkspace(value) {
|
|
27380
27477
|
const text = typeof value === "string" ? value.trim() : "";
|
|
27381
27478
|
if (!text) return "";
|
|
27382
|
-
return
|
|
27479
|
+
return path16.resolve(text);
|
|
27383
27480
|
}
|
|
27384
27481
|
function isCurrentRuntimePtySafelyAttributed(args) {
|
|
27385
27482
|
if (args.adapter.cliType !== "codex-cli") return false;
|
|
@@ -27864,7 +27961,7 @@ function buildDebugBundleText(bundle) {
|
|
|
27864
27961
|
}
|
|
27865
27962
|
function getChatDebugBundleDir() {
|
|
27866
27963
|
const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
|
|
27867
|
-
return override ||
|
|
27964
|
+
return override || path16.join(os9.homedir(), ".adhdev", "debug-bundles", "chat");
|
|
27868
27965
|
}
|
|
27869
27966
|
function safeBundleIdSegment(value, fallback) {
|
|
27870
27967
|
const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
@@ -27921,7 +28018,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
|
|
|
27921
28018
|
const bundleId = createChatDebugBundleId(targetSessionId);
|
|
27922
28019
|
const dir = getChatDebugBundleDir();
|
|
27923
28020
|
fs7.mkdirSync(dir, { recursive: true });
|
|
27924
|
-
const savedPath =
|
|
28021
|
+
const savedPath = path16.join(dir, `${bundleId}.json`);
|
|
27925
28022
|
const json = `${JSON.stringify(bundle, null, 2)}
|
|
27926
28023
|
`;
|
|
27927
28024
|
fs7.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
|
|
@@ -29485,7 +29582,7 @@ async function handleResolveAction(h, args) {
|
|
|
29485
29582
|
|
|
29486
29583
|
// src/commands/cdp-commands.ts
|
|
29487
29584
|
var fs8 = __toESM(require("fs"));
|
|
29488
|
-
var
|
|
29585
|
+
var path17 = __toESM(require("path"));
|
|
29489
29586
|
var os10 = __toESM(require("os"));
|
|
29490
29587
|
var KEY_TO_VK = {
|
|
29491
29588
|
Backspace: 8,
|
|
@@ -29742,25 +29839,25 @@ function resolveSafePath(requestedPath) {
|
|
|
29742
29839
|
const inputPath = rawPath || ".";
|
|
29743
29840
|
const home = os10.homedir();
|
|
29744
29841
|
if (inputPath.startsWith("~")) {
|
|
29745
|
-
return
|
|
29842
|
+
return path17.resolve(path17.join(home, inputPath.slice(1)));
|
|
29746
29843
|
}
|
|
29747
29844
|
if (process.platform === "win32") {
|
|
29748
29845
|
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
29749
|
-
if (
|
|
29750
|
-
return
|
|
29846
|
+
if (path17.win32.isAbsolute(normalized)) {
|
|
29847
|
+
return path17.win32.normalize(normalized);
|
|
29751
29848
|
}
|
|
29752
|
-
return
|
|
29849
|
+
return path17.win32.resolve(normalized);
|
|
29753
29850
|
}
|
|
29754
|
-
if (
|
|
29755
|
-
return
|
|
29851
|
+
if (path17.isAbsolute(inputPath)) {
|
|
29852
|
+
return path17.normalize(inputPath);
|
|
29756
29853
|
}
|
|
29757
|
-
return
|
|
29854
|
+
return path17.resolve(inputPath);
|
|
29758
29855
|
}
|
|
29759
29856
|
function listDirectoryEntriesSafe(dirPath) {
|
|
29760
29857
|
const entries = fs8.readdirSync(dirPath, { withFileTypes: true });
|
|
29761
29858
|
const files = [];
|
|
29762
29859
|
for (const entry of entries) {
|
|
29763
|
-
const entryPath =
|
|
29860
|
+
const entryPath = path17.join(dirPath, entry.name);
|
|
29764
29861
|
try {
|
|
29765
29862
|
if (entry.isDirectory()) {
|
|
29766
29863
|
files.push({ name: entry.name, type: "directory" });
|
|
@@ -29814,7 +29911,7 @@ async function handleFileRead(h, args) {
|
|
|
29814
29911
|
async function handleFileWrite(h, args) {
|
|
29815
29912
|
try {
|
|
29816
29913
|
const filePath = resolveSafePath(args?.path);
|
|
29817
|
-
fs8.mkdirSync(
|
|
29914
|
+
fs8.mkdirSync(path17.dirname(filePath), { recursive: true });
|
|
29818
29915
|
fs8.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
29819
29916
|
return { success: true, path: filePath };
|
|
29820
29917
|
} catch (e) {
|
|
@@ -32598,6 +32695,7 @@ var fs13 = __toESM(require("fs"));
|
|
|
32598
32695
|
var os17 = __toESM(require("os"));
|
|
32599
32696
|
var path22 = __toESM(require("path"));
|
|
32600
32697
|
init_logger();
|
|
32698
|
+
init_load_better_sqlite3();
|
|
32601
32699
|
var UUID_RE = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
32602
32700
|
function executeNativeHistory(cfg, input) {
|
|
32603
32701
|
if (!cfg?.source) return null;
|
|
@@ -32722,7 +32820,7 @@ function executeSqlite(src, input) {
|
|
|
32722
32820
|
if (!resolved || !fs13.existsSync(resolved)) return null;
|
|
32723
32821
|
let Database;
|
|
32724
32822
|
try {
|
|
32725
|
-
Database =
|
|
32823
|
+
Database = loadBetterSqlite3();
|
|
32726
32824
|
} catch {
|
|
32727
32825
|
return null;
|
|
32728
32826
|
}
|
|
@@ -39546,6 +39644,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
39546
39644
|
var fs20 = __toESM(require("fs"));
|
|
39547
39645
|
var path30 = __toESM(require("path"));
|
|
39548
39646
|
var os21 = __toESM(require("os"));
|
|
39647
|
+
init_load_better_sqlite3();
|
|
39549
39648
|
var HERMES_STATE_DB = path30.join(os21.homedir(), ".hermes", "state.db");
|
|
39550
39649
|
var HERMES_LEGACY_SESSIONS_DIR = path30.join(os21.homedir(), ".hermes", "sessions");
|
|
39551
39650
|
function statMtimeMs4(p) {
|
|
@@ -39558,7 +39657,7 @@ function statMtimeMs4(p) {
|
|
|
39558
39657
|
function openDb() {
|
|
39559
39658
|
if (!fs20.existsSync(HERMES_STATE_DB)) return null;
|
|
39560
39659
|
try {
|
|
39561
|
-
const Database =
|
|
39660
|
+
const Database = loadBetterSqlite3();
|
|
39562
39661
|
return new Database(HERMES_STATE_DB, { readonly: true, fileMustExist: true });
|
|
39563
39662
|
} catch {
|
|
39564
39663
|
return null;
|
|
@@ -40933,8 +41032,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
40933
41032
|
return null;
|
|
40934
41033
|
}
|
|
40935
41034
|
registerProviderScriptRootSafely(path33.dirname(path33.dirname(providerDir)));
|
|
40936
|
-
const
|
|
40937
|
-
if (
|
|
41035
|
+
const cached3 = this.scriptsCache.get(dir);
|
|
41036
|
+
if (cached3) return cached3;
|
|
40938
41037
|
const scriptsJs = path33.join(dir, "scripts.js");
|
|
40939
41038
|
if (fs22.existsSync(scriptsJs)) {
|
|
40940
41039
|
try {
|
|
@@ -43620,6 +43719,7 @@ var import_os3 = require("os");
|
|
|
43620
43719
|
var import_path12 = require("path");
|
|
43621
43720
|
var fs26 = __toESM(require("fs"));
|
|
43622
43721
|
var import_node_child_process6 = require("child_process");
|
|
43722
|
+
init_resolve_executable();
|
|
43623
43723
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
43624
43724
|
var CHANNEL_SERVER_URL = {
|
|
43625
43725
|
stable: "https://api.adhf.dev",
|
|
@@ -44013,13 +44113,13 @@ function sanitizeInlineMesh(inlineMesh) {
|
|
|
44013
44113
|
nodes
|
|
44014
44114
|
};
|
|
44015
44115
|
}
|
|
44016
|
-
function reconcileInlineMeshCache(
|
|
44017
|
-
if (!
|
|
44018
|
-
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return
|
|
44019
|
-
const cachedNodes = Array.isArray(
|
|
44116
|
+
function reconcileInlineMeshCache(cached3, incoming) {
|
|
44117
|
+
if (!cached3 || typeof cached3 !== "object" || Array.isArray(cached3)) return incoming;
|
|
44118
|
+
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached3;
|
|
44119
|
+
const cachedNodes = Array.isArray(cached3.nodes) ? cached3.nodes : [];
|
|
44020
44120
|
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
44021
|
-
if (!cachedNodes.length || !incomingNodes.length) return { ...
|
|
44022
|
-
const cachedUpdatedAt = Date.parse(readStringValue(
|
|
44121
|
+
if (!cachedNodes.length || !incomingNodes.length) return { ...cached3, ...incoming };
|
|
44122
|
+
const cachedUpdatedAt = Date.parse(readStringValue(cached3.updatedAt, cached3.updated_at) || "");
|
|
44023
44123
|
const incomingUpdatedAt = Date.parse(readStringValue(incoming.updatedAt, incoming.updated_at) || "");
|
|
44024
44124
|
const preserveCachedMembership = Number.isFinite(cachedUpdatedAt) && (!Number.isFinite(incomingUpdatedAt) || cachedUpdatedAt > incomingUpdatedAt);
|
|
44025
44125
|
const cachedById = /* @__PURE__ */ new Map();
|
|
@@ -44048,7 +44148,7 @@ function reconcileInlineMeshCache(cached2, incoming) {
|
|
|
44048
44148
|
}
|
|
44049
44149
|
}
|
|
44050
44150
|
return {
|
|
44051
|
-
...
|
|
44151
|
+
...cached3,
|
|
44052
44152
|
...incoming,
|
|
44053
44153
|
nodes
|
|
44054
44154
|
};
|
|
@@ -44381,9 +44481,9 @@ var MeshGitProbeCache = class {
|
|
|
44381
44481
|
*/
|
|
44382
44482
|
async probe(daemonId, workspace, probe) {
|
|
44383
44483
|
const key = this.key(daemonId, workspace);
|
|
44384
|
-
const
|
|
44385
|
-
if (
|
|
44386
|
-
return
|
|
44484
|
+
const cached3 = this.recent.get(key);
|
|
44485
|
+
if (cached3 && this.now() - cached3.at < this.reuseMs) {
|
|
44486
|
+
return cached3.value;
|
|
44387
44487
|
}
|
|
44388
44488
|
const existing = this.inflight.get(key);
|
|
44389
44489
|
if (existing) return existing;
|
|
@@ -44718,6 +44818,18 @@ function truncateValidationOutput(value) {
|
|
|
44718
44818
|
return `${text.slice(0, REFINE_VALIDATION_SUMMARY_CHARS)}
|
|
44719
44819
|
[truncated ${text.length - REFINE_VALIDATION_SUMMARY_CHARS} chars]`;
|
|
44720
44820
|
}
|
|
44821
|
+
function isSpawnResolutionError(error) {
|
|
44822
|
+
if (!error) return false;
|
|
44823
|
+
if (error.code === "ENOENT" && typeof error.syscall === "string" && error.syscall.startsWith("spawn")) return true;
|
|
44824
|
+
return error.code === "ENOENT" && (error.syscall === void 0 || String(error.syscall).startsWith("spawn"));
|
|
44825
|
+
}
|
|
44826
|
+
function describeSpawnError(error, command, spawnResolutionFailed) {
|
|
44827
|
+
if (spawnResolutionFailed) {
|
|
44828
|
+
const hint = process.platform === "win32" ? " On Windows, npm-family commands (npm/npx/tsc/vitest) are .cmd shims that the bare-command spawn search does not resolve; configure an absolute path or ensure the command is on PATH." : "";
|
|
44829
|
+
return `Could not resolve executable "${command}" (spawn ENOENT).${hint}`;
|
|
44830
|
+
}
|
|
44831
|
+
return String(error?.message || error);
|
|
44832
|
+
}
|
|
44721
44833
|
function recordMeshRefineStage(stages, stage, status, startedAt, details) {
|
|
44722
44834
|
stages.push({
|
|
44723
44835
|
stage,
|
|
@@ -45619,8 +45731,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45619
45731
|
const startedAt = Date.now();
|
|
45620
45732
|
const cwd = candidate.cwd ? (0, import_path12.resolve)(workspace, candidate.cwd) : workspace;
|
|
45621
45733
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
45734
|
+
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
45622
45735
|
try {
|
|
45623
|
-
const result = await execFileAsync4(
|
|
45736
|
+
const result = await execFileAsync4(resolvedCommand, candidate.args, {
|
|
45624
45737
|
cwd,
|
|
45625
45738
|
encoding: "utf8",
|
|
45626
45739
|
timeout,
|
|
@@ -45629,16 +45742,17 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45629
45742
|
});
|
|
45630
45743
|
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
45631
45744
|
} catch (error) {
|
|
45745
|
+
const spawnResolutionFailed = isSpawnResolutionError(error);
|
|
45632
45746
|
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
|
|
45633
45747
|
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
45634
45748
|
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
45635
45749
|
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
45636
|
-
failureKind: "dependency_bootstrap_failed"
|
|
45750
|
+
...spawnResolutionFailed ? { failureKind: "spawn_resolution_failed", resolvedCommand } : { failureKind: "dependency_bootstrap_failed" }
|
|
45637
45751
|
}));
|
|
45638
|
-
summary.bootstrap = { stage: "failed", error:
|
|
45752
|
+
summary.bootstrap = { stage: "failed", error: describeSpawnError(error, candidate.command, spawnResolutionFailed) };
|
|
45639
45753
|
summary.status = "failed";
|
|
45640
|
-
summary.failureKind = "dependency_bootstrap_failed";
|
|
45641
|
-
summary.failureCode = "dependency_bootstrap_failed";
|
|
45754
|
+
summary.failureKind = spawnResolutionFailed ? "spawn_resolution_failed" : "dependency_bootstrap_failed";
|
|
45755
|
+
summary.failureCode = spawnResolutionFailed ? "spawn_resolution_failed" : "dependency_bootstrap_failed";
|
|
45642
45756
|
return summary;
|
|
45643
45757
|
}
|
|
45644
45758
|
}
|
|
@@ -45661,8 +45775,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45661
45775
|
summary.failureCode = "missing_dependencies";
|
|
45662
45776
|
return summary;
|
|
45663
45777
|
}
|
|
45778
|
+
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
45664
45779
|
try {
|
|
45665
|
-
const result = await execFileAsync4(
|
|
45780
|
+
const result = await execFileAsync4(resolvedCommand, candidate.args, {
|
|
45666
45781
|
cwd,
|
|
45667
45782
|
encoding: "utf8",
|
|
45668
45783
|
timeout,
|
|
@@ -45671,16 +45786,21 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45671
45786
|
});
|
|
45672
45787
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
45673
45788
|
} catch (error) {
|
|
45789
|
+
const spawnResolutionFailed = isSpawnResolutionError(error);
|
|
45674
45790
|
const stderr = truncateValidationOutput(error?.stderr || error?.message);
|
|
45675
|
-
const missingDependencyFailure = /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
|
|
45791
|
+
const missingDependencyFailure = !spawnResolutionFailed && /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
|
|
45676
45792
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
|
|
45677
45793
|
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
45678
45794
|
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
45679
45795
|
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
45680
|
-
...missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
|
|
45796
|
+
...spawnResolutionFailed ? { failureKind: "spawn_resolution_failed", resolvedCommand } : missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
|
|
45681
45797
|
}));
|
|
45682
45798
|
summary.status = "failed";
|
|
45683
|
-
if (
|
|
45799
|
+
if (spawnResolutionFailed) {
|
|
45800
|
+
summary.failureKind = "spawn_resolution_failed";
|
|
45801
|
+
summary.failureCode = "spawn_resolution_failed";
|
|
45802
|
+
summary.spawnResolutionError = describeSpawnError(error, candidate.command, true);
|
|
45803
|
+
} else if (missingDependencyFailure) {
|
|
45684
45804
|
summary.failureKind = "missing_dependencies";
|
|
45685
45805
|
summary.failureCode = "missing_dependencies";
|
|
45686
45806
|
}
|
|
@@ -46031,13 +46151,13 @@ var DaemonCommandRouter = class {
|
|
|
46031
46151
|
};
|
|
46032
46152
|
}
|
|
46033
46153
|
getCachedAggregateMeshStatus(meshId, mesh, options) {
|
|
46034
|
-
const
|
|
46035
|
-
if (!
|
|
46036
|
-
if (
|
|
46037
|
-
let snapshot = this.cloneJsonValue(
|
|
46154
|
+
const cached3 = this.aggregateMeshStatusCache.get(meshId);
|
|
46155
|
+
if (!cached3?.snapshot || cached3.snapshot.success !== true || !Array.isArray(cached3.snapshot.nodes)) return null;
|
|
46156
|
+
if (cached3.queueRevision !== getMeshQueueRevision(meshId)) return null;
|
|
46157
|
+
let snapshot = this.cloneJsonValue(cached3.snapshot);
|
|
46038
46158
|
snapshot = this.hydrateCachedAggregateMeshStatusFromInline(snapshot, mesh, options);
|
|
46039
46159
|
if (shouldRefreshStalePendingAggregate(snapshot, options)) return null;
|
|
46040
|
-
const ageMs = Math.max(0, Date.now() -
|
|
46160
|
+
const ageMs = Math.max(0, Date.now() - cached3.builtAt);
|
|
46041
46161
|
const sourceOfTruth = snapshot.sourceOfTruth && typeof snapshot.sourceOfTruth === "object" ? snapshot.sourceOfTruth : {};
|
|
46042
46162
|
snapshot.sourceOfTruth = {
|
|
46043
46163
|
...sourceOfTruth,
|
|
@@ -46048,7 +46168,7 @@ var DaemonCommandRouter = class {
|
|
|
46048
46168
|
source: "memory",
|
|
46049
46169
|
refreshReason: "memory_cache_hit",
|
|
46050
46170
|
ageMs,
|
|
46051
|
-
cachedAt: new Date(
|
|
46171
|
+
cachedAt: new Date(cached3.builtAt).toISOString(),
|
|
46052
46172
|
returnedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
46053
46173
|
}
|
|
46054
46174
|
};
|
|
@@ -46095,9 +46215,9 @@ var DaemonCommandRouter = class {
|
|
|
46095
46215
|
meshId,
|
|
46096
46216
|
sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh))
|
|
46097
46217
|
);
|
|
46098
|
-
const
|
|
46099
|
-
if (
|
|
46100
|
-
const merged = reconcileInlineMeshCache(
|
|
46218
|
+
const cached3 = this.inlineMeshCache.get(meshId);
|
|
46219
|
+
if (cached3) {
|
|
46220
|
+
const merged = reconcileInlineMeshCache(cached3, sanitizedInlineMesh);
|
|
46101
46221
|
this.inlineMeshCache.set(meshId, merged);
|
|
46102
46222
|
return merged;
|
|
46103
46223
|
}
|
|
@@ -46107,17 +46227,17 @@ var DaemonCommandRouter = class {
|
|
|
46107
46227
|
async getMeshForCommand(meshId, inlineMesh, options) {
|
|
46108
46228
|
const preferInline = options?.preferInline === true;
|
|
46109
46229
|
if (preferInline) {
|
|
46110
|
-
const
|
|
46111
|
-
if (
|
|
46230
|
+
const cached4 = this.getCachedInlineMesh(meshId);
|
|
46231
|
+
if (cached4) {
|
|
46112
46232
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
46113
46233
|
const merged = reconcileInlineMeshCache(
|
|
46114
|
-
|
|
46234
|
+
cached4,
|
|
46115
46235
|
this.applyInlineMeshNodeTombstones(meshId, inlineMesh)
|
|
46116
46236
|
);
|
|
46117
46237
|
this.inlineMeshCache.set(meshId, sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(merged)));
|
|
46118
46238
|
return { mesh: merged, inline: true, source: "inline_cache" };
|
|
46119
46239
|
}
|
|
46120
|
-
return { mesh:
|
|
46240
|
+
return { mesh: cached4, inline: true, source: "inline_cache" };
|
|
46121
46241
|
}
|
|
46122
46242
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
46123
46243
|
this.warmInlineMeshCache(meshId, inlineMesh);
|
|
@@ -46130,8 +46250,8 @@ var DaemonCommandRouter = class {
|
|
|
46130
46250
|
if (mesh) return { mesh, inline: false, source: "local_config" };
|
|
46131
46251
|
} catch {
|
|
46132
46252
|
}
|
|
46133
|
-
const
|
|
46134
|
-
if (
|
|
46253
|
+
const cached3 = this.getCachedInlineMesh(meshId);
|
|
46254
|
+
if (cached3) return { mesh: cached3, inline: true, source: "inline_cache" };
|
|
46135
46255
|
const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
|
|
46136
46256
|
return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
|
|
46137
46257
|
}
|
|
@@ -46941,7 +47061,7 @@ var DaemonCommandRouter = class {
|
|
|
46941
47061
|
if (validationSummary.status === "failed") {
|
|
46942
47062
|
const firstFailedCmd = Array.isArray(validationSummary.commandsRun) ? validationSummary.commandsRun.find((c) => c.success === false) : void 0;
|
|
46943
47063
|
const buildValidationFailedError = () => {
|
|
46944
|
-
const base = validationSummary.failureCode === "missing_dependencies" ? "Refinery validation dependencies are missing; merge/refine was not attempted. Configure validation.bootstrapCommands if Refinery should bootstrap dependencies before validation." : validationSummary.failureCode === "dependency_bootstrap_failed" ? "Refinery dependency/bootstrap command failed; merge/refine was not attempted." : "Refinery validation gate failed; merge/refine was not attempted.";
|
|
47064
|
+
const base = validationSummary.failureCode === "missing_dependencies" ? "Refinery validation dependencies are missing; merge/refine was not attempted. Configure validation.bootstrapCommands if Refinery should bootstrap dependencies before validation." : validationSummary.failureCode === "dependency_bootstrap_failed" ? "Refinery dependency/bootstrap command failed; merge/refine was not attempted." : validationSummary.failureCode === "spawn_resolution_failed" ? validationSummary.spawnResolutionError || "Refinery validation command could not be spawned (executable not found); merge/refine was not attempted." : "Refinery validation gate failed; merge/refine was not attempted.";
|
|
46945
47065
|
if (!firstFailedCmd) return base;
|
|
46946
47066
|
const cmdName = typeof firstFailedCmd.displayCommand === "string" ? firstFailedCmd.displayCommand : typeof firstFailedCmd.command === "string" ? [firstFailedCmd.command, ...Array.isArray(firstFailedCmd.args) ? firstFailedCmd.args : []].join(" ").trim() : typeof firstFailedCmd.cmd === "string" ? firstFailedCmd.cmd : "";
|
|
46947
47067
|
const rawOutput = [firstFailedCmd.stdout, firstFailedCmd.stderr, firstFailedCmd.output].filter((s) => typeof s === "string" && s.length > 0).join("\n");
|
|
@@ -47561,8 +47681,8 @@ ${hintLines.join("\n")}` : "",
|
|
|
47561
47681
|
const repoRootBaseRef = /* @__PURE__ */ new Map();
|
|
47562
47682
|
const submodulePathsByRepoRoot = /* @__PURE__ */ new Map();
|
|
47563
47683
|
const resolveBaseRef = async (repoRoot) => {
|
|
47564
|
-
const
|
|
47565
|
-
if (
|
|
47684
|
+
const cached3 = repoRootBaseRef.get(repoRoot);
|
|
47685
|
+
if (cached3) return cached3;
|
|
47566
47686
|
let baseBranch = "main";
|
|
47567
47687
|
try {
|
|
47568
47688
|
const { stdout } = await execFileAsync4("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
|