@adhdev/daemon-core 0.9.82-rc.316 → 0.9.82-rc.318

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
@@ -353,10 +353,10 @@ function readInjected(value) {
353
353
  }
354
354
  function getDaemonBuildInfo() {
355
355
  if (cached) return cached;
356
- const commit = readInjected(true ? "930909642b3f28668483159d3a8f39d0a796c61a" : void 0) ?? "unknown";
357
- const commitShort = readInjected(true ? "93090964" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
358
- const version = readInjected(true ? "0.9.82-rc.316" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
359
- const builtAt = readInjected(true ? "2026-06-18T07:23:07.242Z" : void 0);
356
+ const commit = readInjected(true ? "506ca246e28984a3b699b04c4601117f62ba2d81" : void 0) ?? "unknown";
357
+ const commitShort = readInjected(true ? "506ca246" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
358
+ const version = readInjected(true ? "0.9.82-rc.318" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
359
+ const builtAt = readInjected(true ? "2026-06-18T12:46:04.472Z" : void 0);
360
360
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
361
361
  return cached;
362
362
  }
@@ -682,14 +682,79 @@ function emptyStatus(workspace, lastCheckedAt, error) {
682
682
  async function getSubmoduleStatuses(repo, options) {
683
683
  if (!repo.repoRoot) return [];
684
684
  try {
685
- const result = await runGit(repo, ["submodule", "status"], options);
686
- const submodules = parseSubmoduleStatusOutput(result.stdout, repo.repoRoot, options.submoduleIgnorePaths);
685
+ const submodules = await deriveSubmoduleGitlinkStatuses(repo, options);
687
686
  await Promise.all(submodules.map((submodule) => enrichSubmoduleWorktreeStatus(repo, submodule, options)));
688
687
  return submodules;
689
688
  } catch {
690
689
  return [];
691
690
  }
692
691
  }
692
+ async function deriveSubmoduleGitlinkStatuses(repo, options) {
693
+ if (!repo.repoRoot) return [];
694
+ const paths = await readSubmodulePaths(repo, options);
695
+ const ignoreSet = new Set(options.submoduleIgnorePaths || []);
696
+ const lastCheckedAt = Date.now();
697
+ const entries = await Promise.all(
698
+ paths.filter((path41) => !ignoreSet.has(path41)).map(async (path41) => {
699
+ const repoPath = repo.repoRoot + "/" + path41;
700
+ const expected = await readGitlinkExpectedSha(repo, path41, options);
701
+ const actual = await readSubmoduleHeadSha(repo, repoPath, options);
702
+ const outOfSync = actual === null ? true : expected !== null && expected !== actual;
703
+ return {
704
+ path: path41,
705
+ // Prefer the recorded gitlink SHA (matches the legacy column); fall back
706
+ // to the checked-out SHA so the field is never empty when both are known.
707
+ commit: expected ?? actual ?? "",
708
+ repoPath,
709
+ dirty: false,
710
+ outOfSync,
711
+ lastCheckedAt
712
+ };
713
+ })
714
+ );
715
+ return entries;
716
+ }
717
+ async function readSubmodulePaths(repo, options) {
718
+ if (!repo.repoRoot) return [];
719
+ const gitmodulesPath = repo.repoRoot + "/.gitmodules";
720
+ try {
721
+ const result = await runGit(
722
+ repo,
723
+ ["config", "--file", gitmodulesPath, "--get-regexp", "^submodule\\..*\\.path$"],
724
+ options
725
+ );
726
+ const paths = [];
727
+ for (const line of result.stdout.split("\n")) {
728
+ const spaceIdx = line.indexOf(" ");
729
+ if (spaceIdx < 0) continue;
730
+ const value = line.slice(spaceIdx + 1).trim();
731
+ if (value) paths.push(value);
732
+ }
733
+ return paths;
734
+ } catch {
735
+ return [];
736
+ }
737
+ }
738
+ async function readGitlinkExpectedSha(repo, submodulePath, options) {
739
+ try {
740
+ const result = await runGit(repo, ["ls-tree", "HEAD", submodulePath], options);
741
+ const line = result.stdout.split("\n").find((l) => l.trim().length > 0);
742
+ if (!line) return null;
743
+ const match = line.match(/^\s*\d+\s+commit\s+([0-9a-f]{40})\b/);
744
+ return match ? match[1] : null;
745
+ } catch {
746
+ return null;
747
+ }
748
+ }
749
+ async function readSubmoduleHeadSha(repo, repoPath, options) {
750
+ try {
751
+ const result = await runGit(repo, ["rev-parse", "HEAD"], { ...options, cwd: repoPath });
752
+ const sha = result.stdout.trim();
753
+ return /^[0-9a-f]{40}$/.test(sha) ? sha : null;
754
+ } catch {
755
+ return null;
756
+ }
757
+ }
693
758
  async function enrichSubmoduleWorktreeStatus(repo, submodule, options) {
694
759
  try {
695
760
  const result = await runGit(repo, ["status", "--porcelain=v2", "--branch"], {
@@ -704,28 +769,6 @@ async function enrichSubmoduleWorktreeStatus(repo, submodule, options) {
704
769
  submodule.error = formatGitError(error);
705
770
  }
706
771
  }
707
- function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
708
- const submodules = [];
709
- const ignoreSet = new Set(ignorePaths || []);
710
- for (const line of output.split("\n")) {
711
- if (!line.trim()) continue;
712
- const match = line.match(/^([\-+U\s])([0-9a-f]{40})\s+(\S+)(?:\s+\(([^)]+)\))?/);
713
- if (!match) continue;
714
- const prefix = match[1];
715
- const commit = match[2];
716
- const path41 = match[3];
717
- if (ignoreSet.has(path41)) continue;
718
- submodules.push({
719
- path: path41,
720
- commit,
721
- repoPath: repoRoot + "/" + path41,
722
- dirty: prefix === "U",
723
- outOfSync: prefix === "-" || prefix === "+",
724
- lastCheckedAt: Date.now()
725
- });
726
- }
727
- return submodules;
728
- }
729
772
  var lastKnownGoodStatus, DAEMON_RUNTIME_PACKAGES, WEB_ONLY_PACKAGES;
730
773
  var init_git_status = __esm({
731
774
  "src/git/git-status.ts"() {
@@ -3955,6 +3998,18 @@ var init_mesh_runtime_store = __esm({
3955
3998
  `).get(meshId, nodeId);
3956
3999
  return row?.count ?? 0;
3957
4000
  }
4001
+ /**
4002
+ * O(1) count of queue tasks in 'pending' status for a mesh. A COUNT(*) over the
4003
+ * indexed status column, so it avoids JSON.parse-ing every queue row — used as a
4004
+ * cheap guard before the reconcile loop runs a full triggerMeshQueue scan.
4005
+ */
4006
+ pendingQueueTaskCount(meshId) {
4007
+ const row = this.db.prepare(`
4008
+ SELECT COUNT(*) as count FROM mesh_queue
4009
+ WHERE mesh_id = ? AND status = 'pending'
4010
+ `).get(meshId);
4011
+ return row?.count ?? 0;
4012
+ }
3958
4013
  /**
3959
4014
  * Read the current per-mesh round-robin cursor (0 when unset). Used to rotate
3960
4015
  * the tie-break winner among nodes tied at the least load.
@@ -7858,6 +7913,405 @@ var init_mesh_events_stale = __esm({
7858
7913
  }
7859
7914
  });
7860
7915
 
7916
+ // src/cli-adapters/spawn-env.ts
7917
+ var import_session_host_core2;
7918
+ var init_spawn_env = __esm({
7919
+ "src/cli-adapters/spawn-env.ts"() {
7920
+ "use strict";
7921
+ import_session_host_core2 = require("@adhdev/session-host-core");
7922
+ }
7923
+ });
7924
+
7925
+ // src/cli-adapters/provider-cli-shared.ts
7926
+ function stripAnsi(str) {
7927
+ return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
7928
+ }
7929
+ function parseCount(params, fallback = 1) {
7930
+ const first = Number(String(params || "").split(";")[0] || fallback);
7931
+ return Math.max(1, Number.isFinite(first) ? first : fallback);
7932
+ }
7933
+ function isCombiningMark(ch) {
7934
+ return /[\u0300-\u036F\u1AB0-\u1AFF\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/.test(ch);
7935
+ }
7936
+ function isWideCodePoint(ch) {
7937
+ const cp = ch.codePointAt(0) || 0;
7938
+ return cp >= 4352 && (cp <= 4447 || cp === 9001 || cp === 9002 || cp >= 11904 && cp <= 42191 && cp !== 12351 || cp >= 44032 && cp <= 55203 || cp >= 63744 && cp <= 64255 || cp >= 65040 && cp <= 65049 || cp >= 65072 && cp <= 65135 || cp >= 65280 && cp <= 65376 || cp >= 65504 && cp <= 65510 || cp >= 127744 && cp <= 129791);
7939
+ }
7940
+ function stripTerminalNoise(str) {
7941
+ return String(str || "").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, "").replace(/\r+/g, "\n").replace(/[ \t]+\n/g, "\n").replace(/\n{4,}/g, "\n\n\n");
7942
+ }
7943
+ function sanitizeTerminalText(str) {
7944
+ const accumulator = new TerminalTranscriptAccumulator();
7945
+ return stripTerminalNoise(stripAnsi(accumulator.append(str)));
7946
+ }
7947
+ function listCliScriptNames(scripts) {
7948
+ if (!scripts) return [];
7949
+ return Object.entries(scripts).filter(([, fn]) => typeof fn === "function").map(([name]) => name);
7950
+ }
7951
+ function splitCliScreenLines(text) {
7952
+ return String(text || "").replace(/\u0007/g, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => line.replace(/\s+$/, ""));
7953
+ }
7954
+ function isPromptLikeCliLine(line) {
7955
+ const trimmed = String(line || "").trim();
7956
+ if (!trimmed) return false;
7957
+ return /^[❯›>]\s*(?:$|\S.*)$/.test(trimmed);
7958
+ }
7959
+ function buildCliScreenSnapshot(text) {
7960
+ const normalizedText = String(text || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
7961
+ const rawLines = splitCliScreenLines(normalizedText);
7962
+ const lines = rawLines.map((line, index, arr) => {
7963
+ const trimmed = String(line || "").trim();
7964
+ return {
7965
+ index,
7966
+ fromTop: index,
7967
+ fromBottom: arr.length - index - 1,
7968
+ text: line,
7969
+ trimmed,
7970
+ isEmpty: trimmed.length === 0
7971
+ };
7972
+ });
7973
+ const nonEmptyLines = lines.filter((line) => !line.isEmpty);
7974
+ const firstNonEmptyLine = nonEmptyLines[0] ?? null;
7975
+ const lastNonEmptyLine = nonEmptyLines[nonEmptyLines.length - 1] ?? null;
7976
+ let promptLineIndex = -1;
7977
+ for (let i = lines.length - 1; i >= 0; i -= 1) {
7978
+ if (isPromptLikeCliLine(lines[i].text)) {
7979
+ promptLineIndex = i;
7980
+ break;
7981
+ }
7982
+ }
7983
+ return {
7984
+ text: normalizedText,
7985
+ lineCount: lines.length,
7986
+ lines,
7987
+ nonEmptyLines,
7988
+ firstNonEmptyLineIndex: firstNonEmptyLine?.index ?? -1,
7989
+ lastNonEmptyLineIndex: lastNonEmptyLine?.index ?? -1,
7990
+ firstNonEmptyLine,
7991
+ lastNonEmptyLine,
7992
+ promptLineIndex,
7993
+ promptLine: promptLineIndex >= 0 ? lines[promptLineIndex] : null,
7994
+ linesAbovePrompt: promptLineIndex >= 0 ? lines.slice(0, promptLineIndex) : [...lines],
7995
+ linesBelowPrompt: promptLineIndex >= 0 ? lines.slice(promptLineIndex + 1) : []
7996
+ };
7997
+ }
7998
+ function findBinary(name) {
7999
+ const trimmed = String(name || "").trim();
8000
+ if (!trimmed) return trimmed;
8001
+ const expanded = trimmed.startsWith("~") ? path10.join(os5.homedir(), trimmed.slice(1)) : trimmed;
8002
+ if (path10.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
8003
+ return path10.isAbsolute(expanded) ? expanded : path10.resolve(expanded);
8004
+ }
8005
+ const isWin = os5.platform() === "win32";
8006
+ const paths = (process.env.PATH || "").split(path10.delimiter);
8007
+ const extraDirs = [];
8008
+ if (isWin) {
8009
+ if (process.env.APPDATA) extraDirs.push(path10.join(process.env.APPDATA, "npm"));
8010
+ try {
8011
+ extraDirs.push(path10.dirname(process.execPath));
8012
+ } catch {
8013
+ }
8014
+ } else {
8015
+ extraDirs.push(path10.join(os5.homedir(), ".npm-global", "bin"));
8016
+ extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
8017
+ try {
8018
+ extraDirs.push(path10.dirname(process.execPath));
8019
+ } catch {
8020
+ }
8021
+ }
8022
+ const searchDirs = [...paths, ...extraDirs];
8023
+ const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
8024
+ for (const p of searchDirs) {
8025
+ if (!p) continue;
8026
+ for (const ext of exes) {
8027
+ const fullPath = path10.join(p, trimmed + ext);
8028
+ try {
8029
+ const fs31 = require("fs");
8030
+ if (fs31.existsSync(fullPath)) {
8031
+ const stat2 = fs31.statSync(fullPath);
8032
+ if (stat2.isFile() && (isWin || stat2.mode & 73)) {
8033
+ return fullPath;
8034
+ }
8035
+ }
8036
+ } catch {
8037
+ }
8038
+ }
8039
+ }
8040
+ return isWin ? `${trimmed}.cmd` : trimmed;
8041
+ }
8042
+ function isScriptBinary(binaryPath) {
8043
+ if (!path10.isAbsolute(binaryPath)) return false;
8044
+ try {
8045
+ const fs31 = require("fs");
8046
+ const resolved = fs31.realpathSync(binaryPath);
8047
+ const head = Buffer.alloc(8);
8048
+ const fd = fs31.openSync(resolved, "r");
8049
+ fs31.readSync(fd, head, 0, 8, 0);
8050
+ fs31.closeSync(fd);
8051
+ let i = 0;
8052
+ if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
8053
+ return head[i] === 35 && head[i + 1] === 33;
8054
+ } catch {
8055
+ return false;
8056
+ }
8057
+ }
8058
+ function looksLikeMachOOrElf(filePath) {
8059
+ if (!path10.isAbsolute(filePath)) return false;
8060
+ try {
8061
+ const fs31 = require("fs");
8062
+ const resolved = fs31.realpathSync(filePath);
8063
+ const buf = Buffer.alloc(8);
8064
+ const fd = fs31.openSync(resolved, "r");
8065
+ fs31.readSync(fd, buf, 0, 8, 0);
8066
+ fs31.closeSync(fd);
8067
+ let i = 0;
8068
+ if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
8069
+ const b = buf.subarray(i);
8070
+ if (b.length < 4) return false;
8071
+ if (b[0] === 127 && b[1] === 69 && b[2] === 76 && b[3] === 70) return true;
8072
+ const le = b.readUInt32LE(0);
8073
+ const be = b.readUInt32BE(0);
8074
+ const magics = [4277009102, 4277009103, 3405691582, 3199925962];
8075
+ return magics.some((m) => m === le || m === be);
8076
+ } catch {
8077
+ return false;
8078
+ }
8079
+ }
8080
+ function shSingleQuote(arg) {
8081
+ if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
8082
+ if (os5.platform() === "win32") {
8083
+ return `"${arg.replace(/"/g, '""')}"`;
8084
+ }
8085
+ return `'${arg.replace(/'/g, `'\\''`)}'`;
8086
+ }
8087
+ function estimatePromptDisplayLines(text, cols = 80) {
8088
+ const normalized = String(text || "").replace(/\r/g, "");
8089
+ if (!normalized) return 1;
8090
+ return normalized.split("\n").reduce((sum, line) => sum + Math.max(1, Math.ceil(Math.max(1, line.length) / cols)), 0);
8091
+ }
8092
+ function extractPromptRetrySnippet(text) {
8093
+ const lines = String(text || "").replace(/\r/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
8094
+ const candidate = lines[lines.length - 1] || lines[0] || "";
8095
+ return candidate.slice(-120);
8096
+ }
8097
+ function normalizePromptText(text) {
8098
+ return String(text || "").replace(/\s+/g, " ").trim();
8099
+ }
8100
+ function compactPromptText(text) {
8101
+ return String(text || "").replace(/\s+/g, "").trim();
8102
+ }
8103
+ function promptLikelyVisible(screenText, promptSnippet) {
8104
+ const snippet = normalizePromptText(promptSnippet);
8105
+ if (!snippet) return false;
8106
+ const normalizedScreen = normalizePromptText(screenText);
8107
+ if (normalizedScreen.includes(snippet)) return true;
8108
+ const compactScreen = compactPromptText(screenText);
8109
+ const compactSnippet = compactPromptText(promptSnippet);
8110
+ if (compactSnippet && compactScreen.includes(compactSnippet)) return true;
8111
+ const tokens = snippet.split(/[^A-Za-z0-9_.:/-]+/).map((token) => token.trim()).filter((token) => token.length >= 4);
8112
+ if (tokens.length === 0) return false;
8113
+ const required = Math.min(tokens.length, 3);
8114
+ const matched = tokens.filter(
8115
+ (token) => normalizedScreen.includes(token) || compactScreen.includes(compactPromptText(token))
8116
+ ).length;
8117
+ return matched >= required;
8118
+ }
8119
+ function normalizeScreenSnapshot(text) {
8120
+ return sanitizeTerminalText(String(text || "")).replace(/\s+/g, " ").trim();
8121
+ }
8122
+ function parsePatternEntry(x) {
8123
+ if (x instanceof RegExp) return x;
8124
+ if (x && typeof x === "object" && typeof x.source === "string") {
8125
+ try {
8126
+ const s = x;
8127
+ return new RegExp(s.source, s.flags || "");
8128
+ } catch {
8129
+ return null;
8130
+ }
8131
+ }
8132
+ return null;
8133
+ }
8134
+ function coercePatternArray(raw) {
8135
+ if (!Array.isArray(raw)) return [];
8136
+ return raw.map(parsePatternEntry).filter((r) => r != null);
8137
+ }
8138
+ function normalizeCliProviderForRuntime(raw) {
8139
+ const patterns = raw && typeof raw === "object" ? raw.patterns : void 0;
8140
+ return {
8141
+ patterns: {
8142
+ approval: coercePatternArray(
8143
+ patterns && typeof patterns === "object" ? patterns.approval : void 0
8144
+ )
8145
+ }
8146
+ };
8147
+ }
8148
+ var os5, path10, TerminalTranscriptAccumulator, buildCliSpawnEnv;
8149
+ var init_provider_cli_shared = __esm({
8150
+ "src/cli-adapters/provider-cli-shared.ts"() {
8151
+ "use strict";
8152
+ os5 = __toESM(require("os"));
8153
+ path10 = __toESM(require("path"));
8154
+ init_spawn_env();
8155
+ TerminalTranscriptAccumulator = class {
8156
+ lines = [[]];
8157
+ row = 0;
8158
+ col = 0;
8159
+ savedCursor = null;
8160
+ pendingEscape = "";
8161
+ append(data) {
8162
+ const input = this.pendingEscape + String(data || "");
8163
+ this.pendingEscape = "";
8164
+ for (let i = 0; i < input.length; i += 1) {
8165
+ let ch = input[i];
8166
+ if (ch === "\x1B") {
8167
+ const consumed = this.consumeEscape(input.slice(i));
8168
+ if (consumed === 0) {
8169
+ this.pendingEscape = input.slice(i);
8170
+ break;
8171
+ }
8172
+ i += consumed - 1;
8173
+ continue;
8174
+ }
8175
+ const cp = input.codePointAt(i);
8176
+ if (cp && cp > 65535) {
8177
+ ch = String.fromCodePoint(cp);
8178
+ i += 1;
8179
+ }
8180
+ this.writeControlOrChar(ch);
8181
+ }
8182
+ return this.getText();
8183
+ }
8184
+ reset() {
8185
+ this.lines = [[]];
8186
+ this.row = 0;
8187
+ this.col = 0;
8188
+ this.savedCursor = null;
8189
+ this.pendingEscape = "";
8190
+ }
8191
+ getText() {
8192
+ return this.lines.map((line) => line.join("").replace(/[ \t]+$/g, "")).join("\n");
8193
+ }
8194
+ ensureRow(row = this.row) {
8195
+ while (this.lines.length <= row) this.lines.push([]);
8196
+ }
8197
+ writeControlOrChar(ch) {
8198
+ if (ch === "\r") {
8199
+ this.col = 0;
8200
+ return;
8201
+ }
8202
+ if (ch === "\n") {
8203
+ this.row += 1;
8204
+ this.col = 0;
8205
+ this.ensureRow();
8206
+ return;
8207
+ }
8208
+ if (ch === "\b") {
8209
+ this.col = Math.max(0, this.col - 1);
8210
+ return;
8211
+ }
8212
+ if (ch < " " || ch === "\x7F") return;
8213
+ this.ensureRow();
8214
+ const line = this.lines[this.row];
8215
+ if (isCombiningMark(ch) && this.col > 0) {
8216
+ line[this.col - 1] = `${line[this.col - 1] || ""}${ch}`;
8217
+ return;
8218
+ }
8219
+ while (line.length < this.col) line.push(" ");
8220
+ const wide = isWideCodePoint(ch);
8221
+ line[this.col] = ch;
8222
+ if (wide) line[this.col + 1] = "";
8223
+ this.col += wide ? 2 : 1;
8224
+ }
8225
+ consumeEscape(seq) {
8226
+ if (seq.length < 2) return 0;
8227
+ const next = seq[1];
8228
+ if (next === "7") {
8229
+ this.savedCursor = { row: this.row, col: this.col };
8230
+ return 2;
8231
+ }
8232
+ if (next === "8") {
8233
+ if (this.savedCursor) {
8234
+ this.row = this.savedCursor.row;
8235
+ this.col = this.savedCursor.col;
8236
+ this.ensureRow();
8237
+ }
8238
+ return 2;
8239
+ }
8240
+ if (next === "]") {
8241
+ const bel = seq.indexOf("\x07", 2);
8242
+ const st = seq.indexOf("\x1B\\", 2);
8243
+ const end = bel >= 0 && (st < 0 || bel < st) ? bel + 1 : st >= 0 ? st + 2 : 0;
8244
+ return end;
8245
+ }
8246
+ if (next === "[") {
8247
+ const match = seq.match(/^\x1B\[([0-?]*)([ -/]*)([@-~])/);
8248
+ if (!match) return seq.length < 32 ? 0 : 1;
8249
+ this.applyCsi(match[1] || "", match[3]);
8250
+ return match[0].length;
8251
+ }
8252
+ if (/[P^_X]/.test(next)) {
8253
+ const bel = seq.indexOf("\x07", 2);
8254
+ const st = seq.indexOf("\x1B\\", 2);
8255
+ const end = bel >= 0 && (st < 0 || bel < st) ? bel + 1 : st >= 0 ? st + 2 : 0;
8256
+ return end;
8257
+ }
8258
+ return 2;
8259
+ }
8260
+ applyCsi(params, final) {
8261
+ const count = parseCount(params);
8262
+ this.ensureRow();
8263
+ if (final === "A") this.row = Math.max(0, this.row - count);
8264
+ else if (final === "B") this.row += count;
8265
+ else if (final === "C") {
8266
+ const line = this.lines[this.row];
8267
+ for (let c = this.col; c < this.col + count; c += 1) {
8268
+ if (line[c] === void 0) line[c] = " ";
8269
+ }
8270
+ this.col += count;
8271
+ } else if (final === "D") this.col = Math.max(0, this.col - count);
8272
+ else if (final === "G") this.col = Math.max(0, count - 1);
8273
+ else if (final === "H" || final === "f") {
8274
+ const parts = String(params || "").split(";");
8275
+ this.row = Math.max(0, (Number(parts[0] || 1) || 1) - 1);
8276
+ this.col = Math.max(0, (Number(parts[1] || 1) || 1) - 1);
8277
+ } else if (final === "J") {
8278
+ const mode = Number(params || 0) || 0;
8279
+ if (mode === 2 || mode === 3) {
8280
+ this.lines = [[]];
8281
+ this.row = 0;
8282
+ this.col = 0;
8283
+ } else if (mode === 0) {
8284
+ this.lines[this.row] = this.lines[this.row].slice(0, this.col);
8285
+ this.lines.splice(this.row + 1);
8286
+ } else if (mode === 1) {
8287
+ for (let r = 0; r < this.row; r += 1) this.lines[r] = [];
8288
+ const line = this.lines[this.row];
8289
+ for (let c = 0; c <= Math.min(this.col, line.length - 1); c += 1) line[c] = " ";
8290
+ }
8291
+ } else if (final === "K") {
8292
+ const mode = Number(params || 0) || 0;
8293
+ const line = this.lines[this.row];
8294
+ if (mode === 2) this.lines[this.row] = [];
8295
+ else if (mode === 1) {
8296
+ for (let c = 0; c <= Math.min(this.col, line.length - 1); c += 1) line[c] = " ";
8297
+ } else {
8298
+ this.lines[this.row] = line.slice(0, this.col);
8299
+ }
8300
+ } else if (final === "s") {
8301
+ this.savedCursor = { row: this.row, col: this.col };
8302
+ } else if (final === "u") {
8303
+ if (this.savedCursor) {
8304
+ this.row = this.savedCursor.row;
8305
+ this.col = this.savedCursor.col;
8306
+ }
8307
+ }
8308
+ this.ensureRow();
8309
+ }
8310
+ };
8311
+ buildCliSpawnEnv = import_session_host_core2.sanitizeSpawnEnv;
8312
+ }
8313
+ });
8314
+
7861
8315
  // src/detection/cli-detector.ts
7862
8316
  function parseVersion(raw) {
7863
8317
  const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
@@ -7870,22 +8324,31 @@ function shellQuote(value) {
7870
8324
  function expandHome(value) {
7871
8325
  const trimmed = value.trim();
7872
8326
  if (!trimmed.startsWith("~")) return trimmed;
7873
- return path10.join(os5.homedir(), trimmed.slice(1));
8327
+ return path11.join(os6.homedir(), trimmed.slice(1));
7874
8328
  }
7875
8329
  function isExplicitCommandPath(command) {
7876
8330
  const trimmed = command.trim();
7877
- return path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
8331
+ return path11.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
7878
8332
  }
7879
8333
  function resolveCommandPath(command) {
7880
8334
  const trimmed = command.trim();
7881
8335
  if (!trimmed) return null;
7882
8336
  if (isExplicitCommandPath(trimmed)) {
7883
8337
  const expanded = expandHome(trimmed);
7884
- const candidate = path10.isAbsolute(expanded) ? expanded : path10.resolve(expanded);
8338
+ const candidate = path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
7885
8339
  return (0, import_fs9.existsSync)(candidate) ? candidate : null;
7886
8340
  }
7887
8341
  return null;
7888
8342
  }
8343
+ async function resolveDetectionPath(command, whichCmd) {
8344
+ const explicitPath = resolveCommandPath(command);
8345
+ if (explicitPath) return explicitPath;
8346
+ const whichResult = await execAsync(`${whichCmd} ${shellQuote(command)}`);
8347
+ if (whichResult) return whichResult.split("\n")[0];
8348
+ const resolved = findBinary(command);
8349
+ if (path11.isAbsolute(resolved) && (0, import_fs9.existsSync)(resolved)) return resolved;
8350
+ return null;
8351
+ }
7889
8352
  function execAsync(cmd, timeoutMs = 5e3) {
7890
8353
  return new Promise((resolve24) => {
7891
8354
  const child = (0, import_child_process.exec)(cmd, {
@@ -7903,17 +8366,15 @@ function execAsync(cmd, timeoutMs = 5e3) {
7903
8366
  });
7904
8367
  }
7905
8368
  async function detectCLIs(providerLoader, options) {
7906
- const platform10 = os5.platform();
8369
+ const platform10 = os6.platform();
7907
8370
  const whichCmd = platform10 === "win32" ? "where" : "which";
7908
8371
  const includeVersion = options?.includeVersion !== false;
7909
8372
  const cliList = providerLoader ? providerLoader.getCliDetectionList() : [];
7910
8373
  const results = await Promise.all(
7911
8374
  cliList.map(async (cli) => {
7912
8375
  try {
7913
- const explicitPath = resolveCommandPath(cli.command);
7914
- const pathResult = explicitPath || await execAsync(`${whichCmd} ${shellQuote(cli.command)}`);
7915
- if (!pathResult) return { ...cli, installed: false };
7916
- const firstPath = explicitPath || pathResult.split("\n")[0];
8376
+ const firstPath = await resolveDetectionPath(cli.command, whichCmd);
8377
+ if (!firstPath) return { ...cli, installed: false };
7917
8378
  let version;
7918
8379
  if (includeVersion) {
7919
8380
  const versionCommands = [
@@ -7947,13 +8408,11 @@ async function detectCLI(cliId, providerLoader, options) {
7947
8408
  const cliList = providerLoader.getCliDetectionList();
7948
8409
  const target = cliList.find((c) => c.id === resolvedId);
7949
8410
  if (target) {
7950
- const platform10 = os5.platform();
8411
+ const platform10 = os6.platform();
7951
8412
  const whichCmd = platform10 === "win32" ? "where" : "which";
7952
8413
  try {
7953
- const explicitPath = resolveCommandPath(target.command);
7954
- const pathResult = explicitPath || await execAsync(`${whichCmd} ${shellQuote(target.command)}`);
7955
- if (!pathResult) return null;
7956
- const firstPath = explicitPath || pathResult.split("\n")[0];
8414
+ const firstPath = await resolveDetectionPath(target.command, whichCmd);
8415
+ if (!firstPath) return null;
7957
8416
  let version;
7958
8417
  if (options?.includeVersion !== false) {
7959
8418
  const versionCommands = [
@@ -7982,14 +8441,15 @@ async function detectCLI(cliId, providerLoader, options) {
7982
8441
  const all = await detectCLIs(providerLoader, options);
7983
8442
  return all.find((c) => c.id === resolvedId && c.installed) || null;
7984
8443
  }
7985
- var import_child_process, os5, path10, import_fs9;
8444
+ var import_child_process, os6, path11, import_fs9;
7986
8445
  var init_cli_detector = __esm({
7987
8446
  "src/detection/cli-detector.ts"() {
7988
8447
  "use strict";
7989
8448
  import_child_process = require("child_process");
7990
- os5 = __toESM(require("os"));
7991
- path10 = __toESM(require("path"));
8449
+ os6 = __toESM(require("os"));
8450
+ path11 = __toESM(require("path"));
7992
8451
  import_fs9 = require("fs");
8452
+ init_provider_cli_shared();
7993
8453
  }
7994
8454
  });
7995
8455
 
@@ -8888,7 +9348,7 @@ async function triggerMeshQueue(components, meshId) {
8888
9348
  }
8889
9349
  const remoteCandidates = [];
8890
9350
  for (const idle of remoteSessions) {
8891
- const node = mesh.nodes.find((n) => n.id === idle.nodeId);
9351
+ const node = mesh.nodes.find((n) => meshNodeIdMatches(n, idle.nodeId));
8892
9352
  if (node) {
8893
9353
  remoteIdleSessionsChecked += 1;
8894
9354
  remoteCandidates.push({ nodeId: idle.nodeId, sessionId: idle.sessionId, providerType: idle.providerType, origin: "remote", node });
@@ -9692,6 +10152,21 @@ async function runMeshReconcileTick(components) {
9692
10152
  }
9693
10153
  }
9694
10154
  }
10155
+ for (const mesh of listMeshes()) {
10156
+ const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
10157
+ if (!daemonHostsMesh(mesh, selfIds)) continue;
10158
+ if (store) {
10159
+ try {
10160
+ if (store.pendingQueueTaskCount(mesh.id) === 0) continue;
10161
+ } catch {
10162
+ }
10163
+ }
10164
+ try {
10165
+ await triggerMeshQueue(components, mesh.id);
10166
+ } catch (e) {
10167
+ LOG.warn("MeshReconcile", `Pending-claim recovery trigger failed for mesh ${mesh.id}: ${e?.message || e}`);
10168
+ }
10169
+ }
9695
10170
  const coordinators = findLiveCoordinators(components);
9696
10171
  if (coordinators.length === 0) {
9697
10172
  return;
@@ -10578,16 +11053,16 @@ __export(external_sources_exports, {
10578
11053
  sourcesProviding: () => sourcesProviding
10579
11054
  });
10580
11055
  function adhdevDir() {
10581
- return path15.join(os10.homedir(), ".adhdev");
11056
+ return path16.join(os11.homedir(), ".adhdev");
10582
11057
  }
10583
11058
  function externalRoot() {
10584
- return path15.join(adhdevDir(), "external");
11059
+ return path16.join(adhdevDir(), "external");
10585
11060
  }
10586
11061
  function sourcesFilePath() {
10587
- return path15.join(adhdevDir(), SOURCES_FILENAME);
11062
+ return path16.join(adhdevDir(), SOURCES_FILENAME);
10588
11063
  }
10589
11064
  function activeFilePath() {
10590
- return path15.join(adhdevDir(), ACTIVE_FILENAME);
11065
+ return path16.join(adhdevDir(), ACTIVE_FILENAME);
10591
11066
  }
10592
11067
  function ensureAdhdevDir() {
10593
11068
  const d = adhdevDir();
@@ -10654,7 +11129,7 @@ function inventoryExternalSources() {
10654
11129
  for (const sourceEntry of entries) {
10655
11130
  if (!sourceEntry.isDirectory()) continue;
10656
11131
  const sourceName = sourceEntry.name;
10657
- const sourceDir = path15.join(root, sourceName);
11132
+ const sourceDir = path16.join(root, sourceName);
10658
11133
  const providers = {};
10659
11134
  let categoryEntries;
10660
11135
  try {
@@ -10665,7 +11140,7 @@ function inventoryExternalSources() {
10665
11140
  for (const categoryEntry of categoryEntries) {
10666
11141
  if (!categoryEntry.isDirectory()) continue;
10667
11142
  const category = categoryEntry.name;
10668
- const categoryDir = path15.join(sourceDir, category);
11143
+ const categoryDir = path16.join(sourceDir, category);
10669
11144
  let typeEntries;
10670
11145
  try {
10671
11146
  typeEntries = fs8.readdirSync(categoryDir, { withFileTypes: true });
@@ -10675,9 +11150,9 @@ function inventoryExternalSources() {
10675
11150
  const types = [];
10676
11151
  for (const typeEntry of typeEntries) {
10677
11152
  if (!typeEntry.isDirectory()) continue;
10678
- const typeDir = path15.join(categoryDir, typeEntry.name);
10679
- const hasV1 = fs8.existsSync(path15.join(typeDir, "provider.v1.json"));
10680
- const hasV0 = fs8.existsSync(path15.join(typeDir, "provider.json"));
11153
+ const typeDir = path16.join(categoryDir, typeEntry.name);
11154
+ const hasV1 = fs8.existsSync(path16.join(typeDir, "provider.v1.json"));
11155
+ const hasV0 = fs8.existsSync(path16.join(typeDir, "provider.json"));
10681
11156
  if (hasV1 || hasV0) types.push(typeEntry.name);
10682
11157
  }
10683
11158
  if (types.length > 0) providers[category] = types;
@@ -10700,13 +11175,13 @@ function resolveActiveSource(category, type, activeFile) {
10700
11175
  }
10701
11176
  return { source: candidates[0], ambiguous: true, candidates };
10702
11177
  }
10703
- var fs8, os10, path15, SOURCES_FILENAME, ACTIVE_FILENAME;
11178
+ var fs8, os11, path16, SOURCES_FILENAME, ACTIVE_FILENAME;
10704
11179
  var init_external_sources = __esm({
10705
11180
  "src/providers/external-sources.ts"() {
10706
11181
  "use strict";
10707
11182
  fs8 = __toESM(require("fs"));
10708
- os10 = __toESM(require("os"));
10709
- path15 = __toESM(require("path"));
11183
+ os11 = __toESM(require("os"));
11184
+ path16 = __toESM(require("path"));
10710
11185
  SOURCES_FILENAME = "providers-sources.json";
10711
11186
  ACTIVE_FILENAME = "providers-active.json";
10712
11187
  }
@@ -10829,19 +11304,19 @@ var init_ghostty_vt_backend = __esm({
10829
11304
  function getTerminalBackendRuntimeStatus() {
10830
11305
  return { backend: "ghostty-vt" };
10831
11306
  }
10832
- var import_session_host_core2, DEFAULT_SCROLLBACK, TerminalScreen;
11307
+ var import_session_host_core3, DEFAULT_SCROLLBACK, TerminalScreen;
10833
11308
  var init_terminal_screen = __esm({
10834
11309
  "src/cli-adapters/terminal-screen.ts"() {
10835
11310
  "use strict";
10836
11311
  init_ghostty_vt_backend();
10837
- import_session_host_core2 = require("@adhdev/session-host-core");
11312
+ import_session_host_core3 = require("@adhdev/session-host-core");
10838
11313
  DEFAULT_SCROLLBACK = 2e3;
10839
11314
  TerminalScreen = class {
10840
11315
  backendKind = "ghostty-vt";
10841
11316
  rows;
10842
11317
  cols;
10843
11318
  terminal;
10844
- constructor(rows = import_session_host_core2.DEFAULT_SESSION_HOST_ROWS, cols = import_session_host_core2.DEFAULT_SESSION_HOST_COLS) {
11319
+ constructor(rows = import_session_host_core3.DEFAULT_SESSION_HOST_ROWS, cols = import_session_host_core3.DEFAULT_SESSION_HOST_COLS) {
10845
11320
  this.rows = Math.max(1, rows | 0);
10846
11321
  this.cols = Math.max(1, cols | 0);
10847
11322
  this.terminal = this.createBackend();
@@ -10884,21 +11359,31 @@ var init_terminal_screen = __esm({
10884
11359
  }
10885
11360
  });
10886
11361
 
10887
- // src/cli-adapters/spawn-env.ts
10888
- var import_session_host_core3;
10889
- var init_spawn_env = __esm({
10890
- "src/cli-adapters/spawn-env.ts"() {
10891
- "use strict";
10892
- import_session_host_core3 = require("@adhdev/session-host-core");
10893
- }
10894
- });
10895
-
10896
11362
  // src/cli-adapters/resolve-executable.ts
11363
+ function resolveWin32GlobalBin(trimmed) {
11364
+ if (path17.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
11365
+ return null;
11366
+ }
11367
+ const extraDirs = [];
11368
+ if (process.env.APPDATA) extraDirs.push(path17.join(process.env.APPDATA, "npm"));
11369
+ try {
11370
+ extraDirs.push(path17.dirname(process.execPath));
11371
+ } catch {
11372
+ }
11373
+ for (const dir of extraDirs) {
11374
+ if (!dir) continue;
11375
+ for (const ext of WIN_EXEC_EXT) {
11376
+ const full = path17.join(dir, trimmed + ext);
11377
+ if ((0, import_fs13.existsSync)(full)) return full;
11378
+ }
11379
+ }
11380
+ return null;
11381
+ }
10897
11382
  function resolveWin32Executable(command) {
10898
11383
  if (process.platform !== "win32") return command;
10899
11384
  const trimmed = (command || "").trim();
10900
11385
  if (!trimmed) return command;
10901
- if (path16.isAbsolute(trimmed) && (0, import_fs13.existsSync)(trimmed)) return trimmed;
11386
+ if (path17.isAbsolute(trimmed) && (0, import_fs13.existsSync)(trimmed)) return trimmed;
10902
11387
  try {
10903
11388
  const out = (0, import_child_process4.execFileSync)("where", [trimmed], {
10904
11389
  encoding: "utf8",
@@ -10906,21 +11391,24 @@ function resolveWin32Executable(command) {
10906
11391
  }).trim();
10907
11392
  if (out) {
10908
11393
  const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
10909
- const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path16.extname(m).toLowerCase()));
11394
+ const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path17.extname(m).toLowerCase()));
10910
11395
  return direct || matches[0] || command;
10911
11396
  }
10912
11397
  } catch {
10913
11398
  }
11399
+ const globalBin = resolveWin32GlobalBin(trimmed);
11400
+ if (globalBin) return globalBin;
10914
11401
  return command;
10915
11402
  }
10916
- var import_child_process4, import_fs13, path16, DIRECT_EXEC_EXT;
11403
+ var import_child_process4, import_fs13, path17, DIRECT_EXEC_EXT, WIN_EXEC_EXT;
10917
11404
  var init_resolve_executable = __esm({
10918
11405
  "src/cli-adapters/resolve-executable.ts"() {
10919
11406
  "use strict";
10920
11407
  import_child_process4 = require("child_process");
10921
11408
  import_fs13 = require("fs");
10922
- path16 = __toESM(require("path"));
11409
+ path17 = __toESM(require("path"));
10923
11410
  DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
11411
+ WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
10924
11412
  }
10925
11413
  });
10926
11414
 
@@ -10933,17 +11421,17 @@ function loadNodePty() {
10933
11421
  if (cachedPty !== void 0) return cachedPty;
10934
11422
  try {
10935
11423
  cachedPty = require("node-pty");
10936
- (0, import_session_host_core3.ensureNodePtySpawnHelperPermissions)();
11424
+ (0, import_session_host_core2.ensureNodePtySpawnHelperPermissions)();
10937
11425
  } catch {
10938
11426
  cachedPty = null;
10939
11427
  }
10940
11428
  return cachedPty;
10941
11429
  }
10942
- var os11, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory;
11430
+ var os12, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory;
10943
11431
  var init_pty_transport = __esm({
10944
11432
  "src/cli-adapters/pty-transport.ts"() {
10945
11433
  "use strict";
10946
- os11 = __toESM(require("os"));
11434
+ os12 = __toESM(require("os"));
10947
11435
  init_spawn_env();
10948
11436
  init_resolve_executable();
10949
11437
  NodePtyRuntimeTransport = class {
@@ -10983,9 +11471,9 @@ var init_pty_transport = __esm({
10983
11471
  try {
10984
11472
  const fs31 = require("fs");
10985
11473
  const stat2 = fs31.statSync(cwd);
10986
- if (!stat2.isDirectory()) cwd = os11.homedir();
11474
+ if (!stat2.isDirectory()) cwd = os12.homedir();
10987
11475
  } catch {
10988
- cwd = os11.homedir();
11476
+ cwd = os12.homedir();
10989
11477
  }
10990
11478
  }
10991
11479
  const handle = pty.spawn(resolveWin32Executable(command), args, {
@@ -11001,396 +11489,6 @@ var init_pty_transport = __esm({
11001
11489
  }
11002
11490
  });
11003
11491
 
11004
- // src/cli-adapters/provider-cli-shared.ts
11005
- function stripAnsi(str) {
11006
- return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
11007
- }
11008
- function parseCount(params, fallback = 1) {
11009
- const first = Number(String(params || "").split(";")[0] || fallback);
11010
- return Math.max(1, Number.isFinite(first) ? first : fallback);
11011
- }
11012
- function isCombiningMark(ch) {
11013
- return /[\u0300-\u036F\u1AB0-\u1AFF\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/.test(ch);
11014
- }
11015
- function isWideCodePoint(ch) {
11016
- const cp = ch.codePointAt(0) || 0;
11017
- return cp >= 4352 && (cp <= 4447 || cp === 9001 || cp === 9002 || cp >= 11904 && cp <= 42191 && cp !== 12351 || cp >= 44032 && cp <= 55203 || cp >= 63744 && cp <= 64255 || cp >= 65040 && cp <= 65049 || cp >= 65072 && cp <= 65135 || cp >= 65280 && cp <= 65376 || cp >= 65504 && cp <= 65510 || cp >= 127744 && cp <= 129791);
11018
- }
11019
- function stripTerminalNoise(str) {
11020
- return String(str || "").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, "").replace(/\r+/g, "\n").replace(/[ \t]+\n/g, "\n").replace(/\n{4,}/g, "\n\n\n");
11021
- }
11022
- function sanitizeTerminalText(str) {
11023
- const accumulator = new TerminalTranscriptAccumulator();
11024
- return stripTerminalNoise(stripAnsi(accumulator.append(str)));
11025
- }
11026
- function listCliScriptNames(scripts) {
11027
- if (!scripts) return [];
11028
- return Object.entries(scripts).filter(([, fn]) => typeof fn === "function").map(([name]) => name);
11029
- }
11030
- function splitCliScreenLines(text) {
11031
- return String(text || "").replace(/\u0007/g, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => line.replace(/\s+$/, ""));
11032
- }
11033
- function isPromptLikeCliLine(line) {
11034
- const trimmed = String(line || "").trim();
11035
- if (!trimmed) return false;
11036
- return /^[❯›>]\s*(?:$|\S.*)$/.test(trimmed);
11037
- }
11038
- function buildCliScreenSnapshot(text) {
11039
- const normalizedText = String(text || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
11040
- const rawLines = splitCliScreenLines(normalizedText);
11041
- const lines = rawLines.map((line, index, arr) => {
11042
- const trimmed = String(line || "").trim();
11043
- return {
11044
- index,
11045
- fromTop: index,
11046
- fromBottom: arr.length - index - 1,
11047
- text: line,
11048
- trimmed,
11049
- isEmpty: trimmed.length === 0
11050
- };
11051
- });
11052
- const nonEmptyLines = lines.filter((line) => !line.isEmpty);
11053
- const firstNonEmptyLine = nonEmptyLines[0] ?? null;
11054
- const lastNonEmptyLine = nonEmptyLines[nonEmptyLines.length - 1] ?? null;
11055
- let promptLineIndex = -1;
11056
- for (let i = lines.length - 1; i >= 0; i -= 1) {
11057
- if (isPromptLikeCliLine(lines[i].text)) {
11058
- promptLineIndex = i;
11059
- break;
11060
- }
11061
- }
11062
- return {
11063
- text: normalizedText,
11064
- lineCount: lines.length,
11065
- lines,
11066
- nonEmptyLines,
11067
- firstNonEmptyLineIndex: firstNonEmptyLine?.index ?? -1,
11068
- lastNonEmptyLineIndex: lastNonEmptyLine?.index ?? -1,
11069
- firstNonEmptyLine,
11070
- lastNonEmptyLine,
11071
- promptLineIndex,
11072
- promptLine: promptLineIndex >= 0 ? lines[promptLineIndex] : null,
11073
- linesAbovePrompt: promptLineIndex >= 0 ? lines.slice(0, promptLineIndex) : [...lines],
11074
- linesBelowPrompt: promptLineIndex >= 0 ? lines.slice(promptLineIndex + 1) : []
11075
- };
11076
- }
11077
- function findBinary(name) {
11078
- const trimmed = String(name || "").trim();
11079
- if (!trimmed) return trimmed;
11080
- const expanded = trimmed.startsWith("~") ? path17.join(os12.homedir(), trimmed.slice(1)) : trimmed;
11081
- if (path17.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
11082
- return path17.isAbsolute(expanded) ? expanded : path17.resolve(expanded);
11083
- }
11084
- const isWin = os12.platform() === "win32";
11085
- const paths = (process.env.PATH || "").split(path17.delimiter);
11086
- const extraDirs = [];
11087
- if (isWin) {
11088
- if (process.env.APPDATA) extraDirs.push(path17.join(process.env.APPDATA, "npm"));
11089
- try {
11090
- extraDirs.push(path17.dirname(process.execPath));
11091
- } catch {
11092
- }
11093
- } else {
11094
- extraDirs.push(path17.join(os12.homedir(), ".npm-global", "bin"));
11095
- extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
11096
- try {
11097
- extraDirs.push(path17.dirname(process.execPath));
11098
- } catch {
11099
- }
11100
- }
11101
- const searchDirs = [...paths, ...extraDirs];
11102
- const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
11103
- for (const p of searchDirs) {
11104
- if (!p) continue;
11105
- for (const ext of exes) {
11106
- const fullPath = path17.join(p, trimmed + ext);
11107
- try {
11108
- const fs31 = require("fs");
11109
- if (fs31.existsSync(fullPath)) {
11110
- const stat2 = fs31.statSync(fullPath);
11111
- if (stat2.isFile() && (isWin || stat2.mode & 73)) {
11112
- return fullPath;
11113
- }
11114
- }
11115
- } catch {
11116
- }
11117
- }
11118
- }
11119
- return isWin ? `${trimmed}.cmd` : trimmed;
11120
- }
11121
- function isScriptBinary(binaryPath) {
11122
- if (!path17.isAbsolute(binaryPath)) return false;
11123
- try {
11124
- const fs31 = require("fs");
11125
- const resolved = fs31.realpathSync(binaryPath);
11126
- const head = Buffer.alloc(8);
11127
- const fd = fs31.openSync(resolved, "r");
11128
- fs31.readSync(fd, head, 0, 8, 0);
11129
- fs31.closeSync(fd);
11130
- let i = 0;
11131
- if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
11132
- return head[i] === 35 && head[i + 1] === 33;
11133
- } catch {
11134
- return false;
11135
- }
11136
- }
11137
- function looksLikeMachOOrElf(filePath) {
11138
- if (!path17.isAbsolute(filePath)) return false;
11139
- try {
11140
- const fs31 = require("fs");
11141
- const resolved = fs31.realpathSync(filePath);
11142
- const buf = Buffer.alloc(8);
11143
- const fd = fs31.openSync(resolved, "r");
11144
- fs31.readSync(fd, buf, 0, 8, 0);
11145
- fs31.closeSync(fd);
11146
- let i = 0;
11147
- if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
11148
- const b = buf.subarray(i);
11149
- if (b.length < 4) return false;
11150
- if (b[0] === 127 && b[1] === 69 && b[2] === 76 && b[3] === 70) return true;
11151
- const le = b.readUInt32LE(0);
11152
- const be = b.readUInt32BE(0);
11153
- const magics = [4277009102, 4277009103, 3405691582, 3199925962];
11154
- return magics.some((m) => m === le || m === be);
11155
- } catch {
11156
- return false;
11157
- }
11158
- }
11159
- function shSingleQuote(arg) {
11160
- if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
11161
- if (os12.platform() === "win32") {
11162
- return `"${arg.replace(/"/g, '""')}"`;
11163
- }
11164
- return `'${arg.replace(/'/g, `'\\''`)}'`;
11165
- }
11166
- function estimatePromptDisplayLines(text, cols = 80) {
11167
- const normalized = String(text || "").replace(/\r/g, "");
11168
- if (!normalized) return 1;
11169
- return normalized.split("\n").reduce((sum, line) => sum + Math.max(1, Math.ceil(Math.max(1, line.length) / cols)), 0);
11170
- }
11171
- function extractPromptRetrySnippet(text) {
11172
- const lines = String(text || "").replace(/\r/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
11173
- const candidate = lines[lines.length - 1] || lines[0] || "";
11174
- return candidate.slice(-120);
11175
- }
11176
- function normalizePromptText(text) {
11177
- return String(text || "").replace(/\s+/g, " ").trim();
11178
- }
11179
- function compactPromptText(text) {
11180
- return String(text || "").replace(/\s+/g, "").trim();
11181
- }
11182
- function promptLikelyVisible(screenText, promptSnippet) {
11183
- const snippet = normalizePromptText(promptSnippet);
11184
- if (!snippet) return false;
11185
- const normalizedScreen = normalizePromptText(screenText);
11186
- if (normalizedScreen.includes(snippet)) return true;
11187
- const compactScreen = compactPromptText(screenText);
11188
- const compactSnippet = compactPromptText(promptSnippet);
11189
- if (compactSnippet && compactScreen.includes(compactSnippet)) return true;
11190
- const tokens = snippet.split(/[^A-Za-z0-9_.:/-]+/).map((token) => token.trim()).filter((token) => token.length >= 4);
11191
- if (tokens.length === 0) return false;
11192
- const required = Math.min(tokens.length, 3);
11193
- const matched = tokens.filter(
11194
- (token) => normalizedScreen.includes(token) || compactScreen.includes(compactPromptText(token))
11195
- ).length;
11196
- return matched >= required;
11197
- }
11198
- function normalizeScreenSnapshot(text) {
11199
- return sanitizeTerminalText(String(text || "")).replace(/\s+/g, " ").trim();
11200
- }
11201
- function parsePatternEntry(x) {
11202
- if (x instanceof RegExp) return x;
11203
- if (x && typeof x === "object" && typeof x.source === "string") {
11204
- try {
11205
- const s = x;
11206
- return new RegExp(s.source, s.flags || "");
11207
- } catch {
11208
- return null;
11209
- }
11210
- }
11211
- return null;
11212
- }
11213
- function coercePatternArray(raw) {
11214
- if (!Array.isArray(raw)) return [];
11215
- return raw.map(parsePatternEntry).filter((r) => r != null);
11216
- }
11217
- function normalizeCliProviderForRuntime(raw) {
11218
- const patterns = raw && typeof raw === "object" ? raw.patterns : void 0;
11219
- return {
11220
- patterns: {
11221
- approval: coercePatternArray(
11222
- patterns && typeof patterns === "object" ? patterns.approval : void 0
11223
- )
11224
- }
11225
- };
11226
- }
11227
- var os12, path17, TerminalTranscriptAccumulator, buildCliSpawnEnv;
11228
- var init_provider_cli_shared = __esm({
11229
- "src/cli-adapters/provider-cli-shared.ts"() {
11230
- "use strict";
11231
- os12 = __toESM(require("os"));
11232
- path17 = __toESM(require("path"));
11233
- init_spawn_env();
11234
- TerminalTranscriptAccumulator = class {
11235
- lines = [[]];
11236
- row = 0;
11237
- col = 0;
11238
- savedCursor = null;
11239
- pendingEscape = "";
11240
- append(data) {
11241
- const input = this.pendingEscape + String(data || "");
11242
- this.pendingEscape = "";
11243
- for (let i = 0; i < input.length; i += 1) {
11244
- let ch = input[i];
11245
- if (ch === "\x1B") {
11246
- const consumed = this.consumeEscape(input.slice(i));
11247
- if (consumed === 0) {
11248
- this.pendingEscape = input.slice(i);
11249
- break;
11250
- }
11251
- i += consumed - 1;
11252
- continue;
11253
- }
11254
- const cp = input.codePointAt(i);
11255
- if (cp && cp > 65535) {
11256
- ch = String.fromCodePoint(cp);
11257
- i += 1;
11258
- }
11259
- this.writeControlOrChar(ch);
11260
- }
11261
- return this.getText();
11262
- }
11263
- reset() {
11264
- this.lines = [[]];
11265
- this.row = 0;
11266
- this.col = 0;
11267
- this.savedCursor = null;
11268
- this.pendingEscape = "";
11269
- }
11270
- getText() {
11271
- return this.lines.map((line) => line.join("").replace(/[ \t]+$/g, "")).join("\n");
11272
- }
11273
- ensureRow(row = this.row) {
11274
- while (this.lines.length <= row) this.lines.push([]);
11275
- }
11276
- writeControlOrChar(ch) {
11277
- if (ch === "\r") {
11278
- this.col = 0;
11279
- return;
11280
- }
11281
- if (ch === "\n") {
11282
- this.row += 1;
11283
- this.col = 0;
11284
- this.ensureRow();
11285
- return;
11286
- }
11287
- if (ch === "\b") {
11288
- this.col = Math.max(0, this.col - 1);
11289
- return;
11290
- }
11291
- if (ch < " " || ch === "\x7F") return;
11292
- this.ensureRow();
11293
- const line = this.lines[this.row];
11294
- if (isCombiningMark(ch) && this.col > 0) {
11295
- line[this.col - 1] = `${line[this.col - 1] || ""}${ch}`;
11296
- return;
11297
- }
11298
- while (line.length < this.col) line.push(" ");
11299
- const wide = isWideCodePoint(ch);
11300
- line[this.col] = ch;
11301
- if (wide) line[this.col + 1] = "";
11302
- this.col += wide ? 2 : 1;
11303
- }
11304
- consumeEscape(seq) {
11305
- if (seq.length < 2) return 0;
11306
- const next = seq[1];
11307
- if (next === "7") {
11308
- this.savedCursor = { row: this.row, col: this.col };
11309
- return 2;
11310
- }
11311
- if (next === "8") {
11312
- if (this.savedCursor) {
11313
- this.row = this.savedCursor.row;
11314
- this.col = this.savedCursor.col;
11315
- this.ensureRow();
11316
- }
11317
- return 2;
11318
- }
11319
- if (next === "]") {
11320
- const bel = seq.indexOf("\x07", 2);
11321
- const st = seq.indexOf("\x1B\\", 2);
11322
- const end = bel >= 0 && (st < 0 || bel < st) ? bel + 1 : st >= 0 ? st + 2 : 0;
11323
- return end;
11324
- }
11325
- if (next === "[") {
11326
- const match = seq.match(/^\x1B\[([0-?]*)([ -/]*)([@-~])/);
11327
- if (!match) return seq.length < 32 ? 0 : 1;
11328
- this.applyCsi(match[1] || "", match[3]);
11329
- return match[0].length;
11330
- }
11331
- if (/[P^_X]/.test(next)) {
11332
- const bel = seq.indexOf("\x07", 2);
11333
- const st = seq.indexOf("\x1B\\", 2);
11334
- const end = bel >= 0 && (st < 0 || bel < st) ? bel + 1 : st >= 0 ? st + 2 : 0;
11335
- return end;
11336
- }
11337
- return 2;
11338
- }
11339
- applyCsi(params, final) {
11340
- const count = parseCount(params);
11341
- this.ensureRow();
11342
- if (final === "A") this.row = Math.max(0, this.row - count);
11343
- else if (final === "B") this.row += count;
11344
- else if (final === "C") {
11345
- const line = this.lines[this.row];
11346
- for (let c = this.col; c < this.col + count; c += 1) {
11347
- if (line[c] === void 0) line[c] = " ";
11348
- }
11349
- this.col += count;
11350
- } else if (final === "D") this.col = Math.max(0, this.col - count);
11351
- else if (final === "G") this.col = Math.max(0, count - 1);
11352
- else if (final === "H" || final === "f") {
11353
- const parts = String(params || "").split(";");
11354
- this.row = Math.max(0, (Number(parts[0] || 1) || 1) - 1);
11355
- this.col = Math.max(0, (Number(parts[1] || 1) || 1) - 1);
11356
- } else if (final === "J") {
11357
- const mode = Number(params || 0) || 0;
11358
- if (mode === 2 || mode === 3) {
11359
- this.lines = [[]];
11360
- this.row = 0;
11361
- this.col = 0;
11362
- } else if (mode === 0) {
11363
- this.lines[this.row] = this.lines[this.row].slice(0, this.col);
11364
- this.lines.splice(this.row + 1);
11365
- } else if (mode === 1) {
11366
- for (let r = 0; r < this.row; r += 1) this.lines[r] = [];
11367
- const line = this.lines[this.row];
11368
- for (let c = 0; c <= Math.min(this.col, line.length - 1); c += 1) line[c] = " ";
11369
- }
11370
- } else if (final === "K") {
11371
- const mode = Number(params || 0) || 0;
11372
- const line = this.lines[this.row];
11373
- if (mode === 2) this.lines[this.row] = [];
11374
- else if (mode === 1) {
11375
- for (let c = 0; c <= Math.min(this.col, line.length - 1); c += 1) line[c] = " ";
11376
- } else {
11377
- this.lines[this.row] = line.slice(0, this.col);
11378
- }
11379
- } else if (final === "s") {
11380
- this.savedCursor = { row: this.row, col: this.col };
11381
- } else if (final === "u") {
11382
- if (this.savedCursor) {
11383
- this.row = this.savedCursor.row;
11384
- this.col = this.savedCursor.col;
11385
- }
11386
- }
11387
- this.ensureRow();
11388
- }
11389
- };
11390
- buildCliSpawnEnv = import_session_host_core3.sanitizeSpawnEnv;
11391
- }
11392
- });
11393
-
11394
11492
  // src/providers/sdk/v1/builders/cli/visible-region.ts
11395
11493
  function compile(re, flags) {
11396
11494
  try {
@@ -19032,7 +19130,7 @@ var import_child_process2 = require("child_process");
19032
19130
  var import_util = require("util");
19033
19131
  var import_fs12 = require("fs");
19034
19132
  var import_os2 = require("os");
19035
- var path11 = __toESM(require("path"));
19133
+ var path12 = __toESM(require("path"));
19036
19134
  var execAsync2 = (0, import_util.promisify)(import_child_process2.exec);
19037
19135
  var BUILTIN_IDE_DEFINITIONS = [];
19038
19136
  var registeredIDEs = /* @__PURE__ */ new Map();
@@ -19052,9 +19150,9 @@ function getMergedDefinitions() {
19052
19150
  function findCliCommand(command) {
19053
19151
  const trimmed = String(command || "").trim();
19054
19152
  if (!trimmed) return null;
19055
- if (path11.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
19056
- const candidate = trimmed.startsWith("~") ? path11.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
19057
- const resolved = path11.isAbsolute(candidate) ? candidate : path11.resolve(candidate);
19153
+ if (path12.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
19154
+ const candidate = trimmed.startsWith("~") ? path12.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
19155
+ const resolved = path12.isAbsolute(candidate) ? candidate : path12.resolve(candidate);
19058
19156
  return (0, import_fs12.existsSync)(resolved) ? resolved : null;
19059
19157
  }
19060
19158
  const isWin = (0, import_os2.platform)() === "win32";
@@ -19063,7 +19161,7 @@ function findCliCommand(command) {
19063
19161
  for (const p of paths) {
19064
19162
  if (!p) continue;
19065
19163
  for (const ext of exes) {
19066
- const fullPath = path11.join(p, trimmed + ext);
19164
+ const fullPath = path12.join(p, trimmed + ext);
19067
19165
  try {
19068
19166
  if ((0, import_fs12.existsSync)(fullPath)) {
19069
19167
  const stat2 = (0, import_fs12.statSync)(fullPath);
@@ -19091,7 +19189,7 @@ async function getIdeVersion(cliCommand) {
19091
19189
  function checkPathExists(paths) {
19092
19190
  const home = (0, import_os2.homedir)();
19093
19191
  for (const p of paths) {
19094
- const normalized = p.startsWith("~") ? path11.join(home, p.slice(1)) : p;
19192
+ const normalized = p.startsWith("~") ? path12.join(home, p.slice(1)) : p;
19095
19193
  if (normalized.includes("*")) {
19096
19194
  const username = home.split(/[\\/]/).pop() || "";
19097
19195
  const resolved = normalized.replace("*", username);
@@ -19114,8 +19212,8 @@ async function detectIDEs(providerLoader) {
19114
19212
  if ((0, import_fs12.existsSync)(bundledCli)) resolvedCli = bundledCli;
19115
19213
  }
19116
19214
  if (!resolvedCli && appPath && os30 === "win32") {
19117
- const { dirname: dirname15 } = await import("path");
19118
- const appDir = dirname15(appPath);
19215
+ const { dirname: dirname16 } = await import("path");
19216
+ const appDir = dirname16(appPath);
19119
19217
  const candidates = [
19120
19218
  `${appDir}\\\\bin\\\\${def.cli}.cmd`,
19121
19219
  `${appDir}\\\\bin\\\\${def.cli}`,
@@ -19150,14 +19248,14 @@ async function detectIDEs(providerLoader) {
19150
19248
  init_cli_detector();
19151
19249
 
19152
19250
  // src/system/host-memory.ts
19153
- var os6 = __toESM(require("os"));
19251
+ var os7 = __toESM(require("os"));
19154
19252
  var import_child_process3 = require("child_process");
19155
19253
  var import_util2 = require("util");
19156
19254
  var execAsync3 = (0, import_util2.promisify)(import_child_process3.exec);
19157
19255
  var cachedDarwinAvail = null;
19158
19256
  var darwinMemoryInterval = null;
19159
19257
  async function updateDarwinMemoryCache() {
19160
- if (os6.platform() !== "darwin") return;
19258
+ if (os7.platform() !== "darwin") return;
19161
19259
  try {
19162
19260
  const { stdout } = await execAsync3("vm_stat", {
19163
19261
  encoding: "utf-8",
@@ -19181,19 +19279,19 @@ async function updateDarwinMemoryCache() {
19181
19279
  const fileBacked = counts["file_backed"] ?? 0;
19182
19280
  const availPages = free + inactive + speculative + purgeable + fileBacked;
19183
19281
  const bytes = availPages * pageSize;
19184
- cachedDarwinAvail = Number.isFinite(bytes) && bytes >= 0 ? Math.min(bytes, os6.totalmem()) : null;
19282
+ cachedDarwinAvail = Number.isFinite(bytes) && bytes >= 0 ? Math.min(bytes, os7.totalmem()) : null;
19185
19283
  } catch {
19186
19284
  }
19187
19285
  }
19188
19286
  function getHostMemorySnapshot() {
19189
- if (os6.platform() === "darwin" && !darwinMemoryInterval) {
19287
+ if (os7.platform() === "darwin" && !darwinMemoryInterval) {
19190
19288
  updateDarwinMemoryCache();
19191
19289
  darwinMemoryInterval = setInterval(updateDarwinMemoryCache, 3e3);
19192
19290
  darwinMemoryInterval.unref();
19193
19291
  }
19194
- const totalMem = os6.totalmem();
19195
- const freeMem = os6.freemem();
19196
- const availableMem = os6.platform() === "darwin" ? cachedDarwinAvail ?? freeMem : freeMem;
19292
+ const totalMem = os7.totalmem();
19293
+ const freeMem = os7.freemem();
19294
+ const availableMem = os7.platform() === "darwin" ? cachedDarwinAvail ?? freeMem : freeMem;
19197
19295
  return {
19198
19296
  totalMem,
19199
19297
  freeMem,
@@ -21555,9 +21653,9 @@ ${cleanBody}`;
21555
21653
 
21556
21654
  // src/config/chat-history.ts
21557
21655
  var fs5 = __toESM(require("fs"));
21558
- var path12 = __toESM(require("path"));
21559
- var os7 = __toESM(require("os"));
21560
- var HISTORY_DIR = path12.join(os7.homedir(), ".adhdev", "history");
21656
+ var path13 = __toESM(require("path"));
21657
+ var os8 = __toESM(require("os"));
21658
+ var HISTORY_DIR = path13.join(os8.homedir(), ".adhdev", "history");
21561
21659
  var RETAIN_DAYS = 30;
21562
21660
  var SAVED_HISTORY_INDEX_VERSION = 1;
21563
21661
  var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
@@ -21743,7 +21841,7 @@ function extractSavedHistorySessionIdFromFile(file) {
21743
21841
  function buildSavedHistoryFileSignatureMap(dir, files) {
21744
21842
  return new Map(files.map((file) => {
21745
21843
  try {
21746
- const stat2 = fs5.statSync(path12.join(dir, file));
21844
+ const stat2 = fs5.statSync(path13.join(dir, file));
21747
21845
  return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
21748
21846
  } catch {
21749
21847
  return [file, `${file}:missing`];
@@ -21754,7 +21852,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
21754
21852
  return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
21755
21853
  }
21756
21854
  function getSavedHistoryIndexFilePath(dir) {
21757
- return path12.join(dir, SAVED_HISTORY_INDEX_FILE);
21855
+ return path13.join(dir, SAVED_HISTORY_INDEX_FILE);
21758
21856
  }
21759
21857
  function getSavedHistoryIndexLockPath(dir) {
21760
21858
  return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
@@ -21856,7 +21954,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
21856
21954
  }
21857
21955
  for (const file of Array.from(currentEntries.keys())) {
21858
21956
  if (incomingFiles.has(file)) continue;
21859
- if (!fs5.existsSync(path12.join(dir, file))) {
21957
+ if (!fs5.existsSync(path13.join(dir, file))) {
21860
21958
  currentEntries.delete(file);
21861
21959
  }
21862
21960
  }
@@ -21882,7 +21980,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
21882
21980
  const indexStat = fs5.statSync(getSavedHistoryIndexFilePath(dir));
21883
21981
  const files = listHistoryFiles(dir);
21884
21982
  for (const file of files) {
21885
- const stat2 = fs5.statSync(path12.join(dir, file));
21983
+ const stat2 = fs5.statSync(path13.join(dir, file));
21886
21984
  if (stat2.mtimeMs > indexStat.mtimeMs) return true;
21887
21985
  }
21888
21986
  return false;
@@ -21892,14 +21990,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
21892
21990
  }
21893
21991
  function buildSavedHistoryFileSignature(dir, file) {
21894
21992
  try {
21895
- const stat2 = fs5.statSync(path12.join(dir, file));
21993
+ const stat2 = fs5.statSync(path13.join(dir, file));
21896
21994
  return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
21897
21995
  } catch {
21898
21996
  return `${file}:missing`;
21899
21997
  }
21900
21998
  }
21901
21999
  function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
21902
- const filePath = path12.join(dir, file);
22000
+ const filePath = path13.join(dir, file);
21903
22001
  const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
21904
22002
  const currentEntry = entries.get(file) || null;
21905
22003
  const nextSummary = updater(currentEntry?.summary || null);
@@ -21972,7 +22070,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
21972
22070
  function computeSavedHistoryFileSummary(dir, file) {
21973
22071
  const historySessionId = extractSavedHistorySessionIdFromFile(file);
21974
22072
  if (!historySessionId) return null;
21975
- const filePath = path12.join(dir, file);
22073
+ const filePath = path13.join(dir, file);
21976
22074
  const content = fs5.readFileSync(filePath, "utf-8");
21977
22075
  const lines = content.split("\n").filter(Boolean);
21978
22076
  let messageCount = 0;
@@ -22059,7 +22157,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
22059
22157
  const summaryBySessionId = /* @__PURE__ */ new Map();
22060
22158
  const nextPersistedEntries = /* @__PURE__ */ new Map();
22061
22159
  for (const file of files.slice().sort()) {
22062
- const filePath = path12.join(dir, file);
22160
+ const filePath = path13.join(dir, file);
22063
22161
  const signature = fileSignatures.get(file) || `${file}:missing`;
22064
22162
  const cached2 = savedHistoryFileSummaryCache.get(filePath);
22065
22163
  const persisted = persistedEntries.get(file);
@@ -22179,12 +22277,12 @@ var ChatHistoryWriter = class {
22179
22277
  });
22180
22278
  }
22181
22279
  if (newMessages.length === 0) return;
22182
- const dir = path12.join(HISTORY_DIR, this.sanitize(agentType));
22280
+ const dir = path13.join(HISTORY_DIR, this.sanitize(agentType));
22183
22281
  fs5.mkdirSync(dir, { recursive: true });
22184
22282
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
22185
22283
  const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
22186
22284
  const fileName = `${filePrefix}${date}.jsonl`;
22187
- const filePath = path12.join(dir, fileName);
22285
+ const filePath = path13.join(dir, fileName);
22188
22286
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
22189
22287
  fs5.appendFileSync(filePath, lines, "utf-8");
22190
22288
  updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
@@ -22275,11 +22373,11 @@ var ChatHistoryWriter = class {
22275
22373
  const ws = String(workspace || "").trim();
22276
22374
  if (!id || !ws) return;
22277
22375
  try {
22278
- const dir = path12.join(HISTORY_DIR, this.sanitize(agentType));
22376
+ const dir = path13.join(HISTORY_DIR, this.sanitize(agentType));
22279
22377
  fs5.mkdirSync(dir, { recursive: true });
22280
22378
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
22281
22379
  const fileName = `${this.sanitize(id)}_${date}.jsonl`;
22282
- const filePath = path12.join(dir, fileName);
22380
+ const filePath = path13.join(dir, fileName);
22283
22381
  const record = {
22284
22382
  ts: (/* @__PURE__ */ new Date()).toISOString(),
22285
22383
  receivedAt: Date.now(),
@@ -22325,14 +22423,14 @@ var ChatHistoryWriter = class {
22325
22423
  this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
22326
22424
  this.lastSeenCounts.delete(fromDedupKey);
22327
22425
  }
22328
- const dir = path12.join(HISTORY_DIR, this.sanitize(agentType));
22426
+ const dir = path13.join(HISTORY_DIR, this.sanitize(agentType));
22329
22427
  if (!fs5.existsSync(dir)) return;
22330
22428
  const fromPrefix = `${this.sanitize(fromId)}_`;
22331
22429
  const toPrefix = `${this.sanitize(toId)}_`;
22332
22430
  const files = fs5.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
22333
22431
  for (const file of files) {
22334
- const sourcePath = path12.join(dir, file);
22335
- const targetPath = path12.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
22432
+ const sourcePath = path13.join(dir, file);
22433
+ const targetPath = path13.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
22336
22434
  const sourceLines = fs5.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
22337
22435
  const rewritten = sourceLines.map((line) => {
22338
22436
  try {
@@ -22366,13 +22464,13 @@ var ChatHistoryWriter = class {
22366
22464
  const sessionId = String(historySessionId || "").trim();
22367
22465
  if (!sessionId) return;
22368
22466
  try {
22369
- const dir = path12.join(HISTORY_DIR, this.sanitize(agentType));
22467
+ const dir = path13.join(HISTORY_DIR, this.sanitize(agentType));
22370
22468
  if (!fs5.existsSync(dir)) return;
22371
22469
  const prefix = `${this.sanitize(sessionId)}_`;
22372
22470
  const files = fs5.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
22373
22471
  const seen = /* @__PURE__ */ new Set();
22374
22472
  for (const file of files) {
22375
- const filePath = path12.join(dir, file);
22473
+ const filePath = path13.join(dir, file);
22376
22474
  const lines = fs5.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
22377
22475
  const next = [];
22378
22476
  for (const line of lines) {
@@ -22426,11 +22524,11 @@ var ChatHistoryWriter = class {
22426
22524
  const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
22427
22525
  const agentDirs = fs5.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
22428
22526
  for (const dir of agentDirs) {
22429
- const dirPath = path12.join(HISTORY_DIR, dir.name);
22527
+ const dirPath = path13.join(HISTORY_DIR, dir.name);
22430
22528
  const files = fs5.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
22431
22529
  let removedAny = false;
22432
22530
  for (const file of files) {
22433
- const filePath = path12.join(dirPath, file);
22531
+ const filePath = path13.join(dirPath, file);
22434
22532
  const stat2 = fs5.statSync(filePath);
22435
22533
  if (stat2.mtimeMs < cutoff) {
22436
22534
  fs5.unlinkSync(filePath);
@@ -22633,7 +22731,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
22633
22731
  const seen = /* @__PURE__ */ new Set();
22634
22732
  let readAllFiles = true;
22635
22733
  for (let f = 0; f < files.length; f++) {
22636
- const filePath = path12.join(dir, files[f]);
22734
+ const filePath = path13.join(dir, files[f]);
22637
22735
  const remaining = Math.max(0, needed - collected.length);
22638
22736
  const perFileNeeded = Math.min(needed, remaining + BOUNDED_TAIL_SLACK);
22639
22737
  const { lines, coversWholeFile } = readFileTailLines(filePath, perFileNeeded);
@@ -22666,7 +22764,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
22666
22764
  function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
22667
22765
  try {
22668
22766
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
22669
- const dir = path12.join(HISTORY_DIR, sanitized);
22767
+ const dir = path13.join(HISTORY_DIR, sanitized);
22670
22768
  if (!fs5.existsSync(dir)) return { messages: [], hasMore: false };
22671
22769
  const files = listHistoryFiles(dir, historySessionId);
22672
22770
  const bounded = isBoundedTailRequest(limit, offset, excludeRecentCount);
@@ -22689,7 +22787,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
22689
22787
  const allMessages = [];
22690
22788
  const seen = /* @__PURE__ */ new Set();
22691
22789
  for (const file of files) {
22692
- const filePath = path12.join(dir, file);
22790
+ const filePath = path13.join(dir, file);
22693
22791
  const content = fs5.readFileSync(filePath, "utf-8");
22694
22792
  const lines = content.trim().split("\n").filter(Boolean);
22695
22793
  for (let i = 0; i < lines.length; i++) {
@@ -22713,7 +22811,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
22713
22811
  function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
22714
22812
  try {
22715
22813
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
22716
- const dir = path12.join(HISTORY_DIR, sanitized);
22814
+ const dir = path13.join(HISTORY_DIR, sanitized);
22717
22815
  if (!fs5.existsSync(dir)) {
22718
22816
  savedHistorySessionCache.delete(sanitized);
22719
22817
  return { sessions: [], hasMore: false };
@@ -22774,11 +22872,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
22774
22872
  }
22775
22873
  function readExistingSessionStartRecord(agentType, historySessionId) {
22776
22874
  try {
22777
- const dir = path12.join(HISTORY_DIR, agentType);
22875
+ const dir = path13.join(HISTORY_DIR, agentType);
22778
22876
  if (!fs5.existsSync(dir)) return null;
22779
22877
  const files = listHistoryFiles(dir, historySessionId).sort();
22780
22878
  for (const file of files) {
22781
- const lines = fs5.readFileSync(path12.join(dir, file), "utf-8").split("\n").filter(Boolean);
22879
+ const lines = fs5.readFileSync(path13.join(dir, file), "utf-8").split("\n").filter(Boolean);
22782
22880
  for (const line of lines) {
22783
22881
  try {
22784
22882
  const parsed = JSON.parse(line);
@@ -22798,16 +22896,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
22798
22896
  function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
22799
22897
  if (records.length === 0) return false;
22800
22898
  try {
22801
- const dir = path12.join(HISTORY_DIR, agentType);
22899
+ const dir = path13.join(HISTORY_DIR, agentType);
22802
22900
  fs5.mkdirSync(dir, { recursive: true });
22803
22901
  const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
22804
22902
  for (const file of fs5.readdirSync(dir)) {
22805
22903
  if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
22806
- fs5.unlinkSync(path12.join(dir, file));
22904
+ fs5.unlinkSync(path13.join(dir, file));
22807
22905
  }
22808
22906
  }
22809
22907
  const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
22810
- const filePath = path12.join(dir, `${prefix}${targetDate}.jsonl`);
22908
+ const filePath = path13.join(dir, `${prefix}${targetDate}.jsonl`);
22811
22909
  fs5.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
22812
22910
  `, "utf-8");
22813
22911
  invalidatePersistedSavedHistoryIndex(agentType, dir);
@@ -25402,8 +25500,8 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
25402
25500
 
25403
25501
  // src/commands/chat-commands.ts
25404
25502
  var fs6 = __toESM(require("fs"));
25405
- var os8 = __toESM(require("os"));
25406
- var path13 = __toESM(require("path"));
25503
+ var os9 = __toESM(require("os"));
25504
+ var path14 = __toESM(require("path"));
25407
25505
  var import_node_crypto3 = require("crypto");
25408
25506
  init_logger();
25409
25507
 
@@ -26452,7 +26550,7 @@ function readExactRuntimeMirrorMessages(args) {
26452
26550
  function normalizeComparableWorkspace(value) {
26453
26551
  const text = typeof value === "string" ? value.trim() : "";
26454
26552
  if (!text) return "";
26455
- return path13.resolve(text);
26553
+ return path14.resolve(text);
26456
26554
  }
26457
26555
  function isCurrentRuntimePtySafelyAttributed(args) {
26458
26556
  if (args.adapter.cliType !== "codex-cli") return false;
@@ -26937,7 +27035,7 @@ function buildDebugBundleText(bundle) {
26937
27035
  }
26938
27036
  function getChatDebugBundleDir() {
26939
27037
  const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
26940
- return override || path13.join(os8.homedir(), ".adhdev", "debug-bundles", "chat");
27038
+ return override || path14.join(os9.homedir(), ".adhdev", "debug-bundles", "chat");
26941
27039
  }
26942
27040
  function safeBundleIdSegment(value, fallback) {
26943
27041
  const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
@@ -26994,7 +27092,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
26994
27092
  const bundleId = createChatDebugBundleId(targetSessionId);
26995
27093
  const dir = getChatDebugBundleDir();
26996
27094
  fs6.mkdirSync(dir, { recursive: true });
26997
- const savedPath = path13.join(dir, `${bundleId}.json`);
27095
+ const savedPath = path14.join(dir, `${bundleId}.json`);
26998
27096
  const json = `${JSON.stringify(bundle, null, 2)}
26999
27097
  `;
27000
27098
  fs6.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
@@ -28558,8 +28656,8 @@ async function handleResolveAction(h, args) {
28558
28656
 
28559
28657
  // src/commands/cdp-commands.ts
28560
28658
  var fs7 = __toESM(require("fs"));
28561
- var path14 = __toESM(require("path"));
28562
- var os9 = __toESM(require("os"));
28659
+ var path15 = __toESM(require("path"));
28660
+ var os10 = __toESM(require("os"));
28563
28661
  var KEY_TO_VK = {
28564
28662
  Backspace: 8,
28565
28663
  Tab: 9,
@@ -28813,27 +28911,27 @@ function normalizeWindowsRequestedPath(requestedPath) {
28813
28911
  function resolveSafePath(requestedPath) {
28814
28912
  const rawPath = typeof requestedPath === "string" ? requestedPath.trim() : "";
28815
28913
  const inputPath = rawPath || ".";
28816
- const home = os9.homedir();
28914
+ const home = os10.homedir();
28817
28915
  if (inputPath.startsWith("~")) {
28818
- return path14.resolve(path14.join(home, inputPath.slice(1)));
28916
+ return path15.resolve(path15.join(home, inputPath.slice(1)));
28819
28917
  }
28820
28918
  if (process.platform === "win32") {
28821
28919
  const normalized = normalizeWindowsRequestedPath(inputPath);
28822
- if (path14.win32.isAbsolute(normalized)) {
28823
- return path14.win32.normalize(normalized);
28920
+ if (path15.win32.isAbsolute(normalized)) {
28921
+ return path15.win32.normalize(normalized);
28824
28922
  }
28825
- return path14.win32.resolve(normalized);
28923
+ return path15.win32.resolve(normalized);
28826
28924
  }
28827
- if (path14.isAbsolute(inputPath)) {
28828
- return path14.normalize(inputPath);
28925
+ if (path15.isAbsolute(inputPath)) {
28926
+ return path15.normalize(inputPath);
28829
28927
  }
28830
- return path14.resolve(inputPath);
28928
+ return path15.resolve(inputPath);
28831
28929
  }
28832
28930
  function listDirectoryEntriesSafe(dirPath) {
28833
28931
  const entries = fs7.readdirSync(dirPath, { withFileTypes: true });
28834
28932
  const files = [];
28835
28933
  for (const entry of entries) {
28836
- const entryPath = path14.join(dirPath, entry.name);
28934
+ const entryPath = path15.join(dirPath, entry.name);
28837
28935
  try {
28838
28936
  if (entry.isDirectory()) {
28839
28937
  files.push({ name: entry.name, type: "directory" });
@@ -28887,7 +28985,7 @@ async function handleFileRead(h, args) {
28887
28985
  async function handleFileWrite(h, args) {
28888
28986
  try {
28889
28987
  const filePath = resolveSafePath(args?.path);
28890
- fs7.mkdirSync(path14.dirname(filePath), { recursive: true });
28988
+ fs7.mkdirSync(path15.dirname(filePath), { recursive: true });
28891
28989
  fs7.writeFileSync(filePath, args?.content || "", "utf-8");
28892
28990
  return { success: true, path: filePath };
28893
28991
  } catch (e) {
@@ -43297,7 +43395,15 @@ var MESH_DIRECT_PROBE_MAX_RETRIES = 2;
43297
43395
  function readMeshConnectionState(connection) {
43298
43396
  return readStringValue(connection?.state);
43299
43397
  }
43398
+ function isMeshConnectionDefinitivelyDown(connection) {
43399
+ if (!connection) return true;
43400
+ const state = readMeshConnectionState(connection);
43401
+ return state === "failed" || state === "closed" || state === "disconnected";
43402
+ }
43300
43403
  async function probeRemoteMeshGitStatusWithRetry(args) {
43404
+ if (args.getConnection && isMeshConnectionDefinitivelyDown(args.getConnection(args.daemonId))) {
43405
+ return null;
43406
+ }
43301
43407
  for (let attempt = 0; attempt <= MESH_DIRECT_PROBE_MAX_RETRIES; attempt += 1) {
43302
43408
  if (attempt > 0) {
43303
43409
  const connection = args.getConnection?.(args.daemonId);
@@ -49135,7 +49241,7 @@ ${ptyResult.output.slice(-2e3)}`);
49135
49241
  };
49136
49242
  }
49137
49243
  const { existsSync: existsSync44, readFileSync: readFileSync35, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
49138
- const { dirname: dirname15 } = await import("path");
49244
+ const { dirname: dirname16 } = await import("path");
49139
49245
  const mcpConfigPath = coordinatorSetup.configPath;
49140
49246
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
49141
49247
  let hermesBaseConfig = null;
@@ -49170,7 +49276,7 @@ ${ptyResult.output.slice(-2e3)}`);
49170
49276
  };
49171
49277
  }
49172
49278
  try {
49173
- mkdirSync21(dirname15(mcpConfigPath), { recursive: true });
49279
+ mkdirSync21(dirname16(mcpConfigPath), { recursive: true });
49174
49280
  } catch (error) {
49175
49281
  const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
49176
49282
  LOG.error("MeshCoordinator", message);
@@ -49180,7 +49286,7 @@ ${ptyResult.output.slice(-2e3)}`);
49180
49286
  const hadExistingMcpConfig = existsSync44(mcpConfigPath);
49181
49287
  let existingMcpConfig = hermesBaseConfig?.config || {};
49182
49288
  if (hermesBaseConfig) {
49183
- copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname15(mcpConfigPath));
49289
+ copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname16(mcpConfigPath));
49184
49290
  }
49185
49291
  if (hadExistingMcpConfig) {
49186
49292
  try {
@@ -49218,7 +49324,7 @@ ${ptyResult.output.slice(-2e3)}`);
49218
49324
  const cliArgs = [];
49219
49325
  const launchEnv = {};
49220
49326
  if (configFormat === "hermes_config_yaml") {
49221
- launchEnv.HERMES_HOME = dirname15(mcpConfigPath);
49327
+ launchEnv.HERMES_HOME = dirname16(mcpConfigPath);
49222
49328
  launchEnv.HERMES_IGNORE_USER_CONFIG = "";
49223
49329
  }
49224
49330
  let autoImportContextFilePath;