@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.mjs
CHANGED
|
@@ -311,10 +311,10 @@ function readInjected(value) {
|
|
|
311
311
|
}
|
|
312
312
|
function getDaemonBuildInfo() {
|
|
313
313
|
if (cached) return cached;
|
|
314
|
-
const commit = readInjected(true ? "
|
|
315
|
-
const commitShort = readInjected(true ? "
|
|
316
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
317
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
314
|
+
const commit = readInjected(true ? "9e5ae5d2814077a6bf9e982b17066ca2051da97b" : void 0) ?? "unknown";
|
|
315
|
+
const commitShort = readInjected(true ? "9e5ae5d2" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
316
|
+
const version = readInjected(true ? "0.9.82-rc.334" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
317
|
+
const builtAt = readInjected(true ? "2026-06-20T03:55:49.426Z" : void 0);
|
|
318
318
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
319
319
|
return cached;
|
|
320
320
|
}
|
|
@@ -582,10 +582,10 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
582
582
|
} catch (error) {
|
|
583
583
|
const gitError = error instanceof GitCommandError ? error : new GitCommandError("git_command_failed", "Failed to read Git status", { cause: error });
|
|
584
584
|
if (isTransientGitFailure(gitError)) {
|
|
585
|
-
const
|
|
586
|
-
if (
|
|
585
|
+
const cached3 = lastKnownGoodStatus.get(workspace);
|
|
586
|
+
if (cached3) {
|
|
587
587
|
return {
|
|
588
|
-
...
|
|
588
|
+
...cached3,
|
|
589
589
|
lastCheckedAt,
|
|
590
590
|
upstreamStatus: "unavailable",
|
|
591
591
|
error: gitError.stderr || gitError.message,
|
|
@@ -708,9 +708,9 @@ function resolveChangeImpactConfigForRepo(repoRoot, options) {
|
|
|
708
708
|
return { config: null, sourceKey: "no-repo-root" };
|
|
709
709
|
}
|
|
710
710
|
const loaded = loadChangeImpactConfig(repoRoot);
|
|
711
|
-
const
|
|
712
|
-
if (
|
|
713
|
-
return { config:
|
|
711
|
+
const cached3 = changeImpactConfigCache.get(repoRoot);
|
|
712
|
+
if (cached3 && cached3.sourceKey === loaded.sourceKey) {
|
|
713
|
+
return { config: cached3.config, sourceKey: loaded.sourceKey };
|
|
714
714
|
}
|
|
715
715
|
const config = loaded.sourceType === "repo_file" ? loaded.config ?? null : null;
|
|
716
716
|
changeImpactConfigCache.set(repoRoot, { sourceKey: loaded.sourceKey, config });
|
|
@@ -2536,6 +2536,46 @@ Follow these recovery rules:
|
|
|
2536
2536
|
}
|
|
2537
2537
|
});
|
|
2538
2538
|
|
|
2539
|
+
// src/system/load-better-sqlite3.ts
|
|
2540
|
+
import { createRequire } from "module";
|
|
2541
|
+
function loadBetterSqlite3() {
|
|
2542
|
+
if (cached2) return cached2;
|
|
2543
|
+
const errors = [];
|
|
2544
|
+
if (typeof __require === "function") {
|
|
2545
|
+
try {
|
|
2546
|
+
cached2 = __require("better-sqlite3");
|
|
2547
|
+
return cached2;
|
|
2548
|
+
} catch (e) {
|
|
2549
|
+
errors.push(e);
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
try {
|
|
2553
|
+
const metaUrl = typeof import.meta?.url === "string" ? import.meta.url : void 0;
|
|
2554
|
+
if (metaUrl) {
|
|
2555
|
+
cached2 = createRequire(metaUrl)("better-sqlite3");
|
|
2556
|
+
return cached2;
|
|
2557
|
+
}
|
|
2558
|
+
} catch (e) {
|
|
2559
|
+
errors.push(e);
|
|
2560
|
+
}
|
|
2561
|
+
try {
|
|
2562
|
+
cached2 = createRequire(`${process.cwd()}/__adhdev_better_sqlite3_loader__.js`)(
|
|
2563
|
+
"better-sqlite3"
|
|
2564
|
+
);
|
|
2565
|
+
return cached2;
|
|
2566
|
+
} catch (e) {
|
|
2567
|
+
errors.push(e);
|
|
2568
|
+
}
|
|
2569
|
+
const detail = errors.map((e) => e instanceof Error ? e.message : String(e)).join("; ");
|
|
2570
|
+
throw new Error(`Failed to load better-sqlite3: ${detail}`);
|
|
2571
|
+
}
|
|
2572
|
+
var cached2;
|
|
2573
|
+
var init_load_better_sqlite3 = __esm({
|
|
2574
|
+
"src/system/load-better-sqlite3.ts"() {
|
|
2575
|
+
"use strict";
|
|
2576
|
+
}
|
|
2577
|
+
});
|
|
2578
|
+
|
|
2539
2579
|
// src/mesh/mesh-ledger.ts
|
|
2540
2580
|
var mesh_ledger_exports = {};
|
|
2541
2581
|
__export(mesh_ledger_exports, {
|
|
@@ -2969,8 +3009,8 @@ function readLedgerFromStore(meshId) {
|
|
|
2969
3009
|
}
|
|
2970
3010
|
function getCachedRawEntries(meshId) {
|
|
2971
3011
|
const now = Date.now();
|
|
2972
|
-
const
|
|
2973
|
-
if (
|
|
3012
|
+
const cached3 = ledgerReadCache.get(meshId);
|
|
3013
|
+
if (cached3 && now - cached3.cachedAt < LEDGER_CACHE_TTL_MS) return cached3.entries;
|
|
2974
3014
|
let entries;
|
|
2975
3015
|
try {
|
|
2976
3016
|
entries = readLedgerFromStore(meshId);
|
|
@@ -3214,6 +3254,297 @@ var init_mesh_ledger = __esm({
|
|
|
3214
3254
|
}
|
|
3215
3255
|
});
|
|
3216
3256
|
|
|
3257
|
+
// src/logging/async-batch-writer.ts
|
|
3258
|
+
import * as fs3 from "fs";
|
|
3259
|
+
var AsyncBatchWriter;
|
|
3260
|
+
var init_async_batch_writer = __esm({
|
|
3261
|
+
"src/logging/async-batch-writer.ts"() {
|
|
3262
|
+
"use strict";
|
|
3263
|
+
AsyncBatchWriter = class {
|
|
3264
|
+
// Maps filePath -> string buffer
|
|
3265
|
+
static buffers = /* @__PURE__ */ new Map();
|
|
3266
|
+
static writePromises = /* @__PURE__ */ new Map();
|
|
3267
|
+
static flushTimer = null;
|
|
3268
|
+
/**
|
|
3269
|
+
* Queues data to be written to a file asynchronously in a batch.
|
|
3270
|
+
*/
|
|
3271
|
+
static write(filePath, data) {
|
|
3272
|
+
let buf = this.buffers.get(filePath);
|
|
3273
|
+
if (!buf) {
|
|
3274
|
+
buf = [];
|
|
3275
|
+
this.buffers.set(filePath, buf);
|
|
3276
|
+
}
|
|
3277
|
+
buf.push(data);
|
|
3278
|
+
if (!this.flushTimer) {
|
|
3279
|
+
this.flushTimer = setTimeout(() => {
|
|
3280
|
+
this.flushTimer = null;
|
|
3281
|
+
this.flushAll();
|
|
3282
|
+
}, 50);
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
static async flushAll() {
|
|
3286
|
+
const entries = Array.from(this.buffers.entries());
|
|
3287
|
+
this.buffers.clear();
|
|
3288
|
+
for (const [filePath, buffer] of entries) {
|
|
3289
|
+
const dataToWrite = buffer.join("");
|
|
3290
|
+
const doWrite = async () => {
|
|
3291
|
+
try {
|
|
3292
|
+
const prevPromise = this.writePromises.get(filePath);
|
|
3293
|
+
if (prevPromise) await prevPromise;
|
|
3294
|
+
await fs3.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
|
|
3295
|
+
} catch {
|
|
3296
|
+
}
|
|
3297
|
+
};
|
|
3298
|
+
const writePromise = doWrite();
|
|
3299
|
+
this.writePromises.set(filePath, writePromise);
|
|
3300
|
+
writePromise.finally(() => {
|
|
3301
|
+
if (this.writePromises.get(filePath) === writePromise) {
|
|
3302
|
+
this.writePromises.delete(filePath);
|
|
3303
|
+
}
|
|
3304
|
+
});
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
};
|
|
3308
|
+
}
|
|
3309
|
+
});
|
|
3310
|
+
|
|
3311
|
+
// src/logging/logger.ts
|
|
3312
|
+
var logger_exports = {};
|
|
3313
|
+
__export(logger_exports, {
|
|
3314
|
+
LOG: () => LOG,
|
|
3315
|
+
LOG_DIR_PATH: () => LOG_DIR_PATH,
|
|
3316
|
+
LOG_PATH: () => LOG_PATH,
|
|
3317
|
+
daemonLog: () => daemonLog,
|
|
3318
|
+
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
3319
|
+
getDaemonLogDir: () => getDaemonLogDir,
|
|
3320
|
+
getLogBufferSize: () => getLogBufferSize,
|
|
3321
|
+
getLogLevel: () => getLogLevel,
|
|
3322
|
+
getLogPath: () => getLogPath,
|
|
3323
|
+
getRecentLogs: () => getRecentLogs,
|
|
3324
|
+
installGlobalInterceptor: () => installGlobalInterceptor,
|
|
3325
|
+
setLogLevel: () => setLogLevel
|
|
3326
|
+
});
|
|
3327
|
+
import * as fs4 from "fs";
|
|
3328
|
+
import * as path9 from "path";
|
|
3329
|
+
import * as os3 from "os";
|
|
3330
|
+
function setLogLevel(level) {
|
|
3331
|
+
currentLevel = level;
|
|
3332
|
+
daemonLog("Logger", `Log level set to: ${level}`, "info");
|
|
3333
|
+
}
|
|
3334
|
+
function getLogLevel() {
|
|
3335
|
+
return currentLevel;
|
|
3336
|
+
}
|
|
3337
|
+
function getDateStr() {
|
|
3338
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3339
|
+
}
|
|
3340
|
+
function getDaemonLogDir() {
|
|
3341
|
+
return LOG_DIR;
|
|
3342
|
+
}
|
|
3343
|
+
function getCurrentDaemonLogPath(date = /* @__PURE__ */ new Date()) {
|
|
3344
|
+
return path9.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
|
|
3345
|
+
}
|
|
3346
|
+
function checkDateRotation() {
|
|
3347
|
+
const today = getDateStr();
|
|
3348
|
+
if (today !== currentDate) {
|
|
3349
|
+
currentDate = today;
|
|
3350
|
+
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
3351
|
+
cleanOldLogs();
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
function cleanOldLogs() {
|
|
3355
|
+
try {
|
|
3356
|
+
const files = fs4.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
|
|
3357
|
+
const cutoff = /* @__PURE__ */ new Date();
|
|
3358
|
+
cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
|
|
3359
|
+
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
3360
|
+
for (const file of files) {
|
|
3361
|
+
const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
3362
|
+
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
3363
|
+
try {
|
|
3364
|
+
fs4.unlinkSync(path9.join(LOG_DIR, file));
|
|
3365
|
+
} catch {
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
} catch {
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
function rotateSizeIfNeeded() {
|
|
3373
|
+
try {
|
|
3374
|
+
const stat2 = fs4.statSync(currentLogFile);
|
|
3375
|
+
if (stat2.size > MAX_LOG_SIZE) {
|
|
3376
|
+
const backup = currentLogFile.replace(".log", ".1.log");
|
|
3377
|
+
try {
|
|
3378
|
+
fs4.unlinkSync(backup);
|
|
3379
|
+
} catch {
|
|
3380
|
+
}
|
|
3381
|
+
fs4.renameSync(currentLogFile, backup);
|
|
3382
|
+
}
|
|
3383
|
+
} catch {
|
|
3384
|
+
}
|
|
3385
|
+
}
|
|
3386
|
+
function writeToFile(line) {
|
|
3387
|
+
try {
|
|
3388
|
+
if (++writeCount % 1e3 === 0) {
|
|
3389
|
+
checkDateRotation();
|
|
3390
|
+
rotateSizeIfNeeded();
|
|
3391
|
+
}
|
|
3392
|
+
AsyncBatchWriter.write(currentLogFile, line + "\n");
|
|
3393
|
+
} catch {
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
3396
|
+
function getRecentLogs(count = 50, minLevel = "info") {
|
|
3397
|
+
const minNum = LEVEL_NUM[minLevel];
|
|
3398
|
+
const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
|
|
3399
|
+
return filtered.slice(-count);
|
|
3400
|
+
}
|
|
3401
|
+
function getLogBufferSize() {
|
|
3402
|
+
return ringBuffer.length;
|
|
3403
|
+
}
|
|
3404
|
+
function ts() {
|
|
3405
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
3406
|
+
}
|
|
3407
|
+
function fullTs() {
|
|
3408
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3409
|
+
}
|
|
3410
|
+
function daemonLog(category, msg, level = "info") {
|
|
3411
|
+
const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
|
|
3412
|
+
const label = LEVEL_LABEL[level];
|
|
3413
|
+
const line = `[${ts()}] [${label}] [${category}] ${msg}`;
|
|
3414
|
+
if (!shouldOutput) return;
|
|
3415
|
+
writeToFile(line);
|
|
3416
|
+
ringBuffer.push({ ts: Date.now(), level, category, message: msg });
|
|
3417
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3418
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3419
|
+
}
|
|
3420
|
+
origConsoleLog(line);
|
|
3421
|
+
}
|
|
3422
|
+
function installGlobalInterceptor() {
|
|
3423
|
+
if (interceptorInstalled) return;
|
|
3424
|
+
interceptorInstalled = true;
|
|
3425
|
+
const stripAnsi4 = (str) => str.replace(/\x1B\[[0-9;]*m/g, "");
|
|
3426
|
+
const isDaemonLogLine = (msg) => /\[(DBG|INF|WRN|ERR)\]/.test(msg);
|
|
3427
|
+
console.log = (...args) => {
|
|
3428
|
+
origConsoleLog(...args);
|
|
3429
|
+
try {
|
|
3430
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
3431
|
+
const clean = stripAnsi4(msg);
|
|
3432
|
+
if (isDaemonLogLine(clean)) return;
|
|
3433
|
+
const line = clean.startsWith("[20") ? clean : `[${fullTs()}] ${clean}`;
|
|
3434
|
+
writeToFile(line);
|
|
3435
|
+
const catMatch = clean.match(/\[([^\]]+)\]/);
|
|
3436
|
+
ringBuffer.push({
|
|
3437
|
+
ts: Date.now(),
|
|
3438
|
+
level: "info",
|
|
3439
|
+
category: catMatch?.[1] || "System",
|
|
3440
|
+
message: clean
|
|
3441
|
+
});
|
|
3442
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3443
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3444
|
+
}
|
|
3445
|
+
} catch {
|
|
3446
|
+
}
|
|
3447
|
+
};
|
|
3448
|
+
console.error = (...args) => {
|
|
3449
|
+
origConsoleError(...args);
|
|
3450
|
+
try {
|
|
3451
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
3452
|
+
const clean = stripAnsi4(msg);
|
|
3453
|
+
if (isDaemonLogLine(clean)) return;
|
|
3454
|
+
const line = `[${fullTs()}] [ERROR] ${clean}`;
|
|
3455
|
+
writeToFile(line);
|
|
3456
|
+
ringBuffer.push({ ts: Date.now(), level: "error", category: "System", message: clean });
|
|
3457
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3458
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3459
|
+
}
|
|
3460
|
+
} catch {
|
|
3461
|
+
}
|
|
3462
|
+
};
|
|
3463
|
+
console.warn = (...args) => {
|
|
3464
|
+
origConsoleWarn(...args);
|
|
3465
|
+
try {
|
|
3466
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
3467
|
+
const clean = stripAnsi4(msg);
|
|
3468
|
+
if (isDaemonLogLine(clean)) return;
|
|
3469
|
+
const line = `[${fullTs()}] [WARN] ${clean}`;
|
|
3470
|
+
writeToFile(line);
|
|
3471
|
+
ringBuffer.push({ ts: Date.now(), level: "warn", category: "System", message: clean });
|
|
3472
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3473
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3474
|
+
}
|
|
3475
|
+
} catch {
|
|
3476
|
+
}
|
|
3477
|
+
};
|
|
3478
|
+
writeToFile(`
|
|
3479
|
+
=== ADHDev Daemon started at ${fullTs()} ===`);
|
|
3480
|
+
writeToFile(`Log file: ${currentLogFile}`);
|
|
3481
|
+
writeToFile(`Log level: ${currentLevel}`);
|
|
3482
|
+
}
|
|
3483
|
+
function getLogPath() {
|
|
3484
|
+
return currentLogFile;
|
|
3485
|
+
}
|
|
3486
|
+
var 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;
|
|
3487
|
+
var init_logger = __esm({
|
|
3488
|
+
"src/logging/logger.ts"() {
|
|
3489
|
+
"use strict";
|
|
3490
|
+
init_async_batch_writer();
|
|
3491
|
+
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
3492
|
+
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
3493
|
+
currentLevel = "info";
|
|
3494
|
+
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");
|
|
3495
|
+
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
3496
|
+
MAX_LOG_DAYS = 7;
|
|
3497
|
+
try {
|
|
3498
|
+
fs4.mkdirSync(LOG_DIR, { recursive: true });
|
|
3499
|
+
} catch {
|
|
3500
|
+
}
|
|
3501
|
+
currentDate = getDateStr();
|
|
3502
|
+
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
3503
|
+
cleanOldLogs();
|
|
3504
|
+
try {
|
|
3505
|
+
const oldLog = path9.join(LOG_DIR, "daemon.log");
|
|
3506
|
+
if (fs4.existsSync(oldLog)) {
|
|
3507
|
+
const stat2 = fs4.statSync(oldLog);
|
|
3508
|
+
const oldDate = stat2.mtime.toISOString().slice(0, 10);
|
|
3509
|
+
fs4.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
3510
|
+
}
|
|
3511
|
+
const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
|
|
3512
|
+
if (fs4.existsSync(oldLogBackup)) {
|
|
3513
|
+
fs4.unlinkSync(oldLogBackup);
|
|
3514
|
+
}
|
|
3515
|
+
} catch {
|
|
3516
|
+
}
|
|
3517
|
+
writeCount = 0;
|
|
3518
|
+
RING_BUFFER_SIZE = 200;
|
|
3519
|
+
ringBuffer = [];
|
|
3520
|
+
origConsoleLog = console.log.bind(console);
|
|
3521
|
+
origConsoleError = console.error.bind(console);
|
|
3522
|
+
origConsoleWarn = console.warn.bind(console);
|
|
3523
|
+
LOG = {
|
|
3524
|
+
debug: (category, msg) => daemonLog(category, msg, "debug"),
|
|
3525
|
+
info: (category, msg) => daemonLog(category, msg, "info"),
|
|
3526
|
+
warn: (category, msg) => daemonLog(category, msg, "warn"),
|
|
3527
|
+
error: (category, msg) => daemonLog(category, msg, "error"),
|
|
3528
|
+
/**
|
|
3529
|
+
* Create a scoped logger for a specific component.
|
|
3530
|
+
* Category is baked in so callers only pass the message.
|
|
3531
|
+
*/
|
|
3532
|
+
forComponent(category) {
|
|
3533
|
+
return {
|
|
3534
|
+
debug: (msg) => daemonLog(category, msg, "debug"),
|
|
3535
|
+
info: (msg) => daemonLog(category, msg, "info"),
|
|
3536
|
+
warn: (msg) => daemonLog(category, msg, "warn"),
|
|
3537
|
+
error: (msg) => daemonLog(category, msg, "error"),
|
|
3538
|
+
asLogFn: (level = "info") => (msg) => daemonLog(category, msg, level)
|
|
3539
|
+
};
|
|
3540
|
+
}
|
|
3541
|
+
};
|
|
3542
|
+
interceptorInstalled = false;
|
|
3543
|
+
LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
3544
|
+
LOG_DIR_PATH = LOG_DIR;
|
|
3545
|
+
}
|
|
3546
|
+
});
|
|
3547
|
+
|
|
3217
3548
|
// src/mesh/mesh-work-queue.ts
|
|
3218
3549
|
var mesh_work_queue_exports = {};
|
|
3219
3550
|
__export(mesh_work_queue_exports, {
|
|
@@ -3679,11 +4010,18 @@ function requeueTask(meshId, taskId, opts) {
|
|
|
3679
4010
|
}
|
|
3680
4011
|
function updateSessionTaskStatus(meshId, sessionId, status, opts) {
|
|
3681
4012
|
return withQueueLock(meshId, () => {
|
|
4013
|
+
const store = MeshRuntimeStore.getInstance();
|
|
3682
4014
|
const occurredAtIso = opts?.occurredAt ? new Date(opts.occurredAt).toISOString() : void 0;
|
|
3683
|
-
const entry =
|
|
3684
|
-
if (!entry)
|
|
4015
|
+
const entry = store.findAssignedBySession(meshId, sessionId, occurredAtIso, opts?.taskId);
|
|
4016
|
+
if (!entry) {
|
|
4017
|
+
const assignedRows = store.getActiveAssignmentDetails(meshId).filter((r) => r.sessionId === sessionId);
|
|
4018
|
+
if (assignedRows.length > 0) {
|
|
4019
|
+
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(",")}`);
|
|
4020
|
+
}
|
|
4021
|
+
return null;
|
|
4022
|
+
}
|
|
3685
4023
|
entry.status = status;
|
|
3686
|
-
|
|
4024
|
+
store.updateQueueEntry(entry);
|
|
3687
4025
|
if (DEPENDENCY_FAILURE_TERMINALS.has(status)) propagateDependencyFailure(meshId, entry.id);
|
|
3688
4026
|
return entry;
|
|
3689
4027
|
});
|
|
@@ -3791,6 +4129,7 @@ var init_mesh_work_queue = __esm({
|
|
|
3791
4129
|
init_repo_mesh_types();
|
|
3792
4130
|
init_mesh_runtime_store();
|
|
3793
4131
|
init_mesh_config();
|
|
4132
|
+
init_logger();
|
|
3794
4133
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
3795
4134
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
3796
4135
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -3847,33 +4186,31 @@ var init_mesh_work_queue = __esm({
|
|
|
3847
4186
|
});
|
|
3848
4187
|
|
|
3849
4188
|
// src/mesh/mesh-runtime-store.ts
|
|
3850
|
-
import { existsSync as
|
|
3851
|
-
import { dirname as dirname2, join as
|
|
3852
|
-
import { createRequire } from "module";
|
|
4189
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, statSync as statSync5 } from "fs";
|
|
4190
|
+
import { dirname as dirname2, join as join9 } from "path";
|
|
3853
4191
|
function loadDatabaseCtor() {
|
|
3854
4192
|
if (DatabaseCtor) return DatabaseCtor;
|
|
3855
|
-
|
|
3856
|
-
DatabaseCtor = runtimeRequire("better-sqlite3");
|
|
4193
|
+
DatabaseCtor = loadBetterSqlite3();
|
|
3857
4194
|
return DatabaseCtor;
|
|
3858
4195
|
}
|
|
3859
4196
|
function safeMeshId(meshId) {
|
|
3860
4197
|
return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3861
4198
|
}
|
|
3862
4199
|
function legacyQueuePath(meshId) {
|
|
3863
|
-
return
|
|
4200
|
+
return join9(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
|
|
3864
4201
|
}
|
|
3865
4202
|
function meshRuntimeStorePath() {
|
|
3866
4203
|
const dir = getLedgerDir();
|
|
3867
|
-
const nextPath =
|
|
3868
|
-
if (
|
|
3869
|
-
const legacyPath =
|
|
3870
|
-
if (!
|
|
4204
|
+
const nextPath = join9(dir, "mesh-runtime.db");
|
|
4205
|
+
if (existsSync8(nextPath)) return nextPath;
|
|
4206
|
+
const legacyPath = join9(dir, "beads.db");
|
|
4207
|
+
if (!existsSync8(legacyPath)) return nextPath;
|
|
3871
4208
|
try {
|
|
3872
|
-
|
|
4209
|
+
renameSync3(legacyPath, nextPath);
|
|
3873
4210
|
for (const suffix of ["-wal", "-shm"]) {
|
|
3874
4211
|
const legacyCompanion = `${legacyPath}${suffix}`;
|
|
3875
|
-
if (
|
|
3876
|
-
|
|
4212
|
+
if (existsSync8(legacyCompanion)) {
|
|
4213
|
+
renameSync3(legacyCompanion, `${nextPath}${suffix}`);
|
|
3877
4214
|
}
|
|
3878
4215
|
}
|
|
3879
4216
|
} catch {
|
|
@@ -3884,6 +4221,7 @@ var DatabaseCtor, MeshRuntimeStore;
|
|
|
3884
4221
|
var init_mesh_runtime_store = __esm({
|
|
3885
4222
|
"src/mesh/mesh-runtime-store.ts"() {
|
|
3886
4223
|
"use strict";
|
|
4224
|
+
init_load_better_sqlite3();
|
|
3887
4225
|
init_mesh_ledger();
|
|
3888
4226
|
init_mesh_work_queue();
|
|
3889
4227
|
MeshRuntimeStore = class _MeshRuntimeStore {
|
|
@@ -3898,7 +4236,7 @@ var init_mesh_runtime_store = __esm({
|
|
|
3898
4236
|
// 50 MB
|
|
3899
4237
|
constructor(dbPath) {
|
|
3900
4238
|
const dir = dirname2(dbPath);
|
|
3901
|
-
if (!
|
|
4239
|
+
if (!existsSync8(dir)) mkdirSync5(dir, { recursive: true });
|
|
3902
4240
|
this.dbPath = dbPath;
|
|
3903
4241
|
this.db = new (loadDatabaseCtor())(dbPath);
|
|
3904
4242
|
this.db.pragma("journal_mode = WAL");
|
|
@@ -4153,8 +4491,8 @@ var init_mesh_runtime_store = __esm({
|
|
|
4153
4491
|
this.walWriteCounter = 0;
|
|
4154
4492
|
try {
|
|
4155
4493
|
const walPath = `${this.dbPath}-wal`;
|
|
4156
|
-
if (!
|
|
4157
|
-
const size =
|
|
4494
|
+
if (!existsSync8(walPath)) return;
|
|
4495
|
+
const size = statSync5(walPath).size;
|
|
4158
4496
|
if (size < _MeshRuntimeStore.WAL_MAX_BYTES) return;
|
|
4159
4497
|
process.stderr.write(
|
|
4160
4498
|
`[adhdev-mesh] WAL file ${Math.round(size / 1024 / 1024)}MB exceeds threshold; forcing checkpoint
|
|
@@ -4170,7 +4508,7 @@ var init_mesh_runtime_store = __esm({
|
|
|
4170
4508
|
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
4171
4509
|
if (count.count > 0) return;
|
|
4172
4510
|
const path42 = legacyQueuePath(meshId);
|
|
4173
|
-
if (!
|
|
4511
|
+
if (!existsSync8(path42)) return;
|
|
4174
4512
|
try {
|
|
4175
4513
|
const entries = JSON.parse(readFileSync6(path42, "utf-8"));
|
|
4176
4514
|
if (!Array.isArray(entries)) return;
|
|
@@ -4450,12 +4788,51 @@ var init_mesh_runtime_store = __esm({
|
|
|
4450
4788
|
return { id, nodeId: r.assigned_node_id ?? void 0, sessionId: r.assigned_session_id ?? void 0, message };
|
|
4451
4789
|
});
|
|
4452
4790
|
}
|
|
4453
|
-
|
|
4791
|
+
/**
|
|
4792
|
+
* Resolve the `assigned` queue row a completion event belongs to.
|
|
4793
|
+
*
|
|
4794
|
+
* Clock-skew safety (C2): a completion event's `occurredAtIso` carries the
|
|
4795
|
+
* REMOTE WORKER's clock, while `updated_at` carries the COORDINATOR's clock
|
|
4796
|
+
* (set at assignment and re-bumped on every mutation). For a remote node,
|
|
4797
|
+
* coordinator-clock > worker-clock skew used to make an `updated_at <= occurredAt`
|
|
4798
|
+
* filter return nothing, stranding the finished task as `assigned` forever.
|
|
4799
|
+
*
|
|
4800
|
+
* We therefore NEVER filter completion-matching on the mutable `updated_at`:
|
|
4801
|
+
* 1. If `taskId` is given, match the exact `assigned` row by id (no time filter).
|
|
4802
|
+
* 2. Otherwise a session holds at most one `assigned` task — match it without a
|
|
4803
|
+
* time filter. If several exist (shouldn't normally), disambiguate by the
|
|
4804
|
+
* IMMUTABLE `dispatchTimestamp`: latest `dispatchTimestamp <= occurredAt`,
|
|
4805
|
+
* and if skew makes ALL of them later than `occurredAt`, fall back to the
|
|
4806
|
+
* most-recent `dispatchTimestamp` rather than returning null.
|
|
4807
|
+
*/
|
|
4808
|
+
findAssignedBySession(meshId, sessionId, occurredAtIso, taskId) {
|
|
4454
4809
|
this.ensureLegacyQueueMigrated(meshId);
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4810
|
+
if (taskId) {
|
|
4811
|
+
const row = this.db.prepare(
|
|
4812
|
+
`SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned' AND id = ? LIMIT 1`
|
|
4813
|
+
).get(meshId, sessionId, taskId);
|
|
4814
|
+
if (row) return JSON.parse(row.payload);
|
|
4815
|
+
}
|
|
4816
|
+
const rows = this.db.prepare(
|
|
4817
|
+
`SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned'`
|
|
4818
|
+
).all(meshId, sessionId);
|
|
4819
|
+
if (rows.length === 0) return null;
|
|
4820
|
+
const entries = rows.map((r) => {
|
|
4821
|
+
try {
|
|
4822
|
+
return JSON.parse(r.payload);
|
|
4823
|
+
} catch {
|
|
4824
|
+
return null;
|
|
4825
|
+
}
|
|
4826
|
+
}).filter((e) => e !== null);
|
|
4827
|
+
if (entries.length === 0) return null;
|
|
4828
|
+
if (entries.length === 1) return entries[0];
|
|
4829
|
+
const orderKey = (e) => e.dispatchTimestamp ?? e.updatedAt ?? "";
|
|
4830
|
+
const byDispatchDesc = [...entries].sort((a, b) => orderKey(b).localeCompare(orderKey(a)));
|
|
4831
|
+
if (occurredAtIso) {
|
|
4832
|
+
const atOrBefore = byDispatchDesc.find((e) => orderKey(e) <= occurredAtIso);
|
|
4833
|
+
if (atOrBefore) return atOrBefore;
|
|
4834
|
+
}
|
|
4835
|
+
return byDispatchDesc[0];
|
|
4459
4836
|
}
|
|
4460
4837
|
toRow(entry) {
|
|
4461
4838
|
return {
|
|
@@ -5711,297 +6088,6 @@ var init_mesh_review_inbox = __esm({
|
|
|
5711
6088
|
}
|
|
5712
6089
|
});
|
|
5713
6090
|
|
|
5714
|
-
// src/logging/async-batch-writer.ts
|
|
5715
|
-
import * as fs3 from "fs";
|
|
5716
|
-
var AsyncBatchWriter;
|
|
5717
|
-
var init_async_batch_writer = __esm({
|
|
5718
|
-
"src/logging/async-batch-writer.ts"() {
|
|
5719
|
-
"use strict";
|
|
5720
|
-
AsyncBatchWriter = class {
|
|
5721
|
-
// Maps filePath -> string buffer
|
|
5722
|
-
static buffers = /* @__PURE__ */ new Map();
|
|
5723
|
-
static writePromises = /* @__PURE__ */ new Map();
|
|
5724
|
-
static flushTimer = null;
|
|
5725
|
-
/**
|
|
5726
|
-
* Queues data to be written to a file asynchronously in a batch.
|
|
5727
|
-
*/
|
|
5728
|
-
static write(filePath, data) {
|
|
5729
|
-
let buf = this.buffers.get(filePath);
|
|
5730
|
-
if (!buf) {
|
|
5731
|
-
buf = [];
|
|
5732
|
-
this.buffers.set(filePath, buf);
|
|
5733
|
-
}
|
|
5734
|
-
buf.push(data);
|
|
5735
|
-
if (!this.flushTimer) {
|
|
5736
|
-
this.flushTimer = setTimeout(() => {
|
|
5737
|
-
this.flushTimer = null;
|
|
5738
|
-
this.flushAll();
|
|
5739
|
-
}, 50);
|
|
5740
|
-
}
|
|
5741
|
-
}
|
|
5742
|
-
static async flushAll() {
|
|
5743
|
-
const entries = Array.from(this.buffers.entries());
|
|
5744
|
-
this.buffers.clear();
|
|
5745
|
-
for (const [filePath, buffer] of entries) {
|
|
5746
|
-
const dataToWrite = buffer.join("");
|
|
5747
|
-
const doWrite = async () => {
|
|
5748
|
-
try {
|
|
5749
|
-
const prevPromise = this.writePromises.get(filePath);
|
|
5750
|
-
if (prevPromise) await prevPromise;
|
|
5751
|
-
await fs3.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
|
|
5752
|
-
} catch {
|
|
5753
|
-
}
|
|
5754
|
-
};
|
|
5755
|
-
const writePromise = doWrite();
|
|
5756
|
-
this.writePromises.set(filePath, writePromise);
|
|
5757
|
-
writePromise.finally(() => {
|
|
5758
|
-
if (this.writePromises.get(filePath) === writePromise) {
|
|
5759
|
-
this.writePromises.delete(filePath);
|
|
5760
|
-
}
|
|
5761
|
-
});
|
|
5762
|
-
}
|
|
5763
|
-
}
|
|
5764
|
-
};
|
|
5765
|
-
}
|
|
5766
|
-
});
|
|
5767
|
-
|
|
5768
|
-
// src/logging/logger.ts
|
|
5769
|
-
var logger_exports = {};
|
|
5770
|
-
__export(logger_exports, {
|
|
5771
|
-
LOG: () => LOG,
|
|
5772
|
-
LOG_DIR_PATH: () => LOG_DIR_PATH,
|
|
5773
|
-
LOG_PATH: () => LOG_PATH,
|
|
5774
|
-
daemonLog: () => daemonLog,
|
|
5775
|
-
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
5776
|
-
getDaemonLogDir: () => getDaemonLogDir,
|
|
5777
|
-
getLogBufferSize: () => getLogBufferSize,
|
|
5778
|
-
getLogLevel: () => getLogLevel,
|
|
5779
|
-
getLogPath: () => getLogPath,
|
|
5780
|
-
getRecentLogs: () => getRecentLogs,
|
|
5781
|
-
installGlobalInterceptor: () => installGlobalInterceptor,
|
|
5782
|
-
setLogLevel: () => setLogLevel
|
|
5783
|
-
});
|
|
5784
|
-
import * as fs4 from "fs";
|
|
5785
|
-
import * as path9 from "path";
|
|
5786
|
-
import * as os3 from "os";
|
|
5787
|
-
function setLogLevel(level) {
|
|
5788
|
-
currentLevel = level;
|
|
5789
|
-
daemonLog("Logger", `Log level set to: ${level}`, "info");
|
|
5790
|
-
}
|
|
5791
|
-
function getLogLevel() {
|
|
5792
|
-
return currentLevel;
|
|
5793
|
-
}
|
|
5794
|
-
function getDateStr() {
|
|
5795
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5796
|
-
}
|
|
5797
|
-
function getDaemonLogDir() {
|
|
5798
|
-
return LOG_DIR;
|
|
5799
|
-
}
|
|
5800
|
-
function getCurrentDaemonLogPath(date = /* @__PURE__ */ new Date()) {
|
|
5801
|
-
return path9.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
|
|
5802
|
-
}
|
|
5803
|
-
function checkDateRotation() {
|
|
5804
|
-
const today = getDateStr();
|
|
5805
|
-
if (today !== currentDate) {
|
|
5806
|
-
currentDate = today;
|
|
5807
|
-
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
5808
|
-
cleanOldLogs();
|
|
5809
|
-
}
|
|
5810
|
-
}
|
|
5811
|
-
function cleanOldLogs() {
|
|
5812
|
-
try {
|
|
5813
|
-
const files = fs4.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
|
|
5814
|
-
const cutoff = /* @__PURE__ */ new Date();
|
|
5815
|
-
cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
|
|
5816
|
-
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
5817
|
-
for (const file of files) {
|
|
5818
|
-
const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
5819
|
-
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
5820
|
-
try {
|
|
5821
|
-
fs4.unlinkSync(path9.join(LOG_DIR, file));
|
|
5822
|
-
} catch {
|
|
5823
|
-
}
|
|
5824
|
-
}
|
|
5825
|
-
}
|
|
5826
|
-
} catch {
|
|
5827
|
-
}
|
|
5828
|
-
}
|
|
5829
|
-
function rotateSizeIfNeeded() {
|
|
5830
|
-
try {
|
|
5831
|
-
const stat2 = fs4.statSync(currentLogFile);
|
|
5832
|
-
if (stat2.size > MAX_LOG_SIZE) {
|
|
5833
|
-
const backup = currentLogFile.replace(".log", ".1.log");
|
|
5834
|
-
try {
|
|
5835
|
-
fs4.unlinkSync(backup);
|
|
5836
|
-
} catch {
|
|
5837
|
-
}
|
|
5838
|
-
fs4.renameSync(currentLogFile, backup);
|
|
5839
|
-
}
|
|
5840
|
-
} catch {
|
|
5841
|
-
}
|
|
5842
|
-
}
|
|
5843
|
-
function writeToFile(line) {
|
|
5844
|
-
try {
|
|
5845
|
-
if (++writeCount % 1e3 === 0) {
|
|
5846
|
-
checkDateRotation();
|
|
5847
|
-
rotateSizeIfNeeded();
|
|
5848
|
-
}
|
|
5849
|
-
AsyncBatchWriter.write(currentLogFile, line + "\n");
|
|
5850
|
-
} catch {
|
|
5851
|
-
}
|
|
5852
|
-
}
|
|
5853
|
-
function getRecentLogs(count = 50, minLevel = "info") {
|
|
5854
|
-
const minNum = LEVEL_NUM[minLevel];
|
|
5855
|
-
const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
|
|
5856
|
-
return filtered.slice(-count);
|
|
5857
|
-
}
|
|
5858
|
-
function getLogBufferSize() {
|
|
5859
|
-
return ringBuffer.length;
|
|
5860
|
-
}
|
|
5861
|
-
function ts() {
|
|
5862
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
5863
|
-
}
|
|
5864
|
-
function fullTs() {
|
|
5865
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
5866
|
-
}
|
|
5867
|
-
function daemonLog(category, msg, level = "info") {
|
|
5868
|
-
const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
|
|
5869
|
-
const label = LEVEL_LABEL[level];
|
|
5870
|
-
const line = `[${ts()}] [${label}] [${category}] ${msg}`;
|
|
5871
|
-
if (!shouldOutput) return;
|
|
5872
|
-
writeToFile(line);
|
|
5873
|
-
ringBuffer.push({ ts: Date.now(), level, category, message: msg });
|
|
5874
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5875
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5876
|
-
}
|
|
5877
|
-
origConsoleLog(line);
|
|
5878
|
-
}
|
|
5879
|
-
function installGlobalInterceptor() {
|
|
5880
|
-
if (interceptorInstalled) return;
|
|
5881
|
-
interceptorInstalled = true;
|
|
5882
|
-
const stripAnsi4 = (str) => str.replace(/\x1B\[[0-9;]*m/g, "");
|
|
5883
|
-
const isDaemonLogLine = (msg) => /\[(DBG|INF|WRN|ERR)\]/.test(msg);
|
|
5884
|
-
console.log = (...args) => {
|
|
5885
|
-
origConsoleLog(...args);
|
|
5886
|
-
try {
|
|
5887
|
-
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
5888
|
-
const clean = stripAnsi4(msg);
|
|
5889
|
-
if (isDaemonLogLine(clean)) return;
|
|
5890
|
-
const line = clean.startsWith("[20") ? clean : `[${fullTs()}] ${clean}`;
|
|
5891
|
-
writeToFile(line);
|
|
5892
|
-
const catMatch = clean.match(/\[([^\]]+)\]/);
|
|
5893
|
-
ringBuffer.push({
|
|
5894
|
-
ts: Date.now(),
|
|
5895
|
-
level: "info",
|
|
5896
|
-
category: catMatch?.[1] || "System",
|
|
5897
|
-
message: clean
|
|
5898
|
-
});
|
|
5899
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5900
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5901
|
-
}
|
|
5902
|
-
} catch {
|
|
5903
|
-
}
|
|
5904
|
-
};
|
|
5905
|
-
console.error = (...args) => {
|
|
5906
|
-
origConsoleError(...args);
|
|
5907
|
-
try {
|
|
5908
|
-
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
5909
|
-
const clean = stripAnsi4(msg);
|
|
5910
|
-
if (isDaemonLogLine(clean)) return;
|
|
5911
|
-
const line = `[${fullTs()}] [ERROR] ${clean}`;
|
|
5912
|
-
writeToFile(line);
|
|
5913
|
-
ringBuffer.push({ ts: Date.now(), level: "error", category: "System", message: clean });
|
|
5914
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5915
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5916
|
-
}
|
|
5917
|
-
} catch {
|
|
5918
|
-
}
|
|
5919
|
-
};
|
|
5920
|
-
console.warn = (...args) => {
|
|
5921
|
-
origConsoleWarn(...args);
|
|
5922
|
-
try {
|
|
5923
|
-
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
5924
|
-
const clean = stripAnsi4(msg);
|
|
5925
|
-
if (isDaemonLogLine(clean)) return;
|
|
5926
|
-
const line = `[${fullTs()}] [WARN] ${clean}`;
|
|
5927
|
-
writeToFile(line);
|
|
5928
|
-
ringBuffer.push({ ts: Date.now(), level: "warn", category: "System", message: clean });
|
|
5929
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5930
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5931
|
-
}
|
|
5932
|
-
} catch {
|
|
5933
|
-
}
|
|
5934
|
-
};
|
|
5935
|
-
writeToFile(`
|
|
5936
|
-
=== ADHDev Daemon started at ${fullTs()} ===`);
|
|
5937
|
-
writeToFile(`Log file: ${currentLogFile}`);
|
|
5938
|
-
writeToFile(`Log level: ${currentLevel}`);
|
|
5939
|
-
}
|
|
5940
|
-
function getLogPath() {
|
|
5941
|
-
return currentLogFile;
|
|
5942
|
-
}
|
|
5943
|
-
var 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;
|
|
5944
|
-
var init_logger = __esm({
|
|
5945
|
-
"src/logging/logger.ts"() {
|
|
5946
|
-
"use strict";
|
|
5947
|
-
init_async_batch_writer();
|
|
5948
|
-
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
5949
|
-
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
5950
|
-
currentLevel = "info";
|
|
5951
|
-
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");
|
|
5952
|
-
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
5953
|
-
MAX_LOG_DAYS = 7;
|
|
5954
|
-
try {
|
|
5955
|
-
fs4.mkdirSync(LOG_DIR, { recursive: true });
|
|
5956
|
-
} catch {
|
|
5957
|
-
}
|
|
5958
|
-
currentDate = getDateStr();
|
|
5959
|
-
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
5960
|
-
cleanOldLogs();
|
|
5961
|
-
try {
|
|
5962
|
-
const oldLog = path9.join(LOG_DIR, "daemon.log");
|
|
5963
|
-
if (fs4.existsSync(oldLog)) {
|
|
5964
|
-
const stat2 = fs4.statSync(oldLog);
|
|
5965
|
-
const oldDate = stat2.mtime.toISOString().slice(0, 10);
|
|
5966
|
-
fs4.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
5967
|
-
}
|
|
5968
|
-
const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
|
|
5969
|
-
if (fs4.existsSync(oldLogBackup)) {
|
|
5970
|
-
fs4.unlinkSync(oldLogBackup);
|
|
5971
|
-
}
|
|
5972
|
-
} catch {
|
|
5973
|
-
}
|
|
5974
|
-
writeCount = 0;
|
|
5975
|
-
RING_BUFFER_SIZE = 200;
|
|
5976
|
-
ringBuffer = [];
|
|
5977
|
-
origConsoleLog = console.log.bind(console);
|
|
5978
|
-
origConsoleError = console.error.bind(console);
|
|
5979
|
-
origConsoleWarn = console.warn.bind(console);
|
|
5980
|
-
LOG = {
|
|
5981
|
-
debug: (category, msg) => daemonLog(category, msg, "debug"),
|
|
5982
|
-
info: (category, msg) => daemonLog(category, msg, "info"),
|
|
5983
|
-
warn: (category, msg) => daemonLog(category, msg, "warn"),
|
|
5984
|
-
error: (category, msg) => daemonLog(category, msg, "error"),
|
|
5985
|
-
/**
|
|
5986
|
-
* Create a scoped logger for a specific component.
|
|
5987
|
-
* Category is baked in so callers only pass the message.
|
|
5988
|
-
*/
|
|
5989
|
-
forComponent(category) {
|
|
5990
|
-
return {
|
|
5991
|
-
debug: (msg) => daemonLog(category, msg, "debug"),
|
|
5992
|
-
info: (msg) => daemonLog(category, msg, "info"),
|
|
5993
|
-
warn: (msg) => daemonLog(category, msg, "warn"),
|
|
5994
|
-
error: (msg) => daemonLog(category, msg, "error"),
|
|
5995
|
-
asLogFn: (level = "info") => (msg) => daemonLog(category, msg, level)
|
|
5996
|
-
};
|
|
5997
|
-
}
|
|
5998
|
-
};
|
|
5999
|
-
interceptorInstalled = false;
|
|
6000
|
-
LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
6001
|
-
LOG_DIR_PATH = LOG_DIR;
|
|
6002
|
-
}
|
|
6003
|
-
});
|
|
6004
|
-
|
|
6005
6091
|
// src/commands/mesh-coordinator.ts
|
|
6006
6092
|
var mesh_coordinator_exports = {};
|
|
6007
6093
|
__export(mesh_coordinator_exports, {
|
|
@@ -6403,6 +6489,59 @@ var init_mesh_coordinator = __esm({
|
|
|
6403
6489
|
}
|
|
6404
6490
|
});
|
|
6405
6491
|
|
|
6492
|
+
// src/cli-adapters/resolve-executable.ts
|
|
6493
|
+
import { execFileSync } from "child_process";
|
|
6494
|
+
import { existsSync as existsSync12 } from "fs";
|
|
6495
|
+
import * as path10 from "path";
|
|
6496
|
+
function resolveWin32GlobalBin(trimmed) {
|
|
6497
|
+
if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
|
|
6498
|
+
return null;
|
|
6499
|
+
}
|
|
6500
|
+
const extraDirs = [];
|
|
6501
|
+
if (process.env.APPDATA) extraDirs.push(path10.join(process.env.APPDATA, "npm"));
|
|
6502
|
+
try {
|
|
6503
|
+
extraDirs.push(path10.dirname(process.execPath));
|
|
6504
|
+
} catch {
|
|
6505
|
+
}
|
|
6506
|
+
for (const dir of extraDirs) {
|
|
6507
|
+
if (!dir) continue;
|
|
6508
|
+
for (const ext of WIN_EXEC_EXT) {
|
|
6509
|
+
const full = path10.join(dir, trimmed + ext);
|
|
6510
|
+
if (existsSync12(full)) return full;
|
|
6511
|
+
}
|
|
6512
|
+
}
|
|
6513
|
+
return null;
|
|
6514
|
+
}
|
|
6515
|
+
function resolveWin32Executable(command) {
|
|
6516
|
+
if (process.platform !== "win32") return command;
|
|
6517
|
+
const trimmed = (command || "").trim();
|
|
6518
|
+
if (!trimmed) return command;
|
|
6519
|
+
if (path10.isAbsolute(trimmed) && existsSync12(trimmed)) return trimmed;
|
|
6520
|
+
try {
|
|
6521
|
+
const out = execFileSync("where", [trimmed], {
|
|
6522
|
+
encoding: "utf8",
|
|
6523
|
+
windowsHide: true
|
|
6524
|
+
}).trim();
|
|
6525
|
+
if (out) {
|
|
6526
|
+
const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
6527
|
+
const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path10.extname(m).toLowerCase()));
|
|
6528
|
+
return direct || matches[0] || command;
|
|
6529
|
+
}
|
|
6530
|
+
} catch {
|
|
6531
|
+
}
|
|
6532
|
+
const globalBin = resolveWin32GlobalBin(trimmed);
|
|
6533
|
+
if (globalBin) return globalBin;
|
|
6534
|
+
return command;
|
|
6535
|
+
}
|
|
6536
|
+
var DIRECT_EXEC_EXT, WIN_EXEC_EXT;
|
|
6537
|
+
var init_resolve_executable = __esm({
|
|
6538
|
+
"src/cli-adapters/resolve-executable.ts"() {
|
|
6539
|
+
"use strict";
|
|
6540
|
+
DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
|
|
6541
|
+
WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
|
|
6542
|
+
}
|
|
6543
|
+
});
|
|
6544
|
+
|
|
6406
6545
|
// src/mesh/mesh-fast-forward.ts
|
|
6407
6546
|
async function fastForwardMeshNode(args) {
|
|
6408
6547
|
const workspace = typeof args.workspace === "string" ? args.workspace.trim() : "";
|
|
@@ -7854,8 +7993,8 @@ var init_mesh_events_utils = __esm({
|
|
|
7854
7993
|
});
|
|
7855
7994
|
|
|
7856
7995
|
// src/mesh/mesh-events-pending.ts
|
|
7857
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
7858
|
-
import { join as
|
|
7996
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync14, readFileSync as readFileSync11, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
7997
|
+
import { join as join15 } from "path";
|
|
7859
7998
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
7860
7999
|
function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
|
|
7861
8000
|
const raw = Array.isArray(coordinatorDaemonId) ? coordinatorDaemonId : coordinatorDaemonId != null ? [coordinatorDaemonId] : [];
|
|
@@ -7918,9 +8057,9 @@ function getPendingEventsPath(meshId, coordinatorDaemonId) {
|
|
|
7918
8057
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7919
8058
|
if (coordinatorDaemonId) {
|
|
7920
8059
|
const safeDaemon = coordinatorDaemonId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7921
|
-
return
|
|
8060
|
+
return join15(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
|
|
7922
8061
|
}
|
|
7923
|
-
return
|
|
8062
|
+
return join15(getLedgerDir(), `${safe}.pending-events.jsonl`);
|
|
7924
8063
|
}
|
|
7925
8064
|
function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
7926
8065
|
if (!meshId) return [];
|
|
@@ -7929,7 +8068,7 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
7929
8068
|
const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
7930
8069
|
const events = [];
|
|
7931
8070
|
for (const path42 of paths) {
|
|
7932
|
-
if (!
|
|
8071
|
+
if (!existsSync14(path42)) continue;
|
|
7933
8072
|
try {
|
|
7934
8073
|
const raw = readFileSync11(path42, "utf-8");
|
|
7935
8074
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
@@ -8006,7 +8145,7 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
8006
8145
|
}
|
|
8007
8146
|
function trimPendingEventsIfNeeded(path42) {
|
|
8008
8147
|
try {
|
|
8009
|
-
if (!
|
|
8148
|
+
if (!existsSync14(path42)) return;
|
|
8010
8149
|
if (statSync6(path42).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
8011
8150
|
const lines = readFileSync11(path42, "utf-8").split("\n").filter(Boolean);
|
|
8012
8151
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
@@ -8108,7 +8247,7 @@ function selectiveDrainFile(path42, predicate) {
|
|
|
8108
8247
|
unlinkSync2(tmpPath);
|
|
8109
8248
|
} catch {
|
|
8110
8249
|
try {
|
|
8111
|
-
if (
|
|
8250
|
+
if (existsSync14(tmpPath) && !existsSync14(path42)) renameSync4(tmpPath, path42);
|
|
8112
8251
|
} catch {
|
|
8113
8252
|
}
|
|
8114
8253
|
return [];
|
|
@@ -8202,7 +8341,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
8202
8341
|
}
|
|
8203
8342
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
8204
8343
|
for (const path42 of paths) {
|
|
8205
|
-
if (
|
|
8344
|
+
if (existsSync14(path42)) try {
|
|
8206
8345
|
unlinkSync2(path42);
|
|
8207
8346
|
} catch {
|
|
8208
8347
|
}
|
|
@@ -8633,7 +8772,7 @@ var init_spawn_env = __esm({
|
|
|
8633
8772
|
|
|
8634
8773
|
// src/cli-adapters/provider-cli-shared.ts
|
|
8635
8774
|
import * as os5 from "os";
|
|
8636
|
-
import * as
|
|
8775
|
+
import * as path11 from "path";
|
|
8637
8776
|
function stripAnsi(str) {
|
|
8638
8777
|
return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
8639
8778
|
}
|
|
@@ -8709,24 +8848,24 @@ function buildCliScreenSnapshot(text) {
|
|
|
8709
8848
|
function findBinary(name) {
|
|
8710
8849
|
const trimmed = String(name || "").trim();
|
|
8711
8850
|
if (!trimmed) return trimmed;
|
|
8712
|
-
const expanded = trimmed.startsWith("~") ?
|
|
8713
|
-
if (
|
|
8714
|
-
return
|
|
8851
|
+
const expanded = trimmed.startsWith("~") ? path11.join(os5.homedir(), trimmed.slice(1)) : trimmed;
|
|
8852
|
+
if (path11.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
8853
|
+
return path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
|
|
8715
8854
|
}
|
|
8716
8855
|
const isWin = os5.platform() === "win32";
|
|
8717
|
-
const paths = (process.env.PATH || "").split(
|
|
8856
|
+
const paths = (process.env.PATH || "").split(path11.delimiter);
|
|
8718
8857
|
const extraDirs = [];
|
|
8719
8858
|
if (isWin) {
|
|
8720
|
-
if (process.env.APPDATA) extraDirs.push(
|
|
8859
|
+
if (process.env.APPDATA) extraDirs.push(path11.join(process.env.APPDATA, "npm"));
|
|
8721
8860
|
try {
|
|
8722
|
-
extraDirs.push(
|
|
8861
|
+
extraDirs.push(path11.dirname(process.execPath));
|
|
8723
8862
|
} catch {
|
|
8724
8863
|
}
|
|
8725
8864
|
} else {
|
|
8726
|
-
extraDirs.push(
|
|
8865
|
+
extraDirs.push(path11.join(os5.homedir(), ".npm-global", "bin"));
|
|
8727
8866
|
extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
|
|
8728
8867
|
try {
|
|
8729
|
-
extraDirs.push(
|
|
8868
|
+
extraDirs.push(path11.dirname(process.execPath));
|
|
8730
8869
|
} catch {
|
|
8731
8870
|
}
|
|
8732
8871
|
}
|
|
@@ -8735,7 +8874,7 @@ function findBinary(name) {
|
|
|
8735
8874
|
for (const p of searchDirs) {
|
|
8736
8875
|
if (!p) continue;
|
|
8737
8876
|
for (const ext of exes) {
|
|
8738
|
-
const fullPath =
|
|
8877
|
+
const fullPath = path11.join(p, trimmed + ext);
|
|
8739
8878
|
try {
|
|
8740
8879
|
const fs32 = __require("fs");
|
|
8741
8880
|
if (fs32.existsSync(fullPath)) {
|
|
@@ -8751,7 +8890,7 @@ function findBinary(name) {
|
|
|
8751
8890
|
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
8752
8891
|
}
|
|
8753
8892
|
function isScriptBinary(binaryPath) {
|
|
8754
|
-
if (!
|
|
8893
|
+
if (!path11.isAbsolute(binaryPath)) return false;
|
|
8755
8894
|
try {
|
|
8756
8895
|
const fs32 = __require("fs");
|
|
8757
8896
|
const resolved = fs32.realpathSync(binaryPath);
|
|
@@ -8767,7 +8906,7 @@ function isScriptBinary(binaryPath) {
|
|
|
8767
8906
|
}
|
|
8768
8907
|
}
|
|
8769
8908
|
function looksLikeMachOOrElf(filePath) {
|
|
8770
|
-
if (!
|
|
8909
|
+
if (!path11.isAbsolute(filePath)) return false;
|
|
8771
8910
|
try {
|
|
8772
8911
|
const fs32 = __require("fs");
|
|
8773
8912
|
const resolved = fs32.realpathSync(filePath);
|
|
@@ -9024,8 +9163,8 @@ var init_provider_cli_shared = __esm({
|
|
|
9024
9163
|
// src/detection/cli-detector.ts
|
|
9025
9164
|
import { exec } from "child_process";
|
|
9026
9165
|
import * as os6 from "os";
|
|
9027
|
-
import * as
|
|
9028
|
-
import { existsSync as
|
|
9166
|
+
import * as path12 from "path";
|
|
9167
|
+
import { existsSync as existsSync15 } from "fs";
|
|
9029
9168
|
function parseVersion(raw) {
|
|
9030
9169
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
9031
9170
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
@@ -9037,19 +9176,19 @@ function shellQuote(value) {
|
|
|
9037
9176
|
function expandHome(value) {
|
|
9038
9177
|
const trimmed = value.trim();
|
|
9039
9178
|
if (!trimmed.startsWith("~")) return trimmed;
|
|
9040
|
-
return
|
|
9179
|
+
return path12.join(os6.homedir(), trimmed.slice(1));
|
|
9041
9180
|
}
|
|
9042
9181
|
function isExplicitCommandPath(command) {
|
|
9043
9182
|
const trimmed = command.trim();
|
|
9044
|
-
return
|
|
9183
|
+
return path12.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
9045
9184
|
}
|
|
9046
9185
|
function resolveCommandPath(command) {
|
|
9047
9186
|
const trimmed = command.trim();
|
|
9048
9187
|
if (!trimmed) return null;
|
|
9049
9188
|
if (isExplicitCommandPath(trimmed)) {
|
|
9050
9189
|
const expanded = expandHome(trimmed);
|
|
9051
|
-
const candidate =
|
|
9052
|
-
return
|
|
9190
|
+
const candidate = path12.isAbsolute(expanded) ? expanded : path12.resolve(expanded);
|
|
9191
|
+
return existsSync15(candidate) ? candidate : null;
|
|
9053
9192
|
}
|
|
9054
9193
|
return null;
|
|
9055
9194
|
}
|
|
@@ -9059,7 +9198,7 @@ async function resolveDetectionPath(command, whichCmd) {
|
|
|
9059
9198
|
const whichResult = await execAsync(`${whichCmd} ${shellQuote(command)}`);
|
|
9060
9199
|
if (whichResult) return whichResult.split("\n")[0];
|
|
9061
9200
|
const resolved = findBinary(command);
|
|
9062
|
-
if (
|
|
9201
|
+
if (path12.isAbsolute(resolved) && existsSync15(resolved)) return resolved;
|
|
9063
9202
|
return null;
|
|
9064
9203
|
}
|
|
9065
9204
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
@@ -9404,7 +9543,7 @@ var init_mesh_unresolved_forward_outbox = __esm({
|
|
|
9404
9543
|
});
|
|
9405
9544
|
|
|
9406
9545
|
// src/mesh/mesh-events-coordinator.ts
|
|
9407
|
-
import { existsSync as
|
|
9546
|
+
import { existsSync as existsSync16 } from "fs";
|
|
9408
9547
|
function resolveCoordinatorDrainDaemonIds(components) {
|
|
9409
9548
|
const ids = /* @__PURE__ */ new Set();
|
|
9410
9549
|
const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
|
|
@@ -9415,8 +9554,8 @@ function resolveCoordinatorDrainDaemonIds(components) {
|
|
|
9415
9554
|
}
|
|
9416
9555
|
function getCachedMeshByWorkspace(workspace) {
|
|
9417
9556
|
const now = Date.now();
|
|
9418
|
-
const
|
|
9419
|
-
if (
|
|
9557
|
+
const cached3 = meshByWorkspaceCache.get(workspace);
|
|
9558
|
+
if (cached3 && now - cached3.cachedAt < MESH_WORKSPACE_CACHE_TTL_MS) return cached3.mesh;
|
|
9420
9559
|
const mesh = getMeshByRepo(workspace);
|
|
9421
9560
|
meshByWorkspaceCache.set(workspace, { mesh, cachedAt: now });
|
|
9422
9561
|
return mesh;
|
|
@@ -10192,7 +10331,7 @@ async function maybeAutoFastForwardIdleNode(components, args) {
|
|
|
10192
10331
|
const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
|
|
10193
10332
|
const workspace = readNonEmptyString2(node?.workspace);
|
|
10194
10333
|
if (!workspace) return;
|
|
10195
|
-
if (!
|
|
10334
|
+
if (!existsSync16(workspace)) return;
|
|
10196
10335
|
const policy = resolveAutoFastForwardPolicy(mesh);
|
|
10197
10336
|
if (!policy.enabled) return;
|
|
10198
10337
|
if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId, args.sessionId)) return;
|
|
@@ -10391,8 +10530,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
10391
10530
|
}
|
|
10392
10531
|
}
|
|
10393
10532
|
function markSessionTerminal(sessionId, outcome, occurredAtMs) {
|
|
10533
|
+
const eventTaskId = readNonEmptyString2(args.metadataEvent.taskId) || void 0;
|
|
10394
10534
|
const task = updateSessionTaskStatus(args.meshId, sessionId, outcome, {
|
|
10395
|
-
occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0
|
|
10535
|
+
occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0,
|
|
10536
|
+
taskId: eventTaskId
|
|
10396
10537
|
});
|
|
10397
10538
|
updateDirectDispatchStatus(args.meshId, sessionId, outcome);
|
|
10398
10539
|
markSessionDeliveriesTerminal(args.meshId, sessionId, outcome);
|
|
@@ -12689,18 +12830,18 @@ __export(external_sources_exports, {
|
|
|
12689
12830
|
});
|
|
12690
12831
|
import * as fs9 from "fs";
|
|
12691
12832
|
import * as os11 from "os";
|
|
12692
|
-
import * as
|
|
12833
|
+
import * as path18 from "path";
|
|
12693
12834
|
function adhdevDir() {
|
|
12694
|
-
return
|
|
12835
|
+
return path18.join(os11.homedir(), ".adhdev");
|
|
12695
12836
|
}
|
|
12696
12837
|
function externalRoot() {
|
|
12697
|
-
return
|
|
12838
|
+
return path18.join(adhdevDir(), "external");
|
|
12698
12839
|
}
|
|
12699
12840
|
function sourcesFilePath() {
|
|
12700
|
-
return
|
|
12841
|
+
return path18.join(adhdevDir(), SOURCES_FILENAME);
|
|
12701
12842
|
}
|
|
12702
12843
|
function activeFilePath() {
|
|
12703
|
-
return
|
|
12844
|
+
return path18.join(adhdevDir(), ACTIVE_FILENAME);
|
|
12704
12845
|
}
|
|
12705
12846
|
function ensureAdhdevDir() {
|
|
12706
12847
|
const d = adhdevDir();
|
|
@@ -12767,7 +12908,7 @@ function inventoryExternalSources() {
|
|
|
12767
12908
|
for (const sourceEntry of entries) {
|
|
12768
12909
|
if (!sourceEntry.isDirectory()) continue;
|
|
12769
12910
|
const sourceName = sourceEntry.name;
|
|
12770
|
-
const sourceDir =
|
|
12911
|
+
const sourceDir = path18.join(root, sourceName);
|
|
12771
12912
|
const providers = {};
|
|
12772
12913
|
let categoryEntries;
|
|
12773
12914
|
try {
|
|
@@ -12778,7 +12919,7 @@ function inventoryExternalSources() {
|
|
|
12778
12919
|
for (const categoryEntry of categoryEntries) {
|
|
12779
12920
|
if (!categoryEntry.isDirectory()) continue;
|
|
12780
12921
|
const category = categoryEntry.name;
|
|
12781
|
-
const categoryDir =
|
|
12922
|
+
const categoryDir = path18.join(sourceDir, category);
|
|
12782
12923
|
let typeEntries;
|
|
12783
12924
|
try {
|
|
12784
12925
|
typeEntries = fs9.readdirSync(categoryDir, { withFileTypes: true });
|
|
@@ -12788,9 +12929,9 @@ function inventoryExternalSources() {
|
|
|
12788
12929
|
const types = [];
|
|
12789
12930
|
for (const typeEntry of typeEntries) {
|
|
12790
12931
|
if (!typeEntry.isDirectory()) continue;
|
|
12791
|
-
const typeDir =
|
|
12792
|
-
const hasV1 = fs9.existsSync(
|
|
12793
|
-
const hasV0 = fs9.existsSync(
|
|
12932
|
+
const typeDir = path18.join(categoryDir, typeEntry.name);
|
|
12933
|
+
const hasV1 = fs9.existsSync(path18.join(typeDir, "provider.v1.json"));
|
|
12934
|
+
const hasV0 = fs9.existsSync(path18.join(typeDir, "provider.json"));
|
|
12794
12935
|
if (hasV1 || hasV0) types.push(typeEntry.name);
|
|
12795
12936
|
}
|
|
12796
12937
|
if (types.length > 0) providers[category] = types;
|
|
@@ -12994,59 +13135,6 @@ var init_terminal_screen = __esm({
|
|
|
12994
13135
|
}
|
|
12995
13136
|
});
|
|
12996
13137
|
|
|
12997
|
-
// src/cli-adapters/resolve-executable.ts
|
|
12998
|
-
import { execFileSync } from "child_process";
|
|
12999
|
-
import { existsSync as existsSync22 } from "fs";
|
|
13000
|
-
import * as path18 from "path";
|
|
13001
|
-
function resolveWin32GlobalBin(trimmed) {
|
|
13002
|
-
if (path18.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
|
|
13003
|
-
return null;
|
|
13004
|
-
}
|
|
13005
|
-
const extraDirs = [];
|
|
13006
|
-
if (process.env.APPDATA) extraDirs.push(path18.join(process.env.APPDATA, "npm"));
|
|
13007
|
-
try {
|
|
13008
|
-
extraDirs.push(path18.dirname(process.execPath));
|
|
13009
|
-
} catch {
|
|
13010
|
-
}
|
|
13011
|
-
for (const dir of extraDirs) {
|
|
13012
|
-
if (!dir) continue;
|
|
13013
|
-
for (const ext of WIN_EXEC_EXT) {
|
|
13014
|
-
const full = path18.join(dir, trimmed + ext);
|
|
13015
|
-
if (existsSync22(full)) return full;
|
|
13016
|
-
}
|
|
13017
|
-
}
|
|
13018
|
-
return null;
|
|
13019
|
-
}
|
|
13020
|
-
function resolveWin32Executable(command) {
|
|
13021
|
-
if (process.platform !== "win32") return command;
|
|
13022
|
-
const trimmed = (command || "").trim();
|
|
13023
|
-
if (!trimmed) return command;
|
|
13024
|
-
if (path18.isAbsolute(trimmed) && existsSync22(trimmed)) return trimmed;
|
|
13025
|
-
try {
|
|
13026
|
-
const out = execFileSync("where", [trimmed], {
|
|
13027
|
-
encoding: "utf8",
|
|
13028
|
-
windowsHide: true
|
|
13029
|
-
}).trim();
|
|
13030
|
-
if (out) {
|
|
13031
|
-
const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
13032
|
-
const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path18.extname(m).toLowerCase()));
|
|
13033
|
-
return direct || matches[0] || command;
|
|
13034
|
-
}
|
|
13035
|
-
} catch {
|
|
13036
|
-
}
|
|
13037
|
-
const globalBin = resolveWin32GlobalBin(trimmed);
|
|
13038
|
-
if (globalBin) return globalBin;
|
|
13039
|
-
return command;
|
|
13040
|
-
}
|
|
13041
|
-
var DIRECT_EXEC_EXT, WIN_EXEC_EXT;
|
|
13042
|
-
var init_resolve_executable = __esm({
|
|
13043
|
-
"src/cli-adapters/resolve-executable.ts"() {
|
|
13044
|
-
"use strict";
|
|
13045
|
-
DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
|
|
13046
|
-
WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
|
|
13047
|
-
}
|
|
13048
|
-
});
|
|
13049
|
-
|
|
13050
13138
|
// src/cli-adapters/pty-transport.ts
|
|
13051
13139
|
var pty_transport_exports = {};
|
|
13052
13140
|
__export(pty_transport_exports, {
|
|
@@ -15260,10 +15348,10 @@ ${lastSnapshot}`;
|
|
|
15260
15348
|
return this.accumulatedRawBuffer.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
15261
15349
|
}
|
|
15262
15350
|
getFreshParsedStatusCache() {
|
|
15263
|
-
const
|
|
15351
|
+
const cached3 = this.parsedStatusCache;
|
|
15264
15352
|
const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
|
|
15265
|
-
if (
|
|
15266
|
-
return
|
|
15353
|
+
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) {
|
|
15354
|
+
return cached3.result;
|
|
15267
15355
|
}
|
|
15268
15356
|
return null;
|
|
15269
15357
|
}
|
|
@@ -15725,10 +15813,10 @@ ${lastSnapshot}`;
|
|
|
15725
15813
|
getScriptParsedStatus() {
|
|
15726
15814
|
const screenText = this.readTerminalScreenText();
|
|
15727
15815
|
const parseScreenText = this.getParseScreenText(screenText);
|
|
15728
|
-
const
|
|
15816
|
+
const cached3 = this.parsedStatusCache;
|
|
15729
15817
|
const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
|
|
15730
|
-
if (!this.providerOwnsTranscript() &&
|
|
15731
|
-
return
|
|
15818
|
+
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) {
|
|
15819
|
+
return cached3.result;
|
|
15732
15820
|
}
|
|
15733
15821
|
const parsed = this.runParseSession();
|
|
15734
15822
|
if (!parsed || !Array.isArray(parsed.messages)) {
|
|
@@ -19394,13 +19482,20 @@ var MESH_REFINE_CONFIG_SCHEMA = {
|
|
|
19394
19482
|
function isMeshConfigRecord(value) {
|
|
19395
19483
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
19396
19484
|
}
|
|
19485
|
+
var SHELL_METACHAR_RE = /[;&|<>`$\n\r'"]/;
|
|
19486
|
+
var SAFE_TOKEN_RE = /^[A-Za-z0-9_@./:=+-]+$/;
|
|
19487
|
+
var SAFE_WIN32_EXEC_TOKEN_RE = /^[A-Za-z0-9_@./:=+\\-]+$/;
|
|
19397
19488
|
function tokenizeCommandString(command) {
|
|
19398
19489
|
const trimmed = command.trim();
|
|
19399
19490
|
if (!trimmed) return null;
|
|
19400
|
-
if (
|
|
19491
|
+
if (SHELL_METACHAR_RE.test(trimmed)) return null;
|
|
19401
19492
|
const tokens = trimmed.split(/\s+/).filter(Boolean);
|
|
19402
19493
|
if (!tokens.length) return null;
|
|
19403
|
-
|
|
19494
|
+
const isWin32 = process.platform === "win32";
|
|
19495
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
19496
|
+
const re = isWin32 && i === 0 ? SAFE_WIN32_EXEC_TOKEN_RE : SAFE_TOKEN_RE;
|
|
19497
|
+
if (!re.test(tokens[i])) return null;
|
|
19498
|
+
}
|
|
19404
19499
|
return tokens;
|
|
19405
19500
|
}
|
|
19406
19501
|
function validateCategory(value) {
|
|
@@ -19610,8 +19705,9 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
|
19610
19705
|
}
|
|
19611
19706
|
|
|
19612
19707
|
// src/mesh/worktree-bootstrap-config.ts
|
|
19613
|
-
|
|
19614
|
-
import {
|
|
19708
|
+
init_resolve_executable();
|
|
19709
|
+
import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
|
|
19710
|
+
import { join as join14, resolve as pathResolve } from "path";
|
|
19615
19711
|
import { execFile as execFile3 } from "child_process";
|
|
19616
19712
|
import { createHash as createHash3 } from "crypto";
|
|
19617
19713
|
import { promisify as promisify3 } from "util";
|
|
@@ -19702,8 +19798,8 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
19702
19798
|
return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
|
|
19703
19799
|
}
|
|
19704
19800
|
for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
19705
|
-
const configPath =
|
|
19706
|
-
if (!
|
|
19801
|
+
const configPath = join14(workspace, relative5);
|
|
19802
|
+
if (!existsSync13(configPath)) continue;
|
|
19707
19803
|
try {
|
|
19708
19804
|
const parsed = parseConfigText3(configPath, readFileSync10(configPath, "utf-8"));
|
|
19709
19805
|
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
|
|
@@ -19718,7 +19814,7 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
19718
19814
|
function computeStaleInputsDigest(workspace, staleInputs) {
|
|
19719
19815
|
const digest = {};
|
|
19720
19816
|
for (const relative5 of staleInputs ?? []) {
|
|
19721
|
-
const filePath =
|
|
19817
|
+
const filePath = join14(workspace, relative5);
|
|
19722
19818
|
try {
|
|
19723
19819
|
digest[relative5] = createHash3("sha256").update(readFileSync10(filePath)).digest("hex");
|
|
19724
19820
|
} catch {
|
|
@@ -19790,10 +19886,10 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
|
19790
19886
|
staleInputs: loaded.config.staleInputs
|
|
19791
19887
|
};
|
|
19792
19888
|
const staleInputPaths = loaded.config.staleInputs ?? [];
|
|
19793
|
-
const initiallyAbsent = staleInputPaths.filter((p) => !
|
|
19889
|
+
const initiallyAbsent = staleInputPaths.filter((p) => !existsSync13(join14(workspace, p)));
|
|
19794
19890
|
for (const command of validation.commands) {
|
|
19795
19891
|
if (initiallyAbsent.length > 0) {
|
|
19796
|
-
const appearedNow = initiallyAbsent.filter((p) =>
|
|
19892
|
+
const appearedNow = initiallyAbsent.filter((p) => existsSync13(join14(workspace, p)));
|
|
19797
19893
|
if (appearedNow.length > 0) {
|
|
19798
19894
|
state.status = "stale";
|
|
19799
19895
|
state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -19804,8 +19900,9 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
|
19804
19900
|
const cwd = command.cwd ? pathResolve(workspace, command.cwd) : workspace;
|
|
19805
19901
|
const startedAt = Date.now();
|
|
19806
19902
|
state.lastCommand = command.displayCommand;
|
|
19903
|
+
const resolvedCommand = resolveWin32Executable(command.command);
|
|
19807
19904
|
try {
|
|
19808
|
-
const result = await execFileAsync4(
|
|
19905
|
+
const result = await execFileAsync4(resolvedCommand, command.args, {
|
|
19809
19906
|
cwd,
|
|
19810
19907
|
encoding: "utf8",
|
|
19811
19908
|
timeout: command.timeoutMs || DEFAULT_TIMEOUT_MS2,
|
|
@@ -20041,8 +20138,8 @@ var P2pRelayFailureError = class extends Error {
|
|
|
20041
20138
|
|
|
20042
20139
|
// src/config/state-store.ts
|
|
20043
20140
|
init_config();
|
|
20044
|
-
import { existsSync as
|
|
20045
|
-
import { join as
|
|
20141
|
+
import { existsSync as existsSync17, readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "fs";
|
|
20142
|
+
import { join as join18 } from "path";
|
|
20046
20143
|
var DEFAULT_STATE = {
|
|
20047
20144
|
recentActivity: [],
|
|
20048
20145
|
savedProviderSessions: [],
|
|
@@ -20055,7 +20152,7 @@ function isPlainObject2(value) {
|
|
|
20055
20152
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
20056
20153
|
}
|
|
20057
20154
|
function getStatePath() {
|
|
20058
|
-
return
|
|
20155
|
+
return join18(getConfigDir(), "state.json");
|
|
20059
20156
|
}
|
|
20060
20157
|
function normalizeState(raw) {
|
|
20061
20158
|
const parsed = isPlainObject2(raw) ? raw : {};
|
|
@@ -20091,7 +20188,7 @@ function normalizeState(raw) {
|
|
|
20091
20188
|
}
|
|
20092
20189
|
function loadState() {
|
|
20093
20190
|
const statePath = getStatePath();
|
|
20094
|
-
if (!
|
|
20191
|
+
if (!existsSync17(statePath)) {
|
|
20095
20192
|
return { ...DEFAULT_STATE };
|
|
20096
20193
|
}
|
|
20097
20194
|
try {
|
|
@@ -20113,19 +20210,19 @@ function resetState() {
|
|
|
20113
20210
|
// src/detection/ide-detector.ts
|
|
20114
20211
|
import { exec as exec2 } from "child_process";
|
|
20115
20212
|
import { promisify as promisify4 } from "util";
|
|
20116
|
-
import { existsSync as
|
|
20213
|
+
import { existsSync as existsSync19, statSync as statSync8 } from "fs";
|
|
20117
20214
|
import { platform as platform3, homedir as homedir8 } from "os";
|
|
20118
|
-
import * as
|
|
20215
|
+
import * as path14 from "path";
|
|
20119
20216
|
|
|
20120
20217
|
// src/detection/win32-ide-version.ts
|
|
20121
20218
|
import * as fs5 from "fs";
|
|
20122
|
-
import * as
|
|
20219
|
+
import * as path13 from "path";
|
|
20123
20220
|
function manifestCandidates(exeDir) {
|
|
20124
20221
|
return [
|
|
20125
|
-
|
|
20126
|
-
|
|
20222
|
+
path13.join(exeDir, "resources", "app", "product.json"),
|
|
20223
|
+
path13.join(exeDir, "resources", "app", "package.json"),
|
|
20127
20224
|
// Some packagings keep product.json one level up.
|
|
20128
|
-
|
|
20225
|
+
path13.join(exeDir, "product.json")
|
|
20129
20226
|
];
|
|
20130
20227
|
}
|
|
20131
20228
|
function parseVersionFromManifest(raw) {
|
|
@@ -20143,9 +20240,9 @@ function readWin32IdeVersionFromDisk(exePath) {
|
|
|
20143
20240
|
if (!exePath) return null;
|
|
20144
20241
|
let exeDir;
|
|
20145
20242
|
try {
|
|
20146
|
-
exeDir = fs5.statSync(exePath).isDirectory() ? exePath :
|
|
20243
|
+
exeDir = fs5.statSync(exePath).isDirectory() ? exePath : path13.dirname(exePath);
|
|
20147
20244
|
} catch {
|
|
20148
|
-
exeDir =
|
|
20245
|
+
exeDir = path13.dirname(exePath);
|
|
20149
20246
|
}
|
|
20150
20247
|
for (const candidate of manifestCandidates(exeDir)) {
|
|
20151
20248
|
try {
|
|
@@ -20159,7 +20256,7 @@ function readWin32IdeVersionFromDisk(exePath) {
|
|
|
20159
20256
|
}
|
|
20160
20257
|
function isKnownWin32GuiExe(binPath, win32ProcessNames) {
|
|
20161
20258
|
if (!binPath) return false;
|
|
20162
|
-
const base =
|
|
20259
|
+
const base = path13.win32.basename(binPath).toLowerCase();
|
|
20163
20260
|
if (!base.endsWith(".exe")) return false;
|
|
20164
20261
|
for (const names of Object.values(win32ProcessNames)) {
|
|
20165
20262
|
for (const name of names) {
|
|
@@ -20191,10 +20288,10 @@ function getMergedDefinitions() {
|
|
|
20191
20288
|
function findCliCommand(command) {
|
|
20192
20289
|
const trimmed = String(command || "").trim();
|
|
20193
20290
|
if (!trimmed) return null;
|
|
20194
|
-
if (
|
|
20195
|
-
const candidate = trimmed.startsWith("~") ?
|
|
20196
|
-
const resolved =
|
|
20197
|
-
return
|
|
20291
|
+
if (path14.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
20292
|
+
const candidate = trimmed.startsWith("~") ? path14.join(homedir8(), trimmed.slice(1)) : trimmed;
|
|
20293
|
+
const resolved = path14.isAbsolute(candidate) ? candidate : path14.resolve(candidate);
|
|
20294
|
+
return existsSync19(resolved) ? resolved : null;
|
|
20198
20295
|
}
|
|
20199
20296
|
const isWin = platform3() === "win32";
|
|
20200
20297
|
const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
|
|
@@ -20202,9 +20299,9 @@ function findCliCommand(command) {
|
|
|
20202
20299
|
for (const p of paths) {
|
|
20203
20300
|
if (!p) continue;
|
|
20204
20301
|
for (const ext of exes) {
|
|
20205
|
-
const fullPath =
|
|
20302
|
+
const fullPath = path14.join(p, trimmed + ext);
|
|
20206
20303
|
try {
|
|
20207
|
-
if (
|
|
20304
|
+
if (existsSync19(fullPath)) {
|
|
20208
20305
|
const stat2 = statSync8(fullPath);
|
|
20209
20306
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
20210
20307
|
return fullPath;
|
|
@@ -20219,13 +20316,13 @@ function findCliCommand(command) {
|
|
|
20219
20316
|
function checkPathExists(paths) {
|
|
20220
20317
|
const home = homedir8();
|
|
20221
20318
|
for (const p of paths) {
|
|
20222
|
-
const normalized = p.startsWith("~") ?
|
|
20319
|
+
const normalized = p.startsWith("~") ? path14.join(home, p.slice(1)) : p;
|
|
20223
20320
|
if (normalized.includes("*")) {
|
|
20224
20321
|
const username = home.split(/[\\/]/).pop() || "";
|
|
20225
20322
|
const resolved = normalized.replace("*", username);
|
|
20226
|
-
if (
|
|
20323
|
+
if (existsSync19(resolved)) return resolved;
|
|
20227
20324
|
} else {
|
|
20228
|
-
if (
|
|
20325
|
+
if (existsSync19(normalized)) return normalized;
|
|
20229
20326
|
}
|
|
20230
20327
|
}
|
|
20231
20328
|
return null;
|
|
@@ -20239,7 +20336,7 @@ async function detectIDEs(providerLoader) {
|
|
|
20239
20336
|
let resolvedCli = cliPath;
|
|
20240
20337
|
if (!resolvedCli && appPath && os30 === "darwin") {
|
|
20241
20338
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
20242
|
-
if (
|
|
20339
|
+
if (existsSync19(bundledCli)) resolvedCli = bundledCli;
|
|
20243
20340
|
}
|
|
20244
20341
|
if (!resolvedCli && appPath && os30 === "win32") {
|
|
20245
20342
|
const { dirname: dirname17 } = await import("path");
|
|
@@ -20252,7 +20349,7 @@ async function detectIDEs(providerLoader) {
|
|
|
20252
20349
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
20253
20350
|
];
|
|
20254
20351
|
for (const c of candidates) {
|
|
20255
|
-
if (
|
|
20352
|
+
if (existsSync19(c)) {
|
|
20256
20353
|
resolvedCli = c;
|
|
20257
20354
|
break;
|
|
20258
20355
|
}
|
|
@@ -22111,9 +22208,9 @@ ${cleanBody}`;
|
|
|
22111
22208
|
// src/config/chat-history.ts
|
|
22112
22209
|
init_chat_message_normalization();
|
|
22113
22210
|
import * as fs6 from "fs";
|
|
22114
|
-
import * as
|
|
22211
|
+
import * as path15 from "path";
|
|
22115
22212
|
import * as os8 from "os";
|
|
22116
|
-
var HISTORY_DIR =
|
|
22213
|
+
var HISTORY_DIR = path15.join(os8.homedir(), ".adhdev", "history");
|
|
22117
22214
|
var RETAIN_DAYS = 30;
|
|
22118
22215
|
var SAVED_HISTORY_INDEX_VERSION = 1;
|
|
22119
22216
|
var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
|
|
@@ -22129,11 +22226,11 @@ var savedHistoryRollupInFlight = /* @__PURE__ */ new Set();
|
|
|
22129
22226
|
var BOUNDED_TAIL_CACHE_MAX_ENTRIES = 64;
|
|
22130
22227
|
var boundedTailReadCache = /* @__PURE__ */ new Map();
|
|
22131
22228
|
function readBoundedTailCache(key, signature) {
|
|
22132
|
-
const
|
|
22133
|
-
if (!
|
|
22229
|
+
const cached3 = boundedTailReadCache.get(key);
|
|
22230
|
+
if (!cached3 || cached3.signature !== signature) return null;
|
|
22134
22231
|
boundedTailReadCache.delete(key);
|
|
22135
|
-
boundedTailReadCache.set(key,
|
|
22136
|
-
return
|
|
22232
|
+
boundedTailReadCache.set(key, cached3);
|
|
22233
|
+
return cached3.result;
|
|
22137
22234
|
}
|
|
22138
22235
|
function writeBoundedTailCache(key, signature, result) {
|
|
22139
22236
|
boundedTailReadCache.delete(key);
|
|
@@ -22299,7 +22396,7 @@ function extractSavedHistorySessionIdFromFile(file) {
|
|
|
22299
22396
|
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
22300
22397
|
return new Map(files.map((file) => {
|
|
22301
22398
|
try {
|
|
22302
|
-
const stat2 = fs6.statSync(
|
|
22399
|
+
const stat2 = fs6.statSync(path15.join(dir, file));
|
|
22303
22400
|
return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
|
|
22304
22401
|
} catch {
|
|
22305
22402
|
return [file, `${file}:missing`];
|
|
@@ -22310,7 +22407,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
|
|
|
22310
22407
|
return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
|
|
22311
22408
|
}
|
|
22312
22409
|
function getSavedHistoryIndexFilePath(dir) {
|
|
22313
|
-
return
|
|
22410
|
+
return path15.join(dir, SAVED_HISTORY_INDEX_FILE);
|
|
22314
22411
|
}
|
|
22315
22412
|
function getSavedHistoryIndexLockPath(dir) {
|
|
22316
22413
|
return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
|
|
@@ -22412,7 +22509,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
|
|
|
22412
22509
|
}
|
|
22413
22510
|
for (const file of Array.from(currentEntries.keys())) {
|
|
22414
22511
|
if (incomingFiles.has(file)) continue;
|
|
22415
|
-
if (!fs6.existsSync(
|
|
22512
|
+
if (!fs6.existsSync(path15.join(dir, file))) {
|
|
22416
22513
|
currentEntries.delete(file);
|
|
22417
22514
|
}
|
|
22418
22515
|
}
|
|
@@ -22438,7 +22535,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
22438
22535
|
const indexStat = fs6.statSync(getSavedHistoryIndexFilePath(dir));
|
|
22439
22536
|
const files = listHistoryFiles(dir);
|
|
22440
22537
|
for (const file of files) {
|
|
22441
|
-
const stat2 = fs6.statSync(
|
|
22538
|
+
const stat2 = fs6.statSync(path15.join(dir, file));
|
|
22442
22539
|
if (stat2.mtimeMs > indexStat.mtimeMs) return true;
|
|
22443
22540
|
}
|
|
22444
22541
|
return false;
|
|
@@ -22448,14 +22545,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
22448
22545
|
}
|
|
22449
22546
|
function buildSavedHistoryFileSignature(dir, file) {
|
|
22450
22547
|
try {
|
|
22451
|
-
const stat2 = fs6.statSync(
|
|
22548
|
+
const stat2 = fs6.statSync(path15.join(dir, file));
|
|
22452
22549
|
return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
|
|
22453
22550
|
} catch {
|
|
22454
22551
|
return `${file}:missing`;
|
|
22455
22552
|
}
|
|
22456
22553
|
}
|
|
22457
22554
|
function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
|
|
22458
|
-
const filePath =
|
|
22555
|
+
const filePath = path15.join(dir, file);
|
|
22459
22556
|
const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
|
|
22460
22557
|
const currentEntry = entries.get(file) || null;
|
|
22461
22558
|
const nextSummary = updater(currentEntry?.summary || null);
|
|
@@ -22528,7 +22625,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
|
|
|
22528
22625
|
function computeSavedHistoryFileSummary(dir, file) {
|
|
22529
22626
|
const historySessionId = extractSavedHistorySessionIdFromFile(file);
|
|
22530
22627
|
if (!historySessionId) return null;
|
|
22531
|
-
const filePath =
|
|
22628
|
+
const filePath = path15.join(dir, file);
|
|
22532
22629
|
const content = fs6.readFileSync(filePath, "utf-8");
|
|
22533
22630
|
const lines = content.split("\n").filter(Boolean);
|
|
22534
22631
|
let messageCount = 0;
|
|
@@ -22615,11 +22712,11 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
|
|
|
22615
22712
|
const summaryBySessionId = /* @__PURE__ */ new Map();
|
|
22616
22713
|
const nextPersistedEntries = /* @__PURE__ */ new Map();
|
|
22617
22714
|
for (const file of files.slice().sort()) {
|
|
22618
|
-
const filePath =
|
|
22715
|
+
const filePath = path15.join(dir, file);
|
|
22619
22716
|
const signature = fileSignatures.get(file) || `${file}:missing`;
|
|
22620
|
-
const
|
|
22717
|
+
const cached3 = savedHistoryFileSummaryCache.get(filePath);
|
|
22621
22718
|
const persisted = persistedEntries.get(file);
|
|
22622
|
-
const reusableEntry =
|
|
22719
|
+
const reusableEntry = cached3?.signature === signature ? cached3 : persisted?.signature === signature ? persisted : null;
|
|
22623
22720
|
const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(dir, file);
|
|
22624
22721
|
const nextEntry = reusableEntry || {
|
|
22625
22722
|
signature,
|
|
@@ -22735,12 +22832,12 @@ var ChatHistoryWriter = class {
|
|
|
22735
22832
|
});
|
|
22736
22833
|
}
|
|
22737
22834
|
if (newMessages.length === 0) return;
|
|
22738
|
-
const dir =
|
|
22835
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
22739
22836
|
fs6.mkdirSync(dir, { recursive: true });
|
|
22740
22837
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
22741
22838
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
22742
22839
|
const fileName = `${filePrefix}${date}.jsonl`;
|
|
22743
|
-
const filePath =
|
|
22840
|
+
const filePath = path15.join(dir, fileName);
|
|
22744
22841
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
22745
22842
|
fs6.appendFileSync(filePath, lines, "utf-8");
|
|
22746
22843
|
updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
|
|
@@ -22831,11 +22928,11 @@ var ChatHistoryWriter = class {
|
|
|
22831
22928
|
const ws = String(workspace || "").trim();
|
|
22832
22929
|
if (!id || !ws) return;
|
|
22833
22930
|
try {
|
|
22834
|
-
const dir =
|
|
22931
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
22835
22932
|
fs6.mkdirSync(dir, { recursive: true });
|
|
22836
22933
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
22837
22934
|
const fileName = `${this.sanitize(id)}_${date}.jsonl`;
|
|
22838
|
-
const filePath =
|
|
22935
|
+
const filePath = path15.join(dir, fileName);
|
|
22839
22936
|
const record = {
|
|
22840
22937
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22841
22938
|
receivedAt: Date.now(),
|
|
@@ -22881,14 +22978,14 @@ var ChatHistoryWriter = class {
|
|
|
22881
22978
|
this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
|
|
22882
22979
|
this.lastSeenCounts.delete(fromDedupKey);
|
|
22883
22980
|
}
|
|
22884
|
-
const dir =
|
|
22981
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
22885
22982
|
if (!fs6.existsSync(dir)) return;
|
|
22886
22983
|
const fromPrefix = `${this.sanitize(fromId)}_`;
|
|
22887
22984
|
const toPrefix = `${this.sanitize(toId)}_`;
|
|
22888
22985
|
const files = fs6.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
|
|
22889
22986
|
for (const file of files) {
|
|
22890
|
-
const sourcePath =
|
|
22891
|
-
const targetPath =
|
|
22987
|
+
const sourcePath = path15.join(dir, file);
|
|
22988
|
+
const targetPath = path15.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
|
|
22892
22989
|
const sourceLines = fs6.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
22893
22990
|
const rewritten = sourceLines.map((line) => {
|
|
22894
22991
|
try {
|
|
@@ -22922,13 +23019,13 @@ var ChatHistoryWriter = class {
|
|
|
22922
23019
|
const sessionId = String(historySessionId || "").trim();
|
|
22923
23020
|
if (!sessionId) return;
|
|
22924
23021
|
try {
|
|
22925
|
-
const dir =
|
|
23022
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
22926
23023
|
if (!fs6.existsSync(dir)) return;
|
|
22927
23024
|
const prefix = `${this.sanitize(sessionId)}_`;
|
|
22928
23025
|
const files = fs6.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
|
|
22929
23026
|
const seen = /* @__PURE__ */ new Set();
|
|
22930
23027
|
for (const file of files) {
|
|
22931
|
-
const filePath =
|
|
23028
|
+
const filePath = path15.join(dir, file);
|
|
22932
23029
|
const lines = fs6.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
22933
23030
|
const next = [];
|
|
22934
23031
|
for (const line of lines) {
|
|
@@ -22982,11 +23079,11 @@ var ChatHistoryWriter = class {
|
|
|
22982
23079
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
22983
23080
|
const agentDirs = fs6.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
22984
23081
|
for (const dir of agentDirs) {
|
|
22985
|
-
const dirPath =
|
|
23082
|
+
const dirPath = path15.join(HISTORY_DIR, dir.name);
|
|
22986
23083
|
const files = fs6.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
22987
23084
|
let removedAny = false;
|
|
22988
23085
|
for (const file of files) {
|
|
22989
|
-
const filePath =
|
|
23086
|
+
const filePath = path15.join(dirPath, file);
|
|
22990
23087
|
const stat2 = fs6.statSync(filePath);
|
|
22991
23088
|
if (stat2.mtimeMs < cutoff) {
|
|
22992
23089
|
fs6.unlinkSync(filePath);
|
|
@@ -23115,16 +23212,16 @@ function readFileTailLines(filePath, needed) {
|
|
|
23115
23212
|
incrementalTailCache.delete(filePath);
|
|
23116
23213
|
return { lines: [], coversWholeFile: true };
|
|
23117
23214
|
}
|
|
23118
|
-
const
|
|
23119
|
-
if (
|
|
23120
|
-
if (
|
|
23215
|
+
const cached3 = incrementalTailCache.get(filePath);
|
|
23216
|
+
if (cached3) {
|
|
23217
|
+
if (cached3.size === size && cached3.mtimeMs === mtimeMs) {
|
|
23121
23218
|
incrementalTailCache.delete(filePath);
|
|
23122
|
-
incrementalTailCache.set(filePath,
|
|
23123
|
-
if (
|
|
23124
|
-
return { lines:
|
|
23219
|
+
incrementalTailCache.set(filePath, cached3);
|
|
23220
|
+
if (cached3.coversWholeFile || cached3.lines.length >= needed) {
|
|
23221
|
+
return { lines: cached3.lines, coversWholeFile: cached3.coversWholeFile };
|
|
23125
23222
|
}
|
|
23126
|
-
} else if (size >
|
|
23127
|
-
const incremental = tryIncrementalTailGrowth(filePath,
|
|
23223
|
+
} else if (size > cached3.size) {
|
|
23224
|
+
const incremental = tryIncrementalTailGrowth(filePath, cached3, size, mtimeMs, needed);
|
|
23128
23225
|
if (incremental) return { lines: incremental.lines, coversWholeFile: incremental.coversWholeFile };
|
|
23129
23226
|
}
|
|
23130
23227
|
incrementalTailCache.delete(filePath);
|
|
@@ -23150,22 +23247,22 @@ function readFileTailLines(filePath, needed) {
|
|
|
23150
23247
|
storeIncrementalTailCache(filePath, result.size, result.mtimeMs, result.lines, result.coversWholeFile);
|
|
23151
23248
|
return { lines: result.lines, coversWholeFile: result.coversWholeFile };
|
|
23152
23249
|
}
|
|
23153
|
-
function tryIncrementalTailGrowth(filePath,
|
|
23250
|
+
function tryIncrementalTailGrowth(filePath, cached3, size, mtimeMs, needed) {
|
|
23154
23251
|
const fd = fs6.openSync(filePath, "r");
|
|
23155
23252
|
try {
|
|
23156
|
-
if (
|
|
23253
|
+
if (cached3.size > 0) {
|
|
23157
23254
|
const boundary = Buffer.alloc(1);
|
|
23158
|
-
fs6.readSync(fd, boundary, 0, 1,
|
|
23255
|
+
fs6.readSync(fd, boundary, 0, 1, cached3.size - 1);
|
|
23159
23256
|
if (boundary[0] !== 10) return null;
|
|
23160
23257
|
}
|
|
23161
|
-
const appendedLength = size -
|
|
23258
|
+
const appendedLength = size - cached3.size;
|
|
23162
23259
|
const appended = Buffer.alloc(appendedLength);
|
|
23163
|
-
fs6.readSync(fd, appended, 0, appendedLength,
|
|
23260
|
+
fs6.readSync(fd, appended, 0, appendedLength, cached3.size);
|
|
23164
23261
|
const newLines = appended.toString("utf-8").split("\n");
|
|
23165
23262
|
if (newLines.length && newLines[newLines.length - 1] === "") newLines.pop();
|
|
23166
|
-
const merged =
|
|
23263
|
+
const merged = cached3.lines.concat(newLines);
|
|
23167
23264
|
const trimmed = merged.length > TAIL_LINES_RETAINED ? merged.slice(merged.length - TAIL_LINES_RETAINED) : merged;
|
|
23168
|
-
const coversWholeFile =
|
|
23265
|
+
const coversWholeFile = cached3.coversWholeFile && trimmed.length === merged.length;
|
|
23169
23266
|
storeIncrementalTailCache(filePath, size, mtimeMs, trimmed, coversWholeFile);
|
|
23170
23267
|
if (coversWholeFile || trimmed.length >= needed) {
|
|
23171
23268
|
return { lines: trimmed, coversWholeFile };
|
|
@@ -23189,7 +23286,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
|
|
|
23189
23286
|
const seen = /* @__PURE__ */ new Set();
|
|
23190
23287
|
let readAllFiles = true;
|
|
23191
23288
|
for (let f = 0; f < files.length; f++) {
|
|
23192
|
-
const filePath =
|
|
23289
|
+
const filePath = path15.join(dir, files[f]);
|
|
23193
23290
|
const remaining = Math.max(0, needed - collected.length);
|
|
23194
23291
|
const perFileNeeded = Math.min(needed, remaining + BOUNDED_TAIL_SLACK);
|
|
23195
23292
|
const { lines, coversWholeFile } = readFileTailLines(filePath, perFileNeeded);
|
|
@@ -23222,7 +23319,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
|
|
|
23222
23319
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
23223
23320
|
try {
|
|
23224
23321
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
23225
|
-
const dir =
|
|
23322
|
+
const dir = path15.join(HISTORY_DIR, sanitized);
|
|
23226
23323
|
if (!fs6.existsSync(dir)) return { messages: [], hasMore: false };
|
|
23227
23324
|
const files = listHistoryFiles(dir, historySessionId);
|
|
23228
23325
|
const bounded = isBoundedTailRequest(limit, offset, excludeRecentCount);
|
|
@@ -23230,8 +23327,8 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
23230
23327
|
const fileSignatures = buildSavedHistoryFileSignatureMap(dir, files);
|
|
23231
23328
|
const cacheKey = `${sanitized}\0${historySessionId || ""}\0${offset}\0${limit}\0${excludeRecentCount}\0${historyBehavior?.collapseConsecutiveAssistantTurns ? "1" : "0"}`;
|
|
23232
23329
|
const signature = buildSavedHistoryCacheSignature(files, fileSignatures);
|
|
23233
|
-
const
|
|
23234
|
-
if (
|
|
23330
|
+
const cached3 = readBoundedTailCache(cacheKey, signature);
|
|
23331
|
+
if (cached3) return cached3;
|
|
23235
23332
|
const numericLimit = Math.max(1, Number(limit));
|
|
23236
23333
|
const numericOffset = Math.max(0, Number(offset));
|
|
23237
23334
|
const numericExclude = Math.max(0, Number(excludeRecentCount));
|
|
@@ -23245,7 +23342,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
23245
23342
|
const allMessages = [];
|
|
23246
23343
|
const seen = /* @__PURE__ */ new Set();
|
|
23247
23344
|
for (const file of files) {
|
|
23248
|
-
const filePath =
|
|
23345
|
+
const filePath = path15.join(dir, file);
|
|
23249
23346
|
const content = fs6.readFileSync(filePath, "utf-8");
|
|
23250
23347
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
23251
23348
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -23269,28 +23366,28 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
23269
23366
|
function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
23270
23367
|
try {
|
|
23271
23368
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
23272
|
-
const dir =
|
|
23369
|
+
const dir = path15.join(HISTORY_DIR, sanitized);
|
|
23273
23370
|
if (!fs6.existsSync(dir)) {
|
|
23274
23371
|
savedHistorySessionCache.delete(sanitized);
|
|
23275
23372
|
return { sessions: [], hasMore: false };
|
|
23276
23373
|
}
|
|
23277
|
-
const
|
|
23374
|
+
const cached3 = savedHistorySessionCache.get(sanitized);
|
|
23278
23375
|
const offset = Math.max(0, options.offset || 0);
|
|
23279
23376
|
const limit = Math.max(1, options.limit || 30);
|
|
23280
23377
|
const indexSignature = buildSavedHistoryIndexFileSignature(dir);
|
|
23281
23378
|
let cacheWasInvalidated = false;
|
|
23282
|
-
if (
|
|
23283
|
-
const cacheLooksPersisted =
|
|
23284
|
-
const cacheStillValid = cacheLooksPersisted ?
|
|
23379
|
+
if (cached3) {
|
|
23380
|
+
const cacheLooksPersisted = cached3.signature.startsWith("index:");
|
|
23381
|
+
const cacheStillValid = cacheLooksPersisted ? cached3.signature === indexSignature : (() => {
|
|
23285
23382
|
const files2 = listHistoryFiles(dir);
|
|
23286
23383
|
const fileSignatures2 = buildSavedHistoryFileSignatureMap(dir, files2);
|
|
23287
|
-
return
|
|
23384
|
+
return cached3.signature === buildSavedHistoryCacheSignature(files2, fileSignatures2);
|
|
23288
23385
|
})();
|
|
23289
23386
|
if (cacheStillValid) {
|
|
23290
|
-
const sliced2 =
|
|
23387
|
+
const sliced2 = cached3.summaries.slice(offset, offset + limit);
|
|
23291
23388
|
return {
|
|
23292
23389
|
sessions: sliced2,
|
|
23293
|
-
hasMore:
|
|
23390
|
+
hasMore: cached3.summaries.length > offset + limit
|
|
23294
23391
|
};
|
|
23295
23392
|
}
|
|
23296
23393
|
cacheWasInvalidated = true;
|
|
@@ -23330,11 +23427,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
|
23330
23427
|
}
|
|
23331
23428
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
23332
23429
|
try {
|
|
23333
|
-
const dir =
|
|
23430
|
+
const dir = path15.join(HISTORY_DIR, agentType);
|
|
23334
23431
|
if (!fs6.existsSync(dir)) return null;
|
|
23335
23432
|
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
23336
23433
|
for (const file of files) {
|
|
23337
|
-
const lines = fs6.readFileSync(
|
|
23434
|
+
const lines = fs6.readFileSync(path15.join(dir, file), "utf-8").split("\n").filter(Boolean);
|
|
23338
23435
|
for (const line of lines) {
|
|
23339
23436
|
try {
|
|
23340
23437
|
const parsed = JSON.parse(line);
|
|
@@ -23354,16 +23451,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
|
23354
23451
|
function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
23355
23452
|
if (records.length === 0) return false;
|
|
23356
23453
|
try {
|
|
23357
|
-
const dir =
|
|
23454
|
+
const dir = path15.join(HISTORY_DIR, agentType);
|
|
23358
23455
|
fs6.mkdirSync(dir, { recursive: true });
|
|
23359
23456
|
const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
23360
23457
|
for (const file of fs6.readdirSync(dir)) {
|
|
23361
23458
|
if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
|
|
23362
|
-
fs6.unlinkSync(
|
|
23459
|
+
fs6.unlinkSync(path15.join(dir, file));
|
|
23363
23460
|
}
|
|
23364
23461
|
}
|
|
23365
23462
|
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
23366
|
-
const filePath =
|
|
23463
|
+
const filePath = path15.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
23367
23464
|
fs6.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
|
|
23368
23465
|
`, "utf-8");
|
|
23369
23466
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
@@ -25969,7 +26066,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
|
|
|
25969
26066
|
init_contracts();
|
|
25970
26067
|
import * as fs7 from "fs";
|
|
25971
26068
|
import * as os9 from "os";
|
|
25972
|
-
import * as
|
|
26069
|
+
import * as path16 from "path";
|
|
25973
26070
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
25974
26071
|
init_logger();
|
|
25975
26072
|
|
|
@@ -27019,7 +27116,7 @@ function readExactRuntimeMirrorMessages(args) {
|
|
|
27019
27116
|
function normalizeComparableWorkspace(value) {
|
|
27020
27117
|
const text = typeof value === "string" ? value.trim() : "";
|
|
27021
27118
|
if (!text) return "";
|
|
27022
|
-
return
|
|
27119
|
+
return path16.resolve(text);
|
|
27023
27120
|
}
|
|
27024
27121
|
function isCurrentRuntimePtySafelyAttributed(args) {
|
|
27025
27122
|
if (args.adapter.cliType !== "codex-cli") return false;
|
|
@@ -27504,7 +27601,7 @@ function buildDebugBundleText(bundle) {
|
|
|
27504
27601
|
}
|
|
27505
27602
|
function getChatDebugBundleDir() {
|
|
27506
27603
|
const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
|
|
27507
|
-
return override ||
|
|
27604
|
+
return override || path16.join(os9.homedir(), ".adhdev", "debug-bundles", "chat");
|
|
27508
27605
|
}
|
|
27509
27606
|
function safeBundleIdSegment(value, fallback) {
|
|
27510
27607
|
const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
@@ -27561,7 +27658,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
|
|
|
27561
27658
|
const bundleId = createChatDebugBundleId(targetSessionId);
|
|
27562
27659
|
const dir = getChatDebugBundleDir();
|
|
27563
27660
|
fs7.mkdirSync(dir, { recursive: true });
|
|
27564
|
-
const savedPath =
|
|
27661
|
+
const savedPath = path16.join(dir, `${bundleId}.json`);
|
|
27565
27662
|
const json = `${JSON.stringify(bundle, null, 2)}
|
|
27566
27663
|
`;
|
|
27567
27664
|
fs7.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
|
|
@@ -29125,7 +29222,7 @@ async function handleResolveAction(h, args) {
|
|
|
29125
29222
|
|
|
29126
29223
|
// src/commands/cdp-commands.ts
|
|
29127
29224
|
import * as fs8 from "fs";
|
|
29128
|
-
import * as
|
|
29225
|
+
import * as path17 from "path";
|
|
29129
29226
|
import * as os10 from "os";
|
|
29130
29227
|
var KEY_TO_VK = {
|
|
29131
29228
|
Backspace: 8,
|
|
@@ -29382,25 +29479,25 @@ function resolveSafePath(requestedPath) {
|
|
|
29382
29479
|
const inputPath = rawPath || ".";
|
|
29383
29480
|
const home = os10.homedir();
|
|
29384
29481
|
if (inputPath.startsWith("~")) {
|
|
29385
|
-
return
|
|
29482
|
+
return path17.resolve(path17.join(home, inputPath.slice(1)));
|
|
29386
29483
|
}
|
|
29387
29484
|
if (process.platform === "win32") {
|
|
29388
29485
|
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
29389
|
-
if (
|
|
29390
|
-
return
|
|
29486
|
+
if (path17.win32.isAbsolute(normalized)) {
|
|
29487
|
+
return path17.win32.normalize(normalized);
|
|
29391
29488
|
}
|
|
29392
|
-
return
|
|
29489
|
+
return path17.win32.resolve(normalized);
|
|
29393
29490
|
}
|
|
29394
|
-
if (
|
|
29395
|
-
return
|
|
29491
|
+
if (path17.isAbsolute(inputPath)) {
|
|
29492
|
+
return path17.normalize(inputPath);
|
|
29396
29493
|
}
|
|
29397
|
-
return
|
|
29494
|
+
return path17.resolve(inputPath);
|
|
29398
29495
|
}
|
|
29399
29496
|
function listDirectoryEntriesSafe(dirPath) {
|
|
29400
29497
|
const entries = fs8.readdirSync(dirPath, { withFileTypes: true });
|
|
29401
29498
|
const files = [];
|
|
29402
29499
|
for (const entry of entries) {
|
|
29403
|
-
const entryPath =
|
|
29500
|
+
const entryPath = path17.join(dirPath, entry.name);
|
|
29404
29501
|
try {
|
|
29405
29502
|
if (entry.isDirectory()) {
|
|
29406
29503
|
files.push({ name: entry.name, type: "directory" });
|
|
@@ -29454,7 +29551,7 @@ async function handleFileRead(h, args) {
|
|
|
29454
29551
|
async function handleFileWrite(h, args) {
|
|
29455
29552
|
try {
|
|
29456
29553
|
const filePath = resolveSafePath(args?.path);
|
|
29457
|
-
fs8.mkdirSync(
|
|
29554
|
+
fs8.mkdirSync(path17.dirname(filePath), { recursive: true });
|
|
29458
29555
|
fs8.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
29459
29556
|
return { success: true, path: filePath };
|
|
29460
29557
|
} catch (e) {
|
|
@@ -32235,6 +32332,7 @@ function collectStableSizes(when, sizes) {
|
|
|
32235
32332
|
|
|
32236
32333
|
// src/providers/spec/native-history-executor.ts
|
|
32237
32334
|
init_logger();
|
|
32335
|
+
init_load_better_sqlite3();
|
|
32238
32336
|
import * as fs13 from "fs";
|
|
32239
32337
|
import * as os17 from "os";
|
|
32240
32338
|
import * as path22 from "path";
|
|
@@ -32362,7 +32460,7 @@ function executeSqlite(src, input) {
|
|
|
32362
32460
|
if (!resolved || !fs13.existsSync(resolved)) return null;
|
|
32363
32461
|
let Database;
|
|
32364
32462
|
try {
|
|
32365
|
-
Database =
|
|
32463
|
+
Database = loadBetterSqlite3();
|
|
32366
32464
|
} catch {
|
|
32367
32465
|
return null;
|
|
32368
32466
|
}
|
|
@@ -39188,6 +39286,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
39188
39286
|
}
|
|
39189
39287
|
|
|
39190
39288
|
// src/providers/native-history/hermes-cli-transcript.ts
|
|
39289
|
+
init_load_better_sqlite3();
|
|
39191
39290
|
import * as fs20 from "fs";
|
|
39192
39291
|
import * as path30 from "path";
|
|
39193
39292
|
import * as os21 from "os";
|
|
@@ -39203,7 +39302,7 @@ function statMtimeMs4(p) {
|
|
|
39203
39302
|
function openDb() {
|
|
39204
39303
|
if (!fs20.existsSync(HERMES_STATE_DB)) return null;
|
|
39205
39304
|
try {
|
|
39206
|
-
const Database =
|
|
39305
|
+
const Database = loadBetterSqlite3();
|
|
39207
39306
|
return new Database(HERMES_STATE_DB, { readonly: true, fileMustExist: true });
|
|
39208
39307
|
} catch {
|
|
39209
39308
|
return null;
|
|
@@ -40578,8 +40677,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
40578
40677
|
return null;
|
|
40579
40678
|
}
|
|
40580
40679
|
registerProviderScriptRootSafely(path33.dirname(path33.dirname(providerDir)));
|
|
40581
|
-
const
|
|
40582
|
-
if (
|
|
40680
|
+
const cached3 = this.scriptsCache.get(dir);
|
|
40681
|
+
if (cached3) return cached3;
|
|
40583
40682
|
const scriptsJs = path33.join(dir, "scripts.js");
|
|
40584
40683
|
if (fs22.existsSync(scriptsJs)) {
|
|
40585
40684
|
try {
|
|
@@ -43265,6 +43364,7 @@ import { homedir as homedir26, hostname as osHostname } from "os";
|
|
|
43265
43364
|
import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
|
|
43266
43365
|
import * as fs26 from "fs";
|
|
43267
43366
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
43367
|
+
init_resolve_executable();
|
|
43268
43368
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
43269
43369
|
var CHANNEL_SERVER_URL = {
|
|
43270
43370
|
stable: "https://api.adhf.dev",
|
|
@@ -43658,13 +43758,13 @@ function sanitizeInlineMesh(inlineMesh) {
|
|
|
43658
43758
|
nodes
|
|
43659
43759
|
};
|
|
43660
43760
|
}
|
|
43661
|
-
function reconcileInlineMeshCache(
|
|
43662
|
-
if (!
|
|
43663
|
-
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return
|
|
43664
|
-
const cachedNodes = Array.isArray(
|
|
43761
|
+
function reconcileInlineMeshCache(cached3, incoming) {
|
|
43762
|
+
if (!cached3 || typeof cached3 !== "object" || Array.isArray(cached3)) return incoming;
|
|
43763
|
+
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached3;
|
|
43764
|
+
const cachedNodes = Array.isArray(cached3.nodes) ? cached3.nodes : [];
|
|
43665
43765
|
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
43666
|
-
if (!cachedNodes.length || !incomingNodes.length) return { ...
|
|
43667
|
-
const cachedUpdatedAt = Date.parse(readStringValue(
|
|
43766
|
+
if (!cachedNodes.length || !incomingNodes.length) return { ...cached3, ...incoming };
|
|
43767
|
+
const cachedUpdatedAt = Date.parse(readStringValue(cached3.updatedAt, cached3.updated_at) || "");
|
|
43668
43768
|
const incomingUpdatedAt = Date.parse(readStringValue(incoming.updatedAt, incoming.updated_at) || "");
|
|
43669
43769
|
const preserveCachedMembership = Number.isFinite(cachedUpdatedAt) && (!Number.isFinite(incomingUpdatedAt) || cachedUpdatedAt > incomingUpdatedAt);
|
|
43670
43770
|
const cachedById = /* @__PURE__ */ new Map();
|
|
@@ -43693,7 +43793,7 @@ function reconcileInlineMeshCache(cached2, incoming) {
|
|
|
43693
43793
|
}
|
|
43694
43794
|
}
|
|
43695
43795
|
return {
|
|
43696
|
-
...
|
|
43796
|
+
...cached3,
|
|
43697
43797
|
...incoming,
|
|
43698
43798
|
nodes
|
|
43699
43799
|
};
|
|
@@ -44026,9 +44126,9 @@ var MeshGitProbeCache = class {
|
|
|
44026
44126
|
*/
|
|
44027
44127
|
async probe(daemonId, workspace, probe) {
|
|
44028
44128
|
const key = this.key(daemonId, workspace);
|
|
44029
|
-
const
|
|
44030
|
-
if (
|
|
44031
|
-
return
|
|
44129
|
+
const cached3 = this.recent.get(key);
|
|
44130
|
+
if (cached3 && this.now() - cached3.at < this.reuseMs) {
|
|
44131
|
+
return cached3.value;
|
|
44032
44132
|
}
|
|
44033
44133
|
const existing = this.inflight.get(key);
|
|
44034
44134
|
if (existing) return existing;
|
|
@@ -44363,6 +44463,18 @@ function truncateValidationOutput(value) {
|
|
|
44363
44463
|
return `${text.slice(0, REFINE_VALIDATION_SUMMARY_CHARS)}
|
|
44364
44464
|
[truncated ${text.length - REFINE_VALIDATION_SUMMARY_CHARS} chars]`;
|
|
44365
44465
|
}
|
|
44466
|
+
function isSpawnResolutionError(error) {
|
|
44467
|
+
if (!error) return false;
|
|
44468
|
+
if (error.code === "ENOENT" && typeof error.syscall === "string" && error.syscall.startsWith("spawn")) return true;
|
|
44469
|
+
return error.code === "ENOENT" && (error.syscall === void 0 || String(error.syscall).startsWith("spawn"));
|
|
44470
|
+
}
|
|
44471
|
+
function describeSpawnError(error, command, spawnResolutionFailed) {
|
|
44472
|
+
if (spawnResolutionFailed) {
|
|
44473
|
+
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." : "";
|
|
44474
|
+
return `Could not resolve executable "${command}" (spawn ENOENT).${hint}`;
|
|
44475
|
+
}
|
|
44476
|
+
return String(error?.message || error);
|
|
44477
|
+
}
|
|
44366
44478
|
function recordMeshRefineStage(stages, stage, status, startedAt, details) {
|
|
44367
44479
|
stages.push({
|
|
44368
44480
|
stage,
|
|
@@ -45264,8 +45376,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45264
45376
|
const startedAt = Date.now();
|
|
45265
45377
|
const cwd = candidate.cwd ? pathResolve2(workspace, candidate.cwd) : workspace;
|
|
45266
45378
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
45379
|
+
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
45267
45380
|
try {
|
|
45268
|
-
const result = await execFileAsync4(
|
|
45381
|
+
const result = await execFileAsync4(resolvedCommand, candidate.args, {
|
|
45269
45382
|
cwd,
|
|
45270
45383
|
encoding: "utf8",
|
|
45271
45384
|
timeout,
|
|
@@ -45274,16 +45387,17 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45274
45387
|
});
|
|
45275
45388
|
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
45276
45389
|
} catch (error) {
|
|
45390
|
+
const spawnResolutionFailed = isSpawnResolutionError(error);
|
|
45277
45391
|
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
|
|
45278
45392
|
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
45279
45393
|
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
45280
45394
|
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
45281
|
-
failureKind: "dependency_bootstrap_failed"
|
|
45395
|
+
...spawnResolutionFailed ? { failureKind: "spawn_resolution_failed", resolvedCommand } : { failureKind: "dependency_bootstrap_failed" }
|
|
45282
45396
|
}));
|
|
45283
|
-
summary.bootstrap = { stage: "failed", error:
|
|
45397
|
+
summary.bootstrap = { stage: "failed", error: describeSpawnError(error, candidate.command, spawnResolutionFailed) };
|
|
45284
45398
|
summary.status = "failed";
|
|
45285
|
-
summary.failureKind = "dependency_bootstrap_failed";
|
|
45286
|
-
summary.failureCode = "dependency_bootstrap_failed";
|
|
45399
|
+
summary.failureKind = spawnResolutionFailed ? "spawn_resolution_failed" : "dependency_bootstrap_failed";
|
|
45400
|
+
summary.failureCode = spawnResolutionFailed ? "spawn_resolution_failed" : "dependency_bootstrap_failed";
|
|
45287
45401
|
return summary;
|
|
45288
45402
|
}
|
|
45289
45403
|
}
|
|
@@ -45306,8 +45420,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45306
45420
|
summary.failureCode = "missing_dependencies";
|
|
45307
45421
|
return summary;
|
|
45308
45422
|
}
|
|
45423
|
+
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
45309
45424
|
try {
|
|
45310
|
-
const result = await execFileAsync4(
|
|
45425
|
+
const result = await execFileAsync4(resolvedCommand, candidate.args, {
|
|
45311
45426
|
cwd,
|
|
45312
45427
|
encoding: "utf8",
|
|
45313
45428
|
timeout,
|
|
@@ -45316,16 +45431,21 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45316
45431
|
});
|
|
45317
45432
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
45318
45433
|
} catch (error) {
|
|
45434
|
+
const spawnResolutionFailed = isSpawnResolutionError(error);
|
|
45319
45435
|
const stderr = truncateValidationOutput(error?.stderr || error?.message);
|
|
45320
|
-
const missingDependencyFailure = /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
|
|
45436
|
+
const missingDependencyFailure = !spawnResolutionFailed && /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
|
|
45321
45437
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
|
|
45322
45438
|
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
45323
45439
|
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
45324
45440
|
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
45325
|
-
...missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
|
|
45441
|
+
...spawnResolutionFailed ? { failureKind: "spawn_resolution_failed", resolvedCommand } : missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
|
|
45326
45442
|
}));
|
|
45327
45443
|
summary.status = "failed";
|
|
45328
|
-
if (
|
|
45444
|
+
if (spawnResolutionFailed) {
|
|
45445
|
+
summary.failureKind = "spawn_resolution_failed";
|
|
45446
|
+
summary.failureCode = "spawn_resolution_failed";
|
|
45447
|
+
summary.spawnResolutionError = describeSpawnError(error, candidate.command, true);
|
|
45448
|
+
} else if (missingDependencyFailure) {
|
|
45329
45449
|
summary.failureKind = "missing_dependencies";
|
|
45330
45450
|
summary.failureCode = "missing_dependencies";
|
|
45331
45451
|
}
|
|
@@ -45676,13 +45796,13 @@ var DaemonCommandRouter = class {
|
|
|
45676
45796
|
};
|
|
45677
45797
|
}
|
|
45678
45798
|
getCachedAggregateMeshStatus(meshId, mesh, options) {
|
|
45679
|
-
const
|
|
45680
|
-
if (!
|
|
45681
|
-
if (
|
|
45682
|
-
let snapshot = this.cloneJsonValue(
|
|
45799
|
+
const cached3 = this.aggregateMeshStatusCache.get(meshId);
|
|
45800
|
+
if (!cached3?.snapshot || cached3.snapshot.success !== true || !Array.isArray(cached3.snapshot.nodes)) return null;
|
|
45801
|
+
if (cached3.queueRevision !== getMeshQueueRevision(meshId)) return null;
|
|
45802
|
+
let snapshot = this.cloneJsonValue(cached3.snapshot);
|
|
45683
45803
|
snapshot = this.hydrateCachedAggregateMeshStatusFromInline(snapshot, mesh, options);
|
|
45684
45804
|
if (shouldRefreshStalePendingAggregate(snapshot, options)) return null;
|
|
45685
|
-
const ageMs = Math.max(0, Date.now() -
|
|
45805
|
+
const ageMs = Math.max(0, Date.now() - cached3.builtAt);
|
|
45686
45806
|
const sourceOfTruth = snapshot.sourceOfTruth && typeof snapshot.sourceOfTruth === "object" ? snapshot.sourceOfTruth : {};
|
|
45687
45807
|
snapshot.sourceOfTruth = {
|
|
45688
45808
|
...sourceOfTruth,
|
|
@@ -45693,7 +45813,7 @@ var DaemonCommandRouter = class {
|
|
|
45693
45813
|
source: "memory",
|
|
45694
45814
|
refreshReason: "memory_cache_hit",
|
|
45695
45815
|
ageMs,
|
|
45696
|
-
cachedAt: new Date(
|
|
45816
|
+
cachedAt: new Date(cached3.builtAt).toISOString(),
|
|
45697
45817
|
returnedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
45698
45818
|
}
|
|
45699
45819
|
};
|
|
@@ -45740,9 +45860,9 @@ var DaemonCommandRouter = class {
|
|
|
45740
45860
|
meshId,
|
|
45741
45861
|
sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh))
|
|
45742
45862
|
);
|
|
45743
|
-
const
|
|
45744
|
-
if (
|
|
45745
|
-
const merged = reconcileInlineMeshCache(
|
|
45863
|
+
const cached3 = this.inlineMeshCache.get(meshId);
|
|
45864
|
+
if (cached3) {
|
|
45865
|
+
const merged = reconcileInlineMeshCache(cached3, sanitizedInlineMesh);
|
|
45746
45866
|
this.inlineMeshCache.set(meshId, merged);
|
|
45747
45867
|
return merged;
|
|
45748
45868
|
}
|
|
@@ -45752,17 +45872,17 @@ var DaemonCommandRouter = class {
|
|
|
45752
45872
|
async getMeshForCommand(meshId, inlineMesh, options) {
|
|
45753
45873
|
const preferInline = options?.preferInline === true;
|
|
45754
45874
|
if (preferInline) {
|
|
45755
|
-
const
|
|
45756
|
-
if (
|
|
45875
|
+
const cached4 = this.getCachedInlineMesh(meshId);
|
|
45876
|
+
if (cached4) {
|
|
45757
45877
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
45758
45878
|
const merged = reconcileInlineMeshCache(
|
|
45759
|
-
|
|
45879
|
+
cached4,
|
|
45760
45880
|
this.applyInlineMeshNodeTombstones(meshId, inlineMesh)
|
|
45761
45881
|
);
|
|
45762
45882
|
this.inlineMeshCache.set(meshId, sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(merged)));
|
|
45763
45883
|
return { mesh: merged, inline: true, source: "inline_cache" };
|
|
45764
45884
|
}
|
|
45765
|
-
return { mesh:
|
|
45885
|
+
return { mesh: cached4, inline: true, source: "inline_cache" };
|
|
45766
45886
|
}
|
|
45767
45887
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
45768
45888
|
this.warmInlineMeshCache(meshId, inlineMesh);
|
|
@@ -45775,8 +45895,8 @@ var DaemonCommandRouter = class {
|
|
|
45775
45895
|
if (mesh) return { mesh, inline: false, source: "local_config" };
|
|
45776
45896
|
} catch {
|
|
45777
45897
|
}
|
|
45778
|
-
const
|
|
45779
|
-
if (
|
|
45898
|
+
const cached3 = this.getCachedInlineMesh(meshId);
|
|
45899
|
+
if (cached3) return { mesh: cached3, inline: true, source: "inline_cache" };
|
|
45780
45900
|
const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
|
|
45781
45901
|
return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
|
|
45782
45902
|
}
|
|
@@ -46586,7 +46706,7 @@ var DaemonCommandRouter = class {
|
|
|
46586
46706
|
if (validationSummary.status === "failed") {
|
|
46587
46707
|
const firstFailedCmd = Array.isArray(validationSummary.commandsRun) ? validationSummary.commandsRun.find((c) => c.success === false) : void 0;
|
|
46588
46708
|
const buildValidationFailedError = () => {
|
|
46589
|
-
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.";
|
|
46709
|
+
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.";
|
|
46590
46710
|
if (!firstFailedCmd) return base;
|
|
46591
46711
|
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 : "";
|
|
46592
46712
|
const rawOutput = [firstFailedCmd.stdout, firstFailedCmd.stderr, firstFailedCmd.output].filter((s) => typeof s === "string" && s.length > 0).join("\n");
|
|
@@ -47206,8 +47326,8 @@ ${hintLines.join("\n")}` : "",
|
|
|
47206
47326
|
const repoRootBaseRef = /* @__PURE__ */ new Map();
|
|
47207
47327
|
const submodulePathsByRepoRoot = /* @__PURE__ */ new Map();
|
|
47208
47328
|
const resolveBaseRef = async (repoRoot) => {
|
|
47209
|
-
const
|
|
47210
|
-
if (
|
|
47329
|
+
const cached3 = repoRootBaseRef.get(repoRoot);
|
|
47330
|
+
if (cached3) return cached3;
|
|
47211
47331
|
let baseBranch = "main";
|
|
47212
47332
|
try {
|
|
47213
47333
|
const { stdout } = await execFileAsync4("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
|