@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.mjs
CHANGED
|
@@ -93,12 +93,10 @@ function ensureMachineId(config) {
|
|
|
93
93
|
if (isStableMachineId(config.machineId)) {
|
|
94
94
|
return { config, changed: false };
|
|
95
95
|
}
|
|
96
|
-
const legacyRegisteredMachineId = !config.registeredMachineId && config.machineSecret && config.machineId ? config.machineId : config.registeredMachineId;
|
|
97
96
|
return {
|
|
98
97
|
config: {
|
|
99
98
|
...config,
|
|
100
|
-
machineId: generateMachineId()
|
|
101
|
-
registeredMachineId: legacyRegisteredMachineId
|
|
99
|
+
machineId: generateMachineId()
|
|
102
100
|
},
|
|
103
101
|
changed: true
|
|
104
102
|
};
|
|
@@ -450,7 +448,7 @@ var init_logger = __esm({
|
|
|
450
448
|
function isModuleNotFoundError(error, ref) {
|
|
451
449
|
if (!(error instanceof Error)) return false;
|
|
452
450
|
const message = error.message || "";
|
|
453
|
-
const code = error.code;
|
|
451
|
+
const code = "code" in error ? error.code : void 0;
|
|
454
452
|
return code === "MODULE_NOT_FOUND" && message.includes(ref);
|
|
455
453
|
}
|
|
456
454
|
function normalizeBinding(mod, ref) {
|
|
@@ -795,12 +793,7 @@ var init_pty_transport = __esm({
|
|
|
795
793
|
}
|
|
796
794
|
});
|
|
797
795
|
|
|
798
|
-
// src/cli-adapters/provider-cli-
|
|
799
|
-
var provider_cli_adapter_exports = {};
|
|
800
|
-
__export(provider_cli_adapter_exports, {
|
|
801
|
-
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
802
|
-
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
803
|
-
});
|
|
796
|
+
// src/cli-adapters/provider-cli-shared.ts
|
|
804
797
|
import * as os8 from "os";
|
|
805
798
|
import * as path9 from "path";
|
|
806
799
|
import { execSync as execSync3 } from "child_process";
|
|
@@ -813,6 +806,10 @@ function stripTerminalNoise(str) {
|
|
|
813
806
|
function sanitizeTerminalText(str) {
|
|
814
807
|
return stripTerminalNoise(stripAnsi(str));
|
|
815
808
|
}
|
|
809
|
+
function listCliScriptNames(scripts) {
|
|
810
|
+
if (!scripts) return [];
|
|
811
|
+
return Object.entries(scripts).filter(([, fn]) => typeof fn === "function").map(([name]) => name);
|
|
812
|
+
}
|
|
816
813
|
function splitCliScreenLines(text) {
|
|
817
814
|
return String(text || "").replace(/\u0007/g, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => line.replace(/\s+$/, ""));
|
|
818
815
|
}
|
|
@@ -860,18 +857,6 @@ function buildCliScreenSnapshot(text) {
|
|
|
860
857
|
linesBelowPrompt: promptLineIndex >= 0 ? lines.slice(promptLineIndex + 1) : []
|
|
861
858
|
};
|
|
862
859
|
}
|
|
863
|
-
function computeTerminalQueryTail(buffer) {
|
|
864
|
-
const prefixes = ["\x1B[6n", "\x1B[?6n"];
|
|
865
|
-
const maxLength = prefixes.reduce((n, value) => Math.max(n, value.length), 0) - 1;
|
|
866
|
-
const start = Math.max(0, buffer.length - maxLength);
|
|
867
|
-
for (let i = start; i < buffer.length; i++) {
|
|
868
|
-
const suffix = buffer.slice(i);
|
|
869
|
-
if (prefixes.some((pattern) => suffix.length < pattern.length && pattern.startsWith(suffix))) {
|
|
870
|
-
return suffix;
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
return "";
|
|
874
|
-
}
|
|
875
860
|
function findBinary(name) {
|
|
876
861
|
const trimmed = String(name || "").trim();
|
|
877
862
|
if (!trimmed) return trimmed;
|
|
@@ -1021,22 +1006,302 @@ function coercePatternArray(raw) {
|
|
|
1021
1006
|
return raw.map(parsePatternEntry).filter((r) => r != null);
|
|
1022
1007
|
}
|
|
1023
1008
|
function normalizeCliProviderForRuntime(raw) {
|
|
1024
|
-
const patterns = raw
|
|
1009
|
+
const patterns = raw && typeof raw === "object" ? raw.patterns : void 0;
|
|
1025
1010
|
return {
|
|
1026
1011
|
patterns: {
|
|
1027
|
-
approval: coercePatternArray(
|
|
1012
|
+
approval: coercePatternArray(
|
|
1013
|
+
patterns && typeof patterns === "object" ? patterns.approval : void 0
|
|
1014
|
+
)
|
|
1028
1015
|
}
|
|
1029
1016
|
};
|
|
1030
1017
|
}
|
|
1031
|
-
var buildCliSpawnEnv
|
|
1018
|
+
var buildCliSpawnEnv;
|
|
1019
|
+
var init_provider_cli_shared = __esm({
|
|
1020
|
+
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
1021
|
+
"use strict";
|
|
1022
|
+
init_spawn_env();
|
|
1023
|
+
buildCliSpawnEnv = sanitizeSpawnEnv;
|
|
1024
|
+
}
|
|
1025
|
+
});
|
|
1026
|
+
|
|
1027
|
+
// src/cli-adapters/provider-cli-parse.ts
|
|
1028
|
+
function sliceFromOffset(text, start) {
|
|
1029
|
+
if (!text) return "";
|
|
1030
|
+
if (!Number.isFinite(start) || start <= 0) return text;
|
|
1031
|
+
if (start >= text.length) return "";
|
|
1032
|
+
return text.slice(start);
|
|
1033
|
+
}
|
|
1034
|
+
function hydrateCliParsedMessages(parsedMessages, options) {
|
|
1035
|
+
const { committedMessages, scope, lastOutputAt } = options;
|
|
1036
|
+
const referenceMessages = [...committedMessages];
|
|
1037
|
+
const usedReferenceIndexes = /* @__PURE__ */ new Set();
|
|
1038
|
+
const now = options.now ?? Date.now();
|
|
1039
|
+
const findReferenceTimestamp = (role, content, parsedIndex) => {
|
|
1040
|
+
const normalizedContent = normalizeComparableMessageContent(content);
|
|
1041
|
+
if (!normalizedContent) return void 0;
|
|
1042
|
+
const sameIndex = referenceMessages[parsedIndex];
|
|
1043
|
+
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && normalizeComparableMessageContent(sameIndex.content) === normalizedContent && typeof sameIndex.timestamp === "number" && Number.isFinite(sameIndex.timestamp)) {
|
|
1044
|
+
usedReferenceIndexes.add(parsedIndex);
|
|
1045
|
+
return sameIndex.timestamp;
|
|
1046
|
+
}
|
|
1047
|
+
for (let i = 0; i < referenceMessages.length; i++) {
|
|
1048
|
+
if (usedReferenceIndexes.has(i)) continue;
|
|
1049
|
+
const candidate = referenceMessages[i];
|
|
1050
|
+
if (!candidate || candidate.role !== role) continue;
|
|
1051
|
+
const candidateContent = normalizeComparableMessageContent(candidate.content);
|
|
1052
|
+
if (!candidateContent) continue;
|
|
1053
|
+
const exactMatch = candidateContent === normalizedContent;
|
|
1054
|
+
const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
|
|
1055
|
+
if (!exactMatch && !fuzzyMatch) continue;
|
|
1056
|
+
if (typeof candidate.timestamp === "number" && Number.isFinite(candidate.timestamp)) {
|
|
1057
|
+
usedReferenceIndexes.add(i);
|
|
1058
|
+
return candidate.timestamp;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
return void 0;
|
|
1062
|
+
};
|
|
1063
|
+
return parsedMessages.filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message, index) => {
|
|
1064
|
+
const role = message.role;
|
|
1065
|
+
const content = typeof message.content === "string" ? message.content : String(message.content || "");
|
|
1066
|
+
const parsedTimestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0;
|
|
1067
|
+
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(role, content, index);
|
|
1068
|
+
const fallbackTimestamp = role === "user" ? scope?.startedAt || now : lastOutputAt || scope?.startedAt || now;
|
|
1069
|
+
const timestamp = referenceTimestamp ?? fallbackTimestamp;
|
|
1070
|
+
return {
|
|
1071
|
+
...message,
|
|
1072
|
+
role,
|
|
1073
|
+
content,
|
|
1074
|
+
timestamp,
|
|
1075
|
+
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp
|
|
1076
|
+
};
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
function normalizeCliParsedMessages(parsedMessages, options) {
|
|
1080
|
+
return hydrateCliParsedMessages(parsedMessages, options).map((message) => ({
|
|
1081
|
+
role: message.role,
|
|
1082
|
+
content: message.content,
|
|
1083
|
+
timestamp: message.timestamp,
|
|
1084
|
+
receivedAt: message.receivedAt,
|
|
1085
|
+
kind: message.kind,
|
|
1086
|
+
id: message.id,
|
|
1087
|
+
index: message.index,
|
|
1088
|
+
meta: message.meta,
|
|
1089
|
+
senderName: message.senderName
|
|
1090
|
+
}));
|
|
1091
|
+
}
|
|
1092
|
+
function buildCliParseInput(options) {
|
|
1093
|
+
const {
|
|
1094
|
+
accumulatedBuffer,
|
|
1095
|
+
accumulatedRawBuffer,
|
|
1096
|
+
recentOutputBuffer,
|
|
1097
|
+
terminalScreenText,
|
|
1098
|
+
baseMessages,
|
|
1099
|
+
partialResponse,
|
|
1100
|
+
scope,
|
|
1101
|
+
runtimeSettings
|
|
1102
|
+
} = options;
|
|
1103
|
+
const buffer = scope ? sliceFromOffset(accumulatedBuffer, scope.bufferStart) || accumulatedBuffer : accumulatedBuffer;
|
|
1104
|
+
const rawBuffer = scope ? sliceFromOffset(accumulatedRawBuffer, scope.rawBufferStart) || accumulatedRawBuffer : accumulatedRawBuffer;
|
|
1105
|
+
const screenText = terminalScreenText;
|
|
1106
|
+
const recentBuffer = buffer.slice(-1e3) || recentOutputBuffer;
|
|
1107
|
+
return {
|
|
1108
|
+
buffer,
|
|
1109
|
+
rawBuffer,
|
|
1110
|
+
recentBuffer,
|
|
1111
|
+
screenText,
|
|
1112
|
+
screen: buildCliScreenSnapshot(screenText),
|
|
1113
|
+
bufferScreen: buildCliScreenSnapshot(buffer),
|
|
1114
|
+
recentScreen: buildCliScreenSnapshot(recentBuffer),
|
|
1115
|
+
messages: [...baseMessages],
|
|
1116
|
+
partialResponse,
|
|
1117
|
+
promptText: scope?.prompt || "",
|
|
1118
|
+
settings: { ...runtimeSettings }
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
function summarizeCliTraceText(text, max = 800) {
|
|
1122
|
+
const value = sanitizeTerminalText(String(text || ""));
|
|
1123
|
+
if (value.length <= max) return value;
|
|
1124
|
+
return `\u2026${value.slice(-max)}`;
|
|
1125
|
+
}
|
|
1126
|
+
function summarizeCliTraceMessages(messages, limit = 3) {
|
|
1127
|
+
return messages.slice(-limit).map((message) => ({
|
|
1128
|
+
role: message.role,
|
|
1129
|
+
content: summarizeCliTraceText(message.content, 240),
|
|
1130
|
+
timestamp: message.timestamp
|
|
1131
|
+
}));
|
|
1132
|
+
}
|
|
1133
|
+
function buildCliTraceParseSnapshot(options) {
|
|
1134
|
+
const { accumulatedBuffer, accumulatedRawBuffer, responseBuffer, partialResponse, scope } = options;
|
|
1135
|
+
const scopedBuffer = scope ? sliceFromOffset(accumulatedBuffer, scope.bufferStart) || accumulatedBuffer : accumulatedBuffer;
|
|
1136
|
+
const scopedRawBuffer = scope ? sliceFromOffset(accumulatedRawBuffer, scope.rawBufferStart) || accumulatedRawBuffer : accumulatedRawBuffer;
|
|
1137
|
+
return {
|
|
1138
|
+
currentTurnScope: scope || null,
|
|
1139
|
+
responseBuffer: summarizeCliTraceText(responseBuffer, 1200),
|
|
1140
|
+
partialResponse: summarizeCliTraceText(partialResponse || responseBuffer, 1200),
|
|
1141
|
+
turnBuffer: summarizeCliTraceText(scopedBuffer, 1600),
|
|
1142
|
+
turnRawPreview: summarizeCliTraceText(scopedRawBuffer, 1600),
|
|
1143
|
+
turnSanitizedRawPreview: summarizeCliTraceText(sanitizeTerminalText(scopedRawBuffer), 1600)
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
var init_provider_cli_parse = __esm({
|
|
1147
|
+
"src/cli-adapters/provider-cli-parse.ts"() {
|
|
1148
|
+
"use strict";
|
|
1149
|
+
init_provider_cli_shared();
|
|
1150
|
+
}
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
// src/cli-adapters/provider-cli-config.ts
|
|
1154
|
+
function resolveCliAdapterConfig(provider) {
|
|
1155
|
+
const t = provider.timeouts || {};
|
|
1156
|
+
const rawKeys = provider.approvalKeys;
|
|
1157
|
+
return {
|
|
1158
|
+
timeouts: {
|
|
1159
|
+
ptyFlush: t.ptyFlush ?? 50,
|
|
1160
|
+
dialogAccept: t.dialogAccept ?? 300,
|
|
1161
|
+
approvalCooldown: t.approvalCooldown ?? 3e3,
|
|
1162
|
+
generatingIdle: t.generatingIdle ?? 6e3,
|
|
1163
|
+
idleFinish: t.idleFinish ?? 5e3,
|
|
1164
|
+
maxResponse: t.maxResponse ?? 3e5,
|
|
1165
|
+
shutdownGrace: t.shutdownGrace ?? 1e3,
|
|
1166
|
+
outputSettle: t.outputSettle ?? 300
|
|
1167
|
+
},
|
|
1168
|
+
approvalKeys: rawKeys && typeof rawKeys === "object" ? rawKeys : {},
|
|
1169
|
+
sendDelayMs: typeof provider.sendDelayMs === "number" ? Math.max(0, provider.sendDelayMs) : 0,
|
|
1170
|
+
sendKey: typeof provider.sendKey === "string" && provider.sendKey.length > 0 ? provider.sendKey : "\r",
|
|
1171
|
+
submitStrategy: provider.submitStrategy === "immediate" ? "immediate" : "wait_for_echo",
|
|
1172
|
+
providerResolutionMeta: {
|
|
1173
|
+
type: provider.type,
|
|
1174
|
+
name: provider.name,
|
|
1175
|
+
resolvedVersion: provider._resolvedVersion || null,
|
|
1176
|
+
resolvedOs: provider._resolvedOs || null,
|
|
1177
|
+
providerDir: provider._resolvedProviderDir || null,
|
|
1178
|
+
scriptDir: provider._resolvedScriptDir || null,
|
|
1179
|
+
scriptsPath: provider._resolvedScriptsPath || null,
|
|
1180
|
+
scriptsSource: provider._resolvedScriptsSource || null,
|
|
1181
|
+
versionWarning: provider._versionWarning || null
|
|
1182
|
+
}
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
var init_provider_cli_config = __esm({
|
|
1186
|
+
"src/cli-adapters/provider-cli-config.ts"() {
|
|
1187
|
+
"use strict";
|
|
1188
|
+
}
|
|
1189
|
+
});
|
|
1190
|
+
|
|
1191
|
+
// src/cli-adapters/provider-cli-runtime.ts
|
|
1192
|
+
import * as os9 from "os";
|
|
1193
|
+
import * as path10 from "path";
|
|
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 init_provider_cli_runtime = __esm({
|
|
1280
|
+
"src/cli-adapters/provider-cli-runtime.ts"() {
|
|
1281
|
+
"use strict";
|
|
1282
|
+
init_provider_cli_shared();
|
|
1283
|
+
}
|
|
1284
|
+
});
|
|
1285
|
+
|
|
1286
|
+
// src/cli-adapters/provider-cli-adapter.ts
|
|
1287
|
+
var provider_cli_adapter_exports = {};
|
|
1288
|
+
__export(provider_cli_adapter_exports, {
|
|
1289
|
+
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
1290
|
+
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
1291
|
+
});
|
|
1292
|
+
import * as os10 from "os";
|
|
1293
|
+
var ProviderCliAdapter;
|
|
1032
1294
|
var init_provider_cli_adapter = __esm({
|
|
1033
1295
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
1034
1296
|
"use strict";
|
|
1035
1297
|
init_logger();
|
|
1036
1298
|
init_terminal_screen();
|
|
1037
1299
|
init_pty_transport();
|
|
1038
|
-
|
|
1039
|
-
|
|
1300
|
+
init_provider_cli_shared();
|
|
1301
|
+
init_provider_cli_parse();
|
|
1302
|
+
init_provider_cli_config();
|
|
1303
|
+
init_provider_cli_runtime();
|
|
1304
|
+
init_provider_cli_shared();
|
|
1040
1305
|
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
1041
1306
|
constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
|
|
1042
1307
|
this.extraArgs = extraArgs;
|
|
@@ -1044,36 +1309,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
1044
1309
|
this.transportFactory = transportFactory;
|
|
1045
1310
|
this.cliType = provider.type;
|
|
1046
1311
|
this.cliName = provider.name;
|
|
1047
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
1048
|
-
const
|
|
1049
|
-
this.timeouts =
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
maxResponse: t.maxResponse ?? 3e5,
|
|
1056
|
-
shutdownGrace: t.shutdownGrace ?? 1e3,
|
|
1057
|
-
outputSettle: t.outputSettle ?? 300
|
|
1058
|
-
};
|
|
1059
|
-
const rawKeys = provider.approvalKeys;
|
|
1060
|
-
this.approvalKeys = rawKeys && typeof rawKeys === "object" ? rawKeys : {};
|
|
1061
|
-
this.sendDelayMs = typeof provider.sendDelayMs === "number" ? Math.max(0, provider.sendDelayMs) : 0;
|
|
1062
|
-
this.sendKey = typeof provider.sendKey === "string" && provider.sendKey.length > 0 ? provider.sendKey : "\r";
|
|
1063
|
-
this.submitStrategy = provider.submitStrategy === "immediate" ? "immediate" : "wait_for_echo";
|
|
1064
|
-
this.providerResolutionMeta = {
|
|
1065
|
-
type: provider.type,
|
|
1066
|
-
name: provider.name,
|
|
1067
|
-
resolvedVersion: provider._resolvedVersion || null,
|
|
1068
|
-
resolvedOs: provider._resolvedOs || null,
|
|
1069
|
-
providerDir: provider._resolvedProviderDir || null,
|
|
1070
|
-
scriptDir: provider._resolvedScriptDir || null,
|
|
1071
|
-
scriptsPath: provider._resolvedScriptsPath || null,
|
|
1072
|
-
scriptsSource: provider._resolvedScriptsSource || null,
|
|
1073
|
-
versionWarning: provider._versionWarning || null
|
|
1074
|
-
};
|
|
1312
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os10.homedir()) : workingDir;
|
|
1313
|
+
const resolvedConfig = resolveCliAdapterConfig(provider);
|
|
1314
|
+
this.timeouts = resolvedConfig.timeouts;
|
|
1315
|
+
this.approvalKeys = resolvedConfig.approvalKeys;
|
|
1316
|
+
this.sendDelayMs = resolvedConfig.sendDelayMs;
|
|
1317
|
+
this.sendKey = resolvedConfig.sendKey;
|
|
1318
|
+
this.submitStrategy = resolvedConfig.submitStrategy;
|
|
1319
|
+
this.providerResolutionMeta = resolvedConfig.providerResolutionMeta;
|
|
1075
1320
|
this.cliScripts = provider.scripts || {};
|
|
1076
|
-
const scriptNames =
|
|
1321
|
+
const scriptNames = listCliScriptNames(this.cliScripts);
|
|
1077
1322
|
if (scriptNames.length > 0) {
|
|
1078
1323
|
LOG.info("CLI", `[${this.cliType}] CLI scripts: [${scriptNames.join(", ")}]`);
|
|
1079
1324
|
LOG.info(
|
|
@@ -1170,88 +1415,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
1170
1415
|
this.messages = [...this.committedMessages];
|
|
1171
1416
|
this.structuredMessages = [...this.committedMessages];
|
|
1172
1417
|
}
|
|
1173
|
-
hydrateParsedMessages(parsedMessages, scope) {
|
|
1174
|
-
const referenceMessages = [...this.committedMessages];
|
|
1175
|
-
const usedReferenceIndexes = /* @__PURE__ */ new Set();
|
|
1176
|
-
const now = Date.now();
|
|
1177
|
-
const findReferenceTimestamp = (role, content, parsedIndex) => {
|
|
1178
|
-
const normalizedContent = normalizeComparableMessageContent(content);
|
|
1179
|
-
if (!normalizedContent) return void 0;
|
|
1180
|
-
const sameIndex = referenceMessages[parsedIndex];
|
|
1181
|
-
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && normalizeComparableMessageContent(sameIndex.content) === normalizedContent && typeof sameIndex.timestamp === "number" && Number.isFinite(sameIndex.timestamp)) {
|
|
1182
|
-
usedReferenceIndexes.add(parsedIndex);
|
|
1183
|
-
return sameIndex.timestamp;
|
|
1184
|
-
}
|
|
1185
|
-
for (let i = 0; i < referenceMessages.length; i++) {
|
|
1186
|
-
if (usedReferenceIndexes.has(i)) continue;
|
|
1187
|
-
const candidate = referenceMessages[i];
|
|
1188
|
-
if (!candidate || candidate.role !== role) continue;
|
|
1189
|
-
const candidateContent = normalizeComparableMessageContent(candidate.content);
|
|
1190
|
-
if (!candidateContent) continue;
|
|
1191
|
-
const exactMatch = candidateContent === normalizedContent;
|
|
1192
|
-
const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
|
|
1193
|
-
if (!exactMatch && !fuzzyMatch) continue;
|
|
1194
|
-
if (typeof candidate.timestamp === "number" && Number.isFinite(candidate.timestamp)) {
|
|
1195
|
-
usedReferenceIndexes.add(i);
|
|
1196
|
-
return candidate.timestamp;
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
return void 0;
|
|
1200
|
-
};
|
|
1201
|
-
return parsedMessages.filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message, index) => {
|
|
1202
|
-
const role = message.role;
|
|
1203
|
-
const content = typeof message.content === "string" ? message.content : String(message.content || "");
|
|
1204
|
-
const parsedTimestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0;
|
|
1205
|
-
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(role, content, index);
|
|
1206
|
-
const fallbackTimestamp = role === "user" ? scope?.startedAt || now : this.lastOutputAt || scope?.startedAt || now;
|
|
1207
|
-
const timestamp = referenceTimestamp ?? fallbackTimestamp;
|
|
1208
|
-
return {
|
|
1209
|
-
...message,
|
|
1210
|
-
role,
|
|
1211
|
-
content,
|
|
1212
|
-
timestamp,
|
|
1213
|
-
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp
|
|
1214
|
-
};
|
|
1215
|
-
});
|
|
1216
|
-
}
|
|
1217
|
-
normalizeParsedMessages(parsedMessages, scope) {
|
|
1218
|
-
return this.hydrateParsedMessages(parsedMessages, scope).map((message) => ({
|
|
1219
|
-
role: message.role,
|
|
1220
|
-
content: message.content,
|
|
1221
|
-
timestamp: message.timestamp,
|
|
1222
|
-
receivedAt: message.receivedAt,
|
|
1223
|
-
kind: message.kind,
|
|
1224
|
-
id: message.id,
|
|
1225
|
-
index: message.index,
|
|
1226
|
-
meta: message.meta,
|
|
1227
|
-
senderName: message.senderName
|
|
1228
|
-
}));
|
|
1229
|
-
}
|
|
1230
|
-
sliceFromOffset(text, start) {
|
|
1231
|
-
if (!text) return "";
|
|
1232
|
-
if (!Number.isFinite(start) || start <= 0) return text;
|
|
1233
|
-
if (start >= text.length) return "";
|
|
1234
|
-
return text.slice(start);
|
|
1235
|
-
}
|
|
1236
|
-
buildParseInput(baseMessages, partialResponse, scope) {
|
|
1237
|
-
const buffer = scope ? this.sliceFromOffset(this.accumulatedBuffer, scope.bufferStart) || this.accumulatedBuffer : this.accumulatedBuffer;
|
|
1238
|
-
const rawBuffer = scope ? this.sliceFromOffset(this.accumulatedRawBuffer, scope.rawBufferStart) || this.accumulatedRawBuffer : this.accumulatedRawBuffer;
|
|
1239
|
-
const screenText = this.terminalScreen.getText();
|
|
1240
|
-
const recentBuffer = buffer.slice(-1e3) || this.recentOutputBuffer;
|
|
1241
|
-
return {
|
|
1242
|
-
buffer,
|
|
1243
|
-
rawBuffer,
|
|
1244
|
-
recentBuffer,
|
|
1245
|
-
screenText,
|
|
1246
|
-
screen: buildCliScreenSnapshot(screenText),
|
|
1247
|
-
bufferScreen: buildCliScreenSnapshot(buffer),
|
|
1248
|
-
recentScreen: buildCliScreenSnapshot(recentBuffer),
|
|
1249
|
-
messages: [...baseMessages],
|
|
1250
|
-
partialResponse,
|
|
1251
|
-
promptText: scope?.prompt || "",
|
|
1252
|
-
settings: { ...this.runtimeSettings }
|
|
1253
|
-
};
|
|
1254
|
-
}
|
|
1255
1418
|
setStatus(status, trigger) {
|
|
1256
1419
|
const prev = this.currentStatus;
|
|
1257
1420
|
if (prev === status) return;
|
|
@@ -1284,7 +1447,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
1284
1447
|
this.recordTrace("idle_candidate_armed", {
|
|
1285
1448
|
confirmMs: _ProviderCliAdapter.IDLE_FINISH_CONFIRM_MS,
|
|
1286
1449
|
candidate: this.idleFinishCandidate,
|
|
1287
|
-
...
|
|
1450
|
+
...buildCliTraceParseSnapshot({
|
|
1451
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
1452
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
1453
|
+
responseBuffer: this.responseBuffer,
|
|
1454
|
+
partialResponse: this.responseBuffer,
|
|
1455
|
+
scope: this.currentTurnScope
|
|
1456
|
+
})
|
|
1288
1457
|
});
|
|
1289
1458
|
if (this.settleTimer) clearTimeout(this.settleTimer);
|
|
1290
1459
|
this.settleTimer = setTimeout(() => {
|
|
@@ -1293,30 +1462,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
1293
1462
|
this.evaluateSettled();
|
|
1294
1463
|
}, _ProviderCliAdapter.IDLE_FINISH_CONFIRM_MS);
|
|
1295
1464
|
}
|
|
1296
|
-
summarizeTraceText(text, max = 800) {
|
|
1297
|
-
const value = sanitizeTerminalText(String(text || ""));
|
|
1298
|
-
if (value.length <= max) return value;
|
|
1299
|
-
return `\u2026${value.slice(-max)}`;
|
|
1300
|
-
}
|
|
1301
|
-
summarizeTraceMessages(messages, limit = 3) {
|
|
1302
|
-
return messages.slice(-limit).map((message) => ({
|
|
1303
|
-
role: message.role,
|
|
1304
|
-
content: this.summarizeTraceText(message.content, 240),
|
|
1305
|
-
timestamp: message.timestamp
|
|
1306
|
-
}));
|
|
1307
|
-
}
|
|
1308
|
-
buildTraceParseSnapshot(scope, partialResponse = "") {
|
|
1309
|
-
const scopedBuffer = scope ? this.sliceFromOffset(this.accumulatedBuffer, scope.bufferStart) || this.accumulatedBuffer : this.accumulatedBuffer;
|
|
1310
|
-
const scopedRawBuffer = scope ? this.sliceFromOffset(this.accumulatedRawBuffer, scope.rawBufferStart) || this.accumulatedRawBuffer : this.accumulatedRawBuffer;
|
|
1311
|
-
return {
|
|
1312
|
-
currentTurnScope: scope || null,
|
|
1313
|
-
responseBuffer: this.summarizeTraceText(this.responseBuffer, 1200),
|
|
1314
|
-
partialResponse: this.summarizeTraceText(partialResponse || this.responseBuffer, 1200),
|
|
1315
|
-
turnBuffer: this.summarizeTraceText(scopedBuffer, 1600),
|
|
1316
|
-
turnRawPreview: this.summarizeTraceText(scopedRawBuffer, 1600),
|
|
1317
|
-
turnSanitizedRawPreview: this.summarizeTraceText(sanitizeTerminalText(scopedRawBuffer), 1600)
|
|
1318
|
-
};
|
|
1319
|
-
}
|
|
1320
1465
|
recordTrace(type, payload = {}) {
|
|
1321
1466
|
const entry = {
|
|
1322
1467
|
id: ++this.traceSeq,
|
|
@@ -1352,7 +1497,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1352
1497
|
/** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
|
|
1353
1498
|
setCliScripts(scripts) {
|
|
1354
1499
|
this.cliScripts = scripts;
|
|
1355
|
-
const scriptNames =
|
|
1500
|
+
const scriptNames = listCliScriptNames(scripts);
|
|
1356
1501
|
LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
|
|
1357
1502
|
}
|
|
1358
1503
|
updateRuntimeSettings(settings) {
|
|
@@ -1384,72 +1529,42 @@ var init_provider_cli_adapter = __esm({
|
|
|
1384
1529
|
}
|
|
1385
1530
|
async spawn() {
|
|
1386
1531
|
if (this.ptyProcess) return;
|
|
1387
|
-
const
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1532
|
+
const spawnPlan = resolveCliSpawnPlan({
|
|
1533
|
+
provider: this.provider,
|
|
1534
|
+
runtimeSettings: this.runtimeSettings,
|
|
1535
|
+
workingDir: this.workingDir,
|
|
1536
|
+
extraArgs: this.extraArgs
|
|
1537
|
+
});
|
|
1392
1538
|
LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
1393
1539
|
this.resetTraceSession();
|
|
1394
|
-
let shellCmd;
|
|
1395
|
-
let shellArgs;
|
|
1396
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
1397
|
-
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
1398
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
1399
|
-
const useShell = isWin ? useShellWin : useShellUnix;
|
|
1400
|
-
if (useShell) {
|
|
1401
|
-
if (!spawnConfig.shell && !isWin) {
|
|
1402
|
-
LOG.info("CLI", `[${this.cliType}] Using login shell (script shim or non-native binary)`);
|
|
1403
|
-
}
|
|
1404
|
-
if (isCmdShim) {
|
|
1405
|
-
LOG.info("CLI", `[${this.cliType}] Using cmd.exe shell for .cmd/.bat shim: ${binaryPath}`);
|
|
1406
|
-
} else if (isWin) {
|
|
1407
|
-
LOG.info("CLI", `[${this.cliType}] Using cmd.exe shell on Windows: ${binaryPath}`);
|
|
1408
|
-
}
|
|
1409
|
-
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
1410
|
-
if (isWin) {
|
|
1411
|
-
shellArgs = ["/c", binaryPath, ...allArgs];
|
|
1412
|
-
} else {
|
|
1413
|
-
const fullCmd = [binaryPath, ...allArgs].map(shSingleQuote).join(" ");
|
|
1414
|
-
shellArgs = ["-l", "-c", fullCmd];
|
|
1415
|
-
}
|
|
1416
|
-
} else {
|
|
1417
|
-
if (isWin && spawnConfig.shell) {
|
|
1418
|
-
LOG.info("CLI", `[${this.cliType}] Spawning Windows binary directly without cmd.exe: ${binaryPath}`);
|
|
1419
|
-
}
|
|
1420
|
-
shellCmd = binaryPath;
|
|
1421
|
-
shellArgs = allArgs;
|
|
1422
|
-
}
|
|
1423
|
-
const ptyOpts = {
|
|
1424
|
-
cols: 80,
|
|
1425
|
-
rows: 24,
|
|
1426
|
-
cwd: this.workingDir,
|
|
1427
|
-
env: buildCliSpawnEnv(process.env, spawnConfig.env)
|
|
1428
|
-
};
|
|
1429
1540
|
this.recordTrace("spawn", {
|
|
1430
|
-
shellCommand: shellCmd,
|
|
1431
|
-
shellArgs,
|
|
1432
|
-
cwd:
|
|
1433
|
-
cols:
|
|
1434
|
-
rows:
|
|
1541
|
+
shellCommand: spawnPlan.shellCmd,
|
|
1542
|
+
shellArgs: spawnPlan.shellArgs,
|
|
1543
|
+
cwd: spawnPlan.ptyOptions.cwd,
|
|
1544
|
+
cols: spawnPlan.ptyOptions.cols,
|
|
1545
|
+
rows: spawnPlan.ptyOptions.rows,
|
|
1435
1546
|
providerResolution: this.providerResolutionMeta
|
|
1436
1547
|
});
|
|
1437
1548
|
try {
|
|
1438
|
-
this.ptyProcess = this.transportFactory.spawn(
|
|
1549
|
+
this.ptyProcess = this.transportFactory.spawn(
|
|
1550
|
+
spawnPlan.shellCmd,
|
|
1551
|
+
spawnPlan.shellArgs,
|
|
1552
|
+
spawnPlan.ptyOptions
|
|
1553
|
+
);
|
|
1439
1554
|
} catch (err) {
|
|
1440
1555
|
const msg = err?.message || String(err);
|
|
1441
|
-
if (!isWin && !useShell && /posix_spawn|spawn/i.test(msg)) {
|
|
1556
|
+
if (!spawnPlan.isWin && !spawnPlan.useShell && /posix_spawn|spawn/i.test(msg)) {
|
|
1442
1557
|
LOG.warn("CLI", `[${this.cliType}] Direct spawn failed (${msg}), retrying via login shell`);
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1558
|
+
const retryPlan = buildCliLoginShellRetry(spawnPlan);
|
|
1559
|
+
this.ptyProcess = this.transportFactory.spawn(
|
|
1560
|
+
retryPlan.shellCmd,
|
|
1561
|
+
retryPlan.shellArgs,
|
|
1562
|
+
spawnPlan.ptyOptions
|
|
1563
|
+
);
|
|
1447
1564
|
} else {
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
throw new Error(`Failed to spawn CLI${hint}: ${msg}`);
|
|
1452
|
-
}
|
|
1565
|
+
const hint = getCliSpawnErrorHint(msg, spawnPlan.shellCmd, spawnPlan.isWin);
|
|
1566
|
+
if (hint) {
|
|
1567
|
+
throw new Error(`Failed to spawn CLI${hint}: ${msg}`);
|
|
1453
1568
|
}
|
|
1454
1569
|
throw err;
|
|
1455
1570
|
}
|
|
@@ -1457,7 +1572,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
1457
1572
|
this.ptyProcess.onData((data) => {
|
|
1458
1573
|
if (Date.now() < this.resizeSuppressUntil) return;
|
|
1459
1574
|
if (!this.ptyProcess?.terminalQueriesHandled) {
|
|
1460
|
-
this.
|
|
1575
|
+
this.pendingTerminalQueryTail = respondToCliTerminalQueries({
|
|
1576
|
+
ptyProcess: this.ptyProcess,
|
|
1577
|
+
pendingTail: this.pendingTerminalQueryTail,
|
|
1578
|
+
data,
|
|
1579
|
+
terminalScreen: this.terminalScreen
|
|
1580
|
+
});
|
|
1461
1581
|
}
|
|
1462
1582
|
this.pendingOutputParseBuffer += data;
|
|
1463
1583
|
if (!this.pendingOutputParseTimer) {
|
|
@@ -1536,9 +1656,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
1536
1656
|
this.recordTrace("output", {
|
|
1537
1657
|
rawLength: rawData.length,
|
|
1538
1658
|
cleanLength: cleanData.length,
|
|
1539
|
-
rawPreview:
|
|
1540
|
-
cleanPreview:
|
|
1541
|
-
screenText:
|
|
1659
|
+
rawPreview: summarizeCliTraceText(rawData, 300),
|
|
1660
|
+
cleanPreview: summarizeCliTraceText(cleanData, 300),
|
|
1661
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 1200)
|
|
1542
1662
|
});
|
|
1543
1663
|
if (this.startupParseGate) {
|
|
1544
1664
|
this.scheduleStartupSettleCheck();
|
|
@@ -1769,7 +1889,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1769
1889
|
loggedWait = true;
|
|
1770
1890
|
LOG.info(
|
|
1771
1891
|
"CLI",
|
|
1772
|
-
`[${this.cliType}] Waiting for interactive prompt: hasPrompt=${hasPrompt} stableMs=${stableMs} recentOutputMs=${recentlyOutput} status=${status} startup=${startupLikelyActive} screen=${JSON.stringify(
|
|
1892
|
+
`[${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)}`
|
|
1773
1893
|
);
|
|
1774
1894
|
}
|
|
1775
1895
|
await new Promise((resolve12) => setTimeout(resolve12, 50));
|
|
@@ -1777,7 +1897,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1777
1897
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
1778
1898
|
LOG.warn(
|
|
1779
1899
|
"CLI",
|
|
1780
|
-
`[${this.cliType}] Interactive prompt wait timed out after ${maxWaitMs}ms; proceeding with screen=${JSON.stringify(
|
|
1900
|
+
`[${this.cliType}] Interactive prompt wait timed out after ${maxWaitMs}ms; proceeding with screen=${JSON.stringify(summarizeCliTraceText(finalScreenText, 240)).slice(0, 280)}`
|
|
1781
1901
|
);
|
|
1782
1902
|
}
|
|
1783
1903
|
evaluateSettled() {
|
|
@@ -1807,23 +1927,33 @@ var init_provider_cli_adapter = __esm({
|
|
|
1807
1927
|
this.responseBuffer,
|
|
1808
1928
|
this.currentTurnScope
|
|
1809
1929
|
);
|
|
1810
|
-
const parsedMessages = Array.isArray(parsedTranscript?.messages) ?
|
|
1930
|
+
const parsedMessages = Array.isArray(parsedTranscript?.messages) ? normalizeCliParsedMessages(parsedTranscript.messages, {
|
|
1931
|
+
committedMessages: this.committedMessages,
|
|
1932
|
+
scope: this.currentTurnScope,
|
|
1933
|
+
lastOutputAt: this.lastOutputAt
|
|
1934
|
+
}) : [];
|
|
1811
1935
|
const lastParsedAssistant = [...parsedMessages].reverse().find((message) => message.role === "assistant");
|
|
1812
1936
|
this.recordTrace("settled", {
|
|
1813
|
-
tail:
|
|
1814
|
-
screenText:
|
|
1937
|
+
tail: summarizeCliTraceText(tail, 500),
|
|
1938
|
+
screenText: summarizeCliTraceText(screenText, 1200),
|
|
1815
1939
|
detectStatus: scriptStatus,
|
|
1816
1940
|
parsedStatus: parsedTranscript?.status || null,
|
|
1817
1941
|
parsedMessageCount: parsedMessages.length,
|
|
1818
|
-
parsedLastAssistant: lastParsedAssistant ?
|
|
1942
|
+
parsedLastAssistant: lastParsedAssistant ? summarizeCliTraceText(lastParsedAssistant.content, 280) : "",
|
|
1819
1943
|
parsedActiveModal: parsedTranscript?.activeModal ?? null,
|
|
1820
1944
|
approval: modal,
|
|
1821
|
-
...
|
|
1945
|
+
...buildCliTraceParseSnapshot({
|
|
1946
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
1947
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
1948
|
+
responseBuffer: this.responseBuffer,
|
|
1949
|
+
partialResponse: this.responseBuffer,
|
|
1950
|
+
scope: this.currentTurnScope
|
|
1951
|
+
})
|
|
1822
1952
|
});
|
|
1823
1953
|
if (this.currentTurnScope && !lastParsedAssistant) {
|
|
1824
1954
|
LOG.info(
|
|
1825
1955
|
"CLI",
|
|
1826
|
-
`[${this.cliType}] Settled without assistant: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(
|
|
1956
|
+
`[${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 || "-"}`
|
|
1827
1957
|
);
|
|
1828
1958
|
}
|
|
1829
1959
|
if (!scriptStatus) return;
|
|
@@ -1877,7 +2007,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
1877
2007
|
lastNonEmptyOutputAt: this.lastNonEmptyOutputAt,
|
|
1878
2008
|
lastScreenChangeAt: this.lastScreenChangeAt,
|
|
1879
2009
|
holdMs: _ProviderCliAdapter.STATUS_ACTIVITY_HOLD_MS,
|
|
1880
|
-
...
|
|
2010
|
+
...buildCliTraceParseSnapshot({
|
|
2011
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2012
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2013
|
+
responseBuffer: this.responseBuffer,
|
|
2014
|
+
partialResponse: this.responseBuffer,
|
|
2015
|
+
scope: this.currentTurnScope
|
|
2016
|
+
})
|
|
1881
2017
|
});
|
|
1882
2018
|
this.onStatusChange?.();
|
|
1883
2019
|
return;
|
|
@@ -1981,7 +2117,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
1981
2117
|
canFinishImmediately,
|
|
1982
2118
|
submitPendingUntil: this.submitPendingUntil,
|
|
1983
2119
|
responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
|
|
1984
|
-
...
|
|
2120
|
+
...buildCliTraceParseSnapshot({
|
|
2121
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2122
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2123
|
+
responseBuffer: this.responseBuffer,
|
|
2124
|
+
partialResponse: this.responseBuffer,
|
|
2125
|
+
scope: this.currentTurnScope
|
|
2126
|
+
})
|
|
1985
2127
|
});
|
|
1986
2128
|
if (canFinishImmediately) {
|
|
1987
2129
|
this.clearIdleFinishCandidate("finish_response");
|
|
@@ -2016,7 +2158,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
2016
2158
|
if (this.responseSettleIgnoreUntil > Date.now()) return;
|
|
2017
2159
|
this.clearIdleFinishCandidate("finish_response_enter");
|
|
2018
2160
|
this.recordTrace("finish_response", {
|
|
2019
|
-
...
|
|
2161
|
+
...buildCliTraceParseSnapshot({
|
|
2162
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2163
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2164
|
+
responseBuffer: this.responseBuffer,
|
|
2165
|
+
partialResponse: this.responseBuffer,
|
|
2166
|
+
scope: this.currentTurnScope
|
|
2167
|
+
})
|
|
2020
2168
|
});
|
|
2021
2169
|
const commitResult = this.commitCurrentTranscript();
|
|
2022
2170
|
if (this.shouldRetryFinishResponse(commitResult)) {
|
|
@@ -2024,8 +2172,14 @@ var init_provider_cli_adapter = __esm({
|
|
|
2024
2172
|
this.recordTrace("finish_response_retry", {
|
|
2025
2173
|
retryCount: this.finishRetryCount,
|
|
2026
2174
|
retryDelayMs: _ProviderCliAdapter.FINISH_RETRY_DELAY_MS,
|
|
2027
|
-
assistantContent:
|
|
2028
|
-
...
|
|
2175
|
+
assistantContent: summarizeCliTraceText(commitResult.assistantContent, 220),
|
|
2176
|
+
...buildCliTraceParseSnapshot({
|
|
2177
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2178
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2179
|
+
responseBuffer: this.responseBuffer,
|
|
2180
|
+
partialResponse: this.responseBuffer,
|
|
2181
|
+
scope: this.currentTurnScope
|
|
2182
|
+
})
|
|
2029
2183
|
});
|
|
2030
2184
|
if (this.finishRetryTimer) clearTimeout(this.finishRetryTimer);
|
|
2031
2185
|
this.finishRetryTimer = setTimeout(() => {
|
|
@@ -2074,7 +2228,11 @@ var init_provider_cli_adapter = __esm({
|
|
|
2074
2228
|
this.currentTurnScope
|
|
2075
2229
|
);
|
|
2076
2230
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
2077
|
-
this.committedMessages =
|
|
2231
|
+
this.committedMessages = normalizeCliParsedMessages(parsed.messages, {
|
|
2232
|
+
committedMessages: this.committedMessages,
|
|
2233
|
+
scope: this.currentTurnScope,
|
|
2234
|
+
lastOutputAt: this.lastOutputAt
|
|
2235
|
+
});
|
|
2078
2236
|
const promptForTrim = this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages);
|
|
2079
2237
|
if (promptForTrim) {
|
|
2080
2238
|
const lastAssistantForTrim = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
|
|
@@ -2087,14 +2245,20 @@ var init_provider_cli_adapter = __esm({
|
|
|
2087
2245
|
this.recordTrace("commit_transcript", {
|
|
2088
2246
|
parsedStatus: parsed.status || null,
|
|
2089
2247
|
messageCount: this.committedMessages.length,
|
|
2090
|
-
lastAssistant: lastAssistant ?
|
|
2091
|
-
messages:
|
|
2092
|
-
...
|
|
2248
|
+
lastAssistant: lastAssistant ? summarizeCliTraceText(lastAssistant.content, 320) : "",
|
|
2249
|
+
messages: summarizeCliTraceMessages(this.committedMessages),
|
|
2250
|
+
...buildCliTraceParseSnapshot({
|
|
2251
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2252
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2253
|
+
responseBuffer: this.responseBuffer,
|
|
2254
|
+
partialResponse: this.responseBuffer,
|
|
2255
|
+
scope: this.currentTurnScope
|
|
2256
|
+
})
|
|
2093
2257
|
});
|
|
2094
2258
|
if (!lastAssistant && this.currentTurnScope) {
|
|
2095
2259
|
LOG.warn(
|
|
2096
2260
|
"CLI",
|
|
2097
|
-
`[${this.cliType}] Commit without assistant turn: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(
|
|
2261
|
+
`[${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 || "-"}`
|
|
2098
2262
|
);
|
|
2099
2263
|
}
|
|
2100
2264
|
return {
|
|
@@ -2186,7 +2350,11 @@ var init_provider_cli_adapter = __esm({
|
|
|
2186
2350
|
index: typeof message.index === "number" ? message.index : index,
|
|
2187
2351
|
kind: message.kind || "standard",
|
|
2188
2352
|
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
2189
|
-
})) :
|
|
2353
|
+
})) : hydrateCliParsedMessages(parsed.messages, {
|
|
2354
|
+
committedMessages: this.committedMessages,
|
|
2355
|
+
scope: this.currentTurnScope,
|
|
2356
|
+
lastOutputAt: this.lastOutputAt
|
|
2357
|
+
});
|
|
2190
2358
|
return {
|
|
2191
2359
|
id: parsed.id || "cli_session",
|
|
2192
2360
|
status: parsed.status || this.currentStatus,
|
|
@@ -2217,11 +2385,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
2217
2385
|
if (typeof fn !== "function") {
|
|
2218
2386
|
throw new Error(`CLI script '${scriptName}' not available`);
|
|
2219
2387
|
}
|
|
2220
|
-
const input =
|
|
2221
|
-
this.
|
|
2222
|
-
this.
|
|
2223
|
-
this.
|
|
2224
|
-
|
|
2388
|
+
const input = buildCliParseInput({
|
|
2389
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2390
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2391
|
+
recentOutputBuffer: this.recentOutputBuffer,
|
|
2392
|
+
terminalScreenText: this.terminalScreen.getText(),
|
|
2393
|
+
baseMessages: this.committedMessages,
|
|
2394
|
+
partialResponse: this.responseBuffer,
|
|
2395
|
+
scope: this.currentTurnScope,
|
|
2396
|
+
runtimeSettings: this.runtimeSettings
|
|
2397
|
+
});
|
|
2225
2398
|
return await Promise.resolve(fn({
|
|
2226
2399
|
...input,
|
|
2227
2400
|
args: args && typeof args === "object" ? { ...args } : {}
|
|
@@ -2230,7 +2403,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
2230
2403
|
parseCurrentTranscript(baseMessages, partialResponse, scope) {
|
|
2231
2404
|
if (!this.cliScripts?.parseOutput) return null;
|
|
2232
2405
|
try {
|
|
2233
|
-
const input =
|
|
2406
|
+
const input = buildCliParseInput({
|
|
2407
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2408
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2409
|
+
recentOutputBuffer: this.recentOutputBuffer,
|
|
2410
|
+
terminalScreenText: this.terminalScreen.getText(),
|
|
2411
|
+
baseMessages,
|
|
2412
|
+
partialResponse,
|
|
2413
|
+
scope,
|
|
2414
|
+
runtimeSettings: this.runtimeSettings
|
|
2415
|
+
});
|
|
2234
2416
|
const parsed = this.cliScripts.parseOutput(input);
|
|
2235
2417
|
const refinedStatus = this.refineDetectedStatus(typeof parsed?.status === "string" ? parsed.status : null, input.recentBuffer, input.screenText);
|
|
2236
2418
|
if (parsed && refinedStatus && parsed.status !== refinedStatus) {
|
|
@@ -2320,7 +2502,7 @@ ${data.message || ""}`.trim();
|
|
|
2320
2502
|
rawBufferStart: this.accumulatedRawBuffer.length
|
|
2321
2503
|
};
|
|
2322
2504
|
this.recordTrace("send_message", {
|
|
2323
|
-
text:
|
|
2505
|
+
text: summarizeCliTraceText(text, 500),
|
|
2324
2506
|
estimatedLines: estimatePromptDisplayLines(text),
|
|
2325
2507
|
turnScope: this.currentTurnScope
|
|
2326
2508
|
});
|
|
@@ -2354,7 +2536,7 @@ ${data.message || ""}`.trim();
|
|
|
2354
2536
|
this.recordTrace("submit_write", {
|
|
2355
2537
|
mode: "submit_key",
|
|
2356
2538
|
sendKey: this.sendKey,
|
|
2357
|
-
screenText:
|
|
2539
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
|
|
2358
2540
|
});
|
|
2359
2541
|
this.ptyProcess.write(this.sendKey);
|
|
2360
2542
|
const retrySubmitIfStuck = (attempt) => {
|
|
@@ -2371,7 +2553,7 @@ ${data.message || ""}`.trim();
|
|
|
2371
2553
|
mode: "submit_retry",
|
|
2372
2554
|
attempt,
|
|
2373
2555
|
sendKey: this.sendKey,
|
|
2374
|
-
screenText:
|
|
2556
|
+
screenText: summarizeCliTraceText(screenText, 500)
|
|
2375
2557
|
});
|
|
2376
2558
|
this.ptyProcess.write(this.sendKey);
|
|
2377
2559
|
if (attempt >= 3) {
|
|
@@ -2387,9 +2569,9 @@ ${data.message || ""}`.trim();
|
|
|
2387
2569
|
this.submitPendingUntil = 0;
|
|
2388
2570
|
this.recordTrace("submit_write", {
|
|
2389
2571
|
mode: "immediate",
|
|
2390
|
-
text:
|
|
2572
|
+
text: summarizeCliTraceText(text, 500),
|
|
2391
2573
|
sendKey: this.sendKey,
|
|
2392
|
-
screenText:
|
|
2574
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
|
|
2393
2575
|
});
|
|
2394
2576
|
this.ptyProcess.write(text + this.sendKey);
|
|
2395
2577
|
this.submitRetryTimer = setTimeout(() => {
|
|
@@ -2405,7 +2587,7 @@ ${data.message || ""}`.trim();
|
|
|
2405
2587
|
mode: "immediate_retry",
|
|
2406
2588
|
attempt: 1,
|
|
2407
2589
|
sendKey: this.sendKey,
|
|
2408
|
-
screenText:
|
|
2590
|
+
screenText: summarizeCliTraceText(screenText, 500)
|
|
2409
2591
|
});
|
|
2410
2592
|
this.ptyProcess.write(this.sendKey);
|
|
2411
2593
|
this.submitRetryUsed = true;
|
|
@@ -2419,9 +2601,9 @@ ${data.message || ""}`.trim();
|
|
|
2419
2601
|
this.ptyProcess.write(text);
|
|
2420
2602
|
this.recordTrace("submit_write", {
|
|
2421
2603
|
mode: "type_then_submit",
|
|
2422
|
-
text:
|
|
2604
|
+
text: summarizeCliTraceText(text, 500),
|
|
2423
2605
|
sendKey: this.sendKey,
|
|
2424
|
-
screenText:
|
|
2606
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
|
|
2425
2607
|
});
|
|
2426
2608
|
const submitStartedAt = Date.now();
|
|
2427
2609
|
let lastNormalizedScreen = "";
|
|
@@ -2756,7 +2938,7 @@ ${data.message || ""}`.trim();
|
|
|
2756
2938
|
responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
|
|
2757
2939
|
resizeSuppressUntil: this.resizeSuppressUntil,
|
|
2758
2940
|
hasCliScripts: this.hasCliScripts(),
|
|
2759
|
-
scriptNames:
|
|
2941
|
+
scriptNames: listCliScriptNames(this.cliScripts),
|
|
2760
2942
|
traceSessionId: this.traceSessionId,
|
|
2761
2943
|
traceEntryCount: this.traceEntries.length,
|
|
2762
2944
|
statusHistory: this.statusHistory.slice(-30),
|
|
@@ -2773,32 +2955,18 @@ ${data.message || ""}`.trim();
|
|
|
2773
2955
|
providerResolution: this.providerResolutionMeta,
|
|
2774
2956
|
entryCount: this.traceEntries.length,
|
|
2775
2957
|
entries: this.traceEntries.slice(-cappedLimit),
|
|
2776
|
-
screenText:
|
|
2777
|
-
recentOutputBuffer:
|
|
2778
|
-
responseBuffer:
|
|
2958
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 4e3),
|
|
2959
|
+
recentOutputBuffer: summarizeCliTraceText(this.recentOutputBuffer, 1e3),
|
|
2960
|
+
responseBuffer: summarizeCliTraceText(this.responseBuffer, 1200),
|
|
2779
2961
|
status: this.currentStatus,
|
|
2780
2962
|
activeModal: this.activeModal,
|
|
2781
2963
|
currentTurnScope: this.currentTurnScope,
|
|
2782
|
-
messages:
|
|
2964
|
+
messages: summarizeCliTraceMessages(this.committedMessages, 5)
|
|
2783
2965
|
};
|
|
2784
2966
|
}
|
|
2785
2967
|
getProviderResolutionMeta() {
|
|
2786
2968
|
return { ...this.providerResolutionMeta };
|
|
2787
2969
|
}
|
|
2788
|
-
respondToTerminalQueries(data) {
|
|
2789
|
-
if (!this.ptyProcess || !data) return;
|
|
2790
|
-
const combined = this.pendingTerminalQueryTail + data;
|
|
2791
|
-
const regex = /\x1b\[(\?)?6n/g;
|
|
2792
|
-
let match;
|
|
2793
|
-
while ((match = regex.exec(combined)) !== null) {
|
|
2794
|
-
const cursor = this.terminalScreen.getCursorPosition();
|
|
2795
|
-
const row = Math.max(1, (cursor.row | 0) + 1);
|
|
2796
|
-
const col = Math.max(1, (cursor.col | 0) + 1);
|
|
2797
|
-
const response = match[1] ? `\x1B[?${row};${col}R` : `\x1B[${row};${col}R`;
|
|
2798
|
-
this.ptyProcess.write(response);
|
|
2799
|
-
}
|
|
2800
|
-
this.pendingTerminalQueryTail = computeTerminalQueryTail(combined);
|
|
2801
|
-
}
|
|
2802
2970
|
};
|
|
2803
2971
|
}
|
|
2804
2972
|
});
|
|
@@ -3195,17 +3363,17 @@ function checkPathExists(paths) {
|
|
|
3195
3363
|
return null;
|
|
3196
3364
|
}
|
|
3197
3365
|
async function detectIDEs(providerLoader) {
|
|
3198
|
-
const
|
|
3366
|
+
const os20 = platform();
|
|
3199
3367
|
const results = [];
|
|
3200
3368
|
for (const def of getMergedDefinitions()) {
|
|
3201
3369
|
const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
|
|
3202
|
-
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[
|
|
3370
|
+
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os20] || []) || []);
|
|
3203
3371
|
let resolvedCli = cliPath;
|
|
3204
|
-
if (!resolvedCli && appPath &&
|
|
3372
|
+
if (!resolvedCli && appPath && os20 === "darwin") {
|
|
3205
3373
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
3206
3374
|
if (existsSync4(bundledCli)) resolvedCli = bundledCli;
|
|
3207
3375
|
}
|
|
3208
|
-
if (!resolvedCli && appPath &&
|
|
3376
|
+
if (!resolvedCli && appPath && os20 === "win32") {
|
|
3209
3377
|
const { dirname: dirname6 } = await import("path");
|
|
3210
3378
|
const appDir = dirname6(appPath);
|
|
3211
3379
|
const candidates = [
|
|
@@ -3222,7 +3390,7 @@ async function detectIDEs(providerLoader) {
|
|
|
3222
3390
|
}
|
|
3223
3391
|
}
|
|
3224
3392
|
}
|
|
3225
|
-
const installed =
|
|
3393
|
+
const installed = os20 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
3226
3394
|
const version = resolvedCli ? getIdeVersion(resolvedCli) : null;
|
|
3227
3395
|
results.push({
|
|
3228
3396
|
id: def.id,
|
|
@@ -3283,8 +3451,8 @@ function execAsync(cmd, timeoutMs = 5e3) {
|
|
|
3283
3451
|
});
|
|
3284
3452
|
}
|
|
3285
3453
|
async function detectCLIs(providerLoader, options) {
|
|
3286
|
-
const
|
|
3287
|
-
const whichCmd =
|
|
3454
|
+
const platform10 = os2.platform();
|
|
3455
|
+
const whichCmd = platform10 === "win32" ? "where" : "which";
|
|
3288
3456
|
const includeVersion = options?.includeVersion !== false;
|
|
3289
3457
|
const cliList = providerLoader ? providerLoader.getCliDetectionList() : [];
|
|
3290
3458
|
const results = await Promise.all(
|
|
@@ -3327,8 +3495,8 @@ async function detectCLI(cliId, providerLoader, options) {
|
|
|
3327
3495
|
const cliList = providerLoader.getCliDetectionList();
|
|
3328
3496
|
const target = cliList.find((c) => c.id === resolvedId);
|
|
3329
3497
|
if (target) {
|
|
3330
|
-
const
|
|
3331
|
-
const whichCmd =
|
|
3498
|
+
const platform10 = os2.platform();
|
|
3499
|
+
const whichCmd = platform10 === "win32" ? "where" : "which";
|
|
3332
3500
|
try {
|
|
3333
3501
|
const explicitPath = resolveCommandPath(target.command);
|
|
3334
3502
|
const pathResult = explicitPath || await execAsync(`${whichCmd} ${shellQuote(target.command)}`);
|
|
@@ -3449,6 +3617,10 @@ var DaemonCdpManager = class {
|
|
|
3449
3617
|
setTargetFilter(filter) {
|
|
3450
3618
|
this._targetFilter = filter;
|
|
3451
3619
|
}
|
|
3620
|
+
/** Clear a previously pinned target so the next connect can reselect a page. */
|
|
3621
|
+
clearTargetId() {
|
|
3622
|
+
this._targetId = null;
|
|
3623
|
+
}
|
|
3452
3624
|
/**
|
|
3453
3625
|
* Check if a page title should be excluded (non-main page).
|
|
3454
3626
|
* Uses provider-configured titleExcludes, falls back to default pattern.
|
|
@@ -5992,7 +6164,8 @@ var IdeProviderInstance = class {
|
|
|
5992
6164
|
}
|
|
5993
6165
|
}
|
|
5994
6166
|
if (!raw || typeof raw !== "object") return;
|
|
5995
|
-
|
|
6167
|
+
const chat = raw;
|
|
6168
|
+
let { activeModal } = chat;
|
|
5996
6169
|
if (activeModal) {
|
|
5997
6170
|
const w = activeModal.width ?? Infinity;
|
|
5998
6171
|
const h = activeModal.height ?? Infinity;
|
|
@@ -6012,26 +6185,28 @@ var IdeProviderInstance = class {
|
|
|
6012
6185
|
if (pm.receivedAt) prevByHash.set(h, pm.receivedAt);
|
|
6013
6186
|
}
|
|
6014
6187
|
const now = Date.now();
|
|
6015
|
-
|
|
6188
|
+
const messages = chat.messages || [];
|
|
6189
|
+
for (const msg of messages) {
|
|
6016
6190
|
const h = `${msg.role}:${(msg.content || "").slice(0, 100)}`;
|
|
6017
6191
|
msg.receivedAt = prevByHash.get(h) || now;
|
|
6018
6192
|
}
|
|
6019
|
-
if (
|
|
6193
|
+
if (messages.length > 0) {
|
|
6020
6194
|
const hiddenKinds = /* @__PURE__ */ new Set();
|
|
6021
6195
|
if (this.settings.showThinking === false) hiddenKinds.add("thought");
|
|
6022
6196
|
if (this.settings.showToolCalls === false) hiddenKinds.add("tool");
|
|
6023
6197
|
if (this.settings.showTerminal === false) hiddenKinds.add("terminal");
|
|
6024
6198
|
if (hiddenKinds.size > 0) {
|
|
6025
|
-
|
|
6199
|
+
chat.messages = messages.filter((m) => !hiddenKinds.has(m.kind || ""));
|
|
6026
6200
|
}
|
|
6027
6201
|
}
|
|
6028
|
-
const controlValues = extractProviderControlValues(this.provider.controls,
|
|
6029
|
-
if (controlValues)
|
|
6030
|
-
this.cachedChat = { ...
|
|
6031
|
-
this.detectAgentTransitions(
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6202
|
+
const controlValues = extractProviderControlValues(this.provider.controls, chat);
|
|
6203
|
+
if (controlValues) chat.controlValues = controlValues;
|
|
6204
|
+
this.cachedChat = { ...chat, activeModal };
|
|
6205
|
+
this.detectAgentTransitions(chat, now);
|
|
6206
|
+
const persistedMessages = chat.messages || messages;
|
|
6207
|
+
if (persistedMessages.length > 0) {
|
|
6208
|
+
let toSave = persistedMessages;
|
|
6209
|
+
if (chat.status === "generating" || chat.status === "long_generating") {
|
|
6035
6210
|
const lastIdx = toSave.length - 1;
|
|
6036
6211
|
if (lastIdx >= 0 && toSave[lastIdx].role === "assistant") {
|
|
6037
6212
|
toSave = toSave.slice(0, lastIdx);
|
|
@@ -6041,7 +6216,7 @@ var IdeProviderInstance = class {
|
|
|
6041
6216
|
this.historyWriter.appendNewMessages(
|
|
6042
6217
|
this.type,
|
|
6043
6218
|
toSave,
|
|
6044
|
-
|
|
6219
|
+
chat.title,
|
|
6045
6220
|
this.instanceId
|
|
6046
6221
|
);
|
|
6047
6222
|
}
|
|
@@ -6057,7 +6232,7 @@ var IdeProviderInstance = class {
|
|
|
6057
6232
|
getReadChatScript() {
|
|
6058
6233
|
const scripts = this.provider.scripts;
|
|
6059
6234
|
if (!scripts?.readChat) return null;
|
|
6060
|
-
return
|
|
6235
|
+
return scripts.readChat({});
|
|
6061
6236
|
}
|
|
6062
6237
|
// ─── status transition detect ─────────────────────────────
|
|
6063
6238
|
detectAgentTransitions(chatData, now) {
|
|
@@ -7128,7 +7303,7 @@ function getTargetInstance(h, args) {
|
|
|
7128
7303
|
const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
|
|
7129
7304
|
const sessionId = targetSessionId || h.currentSession?.sessionId || "";
|
|
7130
7305
|
if (!sessionId) return null;
|
|
7131
|
-
return h.ctx.instanceManager?.getInstance(sessionId);
|
|
7306
|
+
return h.ctx.instanceManager?.getInstance(sessionId) || null;
|
|
7132
7307
|
}
|
|
7133
7308
|
function getTargetTransport(h, provider) {
|
|
7134
7309
|
if (h.currentSession?.transport) return h.currentSession.transport;
|
|
@@ -7166,6 +7341,10 @@ function getHistorySessionId(h, args) {
|
|
|
7166
7341
|
const providerSessionId = typeof state?.providerSessionId === "string" ? state.providerSessionId.trim() : "";
|
|
7167
7342
|
return providerSessionId || targetSessionId;
|
|
7168
7343
|
}
|
|
7344
|
+
function callLegacyTextScript(script, text) {
|
|
7345
|
+
if (typeof script !== "function") return null;
|
|
7346
|
+
return script(text);
|
|
7347
|
+
}
|
|
7169
7348
|
function isRecentDuplicateSend(key) {
|
|
7170
7349
|
const now = Date.now();
|
|
7171
7350
|
for (const [candidate, ts2] of recentSendByTarget.entries()) {
|
|
@@ -7255,7 +7434,7 @@ async function handleReadChat(h, args) {
|
|
|
7255
7434
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7256
7435
|
if (adapter) {
|
|
7257
7436
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
7258
|
-
const status = adapter.getStatus
|
|
7437
|
+
const status = adapter.getStatus();
|
|
7259
7438
|
if (status) {
|
|
7260
7439
|
return {
|
|
7261
7440
|
success: true,
|
|
@@ -7495,7 +7674,7 @@ async function handleSendChat(h, args) {
|
|
|
7495
7674
|
}
|
|
7496
7675
|
if (parsed?.needsTypeAndSend && provider?.webviewMatchText && provider?.scripts?.webviewSendMessage) {
|
|
7497
7676
|
try {
|
|
7498
|
-
const webviewScript = provider.scripts.webviewSendMessage
|
|
7677
|
+
const webviewScript = callLegacyTextScript(provider.scripts.webviewSendMessage, text);
|
|
7499
7678
|
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
7500
7679
|
const matchText = provider.webviewMatchText;
|
|
7501
7680
|
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
@@ -7518,7 +7697,7 @@ async function handleSendChat(h, args) {
|
|
|
7518
7697
|
}
|
|
7519
7698
|
if (provider?.webviewMatchText && provider?.scripts?.webviewSendMessage) {
|
|
7520
7699
|
try {
|
|
7521
|
-
const webviewScript = provider.scripts.webviewSendMessage
|
|
7700
|
+
const webviewScript = callLegacyTextScript(provider.scripts.webviewSendMessage, text);
|
|
7522
7701
|
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
7523
7702
|
const matchText = provider.webviewMatchText;
|
|
7524
7703
|
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
@@ -7750,12 +7929,10 @@ async function handleSetMode(h, args) {
|
|
|
7750
7929
|
const mode = args?.mode || "agent";
|
|
7751
7930
|
if (transport === "acp") {
|
|
7752
7931
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
return { success: true, mode };
|
|
7758
|
-
}
|
|
7932
|
+
const acpInstance = adapter?._acpInstance;
|
|
7933
|
+
if (acpInstance && typeof acpInstance.setMode === "function") {
|
|
7934
|
+
await acpInstance.setMode(mode);
|
|
7935
|
+
return { success: true, mode };
|
|
7759
7936
|
}
|
|
7760
7937
|
return { success: false, error: "ACP adapter not found" };
|
|
7761
7938
|
}
|
|
@@ -7808,13 +7985,11 @@ async function handleChangeModel(h, args) {
|
|
|
7808
7985
|
if (transport === "acp") {
|
|
7809
7986
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7810
7987
|
LOG.info("Command", `[change_model] ACP adapter found: ${!!adapter}, type=${adapter?.cliType}, hasAcpInstance=${!!adapter?._acpInstance}`);
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
return { success: true, model };
|
|
7817
|
-
}
|
|
7988
|
+
const acpInstance = adapter?._acpInstance;
|
|
7989
|
+
if (acpInstance && typeof acpInstance.setConfigOption === "function") {
|
|
7990
|
+
await acpInstance.setConfigOption("model", model);
|
|
7991
|
+
LOG.info("Command", `[change_model] Updated ACP model to ${model}`);
|
|
7992
|
+
return { success: true, model };
|
|
7818
7993
|
}
|
|
7819
7994
|
return { success: false, error: "ACP adapter not found" };
|
|
7820
7995
|
}
|
|
@@ -7871,6 +8046,9 @@ async function handleSetThoughtLevel(h, args) {
|
|
|
7871
8046
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7872
8047
|
const acpInstance = adapter?._acpInstance;
|
|
7873
8048
|
if (!acpInstance) return { success: false, error: "ACP instance not found" };
|
|
8049
|
+
if (typeof acpInstance.setConfigOption !== "function") {
|
|
8050
|
+
return { success: false, error: "ACP setConfigOption not available" };
|
|
8051
|
+
}
|
|
7874
8052
|
try {
|
|
7875
8053
|
await acpInstance.setConfigOption(configId, value);
|
|
7876
8054
|
LOG.info("Command", `[set_thought_level] ${configId}=${value} for ${provider?.type || "unknown_acp"}`);
|
|
@@ -7897,7 +8075,7 @@ async function handleResolveAction(h, args) {
|
|
|
7897
8075
|
return { success: false, error: `CLI resolveAction failed: ${e.message}` };
|
|
7898
8076
|
}
|
|
7899
8077
|
}
|
|
7900
|
-
const status = adapter.getStatus
|
|
8078
|
+
const status = adapter.getStatus();
|
|
7901
8079
|
if (status?.status !== "waiting_approval") {
|
|
7902
8080
|
return { success: false, error: "Not in approval state" };
|
|
7903
8081
|
}
|
|
@@ -7936,6 +8114,9 @@ async function handleResolveAction(h, args) {
|
|
|
7936
8114
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7937
8115
|
const acpInstance = adapter?._acpInstance;
|
|
7938
8116
|
if (!acpInstance) return { success: false, error: "ACP instance not found" };
|
|
8117
|
+
if (typeof acpInstance.resolvePermission !== "function") {
|
|
8118
|
+
return { success: false, error: "ACP resolvePermission not available" };
|
|
8119
|
+
}
|
|
7939
8120
|
try {
|
|
7940
8121
|
await acpInstance.resolvePermission(action === "approve" || action === "accept" || action === "always");
|
|
7941
8122
|
LOG.info("Command", `[resolveAction] ACP \u2192 ${action}`);
|
|
@@ -8097,11 +8278,16 @@ async function handleCdpCommand(h, args) {
|
|
|
8097
8278
|
}
|
|
8098
8279
|
async function handleCdpBatch(h, args) {
|
|
8099
8280
|
if (!h.getCdp()?.isConnected) return { success: false, error: "CDP not connected" };
|
|
8100
|
-
const commands = args?.commands;
|
|
8281
|
+
const commands = Array.isArray(args?.commands) ? args.commands : null;
|
|
8101
8282
|
const stopOnError = args?.stopOnError !== false;
|
|
8102
8283
|
if (!commands?.length) return { success: false, error: "commands array required" };
|
|
8103
8284
|
const results = [];
|
|
8104
8285
|
for (const cmd of commands) {
|
|
8286
|
+
if (!cmd || typeof cmd !== "object" || typeof cmd.method !== "string") {
|
|
8287
|
+
results.push({ method: null, success: false, error: "Invalid command entry" });
|
|
8288
|
+
if (stopOnError) break;
|
|
8289
|
+
continue;
|
|
8290
|
+
}
|
|
8105
8291
|
try {
|
|
8106
8292
|
const result = await h.getCdp().sendCdpCommand(cmd.method, cmd.params || {});
|
|
8107
8293
|
results.push({ method: cmd.method, success: true, result });
|
|
@@ -8396,11 +8582,12 @@ function handlePtyResize(h, args) {
|
|
|
8396
8582
|
if (!adapter || typeof adapter.resize !== "function") {
|
|
8397
8583
|
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
|
|
8398
8584
|
}
|
|
8585
|
+
const resize = adapter.resize;
|
|
8399
8586
|
if (force) {
|
|
8400
|
-
|
|
8401
|
-
setTimeout(() =>
|
|
8587
|
+
resize(cols - 1, rows);
|
|
8588
|
+
setTimeout(() => resize(cols, rows), 50);
|
|
8402
8589
|
} else {
|
|
8403
|
-
|
|
8590
|
+
resize(cols, rows);
|
|
8404
8591
|
}
|
|
8405
8592
|
return { success: true };
|
|
8406
8593
|
}
|
|
@@ -8458,7 +8645,7 @@ function parseScriptResult(result) {
|
|
|
8458
8645
|
return { success: true, payload: { result } };
|
|
8459
8646
|
}
|
|
8460
8647
|
}
|
|
8461
|
-
if (result && typeof result === "object" && result.success === false) {
|
|
8648
|
+
if (result && typeof result === "object" && "success" in result && result.success === false) {
|
|
8462
8649
|
return { success: false, payload: result };
|
|
8463
8650
|
}
|
|
8464
8651
|
return { success: true, payload: result };
|
|
@@ -8881,24 +9068,25 @@ var DaemonCommandHandler = class {
|
|
|
8881
9068
|
if (provider?.scripts) {
|
|
8882
9069
|
const fn = provider.scripts[scriptName];
|
|
8883
9070
|
if (typeof fn === "function") {
|
|
9071
|
+
const callScript = fn;
|
|
8884
9072
|
if (params && Object.keys(params).length > 0) {
|
|
8885
9073
|
const firstVal = Object.values(params)[0];
|
|
8886
9074
|
if (scriptName === "sendMessage" && typeof firstVal === "string") {
|
|
8887
|
-
const legacyScript =
|
|
9075
|
+
const legacyScript = callScript(firstVal);
|
|
8888
9076
|
if (legacyScript) return legacyScript;
|
|
8889
9077
|
}
|
|
8890
|
-
const script =
|
|
9078
|
+
const script = callScript(params);
|
|
8891
9079
|
if (script) {
|
|
8892
9080
|
const likelyLegacyObjectLeak = typeof script === "string" && script.includes("[object Object]") && typeof firstVal === "string";
|
|
8893
9081
|
if (!likelyLegacyObjectLeak) return script;
|
|
8894
9082
|
}
|
|
8895
9083
|
if (firstVal !== void 0) {
|
|
8896
|
-
const legacyScript =
|
|
9084
|
+
const legacyScript = callScript(firstVal);
|
|
8897
9085
|
if (legacyScript) return legacyScript;
|
|
8898
9086
|
}
|
|
8899
9087
|
if (script) return script;
|
|
8900
9088
|
} else {
|
|
8901
|
-
const script =
|
|
9089
|
+
const script = callScript();
|
|
8902
9090
|
if (script) return script;
|
|
8903
9091
|
}
|
|
8904
9092
|
}
|
|
@@ -9279,16 +9467,16 @@ var DaemonCommandHandler = class {
|
|
|
9279
9467
|
|
|
9280
9468
|
// src/commands/cli-manager.ts
|
|
9281
9469
|
init_provider_cli_adapter();
|
|
9282
|
-
import * as
|
|
9283
|
-
import * as
|
|
9470
|
+
import * as os12 from "os";
|
|
9471
|
+
import * as path12 from "path";
|
|
9284
9472
|
import * as crypto4 from "crypto";
|
|
9285
9473
|
import chalk from "chalk";
|
|
9286
9474
|
init_config();
|
|
9287
9475
|
|
|
9288
9476
|
// src/providers/cli-provider-instance.ts
|
|
9289
9477
|
init_provider_cli_adapter();
|
|
9290
|
-
import * as
|
|
9291
|
-
import * as
|
|
9478
|
+
import * as os11 from "os";
|
|
9479
|
+
import * as path11 from "path";
|
|
9292
9480
|
import * as crypto3 from "crypto";
|
|
9293
9481
|
import * as fs5 from "fs";
|
|
9294
9482
|
import { createRequire } from "module";
|
|
@@ -9296,7 +9484,7 @@ init_logger();
|
|
|
9296
9484
|
var CachedDatabaseSync = null;
|
|
9297
9485
|
function getDatabaseSync() {
|
|
9298
9486
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
9299
|
-
const requireFn = typeof __require === "function" ? __require : createRequire(
|
|
9487
|
+
const requireFn = typeof __require === "function" ? __require : createRequire(path11.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
9300
9488
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
9301
9489
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
9302
9490
|
if (!CachedDatabaseSync) {
|
|
@@ -9436,7 +9624,7 @@ var CliProviderInstance = class {
|
|
|
9436
9624
|
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
9437
9625
|
*/
|
|
9438
9626
|
probeSessionIdFromConfig(probe) {
|
|
9439
|
-
const resolvedDbPath = probe.dbPath.replace(/^~/,
|
|
9627
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os11.homedir());
|
|
9440
9628
|
if (!fs5.existsSync(resolvedDbPath)) return null;
|
|
9441
9629
|
const directories = this.getProbeDirectories();
|
|
9442
9630
|
const minCreatedAt = Math.max(0, this.startedAt - 6e4);
|
|
@@ -10866,7 +11054,8 @@ var AcpProviderInstance = class {
|
|
|
10866
11054
|
|
|
10867
11055
|
// src/commands/cli-manager.ts
|
|
10868
11056
|
init_logger();
|
|
10869
|
-
var
|
|
11057
|
+
var chalkModule = chalk;
|
|
11058
|
+
var chalkApi = typeof chalkModule.yellow === "function" ? chalkModule : chalkModule.default || null;
|
|
10870
11059
|
function colorize(color, text) {
|
|
10871
11060
|
const fn = chalkApi?.[color];
|
|
10872
11061
|
return typeof fn === "function" ? fn(text) : text;
|
|
@@ -11116,7 +11305,7 @@ var DaemonCliManager = class {
|
|
|
11116
11305
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
11117
11306
|
const trimmed = (workingDir || "").trim();
|
|
11118
11307
|
if (!trimmed) throw new Error("working directory required");
|
|
11119
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
11308
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os12.homedir()) : path12.resolve(trimmed);
|
|
11120
11309
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
11121
11310
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
11122
11311
|
const key = crypto4.randomUUID();
|
|
@@ -11155,6 +11344,7 @@ ${installInfo}`
|
|
|
11155
11344
|
});
|
|
11156
11345
|
this.adapters.set(key, {
|
|
11157
11346
|
cliType: normalizedType,
|
|
11347
|
+
cliName: provider.name,
|
|
11158
11348
|
workingDir: resolvedDir,
|
|
11159
11349
|
_acpInstance: acpInstance,
|
|
11160
11350
|
spawn: async () => {
|
|
@@ -11173,6 +11363,12 @@ ${installInfo}`
|
|
|
11173
11363
|
activeModal: state.activeChat?.activeModal || null
|
|
11174
11364
|
};
|
|
11175
11365
|
},
|
|
11366
|
+
getPartialResponse: () => "",
|
|
11367
|
+
cancel: () => {
|
|
11368
|
+
instanceManager2.removeInstance(key);
|
|
11369
|
+
},
|
|
11370
|
+
isProcessing: () => false,
|
|
11371
|
+
isReady: () => true,
|
|
11176
11372
|
setOnStatusChange: () => {
|
|
11177
11373
|
},
|
|
11178
11374
|
setOnPtyData: () => {
|
|
@@ -11579,13 +11775,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
11579
11775
|
// src/launch.ts
|
|
11580
11776
|
import { execSync as execSync4, spawn as spawn2 } from "child_process";
|
|
11581
11777
|
import * as net from "net";
|
|
11582
|
-
import * as
|
|
11583
|
-
import * as
|
|
11778
|
+
import * as os14 from "os";
|
|
11779
|
+
import * as path14 from "path";
|
|
11584
11780
|
|
|
11585
11781
|
// src/providers/provider-loader.ts
|
|
11586
11782
|
import * as fs6 from "fs";
|
|
11587
|
-
import * as
|
|
11588
|
-
import * as
|
|
11783
|
+
import * as path13 from "path";
|
|
11784
|
+
import * as os13 from "os";
|
|
11589
11785
|
import * as chokidar from "chokidar";
|
|
11590
11786
|
init_logger();
|
|
11591
11787
|
var ProviderLoader = class _ProviderLoader {
|
|
@@ -11606,12 +11802,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11606
11802
|
static META_FILE = ".meta.json";
|
|
11607
11803
|
constructor(options) {
|
|
11608
11804
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
11609
|
-
const defaultProvidersDir =
|
|
11805
|
+
const defaultProvidersDir = path13.join(os13.homedir(), ".adhdev", "providers");
|
|
11610
11806
|
if (options?.userDir) {
|
|
11611
11807
|
this.userDir = options.userDir;
|
|
11612
11808
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
11613
11809
|
} else {
|
|
11614
|
-
const localRepoPath =
|
|
11810
|
+
const localRepoPath = path13.resolve(__dirname, "../../../../../adhdev-providers");
|
|
11615
11811
|
if (fs6.existsSync(localRepoPath)) {
|
|
11616
11812
|
this.userDir = localRepoPath;
|
|
11617
11813
|
this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
|
|
@@ -11620,7 +11816,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11620
11816
|
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
11621
11817
|
}
|
|
11622
11818
|
}
|
|
11623
|
-
this.upstreamDir =
|
|
11819
|
+
this.upstreamDir = path13.join(defaultProvidersDir, ".upstream");
|
|
11624
11820
|
this.disableUpstream = options?.disableUpstream ?? false;
|
|
11625
11821
|
}
|
|
11626
11822
|
log(msg) {
|
|
@@ -11650,7 +11846,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11650
11846
|
* Canonical provider directory shape for a given root.
|
|
11651
11847
|
*/
|
|
11652
11848
|
getProviderDir(root, category, type) {
|
|
11653
|
-
return
|
|
11849
|
+
return path13.join(root, category, type);
|
|
11654
11850
|
}
|
|
11655
11851
|
/**
|
|
11656
11852
|
* Canonical user override directory for a provider.
|
|
@@ -11677,7 +11873,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11677
11873
|
resolveProviderFile(type, ...segments) {
|
|
11678
11874
|
const dir = this.findProviderDirInternal(type);
|
|
11679
11875
|
if (!dir) return null;
|
|
11680
|
-
return
|
|
11876
|
+
return path13.join(dir, ...segments);
|
|
11681
11877
|
}
|
|
11682
11878
|
/**
|
|
11683
11879
|
* Load all providers (3-tier priority)
|
|
@@ -11716,7 +11912,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11716
11912
|
if (!fs6.existsSync(this.upstreamDir)) return false;
|
|
11717
11913
|
try {
|
|
11718
11914
|
return fs6.readdirSync(this.upstreamDir).some(
|
|
11719
|
-
(d) => fs6.statSync(
|
|
11915
|
+
(d) => fs6.statSync(path13.join(this.upstreamDir, d)).isDirectory()
|
|
11720
11916
|
);
|
|
11721
11917
|
} catch {
|
|
11722
11918
|
return false;
|
|
@@ -11757,8 +11953,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11757
11953
|
const result = [];
|
|
11758
11954
|
for (const p of this.providers.values()) {
|
|
11759
11955
|
if ((p.category === "cli" || p.category === "acp") && p.spawn?.command) {
|
|
11760
|
-
const
|
|
11761
|
-
const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[process.platform] : verCmdConfig;
|
|
11956
|
+
const versionCommand = this.getPlatformVersionCommand(p.versionCommand);
|
|
11762
11957
|
const command = this.getSpawnCommand(p.type, p.spawn.command);
|
|
11763
11958
|
result.push({
|
|
11764
11959
|
id: p.type,
|
|
@@ -11812,8 +12007,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11812
12007
|
* that runtime attach/remove uses.
|
|
11813
12008
|
*/
|
|
11814
12009
|
getIdeExtensionEnabledState(ideType, extensionType) {
|
|
11815
|
-
const
|
|
11816
|
-
|
|
12010
|
+
const config = this.readConfig();
|
|
12011
|
+
if (!config) return false;
|
|
11817
12012
|
const baseIdeType = ideType.split("_")[0];
|
|
11818
12013
|
const val = config.ideSettings?.[baseIdeType]?.extensions?.[extensionType]?.enabled;
|
|
11819
12014
|
return val === true;
|
|
@@ -11822,15 +12017,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11822
12017
|
* Save IDE extension enabled setting
|
|
11823
12018
|
*/
|
|
11824
12019
|
setIdeExtensionEnabled(ideType, extensionType, enabled) {
|
|
12020
|
+
const config = this.readConfig();
|
|
12021
|
+
if (!config) return false;
|
|
11825
12022
|
try {
|
|
11826
|
-
const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
|
|
11827
|
-
const config = loadConfig2();
|
|
11828
12023
|
const baseIdeType = ideType.split("_")[0];
|
|
11829
12024
|
if (!config.ideSettings) config.ideSettings = {};
|
|
11830
12025
|
if (!config.ideSettings[baseIdeType]) config.ideSettings[baseIdeType] = {};
|
|
11831
12026
|
if (!config.ideSettings[baseIdeType].extensions) config.ideSettings[baseIdeType].extensions = {};
|
|
11832
12027
|
config.ideSettings[baseIdeType].extensions[extensionType] = { enabled };
|
|
11833
|
-
|
|
12028
|
+
this.writeConfig(config);
|
|
11834
12029
|
this.log(`IDE extension setting: ${ideType}.${extensionType}.enabled = ${enabled}`);
|
|
11835
12030
|
return true;
|
|
11836
12031
|
} catch (e) {
|
|
@@ -12020,7 +12215,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12020
12215
|
}
|
|
12021
12216
|
if (currentVersion) {
|
|
12022
12217
|
resolved._resolvedVersion = currentVersion;
|
|
12023
|
-
if (
|
|
12218
|
+
if (base.compatibility) {
|
|
12024
12219
|
const compat = base.compatibility;
|
|
12025
12220
|
let matched = false;
|
|
12026
12221
|
for (const entry of compat) {
|
|
@@ -12032,8 +12227,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12032
12227
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
12033
12228
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
12034
12229
|
if (providerDir) {
|
|
12035
|
-
const fullDir =
|
|
12036
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
12230
|
+
const fullDir = path13.join(providerDir, entry.scriptDir);
|
|
12231
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
|
|
12037
12232
|
}
|
|
12038
12233
|
matched = true;
|
|
12039
12234
|
}
|
|
@@ -12048,8 +12243,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12048
12243
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
12049
12244
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
12050
12245
|
if (providerDir) {
|
|
12051
|
-
const fullDir =
|
|
12052
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
12246
|
+
const fullDir = path13.join(providerDir, base.defaultScriptDir);
|
|
12247
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
|
|
12053
12248
|
}
|
|
12054
12249
|
}
|
|
12055
12250
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -12066,8 +12261,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12066
12261
|
resolved._resolvedScriptDir = dirOverride;
|
|
12067
12262
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
12068
12263
|
if (providerDir) {
|
|
12069
|
-
const fullDir =
|
|
12070
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
12264
|
+
const fullDir = path13.join(providerDir, dirOverride);
|
|
12265
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
|
|
12071
12266
|
}
|
|
12072
12267
|
}
|
|
12073
12268
|
} else if (override.scripts) {
|
|
@@ -12075,7 +12270,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12075
12270
|
}
|
|
12076
12271
|
}
|
|
12077
12272
|
}
|
|
12078
|
-
} else if (
|
|
12273
|
+
} else if (base.compatibility && base.defaultScriptDir) {
|
|
12079
12274
|
const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
|
|
12080
12275
|
if (loaded) {
|
|
12081
12276
|
resolved.scripts = loaded;
|
|
@@ -12083,8 +12278,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12083
12278
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
12084
12279
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
12085
12280
|
if (providerDir) {
|
|
12086
|
-
const fullDir =
|
|
12087
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
12281
|
+
const fullDir = path13.join(providerDir, base.defaultScriptDir);
|
|
12282
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path13.join(fullDir, "scripts.js")) ? path13.join(fullDir, "scripts.js") : fullDir;
|
|
12088
12283
|
}
|
|
12089
12284
|
}
|
|
12090
12285
|
}
|
|
@@ -12109,14 +12304,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12109
12304
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
12110
12305
|
return null;
|
|
12111
12306
|
}
|
|
12112
|
-
const dir =
|
|
12307
|
+
const dir = path13.join(providerDir, scriptDir);
|
|
12113
12308
|
if (!fs6.existsSync(dir)) {
|
|
12114
12309
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
12115
12310
|
return null;
|
|
12116
12311
|
}
|
|
12117
12312
|
const cached = this.scriptsCache.get(dir);
|
|
12118
12313
|
if (cached) return cached;
|
|
12119
|
-
const scriptsJs =
|
|
12314
|
+
const scriptsJs = path13.join(dir, "scripts.js");
|
|
12120
12315
|
if (fs6.existsSync(scriptsJs)) {
|
|
12121
12316
|
try {
|
|
12122
12317
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
@@ -12158,7 +12353,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12158
12353
|
return;
|
|
12159
12354
|
}
|
|
12160
12355
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
12161
|
-
this.log(`File changed: ${
|
|
12356
|
+
this.log(`File changed: ${path13.basename(filePath)}, reloading...`);
|
|
12162
12357
|
this.reload();
|
|
12163
12358
|
}
|
|
12164
12359
|
};
|
|
@@ -12213,7 +12408,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12213
12408
|
}
|
|
12214
12409
|
const https = __require("https");
|
|
12215
12410
|
const { execSync: execSync7 } = __require("child_process");
|
|
12216
|
-
const metaPath =
|
|
12411
|
+
const metaPath = path13.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
12217
12412
|
let prevEtag = "";
|
|
12218
12413
|
let prevTimestamp = 0;
|
|
12219
12414
|
try {
|
|
@@ -12273,17 +12468,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12273
12468
|
return { updated: false };
|
|
12274
12469
|
}
|
|
12275
12470
|
this.log("Downloading latest providers from GitHub...");
|
|
12276
|
-
const tmpTar =
|
|
12277
|
-
const tmpExtract =
|
|
12471
|
+
const tmpTar = path13.join(os13.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
12472
|
+
const tmpExtract = path13.join(os13.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
12278
12473
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
12279
12474
|
fs6.mkdirSync(tmpExtract, { recursive: true });
|
|
12280
12475
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
12281
12476
|
const extracted = fs6.readdirSync(tmpExtract);
|
|
12282
12477
|
const rootDir = extracted.find(
|
|
12283
|
-
(d) => fs6.statSync(
|
|
12478
|
+
(d) => fs6.statSync(path13.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
12284
12479
|
);
|
|
12285
12480
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
12286
|
-
const sourceDir =
|
|
12481
|
+
const sourceDir = path13.join(tmpExtract, rootDir);
|
|
12287
12482
|
const backupDir = this.upstreamDir + ".bak";
|
|
12288
12483
|
if (fs6.existsSync(this.upstreamDir)) {
|
|
12289
12484
|
if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -12358,8 +12553,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12358
12553
|
copyDirRecursive(src, dest) {
|
|
12359
12554
|
fs6.mkdirSync(dest, { recursive: true });
|
|
12360
12555
|
for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
|
|
12361
|
-
const srcPath =
|
|
12362
|
-
const destPath =
|
|
12556
|
+
const srcPath = path13.join(src, entry.name);
|
|
12557
|
+
const destPath = path13.join(dest, entry.name);
|
|
12363
12558
|
if (entry.isDirectory()) {
|
|
12364
12559
|
this.copyDirRecursive(srcPath, destPath);
|
|
12365
12560
|
} else {
|
|
@@ -12370,7 +12565,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12370
12565
|
/** .meta.json save */
|
|
12371
12566
|
writeMeta(metaPath, etag, timestamp) {
|
|
12372
12567
|
try {
|
|
12373
|
-
fs6.mkdirSync(
|
|
12568
|
+
fs6.mkdirSync(path13.dirname(metaPath), { recursive: true });
|
|
12374
12569
|
fs6.writeFileSync(metaPath, JSON.stringify({
|
|
12375
12570
|
etag,
|
|
12376
12571
|
timestamp,
|
|
@@ -12387,7 +12582,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12387
12582
|
const scan = (d) => {
|
|
12388
12583
|
try {
|
|
12389
12584
|
for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
|
|
12390
|
-
if (entry.isDirectory()) scan(
|
|
12585
|
+
if (entry.isDirectory()) scan(path13.join(d, entry.name));
|
|
12391
12586
|
else if (entry.name === "provider.json") count++;
|
|
12392
12587
|
}
|
|
12393
12588
|
} catch {
|
|
@@ -12421,14 +12616,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12421
12616
|
getSettingValue(type, key) {
|
|
12422
12617
|
const schemaDef = this.getSettingsSchema(type)[key];
|
|
12423
12618
|
const defaultVal = schemaDef ? key === "autoApprove" && schemaDef.type === "boolean" ? true : schemaDef.default : void 0;
|
|
12424
|
-
|
|
12425
|
-
|
|
12426
|
-
|
|
12427
|
-
const userVal = config.providerSettings?.[type]?.[key];
|
|
12428
|
-
return userVal !== void 0 ? userVal : defaultVal;
|
|
12429
|
-
} catch {
|
|
12430
|
-
return defaultVal;
|
|
12431
|
-
}
|
|
12619
|
+
const config = this.readConfig();
|
|
12620
|
+
const userVal = config?.providerSettings?.[type]?.[key];
|
|
12621
|
+
return userVal !== void 0 ? userVal : defaultVal;
|
|
12432
12622
|
}
|
|
12433
12623
|
/**
|
|
12434
12624
|
* All resolved settings for a provider (default + user override)
|
|
@@ -12456,13 +12646,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12456
12646
|
if (schemaDef.max !== void 0 && value > schemaDef.max) return false;
|
|
12457
12647
|
}
|
|
12458
12648
|
if (schemaDef.type === "select" && schemaDef.options && !schemaDef.options.includes(value)) return false;
|
|
12649
|
+
const config = this.readConfig();
|
|
12650
|
+
if (!config) return false;
|
|
12459
12651
|
try {
|
|
12460
|
-
const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
|
|
12461
|
-
const config = loadConfig2();
|
|
12462
12652
|
if (!config.providerSettings) config.providerSettings = {};
|
|
12463
12653
|
if (!config.providerSettings[type]) config.providerSettings[type] = {};
|
|
12464
12654
|
config.providerSettings[type][key] = value;
|
|
12465
|
-
|
|
12655
|
+
this.writeConfig(config);
|
|
12466
12656
|
this.log(`Setting updated: ${type}.${key} = ${JSON.stringify(value)}`);
|
|
12467
12657
|
return true;
|
|
12468
12658
|
} catch (e) {
|
|
@@ -12476,6 +12666,34 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12476
12666
|
const trimmed = value.trim();
|
|
12477
12667
|
return trimmed ? trimmed : null;
|
|
12478
12668
|
}
|
|
12669
|
+
readConfig() {
|
|
12670
|
+
try {
|
|
12671
|
+
const { loadConfig: loadConfig2 } = (init_config(), __toCommonJS(config_exports));
|
|
12672
|
+
return loadConfig2();
|
|
12673
|
+
} catch {
|
|
12674
|
+
return null;
|
|
12675
|
+
}
|
|
12676
|
+
}
|
|
12677
|
+
writeConfig(config) {
|
|
12678
|
+
const { saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
|
|
12679
|
+
saveConfig3(config);
|
|
12680
|
+
}
|
|
12681
|
+
getPlatformVersionCommand(versionCommand) {
|
|
12682
|
+
if (!versionCommand) return void 0;
|
|
12683
|
+
if (typeof versionCommand === "string") {
|
|
12684
|
+
const trimmed = versionCommand.trim();
|
|
12685
|
+
return trimmed || void 0;
|
|
12686
|
+
}
|
|
12687
|
+
const platformValue = versionCommand[process.platform];
|
|
12688
|
+
if (typeof platformValue === "string" && platformValue.trim()) {
|
|
12689
|
+
return platformValue.trim();
|
|
12690
|
+
}
|
|
12691
|
+
const defaultValue = versionCommand.default;
|
|
12692
|
+
if (typeof defaultValue === "string" && defaultValue.trim()) {
|
|
12693
|
+
return defaultValue.trim();
|
|
12694
|
+
}
|
|
12695
|
+
return void 0;
|
|
12696
|
+
}
|
|
12479
12697
|
getSettingsSchema(type) {
|
|
12480
12698
|
const provider = this.providers.get(type);
|
|
12481
12699
|
if (!provider) return {};
|
|
@@ -12549,17 +12767,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12549
12767
|
for (const root of searchRoots) {
|
|
12550
12768
|
if (!fs6.existsSync(root)) continue;
|
|
12551
12769
|
const candidate = this.getProviderDir(root, cat, type);
|
|
12552
|
-
if (fs6.existsSync(
|
|
12553
|
-
const catDir =
|
|
12770
|
+
if (fs6.existsSync(path13.join(candidate, "provider.json"))) return candidate;
|
|
12771
|
+
const catDir = path13.join(root, cat);
|
|
12554
12772
|
if (fs6.existsSync(catDir)) {
|
|
12555
12773
|
try {
|
|
12556
12774
|
for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
|
|
12557
12775
|
if (!entry.isDirectory()) continue;
|
|
12558
|
-
const jsonPath =
|
|
12776
|
+
const jsonPath = path13.join(catDir, entry.name, "provider.json");
|
|
12559
12777
|
if (fs6.existsSync(jsonPath)) {
|
|
12560
12778
|
try {
|
|
12561
12779
|
const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
|
|
12562
|
-
if (data.type === type) return
|
|
12780
|
+
if (data.type === type) return path13.join(catDir, entry.name);
|
|
12563
12781
|
} catch {
|
|
12564
12782
|
}
|
|
12565
12783
|
}
|
|
@@ -12576,7 +12794,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12576
12794
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
12577
12795
|
*/
|
|
12578
12796
|
buildScriptWrappersFromDir(dir) {
|
|
12579
|
-
const scriptsJs =
|
|
12797
|
+
const scriptsJs = path13.join(dir, "scripts.js");
|
|
12580
12798
|
if (fs6.existsSync(scriptsJs)) {
|
|
12581
12799
|
try {
|
|
12582
12800
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
@@ -12590,7 +12808,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12590
12808
|
for (const file of fs6.readdirSync(dir)) {
|
|
12591
12809
|
if (!file.endsWith(".js")) continue;
|
|
12592
12810
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
12593
|
-
const filePath =
|
|
12811
|
+
const filePath = path13.join(dir, file);
|
|
12594
12812
|
result[scriptName] = (...args) => {
|
|
12595
12813
|
try {
|
|
12596
12814
|
let content = fs6.readFileSync(filePath, "utf-8");
|
|
@@ -12650,35 +12868,39 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12650
12868
|
}
|
|
12651
12869
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
12652
12870
|
if (hasJson) {
|
|
12653
|
-
const jsonPath =
|
|
12871
|
+
const jsonPath = path13.join(d, "provider.json");
|
|
12654
12872
|
try {
|
|
12655
12873
|
const raw = fs6.readFileSync(jsonPath, "utf-8");
|
|
12656
12874
|
const mod = JSON.parse(raw);
|
|
12657
12875
|
if (!mod.type || !mod.name || !mod.category) {
|
|
12658
12876
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: missing type/name/category`);
|
|
12659
12877
|
} else {
|
|
12660
|
-
if (
|
|
12878
|
+
if (typeof mod.extensionIdPattern === "string") {
|
|
12661
12879
|
const flags = mod.extensionIdPattern_flags || "";
|
|
12662
12880
|
mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
|
|
12663
|
-
delete mod.extensionIdPattern_flags;
|
|
12664
12881
|
}
|
|
12665
|
-
const
|
|
12666
|
-
const
|
|
12882
|
+
const { extensionIdPattern_flags, extensionIdPattern, ...providerFields } = mod;
|
|
12883
|
+
const normalizedProvider = {
|
|
12884
|
+
...providerFields,
|
|
12885
|
+
...extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}
|
|
12886
|
+
};
|
|
12887
|
+
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
12888
|
+
const scriptsPath = path13.join(d, "scripts.js");
|
|
12667
12889
|
if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
|
|
12668
12890
|
try {
|
|
12669
12891
|
delete __require.cache[__require.resolve(scriptsPath)];
|
|
12670
12892
|
const scripts = __require(scriptsPath);
|
|
12671
|
-
|
|
12893
|
+
normalizedProvider.scripts = scripts;
|
|
12672
12894
|
} catch (e) {
|
|
12673
12895
|
this.log(`\u26A0 Failed to load scripts: ${scriptsPath}: ${e.message}`);
|
|
12674
12896
|
}
|
|
12675
12897
|
}
|
|
12676
|
-
const existed = this.providers.has(
|
|
12677
|
-
this.providers.set(
|
|
12898
|
+
const existed = this.providers.has(normalizedProvider.type);
|
|
12899
|
+
this.providers.set(normalizedProvider.type, normalizedProvider);
|
|
12678
12900
|
count++;
|
|
12679
12901
|
const source = d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
|
|
12680
12902
|
const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
|
|
12681
|
-
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${
|
|
12903
|
+
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${source}]${overrideWarning}`);
|
|
12682
12904
|
}
|
|
12683
12905
|
} catch (e) {
|
|
12684
12906
|
this.log(`\u26A0 Failed to load ${jsonPath}: ${e.message}`);
|
|
@@ -12689,7 +12911,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12689
12911
|
if (!entry.isDirectory()) continue;
|
|
12690
12912
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
12691
12913
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
12692
|
-
scan(
|
|
12914
|
+
scan(path13.join(d, entry.name));
|
|
12693
12915
|
}
|
|
12694
12916
|
}
|
|
12695
12917
|
};
|
|
@@ -12759,9 +12981,9 @@ function getWinProcessNames() {
|
|
|
12759
12981
|
function getProviderMeta(ideId) {
|
|
12760
12982
|
return getProviderLoader().getMeta(ideId);
|
|
12761
12983
|
}
|
|
12762
|
-
function getPreferredLaunchMethod(ideId,
|
|
12984
|
+
function getPreferredLaunchMethod(ideId, platform10) {
|
|
12763
12985
|
const prefer = getProviderMeta(ideId)?.launch?.prefer;
|
|
12764
|
-
const value = prefer?.[
|
|
12986
|
+
const value = prefer?.[platform10];
|
|
12765
12987
|
return value === "cli" || value === "app" || value === "auto" ? value : "auto";
|
|
12766
12988
|
}
|
|
12767
12989
|
function getCdpStartupTimeoutMs(ideId) {
|
|
@@ -12818,7 +13040,7 @@ async function isCdpActive(port) {
|
|
|
12818
13040
|
});
|
|
12819
13041
|
}
|
|
12820
13042
|
async function killIdeProcess(ideId) {
|
|
12821
|
-
const plat =
|
|
13043
|
+
const plat = os14.platform();
|
|
12822
13044
|
const appName = getMacAppIdentifiers()[ideId];
|
|
12823
13045
|
const winProcesses = getWinProcessNames()[ideId];
|
|
12824
13046
|
try {
|
|
@@ -12877,7 +13099,7 @@ async function killIdeProcess(ideId) {
|
|
|
12877
13099
|
}
|
|
12878
13100
|
}
|
|
12879
13101
|
function isIdeRunning(ideId) {
|
|
12880
|
-
const plat =
|
|
13102
|
+
const plat = os14.platform();
|
|
12881
13103
|
try {
|
|
12882
13104
|
if (plat === "darwin") {
|
|
12883
13105
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -12928,7 +13150,7 @@ function isIdeRunning(ideId) {
|
|
|
12928
13150
|
}
|
|
12929
13151
|
}
|
|
12930
13152
|
function detectCurrentWorkspace(ideId) {
|
|
12931
|
-
const plat =
|
|
13153
|
+
const plat = os14.platform();
|
|
12932
13154
|
if (plat === "darwin") {
|
|
12933
13155
|
try {
|
|
12934
13156
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -12947,8 +13169,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
12947
13169
|
const appNameMap = getMacAppIdentifiers();
|
|
12948
13170
|
const appName = appNameMap[ideId];
|
|
12949
13171
|
if (appName) {
|
|
12950
|
-
const storagePath =
|
|
12951
|
-
process.env.APPDATA ||
|
|
13172
|
+
const storagePath = path14.join(
|
|
13173
|
+
process.env.APPDATA || path14.join(os14.homedir(), "AppData", "Roaming"),
|
|
12952
13174
|
appName,
|
|
12953
13175
|
"storage.json"
|
|
12954
13176
|
);
|
|
@@ -12970,7 +13192,7 @@ function detectCurrentWorkspace(ideId) {
|
|
|
12970
13192
|
return void 0;
|
|
12971
13193
|
}
|
|
12972
13194
|
async function launchWithCdp(options = {}) {
|
|
12973
|
-
const
|
|
13195
|
+
const platform10 = os14.platform();
|
|
12974
13196
|
let targetIde;
|
|
12975
13197
|
const ides = await detectIDEs(getProviderLoader());
|
|
12976
13198
|
if (options.ideId) {
|
|
@@ -13039,9 +13261,9 @@ async function launchWithCdp(options = {}) {
|
|
|
13039
13261
|
}
|
|
13040
13262
|
const port = await findFreePort(portPair);
|
|
13041
13263
|
try {
|
|
13042
|
-
if (
|
|
13264
|
+
if (platform10 === "darwin") {
|
|
13043
13265
|
await launchMacOS(targetIde, port, workspace, options.newWindow);
|
|
13044
|
-
} else if (
|
|
13266
|
+
} else if (platform10 === "win32") {
|
|
13045
13267
|
await launchWindows(targetIde, port, workspace, options.newWindow);
|
|
13046
13268
|
} else {
|
|
13047
13269
|
await launchLinux(targetIde, port, workspace, options.newWindow);
|
|
@@ -13126,9 +13348,9 @@ init_logger();
|
|
|
13126
13348
|
|
|
13127
13349
|
// src/logging/command-log.ts
|
|
13128
13350
|
import * as fs7 from "fs";
|
|
13129
|
-
import * as
|
|
13130
|
-
import * as
|
|
13131
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
13351
|
+
import * as path15 from "path";
|
|
13352
|
+
import * as os15 from "os";
|
|
13353
|
+
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");
|
|
13132
13354
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
13133
13355
|
var MAX_DAYS = 7;
|
|
13134
13356
|
try {
|
|
@@ -13166,13 +13388,13 @@ function getDateStr2() {
|
|
|
13166
13388
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
13167
13389
|
}
|
|
13168
13390
|
var currentDate2 = getDateStr2();
|
|
13169
|
-
var currentFile =
|
|
13391
|
+
var currentFile = path15.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
13170
13392
|
var writeCount2 = 0;
|
|
13171
13393
|
function checkRotation() {
|
|
13172
13394
|
const today = getDateStr2();
|
|
13173
13395
|
if (today !== currentDate2) {
|
|
13174
13396
|
currentDate2 = today;
|
|
13175
|
-
currentFile =
|
|
13397
|
+
currentFile = path15.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
13176
13398
|
cleanOldFiles();
|
|
13177
13399
|
}
|
|
13178
13400
|
}
|
|
@@ -13186,7 +13408,7 @@ function cleanOldFiles() {
|
|
|
13186
13408
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
13187
13409
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
13188
13410
|
try {
|
|
13189
|
-
fs7.unlinkSync(
|
|
13411
|
+
fs7.unlinkSync(path15.join(LOG_DIR2, file));
|
|
13190
13412
|
} catch {
|
|
13191
13413
|
}
|
|
13192
13414
|
}
|
|
@@ -13264,7 +13486,7 @@ init_logger();
|
|
|
13264
13486
|
|
|
13265
13487
|
// src/status/snapshot.ts
|
|
13266
13488
|
init_config();
|
|
13267
|
-
import * as
|
|
13489
|
+
import * as os16 from "os";
|
|
13268
13490
|
init_terminal_screen();
|
|
13269
13491
|
init_logger();
|
|
13270
13492
|
var READ_DEBUG_ENABLED = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
@@ -13383,16 +13605,16 @@ function buildStatusSnapshot(options) {
|
|
|
13383
13605
|
version: options.version,
|
|
13384
13606
|
daemonMode: options.daemonMode,
|
|
13385
13607
|
machine: {
|
|
13386
|
-
hostname:
|
|
13387
|
-
platform:
|
|
13388
|
-
arch:
|
|
13389
|
-
cpus:
|
|
13608
|
+
hostname: os16.hostname(),
|
|
13609
|
+
platform: os16.platform(),
|
|
13610
|
+
arch: os16.arch(),
|
|
13611
|
+
cpus: os16.cpus().length,
|
|
13390
13612
|
totalMem: memSnap.totalMem,
|
|
13391
13613
|
freeMem: memSnap.freeMem,
|
|
13392
13614
|
availableMem: memSnap.availableMem,
|
|
13393
|
-
loadavg:
|
|
13394
|
-
uptime:
|
|
13395
|
-
release:
|
|
13615
|
+
loadavg: os16.loadavg(),
|
|
13616
|
+
uptime: os16.uptime(),
|
|
13617
|
+
release: os16.release()
|
|
13396
13618
|
},
|
|
13397
13619
|
machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
|
|
13398
13620
|
timestamp: options.timestamp ?? Date.now(),
|
|
@@ -13413,14 +13635,14 @@ function buildStatusSnapshot(options) {
|
|
|
13413
13635
|
import { execFileSync } from "child_process";
|
|
13414
13636
|
import { spawn as spawn3 } from "child_process";
|
|
13415
13637
|
import * as fs8 from "fs";
|
|
13416
|
-
import * as
|
|
13417
|
-
import * as
|
|
13638
|
+
import * as os17 from "os";
|
|
13639
|
+
import * as path16 from "path";
|
|
13418
13640
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
13419
13641
|
function getUpgradeLogPath() {
|
|
13420
|
-
const home =
|
|
13421
|
-
const dir =
|
|
13642
|
+
const home = os17.homedir();
|
|
13643
|
+
const dir = path16.join(home, ".adhdev");
|
|
13422
13644
|
fs8.mkdirSync(dir, { recursive: true });
|
|
13423
|
-
return
|
|
13645
|
+
return path16.join(dir, "daemon-upgrade.log");
|
|
13424
13646
|
}
|
|
13425
13647
|
function appendUpgradeLog(message) {
|
|
13426
13648
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -13460,7 +13682,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
13460
13682
|
}
|
|
13461
13683
|
}
|
|
13462
13684
|
function stopSessionHostProcesses(appName) {
|
|
13463
|
-
const pidFile =
|
|
13685
|
+
const pidFile = path16.join(os17.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
13464
13686
|
try {
|
|
13465
13687
|
if (fs8.existsSync(pidFile)) {
|
|
13466
13688
|
const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -13489,7 +13711,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
13489
13711
|
}
|
|
13490
13712
|
}
|
|
13491
13713
|
function removeDaemonPidFile() {
|
|
13492
|
-
const pidFile =
|
|
13714
|
+
const pidFile = path16.join(os17.homedir(), ".adhdev", "daemon.pid");
|
|
13493
13715
|
try {
|
|
13494
13716
|
fs8.unlinkSync(pidFile);
|
|
13495
13717
|
} catch {
|
|
@@ -13500,7 +13722,7 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
|
|
|
13500
13722
|
const npmRoot = execFileSync(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
13501
13723
|
if (!npmRoot) return;
|
|
13502
13724
|
const npmPrefix = execFileSync(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
13503
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
13725
|
+
const binDir = process.platform === "win32" ? npmPrefix : path16.join(npmPrefix, "bin");
|
|
13504
13726
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
13505
13727
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
13506
13728
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -13508,25 +13730,25 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
|
|
|
13508
13730
|
}
|
|
13509
13731
|
if (pkgName.startsWith("@")) {
|
|
13510
13732
|
const [scope, name] = pkgName.split("/");
|
|
13511
|
-
const scopeDir =
|
|
13733
|
+
const scopeDir = path16.join(npmRoot, scope);
|
|
13512
13734
|
if (!fs8.existsSync(scopeDir)) return;
|
|
13513
13735
|
for (const entry of fs8.readdirSync(scopeDir)) {
|
|
13514
13736
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
13515
|
-
fs8.rmSync(
|
|
13516
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
13737
|
+
fs8.rmSync(path16.join(scopeDir, entry), { recursive: true, force: true });
|
|
13738
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path16.join(scopeDir, entry)}`);
|
|
13517
13739
|
}
|
|
13518
13740
|
} else {
|
|
13519
13741
|
for (const entry of fs8.readdirSync(npmRoot)) {
|
|
13520
13742
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
13521
|
-
fs8.rmSync(
|
|
13522
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
13743
|
+
fs8.rmSync(path16.join(npmRoot, entry), { recursive: true, force: true });
|
|
13744
|
+
appendUpgradeLog(`Removed stale staging dir: ${path16.join(npmRoot, entry)}`);
|
|
13523
13745
|
}
|
|
13524
13746
|
}
|
|
13525
13747
|
if (fs8.existsSync(binDir)) {
|
|
13526
13748
|
for (const entry of fs8.readdirSync(binDir)) {
|
|
13527
13749
|
if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
13528
|
-
fs8.rmSync(
|
|
13529
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
13750
|
+
fs8.rmSync(path16.join(binDir, entry), { recursive: true, force: true });
|
|
13751
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path16.join(binDir, entry)}`);
|
|
13530
13752
|
}
|
|
13531
13753
|
}
|
|
13532
13754
|
}
|
|
@@ -13612,6 +13834,18 @@ var CHAT_COMMANDS = [
|
|
|
13612
13834
|
"change_model"
|
|
13613
13835
|
];
|
|
13614
13836
|
var READ_DEBUG_ENABLED2 = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
13837
|
+
function normalizeCommandSource(source) {
|
|
13838
|
+
switch (source) {
|
|
13839
|
+
case "ws":
|
|
13840
|
+
case "p2p":
|
|
13841
|
+
case "ext":
|
|
13842
|
+
case "api":
|
|
13843
|
+
case "standalone":
|
|
13844
|
+
return source;
|
|
13845
|
+
default:
|
|
13846
|
+
return "unknown";
|
|
13847
|
+
}
|
|
13848
|
+
}
|
|
13615
13849
|
function toHostedCliRuntimeDescriptor(record) {
|
|
13616
13850
|
if (!record || typeof record !== "object") return null;
|
|
13617
13851
|
const runtimeId = typeof record.sessionId === "string" ? record.sessionId : "";
|
|
@@ -13649,20 +13883,21 @@ var DaemonCommandRouter = class {
|
|
|
13649
13883
|
*/
|
|
13650
13884
|
async execute(cmd, args, source = "unknown") {
|
|
13651
13885
|
const cmdStart = Date.now();
|
|
13886
|
+
const logSource = normalizeCommandSource(source);
|
|
13652
13887
|
try {
|
|
13653
13888
|
const daemonResult = await this.executeDaemonCommand(cmd, args);
|
|
13654
13889
|
if (daemonResult) {
|
|
13655
|
-
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source, args, success: daemonResult.success, durationMs: Date.now() - cmdStart });
|
|
13890
|
+
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source: logSource, args, success: daemonResult.success, durationMs: Date.now() - cmdStart });
|
|
13656
13891
|
return daemonResult;
|
|
13657
13892
|
}
|
|
13658
13893
|
const handlerResult = await this.deps.commandHandler.handle(cmd, args);
|
|
13659
|
-
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source, args, success: handlerResult.success, durationMs: Date.now() - cmdStart });
|
|
13894
|
+
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source: logSource, args, success: handlerResult.success, durationMs: Date.now() - cmdStart });
|
|
13660
13895
|
if (CHAT_COMMANDS.includes(cmd) && this.deps.onPostChatCommand) {
|
|
13661
13896
|
this.deps.onPostChatCommand();
|
|
13662
13897
|
}
|
|
13663
13898
|
return handlerResult;
|
|
13664
13899
|
} catch (e) {
|
|
13665
|
-
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source, args, success: false, error: e.message, durationMs: Date.now() - cmdStart });
|
|
13900
|
+
logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source: logSource, args, success: false, error: e.message, durationMs: Date.now() - cmdStart });
|
|
13666
13901
|
throw e;
|
|
13667
13902
|
}
|
|
13668
13903
|
}
|
|
@@ -13932,7 +14167,7 @@ var DaemonCommandRouter = class {
|
|
|
13932
14167
|
} catch {
|
|
13933
14168
|
}
|
|
13934
14169
|
}
|
|
13935
|
-
return {
|
|
14170
|
+
return { ...result };
|
|
13936
14171
|
}
|
|
13937
14172
|
// ─── Detect IDEs ───
|
|
13938
14173
|
case "detect_ides": {
|
|
@@ -14062,16 +14297,14 @@ var DaemonCommandRouter = class {
|
|
|
14062
14297
|
}
|
|
14063
14298
|
}
|
|
14064
14299
|
for (const instanceKey of keysToRemove) {
|
|
14065
|
-
|
|
14066
|
-
if (ideInstance) {
|
|
14300
|
+
if (this.deps.instanceManager.getInstance(instanceKey)) {
|
|
14067
14301
|
this.deps.instanceManager.removeInstance(instanceKey);
|
|
14068
14302
|
LOG.info("StopIDE", `Instance removed: ${instanceKey}`);
|
|
14069
14303
|
}
|
|
14070
14304
|
}
|
|
14071
14305
|
if (keysToRemove.length === 0) {
|
|
14072
14306
|
const instanceKey = `ide:${ideType}`;
|
|
14073
|
-
|
|
14074
|
-
if (ideInstance) {
|
|
14307
|
+
if (this.deps.instanceManager.getInstance(instanceKey)) {
|
|
14075
14308
|
this.deps.instanceManager.removeInstance(instanceKey);
|
|
14076
14309
|
LOG.info("StopIDE", `Instance removed: ${instanceKey}`);
|
|
14077
14310
|
}
|
|
@@ -14286,11 +14519,11 @@ var DaemonStatusReporter = class {
|
|
|
14286
14519
|
// ─── P2P ─────────────────────────────────────────
|
|
14287
14520
|
sendP2PPayload(payload) {
|
|
14288
14521
|
const { timestamp: _ts, system: _sys, ...hashTarget } = payload;
|
|
14289
|
-
|
|
14522
|
+
const hashPayload = hashTarget.machine ? (() => {
|
|
14290
14523
|
const { freeMem: _f, availableMem: _a, loadavg: _l, uptime: _u, ...stableMachine } = hashTarget.machine;
|
|
14291
|
-
hashTarget
|
|
14292
|
-
}
|
|
14293
|
-
const h = this.simpleHash(JSON.stringify(
|
|
14524
|
+
return { ...hashTarget, machine: stableMachine };
|
|
14525
|
+
})() : hashTarget;
|
|
14526
|
+
const h = this.simpleHash(JSON.stringify(hashPayload));
|
|
14294
14527
|
if (h !== this.lastP2PStatusHash) {
|
|
14295
14528
|
this.lastP2PStatusHash = h;
|
|
14296
14529
|
this.deps.p2p?.sendStatus(payload);
|
|
@@ -14338,6 +14571,9 @@ var ProviderStreamAdapter = class {
|
|
|
14338
14571
|
hasScript(name) {
|
|
14339
14572
|
return typeof this.provider.scripts?.[name] === "function";
|
|
14340
14573
|
}
|
|
14574
|
+
getStateTitle(state) {
|
|
14575
|
+
return typeof state.title === "string" ? state.title : "";
|
|
14576
|
+
}
|
|
14341
14577
|
parseMaybeJson(raw) {
|
|
14342
14578
|
if (typeof raw !== "string") return raw;
|
|
14343
14579
|
try {
|
|
@@ -14541,7 +14777,7 @@ var ProviderStreamAdapter = class {
|
|
|
14541
14777
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
14542
14778
|
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
14543
14779
|
const state = await this.readChat(evaluate);
|
|
14544
|
-
const title =
|
|
14780
|
+
const title = this.getStateTitle(state);
|
|
14545
14781
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
14546
14782
|
}
|
|
14547
14783
|
return false;
|
|
@@ -14638,6 +14874,11 @@ var DaemonAgentStreamManager = class {
|
|
|
14638
14874
|
const child = (this.sessionRegistry?.listChildren(parentSessionId) || []).find((entry) => entry.transport === "cdp-webview" && entry.providerType === agentType);
|
|
14639
14875
|
return child?.sessionId || null;
|
|
14640
14876
|
}
|
|
14877
|
+
getStateError(state) {
|
|
14878
|
+
if (typeof state.error === "string" && state.error.trim()) return state.error.trim();
|
|
14879
|
+
if (typeof state._error === "string" && state._error.trim()) return state._error.trim();
|
|
14880
|
+
return "unknown";
|
|
14881
|
+
}
|
|
14641
14882
|
async connectManagedSession(cdp, parentSessionId, runtimeSessionId) {
|
|
14642
14883
|
const target = this.getSessionTarget(runtimeSessionId);
|
|
14643
14884
|
if (!target || target.transport !== "cdp-webview") return null;
|
|
@@ -14700,8 +14941,8 @@ var DaemonAgentStreamManager = class {
|
|
|
14700
14941
|
try {
|
|
14701
14942
|
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
14702
14943
|
const state = await agent.adapter.readChat(evaluate);
|
|
14703
|
-
|
|
14704
|
-
|
|
14944
|
+
const stateError = this.getStateError(state);
|
|
14945
|
+
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) : ""}`);
|
|
14705
14946
|
if (state.status === "error" && this.isRecoverableSessionError(stateError)) {
|
|
14706
14947
|
throw new Error(stateError);
|
|
14707
14948
|
}
|
|
@@ -15270,11 +15511,11 @@ var ProviderInstanceManager = class {
|
|
|
15270
15511
|
|
|
15271
15512
|
// src/providers/version-archive.ts
|
|
15272
15513
|
import * as fs10 from "fs";
|
|
15273
|
-
import * as
|
|
15274
|
-
import * as
|
|
15514
|
+
import * as path17 from "path";
|
|
15515
|
+
import * as os18 from "os";
|
|
15275
15516
|
import { execSync as execSync5 } from "child_process";
|
|
15276
|
-
import { platform as
|
|
15277
|
-
var ARCHIVE_PATH =
|
|
15517
|
+
import { platform as platform8 } from "os";
|
|
15518
|
+
var ARCHIVE_PATH = path17.join(os18.homedir(), ".adhdev", "version-history.json");
|
|
15278
15519
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
15279
15520
|
var VersionArchive = class {
|
|
15280
15521
|
history = {};
|
|
@@ -15299,7 +15540,7 @@ var VersionArchive = class {
|
|
|
15299
15540
|
entries.push({
|
|
15300
15541
|
version,
|
|
15301
15542
|
detectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15302
|
-
os:
|
|
15543
|
+
os: platform8()
|
|
15303
15544
|
});
|
|
15304
15545
|
if (entries.length > MAX_ENTRIES_PER_PROVIDER) {
|
|
15305
15546
|
this.history[type] = entries.slice(-MAX_ENTRIES_PER_PROVIDER);
|
|
@@ -15321,7 +15562,7 @@ var VersionArchive = class {
|
|
|
15321
15562
|
}
|
|
15322
15563
|
save() {
|
|
15323
15564
|
try {
|
|
15324
|
-
fs10.mkdirSync(
|
|
15565
|
+
fs10.mkdirSync(path17.dirname(ARCHIVE_PATH), { recursive: true });
|
|
15325
15566
|
fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
15326
15567
|
} catch {
|
|
15327
15568
|
}
|
|
@@ -15339,7 +15580,7 @@ function runCommand(cmd, timeout = 1e4) {
|
|
|
15339
15580
|
}
|
|
15340
15581
|
}
|
|
15341
15582
|
function findBinary2(name) {
|
|
15342
|
-
const cmd =
|
|
15583
|
+
const cmd = platform8() === "win32" ? `where ${name}` : `which ${name}`;
|
|
15343
15584
|
const result = runCommand(cmd, 5e3);
|
|
15344
15585
|
return result ? result.split("\n")[0] : null;
|
|
15345
15586
|
}
|
|
@@ -15347,6 +15588,22 @@ function parseVersion2(raw) {
|
|
|
15347
15588
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
15348
15589
|
return match ? match[1] : raw.split("\n")[0].substring(0, 100);
|
|
15349
15590
|
}
|
|
15591
|
+
function getPlatformVersionCommand(versionCommand, currentOs) {
|
|
15592
|
+
if (!versionCommand) return void 0;
|
|
15593
|
+
if (typeof versionCommand === "string") {
|
|
15594
|
+
const trimmed = versionCommand.trim();
|
|
15595
|
+
return trimmed || void 0;
|
|
15596
|
+
}
|
|
15597
|
+
const platformValue = versionCommand[currentOs];
|
|
15598
|
+
if (typeof platformValue === "string" && platformValue.trim()) {
|
|
15599
|
+
return platformValue.trim();
|
|
15600
|
+
}
|
|
15601
|
+
const defaultValue = versionCommand.default;
|
|
15602
|
+
if (typeof defaultValue === "string" && defaultValue.trim()) {
|
|
15603
|
+
return defaultValue.trim();
|
|
15604
|
+
}
|
|
15605
|
+
return void 0;
|
|
15606
|
+
}
|
|
15350
15607
|
function getVersion(binary, versionCommand) {
|
|
15351
15608
|
if (versionCommand) {
|
|
15352
15609
|
const raw = runCommand(versionCommand);
|
|
@@ -15361,8 +15618,8 @@ function getVersion(binary, versionCommand) {
|
|
|
15361
15618
|
function checkPathExists2(paths) {
|
|
15362
15619
|
for (const p of paths) {
|
|
15363
15620
|
if (p.includes("*")) {
|
|
15364
|
-
const home =
|
|
15365
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
15621
|
+
const home = os18.homedir();
|
|
15622
|
+
const resolved = p.replace(/\*/g, home.split(path17.sep).pop() || "");
|
|
15366
15623
|
if (fs10.existsSync(resolved)) return resolved;
|
|
15367
15624
|
} else {
|
|
15368
15625
|
if (fs10.existsSync(p)) return p;
|
|
@@ -15371,15 +15628,15 @@ function checkPathExists2(paths) {
|
|
|
15371
15628
|
return null;
|
|
15372
15629
|
}
|
|
15373
15630
|
function getMacAppVersion(appPath) {
|
|
15374
|
-
if (
|
|
15375
|
-
const plistPath =
|
|
15631
|
+
if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
15632
|
+
const plistPath = path17.join(appPath, "Contents", "Info.plist");
|
|
15376
15633
|
if (!fs10.existsSync(plistPath)) return null;
|
|
15377
15634
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
15378
15635
|
return raw || null;
|
|
15379
15636
|
}
|
|
15380
15637
|
async function detectAllVersions(loader, archive) {
|
|
15381
15638
|
const results = [];
|
|
15382
|
-
const currentOs =
|
|
15639
|
+
const currentOs = platform8();
|
|
15383
15640
|
for (const provider of loader.getAll()) {
|
|
15384
15641
|
const info = {
|
|
15385
15642
|
type: provider.type,
|
|
@@ -15391,15 +15648,14 @@ async function detectAllVersions(loader, archive) {
|
|
|
15391
15648
|
binary: null,
|
|
15392
15649
|
detectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
15393
15650
|
};
|
|
15394
|
-
const
|
|
15395
|
-
const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[currentOs] : verCmdConfig;
|
|
15651
|
+
const versionCommand = getPlatformVersionCommand(provider.versionCommand, currentOs);
|
|
15396
15652
|
if (provider.category === "ide") {
|
|
15397
15653
|
const osPaths = provider.paths?.[currentOs] || [];
|
|
15398
15654
|
const appPath = checkPathExists2(osPaths);
|
|
15399
15655
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
15400
15656
|
let resolvedBin = cliBin;
|
|
15401
15657
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
15402
|
-
const bundled =
|
|
15658
|
+
const bundled = path17.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
15403
15659
|
if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
|
|
15404
15660
|
}
|
|
15405
15661
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -15440,7 +15696,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
15440
15696
|
// src/daemon/dev-server.ts
|
|
15441
15697
|
import * as http2 from "http";
|
|
15442
15698
|
import * as fs14 from "fs";
|
|
15443
|
-
import * as
|
|
15699
|
+
import * as path21 from "path";
|
|
15444
15700
|
|
|
15445
15701
|
// src/daemon/scaffold-template.ts
|
|
15446
15702
|
function generateFiles(type, name, category, opts = {}) {
|
|
@@ -15777,7 +16033,7 @@ init_logger();
|
|
|
15777
16033
|
// src/daemon/dev-cdp-handlers.ts
|
|
15778
16034
|
init_logger();
|
|
15779
16035
|
import * as fs11 from "fs";
|
|
15780
|
-
import * as
|
|
16036
|
+
import * as path18 from "path";
|
|
15781
16037
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
15782
16038
|
const body = await ctx.readBody(req);
|
|
15783
16039
|
const { expression, timeout, ideType } = body;
|
|
@@ -15955,17 +16211,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
15955
16211
|
return;
|
|
15956
16212
|
}
|
|
15957
16213
|
let scriptsPath = "";
|
|
15958
|
-
const directScripts =
|
|
16214
|
+
const directScripts = path18.join(dir, "scripts.js");
|
|
15959
16215
|
if (fs11.existsSync(directScripts)) {
|
|
15960
16216
|
scriptsPath = directScripts;
|
|
15961
16217
|
} else {
|
|
15962
|
-
const scriptsDir =
|
|
16218
|
+
const scriptsDir = path18.join(dir, "scripts");
|
|
15963
16219
|
if (fs11.existsSync(scriptsDir)) {
|
|
15964
16220
|
const versions = fs11.readdirSync(scriptsDir).filter((d) => {
|
|
15965
|
-
return fs11.statSync(
|
|
16221
|
+
return fs11.statSync(path18.join(scriptsDir, d)).isDirectory();
|
|
15966
16222
|
}).sort().reverse();
|
|
15967
16223
|
for (const ver of versions) {
|
|
15968
|
-
const p =
|
|
16224
|
+
const p = path18.join(scriptsDir, ver, "scripts.js");
|
|
15969
16225
|
if (fs11.existsSync(p)) {
|
|
15970
16226
|
scriptsPath = p;
|
|
15971
16227
|
break;
|
|
@@ -16784,7 +17040,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
16784
17040
|
|
|
16785
17041
|
// src/daemon/dev-cli-debug.ts
|
|
16786
17042
|
import * as fs12 from "fs";
|
|
16787
|
-
import * as
|
|
17043
|
+
import * as path19 from "path";
|
|
16788
17044
|
function slugifyFixtureName(value) {
|
|
16789
17045
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
16790
17046
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -16794,11 +17050,11 @@ function getCliFixtureDir(ctx, type) {
|
|
|
16794
17050
|
if (!providerDir) {
|
|
16795
17051
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
16796
17052
|
}
|
|
16797
|
-
return
|
|
17053
|
+
return path19.join(providerDir, "fixtures");
|
|
16798
17054
|
}
|
|
16799
17055
|
function readCliFixture(ctx, type, name) {
|
|
16800
17056
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
16801
|
-
const filePath =
|
|
17057
|
+
const filePath = path19.join(fixtureDir, `${name}.json`);
|
|
16802
17058
|
if (!fs12.existsSync(filePath)) {
|
|
16803
17059
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
16804
17060
|
}
|
|
@@ -16924,6 +17180,15 @@ function validateCliFixtureResult(result, assertions) {
|
|
|
16924
17180
|
}
|
|
16925
17181
|
return failures;
|
|
16926
17182
|
}
|
|
17183
|
+
function isCliTargetState(state) {
|
|
17184
|
+
return state.category === "cli" || state.category === "acp";
|
|
17185
|
+
}
|
|
17186
|
+
function getCliAdapterFromInstance(instance) {
|
|
17187
|
+
if (!instance) return null;
|
|
17188
|
+
const candidate = instance;
|
|
17189
|
+
if (typeof candidate.getAdapter === "function") return candidate.getAdapter();
|
|
17190
|
+
return candidate.adapter || null;
|
|
17191
|
+
}
|
|
16927
17192
|
function getCliProviderResolutionMeta(ctx, type, adapter) {
|
|
16928
17193
|
const adapterMeta = typeof adapter?.getProviderResolutionMeta === "function" ? adapter.getProviderResolutionMeta() : adapter?.getDebugState?.()?.providerResolution || null;
|
|
16929
17194
|
const resolvedProvider = ctx.providerLoader.resolve(type);
|
|
@@ -16941,7 +17206,7 @@ function getCliProviderResolutionMeta(ctx, type, adapter) {
|
|
|
16941
17206
|
}
|
|
16942
17207
|
function findCliTarget(ctx, type, instanceId) {
|
|
16943
17208
|
if (!ctx.instanceManager) return null;
|
|
16944
|
-
const cliStates = ctx.instanceManager.collectAllStates().filter(
|
|
17209
|
+
const cliStates = ctx.instanceManager.collectAllStates().filter(isCliTargetState);
|
|
16945
17210
|
if (instanceId) return cliStates.find((s) => s.instanceId === instanceId) || null;
|
|
16946
17211
|
if (!type) return cliStates[cliStates.length - 1] || null;
|
|
16947
17212
|
const matches = cliStates.filter((s) => s.type === type);
|
|
@@ -16953,7 +17218,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
|
|
|
16953
17218
|
if (!target) return null;
|
|
16954
17219
|
const instance = ctx.instanceManager.getInstance(target.instanceId);
|
|
16955
17220
|
if (!instance) return null;
|
|
16956
|
-
const adapter = instance
|
|
17221
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
16957
17222
|
if (!adapter) return null;
|
|
16958
17223
|
return { target, instance, adapter };
|
|
16959
17224
|
}
|
|
@@ -17428,7 +17693,7 @@ async function handleCliDebug(ctx, type, _req, res) {
|
|
|
17428
17693
|
return;
|
|
17429
17694
|
}
|
|
17430
17695
|
try {
|
|
17431
|
-
const adapter = instance
|
|
17696
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17432
17697
|
if (adapter && typeof adapter.getDebugState === "function") {
|
|
17433
17698
|
const debugState = adapter.getDebugState();
|
|
17434
17699
|
ctx.json(res, 200, {
|
|
@@ -17475,7 +17740,7 @@ async function handleCliTrace(ctx, type, req, res) {
|
|
|
17475
17740
|
return;
|
|
17476
17741
|
}
|
|
17477
17742
|
try {
|
|
17478
|
-
const adapter = instance
|
|
17743
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17479
17744
|
const url = new URL(req.url || "/", "http://127.0.0.1");
|
|
17480
17745
|
const limit = parseInt(url.searchParams.get("limit") || "120", 10);
|
|
17481
17746
|
if (adapter && typeof adapter.getTraceState === "function") {
|
|
@@ -17557,7 +17822,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
17557
17822
|
},
|
|
17558
17823
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
17559
17824
|
};
|
|
17560
|
-
const filePath =
|
|
17825
|
+
const filePath = path19.join(fixtureDir, `${name}.json`);
|
|
17561
17826
|
fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
17562
17827
|
ctx.json(res, 200, {
|
|
17563
17828
|
saved: true,
|
|
@@ -17581,7 +17846,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
|
|
|
17581
17846
|
return;
|
|
17582
17847
|
}
|
|
17583
17848
|
const fixtures = fs12.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
17584
|
-
const fullPath =
|
|
17849
|
+
const fullPath = path19.join(fixtureDir, file);
|
|
17585
17850
|
try {
|
|
17586
17851
|
const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
|
|
17587
17852
|
return {
|
|
@@ -17661,7 +17926,7 @@ async function handleCliResolve(ctx, req, res) {
|
|
|
17661
17926
|
return;
|
|
17662
17927
|
}
|
|
17663
17928
|
const instance = ctx.instanceManager.getInstance(target.instanceId);
|
|
17664
|
-
const adapter = instance
|
|
17929
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17665
17930
|
if (!adapter) {
|
|
17666
17931
|
ctx.json(res, 404, { error: `Adapter not found for instance: ${target.instanceId}` });
|
|
17667
17932
|
return;
|
|
@@ -17698,7 +17963,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
17698
17963
|
return;
|
|
17699
17964
|
}
|
|
17700
17965
|
const instance = ctx.instanceManager.getInstance(target.instanceId);
|
|
17701
|
-
const adapter = instance
|
|
17966
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17702
17967
|
if (!adapter) {
|
|
17703
17968
|
ctx.json(res, 404, { error: `Adapter not found for instance: ${target.instanceId}` });
|
|
17704
17969
|
return;
|
|
@@ -17717,11 +17982,11 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
17717
17982
|
|
|
17718
17983
|
// src/daemon/dev-auto-implement.ts
|
|
17719
17984
|
import * as fs13 from "fs";
|
|
17720
|
-
import * as
|
|
17721
|
-
import * as
|
|
17985
|
+
import * as path20 from "path";
|
|
17986
|
+
import * as os19 from "os";
|
|
17722
17987
|
function getAutoImplPid(ctx) {
|
|
17723
|
-
const
|
|
17724
|
-
return
|
|
17988
|
+
const pid = ctx.autoImplProcess?.pid;
|
|
17989
|
+
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
17725
17990
|
}
|
|
17726
17991
|
function isPidAlive(pid) {
|
|
17727
17992
|
try {
|
|
@@ -17739,6 +18004,13 @@ function clearStaleAutoImplState(ctx, reason) {
|
|
|
17739
18004
|
ctx.autoImplProcess = null;
|
|
17740
18005
|
ctx.autoImplStatus.running = false;
|
|
17741
18006
|
}
|
|
18007
|
+
function tryKillAutoImplProcess(processRef, signal) {
|
|
18008
|
+
if (!processRef) return;
|
|
18009
|
+
try {
|
|
18010
|
+
processRef.kill(signal);
|
|
18011
|
+
} catch {
|
|
18012
|
+
}
|
|
18013
|
+
}
|
|
17742
18014
|
function getDefaultAutoImplReference(ctx, category, type) {
|
|
17743
18015
|
if (category === "cli") {
|
|
17744
18016
|
return type === "codex-cli" ? "claude-cli" : "codex-cli";
|
|
@@ -17757,22 +18029,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
17757
18029
|
if (!fs13.existsSync(scriptsDir)) return null;
|
|
17758
18030
|
const versions = fs13.readdirSync(scriptsDir).filter((d) => {
|
|
17759
18031
|
try {
|
|
17760
|
-
return fs13.statSync(
|
|
18032
|
+
return fs13.statSync(path20.join(scriptsDir, d)).isDirectory();
|
|
17761
18033
|
} catch {
|
|
17762
18034
|
return false;
|
|
17763
18035
|
}
|
|
17764
18036
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
17765
18037
|
if (versions.length === 0) return null;
|
|
17766
|
-
return
|
|
18038
|
+
return path20.join(scriptsDir, versions[0]);
|
|
17767
18039
|
}
|
|
17768
18040
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
17769
|
-
const canonicalUserDir =
|
|
17770
|
-
const desiredDir = requestedDir ?
|
|
17771
|
-
const upstreamRoot =
|
|
17772
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
18041
|
+
const canonicalUserDir = path20.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
18042
|
+
const desiredDir = requestedDir ? path20.resolve(requestedDir) : canonicalUserDir;
|
|
18043
|
+
const upstreamRoot = path20.resolve(ctx.providerLoader.getUpstreamDir());
|
|
18044
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path20.sep}`)) {
|
|
17773
18045
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
17774
18046
|
}
|
|
17775
|
-
if (
|
|
18047
|
+
if (path20.basename(desiredDir) !== type) {
|
|
17776
18048
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
17777
18049
|
}
|
|
17778
18050
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -17780,11 +18052,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
17780
18052
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
17781
18053
|
}
|
|
17782
18054
|
if (!fs13.existsSync(desiredDir)) {
|
|
17783
|
-
fs13.mkdirSync(
|
|
18055
|
+
fs13.mkdirSync(path20.dirname(desiredDir), { recursive: true });
|
|
17784
18056
|
fs13.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
17785
18057
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
17786
18058
|
}
|
|
17787
|
-
const providerJson =
|
|
18059
|
+
const providerJson = path20.join(desiredDir, "provider.json");
|
|
17788
18060
|
if (!fs13.existsSync(providerJson)) {
|
|
17789
18061
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
17790
18062
|
}
|
|
@@ -17807,13 +18079,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
17807
18079
|
const refDir = ctx.findProviderDir(referenceType);
|
|
17808
18080
|
if (!refDir || !fs13.existsSync(refDir)) return {};
|
|
17809
18081
|
const referenceScripts = {};
|
|
17810
|
-
const scriptsDir =
|
|
18082
|
+
const scriptsDir = path20.join(refDir, "scripts");
|
|
17811
18083
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
17812
18084
|
if (!latestDir) return referenceScripts;
|
|
17813
18085
|
for (const file of fs13.readdirSync(latestDir)) {
|
|
17814
18086
|
if (!file.endsWith(".js")) continue;
|
|
17815
18087
|
try {
|
|
17816
|
-
referenceScripts[file] = fs13.readFileSync(
|
|
18088
|
+
referenceScripts[file] = fs13.readFileSync(path20.join(latestDir, file), "utf-8");
|
|
17817
18089
|
} catch {
|
|
17818
18090
|
}
|
|
17819
18091
|
}
|
|
@@ -17921,9 +18193,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
17921
18193
|
});
|
|
17922
18194
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
17923
18195
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
17924
|
-
const tmpDir =
|
|
18196
|
+
const tmpDir = path20.join(os19.tmpdir(), "adhdev-autoimpl");
|
|
17925
18197
|
if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
|
|
17926
|
-
const promptFile =
|
|
18198
|
+
const promptFile = path20.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
17927
18199
|
fs13.writeFileSync(promptFile, prompt, "utf-8");
|
|
17928
18200
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
17929
18201
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -18075,7 +18347,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18075
18347
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
18076
18348
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
18077
18349
|
let shellCmd;
|
|
18078
|
-
const isWin =
|
|
18350
|
+
const isWin = os19.platform() === "win32";
|
|
18079
18351
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
18080
18352
|
if (command === "claude") {
|
|
18081
18353
|
const args = [...baseArgs, "--dangerously-skip-permissions"];
|
|
@@ -18119,7 +18391,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18119
18391
|
try {
|
|
18120
18392
|
const pty = __require("node-pty");
|
|
18121
18393
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
18122
|
-
const isWin2 =
|
|
18394
|
+
const isWin2 = os19.platform() === "win32";
|
|
18123
18395
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
18124
18396
|
name: "xterm-256color",
|
|
18125
18397
|
cols: 120,
|
|
@@ -18158,10 +18430,12 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18158
18430
|
let autoStopTimer = null;
|
|
18159
18431
|
let autoStopIssued = false;
|
|
18160
18432
|
try {
|
|
18161
|
-
|
|
18162
|
-
|
|
18163
|
-
|
|
18164
|
-
|
|
18433
|
+
if (agentProvider?.category === "cli") {
|
|
18434
|
+
const { normalizeCliProviderForRuntime: normalizeCliProviderForRuntime2 } = await Promise.resolve().then(() => (init_provider_cli_adapter(), provider_cli_adapter_exports));
|
|
18435
|
+
const normalized = normalizeCliProviderForRuntime2(agentProvider);
|
|
18436
|
+
approvalPatterns = normalized.patterns.approval;
|
|
18437
|
+
approvalKeys = agentProvider.approvalKeys || { 0: "y\r", 1: "a\r" };
|
|
18438
|
+
}
|
|
18165
18439
|
} catch (err) {
|
|
18166
18440
|
ctx.log(`Failed to load approval patterns: ${err.message}`);
|
|
18167
18441
|
}
|
|
@@ -18176,10 +18450,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18176
18450
|
[\u{1F916} ADHDev Pipeline] Completion token detected. Proceeding...
|
|
18177
18451
|
`, stream: "stdout" } });
|
|
18178
18452
|
approvalBuffer = "";
|
|
18179
|
-
|
|
18180
|
-
ctx.autoImplProcess.kill("SIGINT");
|
|
18181
|
-
} catch {
|
|
18182
|
-
}
|
|
18453
|
+
tryKillAutoImplProcess(ctx.autoImplProcess, "SIGINT");
|
|
18183
18454
|
return;
|
|
18184
18455
|
}
|
|
18185
18456
|
if (Date.now() - lastApprovalTime < 2e3) return;
|
|
@@ -18216,10 +18487,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18216
18487
|
stream: "stdout"
|
|
18217
18488
|
}
|
|
18218
18489
|
});
|
|
18219
|
-
|
|
18220
|
-
ctx.autoImplProcess.kill("SIGINT");
|
|
18221
|
-
} catch {
|
|
18222
|
-
}
|
|
18490
|
+
tryKillAutoImplProcess(ctx.autoImplProcess, "SIGINT");
|
|
18223
18491
|
}, 3e4);
|
|
18224
18492
|
};
|
|
18225
18493
|
const finalizeCliAutoImpl = async (code) => {
|
|
@@ -18350,7 +18618,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18350
18618
|
setMode: "set_mode.js"
|
|
18351
18619
|
};
|
|
18352
18620
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
18353
|
-
const scriptsDir =
|
|
18621
|
+
const scriptsDir = path20.join(providerDir, "scripts");
|
|
18354
18622
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
18355
18623
|
if (latestScriptsDir) {
|
|
18356
18624
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -18361,7 +18629,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18361
18629
|
for (const file of fs13.readdirSync(latestScriptsDir)) {
|
|
18362
18630
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
18363
18631
|
try {
|
|
18364
|
-
const content = fs13.readFileSync(
|
|
18632
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18365
18633
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
18366
18634
|
lines.push("```javascript");
|
|
18367
18635
|
lines.push(content);
|
|
@@ -18378,7 +18646,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18378
18646
|
lines.push("");
|
|
18379
18647
|
for (const file of refFiles) {
|
|
18380
18648
|
try {
|
|
18381
|
-
const content = fs13.readFileSync(
|
|
18649
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18382
18650
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
18383
18651
|
lines.push("```javascript");
|
|
18384
18652
|
lines.push(content);
|
|
@@ -18419,10 +18687,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18419
18687
|
lines.push("");
|
|
18420
18688
|
}
|
|
18421
18689
|
}
|
|
18422
|
-
const docsDir =
|
|
18690
|
+
const docsDir = path20.join(providerDir, "../../docs");
|
|
18423
18691
|
const loadGuide = (name) => {
|
|
18424
18692
|
try {
|
|
18425
|
-
const p =
|
|
18693
|
+
const p = path20.join(docsDir, name);
|
|
18426
18694
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
18427
18695
|
} catch {
|
|
18428
18696
|
}
|
|
@@ -18657,7 +18925,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18657
18925
|
parseApproval: "parse_approval.js"
|
|
18658
18926
|
};
|
|
18659
18927
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
18660
|
-
const scriptsDir =
|
|
18928
|
+
const scriptsDir = path20.join(providerDir, "scripts");
|
|
18661
18929
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
18662
18930
|
if (latestScriptsDir) {
|
|
18663
18931
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -18669,7 +18937,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18669
18937
|
if (!file.endsWith(".js")) continue;
|
|
18670
18938
|
if (!targetFileNames.has(file)) continue;
|
|
18671
18939
|
try {
|
|
18672
|
-
const content = fs13.readFileSync(
|
|
18940
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18673
18941
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
18674
18942
|
lines.push("```javascript");
|
|
18675
18943
|
lines.push(content);
|
|
@@ -18685,7 +18953,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18685
18953
|
lines.push("");
|
|
18686
18954
|
for (const file of refFiles) {
|
|
18687
18955
|
try {
|
|
18688
|
-
const content = fs13.readFileSync(
|
|
18956
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18689
18957
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
18690
18958
|
lines.push("```javascript");
|
|
18691
18959
|
lines.push(content);
|
|
@@ -18718,10 +18986,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18718
18986
|
lines.push("");
|
|
18719
18987
|
}
|
|
18720
18988
|
}
|
|
18721
|
-
const docsDir =
|
|
18989
|
+
const docsDir = path20.join(providerDir, "../../docs");
|
|
18722
18990
|
const loadGuide = (name) => {
|
|
18723
18991
|
try {
|
|
18724
|
-
const p =
|
|
18992
|
+
const p = path20.join(docsDir, name);
|
|
18725
18993
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
18726
18994
|
} catch {
|
|
18727
18995
|
}
|
|
@@ -19036,6 +19304,38 @@ data: ${JSON.stringify(msg.data)}
|
|
|
19036
19304
|
|
|
19037
19305
|
// src/daemon/dev-server.ts
|
|
19038
19306
|
var DEV_SERVER_PORT = 19280;
|
|
19307
|
+
function getScriptNames(scripts) {
|
|
19308
|
+
if (!scripts) return [];
|
|
19309
|
+
return Object.entries(scripts).filter(([, value]) => typeof value === "function").map(([name]) => name);
|
|
19310
|
+
}
|
|
19311
|
+
function toProviderListEntry(provider) {
|
|
19312
|
+
const base = {
|
|
19313
|
+
type: provider.type,
|
|
19314
|
+
name: provider.name,
|
|
19315
|
+
category: provider.category,
|
|
19316
|
+
icon: provider.icon || null,
|
|
19317
|
+
displayName: provider.displayName || provider.name
|
|
19318
|
+
};
|
|
19319
|
+
if (provider.category === "ide" || provider.category === "extension") {
|
|
19320
|
+
base.scripts = getScriptNames(provider.scripts);
|
|
19321
|
+
base.inputMethod = provider.inputMethod || null;
|
|
19322
|
+
base.inputSelector = provider.inputSelector || null;
|
|
19323
|
+
base.extensionId = provider.extensionId || null;
|
|
19324
|
+
base.cdpPorts = provider.cdpPorts || [];
|
|
19325
|
+
}
|
|
19326
|
+
if (provider.category === "acp") {
|
|
19327
|
+
base.spawn = provider.spawn || null;
|
|
19328
|
+
base.auth = provider.auth || null;
|
|
19329
|
+
base.install = provider.install || null;
|
|
19330
|
+
base.hasSettings = !!provider.settings;
|
|
19331
|
+
base.settingsCount = provider.settings ? Object.keys(provider.settings).length : 0;
|
|
19332
|
+
}
|
|
19333
|
+
if (provider.category === "cli") {
|
|
19334
|
+
base.spawn = provider.spawn || null;
|
|
19335
|
+
base.install = provider.install || null;
|
|
19336
|
+
}
|
|
19337
|
+
return base;
|
|
19338
|
+
}
|
|
19039
19339
|
var DevServer = class _DevServer {
|
|
19040
19340
|
server = null;
|
|
19041
19341
|
providerLoader;
|
|
@@ -19132,8 +19432,8 @@ var DevServer = class _DevServer {
|
|
|
19132
19432
|
}
|
|
19133
19433
|
getEndpointList() {
|
|
19134
19434
|
return this.routes.map((r) => {
|
|
19135
|
-
const
|
|
19136
|
-
return `${r.method.padEnd(5)} ${
|
|
19435
|
+
const path22 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
19436
|
+
return `${r.method.padEnd(5)} ${path22}`;
|
|
19137
19437
|
});
|
|
19138
19438
|
}
|
|
19139
19439
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -19185,34 +19485,7 @@ var DevServer = class _DevServer {
|
|
|
19185
19485
|
}
|
|
19186
19486
|
// ─── Handlers ───
|
|
19187
19487
|
async handleListProviders(_req, res) {
|
|
19188
|
-
const providers = this.providerLoader.getAll().map(
|
|
19189
|
-
const base = {
|
|
19190
|
-
type: p.type,
|
|
19191
|
-
name: p.name,
|
|
19192
|
-
category: p.category,
|
|
19193
|
-
icon: p.icon || null,
|
|
19194
|
-
displayName: p.displayName || p.name
|
|
19195
|
-
};
|
|
19196
|
-
if (p.category === "ide" || p.category === "extension") {
|
|
19197
|
-
base.scripts = p.scripts ? Object.keys(p.scripts).filter((k) => typeof p.scripts[k] === "function") : [];
|
|
19198
|
-
base.inputMethod = p.inputMethod || null;
|
|
19199
|
-
base.inputSelector = p.inputSelector || null;
|
|
19200
|
-
base.extensionId = p.extensionId || null;
|
|
19201
|
-
base.cdpPorts = p.cdpPorts || [];
|
|
19202
|
-
}
|
|
19203
|
-
if (p.category === "acp") {
|
|
19204
|
-
base.spawn = p.spawn || null;
|
|
19205
|
-
base.auth = p.auth || null;
|
|
19206
|
-
base.install = p.install || null;
|
|
19207
|
-
base.hasSettings = !!p.settings;
|
|
19208
|
-
base.settingsCount = p.settings ? Object.keys(p.settings).length : 0;
|
|
19209
|
-
}
|
|
19210
|
-
if (p.category === "cli") {
|
|
19211
|
-
base.spawn = p.spawn || null;
|
|
19212
|
-
base.install = p.install || null;
|
|
19213
|
-
}
|
|
19214
|
-
return base;
|
|
19215
|
-
});
|
|
19488
|
+
const providers = this.providerLoader.getAll().map(toProviderListEntry);
|
|
19216
19489
|
this.json(res, 200, { providers, count: providers.length });
|
|
19217
19490
|
}
|
|
19218
19491
|
async handleProviderConfig(type, _req, res) {
|
|
@@ -19404,7 +19677,7 @@ var DevServer = class _DevServer {
|
|
|
19404
19677
|
}));
|
|
19405
19678
|
for (const cdp of this.cdpManagers.values()) {
|
|
19406
19679
|
if (!cdp.isConnected) {
|
|
19407
|
-
cdp.
|
|
19680
|
+
cdp.clearTargetId();
|
|
19408
19681
|
}
|
|
19409
19682
|
}
|
|
19410
19683
|
this.json(res, 200, { reloaded: true, providers });
|
|
@@ -19415,12 +19688,12 @@ var DevServer = class _DevServer {
|
|
|
19415
19688
|
// ─── DevConsole SPA ───
|
|
19416
19689
|
getConsoleDistDir() {
|
|
19417
19690
|
const candidates = [
|
|
19418
|
-
|
|
19419
|
-
|
|
19420
|
-
|
|
19691
|
+
path21.resolve(__dirname, "../../web-devconsole/dist"),
|
|
19692
|
+
path21.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
19693
|
+
path21.join(process.cwd(), "packages/web-devconsole/dist")
|
|
19421
19694
|
];
|
|
19422
19695
|
for (const dir of candidates) {
|
|
19423
|
-
if (fs14.existsSync(
|
|
19696
|
+
if (fs14.existsSync(path21.join(dir, "index.html"))) return dir;
|
|
19424
19697
|
}
|
|
19425
19698
|
return null;
|
|
19426
19699
|
}
|
|
@@ -19430,7 +19703,7 @@ var DevServer = class _DevServer {
|
|
|
19430
19703
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
19431
19704
|
return;
|
|
19432
19705
|
}
|
|
19433
|
-
const htmlPath =
|
|
19706
|
+
const htmlPath = path21.join(distDir, "index.html");
|
|
19434
19707
|
try {
|
|
19435
19708
|
const html = fs14.readFileSync(htmlPath, "utf-8");
|
|
19436
19709
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -19455,15 +19728,15 @@ var DevServer = class _DevServer {
|
|
|
19455
19728
|
this.json(res, 404, { error: "Not found" });
|
|
19456
19729
|
return;
|
|
19457
19730
|
}
|
|
19458
|
-
const safePath =
|
|
19459
|
-
const filePath =
|
|
19731
|
+
const safePath = path21.normalize(pathname).replace(/^\.\.\//, "");
|
|
19732
|
+
const filePath = path21.join(distDir, safePath);
|
|
19460
19733
|
if (!filePath.startsWith(distDir)) {
|
|
19461
19734
|
this.json(res, 403, { error: "Forbidden" });
|
|
19462
19735
|
return;
|
|
19463
19736
|
}
|
|
19464
19737
|
try {
|
|
19465
19738
|
const content = fs14.readFileSync(filePath);
|
|
19466
|
-
const ext =
|
|
19739
|
+
const ext = path21.extname(filePath);
|
|
19467
19740
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
19468
19741
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
19469
19742
|
res.end(content);
|
|
@@ -19576,9 +19849,9 @@ var DevServer = class _DevServer {
|
|
|
19576
19849
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
19577
19850
|
if (entry.isDirectory()) {
|
|
19578
19851
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
19579
|
-
scan(
|
|
19852
|
+
scan(path21.join(d, entry.name), rel);
|
|
19580
19853
|
} else {
|
|
19581
|
-
const stat = fs14.statSync(
|
|
19854
|
+
const stat = fs14.statSync(path21.join(d, entry.name));
|
|
19582
19855
|
files.push({ path: rel, size: stat.size, type: "file" });
|
|
19583
19856
|
}
|
|
19584
19857
|
}
|
|
@@ -19601,7 +19874,7 @@ var DevServer = class _DevServer {
|
|
|
19601
19874
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
19602
19875
|
return;
|
|
19603
19876
|
}
|
|
19604
|
-
const fullPath =
|
|
19877
|
+
const fullPath = path21.resolve(dir, path21.normalize(filePath));
|
|
19605
19878
|
if (!fullPath.startsWith(dir)) {
|
|
19606
19879
|
this.json(res, 403, { error: "Forbidden" });
|
|
19607
19880
|
return;
|
|
@@ -19626,14 +19899,14 @@ var DevServer = class _DevServer {
|
|
|
19626
19899
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
19627
19900
|
return;
|
|
19628
19901
|
}
|
|
19629
|
-
const fullPath =
|
|
19902
|
+
const fullPath = path21.resolve(dir, path21.normalize(filePath));
|
|
19630
19903
|
if (!fullPath.startsWith(dir)) {
|
|
19631
19904
|
this.json(res, 403, { error: "Forbidden" });
|
|
19632
19905
|
return;
|
|
19633
19906
|
}
|
|
19634
19907
|
try {
|
|
19635
19908
|
if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
|
|
19636
|
-
fs14.mkdirSync(
|
|
19909
|
+
fs14.mkdirSync(path21.dirname(fullPath), { recursive: true });
|
|
19637
19910
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
19638
19911
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
19639
19912
|
this.providerLoader.reload();
|
|
@@ -19650,7 +19923,7 @@ var DevServer = class _DevServer {
|
|
|
19650
19923
|
return;
|
|
19651
19924
|
}
|
|
19652
19925
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
19653
|
-
const p =
|
|
19926
|
+
const p = path21.join(dir, name);
|
|
19654
19927
|
if (fs14.existsSync(p)) {
|
|
19655
19928
|
const source = fs14.readFileSync(p, "utf-8");
|
|
19656
19929
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -19671,8 +19944,8 @@ var DevServer = class _DevServer {
|
|
|
19671
19944
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
19672
19945
|
return;
|
|
19673
19946
|
}
|
|
19674
|
-
const target = fs14.existsSync(
|
|
19675
|
-
const targetPath =
|
|
19947
|
+
const target = fs14.existsSync(path21.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
19948
|
+
const targetPath = path21.join(dir, target);
|
|
19676
19949
|
try {
|
|
19677
19950
|
if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
|
|
19678
19951
|
fs14.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -19832,7 +20105,7 @@ var DevServer = class _DevServer {
|
|
|
19832
20105
|
}
|
|
19833
20106
|
let targetDir;
|
|
19834
20107
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
19835
|
-
const jsonPath =
|
|
20108
|
+
const jsonPath = path21.join(targetDir, "provider.json");
|
|
19836
20109
|
if (fs14.existsSync(jsonPath)) {
|
|
19837
20110
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
19838
20111
|
return;
|
|
@@ -19844,8 +20117,8 @@ var DevServer = class _DevServer {
|
|
|
19844
20117
|
const createdFiles = ["provider.json"];
|
|
19845
20118
|
if (result.files) {
|
|
19846
20119
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
19847
|
-
const fullPath =
|
|
19848
|
-
fs14.mkdirSync(
|
|
20120
|
+
const fullPath = path21.join(targetDir, relPath);
|
|
20121
|
+
fs14.mkdirSync(path21.dirname(fullPath), { recursive: true });
|
|
19849
20122
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
19850
20123
|
createdFiles.push(relPath);
|
|
19851
20124
|
}
|
|
@@ -19898,22 +20171,22 @@ var DevServer = class _DevServer {
|
|
|
19898
20171
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
19899
20172
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
19900
20173
|
try {
|
|
19901
|
-
return fs14.statSync(
|
|
20174
|
+
return fs14.statSync(path21.join(scriptsDir, d)).isDirectory();
|
|
19902
20175
|
} catch {
|
|
19903
20176
|
return false;
|
|
19904
20177
|
}
|
|
19905
20178
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
19906
20179
|
if (versions.length === 0) return null;
|
|
19907
|
-
return
|
|
20180
|
+
return path21.join(scriptsDir, versions[0]);
|
|
19908
20181
|
}
|
|
19909
20182
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
19910
|
-
const canonicalUserDir =
|
|
19911
|
-
const desiredDir = requestedDir ?
|
|
19912
|
-
const upstreamRoot =
|
|
19913
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
20183
|
+
const canonicalUserDir = path21.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
20184
|
+
const desiredDir = requestedDir ? path21.resolve(requestedDir) : canonicalUserDir;
|
|
20185
|
+
const upstreamRoot = path21.resolve(this.providerLoader.getUpstreamDir());
|
|
20186
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path21.sep}`)) {
|
|
19914
20187
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
19915
20188
|
}
|
|
19916
|
-
if (
|
|
20189
|
+
if (path21.basename(desiredDir) !== type) {
|
|
19917
20190
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
19918
20191
|
}
|
|
19919
20192
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -19921,11 +20194,11 @@ var DevServer = class _DevServer {
|
|
|
19921
20194
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
19922
20195
|
}
|
|
19923
20196
|
if (!fs14.existsSync(desiredDir)) {
|
|
19924
|
-
fs14.mkdirSync(
|
|
20197
|
+
fs14.mkdirSync(path21.dirname(desiredDir), { recursive: true });
|
|
19925
20198
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
19926
20199
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
19927
20200
|
}
|
|
19928
|
-
const providerJson =
|
|
20201
|
+
const providerJson = path21.join(desiredDir, "provider.json");
|
|
19929
20202
|
if (!fs14.existsSync(providerJson)) {
|
|
19930
20203
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
19931
20204
|
}
|
|
@@ -19973,7 +20246,7 @@ var DevServer = class _DevServer {
|
|
|
19973
20246
|
setMode: "set_mode.js"
|
|
19974
20247
|
};
|
|
19975
20248
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
19976
|
-
const scriptsDir =
|
|
20249
|
+
const scriptsDir = path21.join(providerDir, "scripts");
|
|
19977
20250
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
19978
20251
|
if (latestScriptsDir) {
|
|
19979
20252
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -19984,7 +20257,7 @@ var DevServer = class _DevServer {
|
|
|
19984
20257
|
for (const file of fs14.readdirSync(latestScriptsDir)) {
|
|
19985
20258
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
19986
20259
|
try {
|
|
19987
|
-
const content = fs14.readFileSync(
|
|
20260
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19988
20261
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
19989
20262
|
lines.push("```javascript");
|
|
19990
20263
|
lines.push(content);
|
|
@@ -20001,7 +20274,7 @@ var DevServer = class _DevServer {
|
|
|
20001
20274
|
lines.push("");
|
|
20002
20275
|
for (const file of refFiles) {
|
|
20003
20276
|
try {
|
|
20004
|
-
const content = fs14.readFileSync(
|
|
20277
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
20005
20278
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
20006
20279
|
lines.push("```javascript");
|
|
20007
20280
|
lines.push(content);
|
|
@@ -20042,10 +20315,10 @@ var DevServer = class _DevServer {
|
|
|
20042
20315
|
lines.push("");
|
|
20043
20316
|
}
|
|
20044
20317
|
}
|
|
20045
|
-
const docsDir =
|
|
20318
|
+
const docsDir = path21.join(providerDir, "../../docs");
|
|
20046
20319
|
const loadGuide = (name) => {
|
|
20047
20320
|
try {
|
|
20048
|
-
const p =
|
|
20321
|
+
const p = path21.join(docsDir, name);
|
|
20049
20322
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
20050
20323
|
} catch {
|
|
20051
20324
|
}
|
|
@@ -20219,7 +20492,7 @@ var DevServer = class _DevServer {
|
|
|
20219
20492
|
parseApproval: "parse_approval.js"
|
|
20220
20493
|
};
|
|
20221
20494
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
20222
|
-
const scriptsDir =
|
|
20495
|
+
const scriptsDir = path21.join(providerDir, "scripts");
|
|
20223
20496
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
20224
20497
|
if (latestScriptsDir) {
|
|
20225
20498
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -20231,7 +20504,7 @@ var DevServer = class _DevServer {
|
|
|
20231
20504
|
if (!file.endsWith(".js")) continue;
|
|
20232
20505
|
if (!targetFileNames.has(file)) continue;
|
|
20233
20506
|
try {
|
|
20234
|
-
const content = fs14.readFileSync(
|
|
20507
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
20235
20508
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
20236
20509
|
lines.push("```javascript");
|
|
20237
20510
|
lines.push(content);
|
|
@@ -20247,7 +20520,7 @@ var DevServer = class _DevServer {
|
|
|
20247
20520
|
lines.push("");
|
|
20248
20521
|
for (const file of refFiles) {
|
|
20249
20522
|
try {
|
|
20250
|
-
const content = fs14.readFileSync(
|
|
20523
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
20251
20524
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
20252
20525
|
lines.push("```javascript");
|
|
20253
20526
|
lines.push(content);
|
|
@@ -20280,10 +20553,10 @@ var DevServer = class _DevServer {
|
|
|
20280
20553
|
lines.push("");
|
|
20281
20554
|
}
|
|
20282
20555
|
}
|
|
20283
|
-
const docsDir =
|
|
20556
|
+
const docsDir = path21.join(providerDir, "../../docs");
|
|
20284
20557
|
const loadGuide = (name) => {
|
|
20285
20558
|
try {
|
|
20286
|
-
const p =
|
|
20559
|
+
const p = path21.join(docsDir, name);
|
|
20287
20560
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
20288
20561
|
} catch {
|
|
20289
20562
|
}
|