@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.mjs CHANGED
@@ -348,10 +348,10 @@ function readInjected(value) {
348
348
  }
349
349
  function getDaemonBuildInfo() {
350
350
  if (cached) return cached;
351
- const commit = readInjected(true ? "930909642b3f28668483159d3a8f39d0a796c61a" : void 0) ?? "unknown";
352
- const commitShort = readInjected(true ? "93090964" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
353
- const version = readInjected(true ? "0.9.82-rc.316" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
354
- const builtAt = readInjected(true ? "2026-06-18T07:23:07.242Z" : void 0);
351
+ const commit = readInjected(true ? "506ca246e28984a3b699b04c4601117f62ba2d81" : void 0) ?? "unknown";
352
+ const commitShort = readInjected(true ? "506ca246" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
353
+ const version = readInjected(true ? "0.9.82-rc.318" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
354
+ const builtAt = readInjected(true ? "2026-06-18T12:46:04.472Z" : void 0);
355
355
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
356
356
  return cached;
357
357
  }
@@ -677,14 +677,79 @@ function emptyStatus(workspace, lastCheckedAt, error) {
677
677
  async function getSubmoduleStatuses(repo, options) {
678
678
  if (!repo.repoRoot) return [];
679
679
  try {
680
- const result = await runGit(repo, ["submodule", "status"], options);
681
- const submodules = parseSubmoduleStatusOutput(result.stdout, repo.repoRoot, options.submoduleIgnorePaths);
680
+ const submodules = await deriveSubmoduleGitlinkStatuses(repo, options);
682
681
  await Promise.all(submodules.map((submodule) => enrichSubmoduleWorktreeStatus(repo, submodule, options)));
683
682
  return submodules;
684
683
  } catch {
685
684
  return [];
686
685
  }
687
686
  }
687
+ async function deriveSubmoduleGitlinkStatuses(repo, options) {
688
+ if (!repo.repoRoot) return [];
689
+ const paths = await readSubmodulePaths(repo, options);
690
+ const ignoreSet = new Set(options.submoduleIgnorePaths || []);
691
+ const lastCheckedAt = Date.now();
692
+ const entries = await Promise.all(
693
+ paths.filter((path41) => !ignoreSet.has(path41)).map(async (path41) => {
694
+ const repoPath = repo.repoRoot + "/" + path41;
695
+ const expected = await readGitlinkExpectedSha(repo, path41, options);
696
+ const actual = await readSubmoduleHeadSha(repo, repoPath, options);
697
+ const outOfSync = actual === null ? true : expected !== null && expected !== actual;
698
+ return {
699
+ path: path41,
700
+ // Prefer the recorded gitlink SHA (matches the legacy column); fall back
701
+ // to the checked-out SHA so the field is never empty when both are known.
702
+ commit: expected ?? actual ?? "",
703
+ repoPath,
704
+ dirty: false,
705
+ outOfSync,
706
+ lastCheckedAt
707
+ };
708
+ })
709
+ );
710
+ return entries;
711
+ }
712
+ async function readSubmodulePaths(repo, options) {
713
+ if (!repo.repoRoot) return [];
714
+ const gitmodulesPath = repo.repoRoot + "/.gitmodules";
715
+ try {
716
+ const result = await runGit(
717
+ repo,
718
+ ["config", "--file", gitmodulesPath, "--get-regexp", "^submodule\\..*\\.path$"],
719
+ options
720
+ );
721
+ const paths = [];
722
+ for (const line of result.stdout.split("\n")) {
723
+ const spaceIdx = line.indexOf(" ");
724
+ if (spaceIdx < 0) continue;
725
+ const value = line.slice(spaceIdx + 1).trim();
726
+ if (value) paths.push(value);
727
+ }
728
+ return paths;
729
+ } catch {
730
+ return [];
731
+ }
732
+ }
733
+ async function readGitlinkExpectedSha(repo, submodulePath, options) {
734
+ try {
735
+ const result = await runGit(repo, ["ls-tree", "HEAD", submodulePath], options);
736
+ const line = result.stdout.split("\n").find((l) => l.trim().length > 0);
737
+ if (!line) return null;
738
+ const match = line.match(/^\s*\d+\s+commit\s+([0-9a-f]{40})\b/);
739
+ return match ? match[1] : null;
740
+ } catch {
741
+ return null;
742
+ }
743
+ }
744
+ async function readSubmoduleHeadSha(repo, repoPath, options) {
745
+ try {
746
+ const result = await runGit(repo, ["rev-parse", "HEAD"], { ...options, cwd: repoPath });
747
+ const sha = result.stdout.trim();
748
+ return /^[0-9a-f]{40}$/.test(sha) ? sha : null;
749
+ } catch {
750
+ return null;
751
+ }
752
+ }
688
753
  async function enrichSubmoduleWorktreeStatus(repo, submodule, options) {
689
754
  try {
690
755
  const result = await runGit(repo, ["status", "--porcelain=v2", "--branch"], {
@@ -699,28 +764,6 @@ async function enrichSubmoduleWorktreeStatus(repo, submodule, options) {
699
764
  submodule.error = formatGitError(error);
700
765
  }
701
766
  }
702
- function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
703
- const submodules = [];
704
- const ignoreSet = new Set(ignorePaths || []);
705
- for (const line of output.split("\n")) {
706
- if (!line.trim()) continue;
707
- const match = line.match(/^([\-+U\s])([0-9a-f]{40})\s+(\S+)(?:\s+\(([^)]+)\))?/);
708
- if (!match) continue;
709
- const prefix = match[1];
710
- const commit = match[2];
711
- const path41 = match[3];
712
- if (ignoreSet.has(path41)) continue;
713
- submodules.push({
714
- path: path41,
715
- commit,
716
- repoPath: repoRoot + "/" + path41,
717
- dirty: prefix === "U",
718
- outOfSync: prefix === "-" || prefix === "+",
719
- lastCheckedAt: Date.now()
720
- });
721
- }
722
- return submodules;
723
- }
724
767
  var lastKnownGoodStatus, DAEMON_RUNTIME_PACKAGES, WEB_ONLY_PACKAGES;
725
768
  var init_git_status = __esm({
726
769
  "src/git/git-status.ts"() {
@@ -3949,6 +3992,18 @@ var init_mesh_runtime_store = __esm({
3949
3992
  `).get(meshId, nodeId);
3950
3993
  return row?.count ?? 0;
3951
3994
  }
3995
+ /**
3996
+ * O(1) count of queue tasks in 'pending' status for a mesh. A COUNT(*) over the
3997
+ * indexed status column, so it avoids JSON.parse-ing every queue row — used as a
3998
+ * cheap guard before the reconcile loop runs a full triggerMeshQueue scan.
3999
+ */
4000
+ pendingQueueTaskCount(meshId) {
4001
+ const row = this.db.prepare(`
4002
+ SELECT COUNT(*) as count FROM mesh_queue
4003
+ WHERE mesh_id = ? AND status = 'pending'
4004
+ `).get(meshId);
4005
+ return row?.count ?? 0;
4006
+ }
3952
4007
  /**
3953
4008
  * Read the current per-mesh round-robin cursor (0 when unset). Used to rotate
3954
4009
  * the tie-break winner among nodes tied at the least load.
@@ -7852,10 +7907,412 @@ var init_mesh_events_stale = __esm({
7852
7907
  }
7853
7908
  });
7854
7909
 
7855
- // src/detection/cli-detector.ts
7856
- import { exec } from "child_process";
7910
+ // src/cli-adapters/spawn-env.ts
7911
+ import {
7912
+ sanitizeSpawnEnv,
7913
+ applyTerminalColorEnv,
7914
+ ensureNodePtySpawnHelperPermissions
7915
+ } from "@adhdev/session-host-core";
7916
+ var init_spawn_env = __esm({
7917
+ "src/cli-adapters/spawn-env.ts"() {
7918
+ "use strict";
7919
+ }
7920
+ });
7921
+
7922
+ // src/cli-adapters/provider-cli-shared.ts
7857
7923
  import * as os5 from "os";
7858
7924
  import * as path10 from "path";
7925
+ function stripAnsi(str) {
7926
+ return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
7927
+ }
7928
+ function parseCount(params, fallback = 1) {
7929
+ const first = Number(String(params || "").split(";")[0] || fallback);
7930
+ return Math.max(1, Number.isFinite(first) ? first : fallback);
7931
+ }
7932
+ function isCombiningMark(ch) {
7933
+ return /[\u0300-\u036F\u1AB0-\u1AFF\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/.test(ch);
7934
+ }
7935
+ function isWideCodePoint(ch) {
7936
+ const cp = ch.codePointAt(0) || 0;
7937
+ 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);
7938
+ }
7939
+ function stripTerminalNoise(str) {
7940
+ 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");
7941
+ }
7942
+ function sanitizeTerminalText(str) {
7943
+ const accumulator = new TerminalTranscriptAccumulator();
7944
+ return stripTerminalNoise(stripAnsi(accumulator.append(str)));
7945
+ }
7946
+ function listCliScriptNames(scripts) {
7947
+ if (!scripts) return [];
7948
+ return Object.entries(scripts).filter(([, fn]) => typeof fn === "function").map(([name]) => name);
7949
+ }
7950
+ function splitCliScreenLines(text) {
7951
+ return String(text || "").replace(/\u0007/g, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => line.replace(/\s+$/, ""));
7952
+ }
7953
+ function isPromptLikeCliLine(line) {
7954
+ const trimmed = String(line || "").trim();
7955
+ if (!trimmed) return false;
7956
+ return /^[❯›>]\s*(?:$|\S.*)$/.test(trimmed);
7957
+ }
7958
+ function buildCliScreenSnapshot(text) {
7959
+ const normalizedText = String(text || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
7960
+ const rawLines = splitCliScreenLines(normalizedText);
7961
+ const lines = rawLines.map((line, index, arr) => {
7962
+ const trimmed = String(line || "").trim();
7963
+ return {
7964
+ index,
7965
+ fromTop: index,
7966
+ fromBottom: arr.length - index - 1,
7967
+ text: line,
7968
+ trimmed,
7969
+ isEmpty: trimmed.length === 0
7970
+ };
7971
+ });
7972
+ const nonEmptyLines = lines.filter((line) => !line.isEmpty);
7973
+ const firstNonEmptyLine = nonEmptyLines[0] ?? null;
7974
+ const lastNonEmptyLine = nonEmptyLines[nonEmptyLines.length - 1] ?? null;
7975
+ let promptLineIndex = -1;
7976
+ for (let i = lines.length - 1; i >= 0; i -= 1) {
7977
+ if (isPromptLikeCliLine(lines[i].text)) {
7978
+ promptLineIndex = i;
7979
+ break;
7980
+ }
7981
+ }
7982
+ return {
7983
+ text: normalizedText,
7984
+ lineCount: lines.length,
7985
+ lines,
7986
+ nonEmptyLines,
7987
+ firstNonEmptyLineIndex: firstNonEmptyLine?.index ?? -1,
7988
+ lastNonEmptyLineIndex: lastNonEmptyLine?.index ?? -1,
7989
+ firstNonEmptyLine,
7990
+ lastNonEmptyLine,
7991
+ promptLineIndex,
7992
+ promptLine: promptLineIndex >= 0 ? lines[promptLineIndex] : null,
7993
+ linesAbovePrompt: promptLineIndex >= 0 ? lines.slice(0, promptLineIndex) : [...lines],
7994
+ linesBelowPrompt: promptLineIndex >= 0 ? lines.slice(promptLineIndex + 1) : []
7995
+ };
7996
+ }
7997
+ function findBinary(name) {
7998
+ const trimmed = String(name || "").trim();
7999
+ if (!trimmed) return trimmed;
8000
+ const expanded = trimmed.startsWith("~") ? path10.join(os5.homedir(), trimmed.slice(1)) : trimmed;
8001
+ if (path10.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
8002
+ return path10.isAbsolute(expanded) ? expanded : path10.resolve(expanded);
8003
+ }
8004
+ const isWin = os5.platform() === "win32";
8005
+ const paths = (process.env.PATH || "").split(path10.delimiter);
8006
+ const extraDirs = [];
8007
+ if (isWin) {
8008
+ if (process.env.APPDATA) extraDirs.push(path10.join(process.env.APPDATA, "npm"));
8009
+ try {
8010
+ extraDirs.push(path10.dirname(process.execPath));
8011
+ } catch {
8012
+ }
8013
+ } else {
8014
+ extraDirs.push(path10.join(os5.homedir(), ".npm-global", "bin"));
8015
+ extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
8016
+ try {
8017
+ extraDirs.push(path10.dirname(process.execPath));
8018
+ } catch {
8019
+ }
8020
+ }
8021
+ const searchDirs = [...paths, ...extraDirs];
8022
+ const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
8023
+ for (const p of searchDirs) {
8024
+ if (!p) continue;
8025
+ for (const ext of exes) {
8026
+ const fullPath = path10.join(p, trimmed + ext);
8027
+ try {
8028
+ const fs31 = __require("fs");
8029
+ if (fs31.existsSync(fullPath)) {
8030
+ const stat2 = fs31.statSync(fullPath);
8031
+ if (stat2.isFile() && (isWin || stat2.mode & 73)) {
8032
+ return fullPath;
8033
+ }
8034
+ }
8035
+ } catch {
8036
+ }
8037
+ }
8038
+ }
8039
+ return isWin ? `${trimmed}.cmd` : trimmed;
8040
+ }
8041
+ function isScriptBinary(binaryPath) {
8042
+ if (!path10.isAbsolute(binaryPath)) return false;
8043
+ try {
8044
+ const fs31 = __require("fs");
8045
+ const resolved = fs31.realpathSync(binaryPath);
8046
+ const head = Buffer.alloc(8);
8047
+ const fd = fs31.openSync(resolved, "r");
8048
+ fs31.readSync(fd, head, 0, 8, 0);
8049
+ fs31.closeSync(fd);
8050
+ let i = 0;
8051
+ if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
8052
+ return head[i] === 35 && head[i + 1] === 33;
8053
+ } catch {
8054
+ return false;
8055
+ }
8056
+ }
8057
+ function looksLikeMachOOrElf(filePath) {
8058
+ if (!path10.isAbsolute(filePath)) return false;
8059
+ try {
8060
+ const fs31 = __require("fs");
8061
+ const resolved = fs31.realpathSync(filePath);
8062
+ const buf = Buffer.alloc(8);
8063
+ const fd = fs31.openSync(resolved, "r");
8064
+ fs31.readSync(fd, buf, 0, 8, 0);
8065
+ fs31.closeSync(fd);
8066
+ let i = 0;
8067
+ if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
8068
+ const b = buf.subarray(i);
8069
+ if (b.length < 4) return false;
8070
+ if (b[0] === 127 && b[1] === 69 && b[2] === 76 && b[3] === 70) return true;
8071
+ const le = b.readUInt32LE(0);
8072
+ const be = b.readUInt32BE(0);
8073
+ const magics = [4277009102, 4277009103, 3405691582, 3199925962];
8074
+ return magics.some((m) => m === le || m === be);
8075
+ } catch {
8076
+ return false;
8077
+ }
8078
+ }
8079
+ function shSingleQuote(arg) {
8080
+ if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
8081
+ if (os5.platform() === "win32") {
8082
+ return `"${arg.replace(/"/g, '""')}"`;
8083
+ }
8084
+ return `'${arg.replace(/'/g, `'\\''`)}'`;
8085
+ }
8086
+ function estimatePromptDisplayLines(text, cols = 80) {
8087
+ const normalized = String(text || "").replace(/\r/g, "");
8088
+ if (!normalized) return 1;
8089
+ return normalized.split("\n").reduce((sum, line) => sum + Math.max(1, Math.ceil(Math.max(1, line.length) / cols)), 0);
8090
+ }
8091
+ function extractPromptRetrySnippet(text) {
8092
+ const lines = String(text || "").replace(/\r/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
8093
+ const candidate = lines[lines.length - 1] || lines[0] || "";
8094
+ return candidate.slice(-120);
8095
+ }
8096
+ function normalizePromptText(text) {
8097
+ return String(text || "").replace(/\s+/g, " ").trim();
8098
+ }
8099
+ function compactPromptText(text) {
8100
+ return String(text || "").replace(/\s+/g, "").trim();
8101
+ }
8102
+ function promptLikelyVisible(screenText, promptSnippet) {
8103
+ const snippet = normalizePromptText(promptSnippet);
8104
+ if (!snippet) return false;
8105
+ const normalizedScreen = normalizePromptText(screenText);
8106
+ if (normalizedScreen.includes(snippet)) return true;
8107
+ const compactScreen = compactPromptText(screenText);
8108
+ const compactSnippet = compactPromptText(promptSnippet);
8109
+ if (compactSnippet && compactScreen.includes(compactSnippet)) return true;
8110
+ const tokens = snippet.split(/[^A-Za-z0-9_.:/-]+/).map((token) => token.trim()).filter((token) => token.length >= 4);
8111
+ if (tokens.length === 0) return false;
8112
+ const required = Math.min(tokens.length, 3);
8113
+ const matched = tokens.filter(
8114
+ (token) => normalizedScreen.includes(token) || compactScreen.includes(compactPromptText(token))
8115
+ ).length;
8116
+ return matched >= required;
8117
+ }
8118
+ function normalizeScreenSnapshot(text) {
8119
+ return sanitizeTerminalText(String(text || "")).replace(/\s+/g, " ").trim();
8120
+ }
8121
+ function parsePatternEntry(x) {
8122
+ if (x instanceof RegExp) return x;
8123
+ if (x && typeof x === "object" && typeof x.source === "string") {
8124
+ try {
8125
+ const s = x;
8126
+ return new RegExp(s.source, s.flags || "");
8127
+ } catch {
8128
+ return null;
8129
+ }
8130
+ }
8131
+ return null;
8132
+ }
8133
+ function coercePatternArray(raw) {
8134
+ if (!Array.isArray(raw)) return [];
8135
+ return raw.map(parsePatternEntry).filter((r) => r != null);
8136
+ }
8137
+ function normalizeCliProviderForRuntime(raw) {
8138
+ const patterns = raw && typeof raw === "object" ? raw.patterns : void 0;
8139
+ return {
8140
+ patterns: {
8141
+ approval: coercePatternArray(
8142
+ patterns && typeof patterns === "object" ? patterns.approval : void 0
8143
+ )
8144
+ }
8145
+ };
8146
+ }
8147
+ var TerminalTranscriptAccumulator, buildCliSpawnEnv;
8148
+ var init_provider_cli_shared = __esm({
8149
+ "src/cli-adapters/provider-cli-shared.ts"() {
8150
+ "use strict";
8151
+ init_spawn_env();
8152
+ TerminalTranscriptAccumulator = class {
8153
+ lines = [[]];
8154
+ row = 0;
8155
+ col = 0;
8156
+ savedCursor = null;
8157
+ pendingEscape = "";
8158
+ append(data) {
8159
+ const input = this.pendingEscape + String(data || "");
8160
+ this.pendingEscape = "";
8161
+ for (let i = 0; i < input.length; i += 1) {
8162
+ let ch = input[i];
8163
+ if (ch === "\x1B") {
8164
+ const consumed = this.consumeEscape(input.slice(i));
8165
+ if (consumed === 0) {
8166
+ this.pendingEscape = input.slice(i);
8167
+ break;
8168
+ }
8169
+ i += consumed - 1;
8170
+ continue;
8171
+ }
8172
+ const cp = input.codePointAt(i);
8173
+ if (cp && cp > 65535) {
8174
+ ch = String.fromCodePoint(cp);
8175
+ i += 1;
8176
+ }
8177
+ this.writeControlOrChar(ch);
8178
+ }
8179
+ return this.getText();
8180
+ }
8181
+ reset() {
8182
+ this.lines = [[]];
8183
+ this.row = 0;
8184
+ this.col = 0;
8185
+ this.savedCursor = null;
8186
+ this.pendingEscape = "";
8187
+ }
8188
+ getText() {
8189
+ return this.lines.map((line) => line.join("").replace(/[ \t]+$/g, "")).join("\n");
8190
+ }
8191
+ ensureRow(row = this.row) {
8192
+ while (this.lines.length <= row) this.lines.push([]);
8193
+ }
8194
+ writeControlOrChar(ch) {
8195
+ if (ch === "\r") {
8196
+ this.col = 0;
8197
+ return;
8198
+ }
8199
+ if (ch === "\n") {
8200
+ this.row += 1;
8201
+ this.col = 0;
8202
+ this.ensureRow();
8203
+ return;
8204
+ }
8205
+ if (ch === "\b") {
8206
+ this.col = Math.max(0, this.col - 1);
8207
+ return;
8208
+ }
8209
+ if (ch < " " || ch === "\x7F") return;
8210
+ this.ensureRow();
8211
+ const line = this.lines[this.row];
8212
+ if (isCombiningMark(ch) && this.col > 0) {
8213
+ line[this.col - 1] = `${line[this.col - 1] || ""}${ch}`;
8214
+ return;
8215
+ }
8216
+ while (line.length < this.col) line.push(" ");
8217
+ const wide = isWideCodePoint(ch);
8218
+ line[this.col] = ch;
8219
+ if (wide) line[this.col + 1] = "";
8220
+ this.col += wide ? 2 : 1;
8221
+ }
8222
+ consumeEscape(seq) {
8223
+ if (seq.length < 2) return 0;
8224
+ const next = seq[1];
8225
+ if (next === "7") {
8226
+ this.savedCursor = { row: this.row, col: this.col };
8227
+ return 2;
8228
+ }
8229
+ if (next === "8") {
8230
+ if (this.savedCursor) {
8231
+ this.row = this.savedCursor.row;
8232
+ this.col = this.savedCursor.col;
8233
+ this.ensureRow();
8234
+ }
8235
+ return 2;
8236
+ }
8237
+ if (next === "]") {
8238
+ const bel = seq.indexOf("\x07", 2);
8239
+ const st = seq.indexOf("\x1B\\", 2);
8240
+ const end = bel >= 0 && (st < 0 || bel < st) ? bel + 1 : st >= 0 ? st + 2 : 0;
8241
+ return end;
8242
+ }
8243
+ if (next === "[") {
8244
+ const match = seq.match(/^\x1B\[([0-?]*)([ -/]*)([@-~])/);
8245
+ if (!match) return seq.length < 32 ? 0 : 1;
8246
+ this.applyCsi(match[1] || "", match[3]);
8247
+ return match[0].length;
8248
+ }
8249
+ if (/[P^_X]/.test(next)) {
8250
+ const bel = seq.indexOf("\x07", 2);
8251
+ const st = seq.indexOf("\x1B\\", 2);
8252
+ const end = bel >= 0 && (st < 0 || bel < st) ? bel + 1 : st >= 0 ? st + 2 : 0;
8253
+ return end;
8254
+ }
8255
+ return 2;
8256
+ }
8257
+ applyCsi(params, final) {
8258
+ const count = parseCount(params);
8259
+ this.ensureRow();
8260
+ if (final === "A") this.row = Math.max(0, this.row - count);
8261
+ else if (final === "B") this.row += count;
8262
+ else if (final === "C") {
8263
+ const line = this.lines[this.row];
8264
+ for (let c = this.col; c < this.col + count; c += 1) {
8265
+ if (line[c] === void 0) line[c] = " ";
8266
+ }
8267
+ this.col += count;
8268
+ } else if (final === "D") this.col = Math.max(0, this.col - count);
8269
+ else if (final === "G") this.col = Math.max(0, count - 1);
8270
+ else if (final === "H" || final === "f") {
8271
+ const parts = String(params || "").split(";");
8272
+ this.row = Math.max(0, (Number(parts[0] || 1) || 1) - 1);
8273
+ this.col = Math.max(0, (Number(parts[1] || 1) || 1) - 1);
8274
+ } else if (final === "J") {
8275
+ const mode = Number(params || 0) || 0;
8276
+ if (mode === 2 || mode === 3) {
8277
+ this.lines = [[]];
8278
+ this.row = 0;
8279
+ this.col = 0;
8280
+ } else if (mode === 0) {
8281
+ this.lines[this.row] = this.lines[this.row].slice(0, this.col);
8282
+ this.lines.splice(this.row + 1);
8283
+ } else if (mode === 1) {
8284
+ for (let r = 0; r < this.row; r += 1) this.lines[r] = [];
8285
+ const line = this.lines[this.row];
8286
+ for (let c = 0; c <= Math.min(this.col, line.length - 1); c += 1) line[c] = " ";
8287
+ }
8288
+ } else if (final === "K") {
8289
+ const mode = Number(params || 0) || 0;
8290
+ const line = this.lines[this.row];
8291
+ if (mode === 2) this.lines[this.row] = [];
8292
+ else if (mode === 1) {
8293
+ for (let c = 0; c <= Math.min(this.col, line.length - 1); c += 1) line[c] = " ";
8294
+ } else {
8295
+ this.lines[this.row] = line.slice(0, this.col);
8296
+ }
8297
+ } else if (final === "s") {
8298
+ this.savedCursor = { row: this.row, col: this.col };
8299
+ } else if (final === "u") {
8300
+ if (this.savedCursor) {
8301
+ this.row = this.savedCursor.row;
8302
+ this.col = this.savedCursor.col;
8303
+ }
8304
+ }
8305
+ this.ensureRow();
8306
+ }
8307
+ };
8308
+ buildCliSpawnEnv = sanitizeSpawnEnv;
8309
+ }
8310
+ });
8311
+
8312
+ // src/detection/cli-detector.ts
8313
+ import { exec } from "child_process";
8314
+ import * as os6 from "os";
8315
+ import * as path11 from "path";
7859
8316
  import { existsSync as existsSync13 } from "fs";
7860
8317
  function parseVersion(raw) {
7861
8318
  const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
@@ -7868,22 +8325,31 @@ function shellQuote(value) {
7868
8325
  function expandHome(value) {
7869
8326
  const trimmed = value.trim();
7870
8327
  if (!trimmed.startsWith("~")) return trimmed;
7871
- return path10.join(os5.homedir(), trimmed.slice(1));
8328
+ return path11.join(os6.homedir(), trimmed.slice(1));
7872
8329
  }
7873
8330
  function isExplicitCommandPath(command) {
7874
8331
  const trimmed = command.trim();
7875
- return path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
8332
+ return path11.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
7876
8333
  }
7877
8334
  function resolveCommandPath(command) {
7878
8335
  const trimmed = command.trim();
7879
8336
  if (!trimmed) return null;
7880
8337
  if (isExplicitCommandPath(trimmed)) {
7881
8338
  const expanded = expandHome(trimmed);
7882
- const candidate = path10.isAbsolute(expanded) ? expanded : path10.resolve(expanded);
8339
+ const candidate = path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
7883
8340
  return existsSync13(candidate) ? candidate : null;
7884
8341
  }
7885
8342
  return null;
7886
8343
  }
8344
+ async function resolveDetectionPath(command, whichCmd) {
8345
+ const explicitPath = resolveCommandPath(command);
8346
+ if (explicitPath) return explicitPath;
8347
+ const whichResult = await execAsync(`${whichCmd} ${shellQuote(command)}`);
8348
+ if (whichResult) return whichResult.split("\n")[0];
8349
+ const resolved = findBinary(command);
8350
+ if (path11.isAbsolute(resolved) && existsSync13(resolved)) return resolved;
8351
+ return null;
8352
+ }
7887
8353
  function execAsync(cmd, timeoutMs = 5e3) {
7888
8354
  return new Promise((resolve24) => {
7889
8355
  const child = exec(cmd, {
@@ -7901,17 +8367,15 @@ function execAsync(cmd, timeoutMs = 5e3) {
7901
8367
  });
7902
8368
  }
7903
8369
  async function detectCLIs(providerLoader, options) {
7904
- const platform10 = os5.platform();
8370
+ const platform10 = os6.platform();
7905
8371
  const whichCmd = platform10 === "win32" ? "where" : "which";
7906
8372
  const includeVersion = options?.includeVersion !== false;
7907
8373
  const cliList = providerLoader ? providerLoader.getCliDetectionList() : [];
7908
8374
  const results = await Promise.all(
7909
8375
  cliList.map(async (cli) => {
7910
8376
  try {
7911
- const explicitPath = resolveCommandPath(cli.command);
7912
- const pathResult = explicitPath || await execAsync(`${whichCmd} ${shellQuote(cli.command)}`);
7913
- if (!pathResult) return { ...cli, installed: false };
7914
- const firstPath = explicitPath || pathResult.split("\n")[0];
8377
+ const firstPath = await resolveDetectionPath(cli.command, whichCmd);
8378
+ if (!firstPath) return { ...cli, installed: false };
7915
8379
  let version;
7916
8380
  if (includeVersion) {
7917
8381
  const versionCommands = [
@@ -7945,13 +8409,11 @@ async function detectCLI(cliId, providerLoader, options) {
7945
8409
  const cliList = providerLoader.getCliDetectionList();
7946
8410
  const target = cliList.find((c) => c.id === resolvedId);
7947
8411
  if (target) {
7948
- const platform10 = os5.platform();
8412
+ const platform10 = os6.platform();
7949
8413
  const whichCmd = platform10 === "win32" ? "where" : "which";
7950
8414
  try {
7951
- const explicitPath = resolveCommandPath(target.command);
7952
- const pathResult = explicitPath || await execAsync(`${whichCmd} ${shellQuote(target.command)}`);
7953
- if (!pathResult) return null;
7954
- const firstPath = explicitPath || pathResult.split("\n")[0];
8415
+ const firstPath = await resolveDetectionPath(target.command, whichCmd);
8416
+ if (!firstPath) return null;
7955
8417
  let version;
7956
8418
  if (options?.includeVersion !== false) {
7957
8419
  const versionCommands = [
@@ -7983,6 +8445,7 @@ async function detectCLI(cliId, providerLoader, options) {
7983
8445
  var init_cli_detector = __esm({
7984
8446
  "src/detection/cli-detector.ts"() {
7985
8447
  "use strict";
8448
+ init_provider_cli_shared();
7986
8449
  }
7987
8450
  });
7988
8451
 
@@ -8882,7 +9345,7 @@ async function triggerMeshQueue(components, meshId) {
8882
9345
  }
8883
9346
  const remoteCandidates = [];
8884
9347
  for (const idle of remoteSessions) {
8885
- const node = mesh.nodes.find((n) => n.id === idle.nodeId);
9348
+ const node = mesh.nodes.find((n) => meshNodeIdMatches(n, idle.nodeId));
8886
9349
  if (node) {
8887
9350
  remoteIdleSessionsChecked += 1;
8888
9351
  remoteCandidates.push({ nodeId: idle.nodeId, sessionId: idle.sessionId, providerType: idle.providerType, origin: "remote", node });
@@ -9685,6 +10148,21 @@ async function runMeshReconcileTick(components) {
9685
10148
  }
9686
10149
  }
9687
10150
  }
10151
+ for (const mesh of listMeshes()) {
10152
+ const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
10153
+ if (!daemonHostsMesh(mesh, selfIds)) continue;
10154
+ if (store) {
10155
+ try {
10156
+ if (store.pendingQueueTaskCount(mesh.id) === 0) continue;
10157
+ } catch {
10158
+ }
10159
+ }
10160
+ try {
10161
+ await triggerMeshQueue(components, mesh.id);
10162
+ } catch (e) {
10163
+ LOG.warn("MeshReconcile", `Pending-claim recovery trigger failed for mesh ${mesh.id}: ${e?.message || e}`);
10164
+ }
10165
+ }
9688
10166
  const coordinators = findLiveCoordinators(components);
9689
10167
  if (coordinators.length === 0) {
9690
10168
  return;
@@ -10571,19 +11049,19 @@ __export(external_sources_exports, {
10571
11049
  sourcesProviding: () => sourcesProviding
10572
11050
  });
10573
11051
  import * as fs8 from "fs";
10574
- import * as os10 from "os";
10575
- import * as path15 from "path";
11052
+ import * as os11 from "os";
11053
+ import * as path16 from "path";
10576
11054
  function adhdevDir() {
10577
- return path15.join(os10.homedir(), ".adhdev");
11055
+ return path16.join(os11.homedir(), ".adhdev");
10578
11056
  }
10579
11057
  function externalRoot() {
10580
- return path15.join(adhdevDir(), "external");
11058
+ return path16.join(adhdevDir(), "external");
10581
11059
  }
10582
11060
  function sourcesFilePath() {
10583
- return path15.join(adhdevDir(), SOURCES_FILENAME);
11061
+ return path16.join(adhdevDir(), SOURCES_FILENAME);
10584
11062
  }
10585
11063
  function activeFilePath() {
10586
- return path15.join(adhdevDir(), ACTIVE_FILENAME);
11064
+ return path16.join(adhdevDir(), ACTIVE_FILENAME);
10587
11065
  }
10588
11066
  function ensureAdhdevDir() {
10589
11067
  const d = adhdevDir();
@@ -10650,7 +11128,7 @@ function inventoryExternalSources() {
10650
11128
  for (const sourceEntry of entries) {
10651
11129
  if (!sourceEntry.isDirectory()) continue;
10652
11130
  const sourceName = sourceEntry.name;
10653
- const sourceDir = path15.join(root, sourceName);
11131
+ const sourceDir = path16.join(root, sourceName);
10654
11132
  const providers = {};
10655
11133
  let categoryEntries;
10656
11134
  try {
@@ -10661,7 +11139,7 @@ function inventoryExternalSources() {
10661
11139
  for (const categoryEntry of categoryEntries) {
10662
11140
  if (!categoryEntry.isDirectory()) continue;
10663
11141
  const category = categoryEntry.name;
10664
- const categoryDir = path15.join(sourceDir, category);
11142
+ const categoryDir = path16.join(sourceDir, category);
10665
11143
  let typeEntries;
10666
11144
  try {
10667
11145
  typeEntries = fs8.readdirSync(categoryDir, { withFileTypes: true });
@@ -10671,9 +11149,9 @@ function inventoryExternalSources() {
10671
11149
  const types = [];
10672
11150
  for (const typeEntry of typeEntries) {
10673
11151
  if (!typeEntry.isDirectory()) continue;
10674
- const typeDir = path15.join(categoryDir, typeEntry.name);
10675
- const hasV1 = fs8.existsSync(path15.join(typeDir, "provider.v1.json"));
10676
- const hasV0 = fs8.existsSync(path15.join(typeDir, "provider.json"));
11152
+ const typeDir = path16.join(categoryDir, typeEntry.name);
11153
+ const hasV1 = fs8.existsSync(path16.join(typeDir, "provider.v1.json"));
11154
+ const hasV0 = fs8.existsSync(path16.join(typeDir, "provider.json"));
10677
11155
  if (hasV1 || hasV0) types.push(typeEntry.name);
10678
11156
  }
10679
11157
  if (types.length > 0) providers[category] = types;
@@ -10877,27 +11355,34 @@ var init_terminal_screen = __esm({
10877
11355
  }
10878
11356
  });
10879
11357
 
10880
- // src/cli-adapters/spawn-env.ts
10881
- import {
10882
- sanitizeSpawnEnv,
10883
- applyTerminalColorEnv,
10884
- ensureNodePtySpawnHelperPermissions
10885
- } from "@adhdev/session-host-core";
10886
- var init_spawn_env = __esm({
10887
- "src/cli-adapters/spawn-env.ts"() {
10888
- "use strict";
10889
- }
10890
- });
10891
-
10892
11358
  // src/cli-adapters/resolve-executable.ts
10893
11359
  import { execFileSync } from "child_process";
10894
11360
  import { existsSync as existsSync20 } from "fs";
10895
- import * as path16 from "path";
11361
+ import * as path17 from "path";
11362
+ function resolveWin32GlobalBin(trimmed) {
11363
+ if (path17.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
11364
+ return null;
11365
+ }
11366
+ const extraDirs = [];
11367
+ if (process.env.APPDATA) extraDirs.push(path17.join(process.env.APPDATA, "npm"));
11368
+ try {
11369
+ extraDirs.push(path17.dirname(process.execPath));
11370
+ } catch {
11371
+ }
11372
+ for (const dir of extraDirs) {
11373
+ if (!dir) continue;
11374
+ for (const ext of WIN_EXEC_EXT) {
11375
+ const full = path17.join(dir, trimmed + ext);
11376
+ if (existsSync20(full)) return full;
11377
+ }
11378
+ }
11379
+ return null;
11380
+ }
10896
11381
  function resolveWin32Executable(command) {
10897
11382
  if (process.platform !== "win32") return command;
10898
11383
  const trimmed = (command || "").trim();
10899
11384
  if (!trimmed) return command;
10900
- if (path16.isAbsolute(trimmed) && existsSync20(trimmed)) return trimmed;
11385
+ if (path17.isAbsolute(trimmed) && existsSync20(trimmed)) return trimmed;
10901
11386
  try {
10902
11387
  const out = execFileSync("where", [trimmed], {
10903
11388
  encoding: "utf8",
@@ -10905,18 +11390,21 @@ function resolveWin32Executable(command) {
10905
11390
  }).trim();
10906
11391
  if (out) {
10907
11392
  const matches = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
10908
- const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path16.extname(m).toLowerCase()));
11393
+ const direct = matches.find((m) => DIRECT_EXEC_EXT.has(path17.extname(m).toLowerCase()));
10909
11394
  return direct || matches[0] || command;
10910
11395
  }
10911
11396
  } catch {
10912
11397
  }
11398
+ const globalBin = resolveWin32GlobalBin(trimmed);
11399
+ if (globalBin) return globalBin;
10913
11400
  return command;
10914
11401
  }
10915
- var DIRECT_EXEC_EXT;
11402
+ var DIRECT_EXEC_EXT, WIN_EXEC_EXT;
10916
11403
  var init_resolve_executable = __esm({
10917
11404
  "src/cli-adapters/resolve-executable.ts"() {
10918
11405
  "use strict";
10919
11406
  DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
11407
+ WIN_EXEC_EXT = [".exe", ".com", ".cmd", ".bat"];
10920
11408
  }
10921
11409
  });
10922
11410
 
@@ -10925,7 +11413,7 @@ var pty_transport_exports = {};
10925
11413
  __export(pty_transport_exports, {
10926
11414
  NodePtyTransportFactory: () => NodePtyTransportFactory
10927
11415
  });
10928
- import * as os11 from "os";
11416
+ import * as os12 from "os";
10929
11417
  function loadNodePty() {
10930
11418
  if (cachedPty !== void 0) return cachedPty;
10931
11419
  try {
@@ -10979,9 +11467,9 @@ var init_pty_transport = __esm({
10979
11467
  try {
10980
11468
  const fs31 = __require("fs");
10981
11469
  const stat2 = fs31.statSync(cwd);
10982
- if (!stat2.isDirectory()) cwd = os11.homedir();
11470
+ if (!stat2.isDirectory()) cwd = os12.homedir();
10983
11471
  } catch {
10984
- cwd = os11.homedir();
11472
+ cwd = os12.homedir();
10985
11473
  }
10986
11474
  }
10987
11475
  const handle = pty.spawn(resolveWin32Executable(command), args, {
@@ -10997,396 +11485,6 @@ var init_pty_transport = __esm({
10997
11485
  }
10998
11486
  });
10999
11487
 
11000
- // src/cli-adapters/provider-cli-shared.ts
11001
- import * as os12 from "os";
11002
- import * as path17 from "path";
11003
- function stripAnsi(str) {
11004
- return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
11005
- }
11006
- function parseCount(params, fallback = 1) {
11007
- const first = Number(String(params || "").split(";")[0] || fallback);
11008
- return Math.max(1, Number.isFinite(first) ? first : fallback);
11009
- }
11010
- function isCombiningMark(ch) {
11011
- return /[\u0300-\u036F\u1AB0-\u1AFF\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/.test(ch);
11012
- }
11013
- function isWideCodePoint(ch) {
11014
- const cp = ch.codePointAt(0) || 0;
11015
- 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);
11016
- }
11017
- function stripTerminalNoise(str) {
11018
- 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");
11019
- }
11020
- function sanitizeTerminalText(str) {
11021
- const accumulator = new TerminalTranscriptAccumulator();
11022
- return stripTerminalNoise(stripAnsi(accumulator.append(str)));
11023
- }
11024
- function listCliScriptNames(scripts) {
11025
- if (!scripts) return [];
11026
- return Object.entries(scripts).filter(([, fn]) => typeof fn === "function").map(([name]) => name);
11027
- }
11028
- function splitCliScreenLines(text) {
11029
- return String(text || "").replace(/\u0007/g, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => line.replace(/\s+$/, ""));
11030
- }
11031
- function isPromptLikeCliLine(line) {
11032
- const trimmed = String(line || "").trim();
11033
- if (!trimmed) return false;
11034
- return /^[❯›>]\s*(?:$|\S.*)$/.test(trimmed);
11035
- }
11036
- function buildCliScreenSnapshot(text) {
11037
- const normalizedText = String(text || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
11038
- const rawLines = splitCliScreenLines(normalizedText);
11039
- const lines = rawLines.map((line, index, arr) => {
11040
- const trimmed = String(line || "").trim();
11041
- return {
11042
- index,
11043
- fromTop: index,
11044
- fromBottom: arr.length - index - 1,
11045
- text: line,
11046
- trimmed,
11047
- isEmpty: trimmed.length === 0
11048
- };
11049
- });
11050
- const nonEmptyLines = lines.filter((line) => !line.isEmpty);
11051
- const firstNonEmptyLine = nonEmptyLines[0] ?? null;
11052
- const lastNonEmptyLine = nonEmptyLines[nonEmptyLines.length - 1] ?? null;
11053
- let promptLineIndex = -1;
11054
- for (let i = lines.length - 1; i >= 0; i -= 1) {
11055
- if (isPromptLikeCliLine(lines[i].text)) {
11056
- promptLineIndex = i;
11057
- break;
11058
- }
11059
- }
11060
- return {
11061
- text: normalizedText,
11062
- lineCount: lines.length,
11063
- lines,
11064
- nonEmptyLines,
11065
- firstNonEmptyLineIndex: firstNonEmptyLine?.index ?? -1,
11066
- lastNonEmptyLineIndex: lastNonEmptyLine?.index ?? -1,
11067
- firstNonEmptyLine,
11068
- lastNonEmptyLine,
11069
- promptLineIndex,
11070
- promptLine: promptLineIndex >= 0 ? lines[promptLineIndex] : null,
11071
- linesAbovePrompt: promptLineIndex >= 0 ? lines.slice(0, promptLineIndex) : [...lines],
11072
- linesBelowPrompt: promptLineIndex >= 0 ? lines.slice(promptLineIndex + 1) : []
11073
- };
11074
- }
11075
- function findBinary(name) {
11076
- const trimmed = String(name || "").trim();
11077
- if (!trimmed) return trimmed;
11078
- const expanded = trimmed.startsWith("~") ? path17.join(os12.homedir(), trimmed.slice(1)) : trimmed;
11079
- if (path17.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
11080
- return path17.isAbsolute(expanded) ? expanded : path17.resolve(expanded);
11081
- }
11082
- const isWin = os12.platform() === "win32";
11083
- const paths = (process.env.PATH || "").split(path17.delimiter);
11084
- const extraDirs = [];
11085
- if (isWin) {
11086
- if (process.env.APPDATA) extraDirs.push(path17.join(process.env.APPDATA, "npm"));
11087
- try {
11088
- extraDirs.push(path17.dirname(process.execPath));
11089
- } catch {
11090
- }
11091
- } else {
11092
- extraDirs.push(path17.join(os12.homedir(), ".npm-global", "bin"));
11093
- extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
11094
- try {
11095
- extraDirs.push(path17.dirname(process.execPath));
11096
- } catch {
11097
- }
11098
- }
11099
- const searchDirs = [...paths, ...extraDirs];
11100
- const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
11101
- for (const p of searchDirs) {
11102
- if (!p) continue;
11103
- for (const ext of exes) {
11104
- const fullPath = path17.join(p, trimmed + ext);
11105
- try {
11106
- const fs31 = __require("fs");
11107
- if (fs31.existsSync(fullPath)) {
11108
- const stat2 = fs31.statSync(fullPath);
11109
- if (stat2.isFile() && (isWin || stat2.mode & 73)) {
11110
- return fullPath;
11111
- }
11112
- }
11113
- } catch {
11114
- }
11115
- }
11116
- }
11117
- return isWin ? `${trimmed}.cmd` : trimmed;
11118
- }
11119
- function isScriptBinary(binaryPath) {
11120
- if (!path17.isAbsolute(binaryPath)) return false;
11121
- try {
11122
- const fs31 = __require("fs");
11123
- const resolved = fs31.realpathSync(binaryPath);
11124
- const head = Buffer.alloc(8);
11125
- const fd = fs31.openSync(resolved, "r");
11126
- fs31.readSync(fd, head, 0, 8, 0);
11127
- fs31.closeSync(fd);
11128
- let i = 0;
11129
- if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
11130
- return head[i] === 35 && head[i + 1] === 33;
11131
- } catch {
11132
- return false;
11133
- }
11134
- }
11135
- function looksLikeMachOOrElf(filePath) {
11136
- if (!path17.isAbsolute(filePath)) return false;
11137
- try {
11138
- const fs31 = __require("fs");
11139
- const resolved = fs31.realpathSync(filePath);
11140
- const buf = Buffer.alloc(8);
11141
- const fd = fs31.openSync(resolved, "r");
11142
- fs31.readSync(fd, buf, 0, 8, 0);
11143
- fs31.closeSync(fd);
11144
- let i = 0;
11145
- if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
11146
- const b = buf.subarray(i);
11147
- if (b.length < 4) return false;
11148
- if (b[0] === 127 && b[1] === 69 && b[2] === 76 && b[3] === 70) return true;
11149
- const le = b.readUInt32LE(0);
11150
- const be = b.readUInt32BE(0);
11151
- const magics = [4277009102, 4277009103, 3405691582, 3199925962];
11152
- return magics.some((m) => m === le || m === be);
11153
- } catch {
11154
- return false;
11155
- }
11156
- }
11157
- function shSingleQuote(arg) {
11158
- if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
11159
- if (os12.platform() === "win32") {
11160
- return `"${arg.replace(/"/g, '""')}"`;
11161
- }
11162
- return `'${arg.replace(/'/g, `'\\''`)}'`;
11163
- }
11164
- function estimatePromptDisplayLines(text, cols = 80) {
11165
- const normalized = String(text || "").replace(/\r/g, "");
11166
- if (!normalized) return 1;
11167
- return normalized.split("\n").reduce((sum, line) => sum + Math.max(1, Math.ceil(Math.max(1, line.length) / cols)), 0);
11168
- }
11169
- function extractPromptRetrySnippet(text) {
11170
- const lines = String(text || "").replace(/\r/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
11171
- const candidate = lines[lines.length - 1] || lines[0] || "";
11172
- return candidate.slice(-120);
11173
- }
11174
- function normalizePromptText(text) {
11175
- return String(text || "").replace(/\s+/g, " ").trim();
11176
- }
11177
- function compactPromptText(text) {
11178
- return String(text || "").replace(/\s+/g, "").trim();
11179
- }
11180
- function promptLikelyVisible(screenText, promptSnippet) {
11181
- const snippet = normalizePromptText(promptSnippet);
11182
- if (!snippet) return false;
11183
- const normalizedScreen = normalizePromptText(screenText);
11184
- if (normalizedScreen.includes(snippet)) return true;
11185
- const compactScreen = compactPromptText(screenText);
11186
- const compactSnippet = compactPromptText(promptSnippet);
11187
- if (compactSnippet && compactScreen.includes(compactSnippet)) return true;
11188
- const tokens = snippet.split(/[^A-Za-z0-9_.:/-]+/).map((token) => token.trim()).filter((token) => token.length >= 4);
11189
- if (tokens.length === 0) return false;
11190
- const required = Math.min(tokens.length, 3);
11191
- const matched = tokens.filter(
11192
- (token) => normalizedScreen.includes(token) || compactScreen.includes(compactPromptText(token))
11193
- ).length;
11194
- return matched >= required;
11195
- }
11196
- function normalizeScreenSnapshot(text) {
11197
- return sanitizeTerminalText(String(text || "")).replace(/\s+/g, " ").trim();
11198
- }
11199
- function parsePatternEntry(x) {
11200
- if (x instanceof RegExp) return x;
11201
- if (x && typeof x === "object" && typeof x.source === "string") {
11202
- try {
11203
- const s = x;
11204
- return new RegExp(s.source, s.flags || "");
11205
- } catch {
11206
- return null;
11207
- }
11208
- }
11209
- return null;
11210
- }
11211
- function coercePatternArray(raw) {
11212
- if (!Array.isArray(raw)) return [];
11213
- return raw.map(parsePatternEntry).filter((r) => r != null);
11214
- }
11215
- function normalizeCliProviderForRuntime(raw) {
11216
- const patterns = raw && typeof raw === "object" ? raw.patterns : void 0;
11217
- return {
11218
- patterns: {
11219
- approval: coercePatternArray(
11220
- patterns && typeof patterns === "object" ? patterns.approval : void 0
11221
- )
11222
- }
11223
- };
11224
- }
11225
- var TerminalTranscriptAccumulator, buildCliSpawnEnv;
11226
- var init_provider_cli_shared = __esm({
11227
- "src/cli-adapters/provider-cli-shared.ts"() {
11228
- "use strict";
11229
- init_spawn_env();
11230
- TerminalTranscriptAccumulator = class {
11231
- lines = [[]];
11232
- row = 0;
11233
- col = 0;
11234
- savedCursor = null;
11235
- pendingEscape = "";
11236
- append(data) {
11237
- const input = this.pendingEscape + String(data || "");
11238
- this.pendingEscape = "";
11239
- for (let i = 0; i < input.length; i += 1) {
11240
- let ch = input[i];
11241
- if (ch === "\x1B") {
11242
- const consumed = this.consumeEscape(input.slice(i));
11243
- if (consumed === 0) {
11244
- this.pendingEscape = input.slice(i);
11245
- break;
11246
- }
11247
- i += consumed - 1;
11248
- continue;
11249
- }
11250
- const cp = input.codePointAt(i);
11251
- if (cp && cp > 65535) {
11252
- ch = String.fromCodePoint(cp);
11253
- i += 1;
11254
- }
11255
- this.writeControlOrChar(ch);
11256
- }
11257
- return this.getText();
11258
- }
11259
- reset() {
11260
- this.lines = [[]];
11261
- this.row = 0;
11262
- this.col = 0;
11263
- this.savedCursor = null;
11264
- this.pendingEscape = "";
11265
- }
11266
- getText() {
11267
- return this.lines.map((line) => line.join("").replace(/[ \t]+$/g, "")).join("\n");
11268
- }
11269
- ensureRow(row = this.row) {
11270
- while (this.lines.length <= row) this.lines.push([]);
11271
- }
11272
- writeControlOrChar(ch) {
11273
- if (ch === "\r") {
11274
- this.col = 0;
11275
- return;
11276
- }
11277
- if (ch === "\n") {
11278
- this.row += 1;
11279
- this.col = 0;
11280
- this.ensureRow();
11281
- return;
11282
- }
11283
- if (ch === "\b") {
11284
- this.col = Math.max(0, this.col - 1);
11285
- return;
11286
- }
11287
- if (ch < " " || ch === "\x7F") return;
11288
- this.ensureRow();
11289
- const line = this.lines[this.row];
11290
- if (isCombiningMark(ch) && this.col > 0) {
11291
- line[this.col - 1] = `${line[this.col - 1] || ""}${ch}`;
11292
- return;
11293
- }
11294
- while (line.length < this.col) line.push(" ");
11295
- const wide = isWideCodePoint(ch);
11296
- line[this.col] = ch;
11297
- if (wide) line[this.col + 1] = "";
11298
- this.col += wide ? 2 : 1;
11299
- }
11300
- consumeEscape(seq) {
11301
- if (seq.length < 2) return 0;
11302
- const next = seq[1];
11303
- if (next === "7") {
11304
- this.savedCursor = { row: this.row, col: this.col };
11305
- return 2;
11306
- }
11307
- if (next === "8") {
11308
- if (this.savedCursor) {
11309
- this.row = this.savedCursor.row;
11310
- this.col = this.savedCursor.col;
11311
- this.ensureRow();
11312
- }
11313
- return 2;
11314
- }
11315
- if (next === "]") {
11316
- const bel = seq.indexOf("\x07", 2);
11317
- const st = seq.indexOf("\x1B\\", 2);
11318
- const end = bel >= 0 && (st < 0 || bel < st) ? bel + 1 : st >= 0 ? st + 2 : 0;
11319
- return end;
11320
- }
11321
- if (next === "[") {
11322
- const match = seq.match(/^\x1B\[([0-?]*)([ -/]*)([@-~])/);
11323
- if (!match) return seq.length < 32 ? 0 : 1;
11324
- this.applyCsi(match[1] || "", match[3]);
11325
- return match[0].length;
11326
- }
11327
- if (/[P^_X]/.test(next)) {
11328
- const bel = seq.indexOf("\x07", 2);
11329
- const st = seq.indexOf("\x1B\\", 2);
11330
- const end = bel >= 0 && (st < 0 || bel < st) ? bel + 1 : st >= 0 ? st + 2 : 0;
11331
- return end;
11332
- }
11333
- return 2;
11334
- }
11335
- applyCsi(params, final) {
11336
- const count = parseCount(params);
11337
- this.ensureRow();
11338
- if (final === "A") this.row = Math.max(0, this.row - count);
11339
- else if (final === "B") this.row += count;
11340
- else if (final === "C") {
11341
- const line = this.lines[this.row];
11342
- for (let c = this.col; c < this.col + count; c += 1) {
11343
- if (line[c] === void 0) line[c] = " ";
11344
- }
11345
- this.col += count;
11346
- } else if (final === "D") this.col = Math.max(0, this.col - count);
11347
- else if (final === "G") this.col = Math.max(0, count - 1);
11348
- else if (final === "H" || final === "f") {
11349
- const parts = String(params || "").split(";");
11350
- this.row = Math.max(0, (Number(parts[0] || 1) || 1) - 1);
11351
- this.col = Math.max(0, (Number(parts[1] || 1) || 1) - 1);
11352
- } else if (final === "J") {
11353
- const mode = Number(params || 0) || 0;
11354
- if (mode === 2 || mode === 3) {
11355
- this.lines = [[]];
11356
- this.row = 0;
11357
- this.col = 0;
11358
- } else if (mode === 0) {
11359
- this.lines[this.row] = this.lines[this.row].slice(0, this.col);
11360
- this.lines.splice(this.row + 1);
11361
- } else if (mode === 1) {
11362
- for (let r = 0; r < this.row; r += 1) this.lines[r] = [];
11363
- const line = this.lines[this.row];
11364
- for (let c = 0; c <= Math.min(this.col, line.length - 1); c += 1) line[c] = " ";
11365
- }
11366
- } else if (final === "K") {
11367
- const mode = Number(params || 0) || 0;
11368
- const line = this.lines[this.row];
11369
- if (mode === 2) this.lines[this.row] = [];
11370
- else if (mode === 1) {
11371
- for (let c = 0; c <= Math.min(this.col, line.length - 1); c += 1) line[c] = " ";
11372
- } else {
11373
- this.lines[this.row] = line.slice(0, this.col);
11374
- }
11375
- } else if (final === "s") {
11376
- this.savedCursor = { row: this.row, col: this.col };
11377
- } else if (final === "u") {
11378
- if (this.savedCursor) {
11379
- this.row = this.savedCursor.row;
11380
- this.col = this.savedCursor.col;
11381
- }
11382
- }
11383
- this.ensureRow();
11384
- }
11385
- };
11386
- buildCliSpawnEnv = sanitizeSpawnEnv;
11387
- }
11388
- });
11389
-
11390
11488
  // src/providers/sdk/v1/builders/cli/visible-region.ts
11391
11489
  function compile(re, flags) {
11392
11490
  try {
@@ -18602,7 +18700,7 @@ var P2pRelayFailureError = class extends Error {
18602
18700
  // src/config/state-store.ts
18603
18701
  init_config();
18604
18702
  import { existsSync as existsSync15, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
18605
- import { join as join15 } from "path";
18703
+ import { join as join16 } from "path";
18606
18704
  var DEFAULT_STATE = {
18607
18705
  recentActivity: [],
18608
18706
  savedProviderSessions: [],
@@ -18615,7 +18713,7 @@ function isPlainObject2(value) {
18615
18713
  return !!value && typeof value === "object" && !Array.isArray(value);
18616
18714
  }
18617
18715
  function getStatePath() {
18618
- return join15(getConfigDir(), "state.json");
18716
+ return join16(getConfigDir(), "state.json");
18619
18717
  }
18620
18718
  function normalizeState(raw) {
18621
18719
  const parsed = isPlainObject2(raw) ? raw : {};
@@ -18674,8 +18772,8 @@ function resetState() {
18674
18772
  import { exec as exec2 } from "child_process";
18675
18773
  import { promisify as promisify4 } from "util";
18676
18774
  import { existsSync as existsSync16, statSync as statSync6 } from "fs";
18677
- import { platform as platform2, homedir as homedir7 } from "os";
18678
- import * as path11 from "path";
18775
+ import { platform as platform3, homedir as homedir8 } from "os";
18776
+ import * as path12 from "path";
18679
18777
  var execAsync2 = promisify4(exec2);
18680
18778
  var BUILTIN_IDE_DEFINITIONS = [];
18681
18779
  var registeredIDEs = /* @__PURE__ */ new Map();
@@ -18695,18 +18793,18 @@ function getMergedDefinitions() {
18695
18793
  function findCliCommand(command) {
18696
18794
  const trimmed = String(command || "").trim();
18697
18795
  if (!trimmed) return null;
18698
- if (path11.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
18699
- const candidate = trimmed.startsWith("~") ? path11.join(homedir7(), trimmed.slice(1)) : trimmed;
18700
- const resolved = path11.isAbsolute(candidate) ? candidate : path11.resolve(candidate);
18796
+ if (path12.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
18797
+ const candidate = trimmed.startsWith("~") ? path12.join(homedir8(), trimmed.slice(1)) : trimmed;
18798
+ const resolved = path12.isAbsolute(candidate) ? candidate : path12.resolve(candidate);
18701
18799
  return existsSync16(resolved) ? resolved : null;
18702
18800
  }
18703
- const isWin = platform2() === "win32";
18801
+ const isWin = platform3() === "win32";
18704
18802
  const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
18705
18803
  const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
18706
18804
  for (const p of paths) {
18707
18805
  if (!p) continue;
18708
18806
  for (const ext of exes) {
18709
- const fullPath = path11.join(p, trimmed + ext);
18807
+ const fullPath = path12.join(p, trimmed + ext);
18710
18808
  try {
18711
18809
  if (existsSync16(fullPath)) {
18712
18810
  const stat2 = statSync6(fullPath);
@@ -18732,9 +18830,9 @@ async function getIdeVersion(cliCommand) {
18732
18830
  }
18733
18831
  }
18734
18832
  function checkPathExists(paths) {
18735
- const home = homedir7();
18833
+ const home = homedir8();
18736
18834
  for (const p of paths) {
18737
- const normalized = p.startsWith("~") ? path11.join(home, p.slice(1)) : p;
18835
+ const normalized = p.startsWith("~") ? path12.join(home, p.slice(1)) : p;
18738
18836
  if (normalized.includes("*")) {
18739
18837
  const username = home.split(/[\\/]/).pop() || "";
18740
18838
  const resolved = normalized.replace("*", username);
@@ -18746,7 +18844,7 @@ function checkPathExists(paths) {
18746
18844
  return null;
18747
18845
  }
18748
18846
  async function detectIDEs(providerLoader) {
18749
- const os30 = platform2();
18847
+ const os30 = platform3();
18750
18848
  const results = [];
18751
18849
  for (const def of getMergedDefinitions()) {
18752
18850
  const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
@@ -18757,8 +18855,8 @@ async function detectIDEs(providerLoader) {
18757
18855
  if (existsSync16(bundledCli)) resolvedCli = bundledCli;
18758
18856
  }
18759
18857
  if (!resolvedCli && appPath && os30 === "win32") {
18760
- const { dirname: dirname15 } = await import("path");
18761
- const appDir = dirname15(appPath);
18858
+ const { dirname: dirname16 } = await import("path");
18859
+ const appDir = dirname16(appPath);
18762
18860
  const candidates = [
18763
18861
  `${appDir}\\\\bin\\\\${def.cli}.cmd`,
18764
18862
  `${appDir}\\\\bin\\\\${def.cli}`,
@@ -18793,14 +18891,14 @@ async function detectIDEs(providerLoader) {
18793
18891
  init_cli_detector();
18794
18892
 
18795
18893
  // src/system/host-memory.ts
18796
- import * as os6 from "os";
18894
+ import * as os7 from "os";
18797
18895
  import { exec as exec3 } from "child_process";
18798
18896
  import { promisify as promisify5 } from "util";
18799
18897
  var execAsync3 = promisify5(exec3);
18800
18898
  var cachedDarwinAvail = null;
18801
18899
  var darwinMemoryInterval = null;
18802
18900
  async function updateDarwinMemoryCache() {
18803
- if (os6.platform() !== "darwin") return;
18901
+ if (os7.platform() !== "darwin") return;
18804
18902
  try {
18805
18903
  const { stdout } = await execAsync3("vm_stat", {
18806
18904
  encoding: "utf-8",
@@ -18824,19 +18922,19 @@ async function updateDarwinMemoryCache() {
18824
18922
  const fileBacked = counts["file_backed"] ?? 0;
18825
18923
  const availPages = free + inactive + speculative + purgeable + fileBacked;
18826
18924
  const bytes = availPages * pageSize;
18827
- cachedDarwinAvail = Number.isFinite(bytes) && bytes >= 0 ? Math.min(bytes, os6.totalmem()) : null;
18925
+ cachedDarwinAvail = Number.isFinite(bytes) && bytes >= 0 ? Math.min(bytes, os7.totalmem()) : null;
18828
18926
  } catch {
18829
18927
  }
18830
18928
  }
18831
18929
  function getHostMemorySnapshot() {
18832
- if (os6.platform() === "darwin" && !darwinMemoryInterval) {
18930
+ if (os7.platform() === "darwin" && !darwinMemoryInterval) {
18833
18931
  updateDarwinMemoryCache();
18834
18932
  darwinMemoryInterval = setInterval(updateDarwinMemoryCache, 3e3);
18835
18933
  darwinMemoryInterval.unref();
18836
18934
  }
18837
- const totalMem = os6.totalmem();
18838
- const freeMem = os6.freemem();
18839
- const availableMem = os6.platform() === "darwin" ? cachedDarwinAvail ?? freeMem : freeMem;
18935
+ const totalMem = os7.totalmem();
18936
+ const freeMem = os7.freemem();
18937
+ const availableMem = os7.platform() === "darwin" ? cachedDarwinAvail ?? freeMem : freeMem;
18840
18938
  return {
18841
18939
  totalMem,
18842
18940
  freeMem,
@@ -21198,9 +21296,9 @@ ${cleanBody}`;
21198
21296
 
21199
21297
  // src/config/chat-history.ts
21200
21298
  import * as fs5 from "fs";
21201
- import * as path12 from "path";
21202
- import * as os7 from "os";
21203
- var HISTORY_DIR = path12.join(os7.homedir(), ".adhdev", "history");
21299
+ import * as path13 from "path";
21300
+ import * as os8 from "os";
21301
+ var HISTORY_DIR = path13.join(os8.homedir(), ".adhdev", "history");
21204
21302
  var RETAIN_DAYS = 30;
21205
21303
  var SAVED_HISTORY_INDEX_VERSION = 1;
21206
21304
  var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
@@ -21386,7 +21484,7 @@ function extractSavedHistorySessionIdFromFile(file) {
21386
21484
  function buildSavedHistoryFileSignatureMap(dir, files) {
21387
21485
  return new Map(files.map((file) => {
21388
21486
  try {
21389
- const stat2 = fs5.statSync(path12.join(dir, file));
21487
+ const stat2 = fs5.statSync(path13.join(dir, file));
21390
21488
  return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
21391
21489
  } catch {
21392
21490
  return [file, `${file}:missing`];
@@ -21397,7 +21495,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
21397
21495
  return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
21398
21496
  }
21399
21497
  function getSavedHistoryIndexFilePath(dir) {
21400
- return path12.join(dir, SAVED_HISTORY_INDEX_FILE);
21498
+ return path13.join(dir, SAVED_HISTORY_INDEX_FILE);
21401
21499
  }
21402
21500
  function getSavedHistoryIndexLockPath(dir) {
21403
21501
  return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
@@ -21499,7 +21597,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
21499
21597
  }
21500
21598
  for (const file of Array.from(currentEntries.keys())) {
21501
21599
  if (incomingFiles.has(file)) continue;
21502
- if (!fs5.existsSync(path12.join(dir, file))) {
21600
+ if (!fs5.existsSync(path13.join(dir, file))) {
21503
21601
  currentEntries.delete(file);
21504
21602
  }
21505
21603
  }
@@ -21525,7 +21623,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
21525
21623
  const indexStat = fs5.statSync(getSavedHistoryIndexFilePath(dir));
21526
21624
  const files = listHistoryFiles(dir);
21527
21625
  for (const file of files) {
21528
- const stat2 = fs5.statSync(path12.join(dir, file));
21626
+ const stat2 = fs5.statSync(path13.join(dir, file));
21529
21627
  if (stat2.mtimeMs > indexStat.mtimeMs) return true;
21530
21628
  }
21531
21629
  return false;
@@ -21535,14 +21633,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
21535
21633
  }
21536
21634
  function buildSavedHistoryFileSignature(dir, file) {
21537
21635
  try {
21538
- const stat2 = fs5.statSync(path12.join(dir, file));
21636
+ const stat2 = fs5.statSync(path13.join(dir, file));
21539
21637
  return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
21540
21638
  } catch {
21541
21639
  return `${file}:missing`;
21542
21640
  }
21543
21641
  }
21544
21642
  function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
21545
- const filePath = path12.join(dir, file);
21643
+ const filePath = path13.join(dir, file);
21546
21644
  const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
21547
21645
  const currentEntry = entries.get(file) || null;
21548
21646
  const nextSummary = updater(currentEntry?.summary || null);
@@ -21615,7 +21713,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
21615
21713
  function computeSavedHistoryFileSummary(dir, file) {
21616
21714
  const historySessionId = extractSavedHistorySessionIdFromFile(file);
21617
21715
  if (!historySessionId) return null;
21618
- const filePath = path12.join(dir, file);
21716
+ const filePath = path13.join(dir, file);
21619
21717
  const content = fs5.readFileSync(filePath, "utf-8");
21620
21718
  const lines = content.split("\n").filter(Boolean);
21621
21719
  let messageCount = 0;
@@ -21702,7 +21800,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
21702
21800
  const summaryBySessionId = /* @__PURE__ */ new Map();
21703
21801
  const nextPersistedEntries = /* @__PURE__ */ new Map();
21704
21802
  for (const file of files.slice().sort()) {
21705
- const filePath = path12.join(dir, file);
21803
+ const filePath = path13.join(dir, file);
21706
21804
  const signature = fileSignatures.get(file) || `${file}:missing`;
21707
21805
  const cached2 = savedHistoryFileSummaryCache.get(filePath);
21708
21806
  const persisted = persistedEntries.get(file);
@@ -21822,12 +21920,12 @@ var ChatHistoryWriter = class {
21822
21920
  });
21823
21921
  }
21824
21922
  if (newMessages.length === 0) return;
21825
- const dir = path12.join(HISTORY_DIR, this.sanitize(agentType));
21923
+ const dir = path13.join(HISTORY_DIR, this.sanitize(agentType));
21826
21924
  fs5.mkdirSync(dir, { recursive: true });
21827
21925
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
21828
21926
  const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
21829
21927
  const fileName = `${filePrefix}${date}.jsonl`;
21830
- const filePath = path12.join(dir, fileName);
21928
+ const filePath = path13.join(dir, fileName);
21831
21929
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
21832
21930
  fs5.appendFileSync(filePath, lines, "utf-8");
21833
21931
  updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
@@ -21918,11 +22016,11 @@ var ChatHistoryWriter = class {
21918
22016
  const ws = String(workspace || "").trim();
21919
22017
  if (!id || !ws) return;
21920
22018
  try {
21921
- const dir = path12.join(HISTORY_DIR, this.sanitize(agentType));
22019
+ const dir = path13.join(HISTORY_DIR, this.sanitize(agentType));
21922
22020
  fs5.mkdirSync(dir, { recursive: true });
21923
22021
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
21924
22022
  const fileName = `${this.sanitize(id)}_${date}.jsonl`;
21925
- const filePath = path12.join(dir, fileName);
22023
+ const filePath = path13.join(dir, fileName);
21926
22024
  const record = {
21927
22025
  ts: (/* @__PURE__ */ new Date()).toISOString(),
21928
22026
  receivedAt: Date.now(),
@@ -21968,14 +22066,14 @@ var ChatHistoryWriter = class {
21968
22066
  this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
21969
22067
  this.lastSeenCounts.delete(fromDedupKey);
21970
22068
  }
21971
- const dir = path12.join(HISTORY_DIR, this.sanitize(agentType));
22069
+ const dir = path13.join(HISTORY_DIR, this.sanitize(agentType));
21972
22070
  if (!fs5.existsSync(dir)) return;
21973
22071
  const fromPrefix = `${this.sanitize(fromId)}_`;
21974
22072
  const toPrefix = `${this.sanitize(toId)}_`;
21975
22073
  const files = fs5.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
21976
22074
  for (const file of files) {
21977
- const sourcePath = path12.join(dir, file);
21978
- const targetPath = path12.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
22075
+ const sourcePath = path13.join(dir, file);
22076
+ const targetPath = path13.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
21979
22077
  const sourceLines = fs5.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
21980
22078
  const rewritten = sourceLines.map((line) => {
21981
22079
  try {
@@ -22009,13 +22107,13 @@ var ChatHistoryWriter = class {
22009
22107
  const sessionId = String(historySessionId || "").trim();
22010
22108
  if (!sessionId) return;
22011
22109
  try {
22012
- const dir = path12.join(HISTORY_DIR, this.sanitize(agentType));
22110
+ const dir = path13.join(HISTORY_DIR, this.sanitize(agentType));
22013
22111
  if (!fs5.existsSync(dir)) return;
22014
22112
  const prefix = `${this.sanitize(sessionId)}_`;
22015
22113
  const files = fs5.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
22016
22114
  const seen = /* @__PURE__ */ new Set();
22017
22115
  for (const file of files) {
22018
- const filePath = path12.join(dir, file);
22116
+ const filePath = path13.join(dir, file);
22019
22117
  const lines = fs5.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
22020
22118
  const next = [];
22021
22119
  for (const line of lines) {
@@ -22069,11 +22167,11 @@ var ChatHistoryWriter = class {
22069
22167
  const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
22070
22168
  const agentDirs = fs5.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
22071
22169
  for (const dir of agentDirs) {
22072
- const dirPath = path12.join(HISTORY_DIR, dir.name);
22170
+ const dirPath = path13.join(HISTORY_DIR, dir.name);
22073
22171
  const files = fs5.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
22074
22172
  let removedAny = false;
22075
22173
  for (const file of files) {
22076
- const filePath = path12.join(dirPath, file);
22174
+ const filePath = path13.join(dirPath, file);
22077
22175
  const stat2 = fs5.statSync(filePath);
22078
22176
  if (stat2.mtimeMs < cutoff) {
22079
22177
  fs5.unlinkSync(filePath);
@@ -22276,7 +22374,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
22276
22374
  const seen = /* @__PURE__ */ new Set();
22277
22375
  let readAllFiles = true;
22278
22376
  for (let f = 0; f < files.length; f++) {
22279
- const filePath = path12.join(dir, files[f]);
22377
+ const filePath = path13.join(dir, files[f]);
22280
22378
  const remaining = Math.max(0, needed - collected.length);
22281
22379
  const perFileNeeded = Math.min(needed, remaining + BOUNDED_TAIL_SLACK);
22282
22380
  const { lines, coversWholeFile } = readFileTailLines(filePath, perFileNeeded);
@@ -22309,7 +22407,7 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
22309
22407
  function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
22310
22408
  try {
22311
22409
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
22312
- const dir = path12.join(HISTORY_DIR, sanitized);
22410
+ const dir = path13.join(HISTORY_DIR, sanitized);
22313
22411
  if (!fs5.existsSync(dir)) return { messages: [], hasMore: false };
22314
22412
  const files = listHistoryFiles(dir, historySessionId);
22315
22413
  const bounded = isBoundedTailRequest(limit, offset, excludeRecentCount);
@@ -22332,7 +22430,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
22332
22430
  const allMessages = [];
22333
22431
  const seen = /* @__PURE__ */ new Set();
22334
22432
  for (const file of files) {
22335
- const filePath = path12.join(dir, file);
22433
+ const filePath = path13.join(dir, file);
22336
22434
  const content = fs5.readFileSync(filePath, "utf-8");
22337
22435
  const lines = content.trim().split("\n").filter(Boolean);
22338
22436
  for (let i = 0; i < lines.length; i++) {
@@ -22356,7 +22454,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
22356
22454
  function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
22357
22455
  try {
22358
22456
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
22359
- const dir = path12.join(HISTORY_DIR, sanitized);
22457
+ const dir = path13.join(HISTORY_DIR, sanitized);
22360
22458
  if (!fs5.existsSync(dir)) {
22361
22459
  savedHistorySessionCache.delete(sanitized);
22362
22460
  return { sessions: [], hasMore: false };
@@ -22417,11 +22515,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
22417
22515
  }
22418
22516
  function readExistingSessionStartRecord(agentType, historySessionId) {
22419
22517
  try {
22420
- const dir = path12.join(HISTORY_DIR, agentType);
22518
+ const dir = path13.join(HISTORY_DIR, agentType);
22421
22519
  if (!fs5.existsSync(dir)) return null;
22422
22520
  const files = listHistoryFiles(dir, historySessionId).sort();
22423
22521
  for (const file of files) {
22424
- const lines = fs5.readFileSync(path12.join(dir, file), "utf-8").split("\n").filter(Boolean);
22522
+ const lines = fs5.readFileSync(path13.join(dir, file), "utf-8").split("\n").filter(Boolean);
22425
22523
  for (const line of lines) {
22426
22524
  try {
22427
22525
  const parsed = JSON.parse(line);
@@ -22441,16 +22539,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
22441
22539
  function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
22442
22540
  if (records.length === 0) return false;
22443
22541
  try {
22444
- const dir = path12.join(HISTORY_DIR, agentType);
22542
+ const dir = path13.join(HISTORY_DIR, agentType);
22445
22543
  fs5.mkdirSync(dir, { recursive: true });
22446
22544
  const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
22447
22545
  for (const file of fs5.readdirSync(dir)) {
22448
22546
  if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
22449
- fs5.unlinkSync(path12.join(dir, file));
22547
+ fs5.unlinkSync(path13.join(dir, file));
22450
22548
  }
22451
22549
  }
22452
22550
  const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
22453
- const filePath = path12.join(dir, `${prefix}${targetDate}.jsonl`);
22551
+ const filePath = path13.join(dir, `${prefix}${targetDate}.jsonl`);
22454
22552
  fs5.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
22455
22553
  `, "utf-8");
22456
22554
  invalidatePersistedSavedHistoryIndex(agentType, dir);
@@ -25045,8 +25143,8 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
25045
25143
 
25046
25144
  // src/commands/chat-commands.ts
25047
25145
  import * as fs6 from "fs";
25048
- import * as os8 from "os";
25049
- import * as path13 from "path";
25146
+ import * as os9 from "os";
25147
+ import * as path14 from "path";
25050
25148
  import { randomUUID as randomUUID11 } from "crypto";
25051
25149
  init_logger();
25052
25150
 
@@ -26095,7 +26193,7 @@ function readExactRuntimeMirrorMessages(args) {
26095
26193
  function normalizeComparableWorkspace(value) {
26096
26194
  const text = typeof value === "string" ? value.trim() : "";
26097
26195
  if (!text) return "";
26098
- return path13.resolve(text);
26196
+ return path14.resolve(text);
26099
26197
  }
26100
26198
  function isCurrentRuntimePtySafelyAttributed(args) {
26101
26199
  if (args.adapter.cliType !== "codex-cli") return false;
@@ -26580,7 +26678,7 @@ function buildDebugBundleText(bundle) {
26580
26678
  }
26581
26679
  function getChatDebugBundleDir() {
26582
26680
  const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
26583
- return override || path13.join(os8.homedir(), ".adhdev", "debug-bundles", "chat");
26681
+ return override || path14.join(os9.homedir(), ".adhdev", "debug-bundles", "chat");
26584
26682
  }
26585
26683
  function safeBundleIdSegment(value, fallback) {
26586
26684
  const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
@@ -26637,7 +26735,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
26637
26735
  const bundleId = createChatDebugBundleId(targetSessionId);
26638
26736
  const dir = getChatDebugBundleDir();
26639
26737
  fs6.mkdirSync(dir, { recursive: true });
26640
- const savedPath = path13.join(dir, `${bundleId}.json`);
26738
+ const savedPath = path14.join(dir, `${bundleId}.json`);
26641
26739
  const json = `${JSON.stringify(bundle, null, 2)}
26642
26740
  `;
26643
26741
  fs6.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
@@ -28201,8 +28299,8 @@ async function handleResolveAction(h, args) {
28201
28299
 
28202
28300
  // src/commands/cdp-commands.ts
28203
28301
  import * as fs7 from "fs";
28204
- import * as path14 from "path";
28205
- import * as os9 from "os";
28302
+ import * as path15 from "path";
28303
+ import * as os10 from "os";
28206
28304
  var KEY_TO_VK = {
28207
28305
  Backspace: 8,
28208
28306
  Tab: 9,
@@ -28456,27 +28554,27 @@ function normalizeWindowsRequestedPath(requestedPath) {
28456
28554
  function resolveSafePath(requestedPath) {
28457
28555
  const rawPath = typeof requestedPath === "string" ? requestedPath.trim() : "";
28458
28556
  const inputPath = rawPath || ".";
28459
- const home = os9.homedir();
28557
+ const home = os10.homedir();
28460
28558
  if (inputPath.startsWith("~")) {
28461
- return path14.resolve(path14.join(home, inputPath.slice(1)));
28559
+ return path15.resolve(path15.join(home, inputPath.slice(1)));
28462
28560
  }
28463
28561
  if (process.platform === "win32") {
28464
28562
  const normalized = normalizeWindowsRequestedPath(inputPath);
28465
- if (path14.win32.isAbsolute(normalized)) {
28466
- return path14.win32.normalize(normalized);
28563
+ if (path15.win32.isAbsolute(normalized)) {
28564
+ return path15.win32.normalize(normalized);
28467
28565
  }
28468
- return path14.win32.resolve(normalized);
28566
+ return path15.win32.resolve(normalized);
28469
28567
  }
28470
- if (path14.isAbsolute(inputPath)) {
28471
- return path14.normalize(inputPath);
28568
+ if (path15.isAbsolute(inputPath)) {
28569
+ return path15.normalize(inputPath);
28472
28570
  }
28473
- return path14.resolve(inputPath);
28571
+ return path15.resolve(inputPath);
28474
28572
  }
28475
28573
  function listDirectoryEntriesSafe(dirPath) {
28476
28574
  const entries = fs7.readdirSync(dirPath, { withFileTypes: true });
28477
28575
  const files = [];
28478
28576
  for (const entry of entries) {
28479
- const entryPath = path14.join(dirPath, entry.name);
28577
+ const entryPath = path15.join(dirPath, entry.name);
28480
28578
  try {
28481
28579
  if (entry.isDirectory()) {
28482
28580
  files.push({ name: entry.name, type: "directory" });
@@ -28530,7 +28628,7 @@ async function handleFileRead(h, args) {
28530
28628
  async function handleFileWrite(h, args) {
28531
28629
  try {
28532
28630
  const filePath = resolveSafePath(args?.path);
28533
- fs7.mkdirSync(path14.dirname(filePath), { recursive: true });
28631
+ fs7.mkdirSync(path15.dirname(filePath), { recursive: true });
28534
28632
  fs7.writeFileSync(filePath, args?.content || "", "utf-8");
28535
28633
  return { success: true, path: filePath };
28536
28634
  } catch (e) {
@@ -41366,7 +41464,7 @@ init_mesh_refine_status();
41366
41464
 
41367
41465
  // src/mesh/mesh-init.ts
41368
41466
  import { existsSync as existsSync35, mkdirSync as mkdirSync15, writeFileSync as writeFileSync17 } from "fs";
41369
- import { dirname as dirname8, join as join37 } from "path";
41467
+ import { dirname as dirname9, join as join38 } from "path";
41370
41468
  var MESH_INIT_REFINE_CONFIG_PATH = MESH_REFINE_CONFIG_LOCATIONS[0];
41371
41469
  var MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH = MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS[0];
41372
41470
  var CANDIDATE_STALE_INPUTS = [
@@ -41380,22 +41478,22 @@ var CANDIDATE_STALE_INPUTS = [
41380
41478
  "requirements.txt"
41381
41479
  ];
41382
41480
  function writeConfigFile(workspace, relativePath, config) {
41383
- const target = join37(workspace, relativePath);
41384
- mkdirSync15(dirname8(target), { recursive: true });
41481
+ const target = join38(workspace, relativePath);
41482
+ mkdirSync15(dirname9(target), { recursive: true });
41385
41483
  writeFileSync17(target, `${JSON.stringify(config, null, 2)}
41386
41484
  `, "utf-8");
41387
41485
  return target;
41388
41486
  }
41389
41487
  function suggestMeshWorktreeBootstrapConfig(workspace) {
41390
41488
  const commands = [];
41391
- const hasPackageJson = existsSync35(join37(workspace, "package.json"));
41392
- const hasNpmLock = existsSync35(join37(workspace, "package-lock.json"));
41489
+ const hasPackageJson = existsSync35(join38(workspace, "package.json"));
41490
+ const hasNpmLock = existsSync35(join38(workspace, "package-lock.json"));
41393
41491
  if (hasPackageJson) {
41394
41492
  commands.push(
41395
41493
  hasNpmLock ? { command: "npm", args: ["ci"] } : { command: "npm", args: ["install"] }
41396
41494
  );
41397
41495
  }
41398
- const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => existsSync35(join37(workspace, relative5)));
41496
+ const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => existsSync35(join38(workspace, relative5)));
41399
41497
  if (!commands.length) {
41400
41498
  return { commands, staleInputs };
41401
41499
  }
@@ -41463,7 +41561,7 @@ function runMeshInit(mesh, workspace, detected, options = {}) {
41463
41561
  }
41464
41562
  function applyConfigSuggestion(input) {
41465
41563
  const { workspace, relativePath, existing, suggestedConfig, validate, write, overwrite } = input;
41466
- const absolute = join37(workspace, relativePath);
41564
+ const absolute = join38(workspace, relativePath);
41467
41565
  if (existing !== void 0 && !overwrite) {
41468
41566
  return { path: absolute, relativePath, written: false, skippedReason: "already_exists", config: existing };
41469
41567
  }
@@ -42945,7 +43043,15 @@ var MESH_DIRECT_PROBE_MAX_RETRIES = 2;
42945
43043
  function readMeshConnectionState(connection) {
42946
43044
  return readStringValue(connection?.state);
42947
43045
  }
43046
+ function isMeshConnectionDefinitivelyDown(connection) {
43047
+ if (!connection) return true;
43048
+ const state = readMeshConnectionState(connection);
43049
+ return state === "failed" || state === "closed" || state === "disconnected";
43050
+ }
42948
43051
  async function probeRemoteMeshGitStatusWithRetry(args) {
43052
+ if (args.getConnection && isMeshConnectionDefinitivelyDown(args.getConnection(args.daemonId))) {
43053
+ return null;
43054
+ }
42949
43055
  for (let attempt = 0; attempt <= MESH_DIRECT_PROBE_MAX_RETRIES; attempt += 1) {
42950
43056
  if (attempt > 0) {
42951
43057
  const connection = args.getConnection?.(args.daemonId);
@@ -48783,7 +48889,7 @@ ${ptyResult.output.slice(-2e3)}`);
48783
48889
  };
48784
48890
  }
48785
48891
  const { existsSync: existsSync44, readFileSync: readFileSync35, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
48786
- const { dirname: dirname15 } = await import("path");
48892
+ const { dirname: dirname16 } = await import("path");
48787
48893
  const mcpConfigPath = coordinatorSetup.configPath;
48788
48894
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
48789
48895
  let hermesBaseConfig = null;
@@ -48818,7 +48924,7 @@ ${ptyResult.output.slice(-2e3)}`);
48818
48924
  };
48819
48925
  }
48820
48926
  try {
48821
- mkdirSync21(dirname15(mcpConfigPath), { recursive: true });
48927
+ mkdirSync21(dirname16(mcpConfigPath), { recursive: true });
48822
48928
  } catch (error) {
48823
48929
  const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
48824
48930
  LOG.error("MeshCoordinator", message);
@@ -48828,7 +48934,7 @@ ${ptyResult.output.slice(-2e3)}`);
48828
48934
  const hadExistingMcpConfig = existsSync44(mcpConfigPath);
48829
48935
  let existingMcpConfig = hermesBaseConfig?.config || {};
48830
48936
  if (hermesBaseConfig) {
48831
- copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname15(mcpConfigPath));
48937
+ copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname16(mcpConfigPath));
48832
48938
  }
48833
48939
  if (hadExistingMcpConfig) {
48834
48940
  try {
@@ -48866,7 +48972,7 @@ ${ptyResult.output.slice(-2e3)}`);
48866
48972
  const cliArgs = [];
48867
48973
  const launchEnv = {};
48868
48974
  if (configFormat === "hermes_config_yaml") {
48869
- launchEnv.HERMES_HOME = dirname15(mcpConfigPath);
48975
+ launchEnv.HERMES_HOME = dirname16(mcpConfigPath);
48870
48976
  launchEnv.HERMES_IGNORE_USER_CONFIG = "";
48871
48977
  }
48872
48978
  let autoImportContextFilePath;
@@ -57891,11 +57997,11 @@ init_parse_session();
57891
57997
  // src/providers/sdk/v1/fixture-tooling/replay.ts
57892
57998
  init_provider_cli_shared();
57893
57999
  import { readFileSync as readFileSync33 } from "fs";
57894
- import { dirname as dirname13, resolve as resolve22 } from "path";
58000
+ import { dirname as dirname14, resolve as resolve22 } from "path";
57895
58001
 
57896
58002
  // src/providers/sdk/v1/validators/taint.ts
57897
58003
  import { readFileSync as readFileSync34, existsSync as existsSync43 } from "fs";
57898
- import { resolve as resolve23, dirname as dirname14, join as join44 } from "path";
58004
+ import { resolve as resolve23, dirname as dirname15, join as join45 } from "path";
57899
58005
 
57900
58006
  // src/providers/sdk/v1/validators/index.ts
57901
58007
  init_manifest();