@adhdev/daemon-standalone 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.js CHANGED
@@ -30036,10 +30036,10 @@ var require_dist3 = __commonJS({
30036
30036
  }
30037
30037
  function getDaemonBuildInfo() {
30038
30038
  if (cached2) return cached2;
30039
- const commit = readInjected(true ? "5d9635b2a6476691469ecfe32b26a17e13484b2b" : void 0) ?? "unknown";
30040
- const commitShort = readInjected(true ? "5d9635b2" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30041
- const version2 = readInjected(true ? "0.9.82-rc.333" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30042
- const builtAt = readInjected(true ? "2026-06-20T02:24:25.156Z" : void 0);
30039
+ const commit = readInjected(true ? "e9e62c9770c0f4a419a90f5287125f3d3bb0fd95" : void 0) ?? "unknown";
30040
+ const commitShort = readInjected(true ? "e9e62c97" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30041
+ const version2 = readInjected(true ? "0.9.82-rc.335" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30042
+ const builtAt = readInjected(true ? "2026-06-20T04:31:22.998Z" : void 0);
30043
30043
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
30044
30044
  return cached2;
30045
30045
  }
@@ -33012,6 +33012,314 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
33012
33012
  ledgerImportDone = /* @__PURE__ */ new Set();
33013
33013
  }
33014
33014
  });
33015
+ var fs32;
33016
+ var AsyncBatchWriter;
33017
+ var init_async_batch_writer = __esm2({
33018
+ "src/logging/async-batch-writer.ts"() {
33019
+ "use strict";
33020
+ fs32 = __toESM2(require("fs"));
33021
+ AsyncBatchWriter = class {
33022
+ // Maps filePath -> string buffer
33023
+ static buffers = /* @__PURE__ */ new Map();
33024
+ static writePromises = /* @__PURE__ */ new Map();
33025
+ static flushTimer = null;
33026
+ /**
33027
+ * Queues data to be written to a file asynchronously in a batch.
33028
+ */
33029
+ static write(filePath, data) {
33030
+ let buf = this.buffers.get(filePath);
33031
+ if (!buf) {
33032
+ buf = [];
33033
+ this.buffers.set(filePath, buf);
33034
+ }
33035
+ buf.push(data);
33036
+ if (!this.flushTimer) {
33037
+ this.flushTimer = setTimeout(() => {
33038
+ this.flushTimer = null;
33039
+ this.flushAll();
33040
+ }, 50);
33041
+ }
33042
+ }
33043
+ static async flushAll() {
33044
+ const entries = Array.from(this.buffers.entries());
33045
+ this.buffers.clear();
33046
+ for (const [filePath, buffer] of entries) {
33047
+ const dataToWrite = buffer.join("");
33048
+ const doWrite = async () => {
33049
+ try {
33050
+ const prevPromise = this.writePromises.get(filePath);
33051
+ if (prevPromise) await prevPromise;
33052
+ await fs32.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
33053
+ } catch {
33054
+ }
33055
+ };
33056
+ const writePromise = doWrite();
33057
+ this.writePromises.set(filePath, writePromise);
33058
+ writePromise.finally(() => {
33059
+ if (this.writePromises.get(filePath) === writePromise) {
33060
+ this.writePromises.delete(filePath);
33061
+ }
33062
+ });
33063
+ }
33064
+ }
33065
+ };
33066
+ }
33067
+ });
33068
+ var logger_exports = {};
33069
+ __export2(logger_exports, {
33070
+ LOG: () => LOG2,
33071
+ LOG_DIR_PATH: () => LOG_DIR_PATH,
33072
+ LOG_PATH: () => LOG_PATH,
33073
+ daemonLog: () => daemonLog,
33074
+ getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
33075
+ getDaemonLogDir: () => getDaemonLogDir,
33076
+ getLogBufferSize: () => getLogBufferSize,
33077
+ getLogLevel: () => getLogLevel,
33078
+ getLogPath: () => getLogPath,
33079
+ getRecentLogs: () => getRecentLogs,
33080
+ installGlobalInterceptor: () => installGlobalInterceptor,
33081
+ setLogLevel: () => setLogLevel
33082
+ });
33083
+ function setLogLevel(level) {
33084
+ currentLevel = level;
33085
+ daemonLog("Logger", `Log level set to: ${level}`, "info");
33086
+ }
33087
+ function getLogLevel() {
33088
+ return currentLevel;
33089
+ }
33090
+ function getDateStr() {
33091
+ return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
33092
+ }
33093
+ function getDaemonLogDir() {
33094
+ return LOG_DIR;
33095
+ }
33096
+ function getCurrentDaemonLogPath(date5 = /* @__PURE__ */ new Date()) {
33097
+ return path9.join(LOG_DIR, `daemon-${date5.toISOString().slice(0, 10)}.log`);
33098
+ }
33099
+ function checkDateRotation() {
33100
+ const today = getDateStr();
33101
+ if (today !== currentDate) {
33102
+ currentDate = today;
33103
+ currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
33104
+ cleanOldLogs();
33105
+ }
33106
+ }
33107
+ function cleanOldLogs() {
33108
+ try {
33109
+ const files = fs4.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
33110
+ const cutoff = /* @__PURE__ */ new Date();
33111
+ cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
33112
+ const cutoffStr = cutoff.toISOString().slice(0, 10);
33113
+ for (const file2 of files) {
33114
+ const dateMatch = file2.match(/daemon-(\d{4}-\d{2}-\d{2})/);
33115
+ if (dateMatch && dateMatch[1] < cutoffStr) {
33116
+ try {
33117
+ fs4.unlinkSync(path9.join(LOG_DIR, file2));
33118
+ } catch {
33119
+ }
33120
+ }
33121
+ }
33122
+ } catch {
33123
+ }
33124
+ }
33125
+ function rotateSizeIfNeeded() {
33126
+ try {
33127
+ const stat2 = fs4.statSync(currentLogFile);
33128
+ if (stat2.size > MAX_LOG_SIZE) {
33129
+ const backup = currentLogFile.replace(".log", ".1.log");
33130
+ try {
33131
+ fs4.unlinkSync(backup);
33132
+ } catch {
33133
+ }
33134
+ fs4.renameSync(currentLogFile, backup);
33135
+ }
33136
+ } catch {
33137
+ }
33138
+ }
33139
+ function writeToFile(line) {
33140
+ try {
33141
+ if (++writeCount % 1e3 === 0) {
33142
+ checkDateRotation();
33143
+ rotateSizeIfNeeded();
33144
+ }
33145
+ AsyncBatchWriter.write(currentLogFile, line + "\n");
33146
+ } catch {
33147
+ }
33148
+ }
33149
+ function getRecentLogs(count = 50, minLevel = "info") {
33150
+ const minNum = LEVEL_NUM[minLevel];
33151
+ const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
33152
+ return filtered.slice(-count);
33153
+ }
33154
+ function getLogBufferSize() {
33155
+ return ringBuffer.length;
33156
+ }
33157
+ function ts() {
33158
+ return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
33159
+ }
33160
+ function fullTs() {
33161
+ return (/* @__PURE__ */ new Date()).toISOString();
33162
+ }
33163
+ function daemonLog(category, msg, level = "info") {
33164
+ const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
33165
+ const label = LEVEL_LABEL[level];
33166
+ const line = `[${ts()}] [${label}] [${category}] ${msg}`;
33167
+ if (!shouldOutput) return;
33168
+ writeToFile(line);
33169
+ ringBuffer.push({ ts: Date.now(), level, category, message: msg });
33170
+ if (ringBuffer.length > RING_BUFFER_SIZE) {
33171
+ ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
33172
+ }
33173
+ origConsoleLog(line);
33174
+ }
33175
+ function installGlobalInterceptor() {
33176
+ if (interceptorInstalled) return;
33177
+ interceptorInstalled = true;
33178
+ const stripAnsi4 = (str) => str.replace(/\x1B\[[0-9;]*m/g, "");
33179
+ const isDaemonLogLine = (msg) => /\[(DBG|INF|WRN|ERR)\]/.test(msg);
33180
+ console.log = (...args) => {
33181
+ origConsoleLog(...args);
33182
+ try {
33183
+ const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
33184
+ const clean = stripAnsi4(msg);
33185
+ if (isDaemonLogLine(clean)) return;
33186
+ const line = clean.startsWith("[20") ? clean : `[${fullTs()}] ${clean}`;
33187
+ writeToFile(line);
33188
+ const catMatch = clean.match(/\[([^\]]+)\]/);
33189
+ ringBuffer.push({
33190
+ ts: Date.now(),
33191
+ level: "info",
33192
+ category: catMatch?.[1] || "System",
33193
+ message: clean
33194
+ });
33195
+ if (ringBuffer.length > RING_BUFFER_SIZE) {
33196
+ ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
33197
+ }
33198
+ } catch {
33199
+ }
33200
+ };
33201
+ console.error = (...args) => {
33202
+ origConsoleError(...args);
33203
+ try {
33204
+ const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
33205
+ const clean = stripAnsi4(msg);
33206
+ if (isDaemonLogLine(clean)) return;
33207
+ const line = `[${fullTs()}] [ERROR] ${clean}`;
33208
+ writeToFile(line);
33209
+ ringBuffer.push({ ts: Date.now(), level: "error", category: "System", message: clean });
33210
+ if (ringBuffer.length > RING_BUFFER_SIZE) {
33211
+ ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
33212
+ }
33213
+ } catch {
33214
+ }
33215
+ };
33216
+ console.warn = (...args) => {
33217
+ origConsoleWarn(...args);
33218
+ try {
33219
+ const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
33220
+ const clean = stripAnsi4(msg);
33221
+ if (isDaemonLogLine(clean)) return;
33222
+ const line = `[${fullTs()}] [WARN] ${clean}`;
33223
+ writeToFile(line);
33224
+ ringBuffer.push({ ts: Date.now(), level: "warn", category: "System", message: clean });
33225
+ if (ringBuffer.length > RING_BUFFER_SIZE) {
33226
+ ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
33227
+ }
33228
+ } catch {
33229
+ }
33230
+ };
33231
+ writeToFile(`
33232
+ === ADHDev Daemon started at ${fullTs()} ===`);
33233
+ writeToFile(`Log file: ${currentLogFile}`);
33234
+ writeToFile(`Log level: ${currentLevel}`);
33235
+ }
33236
+ function getLogPath() {
33237
+ return currentLogFile;
33238
+ }
33239
+ var fs4;
33240
+ var path9;
33241
+ var os32;
33242
+ var LEVEL_NUM;
33243
+ var LEVEL_LABEL;
33244
+ var currentLevel;
33245
+ var LOG_DIR;
33246
+ var MAX_LOG_SIZE;
33247
+ var MAX_LOG_DAYS;
33248
+ var currentDate;
33249
+ var currentLogFile;
33250
+ var writeCount;
33251
+ var RING_BUFFER_SIZE;
33252
+ var ringBuffer;
33253
+ var origConsoleLog;
33254
+ var origConsoleError;
33255
+ var origConsoleWarn;
33256
+ var LOG2;
33257
+ var interceptorInstalled;
33258
+ var LOG_PATH;
33259
+ var LOG_DIR_PATH;
33260
+ var init_logger = __esm2({
33261
+ "src/logging/logger.ts"() {
33262
+ "use strict";
33263
+ fs4 = __toESM2(require("fs"));
33264
+ path9 = __toESM2(require("path"));
33265
+ os32 = __toESM2(require("os"));
33266
+ init_async_batch_writer();
33267
+ LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
33268
+ LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
33269
+ currentLevel = "info";
33270
+ LOG_DIR = process.platform === "win32" ? path9.join(process.env.LOCALAPPDATA || process.env.APPDATA || path9.join(os32.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path9.join(os32.homedir(), "Library", "Logs", "adhdev") : path9.join(os32.homedir(), ".local", "share", "adhdev", "logs");
33271
+ MAX_LOG_SIZE = 5 * 1024 * 1024;
33272
+ MAX_LOG_DAYS = 7;
33273
+ try {
33274
+ fs4.mkdirSync(LOG_DIR, { recursive: true });
33275
+ } catch {
33276
+ }
33277
+ currentDate = getDateStr();
33278
+ currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
33279
+ cleanOldLogs();
33280
+ try {
33281
+ const oldLog = path9.join(LOG_DIR, "daemon.log");
33282
+ if (fs4.existsSync(oldLog)) {
33283
+ const stat2 = fs4.statSync(oldLog);
33284
+ const oldDate = stat2.mtime.toISOString().slice(0, 10);
33285
+ fs4.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
33286
+ }
33287
+ const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
33288
+ if (fs4.existsSync(oldLogBackup)) {
33289
+ fs4.unlinkSync(oldLogBackup);
33290
+ }
33291
+ } catch {
33292
+ }
33293
+ writeCount = 0;
33294
+ RING_BUFFER_SIZE = 200;
33295
+ ringBuffer = [];
33296
+ origConsoleLog = console.log.bind(console);
33297
+ origConsoleError = console.error.bind(console);
33298
+ origConsoleWarn = console.warn.bind(console);
33299
+ LOG2 = {
33300
+ debug: (category, msg) => daemonLog(category, msg, "debug"),
33301
+ info: (category, msg) => daemonLog(category, msg, "info"),
33302
+ warn: (category, msg) => daemonLog(category, msg, "warn"),
33303
+ error: (category, msg) => daemonLog(category, msg, "error"),
33304
+ /**
33305
+ * Create a scoped logger for a specific component.
33306
+ * Category is baked in so callers only pass the message.
33307
+ */
33308
+ forComponent(category) {
33309
+ return {
33310
+ debug: (msg) => daemonLog(category, msg, "debug"),
33311
+ info: (msg) => daemonLog(category, msg, "info"),
33312
+ warn: (msg) => daemonLog(category, msg, "warn"),
33313
+ error: (msg) => daemonLog(category, msg, "error"),
33314
+ asLogFn: (level = "info") => (msg) => daemonLog(category, msg, level)
33315
+ };
33316
+ }
33317
+ };
33318
+ interceptorInstalled = false;
33319
+ LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
33320
+ LOG_DIR_PATH = LOG_DIR;
33321
+ }
33322
+ });
33015
33323
  var mesh_work_queue_exports = {};
33016
33324
  __export2(mesh_work_queue_exports, {
33017
33325
  ACTIVE_MESH_QUEUE_STATUSES: () => ACTIVE_MESH_QUEUE_STATUSES,
@@ -33475,11 +33783,18 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
33475
33783
  }
33476
33784
  function updateSessionTaskStatus(meshId, sessionId, status, opts) {
33477
33785
  return withQueueLock(meshId, () => {
33786
+ const store = MeshRuntimeStore.getInstance();
33478
33787
  const occurredAtIso = opts?.occurredAt ? new Date(opts.occurredAt).toISOString() : void 0;
33479
- const entry = MeshRuntimeStore.getInstance().findAssignedBySession(meshId, sessionId, occurredAtIso);
33480
- if (!entry) return null;
33788
+ const entry = store.findAssignedBySession(meshId, sessionId, occurredAtIso, opts?.taskId);
33789
+ if (!entry) {
33790
+ const assignedRows = store.getActiveAssignmentDetails(meshId).filter((r) => r.sessionId === sessionId);
33791
+ if (assignedRows.length > 0) {
33792
+ LOG2.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(",")}`);
33793
+ }
33794
+ return null;
33795
+ }
33481
33796
  entry.status = status;
33482
- MeshRuntimeStore.getInstance().updateQueueEntry(entry);
33797
+ store.updateQueueEntry(entry);
33483
33798
  if (DEPENDENCY_FAILURE_TERMINALS.has(status)) propagateDependencyFailure(meshId, entry.id);
33484
33799
  return entry;
33485
33800
  });
@@ -33597,6 +33912,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
33597
33912
  init_repo_mesh_types();
33598
33913
  init_mesh_runtime_store();
33599
33914
  init_mesh_config();
33915
+ init_logger();
33600
33916
  ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
33601
33917
  HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
33602
33918
  MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
@@ -34256,12 +34572,51 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34256
34572
  return { id, nodeId: r.assigned_node_id ?? void 0, sessionId: r.assigned_session_id ?? void 0, message };
34257
34573
  });
34258
34574
  }
34259
- findAssignedBySession(meshId, sessionId, occurredAtIso) {
34575
+ /**
34576
+ * Resolve the `assigned` queue row a completion event belongs to.
34577
+ *
34578
+ * Clock-skew safety (C2): a completion event's `occurredAtIso` carries the
34579
+ * REMOTE WORKER's clock, while `updated_at` carries the COORDINATOR's clock
34580
+ * (set at assignment and re-bumped on every mutation). For a remote node,
34581
+ * coordinator-clock > worker-clock skew used to make an `updated_at <= occurredAt`
34582
+ * filter return nothing, stranding the finished task as `assigned` forever.
34583
+ *
34584
+ * We therefore NEVER filter completion-matching on the mutable `updated_at`:
34585
+ * 1. If `taskId` is given, match the exact `assigned` row by id (no time filter).
34586
+ * 2. Otherwise a session holds at most one `assigned` task — match it without a
34587
+ * time filter. If several exist (shouldn't normally), disambiguate by the
34588
+ * IMMUTABLE `dispatchTimestamp`: latest `dispatchTimestamp <= occurredAt`,
34589
+ * and if skew makes ALL of them later than `occurredAt`, fall back to the
34590
+ * most-recent `dispatchTimestamp` rather than returning null.
34591
+ */
34592
+ findAssignedBySession(meshId, sessionId, occurredAtIso, taskId) {
34260
34593
  this.ensureLegacyQueueMigrated(meshId);
34261
- 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`;
34262
- const args = occurredAtIso ? [meshId, sessionId, occurredAtIso] : [meshId, sessionId];
34263
- const row = this.db.prepare(sql).get(...args);
34264
- return row ? JSON.parse(row.payload) : null;
34594
+ if (taskId) {
34595
+ const row = this.db.prepare(
34596
+ `SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned' AND id = ? LIMIT 1`
34597
+ ).get(meshId, sessionId, taskId);
34598
+ if (row) return JSON.parse(row.payload);
34599
+ }
34600
+ const rows = this.db.prepare(
34601
+ `SELECT payload FROM mesh_queue WHERE mesh_id = ? AND assigned_session_id = ? AND status = 'assigned'`
34602
+ ).all(meshId, sessionId);
34603
+ if (rows.length === 0) return null;
34604
+ const entries = rows.map((r) => {
34605
+ try {
34606
+ return JSON.parse(r.payload);
34607
+ } catch {
34608
+ return null;
34609
+ }
34610
+ }).filter((e) => e !== null);
34611
+ if (entries.length === 0) return null;
34612
+ if (entries.length === 1) return entries[0];
34613
+ const orderKey = (e) => e.dispatchTimestamp ?? e.updatedAt ?? "";
34614
+ const byDispatchDesc = [...entries].sort((a, b) => orderKey(b).localeCompare(orderKey(a)));
34615
+ if (occurredAtIso) {
34616
+ const atOrBefore = byDispatchDesc.find((e) => orderKey(e) <= occurredAtIso);
34617
+ if (atOrBefore) return atOrBefore;
34618
+ }
34619
+ return byDispatchDesc[0];
34265
34620
  }
34266
34621
  toRow(entry) {
34267
34622
  return {
@@ -35512,314 +35867,6 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
35512
35867
  MAX_CHANGED_FILES = 100;
35513
35868
  }
35514
35869
  });
35515
- var fs32;
35516
- var AsyncBatchWriter;
35517
- var init_async_batch_writer = __esm2({
35518
- "src/logging/async-batch-writer.ts"() {
35519
- "use strict";
35520
- fs32 = __toESM2(require("fs"));
35521
- AsyncBatchWriter = class {
35522
- // Maps filePath -> string buffer
35523
- static buffers = /* @__PURE__ */ new Map();
35524
- static writePromises = /* @__PURE__ */ new Map();
35525
- static flushTimer = null;
35526
- /**
35527
- * Queues data to be written to a file asynchronously in a batch.
35528
- */
35529
- static write(filePath, data) {
35530
- let buf = this.buffers.get(filePath);
35531
- if (!buf) {
35532
- buf = [];
35533
- this.buffers.set(filePath, buf);
35534
- }
35535
- buf.push(data);
35536
- if (!this.flushTimer) {
35537
- this.flushTimer = setTimeout(() => {
35538
- this.flushTimer = null;
35539
- this.flushAll();
35540
- }, 50);
35541
- }
35542
- }
35543
- static async flushAll() {
35544
- const entries = Array.from(this.buffers.entries());
35545
- this.buffers.clear();
35546
- for (const [filePath, buffer] of entries) {
35547
- const dataToWrite = buffer.join("");
35548
- const doWrite = async () => {
35549
- try {
35550
- const prevPromise = this.writePromises.get(filePath);
35551
- if (prevPromise) await prevPromise;
35552
- await fs32.promises.appendFile(filePath, dataToWrite, { encoding: "utf-8", mode: 384 });
35553
- } catch {
35554
- }
35555
- };
35556
- const writePromise = doWrite();
35557
- this.writePromises.set(filePath, writePromise);
35558
- writePromise.finally(() => {
35559
- if (this.writePromises.get(filePath) === writePromise) {
35560
- this.writePromises.delete(filePath);
35561
- }
35562
- });
35563
- }
35564
- }
35565
- };
35566
- }
35567
- });
35568
- var logger_exports = {};
35569
- __export2(logger_exports, {
35570
- LOG: () => LOG2,
35571
- LOG_DIR_PATH: () => LOG_DIR_PATH,
35572
- LOG_PATH: () => LOG_PATH,
35573
- daemonLog: () => daemonLog,
35574
- getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
35575
- getDaemonLogDir: () => getDaemonLogDir,
35576
- getLogBufferSize: () => getLogBufferSize,
35577
- getLogLevel: () => getLogLevel,
35578
- getLogPath: () => getLogPath,
35579
- getRecentLogs: () => getRecentLogs,
35580
- installGlobalInterceptor: () => installGlobalInterceptor,
35581
- setLogLevel: () => setLogLevel
35582
- });
35583
- function setLogLevel(level) {
35584
- currentLevel = level;
35585
- daemonLog("Logger", `Log level set to: ${level}`, "info");
35586
- }
35587
- function getLogLevel() {
35588
- return currentLevel;
35589
- }
35590
- function getDateStr() {
35591
- return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
35592
- }
35593
- function getDaemonLogDir() {
35594
- return LOG_DIR;
35595
- }
35596
- function getCurrentDaemonLogPath(date5 = /* @__PURE__ */ new Date()) {
35597
- return path9.join(LOG_DIR, `daemon-${date5.toISOString().slice(0, 10)}.log`);
35598
- }
35599
- function checkDateRotation() {
35600
- const today = getDateStr();
35601
- if (today !== currentDate) {
35602
- currentDate = today;
35603
- currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
35604
- cleanOldLogs();
35605
- }
35606
- }
35607
- function cleanOldLogs() {
35608
- try {
35609
- const files = fs4.readdirSync(LOG_DIR).filter((f) => f.startsWith("daemon-") && f.endsWith(".log"));
35610
- const cutoff = /* @__PURE__ */ new Date();
35611
- cutoff.setDate(cutoff.getDate() - MAX_LOG_DAYS);
35612
- const cutoffStr = cutoff.toISOString().slice(0, 10);
35613
- for (const file2 of files) {
35614
- const dateMatch = file2.match(/daemon-(\d{4}-\d{2}-\d{2})/);
35615
- if (dateMatch && dateMatch[1] < cutoffStr) {
35616
- try {
35617
- fs4.unlinkSync(path9.join(LOG_DIR, file2));
35618
- } catch {
35619
- }
35620
- }
35621
- }
35622
- } catch {
35623
- }
35624
- }
35625
- function rotateSizeIfNeeded() {
35626
- try {
35627
- const stat2 = fs4.statSync(currentLogFile);
35628
- if (stat2.size > MAX_LOG_SIZE) {
35629
- const backup = currentLogFile.replace(".log", ".1.log");
35630
- try {
35631
- fs4.unlinkSync(backup);
35632
- } catch {
35633
- }
35634
- fs4.renameSync(currentLogFile, backup);
35635
- }
35636
- } catch {
35637
- }
35638
- }
35639
- function writeToFile(line) {
35640
- try {
35641
- if (++writeCount % 1e3 === 0) {
35642
- checkDateRotation();
35643
- rotateSizeIfNeeded();
35644
- }
35645
- AsyncBatchWriter.write(currentLogFile, line + "\n");
35646
- } catch {
35647
- }
35648
- }
35649
- function getRecentLogs(count = 50, minLevel = "info") {
35650
- const minNum = LEVEL_NUM[minLevel];
35651
- const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
35652
- return filtered.slice(-count);
35653
- }
35654
- function getLogBufferSize() {
35655
- return ringBuffer.length;
35656
- }
35657
- function ts() {
35658
- return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
35659
- }
35660
- function fullTs() {
35661
- return (/* @__PURE__ */ new Date()).toISOString();
35662
- }
35663
- function daemonLog(category, msg, level = "info") {
35664
- const shouldOutput = LEVEL_NUM[level] >= LEVEL_NUM[currentLevel];
35665
- const label = LEVEL_LABEL[level];
35666
- const line = `[${ts()}] [${label}] [${category}] ${msg}`;
35667
- if (!shouldOutput) return;
35668
- writeToFile(line);
35669
- ringBuffer.push({ ts: Date.now(), level, category, message: msg });
35670
- if (ringBuffer.length > RING_BUFFER_SIZE) {
35671
- ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
35672
- }
35673
- origConsoleLog(line);
35674
- }
35675
- function installGlobalInterceptor() {
35676
- if (interceptorInstalled) return;
35677
- interceptorInstalled = true;
35678
- const stripAnsi4 = (str) => str.replace(/\x1B\[[0-9;]*m/g, "");
35679
- const isDaemonLogLine = (msg) => /\[(DBG|INF|WRN|ERR)\]/.test(msg);
35680
- console.log = (...args) => {
35681
- origConsoleLog(...args);
35682
- try {
35683
- const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
35684
- const clean = stripAnsi4(msg);
35685
- if (isDaemonLogLine(clean)) return;
35686
- const line = clean.startsWith("[20") ? clean : `[${fullTs()}] ${clean}`;
35687
- writeToFile(line);
35688
- const catMatch = clean.match(/\[([^\]]+)\]/);
35689
- ringBuffer.push({
35690
- ts: Date.now(),
35691
- level: "info",
35692
- category: catMatch?.[1] || "System",
35693
- message: clean
35694
- });
35695
- if (ringBuffer.length > RING_BUFFER_SIZE) {
35696
- ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
35697
- }
35698
- } catch {
35699
- }
35700
- };
35701
- console.error = (...args) => {
35702
- origConsoleError(...args);
35703
- try {
35704
- const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
35705
- const clean = stripAnsi4(msg);
35706
- if (isDaemonLogLine(clean)) return;
35707
- const line = `[${fullTs()}] [ERROR] ${clean}`;
35708
- writeToFile(line);
35709
- ringBuffer.push({ ts: Date.now(), level: "error", category: "System", message: clean });
35710
- if (ringBuffer.length > RING_BUFFER_SIZE) {
35711
- ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
35712
- }
35713
- } catch {
35714
- }
35715
- };
35716
- console.warn = (...args) => {
35717
- origConsoleWarn(...args);
35718
- try {
35719
- const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
35720
- const clean = stripAnsi4(msg);
35721
- if (isDaemonLogLine(clean)) return;
35722
- const line = `[${fullTs()}] [WARN] ${clean}`;
35723
- writeToFile(line);
35724
- ringBuffer.push({ ts: Date.now(), level: "warn", category: "System", message: clean });
35725
- if (ringBuffer.length > RING_BUFFER_SIZE) {
35726
- ringBuffer.splice(0, ringBuffer.length - RING_BUFFER_SIZE);
35727
- }
35728
- } catch {
35729
- }
35730
- };
35731
- writeToFile(`
35732
- === ADHDev Daemon started at ${fullTs()} ===`);
35733
- writeToFile(`Log file: ${currentLogFile}`);
35734
- writeToFile(`Log level: ${currentLevel}`);
35735
- }
35736
- function getLogPath() {
35737
- return currentLogFile;
35738
- }
35739
- var fs4;
35740
- var path9;
35741
- var os32;
35742
- var LEVEL_NUM;
35743
- var LEVEL_LABEL;
35744
- var currentLevel;
35745
- var LOG_DIR;
35746
- var MAX_LOG_SIZE;
35747
- var MAX_LOG_DAYS;
35748
- var currentDate;
35749
- var currentLogFile;
35750
- var writeCount;
35751
- var RING_BUFFER_SIZE;
35752
- var ringBuffer;
35753
- var origConsoleLog;
35754
- var origConsoleError;
35755
- var origConsoleWarn;
35756
- var LOG2;
35757
- var interceptorInstalled;
35758
- var LOG_PATH;
35759
- var LOG_DIR_PATH;
35760
- var init_logger = __esm2({
35761
- "src/logging/logger.ts"() {
35762
- "use strict";
35763
- fs4 = __toESM2(require("fs"));
35764
- path9 = __toESM2(require("path"));
35765
- os32 = __toESM2(require("os"));
35766
- init_async_batch_writer();
35767
- LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
35768
- LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
35769
- currentLevel = "info";
35770
- LOG_DIR = process.platform === "win32" ? path9.join(process.env.LOCALAPPDATA || process.env.APPDATA || path9.join(os32.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path9.join(os32.homedir(), "Library", "Logs", "adhdev") : path9.join(os32.homedir(), ".local", "share", "adhdev", "logs");
35771
- MAX_LOG_SIZE = 5 * 1024 * 1024;
35772
- MAX_LOG_DAYS = 7;
35773
- try {
35774
- fs4.mkdirSync(LOG_DIR, { recursive: true });
35775
- } catch {
35776
- }
35777
- currentDate = getDateStr();
35778
- currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
35779
- cleanOldLogs();
35780
- try {
35781
- const oldLog = path9.join(LOG_DIR, "daemon.log");
35782
- if (fs4.existsSync(oldLog)) {
35783
- const stat2 = fs4.statSync(oldLog);
35784
- const oldDate = stat2.mtime.toISOString().slice(0, 10);
35785
- fs4.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
35786
- }
35787
- const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
35788
- if (fs4.existsSync(oldLogBackup)) {
35789
- fs4.unlinkSync(oldLogBackup);
35790
- }
35791
- } catch {
35792
- }
35793
- writeCount = 0;
35794
- RING_BUFFER_SIZE = 200;
35795
- ringBuffer = [];
35796
- origConsoleLog = console.log.bind(console);
35797
- origConsoleError = console.error.bind(console);
35798
- origConsoleWarn = console.warn.bind(console);
35799
- LOG2 = {
35800
- debug: (category, msg) => daemonLog(category, msg, "debug"),
35801
- info: (category, msg) => daemonLog(category, msg, "info"),
35802
- warn: (category, msg) => daemonLog(category, msg, "warn"),
35803
- error: (category, msg) => daemonLog(category, msg, "error"),
35804
- /**
35805
- * Create a scoped logger for a specific component.
35806
- * Category is baked in so callers only pass the message.
35807
- */
35808
- forComponent(category) {
35809
- return {
35810
- debug: (msg) => daemonLog(category, msg, "debug"),
35811
- info: (msg) => daemonLog(category, msg, "info"),
35812
- warn: (msg) => daemonLog(category, msg, "warn"),
35813
- error: (msg) => daemonLog(category, msg, "error"),
35814
- asLogFn: (level = "info") => (msg) => daemonLog(category, msg, level)
35815
- };
35816
- }
35817
- };
35818
- interceptorInstalled = false;
35819
- LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
35820
- LOG_DIR_PATH = LOG_DIR;
35821
- }
35822
- });
35823
35870
  var mesh_coordinator_exports = {};
35824
35871
  __export2(mesh_coordinator_exports, {
35825
35872
  applyMeshCoordinatorSystemPromptInjection: () => applyMeshCoordinatorSystemPromptInjection,
@@ -36227,6 +36274,61 @@ ${rendered}`, "utf-8");
36227
36274
  HERMES_MCP_CONFIG_PATH = "~/.hermes/config.yaml";
36228
36275
  }
36229
36276
  });
36277
+ function resolveWin32GlobalBin(trimmed) {
36278
+ if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
36279
+ return null;
36280
+ }
36281
+ const extraDirs = [];
36282
+ if (process.env.APPDATA) extraDirs.push(path10.join(process.env.APPDATA, "npm"));
36283
+ try {
36284
+ extraDirs.push(path10.dirname(process.execPath));
36285
+ } catch {
36286
+ }
36287
+ for (const dir of extraDirs) {
36288
+ if (!dir) continue;
36289
+ for (const ext of WIN_EXEC_EXT) {
36290
+ const full = path10.join(dir, trimmed + ext);
36291
+ if ((0, import_fs8.existsSync)(full)) return full;
36292
+ }
36293
+ }
36294
+ return null;
36295
+ }
36296
+ function resolveWin32Executable(command) {
36297
+ if (process.platform !== "win32") return command;
36298
+ const trimmed = (command || "").trim();
36299
+ if (!trimmed) return command;
36300
+ if (path10.isAbsolute(trimmed) && (0, import_fs8.existsSync)(trimmed)) return trimmed;
36301
+ try {
36302
+ const out = (0, import_child_process.execFileSync)("where", [trimmed], {
36303
+ encoding: "utf8",
36304
+ windowsHide: true
36305
+ }).trim();
36306
+ if (out) {
36307
+ const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
36308
+ const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path10.extname(m).toLowerCase()));
36309
+ return direct || matches[0] || command;
36310
+ }
36311
+ } catch {
36312
+ }
36313
+ const globalBin = resolveWin32GlobalBin(trimmed);
36314
+ if (globalBin) return globalBin;
36315
+ return command;
36316
+ }
36317
+ var import_child_process;
36318
+ var import_fs8;
36319
+ var path10;
36320
+ var DIRECT_EXEC_EXT;
36321
+ var WIN_EXEC_EXT;
36322
+ var init_resolve_executable = __esm2({
36323
+ "src/cli-adapters/resolve-executable.ts"() {
36324
+ "use strict";
36325
+ import_child_process = require("child_process");
36326
+ import_fs8 = require("fs");
36327
+ path10 = __toESM2(require("path"));
36328
+ DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
36329
+ WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
36330
+ }
36331
+ });
36230
36332
  async function fastForwardMeshNode(args) {
36231
36333
  const workspace = typeof args.workspace === "string" ? args.workspace.trim() : "";
36232
36334
  const nodeId = normalizeOptionalString(args.nodeId);
@@ -37743,9 +37845,9 @@ Next step: ${nextStep}`;
37743
37845
  const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
37744
37846
  const events = [];
37745
37847
  for (const path422 of paths) {
37746
- if (!(0, import_fs9.existsSync)(path422)) continue;
37848
+ if (!(0, import_fs10.existsSync)(path422)) continue;
37747
37849
  try {
37748
- const raw = (0, import_fs9.readFileSync)(path422, "utf-8");
37850
+ const raw = (0, import_fs10.readFileSync)(path422, "utf-8");
37749
37851
  const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
37750
37852
  try {
37751
37853
  return [JSON.parse(line)];
@@ -37820,11 +37922,11 @@ Next step: ${nextStep}`;
37820
37922
  }
37821
37923
  function trimPendingEventsIfNeeded(path422) {
37822
37924
  try {
37823
- if (!(0, import_fs9.existsSync)(path422)) return;
37824
- if ((0, import_fs9.statSync)(path422).size <= MAX_PENDING_EVENTS_BYTES) return;
37825
- const lines = (0, import_fs9.readFileSync)(path422, "utf-8").split("\n").filter(Boolean);
37925
+ if (!(0, import_fs10.existsSync)(path422)) return;
37926
+ if ((0, import_fs10.statSync)(path422).size <= MAX_PENDING_EVENTS_BYTES) return;
37927
+ const lines = (0, import_fs10.readFileSync)(path422, "utf-8").split("\n").filter(Boolean);
37826
37928
  if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
37827
- (0, import_fs9.writeFileSync)(path422, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
37929
+ (0, import_fs10.writeFileSync)(path422, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
37828
37930
  } catch {
37829
37931
  }
37830
37932
  }
@@ -37853,7 +37955,7 @@ Next step: ${nextStep}`;
37853
37955
  }
37854
37956
  const path422 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
37855
37957
  trimPendingEventsIfNeeded(path422);
37856
- (0, import_fs9.appendFileSync)(path422, JSON.stringify(event) + "\n", "utf-8");
37958
+ (0, import_fs10.appendFileSync)(path422, JSON.stringify(event) + "\n", "utf-8");
37857
37959
  return true;
37858
37960
  } catch (e) {
37859
37961
  LOG2.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
@@ -37863,20 +37965,20 @@ Next step: ${nextStep}`;
37863
37965
  function atomicDrainFile(path422) {
37864
37966
  const tmpPath = `${path422}.draining`;
37865
37967
  try {
37866
- (0, import_fs9.renameSync)(path422, tmpPath);
37968
+ (0, import_fs10.renameSync)(path422, tmpPath);
37867
37969
  } catch {
37868
37970
  return null;
37869
37971
  }
37870
37972
  try {
37871
- const content = (0, import_fs9.readFileSync)(tmpPath, "utf-8");
37973
+ const content = (0, import_fs10.readFileSync)(tmpPath, "utf-8");
37872
37974
  try {
37873
- (0, import_fs9.unlinkSync)(tmpPath);
37975
+ (0, import_fs10.unlinkSync)(tmpPath);
37874
37976
  } catch {
37875
37977
  }
37876
37978
  return content;
37877
37979
  } catch {
37878
37980
  try {
37879
- (0, import_fs9.unlinkSync)(tmpPath);
37981
+ (0, import_fs10.unlinkSync)(tmpPath);
37880
37982
  } catch {
37881
37983
  }
37882
37984
  return null;
@@ -37885,16 +37987,16 @@ Next step: ${nextStep}`;
37885
37987
  function selectiveDrainFile(path422, predicate) {
37886
37988
  const tmpPath = `${path422}.draining`;
37887
37989
  try {
37888
- (0, import_fs9.renameSync)(path422, tmpPath);
37990
+ (0, import_fs10.renameSync)(path422, tmpPath);
37889
37991
  } catch {
37890
37992
  return [];
37891
37993
  }
37892
37994
  let content;
37893
37995
  try {
37894
- content = (0, import_fs9.readFileSync)(tmpPath, "utf-8");
37996
+ content = (0, import_fs10.readFileSync)(tmpPath, "utf-8");
37895
37997
  } catch {
37896
37998
  try {
37897
- (0, import_fs9.unlinkSync)(tmpPath);
37999
+ (0, import_fs10.unlinkSync)(tmpPath);
37898
38000
  } catch {
37899
38001
  }
37900
38002
  return [];
@@ -37917,12 +38019,12 @@ Next step: ${nextStep}`;
37917
38019
  }
37918
38020
  try {
37919
38021
  if (keptLines.length > 0) {
37920
- (0, import_fs9.writeFileSync)(path422, keptLines.join("\n") + "\n", "utf-8");
38022
+ (0, import_fs10.writeFileSync)(path422, keptLines.join("\n") + "\n", "utf-8");
37921
38023
  }
37922
- (0, import_fs9.unlinkSync)(tmpPath);
38024
+ (0, import_fs10.unlinkSync)(tmpPath);
37923
38025
  } catch {
37924
38026
  try {
37925
- if ((0, import_fs9.existsSync)(tmpPath) && !(0, import_fs9.existsSync)(path422)) (0, import_fs9.renameSync)(tmpPath, path422);
38027
+ if ((0, import_fs10.existsSync)(tmpPath) && !(0, import_fs10.existsSync)(path422)) (0, import_fs10.renameSync)(tmpPath, path422);
37926
38028
  } catch {
37927
38029
  }
37928
38030
  return [];
@@ -38016,13 +38118,13 @@ Next step: ${nextStep}`;
38016
38118
  }
38017
38119
  const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
38018
38120
  for (const path422 of paths) {
38019
- if ((0, import_fs9.existsSync)(path422)) try {
38020
- (0, import_fs9.unlinkSync)(path422);
38121
+ if ((0, import_fs10.existsSync)(path422)) try {
38122
+ (0, import_fs10.unlinkSync)(path422);
38021
38123
  } catch {
38022
38124
  }
38023
38125
  }
38024
38126
  }
38025
- var import_fs9;
38127
+ var import_fs10;
38026
38128
  var import_path9;
38027
38129
  var import_crypto7;
38028
38130
  var REFINE_TERMINAL_EVENTS;
@@ -38031,7 +38133,7 @@ Next step: ${nextStep}`;
38031
38133
  var init_mesh_events_pending = __esm2({
38032
38134
  "src/mesh/mesh-events-pending.ts"() {
38033
38135
  "use strict";
38034
- import_fs9 = require("fs");
38136
+ import_fs10 = require("fs");
38035
38137
  import_path9 = require("path");
38036
38138
  import_crypto7 = require("crypto");
38037
38139
  init_logger();
@@ -38521,24 +38623,24 @@ Next step: ${nextStep}`;
38521
38623
  function findBinary(name) {
38522
38624
  const trimmed = String(name || "").trim();
38523
38625
  if (!trimmed) return trimmed;
38524
- const expanded = trimmed.startsWith("~") ? path10.join(os52.homedir(), trimmed.slice(1)) : trimmed;
38525
- if (path10.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
38526
- return path10.isAbsolute(expanded) ? expanded : path10.resolve(expanded);
38626
+ const expanded = trimmed.startsWith("~") ? path11.join(os52.homedir(), trimmed.slice(1)) : trimmed;
38627
+ if (path11.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
38628
+ return path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
38527
38629
  }
38528
38630
  const isWin = os52.platform() === "win32";
38529
- const paths = (process.env.PATH || "").split(path10.delimiter);
38631
+ const paths = (process.env.PATH || "").split(path11.delimiter);
38530
38632
  const extraDirs = [];
38531
38633
  if (isWin) {
38532
- if (process.env.APPDATA) extraDirs.push(path10.join(process.env.APPDATA, "npm"));
38634
+ if (process.env.APPDATA) extraDirs.push(path11.join(process.env.APPDATA, "npm"));
38533
38635
  try {
38534
- extraDirs.push(path10.dirname(process.execPath));
38636
+ extraDirs.push(path11.dirname(process.execPath));
38535
38637
  } catch {
38536
38638
  }
38537
38639
  } else {
38538
- extraDirs.push(path10.join(os52.homedir(), ".npm-global", "bin"));
38640
+ extraDirs.push(path11.join(os52.homedir(), ".npm-global", "bin"));
38539
38641
  extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
38540
38642
  try {
38541
- extraDirs.push(path10.dirname(process.execPath));
38643
+ extraDirs.push(path11.dirname(process.execPath));
38542
38644
  } catch {
38543
38645
  }
38544
38646
  }
@@ -38547,7 +38649,7 @@ Next step: ${nextStep}`;
38547
38649
  for (const p of searchDirs) {
38548
38650
  if (!p) continue;
38549
38651
  for (const ext of exes) {
38550
- const fullPath = path10.join(p, trimmed + ext);
38652
+ const fullPath = path11.join(p, trimmed + ext);
38551
38653
  try {
38552
38654
  const fs322 = require("fs");
38553
38655
  if (fs322.existsSync(fullPath)) {
@@ -38563,7 +38665,7 @@ Next step: ${nextStep}`;
38563
38665
  return isWin ? `${trimmed}.cmd` : trimmed;
38564
38666
  }
38565
38667
  function isScriptBinary(binaryPath) {
38566
- if (!path10.isAbsolute(binaryPath)) return false;
38668
+ if (!path11.isAbsolute(binaryPath)) return false;
38567
38669
  try {
38568
38670
  const fs322 = require("fs");
38569
38671
  const resolved = fs322.realpathSync(binaryPath);
@@ -38579,7 +38681,7 @@ Next step: ${nextStep}`;
38579
38681
  }
38580
38682
  }
38581
38683
  function looksLikeMachOOrElf(filePath) {
38582
- if (!path10.isAbsolute(filePath)) return false;
38684
+ if (!path11.isAbsolute(filePath)) return false;
38583
38685
  try {
38584
38686
  const fs322 = require("fs");
38585
38687
  const resolved = fs322.realpathSync(filePath);
@@ -38669,14 +38771,14 @@ Next step: ${nextStep}`;
38669
38771
  };
38670
38772
  }
38671
38773
  var os52;
38672
- var path10;
38774
+ var path11;
38673
38775
  var TerminalTranscriptAccumulator;
38674
38776
  var buildCliSpawnEnv;
38675
38777
  var init_provider_cli_shared = __esm2({
38676
38778
  "src/cli-adapters/provider-cli-shared.ts"() {
38677
38779
  "use strict";
38678
38780
  os52 = __toESM2(require("os"));
38679
- path10 = __toESM2(require("path"));
38781
+ path11 = __toESM2(require("path"));
38680
38782
  init_spawn_env();
38681
38783
  TerminalTranscriptAccumulator = class {
38682
38784
  lines = [[]];
@@ -38848,19 +38950,19 @@ Next step: ${nextStep}`;
38848
38950
  function expandHome(value) {
38849
38951
  const trimmed = value.trim();
38850
38952
  if (!trimmed.startsWith("~")) return trimmed;
38851
- return path11.join(os6.homedir(), trimmed.slice(1));
38953
+ return path12.join(os6.homedir(), trimmed.slice(1));
38852
38954
  }
38853
38955
  function isExplicitCommandPath(command) {
38854
38956
  const trimmed = command.trim();
38855
- return path11.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
38957
+ return path12.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
38856
38958
  }
38857
38959
  function resolveCommandPath(command) {
38858
38960
  const trimmed = command.trim();
38859
38961
  if (!trimmed) return null;
38860
38962
  if (isExplicitCommandPath(trimmed)) {
38861
38963
  const expanded = expandHome(trimmed);
38862
- const candidate = path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
38863
- return (0, import_fs10.existsSync)(candidate) ? candidate : null;
38964
+ const candidate = path12.isAbsolute(expanded) ? expanded : path12.resolve(expanded);
38965
+ return (0, import_fs11.existsSync)(candidate) ? candidate : null;
38864
38966
  }
38865
38967
  return null;
38866
38968
  }
@@ -38870,12 +38972,12 @@ Next step: ${nextStep}`;
38870
38972
  const whichResult = await execAsync(`${whichCmd} ${shellQuote(command)}`);
38871
38973
  if (whichResult) return whichResult.split("\n")[0];
38872
38974
  const resolved = findBinary(command);
38873
- if (path11.isAbsolute(resolved) && (0, import_fs10.existsSync)(resolved)) return resolved;
38975
+ if (path12.isAbsolute(resolved) && (0, import_fs11.existsSync)(resolved)) return resolved;
38874
38976
  return null;
38875
38977
  }
38876
38978
  function execAsync(cmd, timeoutMs = 5e3) {
38877
38979
  return new Promise((resolve24) => {
38878
- const child = (0, import_child_process.exec)(cmd, {
38980
+ const child = (0, import_child_process2.exec)(cmd, {
38879
38981
  encoding: "utf-8",
38880
38982
  timeout: timeoutMs,
38881
38983
  ...process.platform === "win32" ? { windowsHide: true } : {}
@@ -38965,17 +39067,17 @@ Next step: ${nextStep}`;
38965
39067
  const all = await detectCLIs(providerLoader, options);
38966
39068
  return all.find((c) => c.id === resolvedId && c.installed) || null;
38967
39069
  }
38968
- var import_child_process;
39070
+ var import_child_process2;
38969
39071
  var os6;
38970
- var path11;
38971
- var import_fs10;
39072
+ var path12;
39073
+ var import_fs11;
38972
39074
  var init_cli_detector = __esm2({
38973
39075
  "src/detection/cli-detector.ts"() {
38974
39076
  "use strict";
38975
- import_child_process = require("child_process");
39077
+ import_child_process2 = require("child_process");
38976
39078
  os6 = __toESM2(require("os"));
38977
- path11 = __toESM2(require("path"));
38978
- import_fs10 = require("fs");
39079
+ path12 = __toESM2(require("path"));
39080
+ import_fs11 = require("fs");
38979
39081
  init_provider_cli_shared();
38980
39082
  }
38981
39083
  });
@@ -40008,7 +40110,7 @@ Next step: ${nextStep}`;
40008
40110
  const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
40009
40111
  const workspace = readNonEmptyString2(node?.workspace);
40010
40112
  if (!workspace) return;
40011
- if (!(0, import_fs11.existsSync)(workspace)) return;
40113
+ if (!(0, import_fs12.existsSync)(workspace)) return;
40012
40114
  const policy = resolveAutoFastForwardPolicy(mesh);
40013
40115
  if (!policy.enabled) return;
40014
40116
  if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId, args.sessionId)) return;
@@ -40207,8 +40309,10 @@ Next step: ${nextStep}`;
40207
40309
  }
40208
40310
  }
40209
40311
  function markSessionTerminal(sessionId, outcome, occurredAtMs) {
40312
+ const eventTaskId = readNonEmptyString2(args.metadataEvent.taskId) || void 0;
40210
40313
  const task = updateSessionTaskStatus(args.meshId, sessionId, outcome, {
40211
- occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0
40314
+ occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0,
40315
+ taskId: eventTaskId
40212
40316
  });
40213
40317
  updateDirectDispatchStatus(args.meshId, sessionId, outcome);
40214
40318
  markSessionDeliveriesTerminal(args.meshId, sessionId, outcome);
@@ -40619,7 +40723,7 @@ Next step: ${nextStep}`;
40619
40723
  });
40620
40724
  });
40621
40725
  }
40622
- var import_fs11;
40726
+ var import_fs12;
40623
40727
  var REMOTE_IDLE_SESSION_TTL_MS;
40624
40728
  var meshByWorkspaceCache;
40625
40729
  var MESH_WORKSPACE_CACHE_TTL_MS;
@@ -40639,7 +40743,7 @@ Next step: ${nextStep}`;
40639
40743
  var init_mesh_events_coordinator = __esm2({
40640
40744
  "src/mesh/mesh-events-coordinator.ts"() {
40641
40745
  "use strict";
40642
- import_fs11 = require("fs");
40746
+ import_fs12 = require("fs");
40643
40747
  init_config();
40644
40748
  init_mesh_config();
40645
40749
  init_cli_detector();
@@ -42522,16 +42626,16 @@ Next step: ${nextStep}`;
42522
42626
  sourcesProviding: () => sourcesProviding
42523
42627
  });
42524
42628
  function adhdevDir() {
42525
- return path17.join(os11.homedir(), ".adhdev");
42629
+ return path18.join(os11.homedir(), ".adhdev");
42526
42630
  }
42527
42631
  function externalRoot() {
42528
- return path17.join(adhdevDir(), "external");
42632
+ return path18.join(adhdevDir(), "external");
42529
42633
  }
42530
42634
  function sourcesFilePath() {
42531
- return path17.join(adhdevDir(), SOURCES_FILENAME);
42635
+ return path18.join(adhdevDir(), SOURCES_FILENAME);
42532
42636
  }
42533
42637
  function activeFilePath() {
42534
- return path17.join(adhdevDir(), ACTIVE_FILENAME);
42638
+ return path18.join(adhdevDir(), ACTIVE_FILENAME);
42535
42639
  }
42536
42640
  function ensureAdhdevDir() {
42537
42641
  const d = adhdevDir();
@@ -42598,7 +42702,7 @@ Next step: ${nextStep}`;
42598
42702
  for (const sourceEntry of entries) {
42599
42703
  if (!sourceEntry.isDirectory()) continue;
42600
42704
  const sourceName = sourceEntry.name;
42601
- const sourceDir = path17.join(root, sourceName);
42705
+ const sourceDir = path18.join(root, sourceName);
42602
42706
  const providers = {};
42603
42707
  let categoryEntries;
42604
42708
  try {
@@ -42609,7 +42713,7 @@ Next step: ${nextStep}`;
42609
42713
  for (const categoryEntry of categoryEntries) {
42610
42714
  if (!categoryEntry.isDirectory()) continue;
42611
42715
  const category = categoryEntry.name;
42612
- const categoryDir = path17.join(sourceDir, category);
42716
+ const categoryDir = path18.join(sourceDir, category);
42613
42717
  let typeEntries;
42614
42718
  try {
42615
42719
  typeEntries = fs9.readdirSync(categoryDir, { withFileTypes: true });
@@ -42619,9 +42723,9 @@ Next step: ${nextStep}`;
42619
42723
  const types = [];
42620
42724
  for (const typeEntry of typeEntries) {
42621
42725
  if (!typeEntry.isDirectory()) continue;
42622
- const typeDir = path17.join(categoryDir, typeEntry.name);
42623
- const hasV1 = fs9.existsSync(path17.join(typeDir, "provider.v1.json"));
42624
- const hasV0 = fs9.existsSync(path17.join(typeDir, "provider.json"));
42726
+ const typeDir = path18.join(categoryDir, typeEntry.name);
42727
+ const hasV1 = fs9.existsSync(path18.join(typeDir, "provider.v1.json"));
42728
+ const hasV0 = fs9.existsSync(path18.join(typeDir, "provider.json"));
42625
42729
  if (hasV1 || hasV0) types.push(typeEntry.name);
42626
42730
  }
42627
42731
  if (types.length > 0) providers[category] = types;
@@ -42646,7 +42750,7 @@ Next step: ${nextStep}`;
42646
42750
  }
42647
42751
  var fs9;
42648
42752
  var os11;
42649
- var path17;
42753
+ var path18;
42650
42754
  var SOURCES_FILENAME;
42651
42755
  var ACTIVE_FILENAME;
42652
42756
  var init_external_sources = __esm2({
@@ -42654,7 +42758,7 @@ Next step: ${nextStep}`;
42654
42758
  "use strict";
42655
42759
  fs9 = __toESM2(require("fs"));
42656
42760
  os11 = __toESM2(require("os"));
42657
- path17 = __toESM2(require("path"));
42761
+ path18 = __toESM2(require("path"));
42658
42762
  SOURCES_FILENAME = "providers-sources.json";
42659
42763
  ACTIVE_FILENAME = "providers-active.json";
42660
42764
  }
@@ -42832,61 +42936,6 @@ Next step: ${nextStep}`;
42832
42936
  };
42833
42937
  }
42834
42938
  });
42835
- function resolveWin32GlobalBin(trimmed) {
42836
- if (path18.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
42837
- return null;
42838
- }
42839
- const extraDirs = [];
42840
- if (process.env.APPDATA) extraDirs.push(path18.join(process.env.APPDATA, "npm"));
42841
- try {
42842
- extraDirs.push(path18.dirname(process.execPath));
42843
- } catch {
42844
- }
42845
- for (const dir of extraDirs) {
42846
- if (!dir) continue;
42847
- for (const ext of WIN_EXEC_EXT) {
42848
- const full = path18.join(dir, trimmed + ext);
42849
- if ((0, import_fs14.existsSync)(full)) return full;
42850
- }
42851
- }
42852
- return null;
42853
- }
42854
- function resolveWin32Executable(command) {
42855
- if (process.platform !== "win32") return command;
42856
- const trimmed = (command || "").trim();
42857
- if (!trimmed) return command;
42858
- if (path18.isAbsolute(trimmed) && (0, import_fs14.existsSync)(trimmed)) return trimmed;
42859
- try {
42860
- const out = (0, import_child_process4.execFileSync)("where", [trimmed], {
42861
- encoding: "utf8",
42862
- windowsHide: true
42863
- }).trim();
42864
- if (out) {
42865
- const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
42866
- const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path18.extname(m).toLowerCase()));
42867
- return direct || matches[0] || command;
42868
- }
42869
- } catch {
42870
- }
42871
- const globalBin = resolveWin32GlobalBin(trimmed);
42872
- if (globalBin) return globalBin;
42873
- return command;
42874
- }
42875
- var import_child_process4;
42876
- var import_fs14;
42877
- var path18;
42878
- var DIRECT_EXEC_EXT;
42879
- var WIN_EXEC_EXT;
42880
- var init_resolve_executable = __esm2({
42881
- "src/cli-adapters/resolve-executable.ts"() {
42882
- "use strict";
42883
- import_child_process4 = require("child_process");
42884
- import_fs14 = require("fs");
42885
- path18 = __toESM2(require("path"));
42886
- DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
42887
- WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
42888
- }
42889
- });
42890
42939
  var pty_transport_exports = {};
42891
42940
  __export2(pty_transport_exports, {
42892
42941
  NodePtyTransportFactory: () => NodePtyTransportFactory
@@ -44873,6 +44922,9 @@ ${cont}` : cont;
44873
44922
  }
44874
44923
  var os14;
44875
44924
  var import_session_host_core5;
44925
+ var FORCE_SUBMIT_SETTLE_MS;
44926
+ var FORCE_SUBMIT_MAX_WAIT_MS;
44927
+ var FORCE_SUBMIT_POLL_MS;
44876
44928
  var ProviderCliAdapter;
44877
44929
  var init_provider_cli_adapter = __esm2({
44878
44930
  "src/cli-adapters/provider-cli-adapter.ts"() {
@@ -44890,6 +44942,9 @@ ${cont}` : cont;
44890
44942
  init_provider_cli_config();
44891
44943
  init_provider_cli_runtime();
44892
44944
  init_provider_cli_shared();
44945
+ FORCE_SUBMIT_SETTLE_MS = 150;
44946
+ FORCE_SUBMIT_MAX_WAIT_MS = 1500;
44947
+ FORCE_SUBMIT_POLL_MS = 50;
44893
44948
  ProviderCliAdapter = class _ProviderCliAdapter {
44894
44949
  constructor(provider, workingDir, extraArgs = [], extraEnv = {}, transportFactory = new NodePtyTransportFactory()) {
44895
44950
  this.extraArgs = extraArgs;
@@ -45818,9 +45873,23 @@ ${lastSnapshot}`;
45818
45873
  return;
45819
45874
  }
45820
45875
  LOG2.info("CLI", `[${this.cliType}] force-sending prompt while status=${this.engine.currentStatus}`);
45821
- await this.writeToPty(content + this.sendKey);
45876
+ await this.writeToPty(content);
45877
+ await this.waitForForceSubmitSettle(content);
45878
+ await this.writeToPty(this.sendKey);
45822
45879
  this.onStatusChange?.();
45823
45880
  }
45881
+ async waitForForceSubmitSettle(content) {
45882
+ const startedAt = Date.now();
45883
+ const normalizedPromptSnippet = normalizePromptText(extractPromptRetrySnippet(content));
45884
+ await new Promise((resolve24) => setTimeout(resolve24, FORCE_SUBMIT_SETTLE_MS));
45885
+ if (!normalizedPromptSnippet) return;
45886
+ while (Date.now() - startedAt < FORCE_SUBMIT_MAX_WAIT_MS) {
45887
+ if (!this.ptyProcess) return;
45888
+ const screenText = this.terminalScreen.getText();
45889
+ if (promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
45890
+ await new Promise((resolve24) => setTimeout(resolve24, FORCE_SUBMIT_POLL_MS));
45891
+ }
45892
+ }
45824
45893
  enqueuePendingOutboundMessage(text, reason) {
45825
45894
  const content = String(text || "");
45826
45895
  const duplicate = this.pendingOutboundQueue.some((message2) => message2.content === content);
@@ -49556,13 +49625,20 @@ ${lastSnapshot}`;
49556
49625
  function isMeshConfigRecord(value) {
49557
49626
  return !!value && typeof value === "object" && !Array.isArray(value);
49558
49627
  }
49628
+ var SHELL_METACHAR_RE = /[;&|<>`$\n\r'"]/;
49629
+ var SAFE_TOKEN_RE = /^[A-Za-z0-9_@./:=+-]+$/;
49630
+ var SAFE_WIN32_EXEC_TOKEN_RE = /^[A-Za-z0-9_@./:=+\\-]+$/;
49559
49631
  function tokenizeCommandString(command) {
49560
49632
  const trimmed = command.trim();
49561
49633
  if (!trimmed) return null;
49562
- if (/[;&|<>`$\\\n\r'\"]/.test(trimmed)) return null;
49634
+ if (SHELL_METACHAR_RE.test(trimmed)) return null;
49563
49635
  const tokens = trimmed.split(/\s+/).filter(Boolean);
49564
49636
  if (!tokens.length) return null;
49565
- if (tokens.some((token) => !/^[A-Za-z0-9_@./:=+-]+$/.test(token))) return null;
49637
+ const isWin32 = process.platform === "win32";
49638
+ for (let i = 0; i < tokens.length; i++) {
49639
+ const re = isWin32 && i === 0 ? SAFE_WIN32_EXEC_TOKEN_RE : SAFE_TOKEN_RE;
49640
+ if (!re.test(tokens[i])) return null;
49641
+ }
49566
49642
  return tokens;
49567
49643
  }
49568
49644
  function validateCategory(value) {
@@ -49770,12 +49846,13 @@ ${lastSnapshot}`;
49770
49846
  unavailableReason: validation.commands.length ? void 0 : "validation_unavailable: repo mesh/refine config has no validation.commands"
49771
49847
  };
49772
49848
  }
49773
- var import_fs8 = require("fs");
49849
+ var import_fs9 = require("fs");
49774
49850
  var import_path8 = require("path");
49775
49851
  var import_node_child_process3 = require("child_process");
49776
49852
  var import_node_crypto2 = require("crypto");
49777
49853
  var import_node_util3 = require("util");
49778
49854
  var yaml3 = __toESM2(require_js_yaml());
49855
+ init_resolve_executable();
49779
49856
  var MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS = [
49780
49857
  ".adhdev/worktree_bootstrap.json",
49781
49858
  ".adhdev/worktree_bootstrap.yaml",
@@ -49863,9 +49940,9 @@ ${lastSnapshot}`;
49863
49940
  }
49864
49941
  for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
49865
49942
  const configPath = (0, import_path8.join)(workspace, relative5);
49866
- if (!(0, import_fs8.existsSync)(configPath)) continue;
49943
+ if (!(0, import_fs9.existsSync)(configPath)) continue;
49867
49944
  try {
49868
- const parsed = parseConfigText3(configPath, (0, import_fs8.readFileSync)(configPath, "utf-8"));
49945
+ const parsed = parseConfigText3(configPath, (0, import_fs9.readFileSync)(configPath, "utf-8"));
49869
49946
  const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
49870
49947
  if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
49871
49948
  return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
@@ -49880,7 +49957,7 @@ ${lastSnapshot}`;
49880
49957
  for (const relative5 of staleInputs ?? []) {
49881
49958
  const filePath = (0, import_path8.join)(workspace, relative5);
49882
49959
  try {
49883
- digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0, import_fs8.readFileSync)(filePath)).digest("hex");
49960
+ digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0, import_fs9.readFileSync)(filePath)).digest("hex");
49884
49961
  } catch {
49885
49962
  digest[relative5] = "absent";
49886
49963
  }
@@ -49950,10 +50027,10 @@ ${lastSnapshot}`;
49950
50027
  staleInputs: loaded.config.staleInputs
49951
50028
  };
49952
50029
  const staleInputPaths = loaded.config.staleInputs ?? [];
49953
- const initiallyAbsent = staleInputPaths.filter((p) => !(0, import_fs8.existsSync)((0, import_path8.join)(workspace, p)));
50030
+ const initiallyAbsent = staleInputPaths.filter((p) => !(0, import_fs9.existsSync)((0, import_path8.join)(workspace, p)));
49954
50031
  for (const command of validation.commands) {
49955
50032
  if (initiallyAbsent.length > 0) {
49956
- const appearedNow = initiallyAbsent.filter((p) => (0, import_fs8.existsSync)((0, import_path8.join)(workspace, p)));
50033
+ const appearedNow = initiallyAbsent.filter((p) => (0, import_fs9.existsSync)((0, import_path8.join)(workspace, p)));
49957
50034
  if (appearedNow.length > 0) {
49958
50035
  state.status = "stale";
49959
50036
  state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -49964,8 +50041,9 @@ ${lastSnapshot}`;
49964
50041
  const cwd = command.cwd ? (0, import_path8.resolve)(workspace, command.cwd) : workspace;
49965
50042
  const startedAt = Date.now();
49966
50043
  state.lastCommand = command.displayCommand;
50044
+ const resolvedCommand = resolveWin32Executable(command.command);
49967
50045
  try {
49968
- const result = await execFileAsync4(command.command, command.args, {
50046
+ const result = await execFileAsync4(resolvedCommand, command.args, {
49969
50047
  cwd,
49970
50048
  encoding: "utf8",
49971
50049
  timeout: command.timeoutMs || DEFAULT_TIMEOUT_MS2,
@@ -50190,7 +50268,7 @@ ${lastSnapshot}`;
50190
50268
  this.targetDaemonId = context.targetDaemonId;
50191
50269
  }
50192
50270
  };
50193
- var import_fs12 = require("fs");
50271
+ var import_fs13 = require("fs");
50194
50272
  var import_path10 = require("path");
50195
50273
  init_config();
50196
50274
  var DEFAULT_STATE = {
@@ -50241,11 +50319,11 @@ ${lastSnapshot}`;
50241
50319
  }
50242
50320
  function loadState() {
50243
50321
  const statePath = getStatePath();
50244
- if (!(0, import_fs12.existsSync)(statePath)) {
50322
+ if (!(0, import_fs13.existsSync)(statePath)) {
50245
50323
  return { ...DEFAULT_STATE };
50246
50324
  }
50247
50325
  try {
50248
- const raw = (0, import_fs12.readFileSync)(statePath, "utf-8");
50326
+ const raw = (0, import_fs13.readFileSync)(statePath, "utf-8");
50249
50327
  return normalizeState(JSON.parse(raw));
50250
50328
  } catch {
50251
50329
  return { ...DEFAULT_STATE };
@@ -50254,24 +50332,24 @@ ${lastSnapshot}`;
50254
50332
  function saveState(state) {
50255
50333
  const statePath = getStatePath();
50256
50334
  const normalized = normalizeState(state);
50257
- (0, import_fs12.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
50335
+ (0, import_fs13.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
50258
50336
  }
50259
50337
  function resetState() {
50260
50338
  saveState({ ...DEFAULT_STATE });
50261
50339
  }
50262
- var import_child_process2 = require("child_process");
50340
+ var import_child_process3 = require("child_process");
50263
50341
  var import_util3 = require("util");
50264
- var import_fs13 = require("fs");
50342
+ var import_fs14 = require("fs");
50265
50343
  var import_os22 = require("os");
50266
- var path13 = __toESM2(require("path"));
50344
+ var path14 = __toESM2(require("path"));
50267
50345
  var fs52 = __toESM2(require("fs"));
50268
- var path12 = __toESM2(require("path"));
50346
+ var path13 = __toESM2(require("path"));
50269
50347
  function manifestCandidates(exeDir) {
50270
50348
  return [
50271
- path12.join(exeDir, "resources", "app", "product.json"),
50272
- path12.join(exeDir, "resources", "app", "package.json"),
50349
+ path13.join(exeDir, "resources", "app", "product.json"),
50350
+ path13.join(exeDir, "resources", "app", "package.json"),
50273
50351
  // Some packagings keep product.json one level up.
50274
- path12.join(exeDir, "product.json")
50352
+ path13.join(exeDir, "product.json")
50275
50353
  ];
50276
50354
  }
50277
50355
  function parseVersionFromManifest(raw) {
@@ -50289,9 +50367,9 @@ ${lastSnapshot}`;
50289
50367
  if (!exePath) return null;
50290
50368
  let exeDir;
50291
50369
  try {
50292
- exeDir = fs52.statSync(exePath).isDirectory() ? exePath : path12.dirname(exePath);
50370
+ exeDir = fs52.statSync(exePath).isDirectory() ? exePath : path13.dirname(exePath);
50293
50371
  } catch {
50294
- exeDir = path12.dirname(exePath);
50372
+ exeDir = path13.dirname(exePath);
50295
50373
  }
50296
50374
  for (const candidate of manifestCandidates(exeDir)) {
50297
50375
  try {
@@ -50305,7 +50383,7 @@ ${lastSnapshot}`;
50305
50383
  }
50306
50384
  function isKnownWin32GuiExe(binPath, win32ProcessNames) {
50307
50385
  if (!binPath) return false;
50308
- const base = path12.win32.basename(binPath).toLowerCase();
50386
+ const base = path13.win32.basename(binPath).toLowerCase();
50309
50387
  if (!base.endsWith(".exe")) return false;
50310
50388
  for (const names of Object.values(win32ProcessNames)) {
50311
50389
  for (const name of names) {
@@ -50316,7 +50394,7 @@ ${lastSnapshot}`;
50316
50394
  }
50317
50395
  return false;
50318
50396
  }
50319
- var execAsync2 = (0, import_util3.promisify)(import_child_process2.exec);
50397
+ var execAsync2 = (0, import_util3.promisify)(import_child_process3.exec);
50320
50398
  var BUILTIN_IDE_DEFINITIONS = [];
50321
50399
  var registeredIDEs = /* @__PURE__ */ new Map();
50322
50400
  function registerIDEDefinition(def) {
@@ -50335,10 +50413,10 @@ ${lastSnapshot}`;
50335
50413
  function findCliCommand(command) {
50336
50414
  const trimmed = String(command || "").trim();
50337
50415
  if (!trimmed) return null;
50338
- if (path13.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
50339
- const candidate = trimmed.startsWith("~") ? path13.join((0, import_os22.homedir)(), trimmed.slice(1)) : trimmed;
50340
- const resolved = path13.isAbsolute(candidate) ? candidate : path13.resolve(candidate);
50341
- return (0, import_fs13.existsSync)(resolved) ? resolved : null;
50416
+ if (path14.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
50417
+ const candidate = trimmed.startsWith("~") ? path14.join((0, import_os22.homedir)(), trimmed.slice(1)) : trimmed;
50418
+ const resolved = path14.isAbsolute(candidate) ? candidate : path14.resolve(candidate);
50419
+ return (0, import_fs14.existsSync)(resolved) ? resolved : null;
50342
50420
  }
50343
50421
  const isWin = (0, import_os22.platform)() === "win32";
50344
50422
  const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
@@ -50346,10 +50424,10 @@ ${lastSnapshot}`;
50346
50424
  for (const p of paths) {
50347
50425
  if (!p) continue;
50348
50426
  for (const ext of exes) {
50349
- const fullPath = path13.join(p, trimmed + ext);
50427
+ const fullPath = path14.join(p, trimmed + ext);
50350
50428
  try {
50351
- if ((0, import_fs13.existsSync)(fullPath)) {
50352
- const stat2 = (0, import_fs13.statSync)(fullPath);
50429
+ if ((0, import_fs14.existsSync)(fullPath)) {
50430
+ const stat2 = (0, import_fs14.statSync)(fullPath);
50353
50431
  if (stat2.isFile() && (isWin || stat2.mode & 73)) {
50354
50432
  return fullPath;
50355
50433
  }
@@ -50363,13 +50441,13 @@ ${lastSnapshot}`;
50363
50441
  function checkPathExists(paths) {
50364
50442
  const home = (0, import_os22.homedir)();
50365
50443
  for (const p of paths) {
50366
- const normalized = p.startsWith("~") ? path13.join(home, p.slice(1)) : p;
50444
+ const normalized = p.startsWith("~") ? path14.join(home, p.slice(1)) : p;
50367
50445
  if (normalized.includes("*")) {
50368
50446
  const username = home.split(/[\\/]/).pop() || "";
50369
50447
  const resolved = normalized.replace("*", username);
50370
- if ((0, import_fs13.existsSync)(resolved)) return resolved;
50448
+ if ((0, import_fs14.existsSync)(resolved)) return resolved;
50371
50449
  } else {
50372
- if ((0, import_fs13.existsSync)(normalized)) return normalized;
50450
+ if ((0, import_fs14.existsSync)(normalized)) return normalized;
50373
50451
  }
50374
50452
  }
50375
50453
  return null;
@@ -50383,7 +50461,7 @@ ${lastSnapshot}`;
50383
50461
  let resolvedCli = cliPath;
50384
50462
  if (!resolvedCli && appPath && os30 === "darwin") {
50385
50463
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
50386
- if ((0, import_fs13.existsSync)(bundledCli)) resolvedCli = bundledCli;
50464
+ if ((0, import_fs14.existsSync)(bundledCli)) resolvedCli = bundledCli;
50387
50465
  }
50388
50466
  if (!resolvedCli && appPath && os30 === "win32") {
50389
50467
  const { dirname: dirname17 } = await import("path");
@@ -50396,7 +50474,7 @@ ${lastSnapshot}`;
50396
50474
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
50397
50475
  ];
50398
50476
  for (const c of candidates) {
50399
- if ((0, import_fs13.existsSync)(c)) {
50477
+ if ((0, import_fs14.existsSync)(c)) {
50400
50478
  resolvedCli = c;
50401
50479
  break;
50402
50480
  }
@@ -50419,9 +50497,9 @@ ${lastSnapshot}`;
50419
50497
  }
50420
50498
  init_cli_detector();
50421
50499
  var os72 = __toESM2(require("os"));
50422
- var import_child_process3 = require("child_process");
50500
+ var import_child_process4 = require("child_process");
50423
50501
  var import_util22 = require("util");
50424
- var execAsync3 = (0, import_util22.promisify)(import_child_process3.exec);
50502
+ var execAsync3 = (0, import_util22.promisify)(import_child_process4.exec);
50425
50503
  var cachedDarwinAvail = null;
50426
50504
  var darwinMemoryInterval = null;
50427
50505
  async function updateDarwinMemoryCache() {
@@ -52232,10 +52310,10 @@ ${cleanBody}`;
52232
52310
  return cleanTitle || cleanBody;
52233
52311
  }
52234
52312
  var fs6 = __toESM2(require("fs"));
52235
- var path14 = __toESM2(require("path"));
52313
+ var path15 = __toESM2(require("path"));
52236
52314
  var os8 = __toESM2(require("os"));
52237
52315
  init_chat_message_normalization();
52238
- var HISTORY_DIR = path14.join(os8.homedir(), ".adhdev", "history");
52316
+ var HISTORY_DIR = path15.join(os8.homedir(), ".adhdev", "history");
52239
52317
  var RETAIN_DAYS = 30;
52240
52318
  var SAVED_HISTORY_INDEX_VERSION = 1;
52241
52319
  var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
@@ -52421,7 +52499,7 @@ ${cleanBody}`;
52421
52499
  function buildSavedHistoryFileSignatureMap(dir, files) {
52422
52500
  return new Map(files.map((file2) => {
52423
52501
  try {
52424
- const stat2 = fs6.statSync(path14.join(dir, file2));
52502
+ const stat2 = fs6.statSync(path15.join(dir, file2));
52425
52503
  return [file2, `${file2}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
52426
52504
  } catch {
52427
52505
  return [file2, `${file2}:missing`];
@@ -52432,7 +52510,7 @@ ${cleanBody}`;
52432
52510
  return files.map((file2) => fileSignatures.get(file2) || `${file2}:missing`).join("|");
52433
52511
  }
52434
52512
  function getSavedHistoryIndexFilePath(dir) {
52435
- return path14.join(dir, SAVED_HISTORY_INDEX_FILE);
52513
+ return path15.join(dir, SAVED_HISTORY_INDEX_FILE);
52436
52514
  }
52437
52515
  function getSavedHistoryIndexLockPath(dir) {
52438
52516
  return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
@@ -52534,7 +52612,7 @@ ${cleanBody}`;
52534
52612
  }
52535
52613
  for (const file2 of Array.from(currentEntries.keys())) {
52536
52614
  if (incomingFiles.has(file2)) continue;
52537
- if (!fs6.existsSync(path14.join(dir, file2))) {
52615
+ if (!fs6.existsSync(path15.join(dir, file2))) {
52538
52616
  currentEntries.delete(file2);
52539
52617
  }
52540
52618
  }
@@ -52560,7 +52638,7 @@ ${cleanBody}`;
52560
52638
  const indexStat = fs6.statSync(getSavedHistoryIndexFilePath(dir));
52561
52639
  const files = listHistoryFiles(dir);
52562
52640
  for (const file2 of files) {
52563
- const stat2 = fs6.statSync(path14.join(dir, file2));
52641
+ const stat2 = fs6.statSync(path15.join(dir, file2));
52564
52642
  if (stat2.mtimeMs > indexStat.mtimeMs) return true;
52565
52643
  }
52566
52644
  return false;
@@ -52570,14 +52648,14 @@ ${cleanBody}`;
52570
52648
  }
52571
52649
  function buildSavedHistoryFileSignature(dir, file2) {
52572
52650
  try {
52573
- const stat2 = fs6.statSync(path14.join(dir, file2));
52651
+ const stat2 = fs6.statSync(path15.join(dir, file2));
52574
52652
  return `${file2}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
52575
52653
  } catch {
52576
52654
  return `${file2}:missing`;
52577
52655
  }
52578
52656
  }
52579
52657
  function persistSavedHistoryFileSummaryEntry(agentType, dir, file2, updater) {
52580
- const filePath = path14.join(dir, file2);
52658
+ const filePath = path15.join(dir, file2);
52581
52659
  const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
52582
52660
  const currentEntry = entries.get(file2) || null;
52583
52661
  const nextSummary = updater(currentEntry?.summary || null);
@@ -52650,7 +52728,7 @@ ${cleanBody}`;
52650
52728
  function computeSavedHistoryFileSummary(dir, file2) {
52651
52729
  const historySessionId = extractSavedHistorySessionIdFromFile(file2);
52652
52730
  if (!historySessionId) return null;
52653
- const filePath = path14.join(dir, file2);
52731
+ const filePath = path15.join(dir, file2);
52654
52732
  const content = fs6.readFileSync(filePath, "utf-8");
52655
52733
  const lines = content.split("\n").filter(Boolean);
52656
52734
  let messageCount = 0;
@@ -52737,7 +52815,7 @@ ${cleanBody}`;
52737
52815
  const summaryBySessionId = /* @__PURE__ */ new Map();
52738
52816
  const nextPersistedEntries = /* @__PURE__ */ new Map();
52739
52817
  for (const file2 of files.slice().sort()) {
52740
- const filePath = path14.join(dir, file2);
52818
+ const filePath = path15.join(dir, file2);
52741
52819
  const signature = fileSignatures.get(file2) || `${file2}:missing`;
52742
52820
  const cached3 = savedHistoryFileSummaryCache.get(filePath);
52743
52821
  const persisted = persistedEntries.get(file2);
@@ -52857,12 +52935,12 @@ ${cleanBody}`;
52857
52935
  });
52858
52936
  }
52859
52937
  if (newMessages.length === 0) return;
52860
- const dir = path14.join(HISTORY_DIR, this.sanitize(agentType));
52938
+ const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
52861
52939
  fs6.mkdirSync(dir, { recursive: true });
52862
52940
  const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
52863
52941
  const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
52864
52942
  const fileName = `${filePrefix}${date5}.jsonl`;
52865
- const filePath = path14.join(dir, fileName);
52943
+ const filePath = path15.join(dir, fileName);
52866
52944
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
52867
52945
  fs6.appendFileSync(filePath, lines, "utf-8");
52868
52946
  updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
@@ -52953,11 +53031,11 @@ ${cleanBody}`;
52953
53031
  const ws = String(workspace || "").trim();
52954
53032
  if (!id || !ws) return;
52955
53033
  try {
52956
- const dir = path14.join(HISTORY_DIR, this.sanitize(agentType));
53034
+ const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
52957
53035
  fs6.mkdirSync(dir, { recursive: true });
52958
53036
  const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
52959
53037
  const fileName = `${this.sanitize(id)}_${date5}.jsonl`;
52960
- const filePath = path14.join(dir, fileName);
53038
+ const filePath = path15.join(dir, fileName);
52961
53039
  const record2 = {
52962
53040
  ts: (/* @__PURE__ */ new Date()).toISOString(),
52963
53041
  receivedAt: Date.now(),
@@ -53003,14 +53081,14 @@ ${cleanBody}`;
53003
53081
  this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
53004
53082
  this.lastSeenCounts.delete(fromDedupKey);
53005
53083
  }
53006
- const dir = path14.join(HISTORY_DIR, this.sanitize(agentType));
53084
+ const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
53007
53085
  if (!fs6.existsSync(dir)) return;
53008
53086
  const fromPrefix = `${this.sanitize(fromId)}_`;
53009
53087
  const toPrefix = `${this.sanitize(toId)}_`;
53010
53088
  const files = fs6.readdirSync(dir).filter((file2) => file2.startsWith(fromPrefix) && file2.endsWith(".jsonl"));
53011
53089
  for (const file2 of files) {
53012
- const sourcePath = path14.join(dir, file2);
53013
- const targetPath = path14.join(dir, `${toPrefix}${file2.slice(fromPrefix.length)}`);
53090
+ const sourcePath = path15.join(dir, file2);
53091
+ const targetPath = path15.join(dir, `${toPrefix}${file2.slice(fromPrefix.length)}`);
53014
53092
  const sourceLines = fs6.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
53015
53093
  const rewritten = sourceLines.map((line) => {
53016
53094
  try {
@@ -53044,13 +53122,13 @@ ${cleanBody}`;
53044
53122
  const sessionId = String(historySessionId || "").trim();
53045
53123
  if (!sessionId) return;
53046
53124
  try {
53047
- const dir = path14.join(HISTORY_DIR, this.sanitize(agentType));
53125
+ const dir = path15.join(HISTORY_DIR, this.sanitize(agentType));
53048
53126
  if (!fs6.existsSync(dir)) return;
53049
53127
  const prefix = `${this.sanitize(sessionId)}_`;
53050
53128
  const files = fs6.readdirSync(dir).filter((file2) => file2.startsWith(prefix) && file2.endsWith(".jsonl")).sort();
53051
53129
  const seen = /* @__PURE__ */ new Set();
53052
53130
  for (const file2 of files) {
53053
- const filePath = path14.join(dir, file2);
53131
+ const filePath = path15.join(dir, file2);
53054
53132
  const lines = fs6.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
53055
53133
  const next = [];
53056
53134
  for (const line of lines) {
@@ -53104,11 +53182,11 @@ ${cleanBody}`;
53104
53182
  const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
53105
53183
  const agentDirs = fs6.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
53106
53184
  for (const dir of agentDirs) {
53107
- const dirPath = path14.join(HISTORY_DIR, dir.name);
53185
+ const dirPath = path15.join(HISTORY_DIR, dir.name);
53108
53186
  const files = fs6.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
53109
53187
  let removedAny = false;
53110
53188
  for (const file2 of files) {
53111
- const filePath = path14.join(dirPath, file2);
53189
+ const filePath = path15.join(dirPath, file2);
53112
53190
  const stat2 = fs6.statSync(filePath);
53113
53191
  if (stat2.mtimeMs < cutoff) {
53114
53192
  fs6.unlinkSync(filePath);
@@ -53311,7 +53389,7 @@ ${cleanBody}`;
53311
53389
  const seen = /* @__PURE__ */ new Set();
53312
53390
  let readAllFiles = true;
53313
53391
  for (let f = 0; f < files.length; f++) {
53314
- const filePath = path14.join(dir, files[f]);
53392
+ const filePath = path15.join(dir, files[f]);
53315
53393
  const remaining = Math.max(0, needed - collected.length);
53316
53394
  const perFileNeeded = Math.min(needed, remaining + BOUNDED_TAIL_SLACK);
53317
53395
  const { lines, coversWholeFile } = readFileTailLines(filePath, perFileNeeded);
@@ -53344,7 +53422,7 @@ ${cleanBody}`;
53344
53422
  function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
53345
53423
  try {
53346
53424
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
53347
- const dir = path14.join(HISTORY_DIR, sanitized);
53425
+ const dir = path15.join(HISTORY_DIR, sanitized);
53348
53426
  if (!fs6.existsSync(dir)) return { messages: [], hasMore: false };
53349
53427
  const files = listHistoryFiles(dir, historySessionId);
53350
53428
  const bounded = isBoundedTailRequest(limit, offset, excludeRecentCount);
@@ -53367,7 +53445,7 @@ ${cleanBody}`;
53367
53445
  const allMessages = [];
53368
53446
  const seen = /* @__PURE__ */ new Set();
53369
53447
  for (const file2 of files) {
53370
- const filePath = path14.join(dir, file2);
53448
+ const filePath = path15.join(dir, file2);
53371
53449
  const content = fs6.readFileSync(filePath, "utf-8");
53372
53450
  const lines = content.trim().split("\n").filter(Boolean);
53373
53451
  for (let i = 0; i < lines.length; i++) {
@@ -53391,7 +53469,7 @@ ${cleanBody}`;
53391
53469
  function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
53392
53470
  try {
53393
53471
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
53394
- const dir = path14.join(HISTORY_DIR, sanitized);
53472
+ const dir = path15.join(HISTORY_DIR, sanitized);
53395
53473
  if (!fs6.existsSync(dir)) {
53396
53474
  savedHistorySessionCache.delete(sanitized);
53397
53475
  return { sessions: [], hasMore: false };
@@ -53452,11 +53530,11 @@ ${cleanBody}`;
53452
53530
  }
53453
53531
  function readExistingSessionStartRecord(agentType, historySessionId) {
53454
53532
  try {
53455
- const dir = path14.join(HISTORY_DIR, agentType);
53533
+ const dir = path15.join(HISTORY_DIR, agentType);
53456
53534
  if (!fs6.existsSync(dir)) return null;
53457
53535
  const files = listHistoryFiles(dir, historySessionId).sort();
53458
53536
  for (const file2 of files) {
53459
- const lines = fs6.readFileSync(path14.join(dir, file2), "utf-8").split("\n").filter(Boolean);
53537
+ const lines = fs6.readFileSync(path15.join(dir, file2), "utf-8").split("\n").filter(Boolean);
53460
53538
  for (const line of lines) {
53461
53539
  try {
53462
53540
  const parsed = JSON.parse(line);
@@ -53476,16 +53554,16 @@ ${cleanBody}`;
53476
53554
  function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
53477
53555
  if (records.length === 0) return false;
53478
53556
  try {
53479
- const dir = path14.join(HISTORY_DIR, agentType);
53557
+ const dir = path15.join(HISTORY_DIR, agentType);
53480
53558
  fs6.mkdirSync(dir, { recursive: true });
53481
53559
  const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
53482
53560
  for (const file2 of fs6.readdirSync(dir)) {
53483
53561
  if (file2.startsWith(prefix) && file2.endsWith(".jsonl")) {
53484
- fs6.unlinkSync(path14.join(dir, file2));
53562
+ fs6.unlinkSync(path15.join(dir, file2));
53485
53563
  }
53486
53564
  }
53487
53565
  const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
53488
- const filePath = path14.join(dir, `${prefix}${targetDate}.jsonl`);
53566
+ const filePath = path15.join(dir, `${prefix}${targetDate}.jsonl`);
53489
53567
  fs6.writeFileSync(filePath, `${records.map((record2) => JSON.stringify(record2)).join("\n")}
53490
53568
  `, "utf-8");
53491
53569
  invalidatePersistedSavedHistoryIndex(agentType, dir);
@@ -56044,7 +56122,7 @@ ${effect.notification.body || ""}`.trim();
56044
56122
  }
56045
56123
  var fs7 = __toESM2(require("fs"));
56046
56124
  var os9 = __toESM2(require("os"));
56047
- var path15 = __toESM2(require("path"));
56125
+ var path16 = __toESM2(require("path"));
56048
56126
  var import_node_crypto3 = require("crypto");
56049
56127
  init_contracts();
56050
56128
  init_logger();
@@ -57085,7 +57163,7 @@ ${effect.notification.body || ""}`.trim();
57085
57163
  function normalizeComparableWorkspace(value) {
57086
57164
  const text = typeof value === "string" ? value.trim() : "";
57087
57165
  if (!text) return "";
57088
- return path15.resolve(text);
57166
+ return path16.resolve(text);
57089
57167
  }
57090
57168
  function isCurrentRuntimePtySafelyAttributed(args) {
57091
57169
  if (args.adapter.cliType !== "codex-cli") return false;
@@ -57570,7 +57648,7 @@ ${effect.notification.body || ""}`.trim();
57570
57648
  }
57571
57649
  function getChatDebugBundleDir() {
57572
57650
  const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
57573
- return override || path15.join(os9.homedir(), ".adhdev", "debug-bundles", "chat");
57651
+ return override || path16.join(os9.homedir(), ".adhdev", "debug-bundles", "chat");
57574
57652
  }
57575
57653
  function safeBundleIdSegment(value, fallback) {
57576
57654
  const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
@@ -57627,7 +57705,7 @@ ${effect.notification.body || ""}`.trim();
57627
57705
  const bundleId = createChatDebugBundleId(targetSessionId);
57628
57706
  const dir = getChatDebugBundleDir();
57629
57707
  fs7.mkdirSync(dir, { recursive: true });
57630
- const savedPath = path15.join(dir, `${bundleId}.json`);
57708
+ const savedPath = path16.join(dir, `${bundleId}.json`);
57631
57709
  const json2 = `${JSON.stringify(bundle, null, 2)}
57632
57710
  `;
57633
57711
  fs7.writeFileSync(savedPath, json2, { encoding: "utf8", mode: 384 });
@@ -59189,7 +59267,7 @@ ${effect.notification.body || ""}`.trim();
59189
59267
  return { success: false, error: "resolveAction script not available for this provider" };
59190
59268
  }
59191
59269
  var fs8 = __toESM2(require("fs"));
59192
- var path16 = __toESM2(require("path"));
59270
+ var path17 = __toESM2(require("path"));
59193
59271
  var os10 = __toESM2(require("os"));
59194
59272
  var KEY_TO_VK = {
59195
59273
  Backspace: 8,
@@ -59446,25 +59524,25 @@ ${effect.notification.body || ""}`.trim();
59446
59524
  const inputPath = rawPath || ".";
59447
59525
  const home = os10.homedir();
59448
59526
  if (inputPath.startsWith("~")) {
59449
- return path16.resolve(path16.join(home, inputPath.slice(1)));
59527
+ return path17.resolve(path17.join(home, inputPath.slice(1)));
59450
59528
  }
59451
59529
  if (process.platform === "win32") {
59452
59530
  const normalized = normalizeWindowsRequestedPath(inputPath);
59453
- if (path16.win32.isAbsolute(normalized)) {
59454
- return path16.win32.normalize(normalized);
59531
+ if (path17.win32.isAbsolute(normalized)) {
59532
+ return path17.win32.normalize(normalized);
59455
59533
  }
59456
- return path16.win32.resolve(normalized);
59534
+ return path17.win32.resolve(normalized);
59457
59535
  }
59458
- if (path16.isAbsolute(inputPath)) {
59459
- return path16.normalize(inputPath);
59536
+ if (path17.isAbsolute(inputPath)) {
59537
+ return path17.normalize(inputPath);
59460
59538
  }
59461
- return path16.resolve(inputPath);
59539
+ return path17.resolve(inputPath);
59462
59540
  }
59463
59541
  function listDirectoryEntriesSafe(dirPath) {
59464
59542
  const entries = fs8.readdirSync(dirPath, { withFileTypes: true });
59465
59543
  const files = [];
59466
59544
  for (const entry of entries) {
59467
- const entryPath = path16.join(dirPath, entry.name);
59545
+ const entryPath = path17.join(dirPath, entry.name);
59468
59546
  try {
59469
59547
  if (entry.isDirectory()) {
59470
59548
  files.push({ name: entry.name, type: "directory" });
@@ -59518,7 +59596,7 @@ ${effect.notification.body || ""}`.trim();
59518
59596
  async function handleFileWrite(h, args) {
59519
59597
  try {
59520
59598
  const filePath = resolveSafePath(args?.path);
59521
- fs8.mkdirSync(path16.dirname(filePath), { recursive: true });
59599
+ fs8.mkdirSync(path17.dirname(filePath), { recursive: true });
59522
59600
  fs8.writeFileSync(filePath, args?.content || "", "utf-8");
59523
59601
  return { success: true, path: filePath };
59524
59602
  } catch (e) {
@@ -73220,6 +73298,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
73220
73298
  var import_path12 = require("path");
73221
73299
  var fs26 = __toESM2(require("fs"));
73222
73300
  var import_node_child_process6 = require("child_process");
73301
+ init_resolve_executable();
73223
73302
  var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
73224
73303
  var CHANNEL_SERVER_URL = {
73225
73304
  stable: "https://api.adhf.dev",
@@ -74318,6 +74397,18 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
74318
74397
  return `${text.slice(0, REFINE_VALIDATION_SUMMARY_CHARS)}
74319
74398
  [truncated ${text.length - REFINE_VALIDATION_SUMMARY_CHARS} chars]`;
74320
74399
  }
74400
+ function isSpawnResolutionError(error48) {
74401
+ if (!error48) return false;
74402
+ if (error48.code === "ENOENT" && typeof error48.syscall === "string" && error48.syscall.startsWith("spawn")) return true;
74403
+ return error48.code === "ENOENT" && (error48.syscall === void 0 || String(error48.syscall).startsWith("spawn"));
74404
+ }
74405
+ function describeSpawnError(error48, command, spawnResolutionFailed) {
74406
+ if (spawnResolutionFailed) {
74407
+ 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." : "";
74408
+ return `Could not resolve executable "${command}" (spawn ENOENT).${hint}`;
74409
+ }
74410
+ return String(error48?.message || error48);
74411
+ }
74321
74412
  function recordMeshRefineStage(stages, stage, status, startedAt, details) {
74322
74413
  stages.push({
74323
74414
  stage,
@@ -75219,8 +75310,9 @@ ${mergeTreeErr?.stderr || ""}`;
75219
75310
  const startedAt = Date.now();
75220
75311
  const cwd = candidate.cwd ? (0, import_path12.resolve)(workspace, candidate.cwd) : workspace;
75221
75312
  const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
75313
+ const resolvedCommand = resolveWin32Executable(candidate.command);
75222
75314
  try {
75223
- const result = await execFileAsync4(candidate.command, candidate.args, {
75315
+ const result = await execFileAsync4(resolvedCommand, candidate.args, {
75224
75316
  cwd,
75225
75317
  encoding: "utf8",
75226
75318
  timeout,
@@ -75229,16 +75321,17 @@ ${mergeTreeErr?.stderr || ""}`;
75229
75321
  });
75230
75322
  summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
75231
75323
  } catch (error48) {
75324
+ const spawnResolutionFailed = isSpawnResolutionError(error48);
75232
75325
  summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, error48, false, {
75233
75326
  exitCode: typeof error48?.code === "number" ? error48.code : null,
75234
75327
  signal: typeof error48?.signal === "string" ? error48.signal : null,
75235
75328
  timedOut: error48?.killed === true || /timed out/i.test(String(error48?.message || "")),
75236
- failureKind: "dependency_bootstrap_failed"
75329
+ ...spawnResolutionFailed ? { failureKind: "spawn_resolution_failed", resolvedCommand } : { failureKind: "dependency_bootstrap_failed" }
75237
75330
  }));
75238
- summary.bootstrap = { stage: "failed", error: String(error48?.message || error48) };
75331
+ summary.bootstrap = { stage: "failed", error: describeSpawnError(error48, candidate.command, spawnResolutionFailed) };
75239
75332
  summary.status = "failed";
75240
- summary.failureKind = "dependency_bootstrap_failed";
75241
- summary.failureCode = "dependency_bootstrap_failed";
75333
+ summary.failureKind = spawnResolutionFailed ? "spawn_resolution_failed" : "dependency_bootstrap_failed";
75334
+ summary.failureCode = spawnResolutionFailed ? "spawn_resolution_failed" : "dependency_bootstrap_failed";
75242
75335
  return summary;
75243
75336
  }
75244
75337
  }
@@ -75261,8 +75354,9 @@ ${mergeTreeErr?.stderr || ""}`;
75261
75354
  summary.failureCode = "missing_dependencies";
75262
75355
  return summary;
75263
75356
  }
75357
+ const resolvedCommand = resolveWin32Executable(candidate.command);
75264
75358
  try {
75265
- const result = await execFileAsync4(candidate.command, candidate.args, {
75359
+ const result = await execFileAsync4(resolvedCommand, candidate.args, {
75266
75360
  cwd,
75267
75361
  encoding: "utf8",
75268
75362
  timeout,
@@ -75271,16 +75365,21 @@ ${mergeTreeErr?.stderr || ""}`;
75271
75365
  });
75272
75366
  summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
75273
75367
  } catch (error48) {
75368
+ const spawnResolutionFailed = isSpawnResolutionError(error48);
75274
75369
  const stderr = truncateValidationOutput(error48?.stderr || error48?.message);
75275
- const missingDependencyFailure = /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
75370
+ const missingDependencyFailure = !spawnResolutionFailed && /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
75276
75371
  summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, error48, false, {
75277
75372
  exitCode: typeof error48?.code === "number" ? error48.code : null,
75278
75373
  signal: typeof error48?.signal === "string" ? error48.signal : null,
75279
75374
  timedOut: error48?.killed === true || /timed out/i.test(String(error48?.message || "")),
75280
- ...missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
75375
+ ...spawnResolutionFailed ? { failureKind: "spawn_resolution_failed", resolvedCommand } : missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
75281
75376
  }));
75282
75377
  summary.status = "failed";
75283
- if (missingDependencyFailure) {
75378
+ if (spawnResolutionFailed) {
75379
+ summary.failureKind = "spawn_resolution_failed";
75380
+ summary.failureCode = "spawn_resolution_failed";
75381
+ summary.spawnResolutionError = describeSpawnError(error48, candidate.command, true);
75382
+ } else if (missingDependencyFailure) {
75284
75383
  summary.failureKind = "missing_dependencies";
75285
75384
  summary.failureCode = "missing_dependencies";
75286
75385
  }
@@ -76541,7 +76640,7 @@ ${mergeTreeErr?.stderr || ""}`;
76541
76640
  if (validationSummary.status === "failed") {
76542
76641
  const firstFailedCmd = Array.isArray(validationSummary.commandsRun) ? validationSummary.commandsRun.find((c) => c.success === false) : void 0;
76543
76642
  const buildValidationFailedError = () => {
76544
- 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.";
76643
+ 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.";
76545
76644
  if (!firstFailedCmd) return base;
76546
76645
  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 : "";
76547
76646
  const rawOutput = [firstFailedCmd.stdout, firstFailedCmd.stderr, firstFailedCmd.output].filter((s) => typeof s === "string" && s.length > 0).join("\n");