@adhdev/daemon-core 0.9.82-rc.333 → 0.9.82-rc.335

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -311,10 +311,10 @@ function readInjected(value) {
311
311
  }
312
312
  function getDaemonBuildInfo() {
313
313
  if (cached) return cached;
314
- const commit = readInjected(true ? "5d9635b2a6476691469ecfe32b26a17e13484b2b" : void 0) ?? "unknown";
315
- const commitShort = readInjected(true ? "5d9635b2" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
316
- const version = readInjected(true ? "0.9.82-rc.333" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
317
- const builtAt = readInjected(true ? "2026-06-20T02:23:56.856Z" : void 0);
314
+ const commit = readInjected(true ? "e9e62c9770c0f4a419a90f5287125f3d3bb0fd95" : void 0) ?? "unknown";
315
+ const commitShort = readInjected(true ? "e9e62c97" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
316
+ const version = readInjected(true ? "0.9.82-rc.335" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
317
+ const builtAt = readInjected(true ? "2026-06-20T04:30:54.863Z" : void 0);
318
318
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
319
319
  return cached;
320
320
  }
@@ -3254,6 +3254,297 @@ var init_mesh_ledger = __esm({
3254
3254
  }
3255
3255
  });
3256
3256
 
3257
+ // src/logging/async-batch-writer.ts
3258
+ import * as fs3 from "fs";
3259
+ var AsyncBatchWriter;
3260
+ var init_async_batch_writer = __esm({
3261
+ "src/logging/async-batch-writer.ts"() {
3262
+ "use strict";
3263
+ AsyncBatchWriter = class {
3264
+ // Maps filePath -> string buffer
3265
+ static buffers = /* @__PURE__ */ new Map();
3266
+ static writePromises = /* @__PURE__ */ new Map();
3267
+ static flushTimer = null;
3268
+ /**
3269
+ * Queues data to be written to a file asynchronously in a batch.
3270
+ */
3271
+ static write(filePath, data) {
3272
+ let buf = this.buffers.get(filePath);
3273
+ if (!buf) {
3274
+ buf = [];
3275
+ this.buffers.set(filePath, buf);
3276
+ }
3277
+ buf.push(data);
3278
+ if (!this.flushTimer) {
3279
+ this.flushTimer = setTimeout(() => {
3280
+ this.flushTimer = null;
3281
+ this.flushAll();
3282
+ }, 50);
3283
+ }
3284
+ }
3285
+ static async flushAll() {
3286
+ const entries = Array.from(this.buffers.entries());
3287
+ this.buffers.clear();
3288
+ for (const [filePath, buffer] of entries) {
3289
+ const dataToWrite = buffer.join("");
3290
+ const doWrite = async () => {
3291
+ try {
3292
+ const prevPromise = this.writePromises.get(filePath);
3293
+ if (prevPromise) await prevPromise;
3294
+ await fs3.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
3295
+ } catch {
3296
+ }
3297
+ };
3298
+ const writePromise = doWrite();
3299
+ this.writePromises.set(filePath, writePromise);
3300
+ writePromise.finally(() => {
3301
+ if (this.writePromises.get(filePath) === writePromise) {
3302
+ this.writePromises.delete(filePath);
3303
+ }
3304
+ });
3305
+ }
3306
+ }
3307
+ };
3308
+ }
3309
+ });
3310
+
3311
+ // src/logging/logger.ts
3312
+ var logger_exports = {};
3313
+ __export(logger_exports, {
3314
+ LOG: () => LOG,
3315
+ LOG_DIR_PATH: () => LOG_DIR_PATH,
3316
+ LOG_PATH: () => LOG_PATH,
3317
+ daemonLog: () => daemonLog,
3318
+ getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
3319
+ getDaemonLogDir: () => getDaemonLogDir,
3320
+ getLogBufferSize: () => getLogBufferSize,
3321
+ getLogLevel: () => getLogLevel,
3322
+ getLogPath: () => getLogPath,
3323
+ getRecentLogs: () => getRecentLogs,
3324
+ installGlobalInterceptor: () => installGlobalInterceptor,
3325
+ setLogLevel: () => setLogLevel
3326
+ });
3327
+ import * as fs4 from "fs";
3328
+ import * as path9 from "path";
3329
+ import * as os3 from "os";
3330
+ function setLogLevel(level) {
3331
+ currentLevel = level;
3332
+ daemonLog("Logger", `Log level set to: ${level}`, "info");
3333
+ }
3334
+ function getLogLevel() {
3335
+ return currentLevel;
3336
+ }
3337
+ function getDateStr() {
3338
+ return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
3339
+ }
3340
+ function getDaemonLogDir() {
3341
+ return LOG_DIR;
3342
+ }
3343
+ function getCurrentDaemonLogPath(date = /* @__PURE__ */ new Date()) {
3344
+ return path9.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
3345
+ }
3346
+ function checkDateRotation() {
3347
+ const today = getDateStr();
3348
+ if (today !== currentDate) {
3349
+ currentDate = today;
3350
+ currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
3351
+ cleanOldLogs();
3352
+ }
3353
+ }
3354
+ function cleanOldLogs() {
3355
+ try {
3356
+ const files = fs4.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
3357
+ const cutoff = /* @__PURE__ */ new Date();
3358
+ cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
3359
+ const cutoffStr = cutoff.toISOString().slice(0, 10);
3360
+ for (const file of files) {
3361
+ const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
3362
+ if (dateMatch && dateMatch[1] < cutoffStr) {
3363
+ try {
3364
+ fs4.unlinkSync(path9.join(LOG_DIR, file));
3365
+ } catch {
3366
+ }
3367
+ }
3368
+ }
3369
+ } catch {
3370
+ }
3371
+ }
3372
+ function rotateSizeIfNeeded() {
3373
+ try {
3374
+ const stat2 = fs4.statSync(currentLogFile);
3375
+ if (stat2.size > MAX_LOG_SIZE) {
3376
+ const backup = currentLogFile.replace(".log", ".1.log");
3377
+ try {
3378
+ fs4.unlinkSync(backup);
3379
+ } catch {
3380
+ }
3381
+ fs4.renameSync(currentLogFile, backup);
3382
+ }
3383
+ } catch {
3384
+ }
3385
+ }
3386
+ function writeToFile(line) {
3387
+ try {
3388
+ if (++writeCount % 1e3 === 0) {
3389
+ checkDateRotation();
3390
+ rotateSizeIfNeeded();
3391
+ }
3392
+ AsyncBatchWriter.write(currentLogFile, line + "\n");
3393
+ } catch {
3394
+ }
3395
+ }
3396
+ function getRecentLogs(count = 50, minLevel = "info") {
3397
+ const minNum = LEVEL_NUM[minLevel];
3398
+ const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
3399
+ return filtered.slice(-count);
3400
+ }
3401
+ function getLogBufferSize() {
3402
+ return ringBuffer.length;
3403
+ }
3404
+ function ts() {
3405
+ return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
3406
+ }
3407
+ function fullTs() {
3408
+ return (/* @__PURE__ */ new Date()).toISOString();
3409
+ }
3410
+ function daemonLog(category, msg, level = "info") {
3411
+ const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
3412
+ const label = LEVEL_LABEL[level];
3413
+ const line = `[${ts()}] [${label}] [${category}] ${msg}`;
3414
+ if (!shouldOutput) return;
3415
+ writeToFile(line);
3416
+ ringBuffer.push({ ts: Date.now(), level, category, message: msg });
3417
+ if (ringBuffer.length > RING_BUFFER_SIZE) {
3418
+ ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
3419
+ }
3420
+ origConsoleLog(line);
3421
+ }
3422
+ function installGlobalInterceptor() {
3423
+ if (interceptorInstalled) return;
3424
+ interceptorInstalled = true;
3425
+ const stripAnsi4 = (str) => str.replace(/\x1B\[[0-9;]*m/g, "");
3426
+ const isDaemonLogLine = (msg) => /\[(DBG|INF|WRN|ERR)\]/.test(msg);
3427
+ console.log = (...args) => {
3428
+ origConsoleLog(...args);
3429
+ try {
3430
+ const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
3431
+ const clean = stripAnsi4(msg);
3432
+ if (isDaemonLogLine(clean)) return;
3433
+ const line = clean.startsWith("[20") ? clean : `[${fullTs()}] ${clean}`;
3434
+ writeToFile(line);
3435
+ const catMatch = clean.match(/\[([^\]]+)\]/);
3436
+ ringBuffer.push({
3437
+ ts: Date.now(),
3438
+ level: "info",
3439
+ category: catMatch?.[1] || "System",
3440
+ message: clean
3441
+ });
3442
+ if (ringBuffer.length > RING_BUFFER_SIZE) {
3443
+ ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
3444
+ }
3445
+ } catch {
3446
+ }
3447
+ };
3448
+ console.error = (...args) => {
3449
+ origConsoleError(...args);
3450
+ try {
3451
+ const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
3452
+ const clean = stripAnsi4(msg);
3453
+ if (isDaemonLogLine(clean)) return;
3454
+ const line = `[${fullTs()}] [ERROR] ${clean}`;
3455
+ writeToFile(line);
3456
+ ringBuffer.push({ ts: Date.now(), level: "error", category: "System", message: clean });
3457
+ if (ringBuffer.length > RING_BUFFER_SIZE) {
3458
+ ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
3459
+ }
3460
+ } catch {
3461
+ }
3462
+ };
3463
+ console.warn = (...args) => {
3464
+ origConsoleWarn(...args);
3465
+ try {
3466
+ const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
3467
+ const clean = stripAnsi4(msg);
3468
+ if (isDaemonLogLine(clean)) return;
3469
+ const line = `[${fullTs()}] [WARN] ${clean}`;
3470
+ writeToFile(line);
3471
+ ringBuffer.push({ ts: Date.now(), level: "warn", category: "System", message: clean });
3472
+ if (ringBuffer.length > RING_BUFFER_SIZE) {
3473
+ ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
3474
+ }
3475
+ } catch {
3476
+ }
3477
+ };
3478
+ writeToFile(`
3479
+ === ADHDev Daemon started at ${fullTs()} ===`);
3480
+ writeToFile(`Log file: ${currentLogFile}`);
3481
+ writeToFile(`Log level: ${currentLevel}`);
3482
+ }
3483
+ function getLogPath() {
3484
+ return currentLogFile;
3485
+ }
3486
+ var LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, LOG_DIR_PATH;
3487
+ var init_logger = __esm({
3488
+ "src/logging/logger.ts"() {
3489
+ "use strict";
3490
+ init_async_batch_writer();
3491
+ LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
3492
+ LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
3493
+ currentLevel = "info";
3494
+ LOG_DIR = process.platform === "win32" ? path9.join(process.env.LOCALAPPDATA || process.env.APPDATA || path9.join(os3.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path9.join(os3.homedir(), "Library", "Logs", "adhdev") : path9.join(os3.homedir(), ".local", "share", "adhdev", "logs");
3495
+ MAX_LOG_SIZE = 5 * 1024 * 1024;
3496
+ MAX_LOG_DAYS = 7;
3497
+ try {
3498
+ fs4.mkdirSync(LOG_DIR, { recursive: true });
3499
+ } catch {
3500
+ }
3501
+ currentDate = getDateStr();
3502
+ currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
3503
+ cleanOldLogs();
3504
+ try {
3505
+ const oldLog = path9.join(LOG_DIR, "daemon.log");
3506
+ if (fs4.existsSync(oldLog)) {
3507
+ const stat2 = fs4.statSync(oldLog);
3508
+ const oldDate = stat2.mtime.toISOString().slice(0, 10);
3509
+ fs4.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
3510
+ }
3511
+ const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
3512
+ if (fs4.existsSync(oldLogBackup)) {
3513
+ fs4.unlinkSync(oldLogBackup);
3514
+ }
3515
+ } catch {
3516
+ }
3517
+ writeCount = 0;
3518
+ RING_BUFFER_SIZE = 200;
3519
+ ringBuffer = [];
3520
+ origConsoleLog = console.log.bind(console);
3521
+ origConsoleError = console.error.bind(console);
3522
+ origConsoleWarn = console.warn.bind(console);
3523
+ LOG = {
3524
+ debug: (category, msg) => daemonLog(category, msg, "debug"),
3525
+ info: (category, msg) => daemonLog(category, msg, "info"),
3526
+ warn: (category, msg) => daemonLog(category, msg, "warn"),
3527
+ error: (category, msg) => daemonLog(category, msg, "error"),
3528
+ /**
3529
+ * Create a scoped logger for a specific component.
3530
+ * Category is baked in so callers only pass the message.
3531
+ */
3532
+ forComponent(category) {
3533
+ return {
3534
+ debug: (msg) => daemonLog(category, msg, "debug"),
3535
+ info: (msg) => daemonLog(category, msg, "info"),
3536
+ warn: (msg) => daemonLog(category, msg, "warn"),
3537
+ error: (msg) => daemonLog(category, msg, "error"),
3538
+ asLogFn: (level = "info") => (msg) => daemonLog(category, msg, level)
3539
+ };
3540
+ }
3541
+ };
3542
+ interceptorInstalled = false;
3543
+ LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
3544
+ LOG_DIR_PATH = LOG_DIR;
3545
+ }
3546
+ });
3547
+
3257
3548
  // src/mesh/mesh-work-queue.ts
3258
3549
  var mesh_work_queue_exports = {};
3259
3550
  __export(mesh_work_queue_exports, {
@@ -3719,11 +4010,18 @@ function requeueTask(meshId, taskId, opts) {
3719
4010
  }
3720
4011
  function updateSessionTaskStatus(meshId, sessionId, status, opts) {
3721
4012
  return withQueueLock(meshId, () => {
4013
+ const store = MeshRuntimeStore.getInstance();
3722
4014
  const occurredAtIso = opts?.occurredAt ? new Date(opts.occurredAt).toISOString() : void 0;
3723
- const entry = MeshRuntimeStore.getInstance().findAssignedBySession(meshId, sessionId, occurredAtIso);
3724
- if (!entry) return null;
4015
+ const entry = store.findAssignedBySession(meshId, sessionId, occurredAtIso, opts?.taskId);
4016
+ if (!entry) {
4017
+ const assignedRows = store.getActiveAssignmentDetails(meshId).filter((r) => r.sessionId === sessionId);
4018
+ if (assignedRows.length > 0) {
4019
+ LOG.warn("MeshQueue", `No assigned queue row matched completion for mesh ${meshId} session ${sessionId} (taskId=${opts?.taskId ?? "none"}, occurredAt=${occurredAtIso ?? "none"}); ${assignedRows.length} assigned row(s) exist: ${assignedRows.map((r) => r.id).join(",")}`);
4020
+ }
4021
+ return null;
4022
+ }
3725
4023
  entry.status = status;
3726
- MeshRuntimeStore.getInstance().updateQueueEntry(entry);
4024
+ store.updateQueueEntry(entry);
3727
4025
  if (DEPENDENCY_FAILURE_TERMINALS.has(status)) propagateDependencyFailure(meshId, entry.id);
3728
4026
  return entry;
3729
4027
  });
@@ -3831,6 +4129,7 @@ var init_mesh_work_queue = __esm({
3831
4129
  init_repo_mesh_types();
3832
4130
  init_mesh_runtime_store();
3833
4131
  init_mesh_config();
4132
+ init_logger();
3834
4133
  ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
3835
4134
  HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
3836
4135
  MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
@@ -3887,8 +4186,8 @@ var init_mesh_work_queue = __esm({
3887
4186
  });
3888
4187
 
3889
4188
  // src/mesh/mesh-runtime-store.ts
3890
- import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, statSync as statSync4 } from "fs";
3891
- import { dirname as dirname2, join as join8 } from "path";
4189
+ import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, statSync as statSync5 } from "fs";
4190
+ import { dirname as dirname2, join as join9 } from "path";
3892
4191
  function loadDatabaseCtor() {
3893
4192
  if (DatabaseCtor) return DatabaseCtor;
3894
4193
  DatabaseCtor = loadBetterSqlite3();
@@ -3898,20 +4197,20 @@ function safeMeshId(meshId) {
3898
4197
  return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
3899
4198
  }
3900
4199
  function legacyQueuePath(meshId) {
3901
- return join8(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
4200
+ return join9(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
3902
4201
  }
3903
4202
  function meshRuntimeStorePath() {
3904
4203
  const dir = getLedgerDir();
3905
- const nextPath = join8(dir, "mesh-runtime.db");
3906
- if (existsSync7(nextPath)) return nextPath;
3907
- const legacyPath = join8(dir, "beads.db");
3908
- if (!existsSync7(legacyPath)) return nextPath;
4204
+ const nextPath = join9(dir, "mesh-runtime.db");
4205
+ if (existsSync8(nextPath)) return nextPath;
4206
+ const legacyPath = join9(dir, "beads.db");
4207
+ if (!existsSync8(legacyPath)) return nextPath;
3909
4208
  try {
3910
- renameSync2(legacyPath, nextPath);
4209
+ renameSync3(legacyPath, nextPath);
3911
4210
  for (const suffix of ["-wal", "-shm"]) {
3912
4211
  const legacyCompanion = `${legacyPath}${suffix}`;
3913
- if (existsSync7(legacyCompanion)) {
3914
- renameSync2(legacyCompanion, `${nextPath}${suffix}`);
4212
+ if (existsSync8(legacyCompanion)) {
4213
+ renameSync3(legacyCompanion, `${nextPath}${suffix}`);
3915
4214
  }
3916
4215
  }
3917
4216
  } catch {
@@ -3937,7 +4236,7 @@ var init_mesh_runtime_store = __esm({
3937
4236
  // 50 MB
3938
4237
  constructor(dbPath) {
3939
4238
  const dir = dirname2(dbPath);
3940
- if (!existsSync7(dir)) mkdirSync4(dir, { recursive: true });
4239
+ if (!existsSync8(dir)) mkdirSync5(dir, { recursive: true });
3941
4240
  this.dbPath = dbPath;
3942
4241
  this.db = new (loadDatabaseCtor())(dbPath);
3943
4242
  this.db.pragma("journal_mode = WAL");
@@ -4192,8 +4491,8 @@ var init_mesh_runtime_store = __esm({
4192
4491
  this.walWriteCounter = 0;
4193
4492
  try {
4194
4493
  const walPath = `${this.dbPath}-wal`;
4195
- if (!existsSync7(walPath)) return;
4196
- const size = statSync4(walPath).size;
4494
+ if (!existsSync8(walPath)) return;
4495
+ const size = statSync5(walPath).size;
4197
4496
  if (size < _MeshRuntimeStore.WAL_MAX_BYTES) return;
4198
4497
  process.stderr.write(
4199
4498
  `[adhdev-mesh] WAL file ${Math.round(size / 1024 / 1024)}MB exceeds threshold; forcing checkpoint
@@ -4209,7 +4508,7 @@ var init_mesh_runtime_store = __esm({
4209
4508
  const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
4210
4509
  if (count.count > 0) return;
4211
4510
  const path42 = legacyQueuePath(meshId);
4212
- if (!existsSync7(path42)) return;
4511
+ if (!existsSync8(path42)) return;
4213
4512
  try {
4214
4513
  const entries = JSON.parse(readFileSync6(path42, "utf-8"));
4215
4514
  if (!Array.isArray(entries)) return;
@@ -4489,12 +4788,51 @@ var init_mesh_runtime_store = __esm({
4489
4788
  return { id, nodeId: r.assigned_node_id ?? void 0, sessionId: r.assigned_session_id ?? void 0, message };
4490
4789
  });
4491
4790
  }
4492
- findAssignedBySession(meshId, sessionId, occurredAtIso) {
4791
+ /**
4792
+ * Resolve the `assigned` queue row a completion event belongs to.
4793
+ *
4794
+ * Clock-skew safety (C2): a completion event's `occurredAtIso` carries the
4795
+ * REMOTE WORKER's clock, while `updated_at` carries the COORDINATOR's clock
4796
+ * (set at assignment and re-bumped on every mutation). For a remote node,
4797
+ * coordinator-clock > worker-clock skew used to make an `updated_at <= occurredAt`
4798
+ * filter return nothing, stranding the finished task as `assigned` forever.
4799
+ *
4800
+ * We therefore NEVER filter completion-matching on the mutable `updated_at`:
4801
+ * 1. If `taskId` is given, match the exact `assigned` row by id (no time filter).
4802
+ * 2. Otherwise a session holds at most one `assigned` task — match it without a
4803
+ * time filter. If several exist (shouldn't normally), disambiguate by the
4804
+ * IMMUTABLE `dispatchTimestamp`: latest `dispatchTimestamp <= occurredAt`,
4805
+ * and if skew makes ALL of them later than `occurredAt`, fall back to the
4806
+ * most-recent `dispatchTimestamp` rather than returning null.
4807
+ */
4808
+ findAssignedBySession(meshId, sessionId, occurredAtIso, taskId) {
4493
4809
  this.ensureLegacyQueueMigrated(meshId);
4494
- const sql = occurredAtIso ? `SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned' AND updated_at <= ? ORDER BY updated_at DESC LIMIT 1` : `SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned' ORDER BY updated_at DESC LIMIT 1`;
4495
- const args = occurredAtIso ? [meshId, sessionId, occurredAtIso] : [meshId, sessionId];
4496
- const row = this.db.prepare(sql).get(...args);
4497
- return row ? JSON.parse(row.payload) : null;
4810
+ if (taskId) {
4811
+ const row = this.db.prepare(
4812
+ `SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned' AND id = ? LIMIT 1`
4813
+ ).get(meshId, sessionId, taskId);
4814
+ if (row) return JSON.parse(row.payload);
4815
+ }
4816
+ const rows = this.db.prepare(
4817
+ `SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned'`
4818
+ ).all(meshId, sessionId);
4819
+ if (rows.length === 0) return null;
4820
+ const entries = rows.map((r) => {
4821
+ try {
4822
+ return JSON.parse(r.payload);
4823
+ } catch {
4824
+ return null;
4825
+ }
4826
+ }).filter((e) => e !== null);
4827
+ if (entries.length === 0) return null;
4828
+ if (entries.length === 1) return entries[0];
4829
+ const orderKey = (e) => e.dispatchTimestamp ?? e.updatedAt ?? "";
4830
+ const byDispatchDesc = [...entries].sort((a, b) => orderKey(b).localeCompare(orderKey(a)));
4831
+ if (occurredAtIso) {
4832
+ const atOrBefore = byDispatchDesc.find((e) => orderKey(e) <= occurredAtIso);
4833
+ if (atOrBefore) return atOrBefore;
4834
+ }
4835
+ return byDispatchDesc[0];
4498
4836
  }
4499
4837
  toRow(entry) {
4500
4838
  return {
@@ -5750,297 +6088,6 @@ var init_mesh_review_inbox = __esm({
5750
6088
  }
5751
6089
  });
5752
6090
 
5753
- // src/logging/async-batch-writer.ts
5754
- import * as fs3 from "fs";
5755
- var AsyncBatchWriter;
5756
- var init_async_batch_writer = __esm({
5757
- "src/logging/async-batch-writer.ts"() {
5758
- "use strict";
5759
- AsyncBatchWriter = class {
5760
- // Maps filePath -> string buffer
5761
- static buffers = /* @__PURE__ */ new Map();
5762
- static writePromises = /* @__PURE__ */ new Map();
5763
- static flushTimer = null;
5764
- /**
5765
- * Queues data to be written to a file asynchronously in a batch.
5766
- */
5767
- static write(filePath, data) {
5768
- let buf = this.buffers.get(filePath);
5769
- if (!buf) {
5770
- buf = [];
5771
- this.buffers.set(filePath, buf);
5772
- }
5773
- buf.push(data);
5774
- if (!this.flushTimer) {
5775
- this.flushTimer = setTimeout(() => {
5776
- this.flushTimer = null;
5777
- this.flushAll();
5778
- }, 50);
5779
- }
5780
- }
5781
- static async flushAll() {
5782
- const entries = Array.from(this.buffers.entries());
5783
- this.buffers.clear();
5784
- for (const [filePath, buffer] of entries) {
5785
- const dataToWrite = buffer.join("");
5786
- const doWrite = async () => {
5787
- try {
5788
- const prevPromise = this.writePromises.get(filePath);
5789
- if (prevPromise) await prevPromise;
5790
- await fs3.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
5791
- } catch {
5792
- }
5793
- };
5794
- const writePromise = doWrite();
5795
- this.writePromises.set(filePath, writePromise);
5796
- writePromise.finally(() => {
5797
- if (this.writePromises.get(filePath) === writePromise) {
5798
- this.writePromises.delete(filePath);
5799
- }
5800
- });
5801
- }
5802
- }
5803
- };
5804
- }
5805
- });
5806
-
5807
- // src/logging/logger.ts
5808
- var logger_exports = {};
5809
- __export(logger_exports, {
5810
- LOG: () => LOG,
5811
- LOG_DIR_PATH: () => LOG_DIR_PATH,
5812
- LOG_PATH: () => LOG_PATH,
5813
- daemonLog: () => daemonLog,
5814
- getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
5815
- getDaemonLogDir: () => getDaemonLogDir,
5816
- getLogBufferSize: () => getLogBufferSize,
5817
- getLogLevel: () => getLogLevel,
5818
- getLogPath: () => getLogPath,
5819
- getRecentLogs: () => getRecentLogs,
5820
- installGlobalInterceptor: () => installGlobalInterceptor,
5821
- setLogLevel: () => setLogLevel
5822
- });
5823
- import * as fs4 from "fs";
5824
- import * as path9 from "path";
5825
- import * as os3 from "os";
5826
- function setLogLevel(level) {
5827
- currentLevel = level;
5828
- daemonLog("Logger", `Log level set to: ${level}`, "info");
5829
- }
5830
- function getLogLevel() {
5831
- return currentLevel;
5832
- }
5833
- function getDateStr() {
5834
- return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
5835
- }
5836
- function getDaemonLogDir() {
5837
- return LOG_DIR;
5838
- }
5839
- function getCurrentDaemonLogPath(date = /* @__PURE__ */ new Date()) {
5840
- return path9.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
5841
- }
5842
- function checkDateRotation() {
5843
- const today = getDateStr();
5844
- if (today !== currentDate) {
5845
- currentDate = today;
5846
- currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
5847
- cleanOldLogs();
5848
- }
5849
- }
5850
- function cleanOldLogs() {
5851
- try {
5852
- const files = fs4.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
5853
- const cutoff = /* @__PURE__ */ new Date();
5854
- cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
5855
- const cutoffStr = cutoff.toISOString().slice(0, 10);
5856
- for (const file of files) {
5857
- const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
5858
- if (dateMatch && dateMatch[1] < cutoffStr) {
5859
- try {
5860
- fs4.unlinkSync(path9.join(LOG_DIR, file));
5861
- } catch {
5862
- }
5863
- }
5864
- }
5865
- } catch {
5866
- }
5867
- }
5868
- function rotateSizeIfNeeded() {
5869
- try {
5870
- const stat2 = fs4.statSync(currentLogFile);
5871
- if (stat2.size > MAX_LOG_SIZE) {
5872
- const backup = currentLogFile.replace(".log", ".1.log");
5873
- try {
5874
- fs4.unlinkSync(backup);
5875
- } catch {
5876
- }
5877
- fs4.renameSync(currentLogFile, backup);
5878
- }
5879
- } catch {
5880
- }
5881
- }
5882
- function writeToFile(line) {
5883
- try {
5884
- if (++writeCount % 1e3 === 0) {
5885
- checkDateRotation();
5886
- rotateSizeIfNeeded();
5887
- }
5888
- AsyncBatchWriter.write(currentLogFile, line + "\n");
5889
- } catch {
5890
- }
5891
- }
5892
- function getRecentLogs(count = 50, minLevel = "info") {
5893
- const minNum = LEVEL_NUM[minLevel];
5894
- const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
5895
- return filtered.slice(-count);
5896
- }
5897
- function getLogBufferSize() {
5898
- return ringBuffer.length;
5899
- }
5900
- function ts() {
5901
- return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
5902
- }
5903
- function fullTs() {
5904
- return (/* @__PURE__ */ new Date()).toISOString();
5905
- }
5906
- function daemonLog(category, msg, level = "info") {
5907
- const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
5908
- const label = LEVEL_LABEL[level];
5909
- const line = `[${ts()}] [${label}] [${category}] ${msg}`;
5910
- if (!shouldOutput) return;
5911
- writeToFile(line);
5912
- ringBuffer.push({ ts: Date.now(), level, category, message: msg });
5913
- if (ringBuffer.length > RING_BUFFER_SIZE) {
5914
- ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
5915
- }
5916
- origConsoleLog(line);
5917
- }
5918
- function installGlobalInterceptor() {
5919
- if (interceptorInstalled) return;
5920
- interceptorInstalled = true;
5921
- const stripAnsi4 = (str) => str.replace(/\x1B\[[0-9;]*m/g, "");
5922
- const isDaemonLogLine = (msg) => /\[(DBG|INF|WRN|ERR)\]/.test(msg);
5923
- console.log = (...args) => {
5924
- origConsoleLog(...args);
5925
- try {
5926
- const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
5927
- const clean = stripAnsi4(msg);
5928
- if (isDaemonLogLine(clean)) return;
5929
- const line = clean.startsWith("[20") ? clean : `[${fullTs()}] ${clean}`;
5930
- writeToFile(line);
5931
- const catMatch = clean.match(/\[([^\]]+)\]/);
5932
- ringBuffer.push({
5933
- ts: Date.now(),
5934
- level: "info",
5935
- category: catMatch?.[1] || "System",
5936
- message: clean
5937
- });
5938
- if (ringBuffer.length > RING_BUFFER_SIZE) {
5939
- ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
5940
- }
5941
- } catch {
5942
- }
5943
- };
5944
- console.error = (...args) => {
5945
- origConsoleError(...args);
5946
- try {
5947
- const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
5948
- const clean = stripAnsi4(msg);
5949
- if (isDaemonLogLine(clean)) return;
5950
- const line = `[${fullTs()}] [ERROR] ${clean}`;
5951
- writeToFile(line);
5952
- ringBuffer.push({ ts: Date.now(), level: "error", category: "System", message: clean });
5953
- if (ringBuffer.length > RING_BUFFER_SIZE) {
5954
- ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
5955
- }
5956
- } catch {
5957
- }
5958
- };
5959
- console.warn = (...args) => {
5960
- origConsoleWarn(...args);
5961
- try {
5962
- const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
5963
- const clean = stripAnsi4(msg);
5964
- if (isDaemonLogLine(clean)) return;
5965
- const line = `[${fullTs()}] [WARN] ${clean}`;
5966
- writeToFile(line);
5967
- ringBuffer.push({ ts: Date.now(), level: "warn", category: "System", message: clean });
5968
- if (ringBuffer.length > RING_BUFFER_SIZE) {
5969
- ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
5970
- }
5971
- } catch {
5972
- }
5973
- };
5974
- writeToFile(`
5975
- === ADHDev Daemon started at ${fullTs()} ===`);
5976
- writeToFile(`Log file: ${currentLogFile}`);
5977
- writeToFile(`Log level: ${currentLevel}`);
5978
- }
5979
- function getLogPath() {
5980
- return currentLogFile;
5981
- }
5982
- var LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, LOG_DIR_PATH;
5983
- var init_logger = __esm({
5984
- "src/logging/logger.ts"() {
5985
- "use strict";
5986
- init_async_batch_writer();
5987
- LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
5988
- LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
5989
- currentLevel = "info";
5990
- 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");
5991
- MAX_LOG_SIZE = 5 * 1024 * 1024;
5992
- MAX_LOG_DAYS = 7;
5993
- try {
5994
- fs4.mkdirSync(LOG_DIR, { recursive: true });
5995
- } catch {
5996
- }
5997
- currentDate = getDateStr();
5998
- currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
5999
- cleanOldLogs();
6000
- try {
6001
- const oldLog = path9.join(LOG_DIR, "daemon.log");
6002
- if (fs4.existsSync(oldLog)) {
6003
- const stat2 = fs4.statSync(oldLog);
6004
- const oldDate = stat2.mtime.toISOString().slice(0, 10);
6005
- fs4.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
6006
- }
6007
- const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
6008
- if (fs4.existsSync(oldLogBackup)) {
6009
- fs4.unlinkSync(oldLogBackup);
6010
- }
6011
- } catch {
6012
- }
6013
- writeCount = 0;
6014
- RING_BUFFER_SIZE = 200;
6015
- ringBuffer = [];
6016
- origConsoleLog = console.log.bind(console);
6017
- origConsoleError = console.error.bind(console);
6018
- origConsoleWarn = console.warn.bind(console);
6019
- LOG = {
6020
- debug: (category, msg) => daemonLog(category, msg, "debug"),
6021
- info: (category, msg) => daemonLog(category, msg, "info"),
6022
- warn: (category, msg) => daemonLog(category, msg, "warn"),
6023
- error: (category, msg) => daemonLog(category, msg, "error"),
6024
- /**
6025
- * Create a scoped logger for a specific component.
6026
- * Category is baked in so callers only pass the message.
6027
- */
6028
- forComponent(category) {
6029
- return {
6030
- debug: (msg) => daemonLog(category, msg, "debug"),
6031
- info: (msg) => daemonLog(category, msg, "info"),
6032
- warn: (msg) => daemonLog(category, msg, "warn"),
6033
- error: (msg) => daemonLog(category, msg, "error"),
6034
- asLogFn: (level = "info") => (msg) => daemonLog(category, msg, level)
6035
- };
6036
- }
6037
- };
6038
- interceptorInstalled = false;
6039
- LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
6040
- LOG_DIR_PATH = LOG_DIR;
6041
- }
6042
- });
6043
-
6044
6091
  // src/commands/mesh-coordinator.ts
6045
6092
  var mesh_coordinator_exports = {};
6046
6093
  __export(mesh_coordinator_exports, {
@@ -6442,6 +6489,59 @@ var init_mesh_coordinator = __esm({
6442
6489
  }
6443
6490
  });
6444
6491
 
6492
+ // src/cli-adapters/resolve-executable.ts
6493
+ import { execFileSync } from "child_process";
6494
+ import { existsSync as existsSync12 } from "fs";
6495
+ import * as path10 from "path";
6496
+ function resolveWin32GlobalBin(trimmed) {
6497
+ if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
6498
+ return null;
6499
+ }
6500
+ const extraDirs = [];
6501
+ if (process.env.APPDATA) extraDirs.push(path10.join(process.env.APPDATA, "npm"));
6502
+ try {
6503
+ extraDirs.push(path10.dirname(process.execPath));
6504
+ } catch {
6505
+ }
6506
+ for (const dir of extraDirs) {
6507
+ if (!dir) continue;
6508
+ for (const ext of WIN_EXEC_EXT) {
6509
+ const full = path10.join(dir, trimmed + ext);
6510
+ if (existsSync12(full)) return full;
6511
+ }
6512
+ }
6513
+ return null;
6514
+ }
6515
+ function resolveWin32Executable(command) {
6516
+ if (process.platform !== "win32") return command;
6517
+ const trimmed = (command || "").trim();
6518
+ if (!trimmed) return command;
6519
+ if (path10.isAbsolute(trimmed) && existsSync12(trimmed)) return trimmed;
6520
+ try {
6521
+ const out = execFileSync("where", [trimmed], {
6522
+ encoding: "utf8",
6523
+ windowsHide: true
6524
+ }).trim();
6525
+ if (out) {
6526
+ const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
6527
+ const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path10.extname(m).toLowerCase()));
6528
+ return direct || matches[0] || command;
6529
+ }
6530
+ } catch {
6531
+ }
6532
+ const globalBin = resolveWin32GlobalBin(trimmed);
6533
+ if (globalBin) return globalBin;
6534
+ return command;
6535
+ }
6536
+ var DIRECT_EXEC_EXT, WIN_EXEC_EXT;
6537
+ var init_resolve_executable = __esm({
6538
+ "src/cli-adapters/resolve-executable.ts"() {
6539
+ "use strict";
6540
+ DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
6541
+ WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
6542
+ }
6543
+ });
6544
+
6445
6545
  // src/mesh/mesh-fast-forward.ts
6446
6546
  async function fastForwardMeshNode(args) {
6447
6547
  const workspace = typeof args.workspace === "string" ? args.workspace.trim() : "";
@@ -7893,8 +7993,8 @@ var init_mesh_events_utils = __esm({
7893
7993
  });
7894
7994
 
7895
7995
  // src/mesh/mesh-events-pending.ts
7896
- import { appendFileSync as appendFileSync2, existsSync as existsSync13, readFileSync as readFileSync11, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
7897
- import { join as join14 } from "path";
7996
+ import { appendFileSync as appendFileSync2, existsSync as existsSync14, readFileSync as readFileSync11, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
7997
+ import { join as join15 } from "path";
7898
7998
  import { randomUUID as randomUUID7 } from "crypto";
7899
7999
  function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
7900
8000
  const raw = Array.isArray(coordinatorDaemonId) ? coordinatorDaemonId : coordinatorDaemonId != null ? [coordinatorDaemonId] : [];
@@ -7957,9 +8057,9 @@ function getPendingEventsPath(meshId, coordinatorDaemonId) {
7957
8057
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
7958
8058
  if (coordinatorDaemonId) {
7959
8059
  const safeDaemon = coordinatorDaemonId.replace(/[^a-zA-Z0-9_-]/g, "_");
7960
- return join14(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
8060
+ return join15(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
7961
8061
  }
7962
- return join14(getLedgerDir(), `${safe}.pending-events.jsonl`);
8062
+ return join15(getLedgerDir(), `${safe}.pending-events.jsonl`);
7963
8063
  }
7964
8064
  function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
7965
8065
  if (!meshId) return [];
@@ -7968,7 +8068,7 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
7968
8068
  const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
7969
8069
  const events = [];
7970
8070
  for (const path42 of paths) {
7971
- if (!existsSync13(path42)) continue;
8071
+ if (!existsSync14(path42)) continue;
7972
8072
  try {
7973
8073
  const raw = readFileSync11(path42, "utf-8");
7974
8074
  const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
@@ -8045,7 +8145,7 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
8045
8145
  }
8046
8146
  function trimPendingEventsIfNeeded(path42) {
8047
8147
  try {
8048
- if (!existsSync13(path42)) return;
8148
+ if (!existsSync14(path42)) return;
8049
8149
  if (statSync6(path42).size <= MAX_PENDING_EVENTS_BYTES) return;
8050
8150
  const lines = readFileSync11(path42, "utf-8").split("\n").filter(Boolean);
8051
8151
  if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
@@ -8147,7 +8247,7 @@ function selectiveDrainFile(path42, predicate) {
8147
8247
  unlinkSync2(tmpPath);
8148
8248
  } catch {
8149
8249
  try {
8150
- if (existsSync13(tmpPath) && !existsSync13(path42)) renameSync4(tmpPath, path42);
8250
+ if (existsSync14(tmpPath) && !existsSync14(path42)) renameSync4(tmpPath, path42);
8151
8251
  } catch {
8152
8252
  }
8153
8253
  return [];
@@ -8241,7 +8341,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
8241
8341
  }
8242
8342
  const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
8243
8343
  for (const path42 of paths) {
8244
- if (existsSync13(path42)) try {
8344
+ if (existsSync14(path42)) try {
8245
8345
  unlinkSync2(path42);
8246
8346
  } catch {
8247
8347
  }
@@ -8672,7 +8772,7 @@ var init_spawn_env = __esm({
8672
8772
 
8673
8773
  // src/cli-adapters/provider-cli-shared.ts
8674
8774
  import * as os5 from "os";
8675
- import * as path10 from "path";
8775
+ import * as path11 from "path";
8676
8776
  function stripAnsi(str) {
8677
8777
  return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
8678
8778
  }
@@ -8748,24 +8848,24 @@ function buildCliScreenSnapshot(text) {
8748
8848
  function findBinary(name) {
8749
8849
  const trimmed = String(name || "").trim();
8750
8850
  if (!trimmed) return trimmed;
8751
- const expanded = trimmed.startsWith("~") ? path10.join(os5.homedir(), trimmed.slice(1)) : trimmed;
8752
- if (path10.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
8753
- return path10.isAbsolute(expanded) ? expanded : path10.resolve(expanded);
8851
+ const expanded = trimmed.startsWith("~") ? path11.join(os5.homedir(), trimmed.slice(1)) : trimmed;
8852
+ if (path11.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
8853
+ return path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
8754
8854
  }
8755
8855
  const isWin = os5.platform() === "win32";
8756
- const paths = (process.env.PATH || "").split(path10.delimiter);
8856
+ const paths = (process.env.PATH || "").split(path11.delimiter);
8757
8857
  const extraDirs = [];
8758
8858
  if (isWin) {
8759
- if (process.env.APPDATA) extraDirs.push(path10.join(process.env.APPDATA, "npm"));
8859
+ if (process.env.APPDATA) extraDirs.push(path11.join(process.env.APPDATA, "npm"));
8760
8860
  try {
8761
- extraDirs.push(path10.dirname(process.execPath));
8861
+ extraDirs.push(path11.dirname(process.execPath));
8762
8862
  } catch {
8763
8863
  }
8764
8864
  } else {
8765
- extraDirs.push(path10.join(os5.homedir(), ".npm-global", "bin"));
8865
+ extraDirs.push(path11.join(os5.homedir(), ".npm-global", "bin"));
8766
8866
  extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
8767
8867
  try {
8768
- extraDirs.push(path10.dirname(process.execPath));
8868
+ extraDirs.push(path11.dirname(process.execPath));
8769
8869
  } catch {
8770
8870
  }
8771
8871
  }
@@ -8774,7 +8874,7 @@ function findBinary(name) {
8774
8874
  for (const p of searchDirs) {
8775
8875
  if (!p) continue;
8776
8876
  for (const ext of exes) {
8777
- const fullPath = path10.join(p, trimmed + ext);
8877
+ const fullPath = path11.join(p, trimmed + ext);
8778
8878
  try {
8779
8879
  const fs32 = __require("fs");
8780
8880
  if (fs32.existsSync(fullPath)) {
@@ -8790,7 +8890,7 @@ function findBinary(name) {
8790
8890
  return isWin ? `${trimmed}.cmd` : trimmed;
8791
8891
  }
8792
8892
  function isScriptBinary(binaryPath) {
8793
- if (!path10.isAbsolute(binaryPath)) return false;
8893
+ if (!path11.isAbsolute(binaryPath)) return false;
8794
8894
  try {
8795
8895
  const fs32 = __require("fs");
8796
8896
  const resolved = fs32.realpathSync(binaryPath);
@@ -8806,7 +8906,7 @@ function isScriptBinary(binaryPath) {
8806
8906
  }
8807
8907
  }
8808
8908
  function looksLikeMachOOrElf(filePath) {
8809
- if (!path10.isAbsolute(filePath)) return false;
8909
+ if (!path11.isAbsolute(filePath)) return false;
8810
8910
  try {
8811
8911
  const fs32 = __require("fs");
8812
8912
  const resolved = fs32.realpathSync(filePath);
@@ -9063,8 +9163,8 @@ var init_provider_cli_shared = __esm({
9063
9163
  // src/detection/cli-detector.ts
9064
9164
  import { exec } from "child_process";
9065
9165
  import * as os6 from "os";
9066
- import * as path11 from "path";
9067
- import { existsSync as existsSync14 } from "fs";
9166
+ import * as path12 from "path";
9167
+ import { existsSync as existsSync15 } from "fs";
9068
9168
  function parseVersion(raw) {
9069
9169
  const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
9070
9170
  return match ? match[1] : raw.split("\n")[0].slice(0, 100);
@@ -9076,19 +9176,19 @@ function shellQuote(value) {
9076
9176
  function expandHome(value) {
9077
9177
  const trimmed = value.trim();
9078
9178
  if (!trimmed.startsWith("~")) return trimmed;
9079
- return path11.join(os6.homedir(), trimmed.slice(1));
9179
+ return path12.join(os6.homedir(), trimmed.slice(1));
9080
9180
  }
9081
9181
  function isExplicitCommandPath(command) {
9082
9182
  const trimmed = command.trim();
9083
- return path11.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
9183
+ return path12.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
9084
9184
  }
9085
9185
  function resolveCommandPath(command) {
9086
9186
  const trimmed = command.trim();
9087
9187
  if (!trimmed) return null;
9088
9188
  if (isExplicitCommandPath(trimmed)) {
9089
9189
  const expanded = expandHome(trimmed);
9090
- const candidate = path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
9091
- return existsSync14(candidate) ? candidate : null;
9190
+ const candidate = path12.isAbsolute(expanded) ? expanded : path12.resolve(expanded);
9191
+ return existsSync15(candidate) ? candidate : null;
9092
9192
  }
9093
9193
  return null;
9094
9194
  }
@@ -9098,7 +9198,7 @@ async function resolveDetectionPath(command, whichCmd) {
9098
9198
  const whichResult = await execAsync(`${whichCmd} ${shellQuote(command)}`);
9099
9199
  if (whichResult) return whichResult.split("\n")[0];
9100
9200
  const resolved = findBinary(command);
9101
- if (path11.isAbsolute(resolved) && existsSync14(resolved)) return resolved;
9201
+ if (path12.isAbsolute(resolved) && existsSync15(resolved)) return resolved;
9102
9202
  return null;
9103
9203
  }
9104
9204
  function execAsync(cmd, timeoutMs = 5e3) {
@@ -9443,7 +9543,7 @@ var init_mesh_unresolved_forward_outbox = __esm({
9443
9543
  });
9444
9544
 
9445
9545
  // src/mesh/mesh-events-coordinator.ts
9446
- import { existsSync as existsSync15 } from "fs";
9546
+ import { existsSync as existsSync16 } from "fs";
9447
9547
  function resolveCoordinatorDrainDaemonIds(components) {
9448
9548
  const ids = /* @__PURE__ */ new Set();
9449
9549
  const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
@@ -10231,7 +10331,7 @@ async function maybeAutoFastForwardIdleNode(components, args) {
10231
10331
  const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
10232
10332
  const workspace = readNonEmptyString2(node?.workspace);
10233
10333
  if (!workspace) return;
10234
- if (!existsSync15(workspace)) return;
10334
+ if (!existsSync16(workspace)) return;
10235
10335
  const policy = resolveAutoFastForwardPolicy(mesh);
10236
10336
  if (!policy.enabled) return;
10237
10337
  if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId, args.sessionId)) return;
@@ -10430,8 +10530,10 @@ function injectMeshSystemMessage(components, args) {
10430
10530
  }
10431
10531
  }
10432
10532
  function markSessionTerminal(sessionId, outcome, occurredAtMs) {
10533
+ const eventTaskId = readNonEmptyString2(args.metadataEvent.taskId) || void 0;
10433
10534
  const task = updateSessionTaskStatus(args.meshId, sessionId, outcome, {
10434
- occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0
10535
+ occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0,
10536
+ taskId: eventTaskId
10435
10537
  });
10436
10538
  updateDirectDispatchStatus(args.meshId, sessionId, outcome);
10437
10539
  markSessionDeliveriesTerminal(args.meshId, sessionId, outcome);
@@ -12728,18 +12830,18 @@ __export(external_sources_exports, {
12728
12830
  });
12729
12831
  import * as fs9 from "fs";
12730
12832
  import * as os11 from "os";
12731
- import * as path17 from "path";
12833
+ import * as path18 from "path";
12732
12834
  function adhdevDir() {
12733
- return path17.join(os11.homedir(), ".adhdev");
12835
+ return path18.join(os11.homedir(), ".adhdev");
12734
12836
  }
12735
12837
  function externalRoot() {
12736
- return path17.join(adhdevDir(), "external");
12838
+ return path18.join(adhdevDir(), "external");
12737
12839
  }
12738
12840
  function sourcesFilePath() {
12739
- return path17.join(adhdevDir(), SOURCES_FILENAME);
12841
+ return path18.join(adhdevDir(), SOURCES_FILENAME);
12740
12842
  }
12741
12843
  function activeFilePath() {
12742
- return path17.join(adhdevDir(), ACTIVE_FILENAME);
12844
+ return path18.join(adhdevDir(), ACTIVE_FILENAME);
12743
12845
  }
12744
12846
  function ensureAdhdevDir() {
12745
12847
  const d = adhdevDir();
@@ -12806,7 +12908,7 @@ function inventoryExternalSources() {
12806
12908
  for (const sourceEntry of entries) {
12807
12909
  if (!sourceEntry.isDirectory()) continue;
12808
12910
  const sourceName = sourceEntry.name;
12809
- const sourceDir = path17.join(root, sourceName);
12911
+ const sourceDir = path18.join(root, sourceName);
12810
12912
  const providers = {};
12811
12913
  let categoryEntries;
12812
12914
  try {
@@ -12817,7 +12919,7 @@ function inventoryExternalSources() {
12817
12919
  for (const categoryEntry of categoryEntries) {
12818
12920
  if (!categoryEntry.isDirectory()) continue;
12819
12921
  const category = categoryEntry.name;
12820
- const categoryDir = path17.join(sourceDir, category);
12922
+ const categoryDir = path18.join(sourceDir, category);
12821
12923
  let typeEntries;
12822
12924
  try {
12823
12925
  typeEntries = fs9.readdirSync(categoryDir, { withFileTypes: true });
@@ -12827,9 +12929,9 @@ function inventoryExternalSources() {
12827
12929
  const types = [];
12828
12930
  for (const typeEntry of typeEntries) {
12829
12931
  if (!typeEntry.isDirectory()) continue;
12830
- const typeDir = path17.join(categoryDir, typeEntry.name);
12831
- const hasV1 = fs9.existsSync(path17.join(typeDir, "provider.v1.json"));
12832
- const hasV0 = fs9.existsSync(path17.join(typeDir, "provider.json"));
12932
+ const typeDir = path18.join(categoryDir, typeEntry.name);
12933
+ const hasV1 = fs9.existsSync(path18.join(typeDir, "provider.v1.json"));
12934
+ const hasV0 = fs9.existsSync(path18.join(typeDir, "provider.json"));
12833
12935
  if (hasV1 || hasV0) types.push(typeEntry.name);
12834
12936
  }
12835
12937
  if (types.length > 0) providers[category] = types;
@@ -13033,59 +13135,6 @@ var init_terminal_screen = __esm({
13033
13135
  }
13034
13136
  });
13035
13137
 
13036
- // src/cli-adapters/resolve-executable.ts
13037
- import { execFileSync } from "child_process";
13038
- import { existsSync as existsSync22 } from "fs";
13039
- import * as path18 from "path";
13040
- function resolveWin32GlobalBin(trimmed) {
13041
- if (path18.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
13042
- return null;
13043
- }
13044
- const extraDirs = [];
13045
- if (process.env.APPDATA) extraDirs.push(path18.join(process.env.APPDATA, "npm"));
13046
- try {
13047
- extraDirs.push(path18.dirname(process.execPath));
13048
- } catch {
13049
- }
13050
- for (const dir of extraDirs) {
13051
- if (!dir) continue;
13052
- for (const ext of WIN_EXEC_EXT) {
13053
- const full = path18.join(dir, trimmed + ext);
13054
- if (existsSync22(full)) return full;
13055
- }
13056
- }
13057
- return null;
13058
- }
13059
- function resolveWin32Executable(command) {
13060
- if (process.platform !== "win32") return command;
13061
- const trimmed = (command || "").trim();
13062
- if (!trimmed) return command;
13063
- if (path18.isAbsolute(trimmed) && existsSync22(trimmed)) return trimmed;
13064
- try {
13065
- const out = execFileSync("where", [trimmed], {
13066
- encoding: "utf8",
13067
- windowsHide: true
13068
- }).trim();
13069
- if (out) {
13070
- const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
13071
- const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path18.extname(m).toLowerCase()));
13072
- return direct || matches[0] || command;
13073
- }
13074
- } catch {
13075
- }
13076
- const globalBin = resolveWin32GlobalBin(trimmed);
13077
- if (globalBin) return globalBin;
13078
- return command;
13079
- }
13080
- var DIRECT_EXEC_EXT, WIN_EXEC_EXT;
13081
- var init_resolve_executable = __esm({
13082
- "src/cli-adapters/resolve-executable.ts"() {
13083
- "use strict";
13084
- DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
13085
- WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
13086
- }
13087
- });
13088
-
13089
13138
  // src/cli-adapters/pty-transport.ts
13090
13139
  var pty_transport_exports = {};
13091
13140
  __export(pty_transport_exports, {
@@ -15076,7 +15125,7 @@ function appendBoundedText(current, chunk, maxChars) {
15076
15125
  if (current.length <= keepFromCurrent) return current + chunk;
15077
15126
  return current.slice(-keepFromCurrent) + chunk;
15078
15127
  }
15079
- var ProviderCliAdapter;
15128
+ var FORCE_SUBMIT_SETTLE_MS, FORCE_SUBMIT_MAX_WAIT_MS, FORCE_SUBMIT_POLL_MS, ProviderCliAdapter;
15080
15129
  var init_provider_cli_adapter = __esm({
15081
15130
  "src/cli-adapters/provider-cli-adapter.ts"() {
15082
15131
  "use strict";
@@ -15091,6 +15140,9 @@ var init_provider_cli_adapter = __esm({
15091
15140
  init_provider_cli_config();
15092
15141
  init_provider_cli_runtime();
15093
15142
  init_provider_cli_shared();
15143
+ FORCE_SUBMIT_SETTLE_MS = 150;
15144
+ FORCE_SUBMIT_MAX_WAIT_MS = 1500;
15145
+ FORCE_SUBMIT_POLL_MS = 50;
15094
15146
  ProviderCliAdapter = class _ProviderCliAdapter {
15095
15147
  constructor(provider, workingDir, extraArgs = [], extraEnv = {}, transportFactory = new NodePtyTransportFactory()) {
15096
15148
  this.extraArgs = extraArgs;
@@ -16019,9 +16071,23 @@ ${lastSnapshot}`;
16019
16071
  return;
16020
16072
  }
16021
16073
  LOG.info("CLI", `[${this.cliType}] force-sending prompt while status=${this.engine.currentStatus}`);
16022
- await this.writeToPty(content + this.sendKey);
16074
+ await this.writeToPty(content);
16075
+ await this.waitForForceSubmitSettle(content);
16076
+ await this.writeToPty(this.sendKey);
16023
16077
  this.onStatusChange?.();
16024
16078
  }
16079
+ async waitForForceSubmitSettle(content) {
16080
+ const startedAt = Date.now();
16081
+ const normalizedPromptSnippet = normalizePromptText(extractPromptRetrySnippet(content));
16082
+ await new Promise((resolve24) => setTimeout(resolve24, FORCE_SUBMIT_SETTLE_MS));
16083
+ if (!normalizedPromptSnippet) return;
16084
+ while (Date.now() - startedAt < FORCE_SUBMIT_MAX_WAIT_MS) {
16085
+ if (!this.ptyProcess) return;
16086
+ const screenText = this.terminalScreen.getText();
16087
+ if (promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
16088
+ await new Promise((resolve24) => setTimeout(resolve24, FORCE_SUBMIT_POLL_MS));
16089
+ }
16090
+ }
16025
16091
  enqueuePendingOutboundMessage(text, reason) {
16026
16092
  const content = String(text || "");
16027
16093
  const duplicate = this.pendingOutboundQueue.some((message2) => message2.content === content);
@@ -19433,13 +19499,20 @@ var MESH_REFINE_CONFIG_SCHEMA = {
19433
19499
  function isMeshConfigRecord(value) {
19434
19500
  return !!value && typeof value === "object" && !Array.isArray(value);
19435
19501
  }
19502
+ var SHELL_METACHAR_RE = /[;&|<>`$\n\r'"]/;
19503
+ var SAFE_TOKEN_RE = /^[A-Za-z0-9_@./:=+-]+$/;
19504
+ var SAFE_WIN32_EXEC_TOKEN_RE = /^[A-Za-z0-9_@./:=+\\-]+$/;
19436
19505
  function tokenizeCommandString(command) {
19437
19506
  const trimmed = command.trim();
19438
19507
  if (!trimmed) return null;
19439
- if (/[;&|<>`$\\\n\r'\"]/.test(trimmed)) return null;
19508
+ if (SHELL_METACHAR_RE.test(trimmed)) return null;
19440
19509
  const tokens = trimmed.split(/\s+/).filter(Boolean);
19441
19510
  if (!tokens.length) return null;
19442
- if (tokens.some((token) => !/^[A-Za-z0-9_@./:=+-]+$/.test(token))) return null;
19511
+ const isWin32 = process.platform === "win32";
19512
+ for (let i = 0; i < tokens.length; i++) {
19513
+ const re = isWin32 && i === 0 ? SAFE_WIN32_EXEC_TOKEN_RE : SAFE_TOKEN_RE;
19514
+ if (!re.test(tokens[i])) return null;
19515
+ }
19443
19516
  return tokens;
19444
19517
  }
19445
19518
  function validateCategory(value) {
@@ -19649,8 +19722,9 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
19649
19722
  }
19650
19723
 
19651
19724
  // src/mesh/worktree-bootstrap-config.ts
19652
- import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
19653
- import { join as join13, resolve as pathResolve } from "path";
19725
+ init_resolve_executable();
19726
+ import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
19727
+ import { join as join14, resolve as pathResolve } from "path";
19654
19728
  import { execFile as execFile3 } from "child_process";
19655
19729
  import { createHash as createHash3 } from "crypto";
19656
19730
  import { promisify as promisify3 } from "util";
@@ -19741,8 +19815,8 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
19741
19815
  return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
19742
19816
  }
19743
19817
  for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
19744
- const configPath = join13(workspace, relative5);
19745
- if (!existsSync12(configPath)) continue;
19818
+ const configPath = join14(workspace, relative5);
19819
+ if (!existsSync13(configPath)) continue;
19746
19820
  try {
19747
19821
  const parsed = parseConfigText3(configPath, readFileSync10(configPath, "utf-8"));
19748
19822
  const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
@@ -19757,7 +19831,7 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
19757
19831
  function computeStaleInputsDigest(workspace, staleInputs) {
19758
19832
  const digest = {};
19759
19833
  for (const relative5 of staleInputs ?? []) {
19760
- const filePath = join13(workspace, relative5);
19834
+ const filePath = join14(workspace, relative5);
19761
19835
  try {
19762
19836
  digest[relative5] = createHash3("sha256").update(readFileSync10(filePath)).digest("hex");
19763
19837
  } catch {
@@ -19829,10 +19903,10 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
19829
19903
  staleInputs: loaded.config.staleInputs
19830
19904
  };
19831
19905
  const staleInputPaths = loaded.config.staleInputs ?? [];
19832
- const initiallyAbsent = staleInputPaths.filter((p) => !existsSync12(join13(workspace, p)));
19906
+ const initiallyAbsent = staleInputPaths.filter((p) => !existsSync13(join14(workspace, p)));
19833
19907
  for (const command of validation.commands) {
19834
19908
  if (initiallyAbsent.length > 0) {
19835
- const appearedNow = initiallyAbsent.filter((p) => existsSync12(join13(workspace, p)));
19909
+ const appearedNow = initiallyAbsent.filter((p) => existsSync13(join14(workspace, p)));
19836
19910
  if (appearedNow.length > 0) {
19837
19911
  state.status = "stale";
19838
19912
  state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -19843,8 +19917,9 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
19843
19917
  const cwd = command.cwd ? pathResolve(workspace, command.cwd) : workspace;
19844
19918
  const startedAt = Date.now();
19845
19919
  state.lastCommand = command.displayCommand;
19920
+ const resolvedCommand = resolveWin32Executable(command.command);
19846
19921
  try {
19847
- const result = await execFileAsync4(command.command, command.args, {
19922
+ const result = await execFileAsync4(resolvedCommand, command.args, {
19848
19923
  cwd,
19849
19924
  encoding: "utf8",
19850
19925
  timeout: command.timeoutMs || DEFAULT_TIMEOUT_MS2,
@@ -20080,8 +20155,8 @@ var P2pRelayFailureError = class extends Error {
20080
20155
 
20081
20156
  // src/config/state-store.ts
20082
20157
  init_config();
20083
- import { existsSync as existsSync16, readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "fs";
20084
- import { join as join17 } from "path";
20158
+ import { existsSync as existsSync17, readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "fs";
20159
+ import { join as join18 } from "path";
20085
20160
  var DEFAULT_STATE = {
20086
20161
  recentActivity: [],
20087
20162
  savedProviderSessions: [],
@@ -20094,7 +20169,7 @@ function isPlainObject2(value) {
20094
20169
  return !!value && typeof value === "object" && !Array.isArray(value);
20095
20170
  }
20096
20171
  function getStatePath() {
20097
- return join17(getConfigDir(), "state.json");
20172
+ return join18(getConfigDir(), "state.json");
20098
20173
  }
20099
20174
  function normalizeState(raw) {
20100
20175
  const parsed = isPlainObject2(raw) ? raw : {};
@@ -20130,7 +20205,7 @@ function normalizeState(raw) {
20130
20205
  }
20131
20206
  function loadState() {
20132
20207
  const statePath = getStatePath();
20133
- if (!existsSync16(statePath)) {
20208
+ if (!existsSync17(statePath)) {
20134
20209
  return { ...DEFAULT_STATE };
20135
20210
  }
20136
20211
  try {
@@ -20152,19 +20227,19 @@ function resetState() {
20152
20227
  // src/detection/ide-detector.ts
20153
20228
  import { exec as exec2 } from "child_process";
20154
20229
  import { promisify as promisify4 } from "util";
20155
- import { existsSync as existsSync18, statSync as statSync8 } from "fs";
20230
+ import { existsSync as existsSync19, statSync as statSync8 } from "fs";
20156
20231
  import { platform as platform3, homedir as homedir8 } from "os";
20157
- import * as path13 from "path";
20232
+ import * as path14 from "path";
20158
20233
 
20159
20234
  // src/detection/win32-ide-version.ts
20160
20235
  import * as fs5 from "fs";
20161
- import * as path12 from "path";
20236
+ import * as path13 from "path";
20162
20237
  function manifestCandidates(exeDir) {
20163
20238
  return [
20164
- path12.join(exeDir, "resources", "app", "product.json"),
20165
- path12.join(exeDir, "resources", "app", "package.json"),
20239
+ path13.join(exeDir, "resources", "app", "product.json"),
20240
+ path13.join(exeDir, "resources", "app", "package.json"),
20166
20241
  // Some packagings keep product.json one level up.
20167
- path12.join(exeDir, "product.json")
20242
+ path13.join(exeDir, "product.json")
20168
20243
  ];
20169
20244
  }
20170
20245
  function parseVersionFromManifest(raw) {
@@ -20182,9 +20257,9 @@ function readWin32IdeVersionFromDisk(exePath) {
20182
20257
  if (!exePath) return null;
20183
20258
  let exeDir;
20184
20259
  try {
20185
- exeDir = fs5.statSync(exePath).isDirectory() ? exePath : path12.dirname(exePath);
20260
+ exeDir = fs5.statSync(exePath).isDirectory() ? exePath : path13.dirname(exePath);
20186
20261
  } catch {
20187
- exeDir = path12.dirname(exePath);
20262
+ exeDir = path13.dirname(exePath);
20188
20263
  }
20189
20264
  for (const candidate of manifestCandidates(exeDir)) {
20190
20265
  try {
@@ -20198,7 +20273,7 @@ function readWin32IdeVersionFromDisk(exePath) {
20198
20273
  }
20199
20274
  function isKnownWin32GuiExe(binPath, win32ProcessNames) {
20200
20275
  if (!binPath) return false;
20201
- const base = path12.win32.basename(binPath).toLowerCase();
20276
+ const base = path13.win32.basename(binPath).toLowerCase();
20202
20277
  if (!base.endsWith(".exe")) return false;
20203
20278
  for (const names of Object.values(win32ProcessNames)) {
20204
20279
  for (const name of names) {
@@ -20230,10 +20305,10 @@ function getMergedDefinitions() {
20230
20305
  function findCliCommand(command) {
20231
20306
  const trimmed = String(command || "").trim();
20232
20307
  if (!trimmed) return null;
20233
- if (path13.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
20234
- const candidate = trimmed.startsWith("~") ? path13.join(homedir8(), trimmed.slice(1)) : trimmed;
20235
- const resolved = path13.isAbsolute(candidate) ? candidate : path13.resolve(candidate);
20236
- return existsSync18(resolved) ? resolved : null;
20308
+ if (path14.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
20309
+ const candidate = trimmed.startsWith("~") ? path14.join(homedir8(), trimmed.slice(1)) : trimmed;
20310
+ const resolved = path14.isAbsolute(candidate) ? candidate : path14.resolve(candidate);
20311
+ return existsSync19(resolved) ? resolved : null;
20237
20312
  }
20238
20313
  const isWin = platform3() === "win32";
20239
20314
  const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
@@ -20241,9 +20316,9 @@ function findCliCommand(command) {
20241
20316
  for (const p of paths) {
20242
20317
  if (!p) continue;
20243
20318
  for (const ext of exes) {
20244
- const fullPath = path13.join(p, trimmed + ext);
20319
+ const fullPath = path14.join(p, trimmed + ext);
20245
20320
  try {
20246
- if (existsSync18(fullPath)) {
20321
+ if (existsSync19(fullPath)) {
20247
20322
  const stat2 = statSync8(fullPath);
20248
20323
  if (stat2.isFile() && (isWin || stat2.mode & 73)) {
20249
20324
  return fullPath;
@@ -20258,13 +20333,13 @@ function findCliCommand(command) {
20258
20333
  function checkPathExists(paths) {
20259
20334
  const home = homedir8();
20260
20335
  for (const p of paths) {
20261
- const normalized = p.startsWith("~") ? path13.join(home, p.slice(1)) : p;
20336
+ const normalized = p.startsWith("~") ? path14.join(home, p.slice(1)) : p;
20262
20337
  if (normalized.includes("*")) {
20263
20338
  const username = home.split(/[\\/]/).pop() || "";
20264
20339
  const resolved = normalized.replace("*", username);
20265
- if (existsSync18(resolved)) return resolved;
20340
+ if (existsSync19(resolved)) return resolved;
20266
20341
  } else {
20267
- if (existsSync18(normalized)) return normalized;
20342
+ if (existsSync19(normalized)) return normalized;
20268
20343
  }
20269
20344
  }
20270
20345
  return null;
@@ -20278,7 +20353,7 @@ async function detectIDEs(providerLoader) {
20278
20353
  let resolvedCli = cliPath;
20279
20354
  if (!resolvedCli && appPath && os30 === "darwin") {
20280
20355
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
20281
- if (existsSync18(bundledCli)) resolvedCli = bundledCli;
20356
+ if (existsSync19(bundledCli)) resolvedCli = bundledCli;
20282
20357
  }
20283
20358
  if (!resolvedCli && appPath && os30 === "win32") {
20284
20359
  const { dirname: dirname17 } = await import("path");
@@ -20291,7 +20366,7 @@ async function detectIDEs(providerLoader) {
20291
20366
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
20292
20367
  ];
20293
20368
  for (const c of candidates) {
20294
- if (existsSync18(c)) {
20369
+ if (existsSync19(c)) {
20295
20370
  resolvedCli = c;
20296
20371
  break;
20297
20372
  }
@@ -22150,9 +22225,9 @@ ${cleanBody}`;
22150
22225
  // src/config/chat-history.ts
22151
22226
  init_chat_message_normalization();
22152
22227
  import * as fs6 from "fs";
22153
- import * as path14 from "path";
22228
+ import * as path15 from "path";
22154
22229
  import * as os8 from "os";
22155
- var HISTORY_DIR = path14.join(os8.homedir(), ".adhdev", "history");
22230
+ var HISTORY_DIR = path15.join(os8.homedir(), ".adhdev", "history");
22156
22231
  var RETAIN_DAYS = 30;
22157
22232
  var SAVED_HISTORY_INDEX_VERSION = 1;
22158
22233
  var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
@@ -22338,7 +22413,7 @@ function extractSavedHistorySessionIdFromFile(file) {
22338
22413
  function buildSavedHistoryFileSignatureMap(dir, files) {
22339
22414
  return new Map(files.map((file) => {
22340
22415
  try {
22341
- const stat2 = fs6.statSync(path14.join(dir, file));
22416
+ const stat2 = fs6.statSync(path15.join(dir, file));
22342
22417
  return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
22343
22418
  } catch {
22344
22419
  return [file, `${file}:missing`];
@@ -22349,7 +22424,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
22349
22424
  return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
22350
22425
  }
22351
22426
  function getSavedHistoryIndexFilePath(dir) {
22352
- return path14.join(dir, SAVED_HISTORY_INDEX_FILE);
22427
+ return path15.join(dir, SAVED_HISTORY_INDEX_FILE);
22353
22428
  }
22354
22429
  function getSavedHistoryIndexLockPath(dir) {
22355
22430
  return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
@@ -22451,7 +22526,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
22451
22526
  }
22452
22527
  for (const file of Array.from(currentEntries.keys())) {
22453
22528
  if (incomingFiles.has(file)) continue;
22454
- if (!fs6.existsSync(path14.join(dir, file))) {
22529
+ if (!fs6.existsSync(path15.join(dir, file))) {
22455
22530
  currentEntries.delete(file);
22456
22531
  }
22457
22532
  }
@@ -22477,7 +22552,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
22477
22552
  const indexStat = fs6.statSync(getSavedHistoryIndexFilePath(dir));
22478
22553
  const files = listHistoryFiles(dir);
22479
22554
  for (const file of files) {
22480
- const stat2 = fs6.statSync(path14.join(dir, file));
22555
+ const stat2 = fs6.statSync(path15.join(dir, file));
22481
22556
  if (stat2.mtimeMs > indexStat.mtimeMs) return true;
22482
22557
  }
22483
22558
  return false;
@@ -22487,14 +22562,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
22487
22562
  }
22488
22563
  function buildSavedHistoryFileSignature(dir, file) {
22489
22564
  try {
22490
- const stat2 = fs6.statSync(path14.join(dir, file));
22565
+ const stat2 = fs6.statSync(path15.join(dir, file));
22491
22566
  return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
22492
22567
  } catch {
22493
22568
  return `${file}:missing`;
22494
22569
  }
22495
22570
  }
22496
22571
  function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
22497
- const filePath = path14.join(dir, file);
22572
+ const filePath = path15.join(dir, file);
22498
22573
  const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
22499
22574
  const currentEntry = entries.get(file) || null;
22500
22575
  const nextSummary = updater(currentEntry?.summary || null);
@@ -22567,7 +22642,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
22567
22642
  function computeSavedHistoryFileSummary(dir, file) {
22568
22643
  const historySessionId = extractSavedHistorySessionIdFromFile(file);
22569
22644
  if (!historySessionId) return null;
22570
- const filePath = path14.join(dir, file);
22645
+ const filePath = path15.join(dir, file);
22571
22646
  const content = fs6.readFileSync(filePath, "utf-8");
22572
22647
  const lines = content.split("\n").filter(Boolean);
22573
22648
  let messageCount = 0;
@@ -22654,7 +22729,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
22654
22729
  const summaryBySessionId = /* @__PURE__ */ new Map();
22655
22730
  const nextPersistedEntries = /* @__PURE__ */ new Map();
22656
22731
  for (const file of files.slice().sort()) {
22657
- const filePath = path14.join(dir, file);
22732
+ const filePath = path15.join(dir, file);
22658
22733
  const signature = fileSignatures.get(file) || `${file}:missing`;
22659
22734
  const cached3 = savedHistoryFileSummaryCache.get(filePath);
22660
22735
  const persisted = persistedEntries.get(file);
@@ -22774,12 +22849,12 @@ var ChatHistoryWriter = class {
22774
22849
  });
22775
22850
  }
22776
22851
  if (newMessages.length === 0) return;
22777
- const dir = path14.join(HISTORY_DIR, this.sanitize(agentType));
22852
+ const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
22778
22853
  fs6.mkdirSync(dir, { recursive: true });
22779
22854
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
22780
22855
  const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
22781
22856
  const fileName = `${filePrefix}${date}.jsonl`;
22782
- const filePath = path14.join(dir, fileName);
22857
+ const filePath = path15.join(dir, fileName);
22783
22858
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
22784
22859
  fs6.appendFileSync(filePath, lines, "utf-8");
22785
22860
  updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
@@ -22870,11 +22945,11 @@ var ChatHistoryWriter = class {
22870
22945
  const ws = String(workspace || "").trim();
22871
22946
  if (!id || !ws) return;
22872
22947
  try {
22873
- const dir = path14.join(HISTORY_DIR, this.sanitize(agentType));
22948
+ const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
22874
22949
  fs6.mkdirSync(dir, { recursive: true });
22875
22950
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
22876
22951
  const fileName = `${this.sanitize(id)}_${date}.jsonl`;
22877
- const filePath = path14.join(dir, fileName);
22952
+ const filePath = path15.join(dir, fileName);
22878
22953
  const record = {
22879
22954
  ts: (/* @__PURE__ */ new Date()).toISOString(),
22880
22955
  receivedAt: Date.now(),
@@ -22920,14 +22995,14 @@ var ChatHistoryWriter = class {
22920
22995
  this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
22921
22996
  this.lastSeenCounts.delete(fromDedupKey);
22922
22997
  }
22923
- const dir = path14.join(HISTORY_DIR, this.sanitize(agentType));
22998
+ const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
22924
22999
  if (!fs6.existsSync(dir)) return;
22925
23000
  const fromPrefix = `${this.sanitize(fromId)}_`;
22926
23001
  const toPrefix = `${this.sanitize(toId)}_`;
22927
23002
  const files = fs6.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
22928
23003
  for (const file of files) {
22929
- const sourcePath = path14.join(dir, file);
22930
- const targetPath = path14.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
23004
+ const sourcePath = path15.join(dir, file);
23005
+ const targetPath = path15.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
22931
23006
  const sourceLines = fs6.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
22932
23007
  const rewritten = sourceLines.map((line) => {
22933
23008
  try {
@@ -22961,13 +23036,13 @@ var ChatHistoryWriter = class {
22961
23036
  const sessionId = String(historySessionId || "").trim();
22962
23037
  if (!sessionId) return;
22963
23038
  try {
22964
- const dir = path14.join(HISTORY_DIR, this.sanitize(agentType));
23039
+ const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
22965
23040
  if (!fs6.existsSync(dir)) return;
22966
23041
  const prefix = `${this.sanitize(sessionId)}_`;
22967
23042
  const files = fs6.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
22968
23043
  const seen = /* @__PURE__ */ new Set();
22969
23044
  for (const file of files) {
22970
- const filePath = path14.join(dir, file);
23045
+ const filePath = path15.join(dir, file);
22971
23046
  const lines = fs6.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
22972
23047
  const next = [];
22973
23048
  for (const line of lines) {
@@ -23021,11 +23096,11 @@ var ChatHistoryWriter = class {
23021
23096
  const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
23022
23097
  const agentDirs = fs6.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
23023
23098
  for (const dir of agentDirs) {
23024
- const dirPath = path14.join(HISTORY_DIR, dir.name);
23099
+ const dirPath = path15.join(HISTORY_DIR, dir.name);
23025
23100
  const files = fs6.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
23026
23101
  let removedAny = false;
23027
23102
  for (const file of files) {
23028
- const filePath = path14.join(dirPath, file);
23103
+ const filePath = path15.join(dirPath, file);
23029
23104
  const stat2 = fs6.statSync(filePath);
23030
23105
  if (stat2.mtimeMs < cutoff) {
23031
23106
  fs6.unlinkSync(filePath);
@@ -23228,7 +23303,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
23228
23303
  const seen = /* @__PURE__ */ new Set();
23229
23304
  let readAllFiles = true;
23230
23305
  for (let f = 0; f < files.length; f++) {
23231
- const filePath = path14.join(dir, files[f]);
23306
+ const filePath = path15.join(dir, files[f]);
23232
23307
  const remaining = Math.max(0, needed - collected.length);
23233
23308
  const perFileNeeded = Math.min(needed, remaining + BOUNDED_TAIL_SLACK);
23234
23309
  const { lines, coversWholeFile } = readFileTailLines(filePath, perFileNeeded);
@@ -23261,7 +23336,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
23261
23336
  function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
23262
23337
  try {
23263
23338
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
23264
- const dir = path14.join(HISTORY_DIR, sanitized);
23339
+ const dir = path15.join(HISTORY_DIR, sanitized);
23265
23340
  if (!fs6.existsSync(dir)) return { messages: [], hasMore: false };
23266
23341
  const files = listHistoryFiles(dir, historySessionId);
23267
23342
  const bounded = isBoundedTailRequest(limit, offset, excludeRecentCount);
@@ -23284,7 +23359,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
23284
23359
  const allMessages = [];
23285
23360
  const seen = /* @__PURE__ */ new Set();
23286
23361
  for (const file of files) {
23287
- const filePath = path14.join(dir, file);
23362
+ const filePath = path15.join(dir, file);
23288
23363
  const content = fs6.readFileSync(filePath, "utf-8");
23289
23364
  const lines = content.trim().split("\n").filter(Boolean);
23290
23365
  for (let i = 0; i < lines.length; i++) {
@@ -23308,7 +23383,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
23308
23383
  function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
23309
23384
  try {
23310
23385
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
23311
- const dir = path14.join(HISTORY_DIR, sanitized);
23386
+ const dir = path15.join(HISTORY_DIR, sanitized);
23312
23387
  if (!fs6.existsSync(dir)) {
23313
23388
  savedHistorySessionCache.delete(sanitized);
23314
23389
  return { sessions: [], hasMore: false };
@@ -23369,11 +23444,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
23369
23444
  }
23370
23445
  function readExistingSessionStartRecord(agentType, historySessionId) {
23371
23446
  try {
23372
- const dir = path14.join(HISTORY_DIR, agentType);
23447
+ const dir = path15.join(HISTORY_DIR, agentType);
23373
23448
  if (!fs6.existsSync(dir)) return null;
23374
23449
  const files = listHistoryFiles(dir, historySessionId).sort();
23375
23450
  for (const file of files) {
23376
- const lines = fs6.readFileSync(path14.join(dir, file), "utf-8").split("\n").filter(Boolean);
23451
+ const lines = fs6.readFileSync(path15.join(dir, file), "utf-8").split("\n").filter(Boolean);
23377
23452
  for (const line of lines) {
23378
23453
  try {
23379
23454
  const parsed = JSON.parse(line);
@@ -23393,16 +23468,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
23393
23468
  function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
23394
23469
  if (records.length === 0) return false;
23395
23470
  try {
23396
- const dir = path14.join(HISTORY_DIR, agentType);
23471
+ const dir = path15.join(HISTORY_DIR, agentType);
23397
23472
  fs6.mkdirSync(dir, { recursive: true });
23398
23473
  const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
23399
23474
  for (const file of fs6.readdirSync(dir)) {
23400
23475
  if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
23401
- fs6.unlinkSync(path14.join(dir, file));
23476
+ fs6.unlinkSync(path15.join(dir, file));
23402
23477
  }
23403
23478
  }
23404
23479
  const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
23405
- const filePath = path14.join(dir, `${prefix}${targetDate}.jsonl`);
23480
+ const filePath = path15.join(dir, `${prefix}${targetDate}.jsonl`);
23406
23481
  fs6.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
23407
23482
  `, "utf-8");
23408
23483
  invalidatePersistedSavedHistoryIndex(agentType, dir);
@@ -26008,7 +26083,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
26008
26083
  init_contracts();
26009
26084
  import * as fs7 from "fs";
26010
26085
  import * as os9 from "os";
26011
- import * as path15 from "path";
26086
+ import * as path16 from "path";
26012
26087
  import { randomUUID as randomUUID11 } from "crypto";
26013
26088
  init_logger();
26014
26089
 
@@ -27058,7 +27133,7 @@ function readExactRuntimeMirrorMessages(args) {
27058
27133
  function normalizeComparableWorkspace(value) {
27059
27134
  const text = typeof value === "string" ? value.trim() : "";
27060
27135
  if (!text) return "";
27061
- return path15.resolve(text);
27136
+ return path16.resolve(text);
27062
27137
  }
27063
27138
  function isCurrentRuntimePtySafelyAttributed(args) {
27064
27139
  if (args.adapter.cliType !== "codex-cli") return false;
@@ -27543,7 +27618,7 @@ function buildDebugBundleText(bundle) {
27543
27618
  }
27544
27619
  function getChatDebugBundleDir() {
27545
27620
  const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
27546
- return override || path15.join(os9.homedir(), ".adhdev", "debug-bundles", "chat");
27621
+ return override || path16.join(os9.homedir(), ".adhdev", "debug-bundles", "chat");
27547
27622
  }
27548
27623
  function safeBundleIdSegment(value, fallback) {
27549
27624
  const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
@@ -27600,7 +27675,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
27600
27675
  const bundleId = createChatDebugBundleId(targetSessionId);
27601
27676
  const dir = getChatDebugBundleDir();
27602
27677
  fs7.mkdirSync(dir, { recursive: true });
27603
- const savedPath = path15.join(dir, `${bundleId}.json`);
27678
+ const savedPath = path16.join(dir, `${bundleId}.json`);
27604
27679
  const json = `${JSON.stringify(bundle, null, 2)}
27605
27680
  `;
27606
27681
  fs7.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
@@ -29164,7 +29239,7 @@ async function handleResolveAction(h, args) {
29164
29239
 
29165
29240
  // src/commands/cdp-commands.ts
29166
29241
  import * as fs8 from "fs";
29167
- import * as path16 from "path";
29242
+ import * as path17 from "path";
29168
29243
  import * as os10 from "os";
29169
29244
  var KEY_TO_VK = {
29170
29245
  Backspace: 8,
@@ -29421,25 +29496,25 @@ function resolveSafePath(requestedPath) {
29421
29496
  const inputPath = rawPath || ".";
29422
29497
  const home = os10.homedir();
29423
29498
  if (inputPath.startsWith("~")) {
29424
- return path16.resolve(path16.join(home, inputPath.slice(1)));
29499
+ return path17.resolve(path17.join(home, inputPath.slice(1)));
29425
29500
  }
29426
29501
  if (process.platform === "win32") {
29427
29502
  const normalized = normalizeWindowsRequestedPath(inputPath);
29428
- if (path16.win32.isAbsolute(normalized)) {
29429
- return path16.win32.normalize(normalized);
29503
+ if (path17.win32.isAbsolute(normalized)) {
29504
+ return path17.win32.normalize(normalized);
29430
29505
  }
29431
- return path16.win32.resolve(normalized);
29506
+ return path17.win32.resolve(normalized);
29432
29507
  }
29433
- if (path16.isAbsolute(inputPath)) {
29434
- return path16.normalize(inputPath);
29508
+ if (path17.isAbsolute(inputPath)) {
29509
+ return path17.normalize(inputPath);
29435
29510
  }
29436
- return path16.resolve(inputPath);
29511
+ return path17.resolve(inputPath);
29437
29512
  }
29438
29513
  function listDirectoryEntriesSafe(dirPath) {
29439
29514
  const entries = fs8.readdirSync(dirPath, { withFileTypes: true });
29440
29515
  const files = [];
29441
29516
  for (const entry of entries) {
29442
- const entryPath = path16.join(dirPath, entry.name);
29517
+ const entryPath = path17.join(dirPath, entry.name);
29443
29518
  try {
29444
29519
  if (entry.isDirectory()) {
29445
29520
  files.push({ name: entry.name, type: "directory" });
@@ -29493,7 +29568,7 @@ async function handleFileRead(h, args) {
29493
29568
  async function handleFileWrite(h, args) {
29494
29569
  try {
29495
29570
  const filePath = resolveSafePath(args?.path);
29496
- fs8.mkdirSync(path16.dirname(filePath), { recursive: true });
29571
+ fs8.mkdirSync(path17.dirname(filePath), { recursive: true });
29497
29572
  fs8.writeFileSync(filePath, args?.content || "", "utf-8");
29498
29573
  return { success: true, path: filePath };
29499
29574
  } catch (e) {
@@ -43306,6 +43381,7 @@ import { homedir as homedir26, hostname as osHostname } from "os";
43306
43381
  import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
43307
43382
  import * as fs26 from "fs";
43308
43383
  import { execFileSync as execFileSync6 } from "child_process";
43384
+ init_resolve_executable();
43309
43385
  var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
43310
43386
  var CHANNEL_SERVER_URL = {
43311
43387
  stable: "https://api.adhf.dev",
@@ -44404,6 +44480,18 @@ function truncateValidationOutput(value) {
44404
44480
  return `${text.slice(0, REFINE_VALIDATION_SUMMARY_CHARS)}
44405
44481
  [truncated ${text.length - REFINE_VALIDATION_SUMMARY_CHARS} chars]`;
44406
44482
  }
44483
+ function isSpawnResolutionError(error) {
44484
+ if (!error) return false;
44485
+ if (error.code === "ENOENT" && typeof error.syscall === "string" && error.syscall.startsWith("spawn")) return true;
44486
+ return error.code === "ENOENT" && (error.syscall === void 0 || String(error.syscall).startsWith("spawn"));
44487
+ }
44488
+ function describeSpawnError(error, command, spawnResolutionFailed) {
44489
+ if (spawnResolutionFailed) {
44490
+ 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." : "";
44491
+ return `Could not resolve executable "${command}" (spawn ENOENT).${hint}`;
44492
+ }
44493
+ return String(error?.message || error);
44494
+ }
44407
44495
  function recordMeshRefineStage(stages, stage, status, startedAt, details) {
44408
44496
  stages.push({
44409
44497
  stage,
@@ -45305,8 +45393,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
45305
45393
  const startedAt = Date.now();
45306
45394
  const cwd = candidate.cwd ? pathResolve2(workspace, candidate.cwd) : workspace;
45307
45395
  const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
45396
+ const resolvedCommand = resolveWin32Executable(candidate.command);
45308
45397
  try {
45309
- const result = await execFileAsync4(candidate.command, candidate.args, {
45398
+ const result = await execFileAsync4(resolvedCommand, candidate.args, {
45310
45399
  cwd,
45311
45400
  encoding: "utf8",
45312
45401
  timeout,
@@ -45315,16 +45404,17 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
45315
45404
  });
45316
45405
  summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
45317
45406
  } catch (error) {
45407
+ const spawnResolutionFailed = isSpawnResolutionError(error);
45318
45408
  summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
45319
45409
  exitCode: typeof error?.code === "number" ? error.code : null,
45320
45410
  signal: typeof error?.signal === "string" ? error.signal : null,
45321
45411
  timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
45322
- failureKind: "dependency_bootstrap_failed"
45412
+ ...spawnResolutionFailed ? { failureKind: "spawn_resolution_failed", resolvedCommand } : { failureKind: "dependency_bootstrap_failed" }
45323
45413
  }));
45324
- summary.bootstrap = { stage: "failed", error: String(error?.message || error) };
45414
+ summary.bootstrap = { stage: "failed", error: describeSpawnError(error, candidate.command, spawnResolutionFailed) };
45325
45415
  summary.status = "failed";
45326
- summary.failureKind = "dependency_bootstrap_failed";
45327
- summary.failureCode = "dependency_bootstrap_failed";
45416
+ summary.failureKind = spawnResolutionFailed ? "spawn_resolution_failed" : "dependency_bootstrap_failed";
45417
+ summary.failureCode = spawnResolutionFailed ? "spawn_resolution_failed" : "dependency_bootstrap_failed";
45328
45418
  return summary;
45329
45419
  }
45330
45420
  }
@@ -45347,8 +45437,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
45347
45437
  summary.failureCode = "missing_dependencies";
45348
45438
  return summary;
45349
45439
  }
45440
+ const resolvedCommand = resolveWin32Executable(candidate.command);
45350
45441
  try {
45351
- const result = await execFileAsync4(candidate.command, candidate.args, {
45442
+ const result = await execFileAsync4(resolvedCommand, candidate.args, {
45352
45443
  cwd,
45353
45444
  encoding: "utf8",
45354
45445
  timeout,
@@ -45357,16 +45448,21 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
45357
45448
  });
45358
45449
  summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
45359
45450
  } catch (error) {
45451
+ const spawnResolutionFailed = isSpawnResolutionError(error);
45360
45452
  const stderr = truncateValidationOutput(error?.stderr || error?.message);
45361
- const missingDependencyFailure = /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
45453
+ const missingDependencyFailure = !spawnResolutionFailed && /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
45362
45454
  summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
45363
45455
  exitCode: typeof error?.code === "number" ? error.code : null,
45364
45456
  signal: typeof error?.signal === "string" ? error.signal : null,
45365
45457
  timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
45366
- ...missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
45458
+ ...spawnResolutionFailed ? { failureKind: "spawn_resolution_failed", resolvedCommand } : missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
45367
45459
  }));
45368
45460
  summary.status = "failed";
45369
- if (missingDependencyFailure) {
45461
+ if (spawnResolutionFailed) {
45462
+ summary.failureKind = "spawn_resolution_failed";
45463
+ summary.failureCode = "spawn_resolution_failed";
45464
+ summary.spawnResolutionError = describeSpawnError(error, candidate.command, true);
45465
+ } else if (missingDependencyFailure) {
45370
45466
  summary.failureKind = "missing_dependencies";
45371
45467
  summary.failureCode = "missing_dependencies";
45372
45468
  }
@@ -46627,7 +46723,7 @@ var DaemonCommandRouter = class {
46627
46723
  if (validationSummary.status === "failed") {
46628
46724
  const firstFailedCmd = Array.isArray(validationSummary.commandsRun) ? validationSummary.commandsRun.find((c) => c.success === false) : void 0;
46629
46725
  const buildValidationFailedError = () => {
46630
- 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.";
46726
+ 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.";
46631
46727
  if (!firstFailedCmd) return base;
46632
46728
  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 : "";
46633
46729
  const rawOutput = [firstFailedCmd.stdout, firstFailedCmd.stderr, firstFailedCmd.output].filter((s) => typeof s === "string" && s.length > 0).join("\n");