@adhdev/daemon-core 0.9.82-rc.333 → 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 +586 -507
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +577 -498
- 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/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 +59 -8
- 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/dist/index.js
CHANGED
|
@@ -316,10 +316,10 @@ function readInjected(value) {
|
|
|
316
316
|
}
|
|
317
317
|
function getDaemonBuildInfo() {
|
|
318
318
|
if (cached) return cached;
|
|
319
|
-
const commit = readInjected(true ? "
|
|
320
|
-
const commitShort = readInjected(true ? "
|
|
321
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
322
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
319
|
+
const commit = readInjected(true ? "9e5ae5d2814077a6bf9e982b17066ca2051da97b" : void 0) ?? "unknown";
|
|
320
|
+
const commitShort = readInjected(true ? "9e5ae5d2" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
321
|
+
const version = readInjected(true ? "0.9.82-rc.334" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
322
|
+
const builtAt = readInjected(true ? "2026-06-20T03:55:49.426Z" : void 0);
|
|
323
323
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
324
324
|
return cached;
|
|
325
325
|
}
|
|
@@ -3260,6 +3260,297 @@ var init_mesh_ledger = __esm({
|
|
|
3260
3260
|
}
|
|
3261
3261
|
});
|
|
3262
3262
|
|
|
3263
|
+
// src/logging/async-batch-writer.ts
|
|
3264
|
+
var fs3, AsyncBatchWriter;
|
|
3265
|
+
var init_async_batch_writer = __esm({
|
|
3266
|
+
"src/logging/async-batch-writer.ts"() {
|
|
3267
|
+
"use strict";
|
|
3268
|
+
fs3 = __toESM(require("fs"));
|
|
3269
|
+
AsyncBatchWriter = class {
|
|
3270
|
+
// Maps filePath -> string buffer
|
|
3271
|
+
static buffers = /* @__PURE__ */ new Map();
|
|
3272
|
+
static writePromises = /* @__PURE__ */ new Map();
|
|
3273
|
+
static flushTimer = null;
|
|
3274
|
+
/**
|
|
3275
|
+
* Queues data to be written to a file asynchronously in a batch.
|
|
3276
|
+
*/
|
|
3277
|
+
static write(filePath, data) {
|
|
3278
|
+
let buf = this.buffers.get(filePath);
|
|
3279
|
+
if (!buf) {
|
|
3280
|
+
buf = [];
|
|
3281
|
+
this.buffers.set(filePath, buf);
|
|
3282
|
+
}
|
|
3283
|
+
buf.push(data);
|
|
3284
|
+
if (!this.flushTimer) {
|
|
3285
|
+
this.flushTimer = setTimeout(() => {
|
|
3286
|
+
this.flushTimer = null;
|
|
3287
|
+
this.flushAll();
|
|
3288
|
+
}, 50);
|
|
3289
|
+
}
|
|
3290
|
+
}
|
|
3291
|
+
static async flushAll() {
|
|
3292
|
+
const entries = Array.from(this.buffers.entries());
|
|
3293
|
+
this.buffers.clear();
|
|
3294
|
+
for (const [filePath, buffer] of entries) {
|
|
3295
|
+
const dataToWrite = buffer.join("");
|
|
3296
|
+
const doWrite = async () => {
|
|
3297
|
+
try {
|
|
3298
|
+
const prevPromise = this.writePromises.get(filePath);
|
|
3299
|
+
if (prevPromise) await prevPromise;
|
|
3300
|
+
await fs3.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
|
|
3301
|
+
} catch {
|
|
3302
|
+
}
|
|
3303
|
+
};
|
|
3304
|
+
const writePromise = doWrite();
|
|
3305
|
+
this.writePromises.set(filePath, writePromise);
|
|
3306
|
+
writePromise.finally(() => {
|
|
3307
|
+
if (this.writePromises.get(filePath) === writePromise) {
|
|
3308
|
+
this.writePromises.delete(filePath);
|
|
3309
|
+
}
|
|
3310
|
+
});
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
3313
|
+
};
|
|
3314
|
+
}
|
|
3315
|
+
});
|
|
3316
|
+
|
|
3317
|
+
// src/logging/logger.ts
|
|
3318
|
+
var logger_exports = {};
|
|
3319
|
+
__export(logger_exports, {
|
|
3320
|
+
LOG: () => LOG,
|
|
3321
|
+
LOG_DIR_PATH: () => LOG_DIR_PATH,
|
|
3322
|
+
LOG_PATH: () => LOG_PATH,
|
|
3323
|
+
daemonLog: () => daemonLog,
|
|
3324
|
+
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
3325
|
+
getDaemonLogDir: () => getDaemonLogDir,
|
|
3326
|
+
getLogBufferSize: () => getLogBufferSize,
|
|
3327
|
+
getLogLevel: () => getLogLevel,
|
|
3328
|
+
getLogPath: () => getLogPath,
|
|
3329
|
+
getRecentLogs: () => getRecentLogs,
|
|
3330
|
+
installGlobalInterceptor: () => installGlobalInterceptor,
|
|
3331
|
+
setLogLevel: () => setLogLevel
|
|
3332
|
+
});
|
|
3333
|
+
function setLogLevel(level) {
|
|
3334
|
+
currentLevel = level;
|
|
3335
|
+
daemonLog("Logger", `Log level set to: ${level}`, "info");
|
|
3336
|
+
}
|
|
3337
|
+
function getLogLevel() {
|
|
3338
|
+
return currentLevel;
|
|
3339
|
+
}
|
|
3340
|
+
function getDateStr() {
|
|
3341
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3342
|
+
}
|
|
3343
|
+
function getDaemonLogDir() {
|
|
3344
|
+
return LOG_DIR;
|
|
3345
|
+
}
|
|
3346
|
+
function getCurrentDaemonLogPath(date = /* @__PURE__ */ new Date()) {
|
|
3347
|
+
return path9.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
|
|
3348
|
+
}
|
|
3349
|
+
function checkDateRotation() {
|
|
3350
|
+
const today = getDateStr();
|
|
3351
|
+
if (today !== currentDate) {
|
|
3352
|
+
currentDate = today;
|
|
3353
|
+
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
3354
|
+
cleanOldLogs();
|
|
3355
|
+
}
|
|
3356
|
+
}
|
|
3357
|
+
function cleanOldLogs() {
|
|
3358
|
+
try {
|
|
3359
|
+
const files = fs4.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
|
|
3360
|
+
const cutoff = /* @__PURE__ */ new Date();
|
|
3361
|
+
cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
|
|
3362
|
+
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
3363
|
+
for (const file of files) {
|
|
3364
|
+
const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
3365
|
+
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
3366
|
+
try {
|
|
3367
|
+
fs4.unlinkSync(path9.join(LOG_DIR, file));
|
|
3368
|
+
} catch {
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
} catch {
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
function rotateSizeIfNeeded() {
|
|
3376
|
+
try {
|
|
3377
|
+
const stat2 = fs4.statSync(currentLogFile);
|
|
3378
|
+
if (stat2.size > MAX_LOG_SIZE) {
|
|
3379
|
+
const backup = currentLogFile.replace(".log", ".1.log");
|
|
3380
|
+
try {
|
|
3381
|
+
fs4.unlinkSync(backup);
|
|
3382
|
+
} catch {
|
|
3383
|
+
}
|
|
3384
|
+
fs4.renameSync(currentLogFile, backup);
|
|
3385
|
+
}
|
|
3386
|
+
} catch {
|
|
3387
|
+
}
|
|
3388
|
+
}
|
|
3389
|
+
function writeToFile(line) {
|
|
3390
|
+
try {
|
|
3391
|
+
if (++writeCount % 1e3 === 0) {
|
|
3392
|
+
checkDateRotation();
|
|
3393
|
+
rotateSizeIfNeeded();
|
|
3394
|
+
}
|
|
3395
|
+
AsyncBatchWriter.write(currentLogFile, line + "\n");
|
|
3396
|
+
} catch {
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
function getRecentLogs(count = 50, minLevel = "info") {
|
|
3400
|
+
const minNum = LEVEL_NUM[minLevel];
|
|
3401
|
+
const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
|
|
3402
|
+
return filtered.slice(-count);
|
|
3403
|
+
}
|
|
3404
|
+
function getLogBufferSize() {
|
|
3405
|
+
return ringBuffer.length;
|
|
3406
|
+
}
|
|
3407
|
+
function ts() {
|
|
3408
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
3409
|
+
}
|
|
3410
|
+
function fullTs() {
|
|
3411
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3412
|
+
}
|
|
3413
|
+
function daemonLog(category, msg, level = "info") {
|
|
3414
|
+
const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
|
|
3415
|
+
const label = LEVEL_LABEL[level];
|
|
3416
|
+
const line = `[${ts()}] [${label}] [${category}] ${msg}`;
|
|
3417
|
+
if (!shouldOutput) return;
|
|
3418
|
+
writeToFile(line);
|
|
3419
|
+
ringBuffer.push({ ts: Date.now(), level, category, message: msg });
|
|
3420
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3421
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3422
|
+
}
|
|
3423
|
+
origConsoleLog(line);
|
|
3424
|
+
}
|
|
3425
|
+
function installGlobalInterceptor() {
|
|
3426
|
+
if (interceptorInstalled) return;
|
|
3427
|
+
interceptorInstalled = true;
|
|
3428
|
+
const stripAnsi4 = (str) => str.replace(/\x1B\[[0-9;]*m/g, "");
|
|
3429
|
+
const isDaemonLogLine = (msg) => /\[(DBG|INF|WRN|ERR)\]/.test(msg);
|
|
3430
|
+
console.log = (...args) => {
|
|
3431
|
+
origConsoleLog(...args);
|
|
3432
|
+
try {
|
|
3433
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
3434
|
+
const clean = stripAnsi4(msg);
|
|
3435
|
+
if (isDaemonLogLine(clean)) return;
|
|
3436
|
+
const line = clean.startsWith("[20") ? clean : `[${fullTs()}] ${clean}`;
|
|
3437
|
+
writeToFile(line);
|
|
3438
|
+
const catMatch = clean.match(/\[([^\]]+)\]/);
|
|
3439
|
+
ringBuffer.push({
|
|
3440
|
+
ts: Date.now(),
|
|
3441
|
+
level: "info",
|
|
3442
|
+
category: catMatch?.[1] || "System",
|
|
3443
|
+
message: clean
|
|
3444
|
+
});
|
|
3445
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3446
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3447
|
+
}
|
|
3448
|
+
} catch {
|
|
3449
|
+
}
|
|
3450
|
+
};
|
|
3451
|
+
console.error = (...args) => {
|
|
3452
|
+
origConsoleError(...args);
|
|
3453
|
+
try {
|
|
3454
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
3455
|
+
const clean = stripAnsi4(msg);
|
|
3456
|
+
if (isDaemonLogLine(clean)) return;
|
|
3457
|
+
const line = `[${fullTs()}] [ERROR] ${clean}`;
|
|
3458
|
+
writeToFile(line);
|
|
3459
|
+
ringBuffer.push({ ts: Date.now(), level: "error", category: "System", message: clean });
|
|
3460
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3461
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3462
|
+
}
|
|
3463
|
+
} catch {
|
|
3464
|
+
}
|
|
3465
|
+
};
|
|
3466
|
+
console.warn = (...args) => {
|
|
3467
|
+
origConsoleWarn(...args);
|
|
3468
|
+
try {
|
|
3469
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
3470
|
+
const clean = stripAnsi4(msg);
|
|
3471
|
+
if (isDaemonLogLine(clean)) return;
|
|
3472
|
+
const line = `[${fullTs()}] [WARN] ${clean}`;
|
|
3473
|
+
writeToFile(line);
|
|
3474
|
+
ringBuffer.push({ ts: Date.now(), level: "warn", category: "System", message: clean });
|
|
3475
|
+
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
3476
|
+
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
3477
|
+
}
|
|
3478
|
+
} catch {
|
|
3479
|
+
}
|
|
3480
|
+
};
|
|
3481
|
+
writeToFile(`
|
|
3482
|
+
=== ADHDev Daemon started at ${fullTs()} ===`);
|
|
3483
|
+
writeToFile(`Log file: ${currentLogFile}`);
|
|
3484
|
+
writeToFile(`Log level: ${currentLevel}`);
|
|
3485
|
+
}
|
|
3486
|
+
function getLogPath() {
|
|
3487
|
+
return currentLogFile;
|
|
3488
|
+
}
|
|
3489
|
+
var fs4, path9, os3, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, LOG_DIR_PATH;
|
|
3490
|
+
var init_logger = __esm({
|
|
3491
|
+
"src/logging/logger.ts"() {
|
|
3492
|
+
"use strict";
|
|
3493
|
+
fs4 = __toESM(require("fs"));
|
|
3494
|
+
path9 = __toESM(require("path"));
|
|
3495
|
+
os3 = __toESM(require("os"));
|
|
3496
|
+
init_async_batch_writer();
|
|
3497
|
+
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
3498
|
+
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
3499
|
+
currentLevel = "info";
|
|
3500
|
+
LOG_DIR = process.platform === "win32" ? path9.join(process.env.LOCALAPPDATA || process.env.APPDATA || path9.join(os3.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path9.join(os3.homedir(), "Library", "Logs", "adhdev") : path9.join(os3.homedir(), ".local", "share", "adhdev", "logs");
|
|
3501
|
+
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
3502
|
+
MAX_LOG_DAYS = 7;
|
|
3503
|
+
try {
|
|
3504
|
+
fs4.mkdirSync(LOG_DIR, { recursive: true });
|
|
3505
|
+
} catch {
|
|
3506
|
+
}
|
|
3507
|
+
currentDate = getDateStr();
|
|
3508
|
+
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
3509
|
+
cleanOldLogs();
|
|
3510
|
+
try {
|
|
3511
|
+
const oldLog = path9.join(LOG_DIR, "daemon.log");
|
|
3512
|
+
if (fs4.existsSync(oldLog)) {
|
|
3513
|
+
const stat2 = fs4.statSync(oldLog);
|
|
3514
|
+
const oldDate = stat2.mtime.toISOString().slice(0, 10);
|
|
3515
|
+
fs4.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
3516
|
+
}
|
|
3517
|
+
const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
|
|
3518
|
+
if (fs4.existsSync(oldLogBackup)) {
|
|
3519
|
+
fs4.unlinkSync(oldLogBackup);
|
|
3520
|
+
}
|
|
3521
|
+
} catch {
|
|
3522
|
+
}
|
|
3523
|
+
writeCount = 0;
|
|
3524
|
+
RING_BUFFER_SIZE = 200;
|
|
3525
|
+
ringBuffer = [];
|
|
3526
|
+
origConsoleLog = console.log.bind(console);
|
|
3527
|
+
origConsoleError = console.error.bind(console);
|
|
3528
|
+
origConsoleWarn = console.warn.bind(console);
|
|
3529
|
+
LOG = {
|
|
3530
|
+
debug: (category, msg) => daemonLog(category, msg, "debug"),
|
|
3531
|
+
info: (category, msg) => daemonLog(category, msg, "info"),
|
|
3532
|
+
warn: (category, msg) => daemonLog(category, msg, "warn"),
|
|
3533
|
+
error: (category, msg) => daemonLog(category, msg, "error"),
|
|
3534
|
+
/**
|
|
3535
|
+
* Create a scoped logger for a specific component.
|
|
3536
|
+
* Category is baked in so callers only pass the message.
|
|
3537
|
+
*/
|
|
3538
|
+
forComponent(category) {
|
|
3539
|
+
return {
|
|
3540
|
+
debug: (msg) => daemonLog(category, msg, "debug"),
|
|
3541
|
+
info: (msg) => daemonLog(category, msg, "info"),
|
|
3542
|
+
warn: (msg) => daemonLog(category, msg, "warn"),
|
|
3543
|
+
error: (msg) => daemonLog(category, msg, "error"),
|
|
3544
|
+
asLogFn: (level = "info") => (msg) => daemonLog(category, msg, level)
|
|
3545
|
+
};
|
|
3546
|
+
}
|
|
3547
|
+
};
|
|
3548
|
+
interceptorInstalled = false;
|
|
3549
|
+
LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
3550
|
+
LOG_DIR_PATH = LOG_DIR;
|
|
3551
|
+
}
|
|
3552
|
+
});
|
|
3553
|
+
|
|
3263
3554
|
// src/mesh/mesh-work-queue.ts
|
|
3264
3555
|
var mesh_work_queue_exports = {};
|
|
3265
3556
|
__export(mesh_work_queue_exports, {
|
|
@@ -3724,11 +4015,18 @@ function requeueTask(meshId, taskId, opts) {
|
|
|
3724
4015
|
}
|
|
3725
4016
|
function updateSessionTaskStatus(meshId, sessionId, status, opts) {
|
|
3726
4017
|
return withQueueLock(meshId, () => {
|
|
4018
|
+
const store = MeshRuntimeStore.getInstance();
|
|
3727
4019
|
const occurredAtIso = opts?.occurredAt ? new Date(opts.occurredAt).toISOString() : void 0;
|
|
3728
|
-
const entry =
|
|
3729
|
-
if (!entry)
|
|
4020
|
+
const entry = store.findAssignedBySession(meshId, sessionId, occurredAtIso, opts?.taskId);
|
|
4021
|
+
if (!entry) {
|
|
4022
|
+
const assignedRows = store.getActiveAssignmentDetails(meshId).filter((r) => r.sessionId === sessionId);
|
|
4023
|
+
if (assignedRows.length > 0) {
|
|
4024
|
+
LOG.warn("MeshQueue", `No assigned queue row matched completion for mesh ${meshId} session ${sessionId} (taskId=${opts?.taskId ?? "none"}, occurredAt=${occurredAtIso ?? "none"}); ${assignedRows.length} assigned row(s) exist: ${assignedRows.map((r) => r.id).join(",")}`);
|
|
4025
|
+
}
|
|
4026
|
+
return null;
|
|
4027
|
+
}
|
|
3730
4028
|
entry.status = status;
|
|
3731
|
-
|
|
4029
|
+
store.updateQueueEntry(entry);
|
|
3732
4030
|
if (DEPENDENCY_FAILURE_TERMINALS.has(status)) propagateDependencyFailure(meshId, entry.id);
|
|
3733
4031
|
return entry;
|
|
3734
4032
|
});
|
|
@@ -3837,6 +4135,7 @@ var init_mesh_work_queue = __esm({
|
|
|
3837
4135
|
init_repo_mesh_types();
|
|
3838
4136
|
init_mesh_runtime_store();
|
|
3839
4137
|
init_mesh_config();
|
|
4138
|
+
init_logger();
|
|
3840
4139
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
3841
4140
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
3842
4141
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -4495,12 +4794,51 @@ var init_mesh_runtime_store = __esm({
|
|
|
4495
4794
|
return { id, nodeId: r.assigned_node_id ?? void 0, sessionId: r.assigned_session_id ?? void 0, message };
|
|
4496
4795
|
});
|
|
4497
4796
|
}
|
|
4498
|
-
|
|
4797
|
+
/**
|
|
4798
|
+
* Resolve the `assigned` queue row a completion event belongs to.
|
|
4799
|
+
*
|
|
4800
|
+
* Clock-skew safety (C2): a completion event's `occurredAtIso` carries the
|
|
4801
|
+
* REMOTE WORKER's clock, while `updated_at` carries the COORDINATOR's clock
|
|
4802
|
+
* (set at assignment and re-bumped on every mutation). For a remote node,
|
|
4803
|
+
* coordinator-clock > worker-clock skew used to make an `updated_at <= occurredAt`
|
|
4804
|
+
* filter return nothing, stranding the finished task as `assigned` forever.
|
|
4805
|
+
*
|
|
4806
|
+
* We therefore NEVER filter completion-matching on the mutable `updated_at`:
|
|
4807
|
+
* 1. If `taskId` is given, match the exact `assigned` row by id (no time filter).
|
|
4808
|
+
* 2. Otherwise a session holds at most one `assigned` task — match it without a
|
|
4809
|
+
* time filter. If several exist (shouldn't normally), disambiguate by the
|
|
4810
|
+
* IMMUTABLE `dispatchTimestamp`: latest `dispatchTimestamp <= occurredAt`,
|
|
4811
|
+
* and if skew makes ALL of them later than `occurredAt`, fall back to the
|
|
4812
|
+
* most-recent `dispatchTimestamp` rather than returning null.
|
|
4813
|
+
*/
|
|
4814
|
+
findAssignedBySession(meshId, sessionId, occurredAtIso, taskId) {
|
|
4499
4815
|
this.ensureLegacyQueueMigrated(meshId);
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4816
|
+
if (taskId) {
|
|
4817
|
+
const row = this.db.prepare(
|
|
4818
|
+
`SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned' AND id = ? LIMIT 1`
|
|
4819
|
+
).get(meshId, sessionId, taskId);
|
|
4820
|
+
if (row) return JSON.parse(row.payload);
|
|
4821
|
+
}
|
|
4822
|
+
const rows = this.db.prepare(
|
|
4823
|
+
`SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned'`
|
|
4824
|
+
).all(meshId, sessionId);
|
|
4825
|
+
if (rows.length === 0) return null;
|
|
4826
|
+
const entries = rows.map((r) => {
|
|
4827
|
+
try {
|
|
4828
|
+
return JSON.parse(r.payload);
|
|
4829
|
+
} catch {
|
|
4830
|
+
return null;
|
|
4831
|
+
}
|
|
4832
|
+
}).filter((e) => e !== null);
|
|
4833
|
+
if (entries.length === 0) return null;
|
|
4834
|
+
if (entries.length === 1) return entries[0];
|
|
4835
|
+
const orderKey = (e) => e.dispatchTimestamp ?? e.updatedAt ?? "";
|
|
4836
|
+
const byDispatchDesc = [...entries].sort((a, b) => orderKey(b).localeCompare(orderKey(a)));
|
|
4837
|
+
if (occurredAtIso) {
|
|
4838
|
+
const atOrBefore = byDispatchDesc.find((e) => orderKey(e) <= occurredAtIso);
|
|
4839
|
+
if (atOrBefore) return atOrBefore;
|
|
4840
|
+
}
|
|
4841
|
+
return byDispatchDesc[0];
|
|
4504
4842
|
}
|
|
4505
4843
|
toRow(entry) {
|
|
4506
4844
|
return {
|
|
@@ -5756,297 +6094,6 @@ var init_mesh_review_inbox = __esm({
|
|
|
5756
6094
|
}
|
|
5757
6095
|
});
|
|
5758
6096
|
|
|
5759
|
-
// src/logging/async-batch-writer.ts
|
|
5760
|
-
var fs3, AsyncBatchWriter;
|
|
5761
|
-
var init_async_batch_writer = __esm({
|
|
5762
|
-
"src/logging/async-batch-writer.ts"() {
|
|
5763
|
-
"use strict";
|
|
5764
|
-
fs3 = __toESM(require("fs"));
|
|
5765
|
-
AsyncBatchWriter = class {
|
|
5766
|
-
// Maps filePath -> string buffer
|
|
5767
|
-
static buffers = /* @__PURE__ */ new Map();
|
|
5768
|
-
static writePromises = /* @__PURE__ */ new Map();
|
|
5769
|
-
static flushTimer = null;
|
|
5770
|
-
/**
|
|
5771
|
-
* Queues data to be written to a file asynchronously in a batch.
|
|
5772
|
-
*/
|
|
5773
|
-
static write(filePath, data) {
|
|
5774
|
-
let buf = this.buffers.get(filePath);
|
|
5775
|
-
if (!buf) {
|
|
5776
|
-
buf = [];
|
|
5777
|
-
this.buffers.set(filePath, buf);
|
|
5778
|
-
}
|
|
5779
|
-
buf.push(data);
|
|
5780
|
-
if (!this.flushTimer) {
|
|
5781
|
-
this.flushTimer = setTimeout(() => {
|
|
5782
|
-
this.flushTimer = null;
|
|
5783
|
-
this.flushAll();
|
|
5784
|
-
}, 50);
|
|
5785
|
-
}
|
|
5786
|
-
}
|
|
5787
|
-
static async flushAll() {
|
|
5788
|
-
const entries = Array.from(this.buffers.entries());
|
|
5789
|
-
this.buffers.clear();
|
|
5790
|
-
for (const [filePath, buffer] of entries) {
|
|
5791
|
-
const dataToWrite = buffer.join("");
|
|
5792
|
-
const doWrite = async () => {
|
|
5793
|
-
try {
|
|
5794
|
-
const prevPromise = this.writePromises.get(filePath);
|
|
5795
|
-
if (prevPromise) await prevPromise;
|
|
5796
|
-
await fs3.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
|
|
5797
|
-
} catch {
|
|
5798
|
-
}
|
|
5799
|
-
};
|
|
5800
|
-
const writePromise = doWrite();
|
|
5801
|
-
this.writePromises.set(filePath, writePromise);
|
|
5802
|
-
writePromise.finally(() => {
|
|
5803
|
-
if (this.writePromises.get(filePath) === writePromise) {
|
|
5804
|
-
this.writePromises.delete(filePath);
|
|
5805
|
-
}
|
|
5806
|
-
});
|
|
5807
|
-
}
|
|
5808
|
-
}
|
|
5809
|
-
};
|
|
5810
|
-
}
|
|
5811
|
-
});
|
|
5812
|
-
|
|
5813
|
-
// src/logging/logger.ts
|
|
5814
|
-
var logger_exports = {};
|
|
5815
|
-
__export(logger_exports, {
|
|
5816
|
-
LOG: () => LOG,
|
|
5817
|
-
LOG_DIR_PATH: () => LOG_DIR_PATH,
|
|
5818
|
-
LOG_PATH: () => LOG_PATH,
|
|
5819
|
-
daemonLog: () => daemonLog,
|
|
5820
|
-
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
5821
|
-
getDaemonLogDir: () => getDaemonLogDir,
|
|
5822
|
-
getLogBufferSize: () => getLogBufferSize,
|
|
5823
|
-
getLogLevel: () => getLogLevel,
|
|
5824
|
-
getLogPath: () => getLogPath,
|
|
5825
|
-
getRecentLogs: () => getRecentLogs,
|
|
5826
|
-
installGlobalInterceptor: () => installGlobalInterceptor,
|
|
5827
|
-
setLogLevel: () => setLogLevel
|
|
5828
|
-
});
|
|
5829
|
-
function setLogLevel(level) {
|
|
5830
|
-
currentLevel = level;
|
|
5831
|
-
daemonLog("Logger", `Log level set to: ${level}`, "info");
|
|
5832
|
-
}
|
|
5833
|
-
function getLogLevel() {
|
|
5834
|
-
return currentLevel;
|
|
5835
|
-
}
|
|
5836
|
-
function getDateStr() {
|
|
5837
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5838
|
-
}
|
|
5839
|
-
function getDaemonLogDir() {
|
|
5840
|
-
return LOG_DIR;
|
|
5841
|
-
}
|
|
5842
|
-
function getCurrentDaemonLogPath(date = /* @__PURE__ */ new Date()) {
|
|
5843
|
-
return path9.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
|
|
5844
|
-
}
|
|
5845
|
-
function checkDateRotation() {
|
|
5846
|
-
const today = getDateStr();
|
|
5847
|
-
if (today !== currentDate) {
|
|
5848
|
-
currentDate = today;
|
|
5849
|
-
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
5850
|
-
cleanOldLogs();
|
|
5851
|
-
}
|
|
5852
|
-
}
|
|
5853
|
-
function cleanOldLogs() {
|
|
5854
|
-
try {
|
|
5855
|
-
const files = fs4.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
|
|
5856
|
-
const cutoff = /* @__PURE__ */ new Date();
|
|
5857
|
-
cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
|
|
5858
|
-
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
5859
|
-
for (const file of files) {
|
|
5860
|
-
const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
5861
|
-
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
5862
|
-
try {
|
|
5863
|
-
fs4.unlinkSync(path9.join(LOG_DIR, file));
|
|
5864
|
-
} catch {
|
|
5865
|
-
}
|
|
5866
|
-
}
|
|
5867
|
-
}
|
|
5868
|
-
} catch {
|
|
5869
|
-
}
|
|
5870
|
-
}
|
|
5871
|
-
function rotateSizeIfNeeded() {
|
|
5872
|
-
try {
|
|
5873
|
-
const stat2 = fs4.statSync(currentLogFile);
|
|
5874
|
-
if (stat2.size > MAX_LOG_SIZE) {
|
|
5875
|
-
const backup = currentLogFile.replace(".log", ".1.log");
|
|
5876
|
-
try {
|
|
5877
|
-
fs4.unlinkSync(backup);
|
|
5878
|
-
} catch {
|
|
5879
|
-
}
|
|
5880
|
-
fs4.renameSync(currentLogFile, backup);
|
|
5881
|
-
}
|
|
5882
|
-
} catch {
|
|
5883
|
-
}
|
|
5884
|
-
}
|
|
5885
|
-
function writeToFile(line) {
|
|
5886
|
-
try {
|
|
5887
|
-
if (++writeCount % 1e3 === 0) {
|
|
5888
|
-
checkDateRotation();
|
|
5889
|
-
rotateSizeIfNeeded();
|
|
5890
|
-
}
|
|
5891
|
-
AsyncBatchWriter.write(currentLogFile, line + "\n");
|
|
5892
|
-
} catch {
|
|
5893
|
-
}
|
|
5894
|
-
}
|
|
5895
|
-
function getRecentLogs(count = 50, minLevel = "info") {
|
|
5896
|
-
const minNum = LEVEL_NUM[minLevel];
|
|
5897
|
-
const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
|
|
5898
|
-
return filtered.slice(-count);
|
|
5899
|
-
}
|
|
5900
|
-
function getLogBufferSize() {
|
|
5901
|
-
return ringBuffer.length;
|
|
5902
|
-
}
|
|
5903
|
-
function ts() {
|
|
5904
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
5905
|
-
}
|
|
5906
|
-
function fullTs() {
|
|
5907
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
5908
|
-
}
|
|
5909
|
-
function daemonLog(category, msg, level = "info") {
|
|
5910
|
-
const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
|
|
5911
|
-
const label = LEVEL_LABEL[level];
|
|
5912
|
-
const line = `[${ts()}] [${label}] [${category}] ${msg}`;
|
|
5913
|
-
if (!shouldOutput) return;
|
|
5914
|
-
writeToFile(line);
|
|
5915
|
-
ringBuffer.push({ ts: Date.now(), level, category, message: msg });
|
|
5916
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5917
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5918
|
-
}
|
|
5919
|
-
origConsoleLog(line);
|
|
5920
|
-
}
|
|
5921
|
-
function installGlobalInterceptor() {
|
|
5922
|
-
if (interceptorInstalled) return;
|
|
5923
|
-
interceptorInstalled = true;
|
|
5924
|
-
const stripAnsi4 = (str) => str.replace(/\x1B\[[0-9;]*m/g, "");
|
|
5925
|
-
const isDaemonLogLine = (msg) => /\[(DBG|INF|WRN|ERR)\]/.test(msg);
|
|
5926
|
-
console.log = (...args) => {
|
|
5927
|
-
origConsoleLog(...args);
|
|
5928
|
-
try {
|
|
5929
|
-
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
5930
|
-
const clean = stripAnsi4(msg);
|
|
5931
|
-
if (isDaemonLogLine(clean)) return;
|
|
5932
|
-
const line = clean.startsWith("[20") ? clean : `[${fullTs()}] ${clean}`;
|
|
5933
|
-
writeToFile(line);
|
|
5934
|
-
const catMatch = clean.match(/\[([^\]]+)\]/);
|
|
5935
|
-
ringBuffer.push({
|
|
5936
|
-
ts: Date.now(),
|
|
5937
|
-
level: "info",
|
|
5938
|
-
category: catMatch?.[1] || "System",
|
|
5939
|
-
message: clean
|
|
5940
|
-
});
|
|
5941
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5942
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5943
|
-
}
|
|
5944
|
-
} catch {
|
|
5945
|
-
}
|
|
5946
|
-
};
|
|
5947
|
-
console.error = (...args) => {
|
|
5948
|
-
origConsoleError(...args);
|
|
5949
|
-
try {
|
|
5950
|
-
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
5951
|
-
const clean = stripAnsi4(msg);
|
|
5952
|
-
if (isDaemonLogLine(clean)) return;
|
|
5953
|
-
const line = `[${fullTs()}] [ERROR] ${clean}`;
|
|
5954
|
-
writeToFile(line);
|
|
5955
|
-
ringBuffer.push({ ts: Date.now(), level: "error", category: "System", message: clean });
|
|
5956
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5957
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5958
|
-
}
|
|
5959
|
-
} catch {
|
|
5960
|
-
}
|
|
5961
|
-
};
|
|
5962
|
-
console.warn = (...args) => {
|
|
5963
|
-
origConsoleWarn(...args);
|
|
5964
|
-
try {
|
|
5965
|
-
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
5966
|
-
const clean = stripAnsi4(msg);
|
|
5967
|
-
if (isDaemonLogLine(clean)) return;
|
|
5968
|
-
const line = `[${fullTs()}] [WARN] ${clean}`;
|
|
5969
|
-
writeToFile(line);
|
|
5970
|
-
ringBuffer.push({ ts: Date.now(), level: "warn", category: "System", message: clean });
|
|
5971
|
-
if (ringBuffer.length > RING_BUFFER_SIZE) {
|
|
5972
|
-
ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
|
|
5973
|
-
}
|
|
5974
|
-
} catch {
|
|
5975
|
-
}
|
|
5976
|
-
};
|
|
5977
|
-
writeToFile(`
|
|
5978
|
-
=== ADHDev Daemon started at ${fullTs()} ===`);
|
|
5979
|
-
writeToFile(`Log file: ${currentLogFile}`);
|
|
5980
|
-
writeToFile(`Log level: ${currentLevel}`);
|
|
5981
|
-
}
|
|
5982
|
-
function getLogPath() {
|
|
5983
|
-
return currentLogFile;
|
|
5984
|
-
}
|
|
5985
|
-
var fs4, path9, os3, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, LOG_DIR_PATH;
|
|
5986
|
-
var init_logger = __esm({
|
|
5987
|
-
"src/logging/logger.ts"() {
|
|
5988
|
-
"use strict";
|
|
5989
|
-
fs4 = __toESM(require("fs"));
|
|
5990
|
-
path9 = __toESM(require("path"));
|
|
5991
|
-
os3 = __toESM(require("os"));
|
|
5992
|
-
init_async_batch_writer();
|
|
5993
|
-
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
5994
|
-
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
5995
|
-
currentLevel = "info";
|
|
5996
|
-
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");
|
|
5997
|
-
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
5998
|
-
MAX_LOG_DAYS = 7;
|
|
5999
|
-
try {
|
|
6000
|
-
fs4.mkdirSync(LOG_DIR, { recursive: true });
|
|
6001
|
-
} catch {
|
|
6002
|
-
}
|
|
6003
|
-
currentDate = getDateStr();
|
|
6004
|
-
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
6005
|
-
cleanOldLogs();
|
|
6006
|
-
try {
|
|
6007
|
-
const oldLog = path9.join(LOG_DIR, "daemon.log");
|
|
6008
|
-
if (fs4.existsSync(oldLog)) {
|
|
6009
|
-
const stat2 = fs4.statSync(oldLog);
|
|
6010
|
-
const oldDate = stat2.mtime.toISOString().slice(0, 10);
|
|
6011
|
-
fs4.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
6012
|
-
}
|
|
6013
|
-
const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
|
|
6014
|
-
if (fs4.existsSync(oldLogBackup)) {
|
|
6015
|
-
fs4.unlinkSync(oldLogBackup);
|
|
6016
|
-
}
|
|
6017
|
-
} catch {
|
|
6018
|
-
}
|
|
6019
|
-
writeCount = 0;
|
|
6020
|
-
RING_BUFFER_SIZE = 200;
|
|
6021
|
-
ringBuffer = [];
|
|
6022
|
-
origConsoleLog = console.log.bind(console);
|
|
6023
|
-
origConsoleError = console.error.bind(console);
|
|
6024
|
-
origConsoleWarn = console.warn.bind(console);
|
|
6025
|
-
LOG = {
|
|
6026
|
-
debug: (category, msg) => daemonLog(category, msg, "debug"),
|
|
6027
|
-
info: (category, msg) => daemonLog(category, msg, "info"),
|
|
6028
|
-
warn: (category, msg) => daemonLog(category, msg, "warn"),
|
|
6029
|
-
error: (category, msg) => daemonLog(category, msg, "error"),
|
|
6030
|
-
/**
|
|
6031
|
-
* Create a scoped logger for a specific component.
|
|
6032
|
-
* Category is baked in so callers only pass the message.
|
|
6033
|
-
*/
|
|
6034
|
-
forComponent(category) {
|
|
6035
|
-
return {
|
|
6036
|
-
debug: (msg) => daemonLog(category, msg, "debug"),
|
|
6037
|
-
info: (msg) => daemonLog(category, msg, "info"),
|
|
6038
|
-
warn: (msg) => daemonLog(category, msg, "warn"),
|
|
6039
|
-
error: (msg) => daemonLog(category, msg, "error"),
|
|
6040
|
-
asLogFn: (level = "info") => (msg) => daemonLog(category, msg, level)
|
|
6041
|
-
};
|
|
6042
|
-
}
|
|
6043
|
-
};
|
|
6044
|
-
interceptorInstalled = false;
|
|
6045
|
-
LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
6046
|
-
LOG_DIR_PATH = LOG_DIR;
|
|
6047
|
-
}
|
|
6048
|
-
});
|
|
6049
|
-
|
|
6050
6097
|
// src/commands/mesh-coordinator.ts
|
|
6051
6098
|
var mesh_coordinator_exports = {};
|
|
6052
6099
|
__export(mesh_coordinator_exports, {
|
|
@@ -6448,6 +6495,59 @@ var init_mesh_coordinator = __esm({
|
|
|
6448
6495
|
}
|
|
6449
6496
|
});
|
|
6450
6497
|
|
|
6498
|
+
// src/cli-adapters/resolve-executable.ts
|
|
6499
|
+
function resolveWin32GlobalBin(trimmed) {
|
|
6500
|
+
if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
|
|
6501
|
+
return null;
|
|
6502
|
+
}
|
|
6503
|
+
const extraDirs = [];
|
|
6504
|
+
if (process.env.APPDATA) extraDirs.push(path10.join(process.env.APPDATA, "npm"));
|
|
6505
|
+
try {
|
|
6506
|
+
extraDirs.push(path10.dirname(process.execPath));
|
|
6507
|
+
} catch {
|
|
6508
|
+
}
|
|
6509
|
+
for (const dir of extraDirs) {
|
|
6510
|
+
if (!dir) continue;
|
|
6511
|
+
for (const ext of WIN_EXEC_EXT) {
|
|
6512
|
+
const full = path10.join(dir, trimmed + ext);
|
|
6513
|
+
if ((0, import_fs8.existsSync)(full)) return full;
|
|
6514
|
+
}
|
|
6515
|
+
}
|
|
6516
|
+
return null;
|
|
6517
|
+
}
|
|
6518
|
+
function resolveWin32Executable(command) {
|
|
6519
|
+
if (process.platform !== "win32") return command;
|
|
6520
|
+
const trimmed = (command || "").trim();
|
|
6521
|
+
if (!trimmed) return command;
|
|
6522
|
+
if (path10.isAbsolute(trimmed) && (0, import_fs8.existsSync)(trimmed)) return trimmed;
|
|
6523
|
+
try {
|
|
6524
|
+
const out = (0, import_child_process.execFileSync)("where", [trimmed], {
|
|
6525
|
+
encoding: "utf8",
|
|
6526
|
+
windowsHide: true
|
|
6527
|
+
}).trim();
|
|
6528
|
+
if (out) {
|
|
6529
|
+
const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
6530
|
+
const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path10.extname(m).toLowerCase()));
|
|
6531
|
+
return direct || matches[0] || command;
|
|
6532
|
+
}
|
|
6533
|
+
} catch {
|
|
6534
|
+
}
|
|
6535
|
+
const globalBin = resolveWin32GlobalBin(trimmed);
|
|
6536
|
+
if (globalBin) return globalBin;
|
|
6537
|
+
return command;
|
|
6538
|
+
}
|
|
6539
|
+
var import_child_process, import_fs8, path10, DIRECT_EXEC_EXT, WIN_EXEC_EXT;
|
|
6540
|
+
var init_resolve_executable = __esm({
|
|
6541
|
+
"src/cli-adapters/resolve-executable.ts"() {
|
|
6542
|
+
"use strict";
|
|
6543
|
+
import_child_process = require("child_process");
|
|
6544
|
+
import_fs8 = require("fs");
|
|
6545
|
+
path10 = __toESM(require("path"));
|
|
6546
|
+
DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
|
|
6547
|
+
WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
|
|
6548
|
+
}
|
|
6549
|
+
});
|
|
6550
|
+
|
|
6451
6551
|
// src/mesh/mesh-fast-forward.ts
|
|
6452
6552
|
async function fastForwardMeshNode(args) {
|
|
6453
6553
|
const workspace = typeof args.workspace === "string" ? args.workspace.trim() : "";
|
|
@@ -7971,9 +8071,9 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
7971
8071
|
const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
7972
8072
|
const events = [];
|
|
7973
8073
|
for (const path42 of paths) {
|
|
7974
|
-
if (!(0,
|
|
8074
|
+
if (!(0, import_fs10.existsSync)(path42)) continue;
|
|
7975
8075
|
try {
|
|
7976
|
-
const raw = (0,
|
|
8076
|
+
const raw = (0, import_fs10.readFileSync)(path42, "utf-8");
|
|
7977
8077
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
7978
8078
|
try {
|
|
7979
8079
|
return [JSON.parse(line)];
|
|
@@ -8048,11 +8148,11 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
8048
8148
|
}
|
|
8049
8149
|
function trimPendingEventsIfNeeded(path42) {
|
|
8050
8150
|
try {
|
|
8051
|
-
if (!(0,
|
|
8052
|
-
if ((0,
|
|
8053
|
-
const lines = (0,
|
|
8151
|
+
if (!(0, import_fs10.existsSync)(path42)) return;
|
|
8152
|
+
if ((0, import_fs10.statSync)(path42).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
8153
|
+
const lines = (0, import_fs10.readFileSync)(path42, "utf-8").split("\n").filter(Boolean);
|
|
8054
8154
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
8055
|
-
(0,
|
|
8155
|
+
(0, import_fs10.writeFileSync)(path42, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
|
|
8056
8156
|
} catch {
|
|
8057
8157
|
}
|
|
8058
8158
|
}
|
|
@@ -8081,7 +8181,7 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
8081
8181
|
}
|
|
8082
8182
|
const path42 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
|
|
8083
8183
|
trimPendingEventsIfNeeded(path42);
|
|
8084
|
-
(0,
|
|
8184
|
+
(0, import_fs10.appendFileSync)(path42, JSON.stringify(event) + "\n", "utf-8");
|
|
8085
8185
|
return true;
|
|
8086
8186
|
} catch (e) {
|
|
8087
8187
|
LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
@@ -8091,20 +8191,20 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
8091
8191
|
function atomicDrainFile(path42) {
|
|
8092
8192
|
const tmpPath = `${path42}.draining`;
|
|
8093
8193
|
try {
|
|
8094
|
-
(0,
|
|
8194
|
+
(0, import_fs10.renameSync)(path42, tmpPath);
|
|
8095
8195
|
} catch {
|
|
8096
8196
|
return null;
|
|
8097
8197
|
}
|
|
8098
8198
|
try {
|
|
8099
|
-
const content = (0,
|
|
8199
|
+
const content = (0, import_fs10.readFileSync)(tmpPath, "utf-8");
|
|
8100
8200
|
try {
|
|
8101
|
-
(0,
|
|
8201
|
+
(0, import_fs10.unlinkSync)(tmpPath);
|
|
8102
8202
|
} catch {
|
|
8103
8203
|
}
|
|
8104
8204
|
return content;
|
|
8105
8205
|
} catch {
|
|
8106
8206
|
try {
|
|
8107
|
-
(0,
|
|
8207
|
+
(0, import_fs10.unlinkSync)(tmpPath);
|
|
8108
8208
|
} catch {
|
|
8109
8209
|
}
|
|
8110
8210
|
return null;
|
|
@@ -8113,16 +8213,16 @@ function atomicDrainFile(path42) {
|
|
|
8113
8213
|
function selectiveDrainFile(path42, predicate) {
|
|
8114
8214
|
const tmpPath = `${path42}.draining`;
|
|
8115
8215
|
try {
|
|
8116
|
-
(0,
|
|
8216
|
+
(0, import_fs10.renameSync)(path42, tmpPath);
|
|
8117
8217
|
} catch {
|
|
8118
8218
|
return [];
|
|
8119
8219
|
}
|
|
8120
8220
|
let content;
|
|
8121
8221
|
try {
|
|
8122
|
-
content = (0,
|
|
8222
|
+
content = (0, import_fs10.readFileSync)(tmpPath, "utf-8");
|
|
8123
8223
|
} catch {
|
|
8124
8224
|
try {
|
|
8125
|
-
(0,
|
|
8225
|
+
(0, import_fs10.unlinkSync)(tmpPath);
|
|
8126
8226
|
} catch {
|
|
8127
8227
|
}
|
|
8128
8228
|
return [];
|
|
@@ -8145,12 +8245,12 @@ function selectiveDrainFile(path42, predicate) {
|
|
|
8145
8245
|
}
|
|
8146
8246
|
try {
|
|
8147
8247
|
if (keptLines.length > 0) {
|
|
8148
|
-
(0,
|
|
8248
|
+
(0, import_fs10.writeFileSync)(path42, keptLines.join("\n") + "\n", "utf-8");
|
|
8149
8249
|
}
|
|
8150
|
-
(0,
|
|
8250
|
+
(0, import_fs10.unlinkSync)(tmpPath);
|
|
8151
8251
|
} catch {
|
|
8152
8252
|
try {
|
|
8153
|
-
if ((0,
|
|
8253
|
+
if ((0, import_fs10.existsSync)(tmpPath) && !(0, import_fs10.existsSync)(path42)) (0, import_fs10.renameSync)(tmpPath, path42);
|
|
8154
8254
|
} catch {
|
|
8155
8255
|
}
|
|
8156
8256
|
return [];
|
|
@@ -8244,17 +8344,17 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
8244
8344
|
}
|
|
8245
8345
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
8246
8346
|
for (const path42 of paths) {
|
|
8247
|
-
if ((0,
|
|
8248
|
-
(0,
|
|
8347
|
+
if ((0, import_fs10.existsSync)(path42)) try {
|
|
8348
|
+
(0, import_fs10.unlinkSync)(path42);
|
|
8249
8349
|
} catch {
|
|
8250
8350
|
}
|
|
8251
8351
|
}
|
|
8252
8352
|
}
|
|
8253
|
-
var
|
|
8353
|
+
var import_fs10, import_path9, import_crypto7, REFINE_TERMINAL_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
|
|
8254
8354
|
var init_mesh_events_pending = __esm({
|
|
8255
8355
|
"src/mesh/mesh-events-pending.ts"() {
|
|
8256
8356
|
"use strict";
|
|
8257
|
-
|
|
8357
|
+
import_fs10 = require("fs");
|
|
8258
8358
|
import_path9 = require("path");
|
|
8259
8359
|
import_crypto7 = require("crypto");
|
|
8260
8360
|
init_logger();
|
|
@@ -8749,24 +8849,24 @@ function buildCliScreenSnapshot(text) {
|
|
|
8749
8849
|
function findBinary(name) {
|
|
8750
8850
|
const trimmed = String(name || "").trim();
|
|
8751
8851
|
if (!trimmed) return trimmed;
|
|
8752
|
-
const expanded = trimmed.startsWith("~") ?
|
|
8753
|
-
if (
|
|
8754
|
-
return
|
|
8852
|
+
const expanded = trimmed.startsWith("~") ? path11.join(os5.homedir(), trimmed.slice(1)) : trimmed;
|
|
8853
|
+
if (path11.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
8854
|
+
return path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
|
|
8755
8855
|
}
|
|
8756
8856
|
const isWin = os5.platform() === "win32";
|
|
8757
|
-
const paths = (process.env.PATH || "").split(
|
|
8857
|
+
const paths = (process.env.PATH || "").split(path11.delimiter);
|
|
8758
8858
|
const extraDirs = [];
|
|
8759
8859
|
if (isWin) {
|
|
8760
|
-
if (process.env.APPDATA) extraDirs.push(
|
|
8860
|
+
if (process.env.APPDATA) extraDirs.push(path11.join(process.env.APPDATA, "npm"));
|
|
8761
8861
|
try {
|
|
8762
|
-
extraDirs.push(
|
|
8862
|
+
extraDirs.push(path11.dirname(process.execPath));
|
|
8763
8863
|
} catch {
|
|
8764
8864
|
}
|
|
8765
8865
|
} else {
|
|
8766
|
-
extraDirs.push(
|
|
8866
|
+
extraDirs.push(path11.join(os5.homedir(), ".npm-global", "bin"));
|
|
8767
8867
|
extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
|
|
8768
8868
|
try {
|
|
8769
|
-
extraDirs.push(
|
|
8869
|
+
extraDirs.push(path11.dirname(process.execPath));
|
|
8770
8870
|
} catch {
|
|
8771
8871
|
}
|
|
8772
8872
|
}
|
|
@@ -8775,7 +8875,7 @@ function findBinary(name) {
|
|
|
8775
8875
|
for (const p of searchDirs) {
|
|
8776
8876
|
if (!p) continue;
|
|
8777
8877
|
for (const ext of exes) {
|
|
8778
|
-
const fullPath =
|
|
8878
|
+
const fullPath = path11.join(p, trimmed + ext);
|
|
8779
8879
|
try {
|
|
8780
8880
|
const fs32 = require("fs");
|
|
8781
8881
|
if (fs32.existsSync(fullPath)) {
|
|
@@ -8791,7 +8891,7 @@ function findBinary(name) {
|
|
|
8791
8891
|
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
8792
8892
|
}
|
|
8793
8893
|
function isScriptBinary(binaryPath) {
|
|
8794
|
-
if (!
|
|
8894
|
+
if (!path11.isAbsolute(binaryPath)) return false;
|
|
8795
8895
|
try {
|
|
8796
8896
|
const fs32 = require("fs");
|
|
8797
8897
|
const resolved = fs32.realpathSync(binaryPath);
|
|
@@ -8807,7 +8907,7 @@ function isScriptBinary(binaryPath) {
|
|
|
8807
8907
|
}
|
|
8808
8908
|
}
|
|
8809
8909
|
function looksLikeMachOOrElf(filePath) {
|
|
8810
|
-
if (!
|
|
8910
|
+
if (!path11.isAbsolute(filePath)) return false;
|
|
8811
8911
|
try {
|
|
8812
8912
|
const fs32 = require("fs");
|
|
8813
8913
|
const resolved = fs32.realpathSync(filePath);
|
|
@@ -8896,12 +8996,12 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
8896
8996
|
}
|
|
8897
8997
|
};
|
|
8898
8998
|
}
|
|
8899
|
-
var os5,
|
|
8999
|
+
var os5, path11, TerminalTranscriptAccumulator, buildCliSpawnEnv;
|
|
8900
9000
|
var init_provider_cli_shared = __esm({
|
|
8901
9001
|
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
8902
9002
|
"use strict";
|
|
8903
9003
|
os5 = __toESM(require("os"));
|
|
8904
|
-
|
|
9004
|
+
path11 = __toESM(require("path"));
|
|
8905
9005
|
init_spawn_env();
|
|
8906
9006
|
TerminalTranscriptAccumulator = class {
|
|
8907
9007
|
lines = [[]];
|
|
@@ -9075,19 +9175,19 @@ function shellQuote(value) {
|
|
|
9075
9175
|
function expandHome(value) {
|
|
9076
9176
|
const trimmed = value.trim();
|
|
9077
9177
|
if (!trimmed.startsWith("~")) return trimmed;
|
|
9078
|
-
return
|
|
9178
|
+
return path12.join(os6.homedir(), trimmed.slice(1));
|
|
9079
9179
|
}
|
|
9080
9180
|
function isExplicitCommandPath(command) {
|
|
9081
9181
|
const trimmed = command.trim();
|
|
9082
|
-
return
|
|
9182
|
+
return path12.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
9083
9183
|
}
|
|
9084
9184
|
function resolveCommandPath(command) {
|
|
9085
9185
|
const trimmed = command.trim();
|
|
9086
9186
|
if (!trimmed) return null;
|
|
9087
9187
|
if (isExplicitCommandPath(trimmed)) {
|
|
9088
9188
|
const expanded = expandHome(trimmed);
|
|
9089
|
-
const candidate =
|
|
9090
|
-
return (0,
|
|
9189
|
+
const candidate = path12.isAbsolute(expanded) ? expanded : path12.resolve(expanded);
|
|
9190
|
+
return (0, import_fs11.existsSync)(candidate) ? candidate : null;
|
|
9091
9191
|
}
|
|
9092
9192
|
return null;
|
|
9093
9193
|
}
|
|
@@ -9097,12 +9197,12 @@ async function resolveDetectionPath(command, whichCmd) {
|
|
|
9097
9197
|
const whichResult = await execAsync(`${whichCmd} ${shellQuote(command)}`);
|
|
9098
9198
|
if (whichResult) return whichResult.split("\n")[0];
|
|
9099
9199
|
const resolved = findBinary(command);
|
|
9100
|
-
if (
|
|
9200
|
+
if (path12.isAbsolute(resolved) && (0, import_fs11.existsSync)(resolved)) return resolved;
|
|
9101
9201
|
return null;
|
|
9102
9202
|
}
|
|
9103
9203
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
9104
9204
|
return new Promise((resolve24) => {
|
|
9105
|
-
const child = (0,
|
|
9205
|
+
const child = (0, import_child_process2.exec)(cmd, {
|
|
9106
9206
|
encoding: "utf-8",
|
|
9107
9207
|
timeout: timeoutMs,
|
|
9108
9208
|
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
@@ -9192,14 +9292,14 @@ async function detectCLI(cliId, providerLoader, options) {
|
|
|
9192
9292
|
const all = await detectCLIs(providerLoader, options);
|
|
9193
9293
|
return all.find((c) => c.id === resolvedId && c.installed) || null;
|
|
9194
9294
|
}
|
|
9195
|
-
var
|
|
9295
|
+
var import_child_process2, os6, path12, import_fs11;
|
|
9196
9296
|
var init_cli_detector = __esm({
|
|
9197
9297
|
"src/detection/cli-detector.ts"() {
|
|
9198
9298
|
"use strict";
|
|
9199
|
-
|
|
9299
|
+
import_child_process2 = require("child_process");
|
|
9200
9300
|
os6 = __toESM(require("os"));
|
|
9201
|
-
|
|
9202
|
-
|
|
9301
|
+
path12 = __toESM(require("path"));
|
|
9302
|
+
import_fs11 = require("fs");
|
|
9203
9303
|
init_provider_cli_shared();
|
|
9204
9304
|
}
|
|
9205
9305
|
});
|
|
@@ -10234,7 +10334,7 @@ async function maybeAutoFastForwardIdleNode(components, args) {
|
|
|
10234
10334
|
const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
|
|
10235
10335
|
const workspace = readNonEmptyString2(node?.workspace);
|
|
10236
10336
|
if (!workspace) return;
|
|
10237
|
-
if (!(0,
|
|
10337
|
+
if (!(0, import_fs12.existsSync)(workspace)) return;
|
|
10238
10338
|
const policy = resolveAutoFastForwardPolicy(mesh);
|
|
10239
10339
|
if (!policy.enabled) return;
|
|
10240
10340
|
if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId, args.sessionId)) return;
|
|
@@ -10433,8 +10533,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
10433
10533
|
}
|
|
10434
10534
|
}
|
|
10435
10535
|
function markSessionTerminal(sessionId, outcome, occurredAtMs) {
|
|
10536
|
+
const eventTaskId = readNonEmptyString2(args.metadataEvent.taskId) || void 0;
|
|
10436
10537
|
const task = updateSessionTaskStatus(args.meshId, sessionId, outcome, {
|
|
10437
|
-
occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0
|
|
10538
|
+
occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0,
|
|
10539
|
+
taskId: eventTaskId
|
|
10438
10540
|
});
|
|
10439
10541
|
updateDirectDispatchStatus(args.meshId, sessionId, outcome);
|
|
10440
10542
|
markSessionDeliveriesTerminal(args.meshId, sessionId, outcome);
|
|
@@ -10845,11 +10947,11 @@ function setupMeshEventForwarding(components) {
|
|
|
10845
10947
|
});
|
|
10846
10948
|
});
|
|
10847
10949
|
}
|
|
10848
|
-
var
|
|
10950
|
+
var import_fs12, REMOTE_IDLE_SESSION_TTL_MS, meshByWorkspaceCache, MESH_WORKSPACE_CACHE_TTL_MS, IDLE_AUTO_FAST_FORWARD_THROTTLE_MS, idleAutoFastForwardLastAttempt, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS, AUTO_LAUNCH_AWAIT_CLAIM_MS, lastAutoLaunchLedgerKey, AUTO_LAUNCH_LEDGER_DEDUP_MAX, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, MESH_FORCE_INJECT_EVENTS;
|
|
10849
10951
|
var init_mesh_events_coordinator = __esm({
|
|
10850
10952
|
"src/mesh/mesh-events-coordinator.ts"() {
|
|
10851
10953
|
"use strict";
|
|
10852
|
-
|
|
10954
|
+
import_fs12 = require("fs");
|
|
10853
10955
|
init_config();
|
|
10854
10956
|
init_mesh_config();
|
|
10855
10957
|
init_cli_detector();
|
|
@@ -12731,16 +12833,16 @@ __export(external_sources_exports, {
|
|
|
12731
12833
|
sourcesProviding: () => sourcesProviding
|
|
12732
12834
|
});
|
|
12733
12835
|
function adhdevDir() {
|
|
12734
|
-
return
|
|
12836
|
+
return path18.join(os11.homedir(), ".adhdev");
|
|
12735
12837
|
}
|
|
12736
12838
|
function externalRoot() {
|
|
12737
|
-
return
|
|
12839
|
+
return path18.join(adhdevDir(), "external");
|
|
12738
12840
|
}
|
|
12739
12841
|
function sourcesFilePath() {
|
|
12740
|
-
return
|
|
12842
|
+
return path18.join(adhdevDir(), SOURCES_FILENAME);
|
|
12741
12843
|
}
|
|
12742
12844
|
function activeFilePath() {
|
|
12743
|
-
return
|
|
12845
|
+
return path18.join(adhdevDir(), ACTIVE_FILENAME);
|
|
12744
12846
|
}
|
|
12745
12847
|
function ensureAdhdevDir() {
|
|
12746
12848
|
const d = adhdevDir();
|
|
@@ -12807,7 +12909,7 @@ function inventoryExternalSources() {
|
|
|
12807
12909
|
for (const sourceEntry of entries) {
|
|
12808
12910
|
if (!sourceEntry.isDirectory()) continue;
|
|
12809
12911
|
const sourceName = sourceEntry.name;
|
|
12810
|
-
const sourceDir =
|
|
12912
|
+
const sourceDir = path18.join(root, sourceName);
|
|
12811
12913
|
const providers = {};
|
|
12812
12914
|
let categoryEntries;
|
|
12813
12915
|
try {
|
|
@@ -12818,7 +12920,7 @@ function inventoryExternalSources() {
|
|
|
12818
12920
|
for (const categoryEntry of categoryEntries) {
|
|
12819
12921
|
if (!categoryEntry.isDirectory()) continue;
|
|
12820
12922
|
const category = categoryEntry.name;
|
|
12821
|
-
const categoryDir =
|
|
12923
|
+
const categoryDir = path18.join(sourceDir, category);
|
|
12822
12924
|
let typeEntries;
|
|
12823
12925
|
try {
|
|
12824
12926
|
typeEntries = fs9.readdirSync(categoryDir, { withFileTypes: true });
|
|
@@ -12828,9 +12930,9 @@ function inventoryExternalSources() {
|
|
|
12828
12930
|
const types = [];
|
|
12829
12931
|
for (const typeEntry of typeEntries) {
|
|
12830
12932
|
if (!typeEntry.isDirectory()) continue;
|
|
12831
|
-
const typeDir =
|
|
12832
|
-
const hasV1 = fs9.existsSync(
|
|
12833
|
-
const hasV0 = fs9.existsSync(
|
|
12933
|
+
const typeDir = path18.join(categoryDir, typeEntry.name);
|
|
12934
|
+
const hasV1 = fs9.existsSync(path18.join(typeDir, "provider.v1.json"));
|
|
12935
|
+
const hasV0 = fs9.existsSync(path18.join(typeDir, "provider.json"));
|
|
12834
12936
|
if (hasV1 || hasV0) types.push(typeEntry.name);
|
|
12835
12937
|
}
|
|
12836
12938
|
if (types.length > 0) providers[category] = types;
|
|
@@ -12853,13 +12955,13 @@ function resolveActiveSource(category, type, activeFile) {
|
|
|
12853
12955
|
}
|
|
12854
12956
|
return { source: candidates[0], ambiguous: true, candidates };
|
|
12855
12957
|
}
|
|
12856
|
-
var fs9, os11,
|
|
12958
|
+
var fs9, os11, path18, SOURCES_FILENAME, ACTIVE_FILENAME;
|
|
12857
12959
|
var init_external_sources = __esm({
|
|
12858
12960
|
"src/providers/external-sources.ts"() {
|
|
12859
12961
|
"use strict";
|
|
12860
12962
|
fs9 = __toESM(require("fs"));
|
|
12861
12963
|
os11 = __toESM(require("os"));
|
|
12862
|
-
|
|
12964
|
+
path18 = __toESM(require("path"));
|
|
12863
12965
|
SOURCES_FILENAME = "providers-sources.json";
|
|
12864
12966
|
ACTIVE_FILENAME = "providers-active.json";
|
|
12865
12967
|
}
|
|
@@ -13037,59 +13139,6 @@ var init_terminal_screen = __esm({
|
|
|
13037
13139
|
}
|
|
13038
13140
|
});
|
|
13039
13141
|
|
|
13040
|
-
// src/cli-adapters/resolve-executable.ts
|
|
13041
|
-
function resolveWin32GlobalBin(trimmed) {
|
|
13042
|
-
if (path18.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
|
|
13043
|
-
return null;
|
|
13044
|
-
}
|
|
13045
|
-
const extraDirs = [];
|
|
13046
|
-
if (process.env.APPDATA) extraDirs.push(path18.join(process.env.APPDATA, "npm"));
|
|
13047
|
-
try {
|
|
13048
|
-
extraDirs.push(path18.dirname(process.execPath));
|
|
13049
|
-
} catch {
|
|
13050
|
-
}
|
|
13051
|
-
for (const dir of extraDirs) {
|
|
13052
|
-
if (!dir) continue;
|
|
13053
|
-
for (const ext of WIN_EXEC_EXT) {
|
|
13054
|
-
const full = path18.join(dir, trimmed + ext);
|
|
13055
|
-
if ((0, import_fs14.existsSync)(full)) return full;
|
|
13056
|
-
}
|
|
13057
|
-
}
|
|
13058
|
-
return null;
|
|
13059
|
-
}
|
|
13060
|
-
function resolveWin32Executable(command) {
|
|
13061
|
-
if (process.platform !== "win32") return command;
|
|
13062
|
-
const trimmed = (command || "").trim();
|
|
13063
|
-
if (!trimmed) return command;
|
|
13064
|
-
if (path18.isAbsolute(trimmed) && (0, import_fs14.existsSync)(trimmed)) return trimmed;
|
|
13065
|
-
try {
|
|
13066
|
-
const out = (0, import_child_process4.execFileSync)("where", [trimmed], {
|
|
13067
|
-
encoding: "utf8",
|
|
13068
|
-
windowsHide: true
|
|
13069
|
-
}).trim();
|
|
13070
|
-
if (out) {
|
|
13071
|
-
const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
13072
|
-
const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path18.extname(m).toLowerCase()));
|
|
13073
|
-
return direct || matches[0] || command;
|
|
13074
|
-
}
|
|
13075
|
-
} catch {
|
|
13076
|
-
}
|
|
13077
|
-
const globalBin = resolveWin32GlobalBin(trimmed);
|
|
13078
|
-
if (globalBin) return globalBin;
|
|
13079
|
-
return command;
|
|
13080
|
-
}
|
|
13081
|
-
var import_child_process4, import_fs14, path18, DIRECT_EXEC_EXT, WIN_EXEC_EXT;
|
|
13082
|
-
var init_resolve_executable = __esm({
|
|
13083
|
-
"src/cli-adapters/resolve-executable.ts"() {
|
|
13084
|
-
"use strict";
|
|
13085
|
-
import_child_process4 = require("child_process");
|
|
13086
|
-
import_fs14 = require("fs");
|
|
13087
|
-
path18 = __toESM(require("path"));
|
|
13088
|
-
DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
|
|
13089
|
-
WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
|
|
13090
|
-
}
|
|
13091
|
-
});
|
|
13092
|
-
|
|
13093
13142
|
// src/cli-adapters/pty-transport.ts
|
|
13094
13143
|
var pty_transport_exports = {};
|
|
13095
13144
|
__export(pty_transport_exports, {
|
|
@@ -19793,13 +19842,20 @@ var MESH_REFINE_CONFIG_SCHEMA = {
|
|
|
19793
19842
|
function isMeshConfigRecord(value) {
|
|
19794
19843
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
19795
19844
|
}
|
|
19845
|
+
var SHELL_METACHAR_RE = /[;&|<>`$\n\r'"]/;
|
|
19846
|
+
var SAFE_TOKEN_RE = /^[A-Za-z0-9_@./:=+-]+$/;
|
|
19847
|
+
var SAFE_WIN32_EXEC_TOKEN_RE = /^[A-Za-z0-9_@./:=+\\-]+$/;
|
|
19796
19848
|
function tokenizeCommandString(command) {
|
|
19797
19849
|
const trimmed = command.trim();
|
|
19798
19850
|
if (!trimmed) return null;
|
|
19799
|
-
if (
|
|
19851
|
+
if (SHELL_METACHAR_RE.test(trimmed)) return null;
|
|
19800
19852
|
const tokens = trimmed.split(/\s+/).filter(Boolean);
|
|
19801
19853
|
if (!tokens.length) return null;
|
|
19802
|
-
|
|
19854
|
+
const isWin32 = process.platform === "win32";
|
|
19855
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
19856
|
+
const re = isWin32 && i === 0 ? SAFE_WIN32_EXEC_TOKEN_RE : SAFE_TOKEN_RE;
|
|
19857
|
+
if (!re.test(tokens[i])) return null;
|
|
19858
|
+
}
|
|
19803
19859
|
return tokens;
|
|
19804
19860
|
}
|
|
19805
19861
|
function validateCategory(value) {
|
|
@@ -20009,12 +20065,13 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
|
20009
20065
|
}
|
|
20010
20066
|
|
|
20011
20067
|
// src/mesh/worktree-bootstrap-config.ts
|
|
20012
|
-
var
|
|
20068
|
+
var import_fs9 = require("fs");
|
|
20013
20069
|
var import_path8 = require("path");
|
|
20014
20070
|
var import_node_child_process3 = require("child_process");
|
|
20015
20071
|
var import_node_crypto2 = require("crypto");
|
|
20016
20072
|
var import_node_util3 = require("util");
|
|
20017
20073
|
var yaml3 = __toESM(require("js-yaml"));
|
|
20074
|
+
init_resolve_executable();
|
|
20018
20075
|
var MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS = [
|
|
20019
20076
|
".adhdev/worktree_bootstrap.json",
|
|
20020
20077
|
".adhdev/worktree_bootstrap.yaml",
|
|
@@ -20102,9 +20159,9 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
20102
20159
|
}
|
|
20103
20160
|
for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
20104
20161
|
const configPath = (0, import_path8.join)(workspace, relative5);
|
|
20105
|
-
if (!(0,
|
|
20162
|
+
if (!(0, import_fs9.existsSync)(configPath)) continue;
|
|
20106
20163
|
try {
|
|
20107
|
-
const parsed = parseConfigText3(configPath, (0,
|
|
20164
|
+
const parsed = parseConfigText3(configPath, (0, import_fs9.readFileSync)(configPath, "utf-8"));
|
|
20108
20165
|
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
|
|
20109
20166
|
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
20110
20167
|
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
@@ -20119,7 +20176,7 @@ function computeStaleInputsDigest(workspace, staleInputs) {
|
|
|
20119
20176
|
for (const relative5 of staleInputs ?? []) {
|
|
20120
20177
|
const filePath = (0, import_path8.join)(workspace, relative5);
|
|
20121
20178
|
try {
|
|
20122
|
-
digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0,
|
|
20179
|
+
digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0, import_fs9.readFileSync)(filePath)).digest("hex");
|
|
20123
20180
|
} catch {
|
|
20124
20181
|
digest[relative5] = "absent";
|
|
20125
20182
|
}
|
|
@@ -20189,10 +20246,10 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
|
20189
20246
|
staleInputs: loaded.config.staleInputs
|
|
20190
20247
|
};
|
|
20191
20248
|
const staleInputPaths = loaded.config.staleInputs ?? [];
|
|
20192
|
-
const initiallyAbsent = staleInputPaths.filter((p) => !(0,
|
|
20249
|
+
const initiallyAbsent = staleInputPaths.filter((p) => !(0, import_fs9.existsSync)((0, import_path8.join)(workspace, p)));
|
|
20193
20250
|
for (const command of validation.commands) {
|
|
20194
20251
|
if (initiallyAbsent.length > 0) {
|
|
20195
|
-
const appearedNow = initiallyAbsent.filter((p) => (0,
|
|
20252
|
+
const appearedNow = initiallyAbsent.filter((p) => (0, import_fs9.existsSync)((0, import_path8.join)(workspace, p)));
|
|
20196
20253
|
if (appearedNow.length > 0) {
|
|
20197
20254
|
state.status = "stale";
|
|
20198
20255
|
state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -20203,8 +20260,9 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
|
20203
20260
|
const cwd = command.cwd ? (0, import_path8.resolve)(workspace, command.cwd) : workspace;
|
|
20204
20261
|
const startedAt = Date.now();
|
|
20205
20262
|
state.lastCommand = command.displayCommand;
|
|
20263
|
+
const resolvedCommand = resolveWin32Executable(command.command);
|
|
20206
20264
|
try {
|
|
20207
|
-
const result = await execFileAsync4(
|
|
20265
|
+
const result = await execFileAsync4(resolvedCommand, command.args, {
|
|
20208
20266
|
cwd,
|
|
20209
20267
|
encoding: "utf8",
|
|
20210
20268
|
timeout: command.timeoutMs || DEFAULT_TIMEOUT_MS2,
|
|
@@ -20439,7 +20497,7 @@ var P2pRelayFailureError = class extends Error {
|
|
|
20439
20497
|
};
|
|
20440
20498
|
|
|
20441
20499
|
// src/config/state-store.ts
|
|
20442
|
-
var
|
|
20500
|
+
var import_fs13 = require("fs");
|
|
20443
20501
|
var import_path10 = require("path");
|
|
20444
20502
|
init_config();
|
|
20445
20503
|
var DEFAULT_STATE = {
|
|
@@ -20490,11 +20548,11 @@ function normalizeState(raw) {
|
|
|
20490
20548
|
}
|
|
20491
20549
|
function loadState() {
|
|
20492
20550
|
const statePath = getStatePath();
|
|
20493
|
-
if (!(0,
|
|
20551
|
+
if (!(0, import_fs13.existsSync)(statePath)) {
|
|
20494
20552
|
return { ...DEFAULT_STATE };
|
|
20495
20553
|
}
|
|
20496
20554
|
try {
|
|
20497
|
-
const raw = (0,
|
|
20555
|
+
const raw = (0, import_fs13.readFileSync)(statePath, "utf-8");
|
|
20498
20556
|
return normalizeState(JSON.parse(raw));
|
|
20499
20557
|
} catch {
|
|
20500
20558
|
return { ...DEFAULT_STATE };
|
|
@@ -20503,28 +20561,28 @@ function loadState() {
|
|
|
20503
20561
|
function saveState(state) {
|
|
20504
20562
|
const statePath = getStatePath();
|
|
20505
20563
|
const normalized = normalizeState(state);
|
|
20506
|
-
(0,
|
|
20564
|
+
(0, import_fs13.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
20507
20565
|
}
|
|
20508
20566
|
function resetState() {
|
|
20509
20567
|
saveState({ ...DEFAULT_STATE });
|
|
20510
20568
|
}
|
|
20511
20569
|
|
|
20512
20570
|
// src/detection/ide-detector.ts
|
|
20513
|
-
var
|
|
20571
|
+
var import_child_process3 = require("child_process");
|
|
20514
20572
|
var import_util = require("util");
|
|
20515
|
-
var
|
|
20573
|
+
var import_fs14 = require("fs");
|
|
20516
20574
|
var import_os2 = require("os");
|
|
20517
|
-
var
|
|
20575
|
+
var path14 = __toESM(require("path"));
|
|
20518
20576
|
|
|
20519
20577
|
// src/detection/win32-ide-version.ts
|
|
20520
20578
|
var fs5 = __toESM(require("fs"));
|
|
20521
|
-
var
|
|
20579
|
+
var path13 = __toESM(require("path"));
|
|
20522
20580
|
function manifestCandidates(exeDir) {
|
|
20523
20581
|
return [
|
|
20524
|
-
|
|
20525
|
-
|
|
20582
|
+
path13.join(exeDir, "resources", "app", "product.json"),
|
|
20583
|
+
path13.join(exeDir, "resources", "app", "package.json"),
|
|
20526
20584
|
// Some packagings keep product.json one level up.
|
|
20527
|
-
|
|
20585
|
+
path13.join(exeDir, "product.json")
|
|
20528
20586
|
];
|
|
20529
20587
|
}
|
|
20530
20588
|
function parseVersionFromManifest(raw) {
|
|
@@ -20542,9 +20600,9 @@ function readWin32IdeVersionFromDisk(exePath) {
|
|
|
20542
20600
|
if (!exePath) return null;
|
|
20543
20601
|
let exeDir;
|
|
20544
20602
|
try {
|
|
20545
|
-
exeDir = fs5.statSync(exePath).isDirectory() ? exePath :
|
|
20603
|
+
exeDir = fs5.statSync(exePath).isDirectory() ? exePath : path13.dirname(exePath);
|
|
20546
20604
|
} catch {
|
|
20547
|
-
exeDir =
|
|
20605
|
+
exeDir = path13.dirname(exePath);
|
|
20548
20606
|
}
|
|
20549
20607
|
for (const candidate of manifestCandidates(exeDir)) {
|
|
20550
20608
|
try {
|
|
@@ -20558,7 +20616,7 @@ function readWin32IdeVersionFromDisk(exePath) {
|
|
|
20558
20616
|
}
|
|
20559
20617
|
function isKnownWin32GuiExe(binPath, win32ProcessNames) {
|
|
20560
20618
|
if (!binPath) return false;
|
|
20561
|
-
const base =
|
|
20619
|
+
const base = path13.win32.basename(binPath).toLowerCase();
|
|
20562
20620
|
if (!base.endsWith(".exe")) return false;
|
|
20563
20621
|
for (const names of Object.values(win32ProcessNames)) {
|
|
20564
20622
|
for (const name of names) {
|
|
@@ -20571,7 +20629,7 @@ function isKnownWin32GuiExe(binPath, win32ProcessNames) {
|
|
|
20571
20629
|
}
|
|
20572
20630
|
|
|
20573
20631
|
// src/detection/ide-detector.ts
|
|
20574
|
-
var execAsync2 = (0, import_util.promisify)(
|
|
20632
|
+
var execAsync2 = (0, import_util.promisify)(import_child_process3.exec);
|
|
20575
20633
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
20576
20634
|
var registeredIDEs = /* @__PURE__ */ new Map();
|
|
20577
20635
|
function registerIDEDefinition(def) {
|
|
@@ -20590,10 +20648,10 @@ function getMergedDefinitions() {
|
|
|
20590
20648
|
function findCliCommand(command) {
|
|
20591
20649
|
const trimmed = String(command || "").trim();
|
|
20592
20650
|
if (!trimmed) return null;
|
|
20593
|
-
if (
|
|
20594
|
-
const candidate = trimmed.startsWith("~") ?
|
|
20595
|
-
const resolved =
|
|
20596
|
-
return (0,
|
|
20651
|
+
if (path14.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
20652
|
+
const candidate = trimmed.startsWith("~") ? path14.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
|
|
20653
|
+
const resolved = path14.isAbsolute(candidate) ? candidate : path14.resolve(candidate);
|
|
20654
|
+
return (0, import_fs14.existsSync)(resolved) ? resolved : null;
|
|
20597
20655
|
}
|
|
20598
20656
|
const isWin = (0, import_os2.platform)() === "win32";
|
|
20599
20657
|
const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
|
|
@@ -20601,10 +20659,10 @@ function findCliCommand(command) {
|
|
|
20601
20659
|
for (const p of paths) {
|
|
20602
20660
|
if (!p) continue;
|
|
20603
20661
|
for (const ext of exes) {
|
|
20604
|
-
const fullPath =
|
|
20662
|
+
const fullPath = path14.join(p, trimmed + ext);
|
|
20605
20663
|
try {
|
|
20606
|
-
if ((0,
|
|
20607
|
-
const stat2 = (0,
|
|
20664
|
+
if ((0, import_fs14.existsSync)(fullPath)) {
|
|
20665
|
+
const stat2 = (0, import_fs14.statSync)(fullPath);
|
|
20608
20666
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
20609
20667
|
return fullPath;
|
|
20610
20668
|
}
|
|
@@ -20618,13 +20676,13 @@ function findCliCommand(command) {
|
|
|
20618
20676
|
function checkPathExists(paths) {
|
|
20619
20677
|
const home = (0, import_os2.homedir)();
|
|
20620
20678
|
for (const p of paths) {
|
|
20621
|
-
const normalized = p.startsWith("~") ?
|
|
20679
|
+
const normalized = p.startsWith("~") ? path14.join(home, p.slice(1)) : p;
|
|
20622
20680
|
if (normalized.includes("*")) {
|
|
20623
20681
|
const username = home.split(/[\\/]/).pop() || "";
|
|
20624
20682
|
const resolved = normalized.replace("*", username);
|
|
20625
|
-
if ((0,
|
|
20683
|
+
if ((0, import_fs14.existsSync)(resolved)) return resolved;
|
|
20626
20684
|
} else {
|
|
20627
|
-
if ((0,
|
|
20685
|
+
if ((0, import_fs14.existsSync)(normalized)) return normalized;
|
|
20628
20686
|
}
|
|
20629
20687
|
}
|
|
20630
20688
|
return null;
|
|
@@ -20638,7 +20696,7 @@ async function detectIDEs(providerLoader) {
|
|
|
20638
20696
|
let resolvedCli = cliPath;
|
|
20639
20697
|
if (!resolvedCli && appPath && os30 === "darwin") {
|
|
20640
20698
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
20641
|
-
if ((0,
|
|
20699
|
+
if ((0, import_fs14.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
20642
20700
|
}
|
|
20643
20701
|
if (!resolvedCli && appPath && os30 === "win32") {
|
|
20644
20702
|
const { dirname: dirname17 } = await import("path");
|
|
@@ -20651,7 +20709,7 @@ async function detectIDEs(providerLoader) {
|
|
|
20651
20709
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
20652
20710
|
];
|
|
20653
20711
|
for (const c of candidates) {
|
|
20654
|
-
if ((0,
|
|
20712
|
+
if ((0, import_fs14.existsSync)(c)) {
|
|
20655
20713
|
resolvedCli = c;
|
|
20656
20714
|
break;
|
|
20657
20715
|
}
|
|
@@ -20678,9 +20736,9 @@ init_cli_detector();
|
|
|
20678
20736
|
|
|
20679
20737
|
// src/system/host-memory.ts
|
|
20680
20738
|
var os7 = __toESM(require("os"));
|
|
20681
|
-
var
|
|
20739
|
+
var import_child_process4 = require("child_process");
|
|
20682
20740
|
var import_util2 = require("util");
|
|
20683
|
-
var execAsync3 = (0, import_util2.promisify)(
|
|
20741
|
+
var execAsync3 = (0, import_util2.promisify)(import_child_process4.exec);
|
|
20684
20742
|
var cachedDarwinAvail = null;
|
|
20685
20743
|
var darwinMemoryInterval = null;
|
|
20686
20744
|
async function updateDarwinMemoryCache() {
|
|
@@ -22509,10 +22567,10 @@ ${cleanBody}`;
|
|
|
22509
22567
|
|
|
22510
22568
|
// src/config/chat-history.ts
|
|
22511
22569
|
var fs6 = __toESM(require("fs"));
|
|
22512
|
-
var
|
|
22570
|
+
var path15 = __toESM(require("path"));
|
|
22513
22571
|
var os8 = __toESM(require("os"));
|
|
22514
22572
|
init_chat_message_normalization();
|
|
22515
|
-
var HISTORY_DIR =
|
|
22573
|
+
var HISTORY_DIR = path15.join(os8.homedir(), ".adhdev", "history");
|
|
22516
22574
|
var RETAIN_DAYS = 30;
|
|
22517
22575
|
var SAVED_HISTORY_INDEX_VERSION = 1;
|
|
22518
22576
|
var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
|
|
@@ -22698,7 +22756,7 @@ function extractSavedHistorySessionIdFromFile(file) {
|
|
|
22698
22756
|
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
22699
22757
|
return new Map(files.map((file) => {
|
|
22700
22758
|
try {
|
|
22701
|
-
const stat2 = fs6.statSync(
|
|
22759
|
+
const stat2 = fs6.statSync(path15.join(dir, file));
|
|
22702
22760
|
return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
|
|
22703
22761
|
} catch {
|
|
22704
22762
|
return [file, `${file}:missing`];
|
|
@@ -22709,7 +22767,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
|
|
|
22709
22767
|
return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
|
|
22710
22768
|
}
|
|
22711
22769
|
function getSavedHistoryIndexFilePath(dir) {
|
|
22712
|
-
return
|
|
22770
|
+
return path15.join(dir, SAVED_HISTORY_INDEX_FILE);
|
|
22713
22771
|
}
|
|
22714
22772
|
function getSavedHistoryIndexLockPath(dir) {
|
|
22715
22773
|
return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
|
|
@@ -22811,7 +22869,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
|
|
|
22811
22869
|
}
|
|
22812
22870
|
for (const file of Array.from(currentEntries.keys())) {
|
|
22813
22871
|
if (incomingFiles.has(file)) continue;
|
|
22814
|
-
if (!fs6.existsSync(
|
|
22872
|
+
if (!fs6.existsSync(path15.join(dir, file))) {
|
|
22815
22873
|
currentEntries.delete(file);
|
|
22816
22874
|
}
|
|
22817
22875
|
}
|
|
@@ -22837,7 +22895,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
22837
22895
|
const indexStat = fs6.statSync(getSavedHistoryIndexFilePath(dir));
|
|
22838
22896
|
const files = listHistoryFiles(dir);
|
|
22839
22897
|
for (const file of files) {
|
|
22840
|
-
const stat2 = fs6.statSync(
|
|
22898
|
+
const stat2 = fs6.statSync(path15.join(dir, file));
|
|
22841
22899
|
if (stat2.mtimeMs > indexStat.mtimeMs) return true;
|
|
22842
22900
|
}
|
|
22843
22901
|
return false;
|
|
@@ -22847,14 +22905,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
22847
22905
|
}
|
|
22848
22906
|
function buildSavedHistoryFileSignature(dir, file) {
|
|
22849
22907
|
try {
|
|
22850
|
-
const stat2 = fs6.statSync(
|
|
22908
|
+
const stat2 = fs6.statSync(path15.join(dir, file));
|
|
22851
22909
|
return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
|
|
22852
22910
|
} catch {
|
|
22853
22911
|
return `${file}:missing`;
|
|
22854
22912
|
}
|
|
22855
22913
|
}
|
|
22856
22914
|
function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
|
|
22857
|
-
const filePath =
|
|
22915
|
+
const filePath = path15.join(dir, file);
|
|
22858
22916
|
const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
|
|
22859
22917
|
const currentEntry = entries.get(file) || null;
|
|
22860
22918
|
const nextSummary = updater(currentEntry?.summary || null);
|
|
@@ -22927,7 +22985,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
|
|
|
22927
22985
|
function computeSavedHistoryFileSummary(dir, file) {
|
|
22928
22986
|
const historySessionId = extractSavedHistorySessionIdFromFile(file);
|
|
22929
22987
|
if (!historySessionId) return null;
|
|
22930
|
-
const filePath =
|
|
22988
|
+
const filePath = path15.join(dir, file);
|
|
22931
22989
|
const content = fs6.readFileSync(filePath, "utf-8");
|
|
22932
22990
|
const lines = content.split("\n").filter(Boolean);
|
|
22933
22991
|
let messageCount = 0;
|
|
@@ -23014,7 +23072,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
|
|
|
23014
23072
|
const summaryBySessionId = /* @__PURE__ */ new Map();
|
|
23015
23073
|
const nextPersistedEntries = /* @__PURE__ */ new Map();
|
|
23016
23074
|
for (const file of files.slice().sort()) {
|
|
23017
|
-
const filePath =
|
|
23075
|
+
const filePath = path15.join(dir, file);
|
|
23018
23076
|
const signature = fileSignatures.get(file) || `${file}:missing`;
|
|
23019
23077
|
const cached3 = savedHistoryFileSummaryCache.get(filePath);
|
|
23020
23078
|
const persisted = persistedEntries.get(file);
|
|
@@ -23134,12 +23192,12 @@ var ChatHistoryWriter = class {
|
|
|
23134
23192
|
});
|
|
23135
23193
|
}
|
|
23136
23194
|
if (newMessages.length === 0) return;
|
|
23137
|
-
const dir =
|
|
23195
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
23138
23196
|
fs6.mkdirSync(dir, { recursive: true });
|
|
23139
23197
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
23140
23198
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
23141
23199
|
const fileName = `${filePrefix}${date}.jsonl`;
|
|
23142
|
-
const filePath =
|
|
23200
|
+
const filePath = path15.join(dir, fileName);
|
|
23143
23201
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
23144
23202
|
fs6.appendFileSync(filePath, lines, "utf-8");
|
|
23145
23203
|
updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
|
|
@@ -23230,11 +23288,11 @@ var ChatHistoryWriter = class {
|
|
|
23230
23288
|
const ws = String(workspace || "").trim();
|
|
23231
23289
|
if (!id || !ws) return;
|
|
23232
23290
|
try {
|
|
23233
|
-
const dir =
|
|
23291
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
23234
23292
|
fs6.mkdirSync(dir, { recursive: true });
|
|
23235
23293
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
23236
23294
|
const fileName = `${this.sanitize(id)}_${date}.jsonl`;
|
|
23237
|
-
const filePath =
|
|
23295
|
+
const filePath = path15.join(dir, fileName);
|
|
23238
23296
|
const record = {
|
|
23239
23297
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
23240
23298
|
receivedAt: Date.now(),
|
|
@@ -23280,14 +23338,14 @@ var ChatHistoryWriter = class {
|
|
|
23280
23338
|
this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
|
|
23281
23339
|
this.lastSeenCounts.delete(fromDedupKey);
|
|
23282
23340
|
}
|
|
23283
|
-
const dir =
|
|
23341
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
23284
23342
|
if (!fs6.existsSync(dir)) return;
|
|
23285
23343
|
const fromPrefix = `${this.sanitize(fromId)}_`;
|
|
23286
23344
|
const toPrefix = `${this.sanitize(toId)}_`;
|
|
23287
23345
|
const files = fs6.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
|
|
23288
23346
|
for (const file of files) {
|
|
23289
|
-
const sourcePath =
|
|
23290
|
-
const targetPath =
|
|
23347
|
+
const sourcePath = path15.join(dir, file);
|
|
23348
|
+
const targetPath = path15.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
|
|
23291
23349
|
const sourceLines = fs6.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
23292
23350
|
const rewritten = sourceLines.map((line) => {
|
|
23293
23351
|
try {
|
|
@@ -23321,13 +23379,13 @@ var ChatHistoryWriter = class {
|
|
|
23321
23379
|
const sessionId = String(historySessionId || "").trim();
|
|
23322
23380
|
if (!sessionId) return;
|
|
23323
23381
|
try {
|
|
23324
|
-
const dir =
|
|
23382
|
+
const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
|
|
23325
23383
|
if (!fs6.existsSync(dir)) return;
|
|
23326
23384
|
const prefix = `${this.sanitize(sessionId)}_`;
|
|
23327
23385
|
const files = fs6.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
|
|
23328
23386
|
const seen = /* @__PURE__ */ new Set();
|
|
23329
23387
|
for (const file of files) {
|
|
23330
|
-
const filePath =
|
|
23388
|
+
const filePath = path15.join(dir, file);
|
|
23331
23389
|
const lines = fs6.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
23332
23390
|
const next = [];
|
|
23333
23391
|
for (const line of lines) {
|
|
@@ -23381,11 +23439,11 @@ var ChatHistoryWriter = class {
|
|
|
23381
23439
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
23382
23440
|
const agentDirs = fs6.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
23383
23441
|
for (const dir of agentDirs) {
|
|
23384
|
-
const dirPath =
|
|
23442
|
+
const dirPath = path15.join(HISTORY_DIR, dir.name);
|
|
23385
23443
|
const files = fs6.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
23386
23444
|
let removedAny = false;
|
|
23387
23445
|
for (const file of files) {
|
|
23388
|
-
const filePath =
|
|
23446
|
+
const filePath = path15.join(dirPath, file);
|
|
23389
23447
|
const stat2 = fs6.statSync(filePath);
|
|
23390
23448
|
if (stat2.mtimeMs < cutoff) {
|
|
23391
23449
|
fs6.unlinkSync(filePath);
|
|
@@ -23588,7 +23646,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
|
|
|
23588
23646
|
const seen = /* @__PURE__ */ new Set();
|
|
23589
23647
|
let readAllFiles = true;
|
|
23590
23648
|
for (let f = 0; f < files.length; f++) {
|
|
23591
|
-
const filePath =
|
|
23649
|
+
const filePath = path15.join(dir, files[f]);
|
|
23592
23650
|
const remaining = Math.max(0, needed - collected.length);
|
|
23593
23651
|
const perFileNeeded = Math.min(needed, remaining + BOUNDED_TAIL_SLACK);
|
|
23594
23652
|
const { lines, coversWholeFile } = readFileTailLines(filePath, perFileNeeded);
|
|
@@ -23621,7 +23679,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
|
|
|
23621
23679
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
23622
23680
|
try {
|
|
23623
23681
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
23624
|
-
const dir =
|
|
23682
|
+
const dir = path15.join(HISTORY_DIR, sanitized);
|
|
23625
23683
|
if (!fs6.existsSync(dir)) return { messages: [], hasMore: false };
|
|
23626
23684
|
const files = listHistoryFiles(dir, historySessionId);
|
|
23627
23685
|
const bounded = isBoundedTailRequest(limit, offset, excludeRecentCount);
|
|
@@ -23644,7 +23702,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
23644
23702
|
const allMessages = [];
|
|
23645
23703
|
const seen = /* @__PURE__ */ new Set();
|
|
23646
23704
|
for (const file of files) {
|
|
23647
|
-
const filePath =
|
|
23705
|
+
const filePath = path15.join(dir, file);
|
|
23648
23706
|
const content = fs6.readFileSync(filePath, "utf-8");
|
|
23649
23707
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
23650
23708
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -23668,7 +23726,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
23668
23726
|
function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
23669
23727
|
try {
|
|
23670
23728
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
23671
|
-
const dir =
|
|
23729
|
+
const dir = path15.join(HISTORY_DIR, sanitized);
|
|
23672
23730
|
if (!fs6.existsSync(dir)) {
|
|
23673
23731
|
savedHistorySessionCache.delete(sanitized);
|
|
23674
23732
|
return { sessions: [], hasMore: false };
|
|
@@ -23729,11 +23787,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
|
23729
23787
|
}
|
|
23730
23788
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
23731
23789
|
try {
|
|
23732
|
-
const dir =
|
|
23790
|
+
const dir = path15.join(HISTORY_DIR, agentType);
|
|
23733
23791
|
if (!fs6.existsSync(dir)) return null;
|
|
23734
23792
|
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
23735
23793
|
for (const file of files) {
|
|
23736
|
-
const lines = fs6.readFileSync(
|
|
23794
|
+
const lines = fs6.readFileSync(path15.join(dir, file), "utf-8").split("\n").filter(Boolean);
|
|
23737
23795
|
for (const line of lines) {
|
|
23738
23796
|
try {
|
|
23739
23797
|
const parsed = JSON.parse(line);
|
|
@@ -23753,16 +23811,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
|
23753
23811
|
function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
23754
23812
|
if (records.length === 0) return false;
|
|
23755
23813
|
try {
|
|
23756
|
-
const dir =
|
|
23814
|
+
const dir = path15.join(HISTORY_DIR, agentType);
|
|
23757
23815
|
fs6.mkdirSync(dir, { recursive: true });
|
|
23758
23816
|
const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
23759
23817
|
for (const file of fs6.readdirSync(dir)) {
|
|
23760
23818
|
if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
|
|
23761
|
-
fs6.unlinkSync(
|
|
23819
|
+
fs6.unlinkSync(path15.join(dir, file));
|
|
23762
23820
|
}
|
|
23763
23821
|
}
|
|
23764
23822
|
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
23765
|
-
const filePath =
|
|
23823
|
+
const filePath = path15.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
23766
23824
|
fs6.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
|
|
23767
23825
|
`, "utf-8");
|
|
23768
23826
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
@@ -26367,7 +26425,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
|
|
|
26367
26425
|
// src/commands/chat-commands.ts
|
|
26368
26426
|
var fs7 = __toESM(require("fs"));
|
|
26369
26427
|
var os9 = __toESM(require("os"));
|
|
26370
|
-
var
|
|
26428
|
+
var path16 = __toESM(require("path"));
|
|
26371
26429
|
var import_node_crypto3 = require("crypto");
|
|
26372
26430
|
init_contracts();
|
|
26373
26431
|
init_logger();
|
|
@@ -27418,7 +27476,7 @@ function readExactRuntimeMirrorMessages(args) {
|
|
|
27418
27476
|
function normalizeComparableWorkspace(value) {
|
|
27419
27477
|
const text = typeof value === "string" ? value.trim() : "";
|
|
27420
27478
|
if (!text) return "";
|
|
27421
|
-
return
|
|
27479
|
+
return path16.resolve(text);
|
|
27422
27480
|
}
|
|
27423
27481
|
function isCurrentRuntimePtySafelyAttributed(args) {
|
|
27424
27482
|
if (args.adapter.cliType !== "codex-cli") return false;
|
|
@@ -27903,7 +27961,7 @@ function buildDebugBundleText(bundle) {
|
|
|
27903
27961
|
}
|
|
27904
27962
|
function getChatDebugBundleDir() {
|
|
27905
27963
|
const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
|
|
27906
|
-
return override ||
|
|
27964
|
+
return override || path16.join(os9.homedir(), ".adhdev", "debug-bundles", "chat");
|
|
27907
27965
|
}
|
|
27908
27966
|
function safeBundleIdSegment(value, fallback) {
|
|
27909
27967
|
const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
@@ -27960,7 +28018,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
|
|
|
27960
28018
|
const bundleId = createChatDebugBundleId(targetSessionId);
|
|
27961
28019
|
const dir = getChatDebugBundleDir();
|
|
27962
28020
|
fs7.mkdirSync(dir, { recursive: true });
|
|
27963
|
-
const savedPath =
|
|
28021
|
+
const savedPath = path16.join(dir, `${bundleId}.json`);
|
|
27964
28022
|
const json = `${JSON.stringify(bundle, null, 2)}
|
|
27965
28023
|
`;
|
|
27966
28024
|
fs7.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
|
|
@@ -29524,7 +29582,7 @@ async function handleResolveAction(h, args) {
|
|
|
29524
29582
|
|
|
29525
29583
|
// src/commands/cdp-commands.ts
|
|
29526
29584
|
var fs8 = __toESM(require("fs"));
|
|
29527
|
-
var
|
|
29585
|
+
var path17 = __toESM(require("path"));
|
|
29528
29586
|
var os10 = __toESM(require("os"));
|
|
29529
29587
|
var KEY_TO_VK = {
|
|
29530
29588
|
Backspace: 8,
|
|
@@ -29781,25 +29839,25 @@ function resolveSafePath(requestedPath) {
|
|
|
29781
29839
|
const inputPath = rawPath || ".";
|
|
29782
29840
|
const home = os10.homedir();
|
|
29783
29841
|
if (inputPath.startsWith("~")) {
|
|
29784
|
-
return
|
|
29842
|
+
return path17.resolve(path17.join(home, inputPath.slice(1)));
|
|
29785
29843
|
}
|
|
29786
29844
|
if (process.platform === "win32") {
|
|
29787
29845
|
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
29788
|
-
if (
|
|
29789
|
-
return
|
|
29846
|
+
if (path17.win32.isAbsolute(normalized)) {
|
|
29847
|
+
return path17.win32.normalize(normalized);
|
|
29790
29848
|
}
|
|
29791
|
-
return
|
|
29849
|
+
return path17.win32.resolve(normalized);
|
|
29792
29850
|
}
|
|
29793
|
-
if (
|
|
29794
|
-
return
|
|
29851
|
+
if (path17.isAbsolute(inputPath)) {
|
|
29852
|
+
return path17.normalize(inputPath);
|
|
29795
29853
|
}
|
|
29796
|
-
return
|
|
29854
|
+
return path17.resolve(inputPath);
|
|
29797
29855
|
}
|
|
29798
29856
|
function listDirectoryEntriesSafe(dirPath) {
|
|
29799
29857
|
const entries = fs8.readdirSync(dirPath, { withFileTypes: true });
|
|
29800
29858
|
const files = [];
|
|
29801
29859
|
for (const entry of entries) {
|
|
29802
|
-
const entryPath =
|
|
29860
|
+
const entryPath = path17.join(dirPath, entry.name);
|
|
29803
29861
|
try {
|
|
29804
29862
|
if (entry.isDirectory()) {
|
|
29805
29863
|
files.push({ name: entry.name, type: "directory" });
|
|
@@ -29853,7 +29911,7 @@ async function handleFileRead(h, args) {
|
|
|
29853
29911
|
async function handleFileWrite(h, args) {
|
|
29854
29912
|
try {
|
|
29855
29913
|
const filePath = resolveSafePath(args?.path);
|
|
29856
|
-
fs8.mkdirSync(
|
|
29914
|
+
fs8.mkdirSync(path17.dirname(filePath), { recursive: true });
|
|
29857
29915
|
fs8.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
29858
29916
|
return { success: true, path: filePath };
|
|
29859
29917
|
} catch (e) {
|
|
@@ -43661,6 +43719,7 @@ var import_os3 = require("os");
|
|
|
43661
43719
|
var import_path12 = require("path");
|
|
43662
43720
|
var fs26 = __toESM(require("fs"));
|
|
43663
43721
|
var import_node_child_process6 = require("child_process");
|
|
43722
|
+
init_resolve_executable();
|
|
43664
43723
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
43665
43724
|
var CHANNEL_SERVER_URL = {
|
|
43666
43725
|
stable: "https://api.adhf.dev",
|
|
@@ -44759,6 +44818,18 @@ function truncateValidationOutput(value) {
|
|
|
44759
44818
|
return `${text.slice(0, REFINE_VALIDATION_SUMMARY_CHARS)}
|
|
44760
44819
|
[truncated ${text.length - REFINE_VALIDATION_SUMMARY_CHARS} chars]`;
|
|
44761
44820
|
}
|
|
44821
|
+
function isSpawnResolutionError(error) {
|
|
44822
|
+
if (!error) return false;
|
|
44823
|
+
if (error.code === "ENOENT" && typeof error.syscall === "string" && error.syscall.startsWith("spawn")) return true;
|
|
44824
|
+
return error.code === "ENOENT" && (error.syscall === void 0 || String(error.syscall).startsWith("spawn"));
|
|
44825
|
+
}
|
|
44826
|
+
function describeSpawnError(error, command, spawnResolutionFailed) {
|
|
44827
|
+
if (spawnResolutionFailed) {
|
|
44828
|
+
const hint = process.platform === "win32" ? " On Windows, npm-family commands (npm/npx/tsc/vitest) are .cmd shims that the bare-command spawn search does not resolve; configure an absolute path or ensure the command is on PATH." : "";
|
|
44829
|
+
return `Could not resolve executable "${command}" (spawn ENOENT).${hint}`;
|
|
44830
|
+
}
|
|
44831
|
+
return String(error?.message || error);
|
|
44832
|
+
}
|
|
44762
44833
|
function recordMeshRefineStage(stages, stage, status, startedAt, details) {
|
|
44763
44834
|
stages.push({
|
|
44764
44835
|
stage,
|
|
@@ -45660,8 +45731,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45660
45731
|
const startedAt = Date.now();
|
|
45661
45732
|
const cwd = candidate.cwd ? (0, import_path12.resolve)(workspace, candidate.cwd) : workspace;
|
|
45662
45733
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
45734
|
+
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
45663
45735
|
try {
|
|
45664
|
-
const result = await execFileAsync4(
|
|
45736
|
+
const result = await execFileAsync4(resolvedCommand, candidate.args, {
|
|
45665
45737
|
cwd,
|
|
45666
45738
|
encoding: "utf8",
|
|
45667
45739
|
timeout,
|
|
@@ -45670,16 +45742,17 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45670
45742
|
});
|
|
45671
45743
|
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
45672
45744
|
} catch (error) {
|
|
45745
|
+
const spawnResolutionFailed = isSpawnResolutionError(error);
|
|
45673
45746
|
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
|
|
45674
45747
|
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
45675
45748
|
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
45676
45749
|
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
45677
|
-
failureKind: "dependency_bootstrap_failed"
|
|
45750
|
+
...spawnResolutionFailed ? { failureKind: "spawn_resolution_failed", resolvedCommand } : { failureKind: "dependency_bootstrap_failed" }
|
|
45678
45751
|
}));
|
|
45679
|
-
summary.bootstrap = { stage: "failed", error:
|
|
45752
|
+
summary.bootstrap = { stage: "failed", error: describeSpawnError(error, candidate.command, spawnResolutionFailed) };
|
|
45680
45753
|
summary.status = "failed";
|
|
45681
|
-
summary.failureKind = "dependency_bootstrap_failed";
|
|
45682
|
-
summary.failureCode = "dependency_bootstrap_failed";
|
|
45754
|
+
summary.failureKind = spawnResolutionFailed ? "spawn_resolution_failed" : "dependency_bootstrap_failed";
|
|
45755
|
+
summary.failureCode = spawnResolutionFailed ? "spawn_resolution_failed" : "dependency_bootstrap_failed";
|
|
45683
45756
|
return summary;
|
|
45684
45757
|
}
|
|
45685
45758
|
}
|
|
@@ -45702,8 +45775,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45702
45775
|
summary.failureCode = "missing_dependencies";
|
|
45703
45776
|
return summary;
|
|
45704
45777
|
}
|
|
45778
|
+
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
45705
45779
|
try {
|
|
45706
|
-
const result = await execFileAsync4(
|
|
45780
|
+
const result = await execFileAsync4(resolvedCommand, candidate.args, {
|
|
45707
45781
|
cwd,
|
|
45708
45782
|
encoding: "utf8",
|
|
45709
45783
|
timeout,
|
|
@@ -45712,16 +45786,21 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
45712
45786
|
});
|
|
45713
45787
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
45714
45788
|
} catch (error) {
|
|
45789
|
+
const spawnResolutionFailed = isSpawnResolutionError(error);
|
|
45715
45790
|
const stderr = truncateValidationOutput(error?.stderr || error?.message);
|
|
45716
|
-
const missingDependencyFailure = /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
|
|
45791
|
+
const missingDependencyFailure = !spawnResolutionFailed && /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
|
|
45717
45792
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
|
|
45718
45793
|
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
45719
45794
|
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
45720
45795
|
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
45721
|
-
...missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
|
|
45796
|
+
...spawnResolutionFailed ? { failureKind: "spawn_resolution_failed", resolvedCommand } : missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
|
|
45722
45797
|
}));
|
|
45723
45798
|
summary.status = "failed";
|
|
45724
|
-
if (
|
|
45799
|
+
if (spawnResolutionFailed) {
|
|
45800
|
+
summary.failureKind = "spawn_resolution_failed";
|
|
45801
|
+
summary.failureCode = "spawn_resolution_failed";
|
|
45802
|
+
summary.spawnResolutionError = describeSpawnError(error, candidate.command, true);
|
|
45803
|
+
} else if (missingDependencyFailure) {
|
|
45725
45804
|
summary.failureKind = "missing_dependencies";
|
|
45726
45805
|
summary.failureCode = "missing_dependencies";
|
|
45727
45806
|
}
|
|
@@ -46982,7 +47061,7 @@ var DaemonCommandRouter = class {
|
|
|
46982
47061
|
if (validationSummary.status === "failed") {
|
|
46983
47062
|
const firstFailedCmd = Array.isArray(validationSummary.commandsRun) ? validationSummary.commandsRun.find((c) => c.success === false) : void 0;
|
|
46984
47063
|
const buildValidationFailedError = () => {
|
|
46985
|
-
const base = validationSummary.failureCode === "missing_dependencies" ? "Refinery validation dependencies are missing; merge/refine was not attempted. Configure validation.bootstrapCommands if Refinery should bootstrap dependencies before validation." : validationSummary.failureCode === "dependency_bootstrap_failed" ? "Refinery dependency/bootstrap command failed; merge/refine was not attempted." : "Refinery validation gate failed; merge/refine was not attempted.";
|
|
47064
|
+
const base = validationSummary.failureCode === "missing_dependencies" ? "Refinery validation dependencies are missing; merge/refine was not attempted. Configure validation.bootstrapCommands if Refinery should bootstrap dependencies before validation." : validationSummary.failureCode === "dependency_bootstrap_failed" ? "Refinery dependency/bootstrap command failed; merge/refine was not attempted." : validationSummary.failureCode === "spawn_resolution_failed" ? validationSummary.spawnResolutionError || "Refinery validation command could not be spawned (executable not found); merge/refine was not attempted." : "Refinery validation gate failed; merge/refine was not attempted.";
|
|
46986
47065
|
if (!firstFailedCmd) return base;
|
|
46987
47066
|
const cmdName = typeof firstFailedCmd.displayCommand === "string" ? firstFailedCmd.displayCommand : typeof firstFailedCmd.command === "string" ? [firstFailedCmd.command, ...Array.isArray(firstFailedCmd.args) ? firstFailedCmd.args : []].join(" ").trim() : typeof firstFailedCmd.cmd === "string" ? firstFailedCmd.cmd : "";
|
|
46988
47067
|
const rawOutput = [firstFailedCmd.stdout, firstFailedCmd.stderr, firstFailedCmd.output].filter((s) => typeof s === "string" && s.length > 0).join("\n");
|