@adhdev/daemon-core 0.8.30 → 0.8.32
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/agent-stream/manager.d.ts +1 -0
- package/dist/agent-stream/provider-adapter.d.ts +1 -0
- package/dist/agent-stream/types.d.ts +3 -0
- package/dist/boot/daemon-lifecycle.d.ts +2 -1
- package/dist/cdp/manager.d.ts +2 -0
- package/dist/cli-adapter-types.d.ts +34 -5
- package/dist/cli-adapters/provider-cli-adapter.d.ts +4 -158
- package/dist/cli-adapters/provider-cli-config.d.ts +30 -0
- package/dist/cli-adapters/provider-cli-parse.d.ts +42 -0
- package/dist/cli-adapters/provider-cli-runtime.d.ts +29 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +158 -0
- package/dist/commands/handler.d.ts +4 -3
- package/dist/config/config.d.ts +4 -3
- package/dist/index.js +866 -592
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +868 -595
- package/dist/index.mjs.map +1 -1
- package/dist/providers/contracts.d.ts +10 -1
- package/dist/providers/provider-loader.d.ts +3 -0
- package/dist/status/reporter.d.ts +2 -3
- package/dist/status/snapshot.d.ts +2 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +3 -1
- package/src/agent-stream/manager.ts +8 -2
- package/src/agent-stream/poller.ts +19 -5
- package/src/agent-stream/provider-adapter.ts +11 -7
- package/src/agent-stream/types.ts +3 -0
- package/src/boot/daemon-lifecycle.ts +7 -6
- package/src/cdp/initializer.ts +2 -2
- package/src/cdp/manager.ts +5 -0
- package/src/cdp/setup.ts +1 -1
- package/src/cli-adapter-types.ts +37 -5
- package/src/cli-adapters/provider-cli-adapter.ts +212 -795
- package/src/cli-adapters/provider-cli-config.ts +66 -0
- package/src/cli-adapters/provider-cli-parse.ts +202 -0
- package/src/cli-adapters/provider-cli-runtime.ts +142 -0
- package/src/cli-adapters/provider-cli-shared.ts +439 -0
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +1 -1
- package/src/commands/cdp-commands.ts +6 -1
- package/src/commands/chat-commands.ts +45 -29
- package/src/commands/cli-manager.ts +28 -9
- package/src/commands/handler.ts +14 -10
- package/src/commands/router.ts +23 -10
- package/src/commands/stream-commands.ts +11 -5
- package/src/config/config.ts +4 -10
- package/src/daemon/dev-auto-implement.ts +22 -18
- package/src/daemon/dev-cli-debug.ts +59 -16
- package/src/daemon/dev-server.ts +67 -43
- package/src/providers/acp-provider-instance.ts +1 -1
- package/src/providers/cli-provider-instance.ts +2 -2
- package/src/providers/contracts.ts +12 -1
- package/src/providers/extension-provider-instance.ts +1 -1
- package/src/providers/ide-provider-instance.ts +39 -18
- package/src/providers/provider-loader.ts +85 -54
- package/src/providers/version-archive.ts +23 -5
- package/src/status/reporter.ts +18 -14
- package/src/status/snapshot.ts +5 -4
package/dist/index.js
CHANGED
|
@@ -94,12 +94,10 @@ function ensureMachineId(config) {
|
|
|
94
94
|
if (isStableMachineId(config.machineId)) {
|
|
95
95
|
return { config, changed: false };
|
|
96
96
|
}
|
|
97
|
-
const legacyRegisteredMachineId = !config.registeredMachineId && config.machineSecret && config.machineId ? config.machineId : config.registeredMachineId;
|
|
98
97
|
return {
|
|
99
98
|
config: {
|
|
100
99
|
...config,
|
|
101
|
-
machineId: generateMachineId()
|
|
102
|
-
registeredMachineId: legacyRegisteredMachineId
|
|
100
|
+
machineId: generateMachineId()
|
|
103
101
|
},
|
|
104
102
|
changed: true
|
|
105
103
|
};
|
|
@@ -455,7 +453,7 @@ var init_logger = __esm({
|
|
|
455
453
|
function isModuleNotFoundError(error, ref) {
|
|
456
454
|
if (!(error instanceof Error)) return false;
|
|
457
455
|
const message = error.message || "";
|
|
458
|
-
const code = error.code;
|
|
456
|
+
const code = "code" in error ? error.code : void 0;
|
|
459
457
|
return code === "MODULE_NOT_FOUND" && message.includes(ref);
|
|
460
458
|
}
|
|
461
459
|
function normalizeBinding(mod, ref) {
|
|
@@ -797,12 +795,7 @@ var init_pty_transport = __esm({
|
|
|
797
795
|
}
|
|
798
796
|
});
|
|
799
797
|
|
|
800
|
-
// src/cli-adapters/provider-cli-
|
|
801
|
-
var provider_cli_adapter_exports = {};
|
|
802
|
-
__export(provider_cli_adapter_exports, {
|
|
803
|
-
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
804
|
-
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
805
|
-
});
|
|
798
|
+
// src/cli-adapters/provider-cli-shared.ts
|
|
806
799
|
function stripAnsi(str) {
|
|
807
800
|
return str.replace(/\x1B\][^\x07]*\x07/g, "").replace(/\x1B\][\s\S]*?\x1B\\/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B\[\d*[A-HJKSTfG]/g, " ").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "").replace(/ +/g, " ");
|
|
808
801
|
}
|
|
@@ -812,6 +805,10 @@ function stripTerminalNoise(str) {
|
|
|
812
805
|
function sanitizeTerminalText(str) {
|
|
813
806
|
return stripTerminalNoise(stripAnsi(str));
|
|
814
807
|
}
|
|
808
|
+
function listCliScriptNames(scripts) {
|
|
809
|
+
if (!scripts) return [];
|
|
810
|
+
return Object.entries(scripts).filter(([, fn]) => typeof fn === "function").map(([name]) => name);
|
|
811
|
+
}
|
|
815
812
|
function splitCliScreenLines(text) {
|
|
816
813
|
return String(text || "").replace(/\u0007/g, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => line.replace(/\s+$/, ""));
|
|
817
814
|
}
|
|
@@ -859,18 +856,6 @@ function buildCliScreenSnapshot(text) {
|
|
|
859
856
|
linesBelowPrompt: promptLineIndex >= 0 ? lines.slice(promptLineIndex + 1) : []
|
|
860
857
|
};
|
|
861
858
|
}
|
|
862
|
-
function computeTerminalQueryTail(buffer) {
|
|
863
|
-
const prefixes = ["\x1B[6n", "\x1B[?6n"];
|
|
864
|
-
const maxLength = prefixes.reduce((n, value) => Math.max(n, value.length), 0) - 1;
|
|
865
|
-
const start = Math.max(0, buffer.length - maxLength);
|
|
866
|
-
for (let i = start; i < buffer.length; i++) {
|
|
867
|
-
const suffix = buffer.slice(i);
|
|
868
|
-
if (prefixes.some((pattern) => suffix.length < pattern.length && pattern.startsWith(suffix))) {
|
|
869
|
-
return suffix;
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
return "";
|
|
873
|
-
}
|
|
874
859
|
function findBinary(name) {
|
|
875
860
|
const trimmed = String(name || "").trim();
|
|
876
861
|
if (!trimmed) return trimmed;
|
|
@@ -1020,25 +1005,306 @@ function coercePatternArray(raw) {
|
|
|
1020
1005
|
return raw.map(parsePatternEntry).filter((r) => r != null);
|
|
1021
1006
|
}
|
|
1022
1007
|
function normalizeCliProviderForRuntime(raw) {
|
|
1023
|
-
const patterns = raw
|
|
1008
|
+
const patterns = raw && typeof raw === "object" ? raw.patterns : void 0;
|
|
1024
1009
|
return {
|
|
1025
1010
|
patterns: {
|
|
1026
|
-
approval: coercePatternArray(
|
|
1011
|
+
approval: coercePatternArray(
|
|
1012
|
+
patterns && typeof patterns === "object" ? patterns.approval : void 0
|
|
1013
|
+
)
|
|
1027
1014
|
}
|
|
1028
1015
|
};
|
|
1029
1016
|
}
|
|
1030
|
-
var os8, path9, import_child_process4, buildCliSpawnEnv
|
|
1031
|
-
var
|
|
1032
|
-
"src/cli-adapters/provider-cli-
|
|
1017
|
+
var os8, path9, import_child_process4, buildCliSpawnEnv;
|
|
1018
|
+
var init_provider_cli_shared = __esm({
|
|
1019
|
+
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
1033
1020
|
"use strict";
|
|
1034
1021
|
os8 = __toESM(require("os"));
|
|
1035
1022
|
path9 = __toESM(require("path"));
|
|
1036
1023
|
import_child_process4 = require("child_process");
|
|
1024
|
+
init_spawn_env();
|
|
1025
|
+
buildCliSpawnEnv = import_session_host_core.sanitizeSpawnEnv;
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
// src/cli-adapters/provider-cli-parse.ts
|
|
1030
|
+
function sliceFromOffset(text, start) {
|
|
1031
|
+
if (!text) return "";
|
|
1032
|
+
if (!Number.isFinite(start) || start <= 0) return text;
|
|
1033
|
+
if (start >= text.length) return "";
|
|
1034
|
+
return text.slice(start);
|
|
1035
|
+
}
|
|
1036
|
+
function hydrateCliParsedMessages(parsedMessages, options) {
|
|
1037
|
+
const { committedMessages, scope, lastOutputAt } = options;
|
|
1038
|
+
const referenceMessages = [...committedMessages];
|
|
1039
|
+
const usedReferenceIndexes = /* @__PURE__ */ new Set();
|
|
1040
|
+
const now = options.now ?? Date.now();
|
|
1041
|
+
const findReferenceTimestamp = (role, content, parsedIndex) => {
|
|
1042
|
+
const normalizedContent = normalizeComparableMessageContent(content);
|
|
1043
|
+
if (!normalizedContent) return void 0;
|
|
1044
|
+
const sameIndex = referenceMessages[parsedIndex];
|
|
1045
|
+
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && normalizeComparableMessageContent(sameIndex.content) === normalizedContent && typeof sameIndex.timestamp === "number" && Number.isFinite(sameIndex.timestamp)) {
|
|
1046
|
+
usedReferenceIndexes.add(parsedIndex);
|
|
1047
|
+
return sameIndex.timestamp;
|
|
1048
|
+
}
|
|
1049
|
+
for (let i = 0; i < referenceMessages.length; i++) {
|
|
1050
|
+
if (usedReferenceIndexes.has(i)) continue;
|
|
1051
|
+
const candidate = referenceMessages[i];
|
|
1052
|
+
if (!candidate || candidate.role !== role) continue;
|
|
1053
|
+
const candidateContent = normalizeComparableMessageContent(candidate.content);
|
|
1054
|
+
if (!candidateContent) continue;
|
|
1055
|
+
const exactMatch = candidateContent === normalizedContent;
|
|
1056
|
+
const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
|
|
1057
|
+
if (!exactMatch && !fuzzyMatch) continue;
|
|
1058
|
+
if (typeof candidate.timestamp === "number" && Number.isFinite(candidate.timestamp)) {
|
|
1059
|
+
usedReferenceIndexes.add(i);
|
|
1060
|
+
return candidate.timestamp;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
return void 0;
|
|
1064
|
+
};
|
|
1065
|
+
return parsedMessages.filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message, index) => {
|
|
1066
|
+
const role = message.role;
|
|
1067
|
+
const content = typeof message.content === "string" ? message.content : String(message.content || "");
|
|
1068
|
+
const parsedTimestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0;
|
|
1069
|
+
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(role, content, index);
|
|
1070
|
+
const fallbackTimestamp = role === "user" ? scope?.startedAt || now : lastOutputAt || scope?.startedAt || now;
|
|
1071
|
+
const timestamp = referenceTimestamp ?? fallbackTimestamp;
|
|
1072
|
+
return {
|
|
1073
|
+
...message,
|
|
1074
|
+
role,
|
|
1075
|
+
content,
|
|
1076
|
+
timestamp,
|
|
1077
|
+
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp
|
|
1078
|
+
};
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
function normalizeCliParsedMessages(parsedMessages, options) {
|
|
1082
|
+
return hydrateCliParsedMessages(parsedMessages, options).map((message) => ({
|
|
1083
|
+
role: message.role,
|
|
1084
|
+
content: message.content,
|
|
1085
|
+
timestamp: message.timestamp,
|
|
1086
|
+
receivedAt: message.receivedAt,
|
|
1087
|
+
kind: message.kind,
|
|
1088
|
+
id: message.id,
|
|
1089
|
+
index: message.index,
|
|
1090
|
+
meta: message.meta,
|
|
1091
|
+
senderName: message.senderName
|
|
1092
|
+
}));
|
|
1093
|
+
}
|
|
1094
|
+
function buildCliParseInput(options) {
|
|
1095
|
+
const {
|
|
1096
|
+
accumulatedBuffer,
|
|
1097
|
+
accumulatedRawBuffer,
|
|
1098
|
+
recentOutputBuffer,
|
|
1099
|
+
terminalScreenText,
|
|
1100
|
+
baseMessages,
|
|
1101
|
+
partialResponse,
|
|
1102
|
+
scope,
|
|
1103
|
+
runtimeSettings
|
|
1104
|
+
} = options;
|
|
1105
|
+
const buffer = scope ? sliceFromOffset(accumulatedBuffer, scope.bufferStart) || accumulatedBuffer : accumulatedBuffer;
|
|
1106
|
+
const rawBuffer = scope ? sliceFromOffset(accumulatedRawBuffer, scope.rawBufferStart) || accumulatedRawBuffer : accumulatedRawBuffer;
|
|
1107
|
+
const screenText = terminalScreenText;
|
|
1108
|
+
const recentBuffer = buffer.slice(-1e3) || recentOutputBuffer;
|
|
1109
|
+
return {
|
|
1110
|
+
buffer,
|
|
1111
|
+
rawBuffer,
|
|
1112
|
+
recentBuffer,
|
|
1113
|
+
screenText,
|
|
1114
|
+
screen: buildCliScreenSnapshot(screenText),
|
|
1115
|
+
bufferScreen: buildCliScreenSnapshot(buffer),
|
|
1116
|
+
recentScreen: buildCliScreenSnapshot(recentBuffer),
|
|
1117
|
+
messages: [...baseMessages],
|
|
1118
|
+
partialResponse,
|
|
1119
|
+
promptText: scope?.prompt || "",
|
|
1120
|
+
settings: { ...runtimeSettings }
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
function summarizeCliTraceText(text, max = 800) {
|
|
1124
|
+
const value = sanitizeTerminalText(String(text || ""));
|
|
1125
|
+
if (value.length <= max) return value;
|
|
1126
|
+
return `\u2026${value.slice(-max)}`;
|
|
1127
|
+
}
|
|
1128
|
+
function summarizeCliTraceMessages(messages, limit = 3) {
|
|
1129
|
+
return messages.slice(-limit).map((message) => ({
|
|
1130
|
+
role: message.role,
|
|
1131
|
+
content: summarizeCliTraceText(message.content, 240),
|
|
1132
|
+
timestamp: message.timestamp
|
|
1133
|
+
}));
|
|
1134
|
+
}
|
|
1135
|
+
function buildCliTraceParseSnapshot(options) {
|
|
1136
|
+
const { accumulatedBuffer, accumulatedRawBuffer, responseBuffer, partialResponse, scope } = options;
|
|
1137
|
+
const scopedBuffer = scope ? sliceFromOffset(accumulatedBuffer, scope.bufferStart) || accumulatedBuffer : accumulatedBuffer;
|
|
1138
|
+
const scopedRawBuffer = scope ? sliceFromOffset(accumulatedRawBuffer, scope.rawBufferStart) || accumulatedRawBuffer : accumulatedRawBuffer;
|
|
1139
|
+
return {
|
|
1140
|
+
currentTurnScope: scope || null,
|
|
1141
|
+
responseBuffer: summarizeCliTraceText(responseBuffer, 1200),
|
|
1142
|
+
partialResponse: summarizeCliTraceText(partialResponse || responseBuffer, 1200),
|
|
1143
|
+
turnBuffer: summarizeCliTraceText(scopedBuffer, 1600),
|
|
1144
|
+
turnRawPreview: summarizeCliTraceText(scopedRawBuffer, 1600),
|
|
1145
|
+
turnSanitizedRawPreview: summarizeCliTraceText(sanitizeTerminalText(scopedRawBuffer), 1600)
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
var init_provider_cli_parse = __esm({
|
|
1149
|
+
"src/cli-adapters/provider-cli-parse.ts"() {
|
|
1150
|
+
"use strict";
|
|
1151
|
+
init_provider_cli_shared();
|
|
1152
|
+
}
|
|
1153
|
+
});
|
|
1154
|
+
|
|
1155
|
+
// src/cli-adapters/provider-cli-config.ts
|
|
1156
|
+
function resolveCliAdapterConfig(provider) {
|
|
1157
|
+
const t = provider.timeouts || {};
|
|
1158
|
+
const rawKeys = provider.approvalKeys;
|
|
1159
|
+
return {
|
|
1160
|
+
timeouts: {
|
|
1161
|
+
ptyFlush: t.ptyFlush ?? 50,
|
|
1162
|
+
dialogAccept: t.dialogAccept ?? 300,
|
|
1163
|
+
approvalCooldown: t.approvalCooldown ?? 3e3,
|
|
1164
|
+
generatingIdle: t.generatingIdle ?? 6e3,
|
|
1165
|
+
idleFinish: t.idleFinish ?? 5e3,
|
|
1166
|
+
maxResponse: t.maxResponse ?? 3e5,
|
|
1167
|
+
shutdownGrace: t.shutdownGrace ?? 1e3,
|
|
1168
|
+
outputSettle: t.outputSettle ?? 300
|
|
1169
|
+
},
|
|
1170
|
+
approvalKeys: rawKeys && typeof rawKeys === "object" ? rawKeys : {},
|
|
1171
|
+
sendDelayMs: typeof provider.sendDelayMs === "number" ? Math.max(0, provider.sendDelayMs) : 0,
|
|
1172
|
+
sendKey: typeof provider.sendKey === "string" && provider.sendKey.length > 0 ? provider.sendKey : "\r",
|
|
1173
|
+
submitStrategy: provider.submitStrategy === "immediate" ? "immediate" : "wait_for_echo",
|
|
1174
|
+
providerResolutionMeta: {
|
|
1175
|
+
type: provider.type,
|
|
1176
|
+
name: provider.name,
|
|
1177
|
+
resolvedVersion: provider._resolvedVersion || null,
|
|
1178
|
+
resolvedOs: provider._resolvedOs || null,
|
|
1179
|
+
providerDir: provider._resolvedProviderDir || null,
|
|
1180
|
+
scriptDir: provider._resolvedScriptDir || null,
|
|
1181
|
+
scriptsPath: provider._resolvedScriptsPath || null,
|
|
1182
|
+
scriptsSource: provider._resolvedScriptsSource || null,
|
|
1183
|
+
versionWarning: provider._versionWarning || null
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
var init_provider_cli_config = __esm({
|
|
1188
|
+
"src/cli-adapters/provider-cli-config.ts"() {
|
|
1189
|
+
"use strict";
|
|
1190
|
+
}
|
|
1191
|
+
});
|
|
1192
|
+
|
|
1193
|
+
// src/cli-adapters/provider-cli-runtime.ts
|
|
1194
|
+
function resolveCliSpawnPlan(options) {
|
|
1195
|
+
const { provider, runtimeSettings, workingDir, extraArgs } = options;
|
|
1196
|
+
const { spawn: spawnConfig } = provider;
|
|
1197
|
+
const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
|
|
1198
|
+
const binaryPath = findBinary(configuredCommand);
|
|
1199
|
+
const isWin = os9.platform() === "win32";
|
|
1200
|
+
const allArgs = [...spawnConfig.args, ...extraArgs];
|
|
1201
|
+
let shellCmd;
|
|
1202
|
+
let shellArgs;
|
|
1203
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path10.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
1204
|
+
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
1205
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path10.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
1206
|
+
const useShell = isWin ? useShellWin : useShellUnix;
|
|
1207
|
+
if (useShell) {
|
|
1208
|
+
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
1209
|
+
if (isWin) {
|
|
1210
|
+
shellArgs = ["/c", binaryPath, ...allArgs];
|
|
1211
|
+
} else {
|
|
1212
|
+
const fullCmd = [binaryPath, ...allArgs].map(shSingleQuote).join(" ");
|
|
1213
|
+
shellArgs = ["-l", "-c", fullCmd];
|
|
1214
|
+
}
|
|
1215
|
+
} else {
|
|
1216
|
+
shellCmd = binaryPath;
|
|
1217
|
+
shellArgs = allArgs;
|
|
1218
|
+
}
|
|
1219
|
+
return {
|
|
1220
|
+
binaryPath,
|
|
1221
|
+
allArgs,
|
|
1222
|
+
shellCmd,
|
|
1223
|
+
shellArgs,
|
|
1224
|
+
isWin,
|
|
1225
|
+
useShell,
|
|
1226
|
+
ptyOptions: {
|
|
1227
|
+
cols: 80,
|
|
1228
|
+
rows: 24,
|
|
1229
|
+
cwd: workingDir,
|
|
1230
|
+
env: buildCliSpawnEnv(process.env, spawnConfig.env)
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
}
|
|
1234
|
+
function buildCliLoginShellRetry(plan) {
|
|
1235
|
+
const shellCmd = process.env.SHELL || "/bin/zsh";
|
|
1236
|
+
const fullCmd = [plan.binaryPath, ...plan.allArgs].map(shSingleQuote).join(" ");
|
|
1237
|
+
return {
|
|
1238
|
+
shellCmd,
|
|
1239
|
+
shellArgs: ["-l", "-c", fullCmd]
|
|
1240
|
+
};
|
|
1241
|
+
}
|
|
1242
|
+
function getCliSpawnErrorHint(message, shellCmd, isWin) {
|
|
1243
|
+
if (!isWin) return null;
|
|
1244
|
+
if (/error code 267|ERROR_DIRECTORY/i.test(message)) {
|
|
1245
|
+
return " (working directory does not exist or is not a directory)";
|
|
1246
|
+
}
|
|
1247
|
+
if (/error code 740|elevation/i.test(message)) {
|
|
1248
|
+
return " (requires administrator privileges)";
|
|
1249
|
+
}
|
|
1250
|
+
if (/error code 2|ENOENT|not found/i.test(message)) {
|
|
1251
|
+
return ` (executable not found: ${shellCmd})`;
|
|
1252
|
+
}
|
|
1253
|
+
return null;
|
|
1254
|
+
}
|
|
1255
|
+
function respondToCliTerminalQueries(options) {
|
|
1256
|
+
const { ptyProcess, pendingTail, data, terminalScreen } = options;
|
|
1257
|
+
if (!ptyProcess || !data) return pendingTail;
|
|
1258
|
+
const combined = pendingTail + data;
|
|
1259
|
+
const regex = /\x1b\[(\?)?6n/g;
|
|
1260
|
+
let match;
|
|
1261
|
+
while ((match = regex.exec(combined)) !== null) {
|
|
1262
|
+
const cursor = terminalScreen.getCursorPosition();
|
|
1263
|
+
const row = Math.max(1, (cursor.row | 0) + 1);
|
|
1264
|
+
const col = Math.max(1, (cursor.col | 0) + 1);
|
|
1265
|
+
const response = match[1] ? `\x1B[?${row};${col}R` : `\x1B[${row};${col}R`;
|
|
1266
|
+
ptyProcess.write(response);
|
|
1267
|
+
}
|
|
1268
|
+
const prefixes = ["\x1B[6n", "\x1B[?6n"];
|
|
1269
|
+
const maxLength = prefixes.reduce((n, value) => Math.max(n, value.length), 0) - 1;
|
|
1270
|
+
const start = Math.max(0, combined.length - maxLength);
|
|
1271
|
+
for (let i = start; i < combined.length; i++) {
|
|
1272
|
+
const suffix = combined.slice(i);
|
|
1273
|
+
if (prefixes.some((pattern) => suffix.length < pattern.length && pattern.startsWith(suffix))) {
|
|
1274
|
+
return suffix;
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
return "";
|
|
1278
|
+
}
|
|
1279
|
+
var os9, path10;
|
|
1280
|
+
var init_provider_cli_runtime = __esm({
|
|
1281
|
+
"src/cli-adapters/provider-cli-runtime.ts"() {
|
|
1282
|
+
"use strict";
|
|
1283
|
+
os9 = __toESM(require("os"));
|
|
1284
|
+
path10 = __toESM(require("path"));
|
|
1285
|
+
init_provider_cli_shared();
|
|
1286
|
+
}
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1289
|
+
// src/cli-adapters/provider-cli-adapter.ts
|
|
1290
|
+
var provider_cli_adapter_exports = {};
|
|
1291
|
+
__export(provider_cli_adapter_exports, {
|
|
1292
|
+
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
1293
|
+
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
1294
|
+
});
|
|
1295
|
+
var os10, ProviderCliAdapter;
|
|
1296
|
+
var init_provider_cli_adapter = __esm({
|
|
1297
|
+
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
1298
|
+
"use strict";
|
|
1299
|
+
os10 = __toESM(require("os"));
|
|
1037
1300
|
init_logger();
|
|
1038
1301
|
init_terminal_screen();
|
|
1039
1302
|
init_pty_transport();
|
|
1040
|
-
|
|
1041
|
-
|
|
1303
|
+
init_provider_cli_shared();
|
|
1304
|
+
init_provider_cli_parse();
|
|
1305
|
+
init_provider_cli_config();
|
|
1306
|
+
init_provider_cli_runtime();
|
|
1307
|
+
init_provider_cli_shared();
|
|
1042
1308
|
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
1043
1309
|
constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
|
|
1044
1310
|
this.extraArgs = extraArgs;
|
|
@@ -1046,36 +1312,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
1046
1312
|
this.transportFactory = transportFactory;
|
|
1047
1313
|
this.cliType = provider.type;
|
|
1048
1314
|
this.cliName = provider.name;
|
|
1049
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
1050
|
-
const
|
|
1051
|
-
this.timeouts =
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
maxResponse: t.maxResponse ?? 3e5,
|
|
1058
|
-
shutdownGrace: t.shutdownGrace ?? 1e3,
|
|
1059
|
-
outputSettle: t.outputSettle ?? 300
|
|
1060
|
-
};
|
|
1061
|
-
const rawKeys = provider.approvalKeys;
|
|
1062
|
-
this.approvalKeys = rawKeys && typeof rawKeys === "object" ? rawKeys : {};
|
|
1063
|
-
this.sendDelayMs = typeof provider.sendDelayMs === "number" ? Math.max(0, provider.sendDelayMs) : 0;
|
|
1064
|
-
this.sendKey = typeof provider.sendKey === "string" && provider.sendKey.length > 0 ? provider.sendKey : "\r";
|
|
1065
|
-
this.submitStrategy = provider.submitStrategy === "immediate" ? "immediate" : "wait_for_echo";
|
|
1066
|
-
this.providerResolutionMeta = {
|
|
1067
|
-
type: provider.type,
|
|
1068
|
-
name: provider.name,
|
|
1069
|
-
resolvedVersion: provider._resolvedVersion || null,
|
|
1070
|
-
resolvedOs: provider._resolvedOs || null,
|
|
1071
|
-
providerDir: provider._resolvedProviderDir || null,
|
|
1072
|
-
scriptDir: provider._resolvedScriptDir || null,
|
|
1073
|
-
scriptsPath: provider._resolvedScriptsPath || null,
|
|
1074
|
-
scriptsSource: provider._resolvedScriptsSource || null,
|
|
1075
|
-
versionWarning: provider._versionWarning || null
|
|
1076
|
-
};
|
|
1315
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os10.homedir()) : workingDir;
|
|
1316
|
+
const resolvedConfig = resolveCliAdapterConfig(provider);
|
|
1317
|
+
this.timeouts = resolvedConfig.timeouts;
|
|
1318
|
+
this.approvalKeys = resolvedConfig.approvalKeys;
|
|
1319
|
+
this.sendDelayMs = resolvedConfig.sendDelayMs;
|
|
1320
|
+
this.sendKey = resolvedConfig.sendKey;
|
|
1321
|
+
this.submitStrategy = resolvedConfig.submitStrategy;
|
|
1322
|
+
this.providerResolutionMeta = resolvedConfig.providerResolutionMeta;
|
|
1077
1323
|
this.cliScripts = provider.scripts || {};
|
|
1078
|
-
const scriptNames =
|
|
1324
|
+
const scriptNames = listCliScriptNames(this.cliScripts);
|
|
1079
1325
|
if (scriptNames.length > 0) {
|
|
1080
1326
|
LOG.info("CLI", `[${this.cliType}] CLI scripts: [${scriptNames.join(", ")}]`);
|
|
1081
1327
|
LOG.info(
|
|
@@ -1172,88 +1418,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
1172
1418
|
this.messages = [...this.committedMessages];
|
|
1173
1419
|
this.structuredMessages = [...this.committedMessages];
|
|
1174
1420
|
}
|
|
1175
|
-
hydrateParsedMessages(parsedMessages, scope) {
|
|
1176
|
-
const referenceMessages = [...this.committedMessages];
|
|
1177
|
-
const usedReferenceIndexes = /* @__PURE__ */ new Set();
|
|
1178
|
-
const now = Date.now();
|
|
1179
|
-
const findReferenceTimestamp = (role, content, parsedIndex) => {
|
|
1180
|
-
const normalizedContent = normalizeComparableMessageContent(content);
|
|
1181
|
-
if (!normalizedContent) return void 0;
|
|
1182
|
-
const sameIndex = referenceMessages[parsedIndex];
|
|
1183
|
-
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && normalizeComparableMessageContent(sameIndex.content) === normalizedContent && typeof sameIndex.timestamp === "number" && Number.isFinite(sameIndex.timestamp)) {
|
|
1184
|
-
usedReferenceIndexes.add(parsedIndex);
|
|
1185
|
-
return sameIndex.timestamp;
|
|
1186
|
-
}
|
|
1187
|
-
for (let i = 0; i < referenceMessages.length; i++) {
|
|
1188
|
-
if (usedReferenceIndexes.has(i)) continue;
|
|
1189
|
-
const candidate = referenceMessages[i];
|
|
1190
|
-
if (!candidate || candidate.role !== role) continue;
|
|
1191
|
-
const candidateContent = normalizeComparableMessageContent(candidate.content);
|
|
1192
|
-
if (!candidateContent) continue;
|
|
1193
|
-
const exactMatch = candidateContent === normalizedContent;
|
|
1194
|
-
const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
|
|
1195
|
-
if (!exactMatch && !fuzzyMatch) continue;
|
|
1196
|
-
if (typeof candidate.timestamp === "number" && Number.isFinite(candidate.timestamp)) {
|
|
1197
|
-
usedReferenceIndexes.add(i);
|
|
1198
|
-
return candidate.timestamp;
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
return void 0;
|
|
1202
|
-
};
|
|
1203
|
-
return parsedMessages.filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message, index) => {
|
|
1204
|
-
const role = message.role;
|
|
1205
|
-
const content = typeof message.content === "string" ? message.content : String(message.content || "");
|
|
1206
|
-
const parsedTimestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0;
|
|
1207
|
-
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(role, content, index);
|
|
1208
|
-
const fallbackTimestamp = role === "user" ? scope?.startedAt || now : this.lastOutputAt || scope?.startedAt || now;
|
|
1209
|
-
const timestamp = referenceTimestamp ?? fallbackTimestamp;
|
|
1210
|
-
return {
|
|
1211
|
-
...message,
|
|
1212
|
-
role,
|
|
1213
|
-
content,
|
|
1214
|
-
timestamp,
|
|
1215
|
-
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp
|
|
1216
|
-
};
|
|
1217
|
-
});
|
|
1218
|
-
}
|
|
1219
|
-
normalizeParsedMessages(parsedMessages, scope) {
|
|
1220
|
-
return this.hydrateParsedMessages(parsedMessages, scope).map((message) => ({
|
|
1221
|
-
role: message.role,
|
|
1222
|
-
content: message.content,
|
|
1223
|
-
timestamp: message.timestamp,
|
|
1224
|
-
receivedAt: message.receivedAt,
|
|
1225
|
-
kind: message.kind,
|
|
1226
|
-
id: message.id,
|
|
1227
|
-
index: message.index,
|
|
1228
|
-
meta: message.meta,
|
|
1229
|
-
senderName: message.senderName
|
|
1230
|
-
}));
|
|
1231
|
-
}
|
|
1232
|
-
sliceFromOffset(text, start) {
|
|
1233
|
-
if (!text) return "";
|
|
1234
|
-
if (!Number.isFinite(start) || start <= 0) return text;
|
|
1235
|
-
if (start >= text.length) return "";
|
|
1236
|
-
return text.slice(start);
|
|
1237
|
-
}
|
|
1238
|
-
buildParseInput(baseMessages, partialResponse, scope) {
|
|
1239
|
-
const buffer = scope ? this.sliceFromOffset(this.accumulatedBuffer, scope.bufferStart) || this.accumulatedBuffer : this.accumulatedBuffer;
|
|
1240
|
-
const rawBuffer = scope ? this.sliceFromOffset(this.accumulatedRawBuffer, scope.rawBufferStart) || this.accumulatedRawBuffer : this.accumulatedRawBuffer;
|
|
1241
|
-
const screenText = this.terminalScreen.getText();
|
|
1242
|
-
const recentBuffer = buffer.slice(-1e3) || this.recentOutputBuffer;
|
|
1243
|
-
return {
|
|
1244
|
-
buffer,
|
|
1245
|
-
rawBuffer,
|
|
1246
|
-
recentBuffer,
|
|
1247
|
-
screenText,
|
|
1248
|
-
screen: buildCliScreenSnapshot(screenText),
|
|
1249
|
-
bufferScreen: buildCliScreenSnapshot(buffer),
|
|
1250
|
-
recentScreen: buildCliScreenSnapshot(recentBuffer),
|
|
1251
|
-
messages: [...baseMessages],
|
|
1252
|
-
partialResponse,
|
|
1253
|
-
promptText: scope?.prompt || "",
|
|
1254
|
-
settings: { ...this.runtimeSettings }
|
|
1255
|
-
};
|
|
1256
|
-
}
|
|
1257
1421
|
setStatus(status, trigger) {
|
|
1258
1422
|
const prev = this.currentStatus;
|
|
1259
1423
|
if (prev === status) return;
|
|
@@ -1286,7 +1450,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
1286
1450
|
this.recordTrace("idle_candidate_armed", {
|
|
1287
1451
|
confirmMs: _ProviderCliAdapter.IDLE_FINISH_CONFIRM_MS,
|
|
1288
1452
|
candidate: this.idleFinishCandidate,
|
|
1289
|
-
...
|
|
1453
|
+
...buildCliTraceParseSnapshot({
|
|
1454
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
1455
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
1456
|
+
responseBuffer: this.responseBuffer,
|
|
1457
|
+
partialResponse: this.responseBuffer,
|
|
1458
|
+
scope: this.currentTurnScope
|
|
1459
|
+
})
|
|
1290
1460
|
});
|
|
1291
1461
|
if (this.settleTimer) clearTimeout(this.settleTimer);
|
|
1292
1462
|
this.settleTimer = setTimeout(() => {
|
|
@@ -1295,30 +1465,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
1295
1465
|
this.evaluateSettled();
|
|
1296
1466
|
}, _ProviderCliAdapter.IDLE_FINISH_CONFIRM_MS);
|
|
1297
1467
|
}
|
|
1298
|
-
summarizeTraceText(text, max = 800) {
|
|
1299
|
-
const value = sanitizeTerminalText(String(text || ""));
|
|
1300
|
-
if (value.length <= max) return value;
|
|
1301
|
-
return `\u2026${value.slice(-max)}`;
|
|
1302
|
-
}
|
|
1303
|
-
summarizeTraceMessages(messages, limit = 3) {
|
|
1304
|
-
return messages.slice(-limit).map((message) => ({
|
|
1305
|
-
role: message.role,
|
|
1306
|
-
content: this.summarizeTraceText(message.content, 240),
|
|
1307
|
-
timestamp: message.timestamp
|
|
1308
|
-
}));
|
|
1309
|
-
}
|
|
1310
|
-
buildTraceParseSnapshot(scope, partialResponse = "") {
|
|
1311
|
-
const scopedBuffer = scope ? this.sliceFromOffset(this.accumulatedBuffer, scope.bufferStart) || this.accumulatedBuffer : this.accumulatedBuffer;
|
|
1312
|
-
const scopedRawBuffer = scope ? this.sliceFromOffset(this.accumulatedRawBuffer, scope.rawBufferStart) || this.accumulatedRawBuffer : this.accumulatedRawBuffer;
|
|
1313
|
-
return {
|
|
1314
|
-
currentTurnScope: scope || null,
|
|
1315
|
-
responseBuffer: this.summarizeTraceText(this.responseBuffer, 1200),
|
|
1316
|
-
partialResponse: this.summarizeTraceText(partialResponse || this.responseBuffer, 1200),
|
|
1317
|
-
turnBuffer: this.summarizeTraceText(scopedBuffer, 1600),
|
|
1318
|
-
turnRawPreview: this.summarizeTraceText(scopedRawBuffer, 1600),
|
|
1319
|
-
turnSanitizedRawPreview: this.summarizeTraceText(sanitizeTerminalText(scopedRawBuffer), 1600)
|
|
1320
|
-
};
|
|
1321
|
-
}
|
|
1322
1468
|
recordTrace(type, payload = {}) {
|
|
1323
1469
|
const entry = {
|
|
1324
1470
|
id: ++this.traceSeq,
|
|
@@ -1354,7 +1500,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1354
1500
|
/** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
|
|
1355
1501
|
setCliScripts(scripts) {
|
|
1356
1502
|
this.cliScripts = scripts;
|
|
1357
|
-
const scriptNames =
|
|
1503
|
+
const scriptNames = listCliScriptNames(scripts);
|
|
1358
1504
|
LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
|
|
1359
1505
|
}
|
|
1360
1506
|
updateRuntimeSettings(settings) {
|
|
@@ -1386,72 +1532,42 @@ var init_provider_cli_adapter = __esm({
|
|
|
1386
1532
|
}
|
|
1387
1533
|
async spawn() {
|
|
1388
1534
|
if (this.ptyProcess) return;
|
|
1389
|
-
const
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1535
|
+
const spawnPlan = resolveCliSpawnPlan({
|
|
1536
|
+
provider: this.provider,
|
|
1537
|
+
runtimeSettings: this.runtimeSettings,
|
|
1538
|
+
workingDir: this.workingDir,
|
|
1539
|
+
extraArgs: this.extraArgs
|
|
1540
|
+
});
|
|
1394
1541
|
LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
1395
1542
|
this.resetTraceSession();
|
|
1396
|
-
let shellCmd;
|
|
1397
|
-
let shellArgs;
|
|
1398
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
1399
|
-
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
1400
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
1401
|
-
const useShell = isWin ? useShellWin : useShellUnix;
|
|
1402
|
-
if (useShell) {
|
|
1403
|
-
if (!spawnConfig.shell && !isWin) {
|
|
1404
|
-
LOG.info("CLI", `[${this.cliType}] Using login shell (script shim or non-native binary)`);
|
|
1405
|
-
}
|
|
1406
|
-
if (isCmdShim) {
|
|
1407
|
-
LOG.info("CLI", `[${this.cliType}] Using cmd.exe shell for .cmd/.bat shim: ${binaryPath}`);
|
|
1408
|
-
} else if (isWin) {
|
|
1409
|
-
LOG.info("CLI", `[${this.cliType}] Using cmd.exe shell on Windows: ${binaryPath}`);
|
|
1410
|
-
}
|
|
1411
|
-
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
1412
|
-
if (isWin) {
|
|
1413
|
-
shellArgs = ["/c", binaryPath, ...allArgs];
|
|
1414
|
-
} else {
|
|
1415
|
-
const fullCmd = [binaryPath, ...allArgs].map(shSingleQuote).join(" ");
|
|
1416
|
-
shellArgs = ["-l", "-c", fullCmd];
|
|
1417
|
-
}
|
|
1418
|
-
} else {
|
|
1419
|
-
if (isWin && spawnConfig.shell) {
|
|
1420
|
-
LOG.info("CLI", `[${this.cliType}] Spawning Windows binary directly without cmd.exe: ${binaryPath}`);
|
|
1421
|
-
}
|
|
1422
|
-
shellCmd = binaryPath;
|
|
1423
|
-
shellArgs = allArgs;
|
|
1424
|
-
}
|
|
1425
|
-
const ptyOpts = {
|
|
1426
|
-
cols: 80,
|
|
1427
|
-
rows: 24,
|
|
1428
|
-
cwd: this.workingDir,
|
|
1429
|
-
env: buildCliSpawnEnv(process.env, spawnConfig.env)
|
|
1430
|
-
};
|
|
1431
1543
|
this.recordTrace("spawn", {
|
|
1432
|
-
shellCommand: shellCmd,
|
|
1433
|
-
shellArgs,
|
|
1434
|
-
cwd:
|
|
1435
|
-
cols:
|
|
1436
|
-
rows:
|
|
1544
|
+
shellCommand: spawnPlan.shellCmd,
|
|
1545
|
+
shellArgs: spawnPlan.shellArgs,
|
|
1546
|
+
cwd: spawnPlan.ptyOptions.cwd,
|
|
1547
|
+
cols: spawnPlan.ptyOptions.cols,
|
|
1548
|
+
rows: spawnPlan.ptyOptions.rows,
|
|
1437
1549
|
providerResolution: this.providerResolutionMeta
|
|
1438
1550
|
});
|
|
1439
1551
|
try {
|
|
1440
|
-
this.ptyProcess = this.transportFactory.spawn(
|
|
1552
|
+
this.ptyProcess = this.transportFactory.spawn(
|
|
1553
|
+
spawnPlan.shellCmd,
|
|
1554
|
+
spawnPlan.shellArgs,
|
|
1555
|
+
spawnPlan.ptyOptions
|
|
1556
|
+
);
|
|
1441
1557
|
} catch (err) {
|
|
1442
1558
|
const msg = err?.message || String(err);
|
|
1443
|
-
if (!isWin && !useShell && /posix_spawn|spawn/i.test(msg)) {
|
|
1559
|
+
if (!spawnPlan.isWin && !spawnPlan.useShell && /posix_spawn|spawn/i.test(msg)) {
|
|
1444
1560
|
LOG.warn("CLI", `[${this.cliType}] Direct spawn failed (${msg}), retrying via login shell`);
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1561
|
+
const retryPlan = buildCliLoginShellRetry(spawnPlan);
|
|
1562
|
+
this.ptyProcess = this.transportFactory.spawn(
|
|
1563
|
+
retryPlan.shellCmd,
|
|
1564
|
+
retryPlan.shellArgs,
|
|
1565
|
+
spawnPlan.ptyOptions
|
|
1566
|
+
);
|
|
1449
1567
|
} else {
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
throw new Error(`Failed to spawn CLI${hint}: ${msg}`);
|
|
1454
|
-
}
|
|
1568
|
+
const hint = getCliSpawnErrorHint(msg, spawnPlan.shellCmd, spawnPlan.isWin);
|
|
1569
|
+
if (hint) {
|
|
1570
|
+
throw new Error(`Failed to spawn CLI${hint}: ${msg}`);
|
|
1455
1571
|
}
|
|
1456
1572
|
throw err;
|
|
1457
1573
|
}
|
|
@@ -1459,7 +1575,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
1459
1575
|
this.ptyProcess.onData((data) => {
|
|
1460
1576
|
if (Date.now() < this.resizeSuppressUntil) return;
|
|
1461
1577
|
if (!this.ptyProcess?.terminalQueriesHandled) {
|
|
1462
|
-
this.
|
|
1578
|
+
this.pendingTerminalQueryTail = respondToCliTerminalQueries({
|
|
1579
|
+
ptyProcess: this.ptyProcess,
|
|
1580
|
+
pendingTail: this.pendingTerminalQueryTail,
|
|
1581
|
+
data,
|
|
1582
|
+
terminalScreen: this.terminalScreen
|
|
1583
|
+
});
|
|
1463
1584
|
}
|
|
1464
1585
|
this.pendingOutputParseBuffer += data;
|
|
1465
1586
|
if (!this.pendingOutputParseTimer) {
|
|
@@ -1538,9 +1659,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
1538
1659
|
this.recordTrace("output", {
|
|
1539
1660
|
rawLength: rawData.length,
|
|
1540
1661
|
cleanLength: cleanData.length,
|
|
1541
|
-
rawPreview:
|
|
1542
|
-
cleanPreview:
|
|
1543
|
-
screenText:
|
|
1662
|
+
rawPreview: summarizeCliTraceText(rawData, 300),
|
|
1663
|
+
cleanPreview: summarizeCliTraceText(cleanData, 300),
|
|
1664
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 1200)
|
|
1544
1665
|
});
|
|
1545
1666
|
if (this.startupParseGate) {
|
|
1546
1667
|
this.scheduleStartupSettleCheck();
|
|
@@ -1771,7 +1892,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1771
1892
|
loggedWait = true;
|
|
1772
1893
|
LOG.info(
|
|
1773
1894
|
"CLI",
|
|
1774
|
-
`[${this.cliType}] Waiting for interactive prompt: hasPrompt=${hasPrompt} stableMs=${stableMs} recentOutputMs=${recentlyOutput} status=${status} startup=${startupLikelyActive} screen=${JSON.stringify(
|
|
1895
|
+
`[${this.cliType}] Waiting for interactive prompt: hasPrompt=${hasPrompt} stableMs=${stableMs} recentOutputMs=${recentlyOutput} status=${status} startup=${startupLikelyActive} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)}`
|
|
1775
1896
|
);
|
|
1776
1897
|
}
|
|
1777
1898
|
await new Promise((resolve12) => setTimeout(resolve12, 50));
|
|
@@ -1779,7 +1900,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1779
1900
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
1780
1901
|
LOG.warn(
|
|
1781
1902
|
"CLI",
|
|
1782
|
-
`[${this.cliType}] Interactive prompt wait timed out after ${maxWaitMs}ms; proceeding with screen=${JSON.stringify(
|
|
1903
|
+
`[${this.cliType}] Interactive prompt wait timed out after ${maxWaitMs}ms; proceeding with screen=${JSON.stringify(summarizeCliTraceText(finalScreenText, 240)).slice(0, 280)}`
|
|
1783
1904
|
);
|
|
1784
1905
|
}
|
|
1785
1906
|
evaluateSettled() {
|
|
@@ -1809,23 +1930,33 @@ var init_provider_cli_adapter = __esm({
|
|
|
1809
1930
|
this.responseBuffer,
|
|
1810
1931
|
this.currentTurnScope
|
|
1811
1932
|
);
|
|
1812
|
-
const parsedMessages = Array.isArray(parsedTranscript?.messages) ?
|
|
1933
|
+
const parsedMessages = Array.isArray(parsedTranscript?.messages) ? normalizeCliParsedMessages(parsedTranscript.messages, {
|
|
1934
|
+
committedMessages: this.committedMessages,
|
|
1935
|
+
scope: this.currentTurnScope,
|
|
1936
|
+
lastOutputAt: this.lastOutputAt
|
|
1937
|
+
}) : [];
|
|
1813
1938
|
const lastParsedAssistant = [...parsedMessages].reverse().find((message) => message.role === "assistant");
|
|
1814
1939
|
this.recordTrace("settled", {
|
|
1815
|
-
tail:
|
|
1816
|
-
screenText:
|
|
1940
|
+
tail: summarizeCliTraceText(tail, 500),
|
|
1941
|
+
screenText: summarizeCliTraceText(screenText, 1200),
|
|
1817
1942
|
detectStatus: scriptStatus,
|
|
1818
1943
|
parsedStatus: parsedTranscript?.status || null,
|
|
1819
1944
|
parsedMessageCount: parsedMessages.length,
|
|
1820
|
-
parsedLastAssistant: lastParsedAssistant ?
|
|
1945
|
+
parsedLastAssistant: lastParsedAssistant ? summarizeCliTraceText(lastParsedAssistant.content, 280) : "",
|
|
1821
1946
|
parsedActiveModal: parsedTranscript?.activeModal ?? null,
|
|
1822
1947
|
approval: modal,
|
|
1823
|
-
...
|
|
1948
|
+
...buildCliTraceParseSnapshot({
|
|
1949
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
1950
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
1951
|
+
responseBuffer: this.responseBuffer,
|
|
1952
|
+
partialResponse: this.responseBuffer,
|
|
1953
|
+
scope: this.currentTurnScope
|
|
1954
|
+
})
|
|
1824
1955
|
});
|
|
1825
1956
|
if (this.currentTurnScope && !lastParsedAssistant) {
|
|
1826
1957
|
LOG.info(
|
|
1827
1958
|
"CLI",
|
|
1828
|
-
`[${this.cliType}] Settled without assistant: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(
|
|
1959
|
+
`[${this.cliType}] Settled without assistant: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(summarizeCliTraceText(this.responseBuffer, 220)).slice(0, 260)} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)} providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"}`
|
|
1829
1960
|
);
|
|
1830
1961
|
}
|
|
1831
1962
|
if (!scriptStatus) return;
|
|
@@ -1879,7 +2010,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
1879
2010
|
lastNonEmptyOutputAt: this.lastNonEmptyOutputAt,
|
|
1880
2011
|
lastScreenChangeAt: this.lastScreenChangeAt,
|
|
1881
2012
|
holdMs: _ProviderCliAdapter.STATUS_ACTIVITY_HOLD_MS,
|
|
1882
|
-
...
|
|
2013
|
+
...buildCliTraceParseSnapshot({
|
|
2014
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2015
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2016
|
+
responseBuffer: this.responseBuffer,
|
|
2017
|
+
partialResponse: this.responseBuffer,
|
|
2018
|
+
scope: this.currentTurnScope
|
|
2019
|
+
})
|
|
1883
2020
|
});
|
|
1884
2021
|
this.onStatusChange?.();
|
|
1885
2022
|
return;
|
|
@@ -1983,7 +2120,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
1983
2120
|
canFinishImmediately,
|
|
1984
2121
|
submitPendingUntil: this.submitPendingUntil,
|
|
1985
2122
|
responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
|
|
1986
|
-
...
|
|
2123
|
+
...buildCliTraceParseSnapshot({
|
|
2124
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2125
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2126
|
+
responseBuffer: this.responseBuffer,
|
|
2127
|
+
partialResponse: this.responseBuffer,
|
|
2128
|
+
scope: this.currentTurnScope
|
|
2129
|
+
})
|
|
1987
2130
|
});
|
|
1988
2131
|
if (canFinishImmediately) {
|
|
1989
2132
|
this.clearIdleFinishCandidate("finish_response");
|
|
@@ -2018,7 +2161,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
2018
2161
|
if (this.responseSettleIgnoreUntil > Date.now()) return;
|
|
2019
2162
|
this.clearIdleFinishCandidate("finish_response_enter");
|
|
2020
2163
|
this.recordTrace("finish_response", {
|
|
2021
|
-
...
|
|
2164
|
+
...buildCliTraceParseSnapshot({
|
|
2165
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2166
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2167
|
+
responseBuffer: this.responseBuffer,
|
|
2168
|
+
partialResponse: this.responseBuffer,
|
|
2169
|
+
scope: this.currentTurnScope
|
|
2170
|
+
})
|
|
2022
2171
|
});
|
|
2023
2172
|
const commitResult = this.commitCurrentTranscript();
|
|
2024
2173
|
if (this.shouldRetryFinishResponse(commitResult)) {
|
|
@@ -2026,8 +2175,14 @@ var init_provider_cli_adapter = __esm({
|
|
|
2026
2175
|
this.recordTrace("finish_response_retry", {
|
|
2027
2176
|
retryCount: this.finishRetryCount,
|
|
2028
2177
|
retryDelayMs: _ProviderCliAdapter.FINISH_RETRY_DELAY_MS,
|
|
2029
|
-
assistantContent:
|
|
2030
|
-
...
|
|
2178
|
+
assistantContent: summarizeCliTraceText(commitResult.assistantContent, 220),
|
|
2179
|
+
...buildCliTraceParseSnapshot({
|
|
2180
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2181
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2182
|
+
responseBuffer: this.responseBuffer,
|
|
2183
|
+
partialResponse: this.responseBuffer,
|
|
2184
|
+
scope: this.currentTurnScope
|
|
2185
|
+
})
|
|
2031
2186
|
});
|
|
2032
2187
|
if (this.finishRetryTimer) clearTimeout(this.finishRetryTimer);
|
|
2033
2188
|
this.finishRetryTimer = setTimeout(() => {
|
|
@@ -2076,7 +2231,11 @@ var init_provider_cli_adapter = __esm({
|
|
|
2076
2231
|
this.currentTurnScope
|
|
2077
2232
|
);
|
|
2078
2233
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
2079
|
-
this.committedMessages =
|
|
2234
|
+
this.committedMessages = normalizeCliParsedMessages(parsed.messages, {
|
|
2235
|
+
committedMessages: this.committedMessages,
|
|
2236
|
+
scope: this.currentTurnScope,
|
|
2237
|
+
lastOutputAt: this.lastOutputAt
|
|
2238
|
+
});
|
|
2080
2239
|
const promptForTrim = this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages);
|
|
2081
2240
|
if (promptForTrim) {
|
|
2082
2241
|
const lastAssistantForTrim = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
|
|
@@ -2089,14 +2248,20 @@ var init_provider_cli_adapter = __esm({
|
|
|
2089
2248
|
this.recordTrace("commit_transcript", {
|
|
2090
2249
|
parsedStatus: parsed.status || null,
|
|
2091
2250
|
messageCount: this.committedMessages.length,
|
|
2092
|
-
lastAssistant: lastAssistant ?
|
|
2093
|
-
messages:
|
|
2094
|
-
...
|
|
2251
|
+
lastAssistant: lastAssistant ? summarizeCliTraceText(lastAssistant.content, 320) : "",
|
|
2252
|
+
messages: summarizeCliTraceMessages(this.committedMessages),
|
|
2253
|
+
...buildCliTraceParseSnapshot({
|
|
2254
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2255
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2256
|
+
responseBuffer: this.responseBuffer,
|
|
2257
|
+
partialResponse: this.responseBuffer,
|
|
2258
|
+
scope: this.currentTurnScope
|
|
2259
|
+
})
|
|
2095
2260
|
});
|
|
2096
2261
|
if (!lastAssistant && this.currentTurnScope) {
|
|
2097
2262
|
LOG.warn(
|
|
2098
2263
|
"CLI",
|
|
2099
|
-
`[${this.cliType}] Commit without assistant turn: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(
|
|
2264
|
+
`[${this.cliType}] Commit without assistant turn: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(summarizeCliTraceText(this.responseBuffer, 220)).slice(0, 260)} providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"} scriptsPath=${this.providerResolutionMeta.scriptsPath || "-"}`
|
|
2100
2265
|
);
|
|
2101
2266
|
}
|
|
2102
2267
|
return {
|
|
@@ -2188,7 +2353,11 @@ var init_provider_cli_adapter = __esm({
|
|
|
2188
2353
|
index: typeof message.index === "number" ? message.index : index,
|
|
2189
2354
|
kind: message.kind || "standard",
|
|
2190
2355
|
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
2191
|
-
})) :
|
|
2356
|
+
})) : hydrateCliParsedMessages(parsed.messages, {
|
|
2357
|
+
committedMessages: this.committedMessages,
|
|
2358
|
+
scope: this.currentTurnScope,
|
|
2359
|
+
lastOutputAt: this.lastOutputAt
|
|
2360
|
+
});
|
|
2192
2361
|
return {
|
|
2193
2362
|
id: parsed.id || "cli_session",
|
|
2194
2363
|
status: parsed.status || this.currentStatus,
|
|
@@ -2219,11 +2388,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
2219
2388
|
if (typeof fn !== "function") {
|
|
2220
2389
|
throw new Error(`CLI script '${scriptName}' not available`);
|
|
2221
2390
|
}
|
|
2222
|
-
const input =
|
|
2223
|
-
this.
|
|
2224
|
-
this.
|
|
2225
|
-
this.
|
|
2226
|
-
|
|
2391
|
+
const input = buildCliParseInput({
|
|
2392
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2393
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2394
|
+
recentOutputBuffer: this.recentOutputBuffer,
|
|
2395
|
+
terminalScreenText: this.terminalScreen.getText(),
|
|
2396
|
+
baseMessages: this.committedMessages,
|
|
2397
|
+
partialResponse: this.responseBuffer,
|
|
2398
|
+
scope: this.currentTurnScope,
|
|
2399
|
+
runtimeSettings: this.runtimeSettings
|
|
2400
|
+
});
|
|
2227
2401
|
return await Promise.resolve(fn({
|
|
2228
2402
|
...input,
|
|
2229
2403
|
args: args && typeof args === "object" ? { ...args } : {}
|
|
@@ -2232,7 +2406,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
2232
2406
|
parseCurrentTranscript(baseMessages, partialResponse, scope) {
|
|
2233
2407
|
if (!this.cliScripts?.parseOutput) return null;
|
|
2234
2408
|
try {
|
|
2235
|
-
const input =
|
|
2409
|
+
const input = buildCliParseInput({
|
|
2410
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2411
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2412
|
+
recentOutputBuffer: this.recentOutputBuffer,
|
|
2413
|
+
terminalScreenText: this.terminalScreen.getText(),
|
|
2414
|
+
baseMessages,
|
|
2415
|
+
partialResponse,
|
|
2416
|
+
scope,
|
|
2417
|
+
runtimeSettings: this.runtimeSettings
|
|
2418
|
+
});
|
|
2236
2419
|
const parsed = this.cliScripts.parseOutput(input);
|
|
2237
2420
|
const refinedStatus = this.refineDetectedStatus(typeof parsed?.status === "string" ? parsed.status : null, input.recentBuffer, input.screenText);
|
|
2238
2421
|
if (parsed && refinedStatus && parsed.status !== refinedStatus) {
|
|
@@ -2322,7 +2505,7 @@ ${data.message || ""}`.trim();
|
|
|
2322
2505
|
rawBufferStart: this.accumulatedRawBuffer.length
|
|
2323
2506
|
};
|
|
2324
2507
|
this.recordTrace("send_message", {
|
|
2325
|
-
text:
|
|
2508
|
+
text: summarizeCliTraceText(text, 500),
|
|
2326
2509
|
estimatedLines: estimatePromptDisplayLines(text),
|
|
2327
2510
|
turnScope: this.currentTurnScope
|
|
2328
2511
|
});
|
|
@@ -2356,7 +2539,7 @@ ${data.message || ""}`.trim();
|
|
|
2356
2539
|
this.recordTrace("submit_write", {
|
|
2357
2540
|
mode: "submit_key",
|
|
2358
2541
|
sendKey: this.sendKey,
|
|
2359
|
-
screenText:
|
|
2542
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
|
|
2360
2543
|
});
|
|
2361
2544
|
this.ptyProcess.write(this.sendKey);
|
|
2362
2545
|
const retrySubmitIfStuck = (attempt) => {
|
|
@@ -2373,7 +2556,7 @@ ${data.message || ""}`.trim();
|
|
|
2373
2556
|
mode: "submit_retry",
|
|
2374
2557
|
attempt,
|
|
2375
2558
|
sendKey: this.sendKey,
|
|
2376
|
-
screenText:
|
|
2559
|
+
screenText: summarizeCliTraceText(screenText, 500)
|
|
2377
2560
|
});
|
|
2378
2561
|
this.ptyProcess.write(this.sendKey);
|
|
2379
2562
|
if (attempt >= 3) {
|
|
@@ -2389,9 +2572,9 @@ ${data.message || ""}`.trim();
|
|
|
2389
2572
|
this.submitPendingUntil = 0;
|
|
2390
2573
|
this.recordTrace("submit_write", {
|
|
2391
2574
|
mode: "immediate",
|
|
2392
|
-
text:
|
|
2575
|
+
text: summarizeCliTraceText(text, 500),
|
|
2393
2576
|
sendKey: this.sendKey,
|
|
2394
|
-
screenText:
|
|
2577
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
|
|
2395
2578
|
});
|
|
2396
2579
|
this.ptyProcess.write(text + this.sendKey);
|
|
2397
2580
|
this.submitRetryTimer = setTimeout(() => {
|
|
@@ -2407,7 +2590,7 @@ ${data.message || ""}`.trim();
|
|
|
2407
2590
|
mode: "immediate_retry",
|
|
2408
2591
|
attempt: 1,
|
|
2409
2592
|
sendKey: this.sendKey,
|
|
2410
|
-
screenText:
|
|
2593
|
+
screenText: summarizeCliTraceText(screenText, 500)
|
|
2411
2594
|
});
|
|
2412
2595
|
this.ptyProcess.write(this.sendKey);
|
|
2413
2596
|
this.submitRetryUsed = true;
|
|
@@ -2421,9 +2604,9 @@ ${data.message || ""}`.trim();
|
|
|
2421
2604
|
this.ptyProcess.write(text);
|
|
2422
2605
|
this.recordTrace("submit_write", {
|
|
2423
2606
|
mode: "type_then_submit",
|
|
2424
|
-
text:
|
|
2607
|
+
text: summarizeCliTraceText(text, 500),
|
|
2425
2608
|
sendKey: this.sendKey,
|
|
2426
|
-
screenText:
|
|
2609
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
|
|
2427
2610
|
});
|
|
2428
2611
|
const submitStartedAt = Date.now();
|
|
2429
2612
|
let lastNormalizedScreen = "";
|
|
@@ -2758,7 +2941,7 @@ ${data.message || ""}`.trim();
|
|
|
2758
2941
|
responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
|
|
2759
2942
|
resizeSuppressUntil: this.resizeSuppressUntil,
|
|
2760
2943
|
hasCliScripts: this.hasCliScripts(),
|
|
2761
|
-
scriptNames:
|
|
2944
|
+
scriptNames: listCliScriptNames(this.cliScripts),
|
|
2762
2945
|
traceSessionId: this.traceSessionId,
|
|
2763
2946
|
traceEntryCount: this.traceEntries.length,
|
|
2764
2947
|
statusHistory: this.statusHistory.slice(-30),
|
|
@@ -2775,32 +2958,18 @@ ${data.message || ""}`.trim();
|
|
|
2775
2958
|
providerResolution: this.providerResolutionMeta,
|
|
2776
2959
|
entryCount: this.traceEntries.length,
|
|
2777
2960
|
entries: this.traceEntries.slice(-cappedLimit),
|
|
2778
|
-
screenText:
|
|
2779
|
-
recentOutputBuffer:
|
|
2780
|
-
responseBuffer:
|
|
2961
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 4e3),
|
|
2962
|
+
recentOutputBuffer: summarizeCliTraceText(this.recentOutputBuffer, 1e3),
|
|
2963
|
+
responseBuffer: summarizeCliTraceText(this.responseBuffer, 1200),
|
|
2781
2964
|
status: this.currentStatus,
|
|
2782
2965
|
activeModal: this.activeModal,
|
|
2783
2966
|
currentTurnScope: this.currentTurnScope,
|
|
2784
|
-
messages:
|
|
2967
|
+
messages: summarizeCliTraceMessages(this.committedMessages, 5)
|
|
2785
2968
|
};
|
|
2786
2969
|
}
|
|
2787
2970
|
getProviderResolutionMeta() {
|
|
2788
2971
|
return { ...this.providerResolutionMeta };
|
|
2789
2972
|
}
|
|
2790
|
-
respondToTerminalQueries(data) {
|
|
2791
|
-
if (!this.ptyProcess || !data) return;
|
|
2792
|
-
const combined = this.pendingTerminalQueryTail + data;
|
|
2793
|
-
const regex = /\x1b\[(\?)?6n/g;
|
|
2794
|
-
let match;
|
|
2795
|
-
while ((match = regex.exec(combined)) !== null) {
|
|
2796
|
-
const cursor = this.terminalScreen.getCursorPosition();
|
|
2797
|
-
const row = Math.max(1, (cursor.row | 0) + 1);
|
|
2798
|
-
const col = Math.max(1, (cursor.col | 0) + 1);
|
|
2799
|
-
const response = match[1] ? `\x1B[?${row};${col}R` : `\x1B[${row};${col}R`;
|
|
2800
|
-
this.ptyProcess.write(response);
|
|
2801
|
-
}
|
|
2802
|
-
this.pendingTerminalQueryTail = computeTerminalQueryTail(combined);
|
|
2803
|
-
}
|
|
2804
2973
|
};
|
|
2805
2974
|
}
|
|
2806
2975
|
});
|
|
@@ -3280,17 +3449,17 @@ function checkPathExists(paths) {
|
|
|
3280
3449
|
return null;
|
|
3281
3450
|
}
|
|
3282
3451
|
async function detectIDEs(providerLoader) {
|
|
3283
|
-
const
|
|
3452
|
+
const os20 = (0, import_os2.platform)();
|
|
3284
3453
|
const results = [];
|
|
3285
3454
|
for (const def of getMergedDefinitions()) {
|
|
3286
3455
|
const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
|
|
3287
|
-
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[
|
|
3456
|
+
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os20] || []) || []);
|
|
3288
3457
|
let resolvedCli = cliPath;
|
|
3289
|
-
if (!resolvedCli && appPath &&
|
|
3458
|
+
if (!resolvedCli && appPath && os20 === "darwin") {
|
|
3290
3459
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
3291
3460
|
if ((0, import_fs3.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
3292
3461
|
}
|
|
3293
|
-
if (!resolvedCli && appPath &&
|
|
3462
|
+
if (!resolvedCli && appPath && os20 === "win32") {
|
|
3294
3463
|
const { dirname: dirname6 } = await import("path");
|
|
3295
3464
|
const appDir = dirname6(appPath);
|
|
3296
3465
|
const candidates = [
|
|
@@ -3307,7 +3476,7 @@ async function detectIDEs(providerLoader) {
|
|
|
3307
3476
|
}
|
|
3308
3477
|
}
|
|
3309
3478
|
}
|
|
3310
|
-
const installed =
|
|
3479
|
+
const installed = os20 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
3311
3480
|
const version = resolvedCli ? getIdeVersion(resolvedCli) : null;
|
|
3312
3481
|
results.push({
|
|
3313
3482
|
id: def.id,
|
|
@@ -3368,8 +3537,8 @@ function execAsync(cmd, timeoutMs = 5e3) {
|
|
|
3368
3537
|
});
|
|
3369
3538
|
}
|
|
3370
3539
|
async function detectCLIs(providerLoader, options) {
|
|
3371
|
-
const
|
|
3372
|
-
const whichCmd =
|
|
3540
|
+
const platform10 = os2.platform();
|
|
3541
|
+
const whichCmd = platform10 === "win32" ? "where" : "which";
|
|
3373
3542
|
const includeVersion = options?.includeVersion !== false;
|
|
3374
3543
|
const cliList = providerLoader ? providerLoader.getCliDetectionList() : [];
|
|
3375
3544
|
const results = await Promise.all(
|
|
@@ -3412,8 +3581,8 @@ async function detectCLI(cliId, providerLoader, options) {
|
|
|
3412
3581
|
const cliList = providerLoader.getCliDetectionList();
|
|
3413
3582
|
const target = cliList.find((c) => c.id === resolvedId);
|
|
3414
3583
|
if (target) {
|
|
3415
|
-
const
|
|
3416
|
-
const whichCmd =
|
|
3584
|
+
const platform10 = os2.platform();
|
|
3585
|
+
const whichCmd = platform10 === "win32" ? "where" : "which";
|
|
3417
3586
|
try {
|
|
3418
3587
|
const explicitPath = resolveCommandPath(target.command);
|
|
3419
3588
|
const pathResult = explicitPath || await execAsync(`${whichCmd} ${shellQuote(target.command)}`);
|
|
@@ -3534,6 +3703,10 @@ var DaemonCdpManager = class {
|
|
|
3534
3703
|
setTargetFilter(filter) {
|
|
3535
3704
|
this._targetFilter = filter;
|
|
3536
3705
|
}
|
|
3706
|
+
/** Clear a previously pinned target so the next connect can reselect a page. */
|
|
3707
|
+
clearTargetId() {
|
|
3708
|
+
this._targetId = null;
|
|
3709
|
+
}
|
|
3537
3710
|
/**
|
|
3538
3711
|
* Check if a page title should be excluded (non-main page).
|
|
3539
3712
|
* Uses provider-configured titleExcludes, falls back to default pattern.
|
|
@@ -6077,7 +6250,8 @@ var IdeProviderInstance = class {
|
|
|
6077
6250
|
}
|
|
6078
6251
|
}
|
|
6079
6252
|
if (!raw || typeof raw !== "object") return;
|
|
6080
|
-
|
|
6253
|
+
const chat = raw;
|
|
6254
|
+
let { activeModal } = chat;
|
|
6081
6255
|
if (activeModal) {
|
|
6082
6256
|
const w = activeModal.width ?? Infinity;
|
|
6083
6257
|
const h = activeModal.height ?? Infinity;
|
|
@@ -6097,26 +6271,28 @@ var IdeProviderInstance = class {
|
|
|
6097
6271
|
if (pm.receivedAt) prevByHash.set(h, pm.receivedAt);
|
|
6098
6272
|
}
|
|
6099
6273
|
const now = Date.now();
|
|
6100
|
-
|
|
6274
|
+
const messages = chat.messages || [];
|
|
6275
|
+
for (const msg of messages) {
|
|
6101
6276
|
const h = `${msg.role}:${(msg.content || "").slice(0, 100)}`;
|
|
6102
6277
|
msg.receivedAt = prevByHash.get(h) || now;
|
|
6103
6278
|
}
|
|
6104
|
-
if (
|
|
6279
|
+
if (messages.length > 0) {
|
|
6105
6280
|
const hiddenKinds = /* @__PURE__ */ new Set();
|
|
6106
6281
|
if (this.settings.showThinking === false) hiddenKinds.add("thought");
|
|
6107
6282
|
if (this.settings.showToolCalls === false) hiddenKinds.add("tool");
|
|
6108
6283
|
if (this.settings.showTerminal === false) hiddenKinds.add("terminal");
|
|
6109
6284
|
if (hiddenKinds.size > 0) {
|
|
6110
|
-
|
|
6285
|
+
chat.messages = messages.filter((m) => !hiddenKinds.has(m.kind || ""));
|
|
6111
6286
|
}
|
|
6112
6287
|
}
|
|
6113
|
-
const controlValues = extractProviderControlValues(this.provider.controls,
|
|
6114
|
-
if (controlValues)
|
|
6115
|
-
this.cachedChat = { ...
|
|
6116
|
-
this.detectAgentTransitions(
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6288
|
+
const controlValues = extractProviderControlValues(this.provider.controls, chat);
|
|
6289
|
+
if (controlValues) chat.controlValues = controlValues;
|
|
6290
|
+
this.cachedChat = { ...chat, activeModal };
|
|
6291
|
+
this.detectAgentTransitions(chat, now);
|
|
6292
|
+
const persistedMessages = chat.messages || messages;
|
|
6293
|
+
if (persistedMessages.length > 0) {
|
|
6294
|
+
let toSave = persistedMessages;
|
|
6295
|
+
if (chat.status === "generating" || chat.status === "long_generating") {
|
|
6120
6296
|
const lastIdx = toSave.length - 1;
|
|
6121
6297
|
if (lastIdx >= 0 && toSave[lastIdx].role === "assistant") {
|
|
6122
6298
|
toSave = toSave.slice(0, lastIdx);
|
|
@@ -6126,7 +6302,7 @@ var IdeProviderInstance = class {
|
|
|
6126
6302
|
this.historyWriter.appendNewMessages(
|
|
6127
6303
|
this.type,
|
|
6128
6304
|
toSave,
|
|
6129
|
-
|
|
6305
|
+
chat.title,
|
|
6130
6306
|
this.instanceId
|
|
6131
6307
|
);
|
|
6132
6308
|
}
|
|
@@ -6142,7 +6318,7 @@ var IdeProviderInstance = class {
|
|
|
6142
6318
|
getReadChatScript() {
|
|
6143
6319
|
const scripts = this.provider.scripts;
|
|
6144
6320
|
if (!scripts?.readChat) return null;
|
|
6145
|
-
return
|
|
6321
|
+
return scripts.readChat({});
|
|
6146
6322
|
}
|
|
6147
6323
|
// ─── status transition detect ─────────────────────────────
|
|
6148
6324
|
detectAgentTransitions(chatData, now) {
|
|
@@ -7213,7 +7389,7 @@ function getTargetInstance(h, args) {
|
|
|
7213
7389
|
const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
|
|
7214
7390
|
const sessionId = targetSessionId || h.currentSession?.sessionId || "";
|
|
7215
7391
|
if (!sessionId) return null;
|
|
7216
|
-
return h.ctx.instanceManager?.getInstance(sessionId);
|
|
7392
|
+
return h.ctx.instanceManager?.getInstance(sessionId) || null;
|
|
7217
7393
|
}
|
|
7218
7394
|
function getTargetTransport(h, provider) {
|
|
7219
7395
|
if (h.currentSession?.transport) return h.currentSession.transport;
|
|
@@ -7251,6 +7427,10 @@ function getHistorySessionId(h, args) {
|
|
|
7251
7427
|
const providerSessionId = typeof state?.providerSessionId === "string" ? state.providerSessionId.trim() : "";
|
|
7252
7428
|
return providerSessionId || targetSessionId;
|
|
7253
7429
|
}
|
|
7430
|
+
function callLegacyTextScript(script, text) {
|
|
7431
|
+
if (typeof script !== "function") return null;
|
|
7432
|
+
return script(text);
|
|
7433
|
+
}
|
|
7254
7434
|
function isRecentDuplicateSend(key) {
|
|
7255
7435
|
const now = Date.now();
|
|
7256
7436
|
for (const [candidate, ts2] of recentSendByTarget.entries()) {
|
|
@@ -7340,7 +7520,7 @@ async function handleReadChat(h, args) {
|
|
|
7340
7520
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7341
7521
|
if (adapter) {
|
|
7342
7522
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
7343
|
-
const status = adapter.getStatus
|
|
7523
|
+
const status = adapter.getStatus();
|
|
7344
7524
|
if (status) {
|
|
7345
7525
|
return {
|
|
7346
7526
|
success: true,
|
|
@@ -7580,7 +7760,7 @@ async function handleSendChat(h, args) {
|
|
|
7580
7760
|
}
|
|
7581
7761
|
if (parsed?.needsTypeAndSend && provider?.webviewMatchText && provider?.scripts?.webviewSendMessage) {
|
|
7582
7762
|
try {
|
|
7583
|
-
const webviewScript = provider.scripts.webviewSendMessage
|
|
7763
|
+
const webviewScript = callLegacyTextScript(provider.scripts.webviewSendMessage, text);
|
|
7584
7764
|
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
7585
7765
|
const matchText = provider.webviewMatchText;
|
|
7586
7766
|
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
@@ -7603,7 +7783,7 @@ async function handleSendChat(h, args) {
|
|
|
7603
7783
|
}
|
|
7604
7784
|
if (provider?.webviewMatchText && provider?.scripts?.webviewSendMessage) {
|
|
7605
7785
|
try {
|
|
7606
|
-
const webviewScript = provider.scripts.webviewSendMessage
|
|
7786
|
+
const webviewScript = callLegacyTextScript(provider.scripts.webviewSendMessage, text);
|
|
7607
7787
|
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
7608
7788
|
const matchText = provider.webviewMatchText;
|
|
7609
7789
|
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
@@ -7835,12 +8015,10 @@ async function handleSetMode(h, args) {
|
|
|
7835
8015
|
const mode = args?.mode || "agent";
|
|
7836
8016
|
if (transport === "acp") {
|
|
7837
8017
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
return { success: true, mode };
|
|
7843
|
-
}
|
|
8018
|
+
const acpInstance = adapter?._acpInstance;
|
|
8019
|
+
if (acpInstance && typeof acpInstance.setMode === "function") {
|
|
8020
|
+
await acpInstance.setMode(mode);
|
|
8021
|
+
return { success: true, mode };
|
|
7844
8022
|
}
|
|
7845
8023
|
return { success: false, error: "ACP adapter not found" };
|
|
7846
8024
|
}
|
|
@@ -7893,13 +8071,11 @@ async function handleChangeModel(h, args) {
|
|
|
7893
8071
|
if (transport === "acp") {
|
|
7894
8072
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7895
8073
|
LOG.info("Command", `[change_model] ACP adapter found: ${!!adapter}, type=${adapter?.cliType}, hasAcpInstance=${!!adapter?._acpInstance}`);
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
return { success: true, model };
|
|
7902
|
-
}
|
|
8074
|
+
const acpInstance = adapter?._acpInstance;
|
|
8075
|
+
if (acpInstance && typeof acpInstance.setConfigOption === "function") {
|
|
8076
|
+
await acpInstance.setConfigOption("model", model);
|
|
8077
|
+
LOG.info("Command", `[change_model] Updated ACP model to ${model}`);
|
|
8078
|
+
return { success: true, model };
|
|
7903
8079
|
}
|
|
7904
8080
|
return { success: false, error: "ACP adapter not found" };
|
|
7905
8081
|
}
|
|
@@ -7956,6 +8132,9 @@ async function handleSetThoughtLevel(h, args) {
|
|
|
7956
8132
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7957
8133
|
const acpInstance = adapter?._acpInstance;
|
|
7958
8134
|
if (!acpInstance) return { success: false, error: "ACP instance not found" };
|
|
8135
|
+
if (typeof acpInstance.setConfigOption !== "function") {
|
|
8136
|
+
return { success: false, error: "ACP setConfigOption not available" };
|
|
8137
|
+
}
|
|
7959
8138
|
try {
|
|
7960
8139
|
await acpInstance.setConfigOption(configId, value);
|
|
7961
8140
|
LOG.info("Command", `[set_thought_level] ${configId}=${value} for ${provider?.type || "unknown_acp"}`);
|
|
@@ -7982,7 +8161,7 @@ async function handleResolveAction(h, args) {
|
|
|
7982
8161
|
return { success: false, error: `CLI resolveAction failed: ${e.message}` };
|
|
7983
8162
|
}
|
|
7984
8163
|
}
|
|
7985
|
-
const status = adapter.getStatus
|
|
8164
|
+
const status = adapter.getStatus();
|
|
7986
8165
|
if (status?.status !== "waiting_approval") {
|
|
7987
8166
|
return { success: false, error: "Not in approval state" };
|
|
7988
8167
|
}
|
|
@@ -8021,6 +8200,9 @@ async function handleResolveAction(h, args) {
|
|
|
8021
8200
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
8022
8201
|
const acpInstance = adapter?._acpInstance;
|
|
8023
8202
|
if (!acpInstance) return { success: false, error: "ACP instance not found" };
|
|
8203
|
+
if (typeof acpInstance.resolvePermission !== "function") {
|
|
8204
|
+
return { success: false, error: "ACP resolvePermission not available" };
|
|
8205
|
+
}
|
|
8024
8206
|
try {
|
|
8025
8207
|
await acpInstance.resolvePermission(action === "approve" || action === "accept" || action === "always");
|
|
8026
8208
|
LOG.info("Command", `[resolveAction] ACP \u2192 ${action}`);
|
|
@@ -8182,11 +8364,16 @@ async function handleCdpCommand(h, args) {
|
|
|
8182
8364
|
}
|
|
8183
8365
|
async function handleCdpBatch(h, args) {
|
|
8184
8366
|
if (!h.getCdp()?.isConnected) return { success: false, error: "CDP not connected" };
|
|
8185
|
-
const commands = args?.commands;
|
|
8367
|
+
const commands = Array.isArray(args?.commands) ? args.commands : null;
|
|
8186
8368
|
const stopOnError = args?.stopOnError !== false;
|
|
8187
8369
|
if (!commands?.length) return { success: false, error: "commands array required" };
|
|
8188
8370
|
const results = [];
|
|
8189
8371
|
for (const cmd of commands) {
|
|
8372
|
+
if (!cmd || typeof cmd !== "object" || typeof cmd.method !== "string") {
|
|
8373
|
+
results.push({ method: null, success: false, error: "Invalid command entry" });
|
|
8374
|
+
if (stopOnError) break;
|
|
8375
|
+
continue;
|
|
8376
|
+
}
|
|
8190
8377
|
try {
|
|
8191
8378
|
const result = await h.getCdp().sendCdpCommand(cmd.method, cmd.params || {});
|
|
8192
8379
|
results.push({ method: cmd.method, success: true, result });
|
|
@@ -8481,11 +8668,12 @@ function handlePtyResize(h, args) {
|
|
|
8481
8668
|
if (!adapter || typeof adapter.resize !== "function") {
|
|
8482
8669
|
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
|
|
8483
8670
|
}
|
|
8671
|
+
const resize = adapter.resize;
|
|
8484
8672
|
if (force) {
|
|
8485
|
-
|
|
8486
|
-
setTimeout(() =>
|
|
8673
|
+
resize(cols - 1, rows);
|
|
8674
|
+
setTimeout(() => resize(cols, rows), 50);
|
|
8487
8675
|
} else {
|
|
8488
|
-
|
|
8676
|
+
resize(cols, rows);
|
|
8489
8677
|
}
|
|
8490
8678
|
return { success: true };
|
|
8491
8679
|
}
|
|
@@ -8543,7 +8731,7 @@ function parseScriptResult(result) {
|
|
|
8543
8731
|
return { success: true, payload: { result } };
|
|
8544
8732
|
}
|
|
8545
8733
|
}
|
|
8546
|
-
if (result && typeof result === "object" && result.success === false) {
|
|
8734
|
+
if (result && typeof result === "object" && "success" in result && result.success === false) {
|
|
8547
8735
|
return { success: false, payload: result };
|
|
8548
8736
|
}
|
|
8549
8737
|
return { success: true, payload: result };
|
|
@@ -8966,24 +9154,25 @@ var DaemonCommandHandler = class {
|
|
|
8966
9154
|
if (provider?.scripts) {
|
|
8967
9155
|
const fn = provider.scripts[scriptName];
|
|
8968
9156
|
if (typeof fn === "function") {
|
|
9157
|
+
const callScript = fn;
|
|
8969
9158
|
if (params && Object.keys(params).length > 0) {
|
|
8970
9159
|
const firstVal = Object.values(params)[0];
|
|
8971
9160
|
if (scriptName === "sendMessage" && typeof firstVal === "string") {
|
|
8972
|
-
const legacyScript =
|
|
9161
|
+
const legacyScript = callScript(firstVal);
|
|
8973
9162
|
if (legacyScript) return legacyScript;
|
|
8974
9163
|
}
|
|
8975
|
-
const script =
|
|
9164
|
+
const script = callScript(params);
|
|
8976
9165
|
if (script) {
|
|
8977
9166
|
const likelyLegacyObjectLeak = typeof script === "string" && script.includes("[object Object]") && typeof firstVal === "string";
|
|
8978
9167
|
if (!likelyLegacyObjectLeak) return script;
|
|
8979
9168
|
}
|
|
8980
9169
|
if (firstVal !== void 0) {
|
|
8981
|
-
const legacyScript =
|
|
9170
|
+
const legacyScript = callScript(firstVal);
|
|
8982
9171
|
if (legacyScript) return legacyScript;
|
|
8983
9172
|
}
|
|
8984
9173
|
if (script) return script;
|
|
8985
9174
|
} else {
|
|
8986
|
-
const script =
|
|
9175
|
+
const script = callScript();
|
|
8987
9176
|
if (script) return script;
|
|
8988
9177
|
}
|
|
8989
9178
|
}
|
|
@@ -9363,16 +9552,16 @@ var DaemonCommandHandler = class {
|
|
|
9363
9552
|
};
|
|
9364
9553
|
|
|
9365
9554
|
// src/commands/cli-manager.ts
|
|
9366
|
-
var
|
|
9367
|
-
var
|
|
9555
|
+
var os12 = __toESM(require("os"));
|
|
9556
|
+
var path12 = __toESM(require("path"));
|
|
9368
9557
|
var crypto4 = __toESM(require("crypto"));
|
|
9369
9558
|
var import_chalk = __toESM(require("chalk"));
|
|
9370
9559
|
init_provider_cli_adapter();
|
|
9371
9560
|
init_config();
|
|
9372
9561
|
|
|
9373
9562
|
// src/providers/cli-provider-instance.ts
|
|
9374
|
-
var
|
|
9375
|
-
var
|
|
9563
|
+
var os11 = __toESM(require("os"));
|
|
9564
|
+
var path11 = __toESM(require("path"));
|
|
9376
9565
|
var crypto3 = __toESM(require("crypto"));
|
|
9377
9566
|
var fs5 = __toESM(require("fs"));
|
|
9378
9567
|
var import_node_module = require("module");
|
|
@@ -9381,7 +9570,7 @@ init_logger();
|
|
|
9381
9570
|
var CachedDatabaseSync = null;
|
|
9382
9571
|
function getDatabaseSync() {
|
|
9383
9572
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
9384
|
-
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(
|
|
9573
|
+
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path11.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
9385
9574
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
9386
9575
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
9387
9576
|
if (!CachedDatabaseSync) {
|
|
@@ -9521,7 +9710,7 @@ var CliProviderInstance = class {
|
|
|
9521
9710
|
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
9522
9711
|
*/
|
|
9523
9712
|
probeSessionIdFromConfig(probe) {
|
|
9524
|
-
const resolvedDbPath = probe.dbPath.replace(/^~/,
|
|
9713
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os11.homedir());
|
|
9525
9714
|
if (!fs5.existsSync(resolvedDbPath)) return null;
|
|
9526
9715
|
const directories = this.getProbeDirectories();
|
|
9527
9716
|
const minCreatedAt = Math.max(0, this.startedAt - 6e4);
|
|
@@ -10946,7 +11135,8 @@ var AcpProviderInstance = class {
|
|
|
10946
11135
|
|
|
10947
11136
|
// src/commands/cli-manager.ts
|
|
10948
11137
|
init_logger();
|
|
10949
|
-
var
|
|
11138
|
+
var chalkModule = import_chalk.default;
|
|
11139
|
+
var chalkApi = typeof chalkModule.yellow === "function" ? chalkModule : chalkModule.default || null;
|
|
10950
11140
|
function colorize(color, text) {
|
|
10951
11141
|
const fn = chalkApi?.[color];
|
|
10952
11142
|
return typeof fn === "function" ? fn(text) : text;
|
|
@@ -11196,7 +11386,7 @@ var DaemonCliManager = class {
|
|
|
11196
11386
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
11197
11387
|
const trimmed = (workingDir || "").trim();
|
|
11198
11388
|
if (!trimmed) throw new Error("working directory required");
|
|
11199
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
11389
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os12.homedir()) : path12.resolve(trimmed);
|
|
11200
11390
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
11201
11391
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
11202
11392
|
const key = crypto4.randomUUID();
|
|
@@ -11235,6 +11425,7 @@ ${installInfo}`
|
|
|
11235
11425
|
});
|
|
11236
11426
|
this.adapters.set(key, {
|
|
11237
11427
|
cliType: normalizedType,
|
|
11428
|
+
cliName: provider.name,
|
|
11238
11429
|
workingDir: resolvedDir,
|
|
11239
11430
|
_acpInstance: acpInstance,
|
|
11240
11431
|
spawn: async () => {
|
|
@@ -11253,6 +11444,12 @@ ${installInfo}`
|
|
|
11253
11444
|
activeModal: state.activeChat?.activeModal || null
|
|
11254
11445
|
};
|
|
11255
11446
|
},
|
|
11447
|
+
getPartialResponse: () => "",
|
|
11448
|
+
cancel: () => {
|
|
11449
|
+
instanceManager2.removeInstance(key);
|
|
11450
|
+
},
|
|
11451
|
+
isProcessing: () => false,
|
|
11452
|
+
isReady: () => true,
|
|
11256
11453
|
setOnStatusChange: () => {
|
|
11257
11454
|
},
|
|
11258
11455
|
setOnPtyData: () => {
|
|
@@ -11659,13 +11856,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
11659
11856
|
// src/launch.ts
|
|
11660
11857
|
var import_child_process6 = require("child_process");
|
|
11661
11858
|
var net = __toESM(require("net"));
|
|
11662
|
-
var
|
|
11663
|
-
var
|
|
11859
|
+
var os14 = __toESM(require("os"));
|
|
11860
|
+
var path14 = __toESM(require("path"));
|
|
11664
11861
|
|
|
11665
11862
|
// src/providers/provider-loader.ts
|
|
11666
11863
|
var fs6 = __toESM(require("fs"));
|
|
11667
|
-
var
|
|
11668
|
-
var
|
|
11864
|
+
var path13 = __toESM(require("path"));
|
|
11865
|
+
var os13 = __toESM(require("os"));
|
|
11669
11866
|
var chokidar = __toESM(require("chokidar"));
|
|
11670
11867
|
init_logger();
|
|
11671
11868
|
var ProviderLoader = class _ProviderLoader {
|
|
@@ -11686,12 +11883,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11686
11883
|
static META_FILE = ".meta.json";
|
|
11687
11884
|
constructor(options) {
|
|
11688
11885
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
11689
|
-
const defaultProvidersDir =
|
|
11886
|
+
const defaultProvidersDir = path13.join(os13.homedir(), ".adhdev", "providers");
|
|
11690
11887
|
if (options?.userDir) {
|
|
11691
11888
|
this.userDir = options.userDir;
|
|
11692
11889
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
11693
11890
|
} else {
|
|
11694
|
-
const localRepoPath =
|
|
11891
|
+
const localRepoPath = path13.resolve(__dirname, "../../../../../adhdev-providers");
|
|
11695
11892
|
if (fs6.existsSync(localRepoPath)) {
|
|
11696
11893
|
this.userDir = localRepoPath;
|
|
11697
11894
|
this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
|
|
@@ -11700,7 +11897,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11700
11897
|
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
11701
11898
|
}
|
|
11702
11899
|
}
|
|
11703
|
-
this.upstreamDir =
|
|
11900
|
+
this.upstreamDir = path13.join(defaultProvidersDir, ".upstream");
|
|
11704
11901
|
this.disableUpstream = options?.disableUpstream ?? false;
|
|
11705
11902
|
}
|
|
11706
11903
|
log(msg) {
|
|
@@ -11730,7 +11927,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11730
11927
|
* Canonical provider directory shape for a given root.
|
|
11731
11928
|
*/
|
|
11732
11929
|
getProviderDir(root, category, type) {
|
|
11733
|
-
return
|
|
11930
|
+
return path13.join(root, category, type);
|
|
11734
11931
|
}
|
|
11735
11932
|
/**
|
|
11736
11933
|
* Canonical user override directory for a provider.
|
|
@@ -11757,7 +11954,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11757
11954
|
resolveProviderFile(type, ...segments) {
|
|
11758
11955
|
const dir = this.findProviderDirInternal(type);
|
|
11759
11956
|
if (!dir) return null;
|
|
11760
|
-
return
|
|
11957
|
+
return path13.join(dir, ...segments);
|
|
11761
11958
|
}
|
|
11762
11959
|
/**
|
|
11763
11960
|
* Load all providers (3-tier priority)
|
|
@@ -11796,7 +11993,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11796
11993
|
if (!fs6.existsSync(this.upstreamDir)) return false;
|
|
11797
11994
|
try {
|
|
11798
11995
|
return fs6.readdirSync(this.upstreamDir).some(
|
|
11799
|
-
(d) => fs6.statSync(
|
|
11996
|
+
(d) => fs6.statSync(path13.join(this.upstreamDir, d)).isDirectory()
|
|
11800
11997
|
);
|
|
11801
11998
|
} catch {
|
|
11802
11999
|
return false;
|
|
@@ -11837,8 +12034,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11837
12034
|
const result = [];
|
|
11838
12035
|
for (const p of this.providers.values()) {
|
|
11839
12036
|
if ((p.category === "cli" || p.category === "acp") && p.spawn?.command) {
|
|
11840
|
-
const
|
|
11841
|
-
const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[process.platform] : verCmdConfig;
|
|
12037
|
+
const versionCommand = this.getPlatformVersionCommand(p.versionCommand);
|
|
11842
12038
|
const command = this.getSpawnCommand(p.type, p.spawn.command);
|
|
11843
12039
|
result.push({
|
|
11844
12040
|
id: p.type,
|
|
@@ -11892,8 +12088,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11892
12088
|
* that runtime attach/remove uses.
|
|
11893
12089
|
*/
|
|
11894
12090
|
getIdeExtensionEnabledState(ideType, extensionType) {
|
|
11895
|
-
const
|
|
11896
|
-
|
|
12091
|
+
const config = this.readConfig();
|
|
12092
|
+
if (!config) return false;
|
|
11897
12093
|
const baseIdeType = ideType.split("_")[0];
|
|
11898
12094
|
const val = config.ideSettings?.[baseIdeType]?.extensions?.[extensionType]?.enabled;
|
|
11899
12095
|
return val === true;
|
|
@@ -11902,15 +12098,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11902
12098
|
* Save IDE extension enabled setting
|
|
11903
12099
|
*/
|
|
11904
12100
|
setIdeExtensionEnabled(ideType, extensionType, enabled) {
|
|
12101
|
+
const config = this.readConfig();
|
|
12102
|
+
if (!config) return false;
|
|
11905
12103
|
try {
|
|
11906
|
-
const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
|
|
11907
|
-
const config = loadConfig2();
|
|
11908
12104
|
const baseIdeType = ideType.split("_")[0];
|
|
11909
12105
|
if (!config.ideSettings) config.ideSettings = {};
|
|
11910
12106
|
if (!config.ideSettings[baseIdeType]) config.ideSettings[baseIdeType] = {};
|
|
11911
12107
|
if (!config.ideSettings[baseIdeType].extensions) config.ideSettings[baseIdeType].extensions = {};
|
|
11912
12108
|
config.ideSettings[baseIdeType].extensions[extensionType] = { enabled };
|
|
11913
|
-
|
|
12109
|
+
this.writeConfig(config);
|
|
11914
12110
|
this.log(`IDE extension setting: ${ideType}.${extensionType}.enabled = ${enabled}`);
|
|
11915
12111
|
return true;
|
|
11916
12112
|
} catch (e) {
|
|
@@ -12100,7 +12296,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12100
12296
|
}
|
|
12101
12297
|
if (currentVersion) {
|
|
12102
12298
|
resolved._resolvedVersion = currentVersion;
|
|
12103
|
-
if (
|
|
12299
|
+
if (base.compatibility) {
|
|
12104
12300
|
const compat = base.compatibility;
|
|
12105
12301
|
let matched = false;
|
|
12106
12302
|
for (const entry of compat) {
|
|
@@ -12112,8 +12308,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12112
12308
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
12113
12309
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
12114
12310
|
if (providerDir) {
|
|
12115
|
-
const fullDir =
|
|
12116
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
12311
|
+
const fullDir = path13.join(providerDir, entry.scriptDir);
|
|
12312
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
|
|
12117
12313
|
}
|
|
12118
12314
|
matched = true;
|
|
12119
12315
|
}
|
|
@@ -12128,8 +12324,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12128
12324
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
12129
12325
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
12130
12326
|
if (providerDir) {
|
|
12131
|
-
const fullDir =
|
|
12132
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
12327
|
+
const fullDir = path13.join(providerDir, base.defaultScriptDir);
|
|
12328
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
|
|
12133
12329
|
}
|
|
12134
12330
|
}
|
|
12135
12331
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -12146,8 +12342,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12146
12342
|
resolved._resolvedScriptDir = dirOverride;
|
|
12147
12343
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
12148
12344
|
if (providerDir) {
|
|
12149
|
-
const fullDir =
|
|
12150
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
12345
|
+
const fullDir = path13.join(providerDir, dirOverride);
|
|
12346
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
|
|
12151
12347
|
}
|
|
12152
12348
|
}
|
|
12153
12349
|
} else if (override.scripts) {
|
|
@@ -12155,7 +12351,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12155
12351
|
}
|
|
12156
12352
|
}
|
|
12157
12353
|
}
|
|
12158
|
-
} else if (
|
|
12354
|
+
} else if (base.compatibility && base.defaultScriptDir) {
|
|
12159
12355
|
const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
|
|
12160
12356
|
if (loaded) {
|
|
12161
12357
|
resolved.scripts = loaded;
|
|
@@ -12163,8 +12359,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12163
12359
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
12164
12360
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
12165
12361
|
if (providerDir) {
|
|
12166
|
-
const fullDir =
|
|
12167
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
12362
|
+
const fullDir = path13.join(providerDir, base.defaultScriptDir);
|
|
12363
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
|
|
12168
12364
|
}
|
|
12169
12365
|
}
|
|
12170
12366
|
}
|
|
@@ -12189,14 +12385,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12189
12385
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
12190
12386
|
return null;
|
|
12191
12387
|
}
|
|
12192
|
-
const dir =
|
|
12388
|
+
const dir = path13.join(providerDir, scriptDir);
|
|
12193
12389
|
if (!fs6.existsSync(dir)) {
|
|
12194
12390
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
12195
12391
|
return null;
|
|
12196
12392
|
}
|
|
12197
12393
|
const cached = this.scriptsCache.get(dir);
|
|
12198
12394
|
if (cached) return cached;
|
|
12199
|
-
const scriptsJs =
|
|
12395
|
+
const scriptsJs = path13.join(dir, "scripts.js");
|
|
12200
12396
|
if (fs6.existsSync(scriptsJs)) {
|
|
12201
12397
|
try {
|
|
12202
12398
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -12238,7 +12434,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12238
12434
|
return;
|
|
12239
12435
|
}
|
|
12240
12436
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
12241
|
-
this.log(`File changed: ${
|
|
12437
|
+
this.log(`File changed: ${path13.basename(filePath)}, reloading...`);
|
|
12242
12438
|
this.reload();
|
|
12243
12439
|
}
|
|
12244
12440
|
};
|
|
@@ -12293,7 +12489,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12293
12489
|
}
|
|
12294
12490
|
const https = require("https");
|
|
12295
12491
|
const { execSync: execSync7 } = require("child_process");
|
|
12296
|
-
const metaPath =
|
|
12492
|
+
const metaPath = path13.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
12297
12493
|
let prevEtag = "";
|
|
12298
12494
|
let prevTimestamp = 0;
|
|
12299
12495
|
try {
|
|
@@ -12353,17 +12549,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12353
12549
|
return { updated: false };
|
|
12354
12550
|
}
|
|
12355
12551
|
this.log("Downloading latest providers from GitHub...");
|
|
12356
|
-
const tmpTar =
|
|
12357
|
-
const tmpExtract =
|
|
12552
|
+
const tmpTar = path13.join(os13.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
12553
|
+
const tmpExtract = path13.join(os13.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
12358
12554
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
12359
12555
|
fs6.mkdirSync(tmpExtract, { recursive: true });
|
|
12360
12556
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
12361
12557
|
const extracted = fs6.readdirSync(tmpExtract);
|
|
12362
12558
|
const rootDir = extracted.find(
|
|
12363
|
-
(d) => fs6.statSync(
|
|
12559
|
+
(d) => fs6.statSync(path13.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
12364
12560
|
);
|
|
12365
12561
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
12366
|
-
const sourceDir =
|
|
12562
|
+
const sourceDir = path13.join(tmpExtract, rootDir);
|
|
12367
12563
|
const backupDir = this.upstreamDir + ".bak";
|
|
12368
12564
|
if (fs6.existsSync(this.upstreamDir)) {
|
|
12369
12565
|
if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -12438,8 +12634,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12438
12634
|
copyDirRecursive(src, dest) {
|
|
12439
12635
|
fs6.mkdirSync(dest, { recursive: true });
|
|
12440
12636
|
for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
|
|
12441
|
-
const srcPath =
|
|
12442
|
-
const destPath =
|
|
12637
|
+
const srcPath = path13.join(src, entry.name);
|
|
12638
|
+
const destPath = path13.join(dest, entry.name);
|
|
12443
12639
|
if (entry.isDirectory()) {
|
|
12444
12640
|
this.copyDirRecursive(srcPath, destPath);
|
|
12445
12641
|
} else {
|
|
@@ -12450,7 +12646,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12450
12646
|
/** .meta.json save */
|
|
12451
12647
|
writeMeta(metaPath, etag, timestamp) {
|
|
12452
12648
|
try {
|
|
12453
|
-
fs6.mkdirSync(
|
|
12649
|
+
fs6.mkdirSync(path13.dirname(metaPath), { recursive: true });
|
|
12454
12650
|
fs6.writeFileSync(metaPath, JSON.stringify({
|
|
12455
12651
|
etag,
|
|
12456
12652
|
timestamp,
|
|
@@ -12467,7 +12663,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12467
12663
|
const scan = (d) => {
|
|
12468
12664
|
try {
|
|
12469
12665
|
for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
|
|
12470
|
-
if (entry.isDirectory()) scan(
|
|
12666
|
+
if (entry.isDirectory()) scan(path13.join(d, entry.name));
|
|
12471
12667
|
else if (entry.name === "provider.json") count++;
|
|
12472
12668
|
}
|
|
12473
12669
|
} catch {
|
|
@@ -12501,14 +12697,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12501
12697
|
getSettingValue(type, key) {
|
|
12502
12698
|
const schemaDef = this.getSettingsSchema(type)[key];
|
|
12503
12699
|
const defaultVal = schemaDef ? key === "autoApprove" && schemaDef.type === "boolean" ? true : schemaDef.default : void 0;
|
|
12504
|
-
|
|
12505
|
-
|
|
12506
|
-
|
|
12507
|
-
const userVal = config.providerSettings?.[type]?.[key];
|
|
12508
|
-
return userVal !== void 0 ? userVal : defaultVal;
|
|
12509
|
-
} catch {
|
|
12510
|
-
return defaultVal;
|
|
12511
|
-
}
|
|
12700
|
+
const config = this.readConfig();
|
|
12701
|
+
const userVal = config?.providerSettings?.[type]?.[key];
|
|
12702
|
+
return userVal !== void 0 ? userVal : defaultVal;
|
|
12512
12703
|
}
|
|
12513
12704
|
/**
|
|
12514
12705
|
* All resolved settings for a provider (default + user override)
|
|
@@ -12536,13 +12727,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12536
12727
|
if (schemaDef.max !== void 0 && value > schemaDef.max) return false;
|
|
12537
12728
|
}
|
|
12538
12729
|
if (schemaDef.type === "select" && schemaDef.options && !schemaDef.options.includes(value)) return false;
|
|
12730
|
+
const config = this.readConfig();
|
|
12731
|
+
if (!config) return false;
|
|
12539
12732
|
try {
|
|
12540
|
-
const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
|
|
12541
|
-
const config = loadConfig2();
|
|
12542
12733
|
if (!config.providerSettings) config.providerSettings = {};
|
|
12543
12734
|
if (!config.providerSettings[type]) config.providerSettings[type] = {};
|
|
12544
12735
|
config.providerSettings[type][key] = value;
|
|
12545
|
-
|
|
12736
|
+
this.writeConfig(config);
|
|
12546
12737
|
this.log(`Setting updated: ${type}.${key} = ${JSON.stringify(value)}`);
|
|
12547
12738
|
return true;
|
|
12548
12739
|
} catch (e) {
|
|
@@ -12556,6 +12747,34 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12556
12747
|
const trimmed = value.trim();
|
|
12557
12748
|
return trimmed ? trimmed : null;
|
|
12558
12749
|
}
|
|
12750
|
+
readConfig() {
|
|
12751
|
+
try {
|
|
12752
|
+
const { loadConfig: loadConfig2 } = (init_config(), __toCommonJS(config_exports));
|
|
12753
|
+
return loadConfig2();
|
|
12754
|
+
} catch {
|
|
12755
|
+
return null;
|
|
12756
|
+
}
|
|
12757
|
+
}
|
|
12758
|
+
writeConfig(config) {
|
|
12759
|
+
const { saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
|
|
12760
|
+
saveConfig3(config);
|
|
12761
|
+
}
|
|
12762
|
+
getPlatformVersionCommand(versionCommand) {
|
|
12763
|
+
if (!versionCommand) return void 0;
|
|
12764
|
+
if (typeof versionCommand === "string") {
|
|
12765
|
+
const trimmed = versionCommand.trim();
|
|
12766
|
+
return trimmed || void 0;
|
|
12767
|
+
}
|
|
12768
|
+
const platformValue = versionCommand[process.platform];
|
|
12769
|
+
if (typeof platformValue === "string" && platformValue.trim()) {
|
|
12770
|
+
return platformValue.trim();
|
|
12771
|
+
}
|
|
12772
|
+
const defaultValue = versionCommand.default;
|
|
12773
|
+
if (typeof defaultValue === "string" && defaultValue.trim()) {
|
|
12774
|
+
return defaultValue.trim();
|
|
12775
|
+
}
|
|
12776
|
+
return void 0;
|
|
12777
|
+
}
|
|
12559
12778
|
getSettingsSchema(type) {
|
|
12560
12779
|
const provider = this.providers.get(type);
|
|
12561
12780
|
if (!provider) return {};
|
|
@@ -12629,17 +12848,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12629
12848
|
for (const root of searchRoots) {
|
|
12630
12849
|
if (!fs6.existsSync(root)) continue;
|
|
12631
12850
|
const candidate = this.getProviderDir(root, cat, type);
|
|
12632
|
-
if (fs6.existsSync(
|
|
12633
|
-
const catDir =
|
|
12851
|
+
if (fs6.existsSync(path13.join(candidate, "provider.json"))) return candidate;
|
|
12852
|
+
const catDir = path13.join(root, cat);
|
|
12634
12853
|
if (fs6.existsSync(catDir)) {
|
|
12635
12854
|
try {
|
|
12636
12855
|
for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
|
|
12637
12856
|
if (!entry.isDirectory()) continue;
|
|
12638
|
-
const jsonPath =
|
|
12857
|
+
const jsonPath = path13.join(catDir, entry.name, "provider.json");
|
|
12639
12858
|
if (fs6.existsSync(jsonPath)) {
|
|
12640
12859
|
try {
|
|
12641
12860
|
const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
|
|
12642
|
-
if (data.type === type) return
|
|
12861
|
+
if (data.type === type) return path13.join(catDir, entry.name);
|
|
12643
12862
|
} catch {
|
|
12644
12863
|
}
|
|
12645
12864
|
}
|
|
@@ -12656,7 +12875,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12656
12875
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
12657
12876
|
*/
|
|
12658
12877
|
buildScriptWrappersFromDir(dir) {
|
|
12659
|
-
const scriptsJs =
|
|
12878
|
+
const scriptsJs = path13.join(dir, "scripts.js");
|
|
12660
12879
|
if (fs6.existsSync(scriptsJs)) {
|
|
12661
12880
|
try {
|
|
12662
12881
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -12670,7 +12889,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12670
12889
|
for (const file of fs6.readdirSync(dir)) {
|
|
12671
12890
|
if (!file.endsWith(".js")) continue;
|
|
12672
12891
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
12673
|
-
const filePath =
|
|
12892
|
+
const filePath = path13.join(dir, file);
|
|
12674
12893
|
result[scriptName] = (...args) => {
|
|
12675
12894
|
try {
|
|
12676
12895
|
let content = fs6.readFileSync(filePath, "utf-8");
|
|
@@ -12730,35 +12949,39 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12730
12949
|
}
|
|
12731
12950
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
12732
12951
|
if (hasJson) {
|
|
12733
|
-
const jsonPath =
|
|
12952
|
+
const jsonPath = path13.join(d, "provider.json");
|
|
12734
12953
|
try {
|
|
12735
12954
|
const raw = fs6.readFileSync(jsonPath, "utf-8");
|
|
12736
12955
|
const mod = JSON.parse(raw);
|
|
12737
12956
|
if (!mod.type || !mod.name || !mod.category) {
|
|
12738
12957
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: missing type/name/category`);
|
|
12739
12958
|
} else {
|
|
12740
|
-
if (
|
|
12959
|
+
if (typeof mod.extensionIdPattern === "string") {
|
|
12741
12960
|
const flags = mod.extensionIdPattern_flags || "";
|
|
12742
12961
|
mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
|
|
12743
|
-
delete mod.extensionIdPattern_flags;
|
|
12744
12962
|
}
|
|
12745
|
-
const
|
|
12746
|
-
const
|
|
12963
|
+
const { extensionIdPattern_flags, extensionIdPattern, ...providerFields } = mod;
|
|
12964
|
+
const normalizedProvider = {
|
|
12965
|
+
...providerFields,
|
|
12966
|
+
...extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}
|
|
12967
|
+
};
|
|
12968
|
+
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
12969
|
+
const scriptsPath = path13.join(d, "scripts.js");
|
|
12747
12970
|
if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
|
|
12748
12971
|
try {
|
|
12749
12972
|
delete require.cache[require.resolve(scriptsPath)];
|
|
12750
12973
|
const scripts = require(scriptsPath);
|
|
12751
|
-
|
|
12974
|
+
normalizedProvider.scripts = scripts;
|
|
12752
12975
|
} catch (e) {
|
|
12753
12976
|
this.log(`\u26A0 Failed to load scripts: ${scriptsPath}: ${e.message}`);
|
|
12754
12977
|
}
|
|
12755
12978
|
}
|
|
12756
|
-
const existed = this.providers.has(
|
|
12757
|
-
this.providers.set(
|
|
12979
|
+
const existed = this.providers.has(normalizedProvider.type);
|
|
12980
|
+
this.providers.set(normalizedProvider.type, normalizedProvider);
|
|
12758
12981
|
count++;
|
|
12759
12982
|
const source = d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
|
|
12760
12983
|
const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
|
|
12761
|
-
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${
|
|
12984
|
+
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${source}]${overrideWarning}`);
|
|
12762
12985
|
}
|
|
12763
12986
|
} catch (e) {
|
|
12764
12987
|
this.log(`\u26A0 Failed to load ${jsonPath}: ${e.message}`);
|
|
@@ -12769,7 +12992,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12769
12992
|
if (!entry.isDirectory()) continue;
|
|
12770
12993
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
12771
12994
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
12772
|
-
scan(
|
|
12995
|
+
scan(path13.join(d, entry.name));
|
|
12773
12996
|
}
|
|
12774
12997
|
}
|
|
12775
12998
|
};
|
|
@@ -12839,9 +13062,9 @@ function getWinProcessNames() {
|
|
|
12839
13062
|
function getProviderMeta(ideId) {
|
|
12840
13063
|
return getProviderLoader().getMeta(ideId);
|
|
12841
13064
|
}
|
|
12842
|
-
function getPreferredLaunchMethod(ideId,
|
|
13065
|
+
function getPreferredLaunchMethod(ideId, platform10) {
|
|
12843
13066
|
const prefer = getProviderMeta(ideId)?.launch?.prefer;
|
|
12844
|
-
const value = prefer?.[
|
|
13067
|
+
const value = prefer?.[platform10];
|
|
12845
13068
|
return value === "cli" || value === "app" || value === "auto" ? value : "auto";
|
|
12846
13069
|
}
|
|
12847
13070
|
function getCdpStartupTimeoutMs(ideId) {
|
|
@@ -12898,7 +13121,7 @@ async function isCdpActive(port) {
|
|
|
12898
13121
|
});
|
|
12899
13122
|
}
|
|
12900
13123
|
async function killIdeProcess(ideId) {
|
|
12901
|
-
const plat =
|
|
13124
|
+
const plat = os14.platform();
|
|
12902
13125
|
const appName = getMacAppIdentifiers()[ideId];
|
|
12903
13126
|
const winProcesses = getWinProcessNames()[ideId];
|
|
12904
13127
|
try {
|
|
@@ -12957,7 +13180,7 @@ async function killIdeProcess(ideId) {
|
|
|
12957
13180
|
}
|
|
12958
13181
|
}
|
|
12959
13182
|
function isIdeRunning(ideId) {
|
|
12960
|
-
const plat =
|
|
13183
|
+
const plat = os14.platform();
|
|
12961
13184
|
try {
|
|
12962
13185
|
if (plat === "darwin") {
|
|
12963
13186
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -13008,7 +13231,7 @@ function isIdeRunning(ideId) {
|
|
|
13008
13231
|
}
|
|
13009
13232
|
}
|
|
13010
13233
|
function detectCurrentWorkspace(ideId) {
|
|
13011
|
-
const plat =
|
|
13234
|
+
const plat = os14.platform();
|
|
13012
13235
|
if (plat === "darwin") {
|
|
13013
13236
|
try {
|
|
13014
13237
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -13027,8 +13250,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
13027
13250
|
const appNameMap = getMacAppIdentifiers();
|
|
13028
13251
|
const appName = appNameMap[ideId];
|
|
13029
13252
|
if (appName) {
|
|
13030
|
-
const storagePath =
|
|
13031
|
-
process.env.APPDATA ||
|
|
13253
|
+
const storagePath = path14.join(
|
|
13254
|
+
process.env.APPDATA || path14.join(os14.homedir(), "AppData", "Roaming"),
|
|
13032
13255
|
appName,
|
|
13033
13256
|
"storage.json"
|
|
13034
13257
|
);
|
|
@@ -13050,7 +13273,7 @@ function detectCurrentWorkspace(ideId) {
|
|
|
13050
13273
|
return void 0;
|
|
13051
13274
|
}
|
|
13052
13275
|
async function launchWithCdp(options = {}) {
|
|
13053
|
-
const
|
|
13276
|
+
const platform10 = os14.platform();
|
|
13054
13277
|
let targetIde;
|
|
13055
13278
|
const ides = await detectIDEs(getProviderLoader());
|
|
13056
13279
|
if (options.ideId) {
|
|
@@ -13119,9 +13342,9 @@ async function launchWithCdp(options = {}) {
|
|
|
13119
13342
|
}
|
|
13120
13343
|
const port = await findFreePort(portPair);
|
|
13121
13344
|
try {
|
|
13122
|
-
if (
|
|
13345
|
+
if (platform10 === "darwin") {
|
|
13123
13346
|
await launchMacOS(targetIde, port, workspace, options.newWindow);
|
|
13124
|
-
} else if (
|
|
13347
|
+
} else if (platform10 === "win32") {
|
|
13125
13348
|
await launchWindows(targetIde, port, workspace, options.newWindow);
|
|
13126
13349
|
} else {
|
|
13127
13350
|
await launchLinux(targetIde, port, workspace, options.newWindow);
|
|
@@ -13206,9 +13429,9 @@ init_logger();
|
|
|
13206
13429
|
|
|
13207
13430
|
// src/logging/command-log.ts
|
|
13208
13431
|
var fs7 = __toESM(require("fs"));
|
|
13209
|
-
var
|
|
13210
|
-
var
|
|
13211
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
13432
|
+
var path15 = __toESM(require("path"));
|
|
13433
|
+
var os15 = __toESM(require("os"));
|
|
13434
|
+
var LOG_DIR2 = process.platform === "win32" ? path15.join(process.env.LOCALAPPDATA || process.env.APPDATA || path15.join(os15.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path15.join(os15.homedir(), "Library", "Logs", "adhdev") : path15.join(os15.homedir(), ".local", "share", "adhdev", "logs");
|
|
13212
13435
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
13213
13436
|
var MAX_DAYS = 7;
|
|
13214
13437
|
try {
|
|
@@ -13246,13 +13469,13 @@ function getDateStr2() {
|
|
|
13246
13469
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
13247
13470
|
}
|
|
13248
13471
|
var currentDate2 = getDateStr2();
|
|
13249
|
-
var currentFile =
|
|
13472
|
+
var currentFile = path15.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
13250
13473
|
var writeCount2 = 0;
|
|
13251
13474
|
function checkRotation() {
|
|
13252
13475
|
const today = getDateStr2();
|
|
13253
13476
|
if (today !== currentDate2) {
|
|
13254
13477
|
currentDate2 = today;
|
|
13255
|
-
currentFile =
|
|
13478
|
+
currentFile = path15.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
13256
13479
|
cleanOldFiles();
|
|
13257
13480
|
}
|
|
13258
13481
|
}
|
|
@@ -13266,7 +13489,7 @@ function cleanOldFiles() {
|
|
|
13266
13489
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
13267
13490
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
13268
13491
|
try {
|
|
13269
|
-
fs7.unlinkSync(
|
|
13492
|
+
fs7.unlinkSync(path15.join(LOG_DIR2, file));
|
|
13270
13493
|
} catch {
|
|
13271
13494
|
}
|
|
13272
13495
|
}
|
|
@@ -13343,7 +13566,7 @@ cleanOldFiles();
|
|
|
13343
13566
|
init_logger();
|
|
13344
13567
|
|
|
13345
13568
|
// src/status/snapshot.ts
|
|
13346
|
-
var
|
|
13569
|
+
var os16 = __toESM(require("os"));
|
|
13347
13570
|
init_config();
|
|
13348
13571
|
init_terminal_screen();
|
|
13349
13572
|
init_logger();
|
|
@@ -13463,16 +13686,16 @@ function buildStatusSnapshot(options) {
|
|
|
13463
13686
|
version: options.version,
|
|
13464
13687
|
daemonMode: options.daemonMode,
|
|
13465
13688
|
machine: {
|
|
13466
|
-
hostname:
|
|
13467
|
-
platform:
|
|
13468
|
-
arch:
|
|
13469
|
-
cpus:
|
|
13689
|
+
hostname: os16.hostname(),
|
|
13690
|
+
platform: os16.platform(),
|
|
13691
|
+
arch: os16.arch(),
|
|
13692
|
+
cpus: os16.cpus().length,
|
|
13470
13693
|
totalMem: memSnap.totalMem,
|
|
13471
13694
|
freeMem: memSnap.freeMem,
|
|
13472
13695
|
availableMem: memSnap.availableMem,
|
|
13473
|
-
loadavg:
|
|
13474
|
-
uptime:
|
|
13475
|
-
release:
|
|
13696
|
+
loadavg: os16.loadavg(),
|
|
13697
|
+
uptime: os16.uptime(),
|
|
13698
|
+
release: os16.release()
|
|
13476
13699
|
},
|
|
13477
13700
|
machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
|
|
13478
13701
|
timestamp: options.timestamp ?? Date.now(),
|
|
@@ -13493,14 +13716,14 @@ function buildStatusSnapshot(options) {
|
|
|
13493
13716
|
var import_child_process7 = require("child_process");
|
|
13494
13717
|
var import_child_process8 = require("child_process");
|
|
13495
13718
|
var fs8 = __toESM(require("fs"));
|
|
13496
|
-
var
|
|
13497
|
-
var
|
|
13719
|
+
var os17 = __toESM(require("os"));
|
|
13720
|
+
var path16 = __toESM(require("path"));
|
|
13498
13721
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
13499
13722
|
function getUpgradeLogPath() {
|
|
13500
|
-
const home =
|
|
13501
|
-
const dir =
|
|
13723
|
+
const home = os17.homedir();
|
|
13724
|
+
const dir = path16.join(home, ".adhdev");
|
|
13502
13725
|
fs8.mkdirSync(dir, { recursive: true });
|
|
13503
|
-
return
|
|
13726
|
+
return path16.join(dir, "daemon-upgrade.log");
|
|
13504
13727
|
}
|
|
13505
13728
|
function appendUpgradeLog(message) {
|
|
13506
13729
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -13540,7 +13763,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
13540
13763
|
}
|
|
13541
13764
|
}
|
|
13542
13765
|
function stopSessionHostProcesses(appName) {
|
|
13543
|
-
const pidFile =
|
|
13766
|
+
const pidFile = path16.join(os17.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
13544
13767
|
try {
|
|
13545
13768
|
if (fs8.existsSync(pidFile)) {
|
|
13546
13769
|
const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -13569,7 +13792,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
13569
13792
|
}
|
|
13570
13793
|
}
|
|
13571
13794
|
function removeDaemonPidFile() {
|
|
13572
|
-
const pidFile =
|
|
13795
|
+
const pidFile = path16.join(os17.homedir(), ".adhdev", "daemon.pid");
|
|
13573
13796
|
try {
|
|
13574
13797
|
fs8.unlinkSync(pidFile);
|
|
13575
13798
|
} catch {
|
|
@@ -13580,7 +13803,7 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
|
|
|
13580
13803
|
const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
13581
13804
|
if (!npmRoot) return;
|
|
13582
13805
|
const npmPrefix = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
13583
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
13806
|
+
const binDir = process.platform === "win32" ? npmPrefix : path16.join(npmPrefix, "bin");
|
|
13584
13807
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
13585
13808
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
13586
13809
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -13588,25 +13811,25 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
|
|
|
13588
13811
|
}
|
|
13589
13812
|
if (pkgName.startsWith("@")) {
|
|
13590
13813
|
const [scope, name] = pkgName.split("/");
|
|
13591
|
-
const scopeDir =
|
|
13814
|
+
const scopeDir = path16.join(npmRoot, scope);
|
|
13592
13815
|
if (!fs8.existsSync(scopeDir)) return;
|
|
13593
13816
|
for (const entry of fs8.readdirSync(scopeDir)) {
|
|
13594
13817
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
13595
|
-
fs8.rmSync(
|
|
13596
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
13818
|
+
fs8.rmSync(path16.join(scopeDir, entry), { recursive: true, force: true });
|
|
13819
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path16.join(scopeDir, entry)}`);
|
|
13597
13820
|
}
|
|
13598
13821
|
} else {
|
|
13599
13822
|
for (const entry of fs8.readdirSync(npmRoot)) {
|
|
13600
13823
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
13601
|
-
fs8.rmSync(
|
|
13602
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
13824
|
+
fs8.rmSync(path16.join(npmRoot, entry), { recursive: true, force: true });
|
|
13825
|
+
appendUpgradeLog(`Removed stale staging dir: ${path16.join(npmRoot, entry)}`);
|
|
13603
13826
|
}
|
|
13604
13827
|
}
|
|
13605
13828
|
if (fs8.existsSync(binDir)) {
|
|
13606
13829
|
for (const entry of fs8.readdirSync(binDir)) {
|
|
13607
13830
|
if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
13608
|
-
fs8.rmSync(
|
|
13609
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
13831
|
+
fs8.rmSync(path16.join(binDir, entry), { recursive: true, force: true });
|
|
13832
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path16.join(binDir, entry)}`);
|
|
13610
13833
|
}
|
|
13611
13834
|
}
|
|
13612
13835
|
}
|
|
@@ -13692,6 +13915,18 @@ var CHAT_COMMANDS = [
|
|
|
13692
13915
|
"change_model"
|
|
13693
13916
|
];
|
|
13694
13917
|
var READ_DEBUG_ENABLED2 = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
13918
|
+
function normalizeCommandSource(source) {
|
|
13919
|
+
switch (source) {
|
|
13920
|
+
case "ws":
|
|
13921
|
+
case "p2p":
|
|
13922
|
+
case "ext":
|
|
13923
|
+
case "api":
|
|
13924
|
+
case "standalone":
|
|
13925
|
+
return source;
|
|
13926
|
+
default:
|
|
13927
|
+
return "unknown";
|
|
13928
|
+
}
|
|
13929
|
+
}
|
|
13695
13930
|
function toHostedCliRuntimeDescriptor(record) {
|
|
13696
13931
|
if (!record || typeof record !== "object") return null;
|
|
13697
13932
|
const runtimeId = typeof record.sessionId === "string" ? record.sessionId : "";
|
|
@@ -13729,20 +13964,21 @@ var DaemonCommandRouter = class {
|
|
|
13729
13964
|
*/
|
|
13730
13965
|
async execute(cmd, args, source = "unknown") {
|
|
13731
13966
|
const cmdStart = Date.now();
|
|
13967
|
+
const logSource = normalizeCommandSource(source);
|
|
13732
13968
|
try {
|
|
13733
13969
|
const daemonResult = await this.executeDaemonCommand(cmd, args);
|
|
13734
13970
|
if (daemonResult) {
|
|
13735
|
-
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source, args, success: daemonResult.success, durationMs: Date.now() - cmdStart });
|
|
13971
|
+
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source: logSource, args, success: daemonResult.success, durationMs: Date.now() - cmdStart });
|
|
13736
13972
|
return daemonResult;
|
|
13737
13973
|
}
|
|
13738
13974
|
const handlerResult = await this.deps.commandHandler.handle(cmd, args);
|
|
13739
|
-
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source, args, success: handlerResult.success, durationMs: Date.now() - cmdStart });
|
|
13975
|
+
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source: logSource, args, success: handlerResult.success, durationMs: Date.now() - cmdStart });
|
|
13740
13976
|
if (CHAT_COMMANDS.includes(cmd) && this.deps.onPostChatCommand) {
|
|
13741
13977
|
this.deps.onPostChatCommand();
|
|
13742
13978
|
}
|
|
13743
13979
|
return handlerResult;
|
|
13744
13980
|
} catch (e) {
|
|
13745
|
-
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source, args, success: false, error: e.message, durationMs: Date.now() - cmdStart });
|
|
13981
|
+
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source: logSource, args, success: false, error: e.message, durationMs: Date.now() - cmdStart });
|
|
13746
13982
|
throw e;
|
|
13747
13983
|
}
|
|
13748
13984
|
}
|
|
@@ -14012,7 +14248,7 @@ var DaemonCommandRouter = class {
|
|
|
14012
14248
|
} catch {
|
|
14013
14249
|
}
|
|
14014
14250
|
}
|
|
14015
|
-
return {
|
|
14251
|
+
return { ...result };
|
|
14016
14252
|
}
|
|
14017
14253
|
// ─── Detect IDEs ───
|
|
14018
14254
|
case "detect_ides": {
|
|
@@ -14142,16 +14378,14 @@ var DaemonCommandRouter = class {
|
|
|
14142
14378
|
}
|
|
14143
14379
|
}
|
|
14144
14380
|
for (const instanceKey of keysToRemove) {
|
|
14145
|
-
|
|
14146
|
-
if (ideInstance) {
|
|
14381
|
+
if (this.deps.instanceManager.getInstance(instanceKey)) {
|
|
14147
14382
|
this.deps.instanceManager.removeInstance(instanceKey);
|
|
14148
14383
|
LOG.info("StopIDE", `Instance removed: ${instanceKey}`);
|
|
14149
14384
|
}
|
|
14150
14385
|
}
|
|
14151
14386
|
if (keysToRemove.length === 0) {
|
|
14152
14387
|
const instanceKey = `ide:${ideType}`;
|
|
14153
|
-
|
|
14154
|
-
if (ideInstance) {
|
|
14388
|
+
if (this.deps.instanceManager.getInstance(instanceKey)) {
|
|
14155
14389
|
this.deps.instanceManager.removeInstance(instanceKey);
|
|
14156
14390
|
LOG.info("StopIDE", `Instance removed: ${instanceKey}`);
|
|
14157
14391
|
}
|
|
@@ -14366,11 +14600,11 @@ var DaemonStatusReporter = class {
|
|
|
14366
14600
|
// ─── P2P ─────────────────────────────────────────
|
|
14367
14601
|
sendP2PPayload(payload) {
|
|
14368
14602
|
const { timestamp: _ts, system: _sys, ...hashTarget } = payload;
|
|
14369
|
-
|
|
14603
|
+
const hashPayload = hashTarget.machine ? (() => {
|
|
14370
14604
|
const { freeMem: _f, availableMem: _a, loadavg: _l, uptime: _u, ...stableMachine } = hashTarget.machine;
|
|
14371
|
-
hashTarget
|
|
14372
|
-
}
|
|
14373
|
-
const h = this.simpleHash(JSON.stringify(
|
|
14605
|
+
return { ...hashTarget, machine: stableMachine };
|
|
14606
|
+
})() : hashTarget;
|
|
14607
|
+
const h = this.simpleHash(JSON.stringify(hashPayload));
|
|
14374
14608
|
if (h !== this.lastP2PStatusHash) {
|
|
14375
14609
|
this.lastP2PStatusHash = h;
|
|
14376
14610
|
this.deps.p2p?.sendStatus(payload);
|
|
@@ -14418,6 +14652,9 @@ var ProviderStreamAdapter = class {
|
|
|
14418
14652
|
hasScript(name) {
|
|
14419
14653
|
return typeof this.provider.scripts?.[name] === "function";
|
|
14420
14654
|
}
|
|
14655
|
+
getStateTitle(state) {
|
|
14656
|
+
return typeof state.title === "string" ? state.title : "";
|
|
14657
|
+
}
|
|
14421
14658
|
parseMaybeJson(raw) {
|
|
14422
14659
|
if (typeof raw !== "string") return raw;
|
|
14423
14660
|
try {
|
|
@@ -14621,7 +14858,7 @@ var ProviderStreamAdapter = class {
|
|
|
14621
14858
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
14622
14859
|
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
14623
14860
|
const state = await this.readChat(evaluate);
|
|
14624
|
-
const title =
|
|
14861
|
+
const title = this.getStateTitle(state);
|
|
14625
14862
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
14626
14863
|
}
|
|
14627
14864
|
return false;
|
|
@@ -14718,6 +14955,11 @@ var DaemonAgentStreamManager = class {
|
|
|
14718
14955
|
const child = (this.sessionRegistry?.listChildren(parentSessionId) || []).find((entry) => entry.transport === "cdp-webview" && entry.providerType === agentType);
|
|
14719
14956
|
return child?.sessionId || null;
|
|
14720
14957
|
}
|
|
14958
|
+
getStateError(state) {
|
|
14959
|
+
if (typeof state.error === "string" && state.error.trim()) return state.error.trim();
|
|
14960
|
+
if (typeof state._error === "string" && state._error.trim()) return state._error.trim();
|
|
14961
|
+
return "unknown";
|
|
14962
|
+
}
|
|
14721
14963
|
async connectManagedSession(cdp, parentSessionId, runtimeSessionId) {
|
|
14722
14964
|
const target = this.getSessionTarget(runtimeSessionId);
|
|
14723
14965
|
if (!target || target.transport !== "cdp-webview") return null;
|
|
@@ -14780,8 +15022,8 @@ var DaemonAgentStreamManager = class {
|
|
|
14780
15022
|
try {
|
|
14781
15023
|
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
14782
15024
|
const state = await agent.adapter.readChat(evaluate);
|
|
14783
|
-
|
|
14784
|
-
|
|
15025
|
+
const stateError = this.getStateError(state);
|
|
15026
|
+
LOG.debug("AgentStream", `[AgentStream] readChat(${type}) result: status=${state.status} msgs=${state.messages?.length || 0} model=${state.model || ""}${state.status === "error" ? " error=" + JSON.stringify(stateError) : ""}`);
|
|
14785
15027
|
if (state.status === "error" && this.isRecoverableSessionError(stateError)) {
|
|
14786
15028
|
throw new Error(stateError);
|
|
14787
15029
|
}
|
|
@@ -15350,11 +15592,11 @@ var ProviderInstanceManager = class {
|
|
|
15350
15592
|
|
|
15351
15593
|
// src/providers/version-archive.ts
|
|
15352
15594
|
var fs10 = __toESM(require("fs"));
|
|
15353
|
-
var
|
|
15354
|
-
var
|
|
15595
|
+
var path17 = __toESM(require("path"));
|
|
15596
|
+
var os18 = __toESM(require("os"));
|
|
15355
15597
|
var import_child_process9 = require("child_process");
|
|
15356
15598
|
var import_os3 = require("os");
|
|
15357
|
-
var ARCHIVE_PATH =
|
|
15599
|
+
var ARCHIVE_PATH = path17.join(os18.homedir(), ".adhdev", "version-history.json");
|
|
15358
15600
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
15359
15601
|
var VersionArchive = class {
|
|
15360
15602
|
history = {};
|
|
@@ -15401,7 +15643,7 @@ var VersionArchive = class {
|
|
|
15401
15643
|
}
|
|
15402
15644
|
save() {
|
|
15403
15645
|
try {
|
|
15404
|
-
fs10.mkdirSync(
|
|
15646
|
+
fs10.mkdirSync(path17.dirname(ARCHIVE_PATH), { recursive: true });
|
|
15405
15647
|
fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
15406
15648
|
} catch {
|
|
15407
15649
|
}
|
|
@@ -15427,6 +15669,22 @@ function parseVersion2(raw) {
|
|
|
15427
15669
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
15428
15670
|
return match ? match[1] : raw.split("\n")[0].substring(0, 100);
|
|
15429
15671
|
}
|
|
15672
|
+
function getPlatformVersionCommand(versionCommand, currentOs) {
|
|
15673
|
+
if (!versionCommand) return void 0;
|
|
15674
|
+
if (typeof versionCommand === "string") {
|
|
15675
|
+
const trimmed = versionCommand.trim();
|
|
15676
|
+
return trimmed || void 0;
|
|
15677
|
+
}
|
|
15678
|
+
const platformValue = versionCommand[currentOs];
|
|
15679
|
+
if (typeof platformValue === "string" && platformValue.trim()) {
|
|
15680
|
+
return platformValue.trim();
|
|
15681
|
+
}
|
|
15682
|
+
const defaultValue = versionCommand.default;
|
|
15683
|
+
if (typeof defaultValue === "string" && defaultValue.trim()) {
|
|
15684
|
+
return defaultValue.trim();
|
|
15685
|
+
}
|
|
15686
|
+
return void 0;
|
|
15687
|
+
}
|
|
15430
15688
|
function getVersion(binary, versionCommand) {
|
|
15431
15689
|
if (versionCommand) {
|
|
15432
15690
|
const raw = runCommand(versionCommand);
|
|
@@ -15441,8 +15699,8 @@ function getVersion(binary, versionCommand) {
|
|
|
15441
15699
|
function checkPathExists2(paths) {
|
|
15442
15700
|
for (const p of paths) {
|
|
15443
15701
|
if (p.includes("*")) {
|
|
15444
|
-
const home =
|
|
15445
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
15702
|
+
const home = os18.homedir();
|
|
15703
|
+
const resolved = p.replace(/\*/g, home.split(path17.sep).pop() || "");
|
|
15446
15704
|
if (fs10.existsSync(resolved)) return resolved;
|
|
15447
15705
|
} else {
|
|
15448
15706
|
if (fs10.existsSync(p)) return p;
|
|
@@ -15452,7 +15710,7 @@ function checkPathExists2(paths) {
|
|
|
15452
15710
|
}
|
|
15453
15711
|
function getMacAppVersion(appPath) {
|
|
15454
15712
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
15455
|
-
const plistPath =
|
|
15713
|
+
const plistPath = path17.join(appPath, "Contents", "Info.plist");
|
|
15456
15714
|
if (!fs10.existsSync(plistPath)) return null;
|
|
15457
15715
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
15458
15716
|
return raw || null;
|
|
@@ -15471,15 +15729,14 @@ async function detectAllVersions(loader, archive) {
|
|
|
15471
15729
|
binary: null,
|
|
15472
15730
|
detectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
15473
15731
|
};
|
|
15474
|
-
const
|
|
15475
|
-
const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[currentOs] : verCmdConfig;
|
|
15732
|
+
const versionCommand = getPlatformVersionCommand(provider.versionCommand, currentOs);
|
|
15476
15733
|
if (provider.category === "ide") {
|
|
15477
15734
|
const osPaths = provider.paths?.[currentOs] || [];
|
|
15478
15735
|
const appPath = checkPathExists2(osPaths);
|
|
15479
15736
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
15480
15737
|
let resolvedBin = cliBin;
|
|
15481
15738
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
15482
|
-
const bundled =
|
|
15739
|
+
const bundled = path17.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
15483
15740
|
if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
|
|
15484
15741
|
}
|
|
15485
15742
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -15520,7 +15777,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
15520
15777
|
// src/daemon/dev-server.ts
|
|
15521
15778
|
var http2 = __toESM(require("http"));
|
|
15522
15779
|
var fs14 = __toESM(require("fs"));
|
|
15523
|
-
var
|
|
15780
|
+
var path21 = __toESM(require("path"));
|
|
15524
15781
|
|
|
15525
15782
|
// src/daemon/scaffold-template.ts
|
|
15526
15783
|
function generateFiles(type, name, category, opts = {}) {
|
|
@@ -15856,7 +16113,7 @@ init_logger();
|
|
|
15856
16113
|
|
|
15857
16114
|
// src/daemon/dev-cdp-handlers.ts
|
|
15858
16115
|
var fs11 = __toESM(require("fs"));
|
|
15859
|
-
var
|
|
16116
|
+
var path18 = __toESM(require("path"));
|
|
15860
16117
|
init_logger();
|
|
15861
16118
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
15862
16119
|
const body = await ctx.readBody(req);
|
|
@@ -16035,17 +16292,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
16035
16292
|
return;
|
|
16036
16293
|
}
|
|
16037
16294
|
let scriptsPath = "";
|
|
16038
|
-
const directScripts =
|
|
16295
|
+
const directScripts = path18.join(dir, "scripts.js");
|
|
16039
16296
|
if (fs11.existsSync(directScripts)) {
|
|
16040
16297
|
scriptsPath = directScripts;
|
|
16041
16298
|
} else {
|
|
16042
|
-
const scriptsDir =
|
|
16299
|
+
const scriptsDir = path18.join(dir, "scripts");
|
|
16043
16300
|
if (fs11.existsSync(scriptsDir)) {
|
|
16044
16301
|
const versions = fs11.readdirSync(scriptsDir).filter((d) => {
|
|
16045
|
-
return fs11.statSync(
|
|
16302
|
+
return fs11.statSync(path18.join(scriptsDir, d)).isDirectory();
|
|
16046
16303
|
}).sort().reverse();
|
|
16047
16304
|
for (const ver of versions) {
|
|
16048
|
-
const p =
|
|
16305
|
+
const p = path18.join(scriptsDir, ver, "scripts.js");
|
|
16049
16306
|
if (fs11.existsSync(p)) {
|
|
16050
16307
|
scriptsPath = p;
|
|
16051
16308
|
break;
|
|
@@ -16864,7 +17121,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
16864
17121
|
|
|
16865
17122
|
// src/daemon/dev-cli-debug.ts
|
|
16866
17123
|
var fs12 = __toESM(require("fs"));
|
|
16867
|
-
var
|
|
17124
|
+
var path19 = __toESM(require("path"));
|
|
16868
17125
|
function slugifyFixtureName(value) {
|
|
16869
17126
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
16870
17127
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -16874,11 +17131,11 @@ function getCliFixtureDir(ctx, type) {
|
|
|
16874
17131
|
if (!providerDir) {
|
|
16875
17132
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
16876
17133
|
}
|
|
16877
|
-
return
|
|
17134
|
+
return path19.join(providerDir, "fixtures");
|
|
16878
17135
|
}
|
|
16879
17136
|
function readCliFixture(ctx, type, name) {
|
|
16880
17137
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
16881
|
-
const filePath =
|
|
17138
|
+
const filePath = path19.join(fixtureDir, `${name}.json`);
|
|
16882
17139
|
if (!fs12.existsSync(filePath)) {
|
|
16883
17140
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
16884
17141
|
}
|
|
@@ -17004,6 +17261,15 @@ function validateCliFixtureResult(result, assertions) {
|
|
|
17004
17261
|
}
|
|
17005
17262
|
return failures;
|
|
17006
17263
|
}
|
|
17264
|
+
function isCliTargetState(state) {
|
|
17265
|
+
return state.category === "cli" || state.category === "acp";
|
|
17266
|
+
}
|
|
17267
|
+
function getCliAdapterFromInstance(instance) {
|
|
17268
|
+
if (!instance) return null;
|
|
17269
|
+
const candidate = instance;
|
|
17270
|
+
if (typeof candidate.getAdapter === "function") return candidate.getAdapter();
|
|
17271
|
+
return candidate.adapter || null;
|
|
17272
|
+
}
|
|
17007
17273
|
function getCliProviderResolutionMeta(ctx, type, adapter) {
|
|
17008
17274
|
const adapterMeta = typeof adapter?.getProviderResolutionMeta === "function" ? adapter.getProviderResolutionMeta() : adapter?.getDebugState?.()?.providerResolution || null;
|
|
17009
17275
|
const resolvedProvider = ctx.providerLoader.resolve(type);
|
|
@@ -17021,7 +17287,7 @@ function getCliProviderResolutionMeta(ctx, type, adapter) {
|
|
|
17021
17287
|
}
|
|
17022
17288
|
function findCliTarget(ctx, type, instanceId) {
|
|
17023
17289
|
if (!ctx.instanceManager) return null;
|
|
17024
|
-
const cliStates = ctx.instanceManager.collectAllStates().filter(
|
|
17290
|
+
const cliStates = ctx.instanceManager.collectAllStates().filter(isCliTargetState);
|
|
17025
17291
|
if (instanceId) return cliStates.find((s) => s.instanceId === instanceId) || null;
|
|
17026
17292
|
if (!type) return cliStates[cliStates.length - 1] || null;
|
|
17027
17293
|
const matches = cliStates.filter((s) => s.type === type);
|
|
@@ -17033,7 +17299,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
|
|
|
17033
17299
|
if (!target) return null;
|
|
17034
17300
|
const instance = ctx.instanceManager.getInstance(target.instanceId);
|
|
17035
17301
|
if (!instance) return null;
|
|
17036
|
-
const adapter = instance
|
|
17302
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17037
17303
|
if (!adapter) return null;
|
|
17038
17304
|
return { target, instance, adapter };
|
|
17039
17305
|
}
|
|
@@ -17508,7 +17774,7 @@ async function handleCliDebug(ctx, type, _req, res) {
|
|
|
17508
17774
|
return;
|
|
17509
17775
|
}
|
|
17510
17776
|
try {
|
|
17511
|
-
const adapter = instance
|
|
17777
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17512
17778
|
if (adapter && typeof adapter.getDebugState === "function") {
|
|
17513
17779
|
const debugState = adapter.getDebugState();
|
|
17514
17780
|
ctx.json(res, 200, {
|
|
@@ -17555,7 +17821,7 @@ async function handleCliTrace(ctx, type, req, res) {
|
|
|
17555
17821
|
return;
|
|
17556
17822
|
}
|
|
17557
17823
|
try {
|
|
17558
|
-
const adapter = instance
|
|
17824
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17559
17825
|
const url = new URL(req.url || "/", "http://127.0.0.1");
|
|
17560
17826
|
const limit = parseInt(url.searchParams.get("limit") || "120", 10);
|
|
17561
17827
|
if (adapter && typeof adapter.getTraceState === "function") {
|
|
@@ -17637,7 +17903,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
17637
17903
|
},
|
|
17638
17904
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
17639
17905
|
};
|
|
17640
|
-
const filePath =
|
|
17906
|
+
const filePath = path19.join(fixtureDir, `${name}.json`);
|
|
17641
17907
|
fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
17642
17908
|
ctx.json(res, 200, {
|
|
17643
17909
|
saved: true,
|
|
@@ -17661,7 +17927,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
|
|
|
17661
17927
|
return;
|
|
17662
17928
|
}
|
|
17663
17929
|
const fixtures = fs12.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
17664
|
-
const fullPath =
|
|
17930
|
+
const fullPath = path19.join(fixtureDir, file);
|
|
17665
17931
|
try {
|
|
17666
17932
|
const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
|
|
17667
17933
|
return {
|
|
@@ -17741,7 +18007,7 @@ async function handleCliResolve(ctx, req, res) {
|
|
|
17741
18007
|
return;
|
|
17742
18008
|
}
|
|
17743
18009
|
const instance = ctx.instanceManager.getInstance(target.instanceId);
|
|
17744
|
-
const adapter = instance
|
|
18010
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17745
18011
|
if (!adapter) {
|
|
17746
18012
|
ctx.json(res, 404, { error: `Adapter not found for instance: ${target.instanceId}` });
|
|
17747
18013
|
return;
|
|
@@ -17778,7 +18044,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
17778
18044
|
return;
|
|
17779
18045
|
}
|
|
17780
18046
|
const instance = ctx.instanceManager.getInstance(target.instanceId);
|
|
17781
|
-
const adapter = instance
|
|
18047
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17782
18048
|
if (!adapter) {
|
|
17783
18049
|
ctx.json(res, 404, { error: `Adapter not found for instance: ${target.instanceId}` });
|
|
17784
18050
|
return;
|
|
@@ -17797,11 +18063,11 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
17797
18063
|
|
|
17798
18064
|
// src/daemon/dev-auto-implement.ts
|
|
17799
18065
|
var fs13 = __toESM(require("fs"));
|
|
17800
|
-
var
|
|
17801
|
-
var
|
|
18066
|
+
var path20 = __toESM(require("path"));
|
|
18067
|
+
var os19 = __toESM(require("os"));
|
|
17802
18068
|
function getAutoImplPid(ctx) {
|
|
17803
|
-
const
|
|
17804
|
-
return
|
|
18069
|
+
const pid = ctx.autoImplProcess?.pid;
|
|
18070
|
+
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
17805
18071
|
}
|
|
17806
18072
|
function isPidAlive(pid) {
|
|
17807
18073
|
try {
|
|
@@ -17819,6 +18085,13 @@ function clearStaleAutoImplState(ctx, reason) {
|
|
|
17819
18085
|
ctx.autoImplProcess = null;
|
|
17820
18086
|
ctx.autoImplStatus.running = false;
|
|
17821
18087
|
}
|
|
18088
|
+
function tryKillAutoImplProcess(processRef, signal) {
|
|
18089
|
+
if (!processRef) return;
|
|
18090
|
+
try {
|
|
18091
|
+
processRef.kill(signal);
|
|
18092
|
+
} catch {
|
|
18093
|
+
}
|
|
18094
|
+
}
|
|
17822
18095
|
function getDefaultAutoImplReference(ctx, category, type) {
|
|
17823
18096
|
if (category === "cli") {
|
|
17824
18097
|
return type === "codex-cli" ? "claude-cli" : "codex-cli";
|
|
@@ -17837,22 +18110,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
17837
18110
|
if (!fs13.existsSync(scriptsDir)) return null;
|
|
17838
18111
|
const versions = fs13.readdirSync(scriptsDir).filter((d) => {
|
|
17839
18112
|
try {
|
|
17840
|
-
return fs13.statSync(
|
|
18113
|
+
return fs13.statSync(path20.join(scriptsDir, d)).isDirectory();
|
|
17841
18114
|
} catch {
|
|
17842
18115
|
return false;
|
|
17843
18116
|
}
|
|
17844
18117
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
17845
18118
|
if (versions.length === 0) return null;
|
|
17846
|
-
return
|
|
18119
|
+
return path20.join(scriptsDir, versions[0]);
|
|
17847
18120
|
}
|
|
17848
18121
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
17849
|
-
const canonicalUserDir =
|
|
17850
|
-
const desiredDir = requestedDir ?
|
|
17851
|
-
const upstreamRoot =
|
|
17852
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
18122
|
+
const canonicalUserDir = path20.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
18123
|
+
const desiredDir = requestedDir ? path20.resolve(requestedDir) : canonicalUserDir;
|
|
18124
|
+
const upstreamRoot = path20.resolve(ctx.providerLoader.getUpstreamDir());
|
|
18125
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path20.sep}`)) {
|
|
17853
18126
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
17854
18127
|
}
|
|
17855
|
-
if (
|
|
18128
|
+
if (path20.basename(desiredDir) !== type) {
|
|
17856
18129
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
17857
18130
|
}
|
|
17858
18131
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -17860,11 +18133,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
17860
18133
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
17861
18134
|
}
|
|
17862
18135
|
if (!fs13.existsSync(desiredDir)) {
|
|
17863
|
-
fs13.mkdirSync(
|
|
18136
|
+
fs13.mkdirSync(path20.dirname(desiredDir), { recursive: true });
|
|
17864
18137
|
fs13.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
17865
18138
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
17866
18139
|
}
|
|
17867
|
-
const providerJson =
|
|
18140
|
+
const providerJson = path20.join(desiredDir, "provider.json");
|
|
17868
18141
|
if (!fs13.existsSync(providerJson)) {
|
|
17869
18142
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
17870
18143
|
}
|
|
@@ -17887,13 +18160,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
17887
18160
|
const refDir = ctx.findProviderDir(referenceType);
|
|
17888
18161
|
if (!refDir || !fs13.existsSync(refDir)) return {};
|
|
17889
18162
|
const referenceScripts = {};
|
|
17890
|
-
const scriptsDir =
|
|
18163
|
+
const scriptsDir = path20.join(refDir, "scripts");
|
|
17891
18164
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
17892
18165
|
if (!latestDir) return referenceScripts;
|
|
17893
18166
|
for (const file of fs13.readdirSync(latestDir)) {
|
|
17894
18167
|
if (!file.endsWith(".js")) continue;
|
|
17895
18168
|
try {
|
|
17896
|
-
referenceScripts[file] = fs13.readFileSync(
|
|
18169
|
+
referenceScripts[file] = fs13.readFileSync(path20.join(latestDir, file), "utf-8");
|
|
17897
18170
|
} catch {
|
|
17898
18171
|
}
|
|
17899
18172
|
}
|
|
@@ -18001,9 +18274,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18001
18274
|
});
|
|
18002
18275
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
18003
18276
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
18004
|
-
const tmpDir =
|
|
18277
|
+
const tmpDir = path20.join(os19.tmpdir(), "adhdev-autoimpl");
|
|
18005
18278
|
if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
|
|
18006
|
-
const promptFile =
|
|
18279
|
+
const promptFile = path20.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
18007
18280
|
fs13.writeFileSync(promptFile, prompt, "utf-8");
|
|
18008
18281
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
18009
18282
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -18155,7 +18428,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18155
18428
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
18156
18429
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
18157
18430
|
let shellCmd;
|
|
18158
|
-
const isWin =
|
|
18431
|
+
const isWin = os19.platform() === "win32";
|
|
18159
18432
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
18160
18433
|
if (command === "claude") {
|
|
18161
18434
|
const args = [...baseArgs, "--dangerously-skip-permissions"];
|
|
@@ -18199,7 +18472,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18199
18472
|
try {
|
|
18200
18473
|
const pty = require("node-pty");
|
|
18201
18474
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
18202
|
-
const isWin2 =
|
|
18475
|
+
const isWin2 = os19.platform() === "win32";
|
|
18203
18476
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
18204
18477
|
name: "xterm-256color",
|
|
18205
18478
|
cols: 120,
|
|
@@ -18238,10 +18511,12 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18238
18511
|
let autoStopTimer = null;
|
|
18239
18512
|
let autoStopIssued = false;
|
|
18240
18513
|
try {
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18514
|
+
if (agentProvider?.category === "cli") {
|
|
18515
|
+
const { normalizeCliProviderForRuntime: normalizeCliProviderForRuntime2 } = await Promise.resolve().then(() => (init_provider_cli_adapter(), provider_cli_adapter_exports));
|
|
18516
|
+
const normalized = normalizeCliProviderForRuntime2(agentProvider);
|
|
18517
|
+
approvalPatterns = normalized.patterns.approval;
|
|
18518
|
+
approvalKeys = agentProvider.approvalKeys || { 0: "y\r", 1: "a\r" };
|
|
18519
|
+
}
|
|
18245
18520
|
} catch (err) {
|
|
18246
18521
|
ctx.log(`Failed to load approval patterns: ${err.message}`);
|
|
18247
18522
|
}
|
|
@@ -18256,10 +18531,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18256
18531
|
[\u{1F916} ADHDev Pipeline] Completion token detected. Proceeding...
|
|
18257
18532
|
`, stream: "stdout" } });
|
|
18258
18533
|
approvalBuffer = "";
|
|
18259
|
-
|
|
18260
|
-
ctx.autoImplProcess.kill("SIGINT");
|
|
18261
|
-
} catch {
|
|
18262
|
-
}
|
|
18534
|
+
tryKillAutoImplProcess(ctx.autoImplProcess, "SIGINT");
|
|
18263
18535
|
return;
|
|
18264
18536
|
}
|
|
18265
18537
|
if (Date.now() - lastApprovalTime < 2e3) return;
|
|
@@ -18296,10 +18568,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18296
18568
|
stream: "stdout"
|
|
18297
18569
|
}
|
|
18298
18570
|
});
|
|
18299
|
-
|
|
18300
|
-
ctx.autoImplProcess.kill("SIGINT");
|
|
18301
|
-
} catch {
|
|
18302
|
-
}
|
|
18571
|
+
tryKillAutoImplProcess(ctx.autoImplProcess, "SIGINT");
|
|
18303
18572
|
}, 3e4);
|
|
18304
18573
|
};
|
|
18305
18574
|
const finalizeCliAutoImpl = async (code) => {
|
|
@@ -18430,7 +18699,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18430
18699
|
setMode: "set_mode.js"
|
|
18431
18700
|
};
|
|
18432
18701
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
18433
|
-
const scriptsDir =
|
|
18702
|
+
const scriptsDir = path20.join(providerDir, "scripts");
|
|
18434
18703
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
18435
18704
|
if (latestScriptsDir) {
|
|
18436
18705
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -18441,7 +18710,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18441
18710
|
for (const file of fs13.readdirSync(latestScriptsDir)) {
|
|
18442
18711
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
18443
18712
|
try {
|
|
18444
|
-
const content = fs13.readFileSync(
|
|
18713
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18445
18714
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
18446
18715
|
lines.push("```javascript");
|
|
18447
18716
|
lines.push(content);
|
|
@@ -18458,7 +18727,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18458
18727
|
lines.push("");
|
|
18459
18728
|
for (const file of refFiles) {
|
|
18460
18729
|
try {
|
|
18461
|
-
const content = fs13.readFileSync(
|
|
18730
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18462
18731
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
18463
18732
|
lines.push("```javascript");
|
|
18464
18733
|
lines.push(content);
|
|
@@ -18499,10 +18768,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18499
18768
|
lines.push("");
|
|
18500
18769
|
}
|
|
18501
18770
|
}
|
|
18502
|
-
const docsDir =
|
|
18771
|
+
const docsDir = path20.join(providerDir, "../../docs");
|
|
18503
18772
|
const loadGuide = (name) => {
|
|
18504
18773
|
try {
|
|
18505
|
-
const p =
|
|
18774
|
+
const p = path20.join(docsDir, name);
|
|
18506
18775
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
18507
18776
|
} catch {
|
|
18508
18777
|
}
|
|
@@ -18737,7 +19006,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18737
19006
|
parseApproval: "parse_approval.js"
|
|
18738
19007
|
};
|
|
18739
19008
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
18740
|
-
const scriptsDir =
|
|
19009
|
+
const scriptsDir = path20.join(providerDir, "scripts");
|
|
18741
19010
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
18742
19011
|
if (latestScriptsDir) {
|
|
18743
19012
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -18749,7 +19018,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18749
19018
|
if (!file.endsWith(".js")) continue;
|
|
18750
19019
|
if (!targetFileNames.has(file)) continue;
|
|
18751
19020
|
try {
|
|
18752
|
-
const content = fs13.readFileSync(
|
|
19021
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18753
19022
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
18754
19023
|
lines.push("```javascript");
|
|
18755
19024
|
lines.push(content);
|
|
@@ -18765,7 +19034,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18765
19034
|
lines.push("");
|
|
18766
19035
|
for (const file of refFiles) {
|
|
18767
19036
|
try {
|
|
18768
|
-
const content = fs13.readFileSync(
|
|
19037
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18769
19038
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
18770
19039
|
lines.push("```javascript");
|
|
18771
19040
|
lines.push(content);
|
|
@@ -18798,10 +19067,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18798
19067
|
lines.push("");
|
|
18799
19068
|
}
|
|
18800
19069
|
}
|
|
18801
|
-
const docsDir =
|
|
19070
|
+
const docsDir = path20.join(providerDir, "../../docs");
|
|
18802
19071
|
const loadGuide = (name) => {
|
|
18803
19072
|
try {
|
|
18804
|
-
const p =
|
|
19073
|
+
const p = path20.join(docsDir, name);
|
|
18805
19074
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
18806
19075
|
} catch {
|
|
18807
19076
|
}
|
|
@@ -19116,6 +19385,38 @@ data: ${JSON.stringify(msg.data)}
|
|
|
19116
19385
|
|
|
19117
19386
|
// src/daemon/dev-server.ts
|
|
19118
19387
|
var DEV_SERVER_PORT = 19280;
|
|
19388
|
+
function getScriptNames(scripts) {
|
|
19389
|
+
if (!scripts) return [];
|
|
19390
|
+
return Object.entries(scripts).filter(([, value]) => typeof value === "function").map(([name]) => name);
|
|
19391
|
+
}
|
|
19392
|
+
function toProviderListEntry(provider) {
|
|
19393
|
+
const base = {
|
|
19394
|
+
type: provider.type,
|
|
19395
|
+
name: provider.name,
|
|
19396
|
+
category: provider.category,
|
|
19397
|
+
icon: provider.icon || null,
|
|
19398
|
+
displayName: provider.displayName || provider.name
|
|
19399
|
+
};
|
|
19400
|
+
if (provider.category === "ide" || provider.category === "extension") {
|
|
19401
|
+
base.scripts = getScriptNames(provider.scripts);
|
|
19402
|
+
base.inputMethod = provider.inputMethod || null;
|
|
19403
|
+
base.inputSelector = provider.inputSelector || null;
|
|
19404
|
+
base.extensionId = provider.extensionId || null;
|
|
19405
|
+
base.cdpPorts = provider.cdpPorts || [];
|
|
19406
|
+
}
|
|
19407
|
+
if (provider.category === "acp") {
|
|
19408
|
+
base.spawn = provider.spawn || null;
|
|
19409
|
+
base.auth = provider.auth || null;
|
|
19410
|
+
base.install = provider.install || null;
|
|
19411
|
+
base.hasSettings = !!provider.settings;
|
|
19412
|
+
base.settingsCount = provider.settings ? Object.keys(provider.settings).length : 0;
|
|
19413
|
+
}
|
|
19414
|
+
if (provider.category === "cli") {
|
|
19415
|
+
base.spawn = provider.spawn || null;
|
|
19416
|
+
base.install = provider.install || null;
|
|
19417
|
+
}
|
|
19418
|
+
return base;
|
|
19419
|
+
}
|
|
19119
19420
|
var DevServer = class _DevServer {
|
|
19120
19421
|
server = null;
|
|
19121
19422
|
providerLoader;
|
|
@@ -19212,8 +19513,8 @@ var DevServer = class _DevServer {
|
|
|
19212
19513
|
}
|
|
19213
19514
|
getEndpointList() {
|
|
19214
19515
|
return this.routes.map((r) => {
|
|
19215
|
-
const
|
|
19216
|
-
return `${r.method.padEnd(5)} ${
|
|
19516
|
+
const path22 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
19517
|
+
return `${r.method.padEnd(5)} ${path22}`;
|
|
19217
19518
|
});
|
|
19218
19519
|
}
|
|
19219
19520
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -19265,34 +19566,7 @@ var DevServer = class _DevServer {
|
|
|
19265
19566
|
}
|
|
19266
19567
|
// ─── Handlers ───
|
|
19267
19568
|
async handleListProviders(_req, res) {
|
|
19268
|
-
const providers = this.providerLoader.getAll().map(
|
|
19269
|
-
const base = {
|
|
19270
|
-
type: p.type,
|
|
19271
|
-
name: p.name,
|
|
19272
|
-
category: p.category,
|
|
19273
|
-
icon: p.icon || null,
|
|
19274
|
-
displayName: p.displayName || p.name
|
|
19275
|
-
};
|
|
19276
|
-
if (p.category === "ide" || p.category === "extension") {
|
|
19277
|
-
base.scripts = p.scripts ? Object.keys(p.scripts).filter((k) => typeof p.scripts[k] === "function") : [];
|
|
19278
|
-
base.inputMethod = p.inputMethod || null;
|
|
19279
|
-
base.inputSelector = p.inputSelector || null;
|
|
19280
|
-
base.extensionId = p.extensionId || null;
|
|
19281
|
-
base.cdpPorts = p.cdpPorts || [];
|
|
19282
|
-
}
|
|
19283
|
-
if (p.category === "acp") {
|
|
19284
|
-
base.spawn = p.spawn || null;
|
|
19285
|
-
base.auth = p.auth || null;
|
|
19286
|
-
base.install = p.install || null;
|
|
19287
|
-
base.hasSettings = !!p.settings;
|
|
19288
|
-
base.settingsCount = p.settings ? Object.keys(p.settings).length : 0;
|
|
19289
|
-
}
|
|
19290
|
-
if (p.category === "cli") {
|
|
19291
|
-
base.spawn = p.spawn || null;
|
|
19292
|
-
base.install = p.install || null;
|
|
19293
|
-
}
|
|
19294
|
-
return base;
|
|
19295
|
-
});
|
|
19569
|
+
const providers = this.providerLoader.getAll().map(toProviderListEntry);
|
|
19296
19570
|
this.json(res, 200, { providers, count: providers.length });
|
|
19297
19571
|
}
|
|
19298
19572
|
async handleProviderConfig(type, _req, res) {
|
|
@@ -19484,7 +19758,7 @@ var DevServer = class _DevServer {
|
|
|
19484
19758
|
}));
|
|
19485
19759
|
for (const cdp of this.cdpManagers.values()) {
|
|
19486
19760
|
if (!cdp.isConnected) {
|
|
19487
|
-
cdp.
|
|
19761
|
+
cdp.clearTargetId();
|
|
19488
19762
|
}
|
|
19489
19763
|
}
|
|
19490
19764
|
this.json(res, 200, { reloaded: true, providers });
|
|
@@ -19495,12 +19769,12 @@ var DevServer = class _DevServer {
|
|
|
19495
19769
|
// ─── DevConsole SPA ───
|
|
19496
19770
|
getConsoleDistDir() {
|
|
19497
19771
|
const candidates = [
|
|
19498
|
-
|
|
19499
|
-
|
|
19500
|
-
|
|
19772
|
+
path21.resolve(__dirname, "../../web-devconsole/dist"),
|
|
19773
|
+
path21.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
19774
|
+
path21.join(process.cwd(), "packages/web-devconsole/dist")
|
|
19501
19775
|
];
|
|
19502
19776
|
for (const dir of candidates) {
|
|
19503
|
-
if (fs14.existsSync(
|
|
19777
|
+
if (fs14.existsSync(path21.join(dir, "index.html"))) return dir;
|
|
19504
19778
|
}
|
|
19505
19779
|
return null;
|
|
19506
19780
|
}
|
|
@@ -19510,7 +19784,7 @@ var DevServer = class _DevServer {
|
|
|
19510
19784
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
19511
19785
|
return;
|
|
19512
19786
|
}
|
|
19513
|
-
const htmlPath =
|
|
19787
|
+
const htmlPath = path21.join(distDir, "index.html");
|
|
19514
19788
|
try {
|
|
19515
19789
|
const html = fs14.readFileSync(htmlPath, "utf-8");
|
|
19516
19790
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -19535,15 +19809,15 @@ var DevServer = class _DevServer {
|
|
|
19535
19809
|
this.json(res, 404, { error: "Not found" });
|
|
19536
19810
|
return;
|
|
19537
19811
|
}
|
|
19538
|
-
const safePath =
|
|
19539
|
-
const filePath =
|
|
19812
|
+
const safePath = path21.normalize(pathname).replace(/^\.\.\//, "");
|
|
19813
|
+
const filePath = path21.join(distDir, safePath);
|
|
19540
19814
|
if (!filePath.startsWith(distDir)) {
|
|
19541
19815
|
this.json(res, 403, { error: "Forbidden" });
|
|
19542
19816
|
return;
|
|
19543
19817
|
}
|
|
19544
19818
|
try {
|
|
19545
19819
|
const content = fs14.readFileSync(filePath);
|
|
19546
|
-
const ext =
|
|
19820
|
+
const ext = path21.extname(filePath);
|
|
19547
19821
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
19548
19822
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
19549
19823
|
res.end(content);
|
|
@@ -19656,9 +19930,9 @@ var DevServer = class _DevServer {
|
|
|
19656
19930
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
19657
19931
|
if (entry.isDirectory()) {
|
|
19658
19932
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
19659
|
-
scan(
|
|
19933
|
+
scan(path21.join(d, entry.name), rel);
|
|
19660
19934
|
} else {
|
|
19661
|
-
const stat = fs14.statSync(
|
|
19935
|
+
const stat = fs14.statSync(path21.join(d, entry.name));
|
|
19662
19936
|
files.push({ path: rel, size: stat.size, type: "file" });
|
|
19663
19937
|
}
|
|
19664
19938
|
}
|
|
@@ -19681,7 +19955,7 @@ var DevServer = class _DevServer {
|
|
|
19681
19955
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
19682
19956
|
return;
|
|
19683
19957
|
}
|
|
19684
|
-
const fullPath =
|
|
19958
|
+
const fullPath = path21.resolve(dir, path21.normalize(filePath));
|
|
19685
19959
|
if (!fullPath.startsWith(dir)) {
|
|
19686
19960
|
this.json(res, 403, { error: "Forbidden" });
|
|
19687
19961
|
return;
|
|
@@ -19706,14 +19980,14 @@ var DevServer = class _DevServer {
|
|
|
19706
19980
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
19707
19981
|
return;
|
|
19708
19982
|
}
|
|
19709
|
-
const fullPath =
|
|
19983
|
+
const fullPath = path21.resolve(dir, path21.normalize(filePath));
|
|
19710
19984
|
if (!fullPath.startsWith(dir)) {
|
|
19711
19985
|
this.json(res, 403, { error: "Forbidden" });
|
|
19712
19986
|
return;
|
|
19713
19987
|
}
|
|
19714
19988
|
try {
|
|
19715
19989
|
if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
|
|
19716
|
-
fs14.mkdirSync(
|
|
19990
|
+
fs14.mkdirSync(path21.dirname(fullPath), { recursive: true });
|
|
19717
19991
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
19718
19992
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
19719
19993
|
this.providerLoader.reload();
|
|
@@ -19730,7 +20004,7 @@ var DevServer = class _DevServer {
|
|
|
19730
20004
|
return;
|
|
19731
20005
|
}
|
|
19732
20006
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
19733
|
-
const p =
|
|
20007
|
+
const p = path21.join(dir, name);
|
|
19734
20008
|
if (fs14.existsSync(p)) {
|
|
19735
20009
|
const source = fs14.readFileSync(p, "utf-8");
|
|
19736
20010
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -19751,8 +20025,8 @@ var DevServer = class _DevServer {
|
|
|
19751
20025
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
19752
20026
|
return;
|
|
19753
20027
|
}
|
|
19754
|
-
const target = fs14.existsSync(
|
|
19755
|
-
const targetPath =
|
|
20028
|
+
const target = fs14.existsSync(path21.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
20029
|
+
const targetPath = path21.join(dir, target);
|
|
19756
20030
|
try {
|
|
19757
20031
|
if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
|
|
19758
20032
|
fs14.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -19912,7 +20186,7 @@ var DevServer = class _DevServer {
|
|
|
19912
20186
|
}
|
|
19913
20187
|
let targetDir;
|
|
19914
20188
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
19915
|
-
const jsonPath =
|
|
20189
|
+
const jsonPath = path21.join(targetDir, "provider.json");
|
|
19916
20190
|
if (fs14.existsSync(jsonPath)) {
|
|
19917
20191
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
19918
20192
|
return;
|
|
@@ -19924,8 +20198,8 @@ var DevServer = class _DevServer {
|
|
|
19924
20198
|
const createdFiles = ["provider.json"];
|
|
19925
20199
|
if (result.files) {
|
|
19926
20200
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
19927
|
-
const fullPath =
|
|
19928
|
-
fs14.mkdirSync(
|
|
20201
|
+
const fullPath = path21.join(targetDir, relPath);
|
|
20202
|
+
fs14.mkdirSync(path21.dirname(fullPath), { recursive: true });
|
|
19929
20203
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
19930
20204
|
createdFiles.push(relPath);
|
|
19931
20205
|
}
|
|
@@ -19978,22 +20252,22 @@ var DevServer = class _DevServer {
|
|
|
19978
20252
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
19979
20253
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
19980
20254
|
try {
|
|
19981
|
-
return fs14.statSync(
|
|
20255
|
+
return fs14.statSync(path21.join(scriptsDir, d)).isDirectory();
|
|
19982
20256
|
} catch {
|
|
19983
20257
|
return false;
|
|
19984
20258
|
}
|
|
19985
20259
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
19986
20260
|
if (versions.length === 0) return null;
|
|
19987
|
-
return
|
|
20261
|
+
return path21.join(scriptsDir, versions[0]);
|
|
19988
20262
|
}
|
|
19989
20263
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
19990
|
-
const canonicalUserDir =
|
|
19991
|
-
const desiredDir = requestedDir ?
|
|
19992
|
-
const upstreamRoot =
|
|
19993
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
20264
|
+
const canonicalUserDir = path21.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
20265
|
+
const desiredDir = requestedDir ? path21.resolve(requestedDir) : canonicalUserDir;
|
|
20266
|
+
const upstreamRoot = path21.resolve(this.providerLoader.getUpstreamDir());
|
|
20267
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path21.sep}`)) {
|
|
19994
20268
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
19995
20269
|
}
|
|
19996
|
-
if (
|
|
20270
|
+
if (path21.basename(desiredDir) !== type) {
|
|
19997
20271
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
19998
20272
|
}
|
|
19999
20273
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -20001,11 +20275,11 @@ var DevServer = class _DevServer {
|
|
|
20001
20275
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
20002
20276
|
}
|
|
20003
20277
|
if (!fs14.existsSync(desiredDir)) {
|
|
20004
|
-
fs14.mkdirSync(
|
|
20278
|
+
fs14.mkdirSync(path21.dirname(desiredDir), { recursive: true });
|
|
20005
20279
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
20006
20280
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
20007
20281
|
}
|
|
20008
|
-
const providerJson =
|
|
20282
|
+
const providerJson = path21.join(desiredDir, "provider.json");
|
|
20009
20283
|
if (!fs14.existsSync(providerJson)) {
|
|
20010
20284
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
20011
20285
|
}
|
|
@@ -20053,7 +20327,7 @@ var DevServer = class _DevServer {
|
|
|
20053
20327
|
setMode: "set_mode.js"
|
|
20054
20328
|
};
|
|
20055
20329
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
20056
|
-
const scriptsDir =
|
|
20330
|
+
const scriptsDir = path21.join(providerDir, "scripts");
|
|
20057
20331
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
20058
20332
|
if (latestScriptsDir) {
|
|
20059
20333
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -20064,7 +20338,7 @@ var DevServer = class _DevServer {
|
|
|
20064
20338
|
for (const file of fs14.readdirSync(latestScriptsDir)) {
|
|
20065
20339
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
20066
20340
|
try {
|
|
20067
|
-
const content = fs14.readFileSync(
|
|
20341
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
20068
20342
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
20069
20343
|
lines.push("```javascript");
|
|
20070
20344
|
lines.push(content);
|
|
@@ -20081,7 +20355,7 @@ var DevServer = class _DevServer {
|
|
|
20081
20355
|
lines.push("");
|
|
20082
20356
|
for (const file of refFiles) {
|
|
20083
20357
|
try {
|
|
20084
|
-
const content = fs14.readFileSync(
|
|
20358
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
20085
20359
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
20086
20360
|
lines.push("```javascript");
|
|
20087
20361
|
lines.push(content);
|
|
@@ -20122,10 +20396,10 @@ var DevServer = class _DevServer {
|
|
|
20122
20396
|
lines.push("");
|
|
20123
20397
|
}
|
|
20124
20398
|
}
|
|
20125
|
-
const docsDir =
|
|
20399
|
+
const docsDir = path21.join(providerDir, "../../docs");
|
|
20126
20400
|
const loadGuide = (name) => {
|
|
20127
20401
|
try {
|
|
20128
|
-
const p =
|
|
20402
|
+
const p = path21.join(docsDir, name);
|
|
20129
20403
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
20130
20404
|
} catch {
|
|
20131
20405
|
}
|
|
@@ -20299,7 +20573,7 @@ var DevServer = class _DevServer {
|
|
|
20299
20573
|
parseApproval: "parse_approval.js"
|
|
20300
20574
|
};
|
|
20301
20575
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
20302
|
-
const scriptsDir =
|
|
20576
|
+
const scriptsDir = path21.join(providerDir, "scripts");
|
|
20303
20577
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
20304
20578
|
if (latestScriptsDir) {
|
|
20305
20579
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -20311,7 +20585,7 @@ var DevServer = class _DevServer {
|
|
|
20311
20585
|
if (!file.endsWith(".js")) continue;
|
|
20312
20586
|
if (!targetFileNames.has(file)) continue;
|
|
20313
20587
|
try {
|
|
20314
|
-
const content = fs14.readFileSync(
|
|
20588
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
20315
20589
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
20316
20590
|
lines.push("```javascript");
|
|
20317
20591
|
lines.push(content);
|
|
@@ -20327,7 +20601,7 @@ var DevServer = class _DevServer {
|
|
|
20327
20601
|
lines.push("");
|
|
20328
20602
|
for (const file of refFiles) {
|
|
20329
20603
|
try {
|
|
20330
|
-
const content = fs14.readFileSync(
|
|
20604
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
20331
20605
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
20332
20606
|
lines.push("```javascript");
|
|
20333
20607
|
lines.push(content);
|
|
@@ -20360,10 +20634,10 @@ var DevServer = class _DevServer {
|
|
|
20360
20634
|
lines.push("");
|
|
20361
20635
|
}
|
|
20362
20636
|
}
|
|
20363
|
-
const docsDir =
|
|
20637
|
+
const docsDir = path21.join(providerDir, "../../docs");
|
|
20364
20638
|
const loadGuide = (name) => {
|
|
20365
20639
|
try {
|
|
20366
|
-
const p =
|
|
20640
|
+
const p = path21.join(docsDir, name);
|
|
20367
20641
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
20368
20642
|
} catch {
|
|
20369
20643
|
}
|