@adhdev/daemon-core 0.9.82-rc.311 → 0.9.82-rc.312

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
@@ -316,10 +316,10 @@ function readInjected(value) {
316
316
  }
317
317
  function getDaemonBuildInfo() {
318
318
  if (cached) return cached;
319
- const commit = readInjected(true ? "3902f3d63eabe7b9e34d0e849dc0fed2fd66c026" : void 0) ?? "unknown";
320
- const commitShort = readInjected(true ? "3902f3d6" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
321
- const version = readInjected(true ? "0.9.82-rc.311" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
322
- const builtAt = readInjected(true ? "2026-06-17T12:17:11.243Z" : void 0);
319
+ const commit = readInjected(true ? "35facf0367dbbe37f25a3b5589287dc757ee6213" : void 0) ?? "unknown";
320
+ const commitShort = readInjected(true ? "35facf03" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
321
+ const version = readInjected(true ? "0.9.82-rc.312" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
322
+ const builtAt = readInjected(true ? "2026-06-17T22:48:50.124Z" : void 0);
323
323
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
324
324
  return cached;
325
325
  }
@@ -2118,6 +2118,7 @@ var init_coordinator_prompt = __esm({
2118
2118
  | \`mesh_read_debug\` | Collect a daemon-side chat/parser debug bundle for a session |
2119
2119
  | \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
2120
2120
  | \`mesh_git_status\` | Check git status on a specific node |
2121
+ | \`mesh_read_node_logs\` | Fetch a remote node's daemon log tail directly over P2P (grep/since/byte-bounded, secrets redacted) \u2014 no session/PowerShell needed to debug a node's daemon |
2121
2122
  | \`mesh_fast_forward_node\` | Safely dry-run or explicitly execute an obvious clean fast-forward without launching an agent session |
2122
2123
  | \`mesh_checkpoint\` | Create a git checkpoint on a node |
2123
2124
  | \`mesh_approve\` | Approve/reject a pending agent action |
@@ -5825,8 +5826,8 @@ function stripCoordinatorWrapperFile(filePath) {
5825
5826
  const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
5826
5827
  if (!remaining.trim()) {
5827
5828
  try {
5828
- const fs30 = require("fs");
5829
- fs30.unlinkSync(filePath);
5829
+ const fs31 = require("fs");
5830
+ fs31.unlinkSync(filePath);
5830
5831
  } catch {
5831
5832
  }
5832
5833
  } else {
@@ -10858,8 +10859,8 @@ var init_pty_transport = __esm({
10858
10859
  let cwd = options.cwd;
10859
10860
  if (cwd) {
10860
10861
  try {
10861
- const fs30 = require("fs");
10862
- const stat2 = fs30.statSync(cwd);
10862
+ const fs31 = require("fs");
10863
+ const stat2 = fs31.statSync(cwd);
10863
10864
  if (!stat2.isDirectory()) cwd = os11.homedir();
10864
10865
  } catch {
10865
10866
  cwd = os11.homedir();
@@ -10966,9 +10967,9 @@ function findBinary(name) {
10966
10967
  for (const ext of exes) {
10967
10968
  const fullPath = path17.join(p, trimmed + ext);
10968
10969
  try {
10969
- const fs30 = require("fs");
10970
- if (fs30.existsSync(fullPath)) {
10971
- const stat2 = fs30.statSync(fullPath);
10970
+ const fs31 = require("fs");
10971
+ if (fs31.existsSync(fullPath)) {
10972
+ const stat2 = fs31.statSync(fullPath);
10972
10973
  if (stat2.isFile() && (isWin || stat2.mode & 73)) {
10973
10974
  return fullPath;
10974
10975
  }
@@ -10982,12 +10983,12 @@ function findBinary(name) {
10982
10983
  function isScriptBinary(binaryPath) {
10983
10984
  if (!path17.isAbsolute(binaryPath)) return false;
10984
10985
  try {
10985
- const fs30 = require("fs");
10986
- const resolved = fs30.realpathSync(binaryPath);
10986
+ const fs31 = require("fs");
10987
+ const resolved = fs31.realpathSync(binaryPath);
10987
10988
  const head = Buffer.alloc(8);
10988
- const fd = fs30.openSync(resolved, "r");
10989
- fs30.readSync(fd, head, 0, 8, 0);
10990
- fs30.closeSync(fd);
10989
+ const fd = fs31.openSync(resolved, "r");
10990
+ fs31.readSync(fd, head, 0, 8, 0);
10991
+ fs31.closeSync(fd);
10991
10992
  let i = 0;
10992
10993
  if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
10993
10994
  return head[i] === 35 && head[i + 1] === 33;
@@ -10998,12 +10999,12 @@ function isScriptBinary(binaryPath) {
10998
10999
  function looksLikeMachOOrElf(filePath) {
10999
11000
  if (!path17.isAbsolute(filePath)) return false;
11000
11001
  try {
11001
- const fs30 = require("fs");
11002
- const resolved = fs30.realpathSync(filePath);
11002
+ const fs31 = require("fs");
11003
+ const resolved = fs31.realpathSync(filePath);
11003
11004
  const buf = Buffer.alloc(8);
11004
- const fd = fs30.openSync(resolved, "r");
11005
- fs30.readSync(fd, buf, 0, 8, 0);
11006
- fs30.closeSync(fd);
11005
+ const fd = fs31.openSync(resolved, "r");
11006
+ fs31.readSync(fd, buf, 0, 8, 0);
11007
+ fs31.closeSync(fd);
11007
11008
  let i = 0;
11008
11009
  if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
11009
11010
  const b = buf.subarray(i);
@@ -29841,7 +29842,7 @@ var DaemonCommandHandler = class {
29841
29842
  return { success: false, error: "invalid type" };
29842
29843
  }
29843
29844
  const https = require("https");
29844
- const fs30 = require("fs");
29845
+ const fs31 = require("fs");
29845
29846
  const path41 = require("path");
29846
29847
  const crypto6 = require("crypto");
29847
29848
  const REGISTRY = "https://api.adhf.dev/api/v1/registry";
@@ -29885,7 +29886,7 @@ var DaemonCommandHandler = class {
29885
29886
  if (!targetDir.startsWith(installRootResolved + path41.sep)) {
29886
29887
  return { success: false, error: "install path escaped upstream root" };
29887
29888
  }
29888
- fs30.mkdirSync(targetDir, { recursive: true });
29889
+ fs31.mkdirSync(targetDir, { recursive: true });
29889
29890
  let manifestProbe = {};
29890
29891
  try {
29891
29892
  manifestProbe = JSON.parse(manifestBody);
@@ -29910,7 +29911,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29910
29911
  }
29911
29912
  const targetFile = isV1 ? "provider.v1.json" : "provider.json";
29912
29913
  const targetPath = path41.join(targetDir, targetFile);
29913
- fs30.writeFileSync(targetPath, manifestBody, "utf-8");
29914
+ fs31.writeFileSync(targetPath, manifestBody, "utf-8");
29914
29915
  const manifestJson = JSON.parse(manifestBody);
29915
29916
  const scriptFetch = await this.fetchProviderSources(
29916
29917
  manifestJson,
@@ -29980,7 +29981,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29980
29981
  const repo = source.repo;
29981
29982
  const ref = source.ref;
29982
29983
  const https = require("https");
29983
- const fs30 = require("fs");
29984
+ const fs31 = require("fs");
29984
29985
  const path41 = require("path");
29985
29986
  function fetchJson(url, timeoutMs) {
29986
29987
  return new Promise((resolve24, reject) => {
@@ -30064,8 +30065,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
30064
30065
  const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
30065
30066
  const outPath = path41.resolve(path41.join(sharedTargetDir, relInside));
30066
30067
  if (!outPath.startsWith(path41.resolve(sharedTargetDir) + path41.sep)) continue;
30067
- fs30.mkdirSync(path41.dirname(outPath), { recursive: true });
30068
- fs30.writeFileSync(outPath, body);
30068
+ fs31.mkdirSync(path41.dirname(outPath), { recursive: true });
30069
+ fs31.writeFileSync(outPath, body);
30069
30070
  fetchedCount++;
30070
30071
  } catch (e) {
30071
30072
  errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
@@ -30103,8 +30104,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
30103
30104
  errors.push(`refusing to write outside targetDir: ${entry.path}`);
30104
30105
  continue;
30105
30106
  }
30106
- fs30.mkdirSync(path41.dirname(outPath), { recursive: true });
30107
- fs30.writeFileSync(outPath, body);
30107
+ fs31.mkdirSync(path41.dirname(outPath), { recursive: true });
30108
+ fs31.writeFileSync(outPath, body);
30108
30109
  fetchedCount++;
30109
30110
  } catch (e) {
30110
30111
  errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
@@ -30132,7 +30133,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
30132
30133
  if (!["cli", "ide", "extension", "acp"].includes(category)) {
30133
30134
  return { success: false, error: `unknown category: ${category}` };
30134
30135
  }
30135
- const fs30 = require("fs");
30136
+ const fs31 = require("fs");
30136
30137
  const path41 = require("path");
30137
30138
  try {
30138
30139
  const installRoot = this.getUpstreamInstallRoot();
@@ -30141,10 +30142,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
30141
30142
  if (!targetDir.startsWith(installRootResolved + path41.sep)) {
30142
30143
  return { success: false, error: "refusing to delete outside upstream root" };
30143
30144
  }
30144
- if (!fs30.existsSync(targetDir)) {
30145
+ if (!fs31.existsSync(targetDir)) {
30145
30146
  return { success: false, error: "not installed" };
30146
30147
  }
30147
- fs30.rmSync(targetDir, { recursive: true, force: true });
30148
+ fs31.rmSync(targetDir, { recursive: true, force: true });
30148
30149
  if (this._ctx.providerLoader) {
30149
30150
  this._ctx.providerLoader.reload();
30150
30151
  this._ctx.providerLoader.registerToDetector();
@@ -30160,28 +30161,28 @@ ${formatManifestValidationIssues2(validation.issues)}`,
30160
30161
  * the UI and by the update checker.
30161
30162
  */
30162
30163
  handleListInstalledProviders(_args) {
30163
- const fs30 = require("fs");
30164
+ const fs31 = require("fs");
30164
30165
  const path41 = require("path");
30165
30166
  const installRoot = this.getUpstreamInstallRoot();
30166
- if (!fs30.existsSync(installRoot)) return { success: true, providers: [] };
30167
+ if (!fs31.existsSync(installRoot)) return { success: true, providers: [] };
30167
30168
  const CATEGORIES = ["cli", "ide", "extension", "acp"];
30168
30169
  const items = [];
30169
30170
  for (const category of CATEGORIES) {
30170
30171
  const categoryDir = path41.join(installRoot, category);
30171
- if (!fs30.existsSync(categoryDir)) continue;
30172
+ if (!fs31.existsSync(categoryDir)) continue;
30172
30173
  let entries;
30173
30174
  try {
30174
- entries = fs30.readdirSync(categoryDir);
30175
+ entries = fs31.readdirSync(categoryDir);
30175
30176
  } catch {
30176
30177
  continue;
30177
30178
  }
30178
30179
  for (const type of entries) {
30179
30180
  const v1Path = path41.join(categoryDir, type, "provider.v1.json");
30180
30181
  const v0Path = path41.join(categoryDir, type, "provider.json");
30181
- const manifestPath = fs30.existsSync(v1Path) ? v1Path : fs30.existsSync(v0Path) ? v0Path : null;
30182
+ const manifestPath = fs31.existsSync(v1Path) ? v1Path : fs31.existsSync(v0Path) ? v0Path : null;
30182
30183
  if (!manifestPath) continue;
30183
30184
  try {
30184
- const m = JSON.parse(fs30.readFileSync(manifestPath, "utf-8"));
30185
+ const m = JSON.parse(fs31.readFileSync(manifestPath, "utf-8"));
30185
30186
  items.push({
30186
30187
  type,
30187
30188
  category,
@@ -30292,7 +30293,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
30292
30293
  if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
30293
30294
  return { success: false, error: "name must match @[a-z0-9_-]+" };
30294
30295
  }
30295
- const fs30 = require("fs");
30296
+ const fs31 = require("fs");
30296
30297
  const path41 = require("path");
30297
30298
  const { spawnSync: spawnSync2 } = require("child_process");
30298
30299
  const file = ext.loadExternalSources();
@@ -30303,8 +30304,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
30303
30304
  return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
30304
30305
  }
30305
30306
  const sourceDir = path41.join(ext.externalRoot(), requestedName);
30306
- if (!fs30.existsSync(ext.externalRoot())) fs30.mkdirSync(ext.externalRoot(), { recursive: true });
30307
- if (fs30.existsSync(sourceDir)) {
30307
+ if (!fs31.existsSync(ext.externalRoot())) fs31.mkdirSync(ext.externalRoot(), { recursive: true });
30308
+ if (fs31.existsSync(sourceDir)) {
30308
30309
  return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
30309
30310
  }
30310
30311
  const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
@@ -30314,7 +30315,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
30314
30315
  });
30315
30316
  if (clone.status !== 0) {
30316
30317
  try {
30317
- fs30.rmSync(sourceDir, { recursive: true, force: true });
30318
+ fs31.rmSync(sourceDir, { recursive: true, force: true });
30318
30319
  } catch {
30319
30320
  }
30320
30321
  return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
@@ -30358,15 +30359,15 @@ ${formatManifestValidationIssues2(validation.issues)}`,
30358
30359
  const name = typeof args?.name === "string" ? args.name.trim() : "";
30359
30360
  if (!name) return { success: false, error: "name is required" };
30360
30361
  const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
30361
- const fs30 = require("fs");
30362
+ const fs31 = require("fs");
30362
30363
  const path41 = require("path");
30363
30364
  const file = ext.loadExternalSources();
30364
30365
  const match = file.sources.find((s) => s.name === name);
30365
30366
  if (!match) return { success: false, error: `source "${name}" not registered` };
30366
30367
  const sourceDir = path41.join(ext.externalRoot(), name);
30367
- if (fs30.existsSync(sourceDir)) {
30368
+ if (fs31.existsSync(sourceDir)) {
30368
30369
  try {
30369
- fs30.rmSync(sourceDir, { recursive: true, force: true });
30370
+ fs31.rmSync(sourceDir, { recursive: true, force: true });
30370
30371
  } catch (e) {
30371
30372
  return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
30372
30373
  }
@@ -39478,7 +39479,7 @@ var ProviderLoader = class _ProviderLoader {
39478
39479
  }
39479
39480
  if (providerDir) {
39480
39481
  try {
39481
- const fs30 = require("fs");
39482
+ const fs31 = require("fs");
39482
39483
  const path41 = require("path");
39483
39484
  const candidates = [];
39484
39485
  if (Array.isArray(base.compatibility)) {
@@ -39490,13 +39491,13 @@ var ProviderLoader = class _ProviderLoader {
39490
39491
  }
39491
39492
  candidates.push(path41.join(providerDir, "specs", "default.json"));
39492
39493
  candidates.push(path41.join(providerDir, "spec.json"));
39493
- const specPath = candidates.find((p) => fs30.existsSync(p));
39494
+ const specPath = candidates.find((p) => fs31.existsSync(p));
39494
39495
  if (specPath) {
39495
39496
  resolved._resolvedSpecPath = specPath;
39496
39497
  let specControls;
39497
39498
  let nh;
39498
39499
  try {
39499
- const rawSpec = JSON.parse(fs30.readFileSync(specPath, "utf8"));
39500
+ const rawSpec = JSON.parse(fs31.readFileSync(specPath, "utf8"));
39500
39501
  specControls = rawSpec.control_bar;
39501
39502
  nh = rawSpec.native_history;
39502
39503
  } catch {
@@ -39521,7 +39522,7 @@ var ProviderLoader = class _ProviderLoader {
39521
39522
  reader = (input) => executeNativeHistory(nh, input);
39522
39523
  } else if (nh.override_path) {
39523
39524
  const overrideFile = path41.resolve(providerDir, nh.override_path);
39524
- if (fs30.existsSync(overrideFile)) {
39525
+ if (fs31.existsSync(overrideFile)) {
39525
39526
  try {
39526
39527
  registerProviderScriptRootSafely(path41.dirname(path41.dirname(providerDir)));
39527
39528
  delete require.cache[require.resolve(overrideFile)];
@@ -40706,7 +40707,7 @@ async function detectCurrentWorkspace(ideId) {
40706
40707
  }
40707
40708
  } else if (plat === "win32") {
40708
40709
  try {
40709
- const fs30 = require("fs");
40710
+ const fs31 = require("fs");
40710
40711
  const appNameMap = getMacAppIdentifiers();
40711
40712
  const appName = appNameMap[ideId];
40712
40713
  if (appName) {
@@ -40715,8 +40716,8 @@ async function detectCurrentWorkspace(ideId) {
40715
40716
  appName,
40716
40717
  "storage.json"
40717
40718
  );
40718
- if (fs30.existsSync(storagePath)) {
40719
- const data = JSON.parse(fs30.readFileSync(storagePath, "utf-8"));
40719
+ if (fs31.existsSync(storagePath)) {
40720
+ const data = JSON.parse(fs31.readFileSync(storagePath, "utf-8"));
40720
40721
  const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
40721
40722
  if (workspaces.length > 0) {
40722
40723
  const recent = workspaces[0];
@@ -41048,6 +41049,210 @@ cleanOldFiles();
41048
41049
  // src/commands/router.ts
41049
41050
  var yaml3 = __toESM(require("js-yaml"));
41050
41051
  init_logger();
41052
+
41053
+ // src/logging/log-tail-reader.ts
41054
+ var fs23 = __toESM(require("fs"));
41055
+ init_logger();
41056
+ var DEFAULT_TAIL_BYTES = 64 * 1024;
41057
+ var MAX_TAIL_BYTES = 128 * 1024;
41058
+ var READ_CHUNK_BYTES = 64 * 1024;
41059
+ function resolveLogPath(date) {
41060
+ if (date instanceof Date) return getCurrentDaemonLogPath(date);
41061
+ if (typeof date === "string" && date.trim()) {
41062
+ const parsed = /* @__PURE__ */ new Date(`${date.trim()}T00:00:00.000Z`);
41063
+ if (!Number.isNaN(parsed.getTime())) return getCurrentDaemonLogPath(parsed);
41064
+ }
41065
+ return getCurrentDaemonLogPath();
41066
+ }
41067
+ function clampTailBytes(tailBytes) {
41068
+ if (!Number.isFinite(tailBytes) || tailBytes <= 0) return DEFAULT_TAIL_BYTES;
41069
+ return Math.min(Math.floor(tailBytes), MAX_TAIL_BYTES);
41070
+ }
41071
+ function readByteBoundedTail(filePath, limitBytes) {
41072
+ const fd = fs23.openSync(filePath, "r");
41073
+ try {
41074
+ const stat2 = fs23.fstatSync(fd);
41075
+ const size = stat2.size;
41076
+ if (size === 0) return { text: "", truncated: false, bytesReturned: 0 };
41077
+ const want = Math.min(limitBytes, size);
41078
+ let start = size - want;
41079
+ const truncated = start > 0;
41080
+ const buffers = [];
41081
+ let position = start;
41082
+ while (position < size) {
41083
+ const chunkSize = Math.min(READ_CHUNK_BYTES, size - position);
41084
+ const chunk = Buffer.alloc(chunkSize);
41085
+ fs23.readSync(fd, chunk, 0, chunkSize, position);
41086
+ buffers.push(chunk);
41087
+ position += chunkSize;
41088
+ }
41089
+ let buf = Buffer.concat(buffers);
41090
+ if (truncated) {
41091
+ const firstNewline = buf.indexOf(10);
41092
+ if (firstNewline >= 0) {
41093
+ buf = buf.subarray(firstNewline + 1);
41094
+ }
41095
+ }
41096
+ return { text: buf.toString("utf-8"), truncated, bytesReturned: buf.length };
41097
+ } finally {
41098
+ fs23.closeSync(fd);
41099
+ }
41100
+ }
41101
+ function parseLineEpochMs(line, fileDate) {
41102
+ const m = line.match(/^\[(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?\]/);
41103
+ if (!m) {
41104
+ const iso = line.match(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?/);
41105
+ if (iso) {
41106
+ const t = Date.parse(iso[0].replace(" ", "T"));
41107
+ return Number.isNaN(t) ? null : t;
41108
+ }
41109
+ return null;
41110
+ }
41111
+ const d = new Date(fileDate);
41112
+ d.setHours(Number(m[1]), Number(m[2]), Number(m[3]), m[4] ? Number(m[4].padEnd(3, "0")) : 0);
41113
+ return d.getTime();
41114
+ }
41115
+ function readDaemonLogTail(args = {}) {
41116
+ const platform10 = process.platform;
41117
+ const limitBytes = clampTailBytes(args.tailBytes);
41118
+ let logPath = resolveLogPath(args.date);
41119
+ if (!fs23.existsSync(logPath)) {
41120
+ const backup = logPath.replace(/\.log$/, ".1.log");
41121
+ if (fs23.existsSync(backup)) {
41122
+ logPath = backup;
41123
+ } else {
41124
+ return {
41125
+ success: false,
41126
+ error: `No daemon log file at ${logPath} (dir: ${getDaemonLogDir()})`,
41127
+ lines: [],
41128
+ truncated: false,
41129
+ logPath,
41130
+ platform: platform10,
41131
+ bytesReturned: 0,
41132
+ filtered: false
41133
+ };
41134
+ }
41135
+ }
41136
+ let raw;
41137
+ try {
41138
+ raw = readByteBoundedTail(logPath, limitBytes);
41139
+ } catch (e) {
41140
+ return {
41141
+ success: false,
41142
+ error: `Failed to read ${logPath}: ${e?.message ?? String(e)}`,
41143
+ lines: [],
41144
+ truncated: false,
41145
+ logPath,
41146
+ platform: platform10,
41147
+ bytesReturned: 0,
41148
+ filtered: false
41149
+ };
41150
+ }
41151
+ let lines = raw.text.split("\n");
41152
+ if (lines.length && lines[lines.length - 1] === "") lines.pop();
41153
+ const rawCount = lines.length;
41154
+ if (Number.isFinite(args.sinceMs)) {
41155
+ const fileDate = args.date instanceof Date ? args.date : typeof args.date === "string" && args.date.trim() ? /* @__PURE__ */ new Date(`${args.date.trim()}T00:00:00.000Z`) : /* @__PURE__ */ new Date();
41156
+ const floor = args.sinceMs;
41157
+ lines = lines.filter((line) => {
41158
+ const ts2 = parseLineEpochMs(line, fileDate);
41159
+ return ts2 === null || ts2 >= floor;
41160
+ });
41161
+ }
41162
+ let appliedGrep;
41163
+ if (typeof args.grep === "string" && args.grep.trim()) {
41164
+ appliedGrep = args.grep.trim();
41165
+ let re = null;
41166
+ try {
41167
+ re = new RegExp(appliedGrep, "i");
41168
+ } catch {
41169
+ re = null;
41170
+ }
41171
+ if (re) {
41172
+ const compiled = re;
41173
+ lines = lines.filter((line) => compiled.test(line));
41174
+ } else {
41175
+ const needle = appliedGrep.toLowerCase();
41176
+ lines = lines.filter((line) => line.toLowerCase().includes(needle));
41177
+ }
41178
+ }
41179
+ return {
41180
+ success: true,
41181
+ lines,
41182
+ truncated: raw.truncated,
41183
+ logPath,
41184
+ platform: platform10,
41185
+ bytesReturned: raw.bytesReturned,
41186
+ filtered: lines.length !== rawCount,
41187
+ ...appliedGrep ? { grep: appliedGrep } : {}
41188
+ };
41189
+ }
41190
+
41191
+ // src/logging/log-redactor.ts
41192
+ var MASK = "\u2022\u2022\u2022\u2022redacted";
41193
+ function maskKeepTail(token) {
41194
+ if (token.length <= 8) return MASK;
41195
+ return `${MASK}${token.slice(-4)}`;
41196
+ }
41197
+ var RULES = [
41198
+ // `JWT_SECRET=...`, `TOKEN=...`, `API_KEY=...`, `password: ...` env/config dumps.
41199
+ // Captures the key + delimiter and masks only the value.
41200
+ {
41201
+ name: "key_value_secret",
41202
+ pattern: /\b([A-Z0-9_]*(?:SECRET|TOKEN|API[_-]?KEY|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CREDENTIAL|CLIENT[_-]?SECRET)[A-Z0-9_]*)(\s*[:=]\s*)(["']?)([^\s"',;]+)\3/gi,
41203
+ replace: (_m, key, delim, quote) => `${key}${delim}${quote}${MASK}${quote}`
41204
+ },
41205
+ // Authorization: Bearer <token>
41206
+ {
41207
+ name: "bearer_token",
41208
+ pattern: /\b(Bearer\s+)([A-Za-z0-9._\-+/=]{8,})/g,
41209
+ replace: (_m, prefix, token) => `${prefix}${maskKeepTail(token)}`
41210
+ },
41211
+ // ADHDev credential prefixes: API key (adk_), machine secret (adm_), provider key (adp_).
41212
+ {
41213
+ name: "adhdev_prefixed_secret",
41214
+ pattern: /\b(ad[kmp]_)([A-Za-z0-9]{6,})/g,
41215
+ replace: (_m, prefix, token) => `${prefix}${maskKeepTail(prefix + token)}`
41216
+ },
41217
+ // JWT: three base64url segments separated by dots, header starts with eyJ.
41218
+ {
41219
+ name: "jwt",
41220
+ pattern: /\beyJ[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}/g,
41221
+ replace: () => MASK
41222
+ },
41223
+ // TURN credential: a long credential value following a `credential` key in
41224
+ // any common shape — `credential: x`, `credential=x`, or `credential "x"`.
41225
+ // Mask the credential value only, preserving the key + delimiter/quote.
41226
+ {
41227
+ name: "turn_credential",
41228
+ pattern: /\b(credential["']?\s*(?:[:=]\s*)?["']?)([^\s"',;]{6,})/gi,
41229
+ replace: (_m, prefix) => `${prefix}${MASK}`
41230
+ },
41231
+ // TURN REST username:credential of the form `<expiry-ts>:<base64hmac>`,
41232
+ // where the hmac part is long base64. Mask the hmac.
41233
+ {
41234
+ name: "turn_rest_pair",
41235
+ pattern: /\b(\d{10,}:)([A-Za-z0-9+/]{20,}={0,2})\b/g,
41236
+ replace: (_m, prefix) => `${prefix}${MASK}`
41237
+ }
41238
+ ];
41239
+ function redactLogLine(line) {
41240
+ if (!line) return line;
41241
+ let out = line;
41242
+ for (const rule of RULES) {
41243
+ try {
41244
+ out = out.replace(rule.pattern, rule.replace);
41245
+ } catch {
41246
+ }
41247
+ }
41248
+ return out;
41249
+ }
41250
+ function redactLogLines(lines) {
41251
+ return lines.map((line) => redactLogLine(line));
41252
+ }
41253
+ var LOG_REDACTION_RULE_NAMES = RULES.map((r) => r.name);
41254
+
41255
+ // src/commands/router.ts
41051
41256
  init_mesh_coordinator();
41052
41257
  init_mesh_events();
41053
41258
  init_mesh_routing();
@@ -41692,21 +41897,21 @@ init_build_info();
41692
41897
  // src/commands/upgrade-helper.ts
41693
41898
  var import_child_process8 = require("child_process");
41694
41899
  var import_child_process9 = require("child_process");
41695
- var fs23 = __toESM(require("fs"));
41900
+ var fs24 = __toESM(require("fs"));
41696
41901
  var os27 = __toESM(require("os"));
41697
41902
  var path35 = __toESM(require("path"));
41698
41903
  var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
41699
41904
  function getUpgradeLogPath() {
41700
41905
  const home = os27.homedir();
41701
41906
  const dir = path35.join(home, ".adhdev");
41702
- fs23.mkdirSync(dir, { recursive: true });
41907
+ fs24.mkdirSync(dir, { recursive: true });
41703
41908
  return path35.join(dir, "daemon-upgrade.log");
41704
41909
  }
41705
41910
  function appendUpgradeLog(message) {
41706
41911
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
41707
41912
  `;
41708
41913
  try {
41709
- fs23.appendFileSync(getUpgradeLogPath(), line, "utf8");
41914
+ fs24.appendFileSync(getUpgradeLogPath(), line, "utf8");
41710
41915
  } catch {
41711
41916
  }
41712
41917
  }
@@ -41714,12 +41919,12 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
41714
41919
  const binDir = path35.dirname(nodeExecutable);
41715
41920
  if (platform10 === "win32") {
41716
41921
  const npmCliPath = path35.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
41717
- if (fs23.existsSync(npmCliPath)) {
41922
+ if (fs24.existsSync(npmCliPath)) {
41718
41923
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
41719
41924
  }
41720
41925
  for (const candidate of ["npm.exe", "npm"]) {
41721
41926
  const candidatePath = path35.join(binDir, candidate);
41722
- if (fs23.existsSync(candidatePath)) {
41927
+ if (fs24.existsSync(candidatePath)) {
41723
41928
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
41724
41929
  }
41725
41930
  }
@@ -41727,7 +41932,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
41727
41932
  }
41728
41933
  for (const candidate of ["npm"]) {
41729
41934
  const candidatePath = path35.join(binDir, candidate);
41730
- if (fs23.existsSync(candidatePath)) {
41935
+ if (fs24.existsSync(candidatePath)) {
41731
41936
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
41732
41937
  }
41733
41938
  }
@@ -41737,12 +41942,12 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
41737
41942
  if (!currentCliPath) return null;
41738
41943
  let resolvedPath = currentCliPath;
41739
41944
  try {
41740
- resolvedPath = fs23.realpathSync.native(currentCliPath);
41945
+ resolvedPath = fs24.realpathSync.native(currentCliPath);
41741
41946
  } catch {
41742
41947
  }
41743
41948
  let currentDir = resolvedPath;
41744
41949
  try {
41745
- if (fs23.statSync(resolvedPath).isFile()) {
41950
+ if (fs24.statSync(resolvedPath).isFile()) {
41746
41951
  currentDir = path35.dirname(resolvedPath);
41747
41952
  }
41748
41953
  } catch {
@@ -41751,8 +41956,8 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
41751
41956
  while (true) {
41752
41957
  const packageJsonPath = path35.join(currentDir, "package.json");
41753
41958
  try {
41754
- if (fs23.existsSync(packageJsonPath)) {
41755
- const parsed = JSON.parse(fs23.readFileSync(packageJsonPath, "utf8"));
41959
+ if (fs24.existsSync(packageJsonPath)) {
41960
+ const parsed = JSON.parse(fs24.readFileSync(packageJsonPath, "utf8"));
41756
41961
  if (parsed?.name === packageName) {
41757
41962
  const normalized = currentDir.replace(/\\/g, "/");
41758
41963
  return normalized.includes("/node_modules/") ? currentDir : null;
@@ -41901,8 +42106,8 @@ async function waitForPidExit(pid, timeoutMs) {
41901
42106
  function stopSessionHostProcesses(appName) {
41902
42107
  const pidFile = path35.join(os27.homedir(), ".adhdev", `${appName}-session-host.pid`);
41903
42108
  try {
41904
- if (fs23.existsSync(pidFile)) {
41905
- const pid = Number.parseInt(fs23.readFileSync(pidFile, "utf8").trim(), 10);
42109
+ if (fs24.existsSync(pidFile)) {
42110
+ const pid = Number.parseInt(fs24.readFileSync(pidFile, "utf8").trim(), 10);
41906
42111
  if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
41907
42112
  killPid(pid);
41908
42113
  }
@@ -41910,7 +42115,7 @@ function stopSessionHostProcesses(appName) {
41910
42115
  } catch {
41911
42116
  } finally {
41912
42117
  try {
41913
- fs23.unlinkSync(pidFile);
42118
+ fs24.unlinkSync(pidFile);
41914
42119
  } catch {
41915
42120
  }
41916
42121
  }
@@ -41918,7 +42123,7 @@ function stopSessionHostProcesses(appName) {
41918
42123
  function removeDaemonPidFile() {
41919
42124
  const pidFile = path35.join(os27.homedir(), ".adhdev", "daemon.pid");
41920
42125
  try {
41921
- fs23.unlinkSync(pidFile);
42126
+ fs24.unlinkSync(pidFile);
41922
42127
  } catch {
41923
42128
  }
41924
42129
  }
@@ -41936,23 +42141,23 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
41936
42141
  if (pkgName.startsWith("@")) {
41937
42142
  const [scope, name] = pkgName.split("/");
41938
42143
  const scopeDir = path35.join(npmRoot, scope);
41939
- if (!fs23.existsSync(scopeDir)) return;
41940
- for (const entry of fs23.readdirSync(scopeDir)) {
42144
+ if (!fs24.existsSync(scopeDir)) return;
42145
+ for (const entry of fs24.readdirSync(scopeDir)) {
41941
42146
  if (!entry.startsWith(`.${name}-`)) continue;
41942
- fs23.rmSync(path35.join(scopeDir, entry), { recursive: true, force: true });
42147
+ fs24.rmSync(path35.join(scopeDir, entry), { recursive: true, force: true });
41943
42148
  appendUpgradeLog(`Removed stale scoped staging dir: ${path35.join(scopeDir, entry)}`);
41944
42149
  }
41945
42150
  } else {
41946
- for (const entry of fs23.readdirSync(npmRoot)) {
42151
+ for (const entry of fs24.readdirSync(npmRoot)) {
41947
42152
  if (!entry.startsWith(`.${pkgName}-`)) continue;
41948
- fs23.rmSync(path35.join(npmRoot, entry), { recursive: true, force: true });
42153
+ fs24.rmSync(path35.join(npmRoot, entry), { recursive: true, force: true });
41949
42154
  appendUpgradeLog(`Removed stale staging dir: ${path35.join(npmRoot, entry)}`);
41950
42155
  }
41951
42156
  }
41952
- if (fs23.existsSync(binDir)) {
41953
- for (const entry of fs23.readdirSync(binDir)) {
42157
+ if (fs24.existsSync(binDir)) {
42158
+ for (const entry of fs24.readdirSync(binDir)) {
41954
42159
  if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
41955
- fs23.rmSync(path35.join(binDir, entry), { recursive: true, force: true });
42160
+ fs24.rmSync(path35.join(binDir, entry), { recursive: true, force: true });
41956
42161
  appendUpgradeLog(`Removed stale bin staging entry: ${path35.join(binDir, entry)}`);
41957
42162
  }
41958
42163
  }
@@ -42043,7 +42248,7 @@ init_mesh_work_queue();
42043
42248
  init_repo_mesh_types();
42044
42249
  var import_os3 = require("os");
42045
42250
  var import_path11 = require("path");
42046
- var fs24 = __toESM(require("fs"));
42251
+ var fs25 = __toESM(require("fs"));
42047
42252
  var import_node_child_process6 = require("child_process");
42048
42253
  var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
42049
42254
  var CHANNEL_SERVER_URL = {
@@ -42369,6 +42574,12 @@ function inlineMeshCarriesTransientNodeTruth(inlineMesh) {
42369
42574
  function readInlineMeshNodeId(node) {
42370
42575
  return normalizeMeshNodeId(node) ?? "";
42371
42576
  }
42577
+ function isDeadLocalWorktreeNode(node) {
42578
+ if (node?.isLocalWorktree !== true) return false;
42579
+ const workspace = readStringValue(node?.workspace);
42580
+ if (!workspace) return false;
42581
+ return !fs25.existsSync(workspace);
42582
+ }
42372
42583
  function foldMeshNodeIdentityToCanonical(node) {
42373
42584
  if (!node || typeof node !== "object" || Array.isArray(node)) return node;
42374
42585
  const canonical = normalizeMeshNodeId(node);
@@ -42615,7 +42826,7 @@ function summarizeInlineMeshBranchConvergence(nodes) {
42615
42826
  const followUps = nodes.filter((node) => {
42616
42827
  if (readObjectRecord(node.branchConvergence).needsConvergence !== true) return false;
42617
42828
  const workspace = typeof node.workspace === "string" ? node.workspace : "";
42618
- if (workspace && !fs24.existsSync(workspace)) return false;
42829
+ if (workspace && !fs25.existsSync(workspace)) return false;
42619
42830
  return true;
42620
42831
  }).map((node) => {
42621
42832
  const convergence = readObjectRecord(node.branchConvergence);
@@ -42823,7 +43034,8 @@ async function hydrateInlineMeshDirectTruth(args) {
42823
43034
  peerAttemptedCount: 0,
42824
43035
  peerConfirmedCount: 0,
42825
43036
  standingEvidenceCount: 0,
42826
- unavailableNodeIds: []
43037
+ unavailableNodeIds: [],
43038
+ deadNodeIds: []
42827
43039
  };
42828
43040
  }
42829
43041
  const selectedCoordinatorNodeId = readStringValue(
@@ -42836,6 +43048,7 @@ async function hydrateInlineMeshDirectTruth(args) {
42836
43048
  let peerConfirmedCount = 0;
42837
43049
  let standingEvidenceCount = 0;
42838
43050
  const unavailableNodeIds = [];
43051
+ const deadNodeIds = [];
42839
43052
  for (const [nodeIndex, node] of nodes.entries()) {
42840
43053
  const nodeId = normalizeMeshNodeId(node) || `node_${nodeIndex}`;
42841
43054
  const workspace = readStringValue(node?.workspace);
@@ -42845,11 +43058,18 @@ async function hydrateInlineMeshDirectTruth(args) {
42845
43058
  ) || Boolean(
42846
43059
  daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
42847
43060
  ) || Boolean(args.meshSource !== "local_config" && nodeIndex === 0);
43061
+ const isSelfDaemonNode = Boolean(
43062
+ daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
43063
+ );
43064
+ if ((isSelfNode || isSelfDaemonNode) && isDeadLocalWorktreeNode(node)) {
43065
+ deadNodeIds.push(nodeId);
43066
+ continue;
43067
+ }
42848
43068
  if (!workspace) {
42849
43069
  if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
42850
43070
  continue;
42851
43071
  }
42852
- if (fs24.existsSync(workspace)) {
43072
+ if (fs25.existsSync(workspace)) {
42853
43073
  try {
42854
43074
  const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
42855
43075
  if (localGit?.isGitRepo) {
@@ -42895,7 +43115,8 @@ async function hydrateInlineMeshDirectTruth(args) {
42895
43115
  peerAttemptedCount,
42896
43116
  peerConfirmedCount,
42897
43117
  standingEvidenceCount,
42898
- unavailableNodeIds
43118
+ unavailableNodeIds,
43119
+ deadNodeIds
42899
43120
  };
42900
43121
  }
42901
43122
  function summarizeMeshSessionRecord(record) {
@@ -42954,7 +43175,7 @@ function readLiveMeshNodeWorkspace(args) {
42954
43175
  }
42955
43176
  function collectLiveMeshSessionRecords(args) {
42956
43177
  const nodeWorkspace = readStringValue(args.node?.workspace);
42957
- const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs24.existsSync(nodeWorkspace);
43178
+ const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs25.existsSync(nodeWorkspace);
42958
43179
  const matches = args.liveSessionRecords.filter((record) => {
42959
43180
  const recordNodeId = readStringValue(record?.meta?.meshNodeId);
42960
43181
  if (recordNodeId && recordNodeId !== args.nodeId) return false;
@@ -42981,7 +43202,7 @@ function buildHistoricalMeshSessions(args) {
42981
43202
  const workspace = readStringValue(node?.workspace);
42982
43203
  if (nodeId) liveNodeIds.add(nodeId);
42983
43204
  if (workspace) liveWorkspaces.add(workspace);
42984
- if (nodeId && node?.isLocalWorktree === true && workspace && !fs24.existsSync(workspace)) {
43205
+ if (nodeId && node?.isLocalWorktree === true && workspace && !fs25.existsSync(workspace)) {
42985
43206
  missingLocalWorktreeNodeIds.add(nodeId);
42986
43207
  }
42987
43208
  }
@@ -43341,7 +43562,7 @@ function isSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit) {
43341
43562
  if (!baseCommit || !branchCommit) return false;
43342
43563
  if (baseCommit === branchCommit) return true;
43343
43564
  try {
43344
- if (!fs24.existsSync(submoduleRepoPath)) return false;
43565
+ if (!fs25.existsSync(submoduleRepoPath)) return false;
43345
43566
  (0, import_node_child_process6.execFileSync)("git", ["cat-file", "-e", `${baseCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
43346
43567
  (0, import_node_child_process6.execFileSync)("git", ["cat-file", "-e", `${branchCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
43347
43568
  (0, import_node_child_process6.execFileSync)("git", ["merge-base", "--is-ancestor", baseCommit, branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
@@ -43458,7 +43679,7 @@ function buildTreeWithGitlinksEqualized(repoRoot, commitish, paths, placeholderC
43458
43679
  return newTree || void 0;
43459
43680
  } finally {
43460
43681
  try {
43461
- fs24.rmSync(tmpIndex, { force: true });
43682
+ fs25.rmSync(tmpIndex, { force: true });
43462
43683
  } catch {
43463
43684
  }
43464
43685
  }
@@ -43533,7 +43754,7 @@ function synthesizeTrivialFastForwardMergeTree(repoRoot, baseHead, branchHead, g
43533
43754
  return newTree || void 0;
43534
43755
  } finally {
43535
43756
  try {
43536
- fs24.rmSync(tmpIndex, { force: true });
43757
+ fs25.rmSync(tmpIndex, { force: true });
43537
43758
  } catch {
43538
43759
  }
43539
43760
  }
@@ -43639,7 +43860,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
43639
43860
  return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
43640
43861
  };
43641
43862
  const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
43642
- if (!fs24.existsSync(worktreeSubmodulePath)) return false;
43863
+ if (!fs25.existsSync(worktreeSubmodulePath)) return false;
43643
43864
  try {
43644
43865
  await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
43645
43866
  } catch {
@@ -43662,7 +43883,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
43662
43883
  reachable: false
43663
43884
  };
43664
43885
  try {
43665
- if (!fs24.existsSync(submodulePath)) {
43886
+ if (!fs25.existsSync(submodulePath)) {
43666
43887
  entry.error = `Submodule checkout missing at ${gitlink.path}`;
43667
43888
  entry.publishRequired = true;
43668
43889
  if (options.allowAutoPublishSubmoduleMainCommits === true) {
@@ -43899,9 +44120,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
43899
44120
  return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
43900
44121
  };
43901
44122
  const dependenciesLikelyMissing = (cwd) => {
43902
- if (!fs24.existsSync((0, import_path11.join)(cwd, "package.json"))) return false;
43903
- if (fs24.existsSync((0, import_path11.join)(cwd, "node_modules"))) return false;
43904
- return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs24.existsSync((0, import_path11.join)(cwd, lock)));
44123
+ if (!fs25.existsSync((0, import_path11.join)(cwd, "package.json"))) return false;
44124
+ if (fs25.existsSync((0, import_path11.join)(cwd, "node_modules"))) return false;
44125
+ return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs25.existsSync((0, import_path11.join)(cwd, lock)));
43905
44126
  };
43906
44127
  if (runLegacyBootstrapCommands) {
43907
44128
  summary.bootstrap = { stage: "legacy" };
@@ -44003,9 +44224,9 @@ function resolveHermesUserHome() {
44003
44224
  function loadHermesCoordinatorBaseConfig(targetConfigPath) {
44004
44225
  const sourceHome = resolveHermesUserHome();
44005
44226
  const sourceConfigPath = (0, import_path11.join)(sourceHome, "config.yaml");
44006
- if (!fs24.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
44227
+ if (!fs25.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
44007
44228
  if ((0, import_path11.resolve)(sourceConfigPath) === (0, import_path11.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
44008
- const parsed = parseMeshCoordinatorMcpConfig(fs24.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
44229
+ const parsed = parseMeshCoordinatorMcpConfig(fs25.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
44009
44230
  const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
44010
44231
  return { config: baseConfig, sourceHome, sourceConfigPath };
44011
44232
  }
@@ -44042,9 +44263,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
44042
44263
  for (const fileName of [".env", "auth.json"]) {
44043
44264
  const sourcePath = (0, import_path11.join)(sourceHome, fileName);
44044
44265
  const targetPath = (0, import_path11.join)(targetHome, fileName);
44045
- if (!fs24.existsSync(sourcePath)) continue;
44266
+ if (!fs25.existsSync(sourcePath)) continue;
44046
44267
  try {
44047
- fs24.copyFileSync(sourcePath, targetPath);
44268
+ fs25.copyFileSync(sourcePath, targetPath);
44048
44269
  } catch (error) {
44049
44270
  LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
44050
44271
  }
@@ -44202,6 +44423,15 @@ var DaemonCommandRouter = class {
44202
44423
  * Allows the MCP server to query mesh data via get_mesh even when
44203
44424
  * the mesh doesn't exist in the local meshes.json file. */
44204
44425
  inlineMeshCache = /* @__PURE__ */ new Map();
44426
+ /** Tombstones for inline mesh nodes removed via remove_mesh_node, keyed by
44427
+ * meshId → set of removed nodeIds. The dashboard keeps echoing the removed
44428
+ * node in the inlineMesh it attaches to every command; without a tombstone,
44429
+ * reconcileInlineMeshCache MERGEs it straight back (resurrection). A
44430
+ * tombstoned node is skipped during reconcile only while its workspace is
44431
+ * absent from disk — a genuine re-registration (same nodeId, workspace back
44432
+ * on disk) clears the tombstone and merges normally, preserving clone
44433
+ * worktree visibility and legitimate node re-creation. */
44434
+ removedInlineMeshNodeIds = /* @__PURE__ */ new Map();
44205
44435
  /** Coordinator-owned whole-mesh aggregate status snapshots. Browser callers read this by default. */
44206
44436
  aggregateMeshStatusCache = /* @__PURE__ */ new Map();
44207
44437
  /** Shared per-peer git_status probe dedup + recently-probed reuse gate.
@@ -44235,10 +44465,23 @@ var DaemonCommandRouter = class {
44235
44465
  const unavailableNodeIds = /* @__PURE__ */ new Set();
44236
44466
  const sourceOfTruth = readObjectRecord(snapshot.sourceOfTruth);
44237
44467
  const directPeerTruth = readObjectRecord(sourceOfTruth.directPeerTruth);
44468
+ const deadNodeIds = /* @__PURE__ */ new Set();
44469
+ for (const node of mesh.nodes) {
44470
+ if (!isDeadLocalWorktreeNode(node)) continue;
44471
+ const deadId = readInlineMeshNodeId(node);
44472
+ if (deadId) deadNodeIds.add(deadId);
44473
+ }
44474
+ let droppedDeadUnavailable = false;
44238
44475
  for (const entry of Array.isArray(directPeerTruth.unavailableNodeIds) ? directPeerTruth.unavailableNodeIds : []) {
44239
44476
  const nodeId = readStringValue(entry);
44240
- if (nodeId) unavailableNodeIds.add(nodeId);
44477
+ if (!nodeId) continue;
44478
+ if (deadNodeIds.has(nodeId)) {
44479
+ droppedDeadUnavailable = true;
44480
+ continue;
44481
+ }
44482
+ unavailableNodeIds.add(nodeId);
44241
44483
  }
44484
+ if (droppedDeadUnavailable) changed = true;
44242
44485
  const nodes = snapshot.nodes.map((statusNode) => {
44243
44486
  const nodeId = normalizeMeshNodeId(statusNode);
44244
44487
  const inlineNode = nodeId ? inlineNodesById.get(nodeId) : void 0;
@@ -44353,7 +44596,10 @@ var DaemonCommandRouter = class {
44353
44596
  }
44354
44597
  warmInlineMeshCache(meshId, inlineMesh) {
44355
44598
  if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
44356
- const sanitizedInlineMesh = sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh));
44599
+ const sanitizedInlineMesh = this.applyInlineMeshNodeTombstones(
44600
+ meshId,
44601
+ sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh))
44602
+ );
44357
44603
  const cached2 = this.inlineMeshCache.get(meshId);
44358
44604
  if (cached2) {
44359
44605
  const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
@@ -44369,7 +44615,10 @@ var DaemonCommandRouter = class {
44369
44615
  const cached3 = this.getCachedInlineMesh(meshId);
44370
44616
  if (cached3) {
44371
44617
  if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
44372
- const merged = reconcileInlineMeshCache(cached3, inlineMesh);
44618
+ const merged = reconcileInlineMeshCache(
44619
+ cached3,
44620
+ this.applyInlineMeshNodeTombstones(meshId, inlineMesh)
44621
+ );
44373
44622
  this.inlineMeshCache.set(meshId, sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(merged)));
44374
44623
  return { mesh: merged, inline: true, source: "inline_cache" };
44375
44624
  }
@@ -44420,12 +44669,49 @@ var DaemonCommandRouter = class {
44420
44669
  if (!mesh || !Array.isArray(mesh.nodes)) return false;
44421
44670
  const idx = mesh.nodes.findIndex((entry) => meshNodeIdMatches(entry, nodeId));
44422
44671
  if (idx === -1) return false;
44672
+ const canonicalNodeId = readInlineMeshNodeId(mesh.nodes[idx]) || nodeId;
44423
44673
  mesh.nodes.splice(idx, 1);
44424
44674
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
44425
44675
  this.inlineMeshCache.set(meshId, mesh);
44676
+ this.tombstoneRemovedInlineMeshNode(meshId, canonicalNodeId);
44677
+ if (canonicalNodeId !== nodeId) this.tombstoneRemovedInlineMeshNode(meshId, nodeId);
44426
44678
  this.invalidateAggregateMeshStatus(meshId);
44427
44679
  return true;
44428
44680
  }
44681
+ tombstoneRemovedInlineMeshNode(meshId, nodeId) {
44682
+ if (!nodeId) return;
44683
+ let set = this.removedInlineMeshNodeIds.get(meshId);
44684
+ if (!set) {
44685
+ set = /* @__PURE__ */ new Set();
44686
+ this.removedInlineMeshNodeIds.set(meshId, set);
44687
+ }
44688
+ set.add(nodeId);
44689
+ }
44690
+ /** Filter an incoming inline mesh against this mesh's tombstones before it is
44691
+ * reconciled into the cache. A tombstoned node is dropped only while its
44692
+ * workspace is still absent from disk; if the workspace is back (genuine
44693
+ * re-registration), the tombstone is cleared and the node merges normally. */
44694
+ applyInlineMeshNodeTombstones(meshId, incoming) {
44695
+ const tombstones = this.removedInlineMeshNodeIds.get(meshId);
44696
+ if (!tombstones?.size || !incoming || typeof incoming !== "object" || !Array.isArray(incoming.nodes)) {
44697
+ return incoming;
44698
+ }
44699
+ let dropped = false;
44700
+ const nodes = incoming.nodes.filter((node) => {
44701
+ const nodeId = readInlineMeshNodeId(node);
44702
+ if (!nodeId || !tombstones.has(nodeId)) return true;
44703
+ const workspace = readStringValue(node?.workspace);
44704
+ if (workspace && fs25.existsSync(workspace)) {
44705
+ tombstones.delete(nodeId);
44706
+ return true;
44707
+ }
44708
+ dropped = true;
44709
+ return false;
44710
+ });
44711
+ if (tombstones.size === 0) this.removedInlineMeshNodeIds.delete(meshId);
44712
+ if (!dropped) return incoming;
44713
+ return { ...incoming, nodes };
44714
+ }
44429
44715
  normalizeMeshSessionCleanupMode(value) {
44430
44716
  return value === "stop" || value === "delete_stopped" || value === "stop_and_delete" || value === "preserve" ? value : "preserve";
44431
44717
  }
@@ -44448,13 +44734,13 @@ var DaemonCommandRouter = class {
44448
44734
  recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
44449
44735
  };
44450
44736
  }
44451
- const worktreeExists = fs24.existsSync(workspace);
44737
+ const worktreeExists = fs25.existsSync(workspace);
44452
44738
  const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => meshNodeIdMatches(n, args.node.clonedFromNodeId)) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
44453
44739
  const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
44454
44740
  if (!worktreeExists) {
44455
44741
  return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
44456
44742
  }
44457
- if (!repoRoot || !fs24.existsSync(repoRoot)) {
44743
+ if (!repoRoot || !fs25.existsSync(repoRoot)) {
44458
44744
  return {
44459
44745
  success: false,
44460
44746
  code: "mesh_worktree_cleanup_missing_source_repo",
@@ -44474,7 +44760,7 @@ var DaemonCommandRouter = class {
44474
44760
  const normalizePath = (value) => {
44475
44761
  const resolved = (0, import_path11.resolve)(value);
44476
44762
  try {
44477
- return fs24.realpathSync(resolved);
44763
+ return fs25.realpathSync(resolved);
44478
44764
  } catch {
44479
44765
  return resolved;
44480
44766
  }
@@ -44560,7 +44846,7 @@ var DaemonCommandRouter = class {
44560
44846
  };
44561
44847
  } catch (deinitError) {
44562
44848
  try {
44563
- fs24.rmSync(workspace, { recursive: true, force: true });
44849
+ fs25.rmSync(workspace, { recursive: true, force: true });
44564
44850
  await execFileAsync4("git", ["worktree", "prune"], {
44565
44851
  cwd: repoRoot,
44566
44852
  encoding: "utf8",
@@ -46339,8 +46625,8 @@ ${hintLines.join("\n")}` : "",
46339
46625
  if (sinceTs > 0) {
46340
46626
  return { success: true, logs: [], totalBuffered: 0 };
46341
46627
  }
46342
- if (fs24.existsSync(LOG_PATH)) {
46343
- const content = fs24.readFileSync(LOG_PATH, "utf-8");
46628
+ if (fs25.existsSync(LOG_PATH)) {
46629
+ const content = fs25.readFileSync(LOG_PATH, "utf-8");
46344
46630
  const allLines = content.split("\n");
46345
46631
  const recent = allLines.slice(-count).join("\n");
46346
46632
  return { success: true, logs: recent, totalLines: allLines.length };
@@ -46885,14 +47171,14 @@ ${hintLines.join("\n")}` : "",
46885
47171
  // Settings page in the dashboard reads/writes via these two
46886
47172
  // commands instead of going through fs from the browser.
46887
47173
  case "list_coordinator_prompts": {
46888
- const fs30 = await import("fs");
47174
+ const fs31 = await import("fs");
46889
47175
  const path41 = await import("path");
46890
47176
  const os30 = await import("os");
46891
47177
  const dir = path41.join(os30.homedir(), ".adhdev", "coordinator-prompts");
46892
47178
  const entries = {};
46893
47179
  try {
46894
- if (fs30.existsSync(dir)) {
46895
- for (const name of fs30.readdirSync(dir)) {
47180
+ if (fs31.existsSync(dir)) {
47181
+ for (const name of fs31.readdirSync(dir)) {
46896
47182
  const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
46897
47183
  const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
46898
47184
  const m = matchAppend || matchOverride;
@@ -46902,7 +47188,7 @@ ${hintLines.join("\n")}` : "",
46902
47188
  const full = path41.join(dir, name);
46903
47189
  let content = "";
46904
47190
  try {
46905
- content = fs30.readFileSync(full, "utf8");
47191
+ content = fs31.readFileSync(full, "utf8");
46906
47192
  } catch {
46907
47193
  }
46908
47194
  if (!entries[key]) entries[key] = { override: "", append: "" };
@@ -46916,7 +47202,7 @@ ${hintLines.join("\n")}` : "",
46916
47202
  return { success: true, dir, entries };
46917
47203
  }
46918
47204
  case "write_coordinator_prompt": {
46919
- const fs30 = await import("fs");
47205
+ const fs31 = await import("fs");
46920
47206
  const path41 = await import("path");
46921
47207
  const os30 = await import("os");
46922
47208
  const key = typeof args?.key === "string" ? args.key.trim() : "";
@@ -46929,11 +47215,11 @@ ${hintLines.join("\n")}` : "",
46929
47215
  const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
46930
47216
  const full = path41.join(dir, filename);
46931
47217
  try {
46932
- fs30.mkdirSync(dir, { recursive: true });
47218
+ fs31.mkdirSync(dir, { recursive: true });
46933
47219
  if (content.trim()) {
46934
- fs30.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
46935
- } else if (fs30.existsSync(full)) {
46936
- fs30.unlinkSync(full);
47220
+ fs31.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
47221
+ } else if (fs31.existsSync(full)) {
47222
+ fs31.unlinkSync(full);
46937
47223
  }
46938
47224
  return { success: true, path: full, kind, key };
46939
47225
  } catch (error) {
@@ -47711,6 +47997,55 @@ ${hintLines.join("\n")}` : "",
47711
47997
  });
47712
47998
  return result;
47713
47999
  }
48000
+ case "get_mesh_node_logs": {
48001
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
48002
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
48003
+ let nodeDaemonId;
48004
+ if (meshId && nodeId) {
48005
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
48006
+ const node = meshRecord?.mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
48007
+ nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
48008
+ }
48009
+ const selfDaemonId = this.deps.statusInstanceId;
48010
+ const isRemote = nodeDaemonId && selfDaemonId && nodeDaemonId !== selfDaemonId;
48011
+ if (isRemote && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
48012
+ const forwarded = await this.deps.dispatchMeshCommand(nodeDaemonId, "get_mesh_node_logs", {
48013
+ ...typeof args === "object" && args !== null ? args : {},
48014
+ _meshDirectDispatch: true
48015
+ });
48016
+ return forwarded ?? { success: false, error: "no response from remote node" };
48017
+ }
48018
+ const rawTailBytes = Number(args?.tailBytes);
48019
+ const tail = readDaemonLogTail({
48020
+ date: typeof args?.date === "string" ? args.date : void 0,
48021
+ tailBytes: Number.isFinite(rawTailBytes) ? Math.min(rawTailBytes, MAX_TAIL_BYTES) : void 0,
48022
+ grep: typeof args?.grep === "string" ? args.grep : void 0,
48023
+ sinceMs: Number.isFinite(Number(args?.sinceMs)) ? Number(args?.sinceMs) : void 0
48024
+ });
48025
+ if (!tail.success) {
48026
+ return {
48027
+ success: false,
48028
+ error: tail.error || "failed to read daemon log tail",
48029
+ nodeId,
48030
+ logPath: tail.logPath,
48031
+ platform: tail.platform
48032
+ };
48033
+ }
48034
+ const redactedLines = redactLogLines(tail.lines);
48035
+ return {
48036
+ success: true,
48037
+ nodeId,
48038
+ daemonId: selfDaemonId,
48039
+ logPath: tail.logPath,
48040
+ platform: tail.platform,
48041
+ lines: redactedLines,
48042
+ lineCount: redactedLines.length,
48043
+ truncated: tail.truncated,
48044
+ filtered: tail.filtered,
48045
+ bytesReturned: tail.bytesReturned,
48046
+ ...tail.grep ? { grep: tail.grep } : {}
48047
+ };
48048
+ }
47714
48049
  case "refine_mesh_node": {
47715
48050
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47716
48051
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
@@ -48378,15 +48713,15 @@ ${ptyResult.output.slice(-2e3)}`);
48378
48713
  }
48379
48714
  if (cliType === "codex-cli") {
48380
48715
  const repoMcpConfigPath = (0, import_path11.join)(workspace, ".mcp.json");
48381
- if (fs24.existsSync(repoMcpConfigPath)) {
48716
+ if (fs25.existsSync(repoMcpConfigPath)) {
48382
48717
  try {
48383
48718
  const repoMcpConfig = parseMeshCoordinatorMcpConfig(
48384
- fs24.readFileSync(repoMcpConfigPath, "utf-8"),
48719
+ fs25.readFileSync(repoMcpConfigPath, "utf-8"),
48385
48720
  "claude_mcp_json"
48386
48721
  );
48387
48722
  const existingServers2 = repoMcpConfig.mcpServers;
48388
48723
  if (existingServers2 && typeof existingServers2 === "object" && !Array.isArray(existingServers2) && existingServers2[coordinatorSetup.serverName]) {
48389
- fs24.writeFileSync(repoMcpConfigPath, serializeMeshCoordinatorMcpConfig({
48724
+ fs25.writeFileSync(repoMcpConfigPath, serializeMeshCoordinatorMcpConfig({
48390
48725
  ...repoMcpConfig,
48391
48726
  mcpServers: {
48392
48727
  ...existingServers2,
@@ -48502,7 +48837,7 @@ ${ptyResult.output.slice(-2e3)}`);
48502
48837
  workspace
48503
48838
  };
48504
48839
  }
48505
- const { existsSync: existsSync43, readFileSync: readFileSync35, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
48840
+ const { existsSync: existsSync44, readFileSync: readFileSync35, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
48506
48841
  const { dirname: dirname14 } = await import("path");
48507
48842
  const mcpConfigPath = coordinatorSetup.configPath;
48508
48843
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -48545,7 +48880,7 @@ ${ptyResult.output.slice(-2e3)}`);
48545
48880
  if (hermesManualFallback) return returnManualFallback(message);
48546
48881
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
48547
48882
  }
48548
- const hadExistingMcpConfig = existsSync43(mcpConfigPath);
48883
+ const hadExistingMcpConfig = existsSync44(mcpConfigPath);
48549
48884
  let existingMcpConfig = hermesBaseConfig?.config || {};
48550
48885
  if (hermesBaseConfig) {
48551
48886
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname14(mcpConfigPath));
@@ -48722,7 +49057,8 @@ ${ptyResult.output.slice(-2e3)}`);
48722
49057
  peerAttemptedCount: 0,
48723
49058
  peerConfirmedCount: 0,
48724
49059
  standingEvidenceCount: 0,
48725
- unavailableNodeIds: []
49060
+ unavailableNodeIds: [],
49061
+ deadNodeIds: []
48726
49062
  };
48727
49063
  const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
48728
49064
  const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
@@ -48862,7 +49198,7 @@ ${ptyResult.output.slice(-2e3)}`);
48862
49198
  }
48863
49199
  }
48864
49200
  if (workspace) {
48865
- if (!fs24.existsSync(workspace)) {
49201
+ if (!fs25.existsSync(workspace)) {
48866
49202
  const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
48867
49203
  let remoteProbeApplied = false;
48868
49204
  if (inlineTransitGit) {
@@ -48953,7 +49289,7 @@ ${ptyResult.output.slice(-2e3)}`);
48953
49289
  const pendingCoordinatorEvents = getPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
48954
49290
  const unroutableDeliveries = getRecentUnroutableDeliveries();
48955
49291
  const previewFreshness = (() => {
48956
- const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs24.existsSync(candidate));
49292
+ const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs25.existsSync(candidate));
48957
49293
  return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
48958
49294
  })();
48959
49295
  const asyncRefineJobs = buildMeshAsyncRefineJobs({
@@ -49048,7 +49384,7 @@ ${ptyResult.output.slice(-2e3)}`);
49048
49384
  const { deriveMeshReviewInboxItems: deriveMeshReviewInboxItems2 } = await Promise.resolve().then(() => (init_mesh_review_inbox(), mesh_review_inbox_exports));
49049
49385
  const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
49050
49386
  const { getGitDiffSummary: getGitDiffSummary2 } = await Promise.resolve().then(() => (init_git_diff(), git_diff_exports));
49051
- const { existsSync: existsSync43 } = await import("fs");
49387
+ const { existsSync: existsSync44 } = await import("fs");
49052
49388
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
49053
49389
  const mesh = meshRecord?.mesh;
49054
49390
  if (!mesh) return { success: false, error: "Mesh not found" };
@@ -49067,7 +49403,7 @@ ${ptyResult.output.slice(-2e3)}`);
49067
49403
  const derivation = deriveMeshReviewInboxItems2({ nodes: nodeStatuses, ledgerEntries });
49068
49404
  for (const item of derivation.items) {
49069
49405
  const workspace = item.workspace;
49070
- if (!workspace || !existsSync43(workspace)) continue;
49406
+ if (!workspace || !existsSync44(workspace)) continue;
49071
49407
  const baseRef = item.defaultBranch ? `origin/${item.defaultBranch}` : "origin/main";
49072
49408
  try {
49073
49409
  const diffResult = await getGitDiffSummary2(workspace, { baseRef, maxFiles: 100 });
@@ -50813,7 +51149,7 @@ var ProviderInstanceManager = class {
50813
51149
  };
50814
51150
 
50815
51151
  // src/providers/version-archive.ts
50816
- var fs25 = __toESM(require("fs"));
51152
+ var fs26 = __toESM(require("fs"));
50817
51153
  var path36 = __toESM(require("path"));
50818
51154
  var os28 = __toESM(require("os"));
50819
51155
  var import_os4 = require("os");
@@ -50827,8 +51163,8 @@ var VersionArchive = class {
50827
51163
  }
50828
51164
  load() {
50829
51165
  try {
50830
- if (fs25.existsSync(ARCHIVE_PATH)) {
50831
- this.history = JSON.parse(fs25.readFileSync(ARCHIVE_PATH, "utf-8"));
51166
+ if (fs26.existsSync(ARCHIVE_PATH)) {
51167
+ this.history = JSON.parse(fs26.readFileSync(ARCHIVE_PATH, "utf-8"));
50832
51168
  }
50833
51169
  } catch {
50834
51170
  this.history = {};
@@ -50865,8 +51201,8 @@ var VersionArchive = class {
50865
51201
  }
50866
51202
  save() {
50867
51203
  try {
50868
- fs25.mkdirSync(path36.dirname(ARCHIVE_PATH), { recursive: true });
50869
- fs25.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
51204
+ fs26.mkdirSync(path36.dirname(ARCHIVE_PATH), { recursive: true });
51205
+ fs26.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
50870
51206
  } catch {
50871
51207
  }
50872
51208
  }
@@ -50891,8 +51227,8 @@ function findBinary2(name) {
50891
51227
  for (const ext of exes) {
50892
51228
  const fullPath = path36.join(p, name + ext);
50893
51229
  try {
50894
- if (fs25.existsSync(fullPath)) {
50895
- const stat2 = fs25.statSync(fullPath);
51230
+ if (fs26.existsSync(fullPath)) {
51231
+ const stat2 = fs26.statSync(fullPath);
50896
51232
  if (stat2.isFile() && (isWin || stat2.mode & 73)) {
50897
51233
  return fullPath;
50898
51234
  }
@@ -50939,9 +51275,9 @@ function checkPathExists2(paths) {
50939
51275
  if (p.includes("*")) {
50940
51276
  const home = os28.homedir();
50941
51277
  const resolved = p.replace(/\*/g, home.split(path36.sep).pop() || "");
50942
- if (fs25.existsSync(resolved)) return resolved;
51278
+ if (fs26.existsSync(resolved)) return resolved;
50943
51279
  } else {
50944
- if (fs25.existsSync(p)) return p;
51280
+ if (fs26.existsSync(p)) return p;
50945
51281
  }
50946
51282
  }
50947
51283
  return null;
@@ -50949,7 +51285,7 @@ function checkPathExists2(paths) {
50949
51285
  async function getMacAppVersion(appPath) {
50950
51286
  if ((0, import_os4.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
50951
51287
  const plistPath = path36.join(appPath, "Contents", "Info.plist");
50952
- if (!fs25.existsSync(plistPath)) return null;
51288
+ if (!fs26.existsSync(plistPath)) return null;
50953
51289
  const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
50954
51290
  return raw || null;
50955
51291
  }
@@ -50975,7 +51311,7 @@ async function detectAllVersions(loader, archive) {
50975
51311
  let resolvedBin = cliBin;
50976
51312
  if (!resolvedBin && appPath && currentOs === "darwin") {
50977
51313
  const bundled = path36.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
50978
- if (provider.cli && fs25.existsSync(bundled)) resolvedBin = bundled;
51314
+ if (provider.cli && fs26.existsSync(bundled)) resolvedBin = bundled;
50979
51315
  }
50980
51316
  info.installed = !!(appPath || resolvedBin);
50981
51317
  info.path = appPath || null;
@@ -51014,7 +51350,7 @@ async function detectAllVersions(loader, archive) {
51014
51350
 
51015
51351
  // src/daemon/dev-server.ts
51016
51352
  var http2 = __toESM(require("http"));
51017
- var fs29 = __toESM(require("fs"));
51353
+ var fs30 = __toESM(require("fs"));
51018
51354
  var path40 = __toESM(require("path"));
51019
51355
  init_config();
51020
51356
 
@@ -51365,7 +51701,7 @@ async (params) => {
51365
51701
  init_logger();
51366
51702
 
51367
51703
  // src/daemon/dev-cdp-handlers.ts
51368
- var fs26 = __toESM(require("fs"));
51704
+ var fs27 = __toESM(require("fs"));
51369
51705
  var path37 = __toESM(require("path"));
51370
51706
  init_logger();
51371
51707
  async function handleCdpEvaluate(ctx, req, res) {
@@ -51546,17 +51882,17 @@ async function handleScriptHints(ctx, type, _req, res) {
51546
51882
  }
51547
51883
  let scriptsPath = "";
51548
51884
  const directScripts = path37.join(dir, "scripts.js");
51549
- if (fs26.existsSync(directScripts)) {
51885
+ if (fs27.existsSync(directScripts)) {
51550
51886
  scriptsPath = directScripts;
51551
51887
  } else {
51552
51888
  const scriptsDir = path37.join(dir, "scripts");
51553
- if (fs26.existsSync(scriptsDir)) {
51554
- const versions = fs26.readdirSync(scriptsDir).filter((d) => {
51555
- return fs26.statSync(path37.join(scriptsDir, d)).isDirectory();
51889
+ if (fs27.existsSync(scriptsDir)) {
51890
+ const versions = fs27.readdirSync(scriptsDir).filter((d) => {
51891
+ return fs27.statSync(path37.join(scriptsDir, d)).isDirectory();
51556
51892
  }).sort().reverse();
51557
51893
  for (const ver of versions) {
51558
51894
  const p = path37.join(scriptsDir, ver, "scripts.js");
51559
- if (fs26.existsSync(p)) {
51895
+ if (fs27.existsSync(p)) {
51560
51896
  scriptsPath = p;
51561
51897
  break;
51562
51898
  }
@@ -51568,7 +51904,7 @@ async function handleScriptHints(ctx, type, _req, res) {
51568
51904
  return;
51569
51905
  }
51570
51906
  try {
51571
- const source = fs26.readFileSync(scriptsPath, "utf-8");
51907
+ const source = fs27.readFileSync(scriptsPath, "utf-8");
51572
51908
  const hints = {};
51573
51909
  const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
51574
51910
  let match;
@@ -52383,7 +52719,7 @@ async function handleDomContext(ctx, type, req, res) {
52383
52719
  }
52384
52720
 
52385
52721
  // src/daemon/dev-cli-debug.ts
52386
- var fs27 = __toESM(require("fs"));
52722
+ var fs28 = __toESM(require("fs"));
52387
52723
  var path38 = __toESM(require("path"));
52388
52724
  function slugifyFixtureName(value) {
52389
52725
  const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
@@ -52399,10 +52735,10 @@ function getCliFixtureDir(ctx, type) {
52399
52735
  function readCliFixture(ctx, type, name) {
52400
52736
  const fixtureDir = getCliFixtureDir(ctx, type);
52401
52737
  const filePath = path38.join(fixtureDir, `${name}.json`);
52402
- if (!fs27.existsSync(filePath)) {
52738
+ if (!fs28.existsSync(filePath)) {
52403
52739
  throw new Error(`Fixture not found: ${filePath}`);
52404
52740
  }
52405
- return JSON.parse(fs27.readFileSync(filePath, "utf-8"));
52741
+ return JSON.parse(fs28.readFileSync(filePath, "utf-8"));
52406
52742
  }
52407
52743
  function getExerciseTranscriptText(result) {
52408
52744
  const parts = [];
@@ -53147,7 +53483,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
53147
53483
  return;
53148
53484
  }
53149
53485
  const fixtureDir = getCliFixtureDir(ctx, type);
53150
- fs27.mkdirSync(fixtureDir, { recursive: true });
53486
+ fs28.mkdirSync(fixtureDir, { recursive: true });
53151
53487
  const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
53152
53488
  const result = await runCliExerciseInternal(ctx, { ...request, type });
53153
53489
  const fixture = {
@@ -53175,7 +53511,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
53175
53511
  notes: typeof body?.notes === "string" ? body.notes : void 0
53176
53512
  };
53177
53513
  const filePath = path38.join(fixtureDir, `${name}.json`);
53178
- fs27.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
53514
+ fs28.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
53179
53515
  ctx.json(res, 200, {
53180
53516
  saved: true,
53181
53517
  name,
@@ -53193,14 +53529,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
53193
53529
  async function handleCliFixtureList(ctx, type, _req, res) {
53194
53530
  try {
53195
53531
  const fixtureDir = getCliFixtureDir(ctx, type);
53196
- if (!fs27.existsSync(fixtureDir)) {
53532
+ if (!fs28.existsSync(fixtureDir)) {
53197
53533
  ctx.json(res, 200, { fixtures: [], count: 0 });
53198
53534
  return;
53199
53535
  }
53200
- const fixtures = fs27.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
53536
+ const fixtures = fs28.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
53201
53537
  const fullPath = path38.join(fixtureDir, file);
53202
53538
  try {
53203
- const raw = JSON.parse(fs27.readFileSync(fullPath, "utf-8"));
53539
+ const raw = JSON.parse(fs28.readFileSync(fullPath, "utf-8"));
53204
53540
  return {
53205
53541
  name: raw.name || file.replace(/\.json$/i, ""),
53206
53542
  path: fullPath,
@@ -53333,7 +53669,7 @@ async function handleCliRaw(ctx, req, res) {
53333
53669
  }
53334
53670
 
53335
53671
  // src/daemon/dev-auto-implement.ts
53336
- var fs28 = __toESM(require("fs"));
53672
+ var fs29 = __toESM(require("fs"));
53337
53673
  var path39 = __toESM(require("path"));
53338
53674
  var os29 = __toESM(require("os"));
53339
53675
  var import_session_host_core8 = require("@adhdev/session-host-core");
@@ -53382,10 +53718,10 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
53382
53718
  return fallback?.type || null;
53383
53719
  }
53384
53720
  function getLatestScriptVersionDir(scriptsDir) {
53385
- if (!fs28.existsSync(scriptsDir)) return null;
53386
- const versions = fs28.readdirSync(scriptsDir).filter((d) => {
53721
+ if (!fs29.existsSync(scriptsDir)) return null;
53722
+ const versions = fs29.readdirSync(scriptsDir).filter((d) => {
53387
53723
  try {
53388
- return fs28.statSync(path39.join(scriptsDir, d)).isDirectory();
53724
+ return fs29.statSync(path39.join(scriptsDir, d)).isDirectory();
53389
53725
  } catch {
53390
53726
  return false;
53391
53727
  }
@@ -53407,13 +53743,13 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
53407
53743
  if (!sourceDir) {
53408
53744
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
53409
53745
  }
53410
- if (!fs28.existsSync(desiredDir)) {
53411
- fs28.mkdirSync(path39.dirname(desiredDir), { recursive: true });
53412
- fs28.cpSync(sourceDir, desiredDir, { recursive: true });
53746
+ if (!fs29.existsSync(desiredDir)) {
53747
+ fs29.mkdirSync(path39.dirname(desiredDir), { recursive: true });
53748
+ fs29.cpSync(sourceDir, desiredDir, { recursive: true });
53413
53749
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
53414
53750
  }
53415
53751
  const providerJson = path39.join(desiredDir, "provider.json");
53416
- if (!fs28.existsSync(providerJson)) {
53752
+ if (!fs29.existsSync(providerJson)) {
53417
53753
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
53418
53754
  }
53419
53755
  return { dir: desiredDir };
@@ -53421,15 +53757,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
53421
53757
  function loadAutoImplReferenceScripts(ctx, referenceType) {
53422
53758
  if (!referenceType) return {};
53423
53759
  const refDir = ctx.findProviderDir(referenceType);
53424
- if (!refDir || !fs28.existsSync(refDir)) return {};
53760
+ if (!refDir || !fs29.existsSync(refDir)) return {};
53425
53761
  const referenceScripts = {};
53426
53762
  const scriptsDir = path39.join(refDir, "scripts");
53427
53763
  const latestDir = getLatestScriptVersionDir(scriptsDir);
53428
53764
  if (!latestDir) return referenceScripts;
53429
- for (const file of fs28.readdirSync(latestDir)) {
53765
+ for (const file of fs29.readdirSync(latestDir)) {
53430
53766
  if (!file.endsWith(".js")) continue;
53431
53767
  try {
53432
- referenceScripts[file] = fs28.readFileSync(path39.join(latestDir, file), "utf-8");
53768
+ referenceScripts[file] = fs29.readFileSync(path39.join(latestDir, file), "utf-8");
53433
53769
  } catch {
53434
53770
  }
53435
53771
  }
@@ -53538,15 +53874,15 @@ async function handleAutoImplement(ctx, type, req, res) {
53538
53874
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
53539
53875
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
53540
53876
  const tmpDir = path39.join(os29.tmpdir(), "adhdev-autoimpl");
53541
- if (!fs28.existsSync(tmpDir)) fs28.mkdirSync(tmpDir, { recursive: true });
53877
+ if (!fs29.existsSync(tmpDir)) fs29.mkdirSync(tmpDir, { recursive: true });
53542
53878
  const promptFile = path39.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
53543
- fs28.writeFileSync(promptFile, prompt, "utf-8");
53879
+ fs29.writeFileSync(promptFile, prompt, "utf-8");
53544
53880
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
53545
53881
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
53546
53882
  const spawn4 = agentProvider?.spawn;
53547
53883
  if (!spawn4?.command) {
53548
53884
  try {
53549
- fs28.unlinkSync(promptFile);
53885
+ fs29.unlinkSync(promptFile);
53550
53886
  } catch {
53551
53887
  }
53552
53888
  ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
@@ -53648,7 +53984,7 @@ async function handleAutoImplement(ctx, type, req, res) {
53648
53984
  } catch {
53649
53985
  }
53650
53986
  try {
53651
- fs28.unlinkSync(promptFile);
53987
+ fs29.unlinkSync(promptFile);
53652
53988
  } catch {
53653
53989
  }
53654
53990
  ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
@@ -53874,7 +54210,7 @@ async function handleAutoImplement(ctx, type, req, res) {
53874
54210
  }
53875
54211
  });
53876
54212
  try {
53877
- fs28.unlinkSync(promptFile);
54213
+ fs29.unlinkSync(promptFile);
53878
54214
  } catch {
53879
54215
  }
53880
54216
  ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
@@ -53979,10 +54315,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
53979
54315
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
53980
54316
  lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
53981
54317
  lines.push("");
53982
- for (const file of fs28.readdirSync(latestScriptsDir)) {
54318
+ for (const file of fs29.readdirSync(latestScriptsDir)) {
53983
54319
  if (file.endsWith(".js") && targetFileNames.has(file)) {
53984
54320
  try {
53985
- const content = fs28.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
54321
+ const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
53986
54322
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
53987
54323
  lines.push("```javascript");
53988
54324
  lines.push(content);
@@ -53992,14 +54328,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
53992
54328
  }
53993
54329
  }
53994
54330
  }
53995
- const refFiles = fs28.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
54331
+ const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
53996
54332
  if (refFiles.length > 0) {
53997
54333
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
53998
54334
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
53999
54335
  lines.push("");
54000
54336
  for (const file of refFiles) {
54001
54337
  try {
54002
- const content = fs28.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
54338
+ const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
54003
54339
  lines.push(`### \`${file}\` \u{1F512}`);
54004
54340
  lines.push("```javascript");
54005
54341
  lines.push(content);
@@ -54044,7 +54380,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
54044
54380
  const loadGuide = (name) => {
54045
54381
  try {
54046
54382
  const p = path39.join(docsDir, name);
54047
- if (fs28.existsSync(p)) return fs28.readFileSync(p, "utf-8");
54383
+ if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
54048
54384
  } catch {
54049
54385
  }
54050
54386
  return null;
@@ -54288,11 +54624,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
54288
54624
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
54289
54625
  lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
54290
54626
  lines.push("");
54291
- for (const file of fs28.readdirSync(latestScriptsDir)) {
54627
+ for (const file of fs29.readdirSync(latestScriptsDir)) {
54292
54628
  if (!file.endsWith(".js")) continue;
54293
54629
  if (!targetFileNames.has(file)) continue;
54294
54630
  try {
54295
- const content = fs28.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
54631
+ const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
54296
54632
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
54297
54633
  lines.push("```javascript");
54298
54634
  lines.push(content);
@@ -54301,14 +54637,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
54301
54637
  } catch {
54302
54638
  }
54303
54639
  }
54304
- const refFiles = fs28.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
54640
+ const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
54305
54641
  if (refFiles.length > 0) {
54306
54642
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
54307
54643
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
54308
54644
  lines.push("");
54309
54645
  for (const file of refFiles) {
54310
54646
  try {
54311
- const content = fs28.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
54647
+ const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
54312
54648
  lines.push(`### \`${file}\` \u{1F512}`);
54313
54649
  lines.push("```javascript");
54314
54650
  lines.push(content);
@@ -54345,7 +54681,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
54345
54681
  const loadGuide = (name) => {
54346
54682
  try {
54347
54683
  const p = path39.join(docsDir, name);
54348
- if (fs28.existsSync(p)) return fs28.readFileSync(p, "utf-8");
54684
+ if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
54349
54685
  } catch {
54350
54686
  }
54351
54687
  return null;
@@ -55085,7 +55421,7 @@ var DevServer = class _DevServer {
55085
55421
  path40.join(process.cwd(), "packages/web-devconsole/dist")
55086
55422
  ];
55087
55423
  for (const dir of candidates) {
55088
- if (fs29.existsSync(path40.join(dir, "index.html"))) return dir;
55424
+ if (fs30.existsSync(path40.join(dir, "index.html"))) return dir;
55089
55425
  }
55090
55426
  return null;
55091
55427
  }
@@ -55097,7 +55433,7 @@ var DevServer = class _DevServer {
55097
55433
  }
55098
55434
  const htmlPath = path40.join(distDir, "index.html");
55099
55435
  try {
55100
- const html = fs29.readFileSync(htmlPath, "utf-8");
55436
+ const html = fs30.readFileSync(htmlPath, "utf-8");
55101
55437
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
55102
55438
  res.end(html);
55103
55439
  } catch (e) {
@@ -55127,7 +55463,7 @@ var DevServer = class _DevServer {
55127
55463
  return;
55128
55464
  }
55129
55465
  try {
55130
- const content = fs29.readFileSync(filePath);
55466
+ const content = fs30.readFileSync(filePath);
55131
55467
  const ext = path40.extname(filePath);
55132
55468
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
55133
55469
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
@@ -55236,14 +55572,14 @@ var DevServer = class _DevServer {
55236
55572
  const files = [];
55237
55573
  const scan = (d, prefix) => {
55238
55574
  try {
55239
- for (const entry of fs29.readdirSync(d, { withFileTypes: true })) {
55575
+ for (const entry of fs30.readdirSync(d, { withFileTypes: true })) {
55240
55576
  if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
55241
55577
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
55242
55578
  if (entry.isDirectory()) {
55243
55579
  files.push({ path: rel, size: 0, type: "dir" });
55244
55580
  scan(path40.join(d, entry.name), rel);
55245
55581
  } else {
55246
- const stat2 = fs29.statSync(path40.join(d, entry.name));
55582
+ const stat2 = fs30.statSync(path40.join(d, entry.name));
55247
55583
  files.push({ path: rel, size: stat2.size, type: "file" });
55248
55584
  }
55249
55585
  }
@@ -55271,11 +55607,11 @@ var DevServer = class _DevServer {
55271
55607
  this.json(res, 403, { error: "Forbidden" });
55272
55608
  return;
55273
55609
  }
55274
- if (!fs29.existsSync(fullPath) || fs29.statSync(fullPath).isDirectory()) {
55610
+ if (!fs30.existsSync(fullPath) || fs30.statSync(fullPath).isDirectory()) {
55275
55611
  this.json(res, 404, { error: `File not found: ${filePath}` });
55276
55612
  return;
55277
55613
  }
55278
- const content = fs29.readFileSync(fullPath, "utf-8");
55614
+ const content = fs30.readFileSync(fullPath, "utf-8");
55279
55615
  this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
55280
55616
  }
55281
55617
  /** POST /api/providers/:type/file — write a file { path, content } */
@@ -55297,9 +55633,9 @@ var DevServer = class _DevServer {
55297
55633
  return;
55298
55634
  }
55299
55635
  try {
55300
- if (fs29.existsSync(fullPath)) fs29.copyFileSync(fullPath, fullPath + ".bak");
55301
- fs29.mkdirSync(path40.dirname(fullPath), { recursive: true });
55302
- fs29.writeFileSync(fullPath, content, "utf-8");
55636
+ if (fs30.existsSync(fullPath)) fs30.copyFileSync(fullPath, fullPath + ".bak");
55637
+ fs30.mkdirSync(path40.dirname(fullPath), { recursive: true });
55638
+ fs30.writeFileSync(fullPath, content, "utf-8");
55303
55639
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
55304
55640
  this.providerLoader.reload();
55305
55641
  this.json(res, 200, { saved: true, path: filePath, chars: content.length });
@@ -55316,8 +55652,8 @@ var DevServer = class _DevServer {
55316
55652
  }
55317
55653
  for (const name of ["scripts.js", "provider.json"]) {
55318
55654
  const p = path40.join(dir, name);
55319
- if (fs29.existsSync(p)) {
55320
- const source = fs29.readFileSync(p, "utf-8");
55655
+ if (fs30.existsSync(p)) {
55656
+ const source = fs30.readFileSync(p, "utf-8");
55321
55657
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
55322
55658
  return;
55323
55659
  }
@@ -55336,11 +55672,11 @@ var DevServer = class _DevServer {
55336
55672
  this.json(res, 404, { error: `Provider not found: ${type}` });
55337
55673
  return;
55338
55674
  }
55339
- const target = fs29.existsSync(path40.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
55675
+ const target = fs30.existsSync(path40.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
55340
55676
  const targetPath = path40.join(dir, target);
55341
55677
  try {
55342
- if (fs29.existsSync(targetPath)) fs29.copyFileSync(targetPath, targetPath + ".bak");
55343
- fs29.writeFileSync(targetPath, source, "utf-8");
55678
+ if (fs30.existsSync(targetPath)) fs30.copyFileSync(targetPath, targetPath + ".bak");
55679
+ fs30.writeFileSync(targetPath, source, "utf-8");
55344
55680
  this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
55345
55681
  this.providerLoader.reload();
55346
55682
  this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
@@ -55485,20 +55821,20 @@ var DevServer = class _DevServer {
55485
55821
  let targetDir;
55486
55822
  targetDir = this.providerLoader.getUserProviderDir(category, type);
55487
55823
  const jsonPath = path40.join(targetDir, "provider.json");
55488
- if (fs29.existsSync(jsonPath)) {
55824
+ if (fs30.existsSync(jsonPath)) {
55489
55825
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
55490
55826
  return;
55491
55827
  }
55492
55828
  try {
55493
55829
  const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
55494
- fs29.mkdirSync(targetDir, { recursive: true });
55495
- fs29.writeFileSync(jsonPath, result["provider.json"], "utf-8");
55830
+ fs30.mkdirSync(targetDir, { recursive: true });
55831
+ fs30.writeFileSync(jsonPath, result["provider.json"], "utf-8");
55496
55832
  const createdFiles = ["provider.json"];
55497
55833
  if (result.files) {
55498
55834
  for (const [relPath, content] of Object.entries(result.files)) {
55499
55835
  const fullPath = path40.join(targetDir, relPath);
55500
- fs29.mkdirSync(path40.dirname(fullPath), { recursive: true });
55501
- fs29.writeFileSync(fullPath, content, "utf-8");
55836
+ fs30.mkdirSync(path40.dirname(fullPath), { recursive: true });
55837
+ fs30.writeFileSync(fullPath, content, "utf-8");
55502
55838
  createdFiles.push(relPath);
55503
55839
  }
55504
55840
  }
@@ -55547,10 +55883,10 @@ var DevServer = class _DevServer {
55547
55883
  }
55548
55884
  // ─── Phase 2: Auto-Implement Backend ───
55549
55885
  getLatestScriptVersionDir(scriptsDir) {
55550
- if (!fs29.existsSync(scriptsDir)) return null;
55551
- const versions = fs29.readdirSync(scriptsDir).filter((d) => {
55886
+ if (!fs30.existsSync(scriptsDir)) return null;
55887
+ const versions = fs30.readdirSync(scriptsDir).filter((d) => {
55552
55888
  try {
55553
- return fs29.statSync(path40.join(scriptsDir, d)).isDirectory();
55889
+ return fs30.statSync(path40.join(scriptsDir, d)).isDirectory();
55554
55890
  } catch {
55555
55891
  return false;
55556
55892
  }
@@ -55572,13 +55908,13 @@ var DevServer = class _DevServer {
55572
55908
  if (!sourceDir) {
55573
55909
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
55574
55910
  }
55575
- if (!fs29.existsSync(desiredDir)) {
55576
- fs29.mkdirSync(path40.dirname(desiredDir), { recursive: true });
55577
- fs29.cpSync(sourceDir, desiredDir, { recursive: true });
55911
+ if (!fs30.existsSync(desiredDir)) {
55912
+ fs30.mkdirSync(path40.dirname(desiredDir), { recursive: true });
55913
+ fs30.cpSync(sourceDir, desiredDir, { recursive: true });
55578
55914
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
55579
55915
  }
55580
55916
  const providerJson = path40.join(desiredDir, "provider.json");
55581
- if (!fs29.existsSync(providerJson)) {
55917
+ if (!fs30.existsSync(providerJson)) {
55582
55918
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
55583
55919
  }
55584
55920
  return { dir: desiredDir };
@@ -55621,10 +55957,10 @@ var DevServer = class _DevServer {
55621
55957
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
55622
55958
  lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
55623
55959
  lines.push("");
55624
- for (const file of fs29.readdirSync(latestScriptsDir)) {
55960
+ for (const file of fs30.readdirSync(latestScriptsDir)) {
55625
55961
  if (file.endsWith(".js") && targetFileNames.has(file)) {
55626
55962
  try {
55627
- const content = fs29.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55963
+ const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55628
55964
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
55629
55965
  lines.push("```javascript");
55630
55966
  lines.push(content);
@@ -55634,14 +55970,14 @@ var DevServer = class _DevServer {
55634
55970
  }
55635
55971
  }
55636
55972
  }
55637
- const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
55973
+ const refFiles = fs30.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
55638
55974
  if (refFiles.length > 0) {
55639
55975
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
55640
55976
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
55641
55977
  lines.push("");
55642
55978
  for (const file of refFiles) {
55643
55979
  try {
55644
- const content = fs29.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55980
+ const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55645
55981
  lines.push(`### \`${file}\` \u{1F512}`);
55646
55982
  lines.push("```javascript");
55647
55983
  lines.push(content);
@@ -55686,7 +56022,7 @@ var DevServer = class _DevServer {
55686
56022
  const loadGuide = (name) => {
55687
56023
  try {
55688
56024
  const p = path40.join(docsDir, name);
55689
- if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
56025
+ if (fs30.existsSync(p)) return fs30.readFileSync(p, "utf-8");
55690
56026
  } catch {
55691
56027
  }
55692
56028
  return null;
@@ -55867,11 +56203,11 @@ var DevServer = class _DevServer {
55867
56203
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
55868
56204
  lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
55869
56205
  lines.push("");
55870
- for (const file of fs29.readdirSync(latestScriptsDir)) {
56206
+ for (const file of fs30.readdirSync(latestScriptsDir)) {
55871
56207
  if (!file.endsWith(".js")) continue;
55872
56208
  if (!targetFileNames.has(file)) continue;
55873
56209
  try {
55874
- const content = fs29.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
56210
+ const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55875
56211
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
55876
56212
  lines.push("```javascript");
55877
56213
  lines.push(content);
@@ -55880,14 +56216,14 @@ var DevServer = class _DevServer {
55880
56216
  } catch {
55881
56217
  }
55882
56218
  }
55883
- const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
56219
+ const refFiles = fs30.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
55884
56220
  if (refFiles.length > 0) {
55885
56221
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
55886
56222
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
55887
56223
  lines.push("");
55888
56224
  for (const file of refFiles) {
55889
56225
  try {
55890
- const content = fs29.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
56226
+ const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55891
56227
  lines.push(`### \`${file}\` \u{1F512}`);
55892
56228
  lines.push("```javascript");
55893
56229
  lines.push(content);
@@ -55924,7 +56260,7 @@ var DevServer = class _DevServer {
55924
56260
  const loadGuide = (name) => {
55925
56261
  try {
55926
56262
  const p = path40.join(docsDir, name);
55927
- if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
56263
+ if (fs30.existsSync(p)) return fs30.readFileSync(p, "utf-8");
55928
56264
  } catch {
55929
56265
  }
55930
56266
  return null;
@@ -57025,8 +57361,8 @@ async function installExtension(ide, extension) {
57025
57361
  const res = await fetch(extension.vsixUrl);
57026
57362
  if (res.ok) {
57027
57363
  const buffer = Buffer.from(await res.arrayBuffer());
57028
- const fs30 = await import("fs");
57029
- fs30.writeFileSync(vsixPath, buffer);
57364
+ const fs31 = await import("fs");
57365
+ fs31.writeFileSync(vsixPath, buffer);
57030
57366
  return new Promise((resolve24) => {
57031
57367
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
57032
57368
  (0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {