@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 +641 -535
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +652 -546
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-runtime-store.d.ts +6 -0
- package/package.json +2 -2
- package/src/cli-adapters/resolve-executable.ts +46 -1
- package/src/commands/router.ts +32 -0
- package/src/detection/cli-detector.ts +28 -9
- package/src/git/git-status.ts +122 -41
- package/src/mesh/mesh-events-coordinator.ts +5 -1
- package/src/mesh/mesh-reconcile-loop.ts +31 -1
- package/src/mesh/mesh-runtime-store.ts +13 -0
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 ? "
|
|
357
|
-
const commitShort = readInjected(true ? "
|
|
358
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
359
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
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
|
|
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
|
|
8327
|
+
return path11.join(os6.homedir(), trimmed.slice(1));
|
|
7874
8328
|
}
|
|
7875
8329
|
function isExplicitCommandPath(command) {
|
|
7876
8330
|
const trimmed = command.trim();
|
|
7877
|
-
return
|
|
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 =
|
|
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 =
|
|
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
|
|
7914
|
-
|
|
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 =
|
|
8411
|
+
const platform10 = os6.platform();
|
|
7951
8412
|
const whichCmd = platform10 === "win32" ? "where" : "which";
|
|
7952
8413
|
try {
|
|
7953
|
-
const
|
|
7954
|
-
|
|
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,
|
|
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
|
-
|
|
7991
|
-
|
|
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
|
|
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
|
|
11056
|
+
return path16.join(os11.homedir(), ".adhdev");
|
|
10582
11057
|
}
|
|
10583
11058
|
function externalRoot() {
|
|
10584
|
-
return
|
|
11059
|
+
return path16.join(adhdevDir(), "external");
|
|
10585
11060
|
}
|
|
10586
11061
|
function sourcesFilePath() {
|
|
10587
|
-
return
|
|
11062
|
+
return path16.join(adhdevDir(), SOURCES_FILENAME);
|
|
10588
11063
|
}
|
|
10589
11064
|
function activeFilePath() {
|
|
10590
|
-
return
|
|
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 =
|
|
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 =
|
|
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 =
|
|
10679
|
-
const hasV1 = fs8.existsSync(
|
|
10680
|
-
const hasV0 = fs8.existsSync(
|
|
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,
|
|
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
|
-
|
|
10709
|
-
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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 (
|
|
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(
|
|
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,
|
|
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
|
-
|
|
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,
|
|
11424
|
+
(0, import_session_host_core2.ensureNodePtySpawnHelperPermissions)();
|
|
10937
11425
|
} catch {
|
|
10938
11426
|
cachedPty = null;
|
|
10939
11427
|
}
|
|
10940
11428
|
return cachedPty;
|
|
10941
11429
|
}
|
|
10942
|
-
var
|
|
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
|
-
|
|
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 =
|
|
11474
|
+
if (!stat2.isDirectory()) cwd = os12.homedir();
|
|
10987
11475
|
} catch {
|
|
10988
|
-
cwd =
|
|
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
|
|
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 (
|
|
19056
|
-
const candidate = trimmed.startsWith("~") ?
|
|
19057
|
-
const resolved =
|
|
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 =
|
|
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("~") ?
|
|
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:
|
|
19118
|
-
const appDir =
|
|
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
|
|
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 (
|
|
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,
|
|
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 (
|
|
19287
|
+
if (os7.platform() === "darwin" && !darwinMemoryInterval) {
|
|
19190
19288
|
updateDarwinMemoryCache();
|
|
19191
19289
|
darwinMemoryInterval = setInterval(updateDarwinMemoryCache, 3e3);
|
|
19192
19290
|
darwinMemoryInterval.unref();
|
|
19193
19291
|
}
|
|
19194
|
-
const totalMem =
|
|
19195
|
-
const freeMem =
|
|
19196
|
-
const availableMem =
|
|
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
|
|
21559
|
-
var
|
|
21560
|
-
var HISTORY_DIR =
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
22335
|
-
const targetPath =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
|
25406
|
-
var
|
|
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
|
|
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 ||
|
|
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 =
|
|
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
|
|
28562
|
-
var
|
|
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 =
|
|
28914
|
+
const home = os10.homedir();
|
|
28817
28915
|
if (inputPath.startsWith("~")) {
|
|
28818
|
-
return
|
|
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 (
|
|
28823
|
-
return
|
|
28920
|
+
if (path15.win32.isAbsolute(normalized)) {
|
|
28921
|
+
return path15.win32.normalize(normalized);
|
|
28824
28922
|
}
|
|
28825
|
-
return
|
|
28923
|
+
return path15.win32.resolve(normalized);
|
|
28826
28924
|
}
|
|
28827
|
-
if (
|
|
28828
|
-
return
|
|
28925
|
+
if (path15.isAbsolute(inputPath)) {
|
|
28926
|
+
return path15.normalize(inputPath);
|
|
28829
28927
|
}
|
|
28830
|
-
return
|
|
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 =
|
|
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(
|
|
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:
|
|
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(
|
|
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,
|
|
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 =
|
|
49327
|
+
launchEnv.HERMES_HOME = dirname16(mcpConfigPath);
|
|
49222
49328
|
launchEnv.HERMES_IGNORE_USER_CONFIG = "";
|
|
49223
49329
|
}
|
|
49224
49330
|
let autoImportContextFilePath;
|