@adhdev/daemon-core 0.8.29 → 0.8.31
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 +1033 -621
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1035 -624
- package/dist/index.mjs.map +1 -1
- package/dist/providers/acp-provider-instance.d.ts +1 -0
- package/dist/providers/approval-utils.d.ts +7 -0
- package/dist/providers/cli-provider-instance.d.ts +2 -0
- package/dist/providers/contracts.d.ts +12 -1
- package/dist/providers/ide-provider-instance.d.ts +1 -0
- 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 +57 -6
- 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 +18 -3
- package/src/providers/approval-utils.ts +66 -0
- package/src/providers/cli-provider-instance.ts +32 -6
- package/src/providers/contracts.d.ts +1 -0
- package/src/providers/contracts.ts +15 -2
- package/src/providers/extension-provider-instance.ts +1 -1
- package/src/providers/ide-provider-instance.ts +67 -41
- package/src/providers/provider-loader.ts +110 -55
- 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
|
+
)
|
|
1015
|
+
}
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
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
|
+
}
|
|
1028
1060
|
}
|
|
1061
|
+
return void 0;
|
|
1029
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 "";
|
|
1030
1278
|
}
|
|
1031
|
-
var
|
|
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.
|
|
@@ -5714,6 +5886,55 @@ ${effect.notification.body || ""}`.trim();
|
|
|
5714
5886
|
|
|
5715
5887
|
// src/providers/ide-provider-instance.ts
|
|
5716
5888
|
init_logger();
|
|
5889
|
+
|
|
5890
|
+
// src/providers/approval-utils.ts
|
|
5891
|
+
var DEFAULT_APPROVAL_POSITIVE_HINTS = [
|
|
5892
|
+
"run",
|
|
5893
|
+
"approve",
|
|
5894
|
+
"accept",
|
|
5895
|
+
"allow once",
|
|
5896
|
+
"always allow",
|
|
5897
|
+
"allow",
|
|
5898
|
+
"yes",
|
|
5899
|
+
"proceed",
|
|
5900
|
+
"continue",
|
|
5901
|
+
"confirm",
|
|
5902
|
+
"save",
|
|
5903
|
+
"ok",
|
|
5904
|
+
"trust"
|
|
5905
|
+
];
|
|
5906
|
+
function normalizeApprovalLabel(value) {
|
|
5907
|
+
return String(value || "").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
|
|
5908
|
+
}
|
|
5909
|
+
function getApprovalPositiveHints(provider) {
|
|
5910
|
+
const customHints = Array.isArray(provider?.approvalPositiveHints) ? provider.approvalPositiveHints.map((hint) => normalizeApprovalLabel(String(hint || ""))).filter(Boolean) : [];
|
|
5911
|
+
return customHints.length > 0 ? customHints : DEFAULT_APPROVAL_POSITIVE_HINTS;
|
|
5912
|
+
}
|
|
5913
|
+
function pickApprovalButton(buttons, provider) {
|
|
5914
|
+
const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
|
|
5915
|
+
if (labels.length === 0) {
|
|
5916
|
+
return { index: 0, label: "Approve" };
|
|
5917
|
+
}
|
|
5918
|
+
const normalizedButtons = labels.map((label) => normalizeApprovalLabel(label));
|
|
5919
|
+
const hints = getApprovalPositiveHints(provider);
|
|
5920
|
+
for (const hint of hints) {
|
|
5921
|
+
const exactIndex = normalizedButtons.findIndex((label) => label === hint);
|
|
5922
|
+
if (exactIndex >= 0) return { index: exactIndex, label: labels[exactIndex] };
|
|
5923
|
+
const prefixIndex = normalizedButtons.findIndex((label) => label.startsWith(hint));
|
|
5924
|
+
if (prefixIndex >= 0) return { index: prefixIndex, label: labels[prefixIndex] };
|
|
5925
|
+
const includeIndex = normalizedButtons.findIndex((label) => label.includes(hint));
|
|
5926
|
+
if (includeIndex >= 0) return { index: includeIndex, label: labels[includeIndex] };
|
|
5927
|
+
}
|
|
5928
|
+
return { index: 0, label: labels[0] };
|
|
5929
|
+
}
|
|
5930
|
+
function formatAutoApprovalMessage(modalMessage, buttonLabel) {
|
|
5931
|
+
const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ""}`];
|
|
5932
|
+
const cleanMessage = String(modalMessage || "").trim();
|
|
5933
|
+
if (cleanMessage) lines.push(cleanMessage);
|
|
5934
|
+
return lines.join("\n");
|
|
5935
|
+
}
|
|
5936
|
+
|
|
5937
|
+
// src/providers/ide-provider-instance.ts
|
|
5717
5938
|
var IdeProviderInstance = class {
|
|
5718
5939
|
type;
|
|
5719
5940
|
category = "ide";
|
|
@@ -5780,6 +6001,8 @@ var IdeProviderInstance = class {
|
|
|
5780
6001
|
}
|
|
5781
6002
|
getState() {
|
|
5782
6003
|
const cdp = this.context?.cdp;
|
|
6004
|
+
const autoApproveActive = (this.currentStatus === "waiting_approval" || this.cachedChat?.status === "waiting_approval") && this.canAutoApprove();
|
|
6005
|
+
const visibleStatus = autoApproveActive ? "generating" : this.currentStatus;
|
|
5783
6006
|
const extensionStates = [];
|
|
5784
6007
|
for (const ext of this.extensions.values()) {
|
|
5785
6008
|
extensionStates.push(ext.getState());
|
|
@@ -5788,13 +6011,13 @@ var IdeProviderInstance = class {
|
|
|
5788
6011
|
type: this.type,
|
|
5789
6012
|
name: this.provider.name,
|
|
5790
6013
|
category: "ide",
|
|
5791
|
-
status:
|
|
6014
|
+
status: visibleStatus,
|
|
5792
6015
|
activeChat: this.cachedChat ? {
|
|
5793
6016
|
id: this.cachedChat.id || "active_session",
|
|
5794
6017
|
title: this.cachedChat.title || this.type,
|
|
5795
|
-
status: this.cachedChat.status
|
|
6018
|
+
status: autoApproveActive && this.cachedChat.status === "waiting_approval" ? "generating" : this.cachedChat.status || visibleStatus,
|
|
5796
6019
|
messages: this.mergeConversationMessages(this.cachedChat.messages || []),
|
|
5797
|
-
activeModal: this.cachedChat.activeModal || null,
|
|
6020
|
+
activeModal: autoApproveActive ? null : this.cachedChat.activeModal || null,
|
|
5798
6021
|
inputContent: this.cachedChat.inputContent || ""
|
|
5799
6022
|
} : null,
|
|
5800
6023
|
workspace: this.workspace || null,
|
|
@@ -5941,7 +6164,8 @@ var IdeProviderInstance = class {
|
|
|
5941
6164
|
}
|
|
5942
6165
|
}
|
|
5943
6166
|
if (!raw || typeof raw !== "object") return;
|
|
5944
|
-
|
|
6167
|
+
const chat = raw;
|
|
6168
|
+
let { activeModal } = chat;
|
|
5945
6169
|
if (activeModal) {
|
|
5946
6170
|
const w = activeModal.width ?? Infinity;
|
|
5947
6171
|
const h = activeModal.height ?? Infinity;
|
|
@@ -5961,26 +6185,28 @@ var IdeProviderInstance = class {
|
|
|
5961
6185
|
if (pm.receivedAt) prevByHash.set(h, pm.receivedAt);
|
|
5962
6186
|
}
|
|
5963
6187
|
const now = Date.now();
|
|
5964
|
-
|
|
6188
|
+
const messages = chat.messages || [];
|
|
6189
|
+
for (const msg of messages) {
|
|
5965
6190
|
const h = `${msg.role}:${(msg.content || "").slice(0, 100)}`;
|
|
5966
6191
|
msg.receivedAt = prevByHash.get(h) || now;
|
|
5967
6192
|
}
|
|
5968
|
-
if (
|
|
6193
|
+
if (messages.length > 0) {
|
|
5969
6194
|
const hiddenKinds = /* @__PURE__ */ new Set();
|
|
5970
6195
|
if (this.settings.showThinking === false) hiddenKinds.add("thought");
|
|
5971
6196
|
if (this.settings.showToolCalls === false) hiddenKinds.add("tool");
|
|
5972
6197
|
if (this.settings.showTerminal === false) hiddenKinds.add("terminal");
|
|
5973
6198
|
if (hiddenKinds.size > 0) {
|
|
5974
|
-
|
|
6199
|
+
chat.messages = messages.filter((m) => !hiddenKinds.has(m.kind || ""));
|
|
5975
6200
|
}
|
|
5976
6201
|
}
|
|
5977
|
-
const controlValues = extractProviderControlValues(this.provider.controls,
|
|
5978
|
-
if (controlValues)
|
|
5979
|
-
this.cachedChat = { ...
|
|
5980
|
-
this.detectAgentTransitions(
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
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") {
|
|
5984
6210
|
const lastIdx = toSave.length - 1;
|
|
5985
6211
|
if (lastIdx >= 0 && toSave[lastIdx].role === "assistant") {
|
|
5986
6212
|
toSave = toSave.slice(0, lastIdx);
|
|
@@ -5990,7 +6216,7 @@ var IdeProviderInstance = class {
|
|
|
5990
6216
|
this.historyWriter.appendNewMessages(
|
|
5991
6217
|
this.type,
|
|
5992
6218
|
toSave,
|
|
5993
|
-
|
|
6219
|
+
chat.title,
|
|
5994
6220
|
this.instanceId
|
|
5995
6221
|
);
|
|
5996
6222
|
}
|
|
@@ -6006,14 +6232,16 @@ var IdeProviderInstance = class {
|
|
|
6006
6232
|
getReadChatScript() {
|
|
6007
6233
|
const scripts = this.provider.scripts;
|
|
6008
6234
|
if (!scripts?.readChat) return null;
|
|
6009
|
-
return
|
|
6235
|
+
return scripts.readChat({});
|
|
6010
6236
|
}
|
|
6011
6237
|
// ─── status transition detect ─────────────────────────────
|
|
6012
6238
|
detectAgentTransitions(chatData, now) {
|
|
6013
6239
|
const chatStatus = chatData?.status;
|
|
6014
6240
|
if (!chatStatus) return;
|
|
6015
6241
|
const agentKey = `${this.type}:native`;
|
|
6016
|
-
const
|
|
6242
|
+
const rawAgentStatus = chatStatus === "streaming" || chatStatus === "generating" ? "generating" : chatStatus === "waiting_approval" ? "waiting_approval" : "idle";
|
|
6243
|
+
const autoApproveActive = rawAgentStatus === "waiting_approval" && this.canAutoApprove();
|
|
6244
|
+
const agentStatus = autoApproveActive ? "generating" : rawAgentStatus;
|
|
6017
6245
|
const lastMsg = Array.isArray(chatData?.messages) && chatData.messages.length > 0 ? chatData.messages[chatData.messages.length - 1] : null;
|
|
6018
6246
|
const progressFingerprint = agentStatus === "generating" ? `${lastMsg?.role || ""}:${typeof lastMsg?.content === "string" ? lastMsg.content : JSON.stringify(lastMsg?.content || "")}`.slice(-2e3) : void 0;
|
|
6019
6247
|
this.currentStatus = agentStatus;
|
|
@@ -6045,7 +6273,7 @@ var IdeProviderInstance = class {
|
|
|
6045
6273
|
this.applyProviderResponse(chatData, {
|
|
6046
6274
|
phase: agentStatus === "idle" && (lastStatus === "generating" || lastStatus === "waiting_approval") ? "turn_completed" : "immediate"
|
|
6047
6275
|
});
|
|
6048
|
-
if (
|
|
6276
|
+
if (rawAgentStatus === "waiting_approval" && autoApproveActive && !this.autoApproveBusy) {
|
|
6049
6277
|
this.autoApproveViaScript(chatData);
|
|
6050
6278
|
}
|
|
6051
6279
|
const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint);
|
|
@@ -6196,6 +6424,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
6196
6424
|
updateCdp(cdp) {
|
|
6197
6425
|
if (this.context) this.context.cdp = cdp;
|
|
6198
6426
|
}
|
|
6427
|
+
canAutoApprove() {
|
|
6428
|
+
return this.settings.autoApprove !== false && typeof this.provider.scripts?.resolveAction === "function" && !!this.context?.cdp?.isConnected;
|
|
6429
|
+
}
|
|
6199
6430
|
// ─── Auto-approve via CDP script ────────────────────
|
|
6200
6431
|
async autoApproveViaScript(_chatData) {
|
|
6201
6432
|
const cdp = this.context?.cdp;
|
|
@@ -6207,17 +6438,15 @@ ${effect.notification.body || ""}`.trim();
|
|
|
6207
6438
|
}
|
|
6208
6439
|
this.autoApproveBusy = true;
|
|
6209
6440
|
try {
|
|
6210
|
-
|
|
6211
|
-
const buttons = _chatData?.activeModal?.buttons || [];
|
|
6212
|
-
for (const b of buttons) {
|
|
6213
|
-
const lower = String(b).toLowerCase().replace(/[^\w]/g, "");
|
|
6214
|
-
if (/^(run|approve|accept|yes|allow|always|proceed|save)/.test(lower)) {
|
|
6215
|
-
targetButton = b;
|
|
6216
|
-
break;
|
|
6217
|
-
}
|
|
6218
|
-
}
|
|
6441
|
+
const { label: targetButton } = pickApprovalButton(_chatData?.activeModal?.buttons, this.provider);
|
|
6219
6442
|
const script = scriptFn({ action: "approve", button: targetButton, buttonText: targetButton });
|
|
6220
6443
|
if (!script) return;
|
|
6444
|
+
const now = Date.now();
|
|
6445
|
+
this.appendRuntimeSystemMessage(
|
|
6446
|
+
formatAutoApprovalMessage(_chatData?.activeModal?.message, targetButton),
|
|
6447
|
+
`auto_approval:${now}:${targetButton}`,
|
|
6448
|
+
now
|
|
6449
|
+
);
|
|
6221
6450
|
LOG.info("IdeInstance", `[IdeInstance:${this.type}] autoApprove: executing resolveAction for "${targetButton}"`);
|
|
6222
6451
|
let rawResult = await cdp.evaluate(script, 1e4);
|
|
6223
6452
|
if (typeof rawResult === "string") {
|
|
@@ -6239,12 +6468,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
6239
6468
|
LOG.warn("IdeInstance", `[IdeInstance:${this.type}] autoApprove: cdp.send() not available for coordinate click`);
|
|
6240
6469
|
}
|
|
6241
6470
|
}
|
|
6242
|
-
this.pushEvent({
|
|
6243
|
-
event: "agent:auto_approved",
|
|
6244
|
-
chatTitle: _chatData?.title || this.provider.name,
|
|
6245
|
-
timestamp: Date.now(),
|
|
6246
|
-
ideType: this.type
|
|
6247
|
-
});
|
|
6248
6471
|
} catch (e) {
|
|
6249
6472
|
LOG.warn("IdeInstance", `[IdeInstance:${this.type}] autoApprove error: ${e?.message}`);
|
|
6250
6473
|
} finally {
|
|
@@ -7080,7 +7303,7 @@ function getTargetInstance(h, args) {
|
|
|
7080
7303
|
const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
|
|
7081
7304
|
const sessionId = targetSessionId || h.currentSession?.sessionId || "";
|
|
7082
7305
|
if (!sessionId) return null;
|
|
7083
|
-
return h.ctx.instanceManager?.getInstance(sessionId);
|
|
7306
|
+
return h.ctx.instanceManager?.getInstance(sessionId) || null;
|
|
7084
7307
|
}
|
|
7085
7308
|
function getTargetTransport(h, provider) {
|
|
7086
7309
|
if (h.currentSession?.transport) return h.currentSession.transport;
|
|
@@ -7118,6 +7341,10 @@ function getHistorySessionId(h, args) {
|
|
|
7118
7341
|
const providerSessionId = typeof state?.providerSessionId === "string" ? state.providerSessionId.trim() : "";
|
|
7119
7342
|
return providerSessionId || targetSessionId;
|
|
7120
7343
|
}
|
|
7344
|
+
function callLegacyTextScript(script, text) {
|
|
7345
|
+
if (typeof script !== "function") return null;
|
|
7346
|
+
return script(text);
|
|
7347
|
+
}
|
|
7121
7348
|
function isRecentDuplicateSend(key) {
|
|
7122
7349
|
const now = Date.now();
|
|
7123
7350
|
for (const [candidate, ts2] of recentSendByTarget.entries()) {
|
|
@@ -7207,7 +7434,7 @@ async function handleReadChat(h, args) {
|
|
|
7207
7434
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7208
7435
|
if (adapter) {
|
|
7209
7436
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
7210
|
-
const status = adapter.getStatus
|
|
7437
|
+
const status = adapter.getStatus();
|
|
7211
7438
|
if (status) {
|
|
7212
7439
|
return {
|
|
7213
7440
|
success: true,
|
|
@@ -7447,7 +7674,7 @@ async function handleSendChat(h, args) {
|
|
|
7447
7674
|
}
|
|
7448
7675
|
if (parsed?.needsTypeAndSend && provider?.webviewMatchText && provider?.scripts?.webviewSendMessage) {
|
|
7449
7676
|
try {
|
|
7450
|
-
const webviewScript = provider.scripts.webviewSendMessage
|
|
7677
|
+
const webviewScript = callLegacyTextScript(provider.scripts.webviewSendMessage, text);
|
|
7451
7678
|
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
7452
7679
|
const matchText = provider.webviewMatchText;
|
|
7453
7680
|
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
@@ -7470,7 +7697,7 @@ async function handleSendChat(h, args) {
|
|
|
7470
7697
|
}
|
|
7471
7698
|
if (provider?.webviewMatchText && provider?.scripts?.webviewSendMessage) {
|
|
7472
7699
|
try {
|
|
7473
|
-
const webviewScript = provider.scripts.webviewSendMessage
|
|
7700
|
+
const webviewScript = callLegacyTextScript(provider.scripts.webviewSendMessage, text);
|
|
7474
7701
|
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
7475
7702
|
const matchText = provider.webviewMatchText;
|
|
7476
7703
|
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
@@ -7702,12 +7929,10 @@ async function handleSetMode(h, args) {
|
|
|
7702
7929
|
const mode = args?.mode || "agent";
|
|
7703
7930
|
if (transport === "acp") {
|
|
7704
7931
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
return { success: true, mode };
|
|
7710
|
-
}
|
|
7932
|
+
const acpInstance = adapter?._acpInstance;
|
|
7933
|
+
if (acpInstance && typeof acpInstance.setMode === "function") {
|
|
7934
|
+
await acpInstance.setMode(mode);
|
|
7935
|
+
return { success: true, mode };
|
|
7711
7936
|
}
|
|
7712
7937
|
return { success: false, error: "ACP adapter not found" };
|
|
7713
7938
|
}
|
|
@@ -7760,13 +7985,11 @@ async function handleChangeModel(h, args) {
|
|
|
7760
7985
|
if (transport === "acp") {
|
|
7761
7986
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7762
7987
|
LOG.info("Command", `[change_model] ACP adapter found: ${!!adapter}, type=${adapter?.cliType}, hasAcpInstance=${!!adapter?._acpInstance}`);
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
return { success: true, model };
|
|
7769
|
-
}
|
|
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 };
|
|
7770
7993
|
}
|
|
7771
7994
|
return { success: false, error: "ACP adapter not found" };
|
|
7772
7995
|
}
|
|
@@ -7823,6 +8046,9 @@ async function handleSetThoughtLevel(h, args) {
|
|
|
7823
8046
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7824
8047
|
const acpInstance = adapter?._acpInstance;
|
|
7825
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
|
+
}
|
|
7826
8052
|
try {
|
|
7827
8053
|
await acpInstance.setConfigOption(configId, value);
|
|
7828
8054
|
LOG.info("Command", `[set_thought_level] ${configId}=${value} for ${provider?.type || "unknown_acp"}`);
|
|
@@ -7849,7 +8075,7 @@ async function handleResolveAction(h, args) {
|
|
|
7849
8075
|
return { success: false, error: `CLI resolveAction failed: ${e.message}` };
|
|
7850
8076
|
}
|
|
7851
8077
|
}
|
|
7852
|
-
const status = adapter.getStatus
|
|
8078
|
+
const status = adapter.getStatus();
|
|
7853
8079
|
if (status?.status !== "waiting_approval") {
|
|
7854
8080
|
return { success: false, error: "Not in approval state" };
|
|
7855
8081
|
}
|
|
@@ -7888,6 +8114,9 @@ async function handleResolveAction(h, args) {
|
|
|
7888
8114
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
7889
8115
|
const acpInstance = adapter?._acpInstance;
|
|
7890
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
|
+
}
|
|
7891
8120
|
try {
|
|
7892
8121
|
await acpInstance.resolvePermission(action === "approve" || action === "accept" || action === "always");
|
|
7893
8122
|
LOG.info("Command", `[resolveAction] ACP \u2192 ${action}`);
|
|
@@ -8049,11 +8278,16 @@ async function handleCdpCommand(h, args) {
|
|
|
8049
8278
|
}
|
|
8050
8279
|
async function handleCdpBatch(h, args) {
|
|
8051
8280
|
if (!h.getCdp()?.isConnected) return { success: false, error: "CDP not connected" };
|
|
8052
|
-
const commands = args?.commands;
|
|
8281
|
+
const commands = Array.isArray(args?.commands) ? args.commands : null;
|
|
8053
8282
|
const stopOnError = args?.stopOnError !== false;
|
|
8054
8283
|
if (!commands?.length) return { success: false, error: "commands array required" };
|
|
8055
8284
|
const results = [];
|
|
8056
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
|
+
}
|
|
8057
8291
|
try {
|
|
8058
8292
|
const result = await h.getCdp().sendCdpCommand(cmd.method, cmd.params || {});
|
|
8059
8293
|
results.push({ method: cmd.method, success: true, result });
|
|
@@ -8348,11 +8582,12 @@ function handlePtyResize(h, args) {
|
|
|
8348
8582
|
if (!adapter || typeof adapter.resize !== "function") {
|
|
8349
8583
|
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
|
|
8350
8584
|
}
|
|
8585
|
+
const resize = adapter.resize;
|
|
8351
8586
|
if (force) {
|
|
8352
|
-
|
|
8353
|
-
setTimeout(() =>
|
|
8587
|
+
resize(cols - 1, rows);
|
|
8588
|
+
setTimeout(() => resize(cols, rows), 50);
|
|
8354
8589
|
} else {
|
|
8355
|
-
|
|
8590
|
+
resize(cols, rows);
|
|
8356
8591
|
}
|
|
8357
8592
|
return { success: true };
|
|
8358
8593
|
}
|
|
@@ -8410,7 +8645,7 @@ function parseScriptResult(result) {
|
|
|
8410
8645
|
return { success: true, payload: { result } };
|
|
8411
8646
|
}
|
|
8412
8647
|
}
|
|
8413
|
-
if (result && typeof result === "object" && result.success === false) {
|
|
8648
|
+
if (result && typeof result === "object" && "success" in result && result.success === false) {
|
|
8414
8649
|
return { success: false, payload: result };
|
|
8415
8650
|
}
|
|
8416
8651
|
return { success: true, payload: result };
|
|
@@ -8833,24 +9068,25 @@ var DaemonCommandHandler = class {
|
|
|
8833
9068
|
if (provider?.scripts) {
|
|
8834
9069
|
const fn = provider.scripts[scriptName];
|
|
8835
9070
|
if (typeof fn === "function") {
|
|
9071
|
+
const callScript = fn;
|
|
8836
9072
|
if (params && Object.keys(params).length > 0) {
|
|
8837
9073
|
const firstVal = Object.values(params)[0];
|
|
8838
9074
|
if (scriptName === "sendMessage" && typeof firstVal === "string") {
|
|
8839
|
-
const legacyScript =
|
|
9075
|
+
const legacyScript = callScript(firstVal);
|
|
8840
9076
|
if (legacyScript) return legacyScript;
|
|
8841
9077
|
}
|
|
8842
|
-
const script =
|
|
9078
|
+
const script = callScript(params);
|
|
8843
9079
|
if (script) {
|
|
8844
9080
|
const likelyLegacyObjectLeak = typeof script === "string" && script.includes("[object Object]") && typeof firstVal === "string";
|
|
8845
9081
|
if (!likelyLegacyObjectLeak) return script;
|
|
8846
9082
|
}
|
|
8847
9083
|
if (firstVal !== void 0) {
|
|
8848
|
-
const legacyScript =
|
|
9084
|
+
const legacyScript = callScript(firstVal);
|
|
8849
9085
|
if (legacyScript) return legacyScript;
|
|
8850
9086
|
}
|
|
8851
9087
|
if (script) return script;
|
|
8852
9088
|
} else {
|
|
8853
|
-
const script =
|
|
9089
|
+
const script = callScript();
|
|
8854
9090
|
if (script) return script;
|
|
8855
9091
|
}
|
|
8856
9092
|
}
|
|
@@ -9231,16 +9467,16 @@ var DaemonCommandHandler = class {
|
|
|
9231
9467
|
|
|
9232
9468
|
// src/commands/cli-manager.ts
|
|
9233
9469
|
init_provider_cli_adapter();
|
|
9234
|
-
import * as
|
|
9235
|
-
import * as
|
|
9470
|
+
import * as os12 from "os";
|
|
9471
|
+
import * as path12 from "path";
|
|
9236
9472
|
import * as crypto4 from "crypto";
|
|
9237
9473
|
import chalk from "chalk";
|
|
9238
9474
|
init_config();
|
|
9239
9475
|
|
|
9240
9476
|
// src/providers/cli-provider-instance.ts
|
|
9241
9477
|
init_provider_cli_adapter();
|
|
9242
|
-
import * as
|
|
9243
|
-
import * as
|
|
9478
|
+
import * as os11 from "os";
|
|
9479
|
+
import * as path11 from "path";
|
|
9244
9480
|
import * as crypto3 from "crypto";
|
|
9245
9481
|
import * as fs5 from "fs";
|
|
9246
9482
|
import { createRequire } from "module";
|
|
@@ -9248,7 +9484,7 @@ init_logger();
|
|
|
9248
9484
|
var CachedDatabaseSync = null;
|
|
9249
9485
|
function getDatabaseSync() {
|
|
9250
9486
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
9251
|
-
const requireFn = typeof __require === "function" ? __require : createRequire(
|
|
9487
|
+
const requireFn = typeof __require === "function" ? __require : createRequire(path11.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
9252
9488
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
9253
9489
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
9254
9490
|
if (!CachedDatabaseSync) {
|
|
@@ -9388,7 +9624,7 @@ var CliProviderInstance = class {
|
|
|
9388
9624
|
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
9389
9625
|
*/
|
|
9390
9626
|
probeSessionIdFromConfig(probe) {
|
|
9391
|
-
const resolvedDbPath = probe.dbPath.replace(/^~/,
|
|
9627
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os11.homedir());
|
|
9392
9628
|
if (!fs5.existsSync(resolvedDbPath)) return null;
|
|
9393
9629
|
const directories = this.getProbeDirectories();
|
|
9394
9630
|
const minCreatedAt = Math.max(0, this.startedAt - 6e4);
|
|
@@ -9412,6 +9648,8 @@ var CliProviderInstance = class {
|
|
|
9412
9648
|
getState() {
|
|
9413
9649
|
const adapterStatus = this.adapter.getStatus();
|
|
9414
9650
|
const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
|
|
9651
|
+
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
9652
|
+
const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
|
|
9415
9653
|
const parsedProviderSessionId = typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId.trim() : "";
|
|
9416
9654
|
if (parsedProviderSessionId) {
|
|
9417
9655
|
this.promoteProviderSessionId(parsedProviderSessionId);
|
|
@@ -9451,14 +9689,14 @@ var CliProviderInstance = class {
|
|
|
9451
9689
|
type: this.type,
|
|
9452
9690
|
name: this.provider.name,
|
|
9453
9691
|
category: "cli",
|
|
9454
|
-
status:
|
|
9692
|
+
status: visibleStatus,
|
|
9455
9693
|
mode: this.presentationMode,
|
|
9456
9694
|
activeChat: {
|
|
9457
9695
|
id: `${this.type}_${this.workingDir}`,
|
|
9458
9696
|
title: parsedStatus?.title || dirName,
|
|
9459
|
-
status: parsedStatus?.status ||
|
|
9697
|
+
status: autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
|
|
9460
9698
|
messages: mergedMessages,
|
|
9461
|
-
activeModal: parsedStatus?.activeModal ?? adapterStatus.activeModal,
|
|
9699
|
+
activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
|
|
9462
9700
|
inputContent: ""
|
|
9463
9701
|
},
|
|
9464
9702
|
workspace: this.workingDir,
|
|
@@ -9522,7 +9760,16 @@ var CliProviderInstance = class {
|
|
|
9522
9760
|
const now = Date.now();
|
|
9523
9761
|
const adapterStatus = this.adapter.getStatus();
|
|
9524
9762
|
const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
|
|
9525
|
-
const
|
|
9763
|
+
const rawStatus = adapterStatus.status;
|
|
9764
|
+
const autoApproveActive = rawStatus === "waiting_approval" && this.shouldAutoApprove();
|
|
9765
|
+
if (autoApproveActive) {
|
|
9766
|
+
const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(adapterStatus.activeModal?.buttons, this.provider);
|
|
9767
|
+
this.recordAutoApproval(adapterStatus.activeModal?.message, buttonLabel, now);
|
|
9768
|
+
setTimeout(() => {
|
|
9769
|
+
this.adapter.resolveModal(buttonIndex);
|
|
9770
|
+
}, 0);
|
|
9771
|
+
}
|
|
9772
|
+
const newStatus = autoApproveActive ? "generating" : rawStatus;
|
|
9526
9773
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
9527
9774
|
const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
|
|
9528
9775
|
const partial = this.adapter.getPartialResponse();
|
|
@@ -9732,6 +9979,16 @@ ${effect.notification.body || ""}`.trim();
|
|
|
9732
9979
|
get cliName() {
|
|
9733
9980
|
return this.provider.name;
|
|
9734
9981
|
}
|
|
9982
|
+
shouldAutoApprove() {
|
|
9983
|
+
return this.settings.autoApprove !== false;
|
|
9984
|
+
}
|
|
9985
|
+
recordAutoApproval(modalMessage, buttonLabel, now = Date.now()) {
|
|
9986
|
+
this.appendRuntimeSystemMessage(
|
|
9987
|
+
formatAutoApprovalMessage(modalMessage, buttonLabel),
|
|
9988
|
+
`auto_approval:${now}:${buttonLabel || "approve"}`,
|
|
9989
|
+
now
|
|
9990
|
+
);
|
|
9991
|
+
}
|
|
9735
9992
|
recordApprovalSelection(buttonText) {
|
|
9736
9993
|
const cleanButton = String(buttonText || "").trim();
|
|
9737
9994
|
if (!cleanButton) return;
|
|
@@ -10310,8 +10567,10 @@ var AcpProviderInstance = class {
|
|
|
10310
10567
|
input: tc.rawInput ? typeof tc.rawInput === "string" ? tc.rawInput : JSON.stringify(tc.rawInput) : void 0
|
|
10311
10568
|
});
|
|
10312
10569
|
}
|
|
10313
|
-
if (this.settings.autoApprove) {
|
|
10314
|
-
|
|
10570
|
+
if (this.settings.autoApprove !== false) {
|
|
10571
|
+
const toolTitle = tc.title || tc.toolCallId || "tool call";
|
|
10572
|
+
this.log.info(`[${this.type}] Auto-approving: ${toolTitle}`);
|
|
10573
|
+
this.appendSystemMessage(`Auto-approved: ${toolTitle}`);
|
|
10315
10574
|
const allowOption = params.options.find((o) => o.kind === "allow_once") || params.options.find((o) => o.kind === "allow_always");
|
|
10316
10575
|
if (allowOption) {
|
|
10317
10576
|
return { outcome: { outcome: "selected", optionId: allowOption.optionId } };
|
|
@@ -10763,6 +11022,18 @@ var AcpProviderInstance = class {
|
|
|
10763
11022
|
this.events.push(event);
|
|
10764
11023
|
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
10765
11024
|
}
|
|
11025
|
+
appendSystemMessage(content, timestamp = Date.now()) {
|
|
11026
|
+
const normalizedContent = String(content || "").trim();
|
|
11027
|
+
if (!normalizedContent) return;
|
|
11028
|
+
this.messages.push({
|
|
11029
|
+
role: "system",
|
|
11030
|
+
content: normalizedContent,
|
|
11031
|
+
timestamp
|
|
11032
|
+
});
|
|
11033
|
+
if (this.messages.length > 200) {
|
|
11034
|
+
this.messages = this.messages.slice(-100);
|
|
11035
|
+
}
|
|
11036
|
+
}
|
|
10766
11037
|
flushEvents() {
|
|
10767
11038
|
const events = [...this.events];
|
|
10768
11039
|
this.events = [];
|
|
@@ -10783,7 +11054,8 @@ var AcpProviderInstance = class {
|
|
|
10783
11054
|
|
|
10784
11055
|
// src/commands/cli-manager.ts
|
|
10785
11056
|
init_logger();
|
|
10786
|
-
var
|
|
11057
|
+
var chalkModule = chalk;
|
|
11058
|
+
var chalkApi = typeof chalkModule.yellow === "function" ? chalkModule : chalkModule.default || null;
|
|
10787
11059
|
function colorize(color, text) {
|
|
10788
11060
|
const fn = chalkApi?.[color];
|
|
10789
11061
|
return typeof fn === "function" ? fn(text) : text;
|
|
@@ -11033,7 +11305,7 @@ var DaemonCliManager = class {
|
|
|
11033
11305
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
11034
11306
|
const trimmed = (workingDir || "").trim();
|
|
11035
11307
|
if (!trimmed) throw new Error("working directory required");
|
|
11036
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
11308
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os12.homedir()) : path12.resolve(trimmed);
|
|
11037
11309
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
11038
11310
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
11039
11311
|
const key = crypto4.randomUUID();
|
|
@@ -11072,6 +11344,7 @@ ${installInfo}`
|
|
|
11072
11344
|
});
|
|
11073
11345
|
this.adapters.set(key, {
|
|
11074
11346
|
cliType: normalizedType,
|
|
11347
|
+
cliName: provider.name,
|
|
11075
11348
|
workingDir: resolvedDir,
|
|
11076
11349
|
_acpInstance: acpInstance,
|
|
11077
11350
|
spawn: async () => {
|
|
@@ -11090,6 +11363,12 @@ ${installInfo}`
|
|
|
11090
11363
|
activeModal: state.activeChat?.activeModal || null
|
|
11091
11364
|
};
|
|
11092
11365
|
},
|
|
11366
|
+
getPartialResponse: () => "",
|
|
11367
|
+
cancel: () => {
|
|
11368
|
+
instanceManager2.removeInstance(key);
|
|
11369
|
+
},
|
|
11370
|
+
isProcessing: () => false,
|
|
11371
|
+
isReady: () => true,
|
|
11093
11372
|
setOnStatusChange: () => {
|
|
11094
11373
|
},
|
|
11095
11374
|
setOnPtyData: () => {
|
|
@@ -11496,13 +11775,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
11496
11775
|
// src/launch.ts
|
|
11497
11776
|
import { execSync as execSync4, spawn as spawn2 } from "child_process";
|
|
11498
11777
|
import * as net from "net";
|
|
11499
|
-
import * as
|
|
11500
|
-
import * as
|
|
11778
|
+
import * as os14 from "os";
|
|
11779
|
+
import * as path14 from "path";
|
|
11501
11780
|
|
|
11502
11781
|
// src/providers/provider-loader.ts
|
|
11503
11782
|
import * as fs6 from "fs";
|
|
11504
|
-
import * as
|
|
11505
|
-
import * as
|
|
11783
|
+
import * as path13 from "path";
|
|
11784
|
+
import * as os13 from "os";
|
|
11506
11785
|
import * as chokidar from "chokidar";
|
|
11507
11786
|
init_logger();
|
|
11508
11787
|
var ProviderLoader = class _ProviderLoader {
|
|
@@ -11523,12 +11802,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11523
11802
|
static META_FILE = ".meta.json";
|
|
11524
11803
|
constructor(options) {
|
|
11525
11804
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
11526
|
-
const defaultProvidersDir =
|
|
11805
|
+
const defaultProvidersDir = path13.join(os13.homedir(), ".adhdev", "providers");
|
|
11527
11806
|
if (options?.userDir) {
|
|
11528
11807
|
this.userDir = options.userDir;
|
|
11529
11808
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
11530
11809
|
} else {
|
|
11531
|
-
const localRepoPath =
|
|
11810
|
+
const localRepoPath = path13.resolve(__dirname, "../../../../../adhdev-providers");
|
|
11532
11811
|
if (fs6.existsSync(localRepoPath)) {
|
|
11533
11812
|
this.userDir = localRepoPath;
|
|
11534
11813
|
this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
|
|
@@ -11537,7 +11816,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11537
11816
|
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
11538
11817
|
}
|
|
11539
11818
|
}
|
|
11540
|
-
this.upstreamDir =
|
|
11819
|
+
this.upstreamDir = path13.join(defaultProvidersDir, ".upstream");
|
|
11541
11820
|
this.disableUpstream = options?.disableUpstream ?? false;
|
|
11542
11821
|
}
|
|
11543
11822
|
log(msg) {
|
|
@@ -11567,7 +11846,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11567
11846
|
* Canonical provider directory shape for a given root.
|
|
11568
11847
|
*/
|
|
11569
11848
|
getProviderDir(root, category, type) {
|
|
11570
|
-
return
|
|
11849
|
+
return path13.join(root, category, type);
|
|
11571
11850
|
}
|
|
11572
11851
|
/**
|
|
11573
11852
|
* Canonical user override directory for a provider.
|
|
@@ -11594,7 +11873,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11594
11873
|
resolveProviderFile(type, ...segments) {
|
|
11595
11874
|
const dir = this.findProviderDirInternal(type);
|
|
11596
11875
|
if (!dir) return null;
|
|
11597
|
-
return
|
|
11876
|
+
return path13.join(dir, ...segments);
|
|
11598
11877
|
}
|
|
11599
11878
|
/**
|
|
11600
11879
|
* Load all providers (3-tier priority)
|
|
@@ -11633,7 +11912,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11633
11912
|
if (!fs6.existsSync(this.upstreamDir)) return false;
|
|
11634
11913
|
try {
|
|
11635
11914
|
return fs6.readdirSync(this.upstreamDir).some(
|
|
11636
|
-
(d) => fs6.statSync(
|
|
11915
|
+
(d) => fs6.statSync(path13.join(this.upstreamDir, d)).isDirectory()
|
|
11637
11916
|
);
|
|
11638
11917
|
} catch {
|
|
11639
11918
|
return false;
|
|
@@ -11674,8 +11953,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11674
11953
|
const result = [];
|
|
11675
11954
|
for (const p of this.providers.values()) {
|
|
11676
11955
|
if ((p.category === "cli" || p.category === "acp") && p.spawn?.command) {
|
|
11677
|
-
const
|
|
11678
|
-
const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[process.platform] : verCmdConfig;
|
|
11956
|
+
const versionCommand = this.getPlatformVersionCommand(p.versionCommand);
|
|
11679
11957
|
const command = this.getSpawnCommand(p.type, p.spawn.command);
|
|
11680
11958
|
result.push({
|
|
11681
11959
|
id: p.type,
|
|
@@ -11729,8 +12007,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11729
12007
|
* that runtime attach/remove uses.
|
|
11730
12008
|
*/
|
|
11731
12009
|
getIdeExtensionEnabledState(ideType, extensionType) {
|
|
11732
|
-
const
|
|
11733
|
-
|
|
12010
|
+
const config = this.readConfig();
|
|
12011
|
+
if (!config) return false;
|
|
11734
12012
|
const baseIdeType = ideType.split("_")[0];
|
|
11735
12013
|
const val = config.ideSettings?.[baseIdeType]?.extensions?.[extensionType]?.enabled;
|
|
11736
12014
|
return val === true;
|
|
@@ -11739,15 +12017,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11739
12017
|
* Save IDE extension enabled setting
|
|
11740
12018
|
*/
|
|
11741
12019
|
setIdeExtensionEnabled(ideType, extensionType, enabled) {
|
|
12020
|
+
const config = this.readConfig();
|
|
12021
|
+
if (!config) return false;
|
|
11742
12022
|
try {
|
|
11743
|
-
const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
|
|
11744
|
-
const config = loadConfig2();
|
|
11745
12023
|
const baseIdeType = ideType.split("_")[0];
|
|
11746
12024
|
if (!config.ideSettings) config.ideSettings = {};
|
|
11747
12025
|
if (!config.ideSettings[baseIdeType]) config.ideSettings[baseIdeType] = {};
|
|
11748
12026
|
if (!config.ideSettings[baseIdeType].extensions) config.ideSettings[baseIdeType].extensions = {};
|
|
11749
12027
|
config.ideSettings[baseIdeType].extensions[extensionType] = { enabled };
|
|
11750
|
-
|
|
12028
|
+
this.writeConfig(config);
|
|
11751
12029
|
this.log(`IDE extension setting: ${ideType}.${extensionType}.enabled = ${enabled}`);
|
|
11752
12030
|
return true;
|
|
11753
12031
|
} catch (e) {
|
|
@@ -11937,7 +12215,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11937
12215
|
}
|
|
11938
12216
|
if (currentVersion) {
|
|
11939
12217
|
resolved._resolvedVersion = currentVersion;
|
|
11940
|
-
if (
|
|
12218
|
+
if (base.compatibility) {
|
|
11941
12219
|
const compat = base.compatibility;
|
|
11942
12220
|
let matched = false;
|
|
11943
12221
|
for (const entry of compat) {
|
|
@@ -11949,8 +12227,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11949
12227
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
11950
12228
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
11951
12229
|
if (providerDir) {
|
|
11952
|
-
const fullDir =
|
|
11953
|
-
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;
|
|
11954
12232
|
}
|
|
11955
12233
|
matched = true;
|
|
11956
12234
|
}
|
|
@@ -11965,8 +12243,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11965
12243
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
11966
12244
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
11967
12245
|
if (providerDir) {
|
|
11968
|
-
const fullDir =
|
|
11969
|
-
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;
|
|
11970
12248
|
}
|
|
11971
12249
|
}
|
|
11972
12250
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -11983,8 +12261,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11983
12261
|
resolved._resolvedScriptDir = dirOverride;
|
|
11984
12262
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
11985
12263
|
if (providerDir) {
|
|
11986
|
-
const fullDir =
|
|
11987
|
-
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;
|
|
11988
12266
|
}
|
|
11989
12267
|
}
|
|
11990
12268
|
} else if (override.scripts) {
|
|
@@ -11992,7 +12270,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
11992
12270
|
}
|
|
11993
12271
|
}
|
|
11994
12272
|
}
|
|
11995
|
-
} else if (
|
|
12273
|
+
} else if (base.compatibility && base.defaultScriptDir) {
|
|
11996
12274
|
const loaded = this.loadScriptsFromDir(type, base.defaultScriptDir);
|
|
11997
12275
|
if (loaded) {
|
|
11998
12276
|
resolved.scripts = loaded;
|
|
@@ -12000,8 +12278,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12000
12278
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
12001
12279
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
12002
12280
|
if (providerDir) {
|
|
12003
|
-
const fullDir =
|
|
12004
|
-
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;
|
|
12005
12283
|
}
|
|
12006
12284
|
}
|
|
12007
12285
|
}
|
|
@@ -12026,14 +12304,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12026
12304
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
12027
12305
|
return null;
|
|
12028
12306
|
}
|
|
12029
|
-
const dir =
|
|
12307
|
+
const dir = path13.join(providerDir, scriptDir);
|
|
12030
12308
|
if (!fs6.existsSync(dir)) {
|
|
12031
12309
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
12032
12310
|
return null;
|
|
12033
12311
|
}
|
|
12034
12312
|
const cached = this.scriptsCache.get(dir);
|
|
12035
12313
|
if (cached) return cached;
|
|
12036
|
-
const scriptsJs =
|
|
12314
|
+
const scriptsJs = path13.join(dir, "scripts.js");
|
|
12037
12315
|
if (fs6.existsSync(scriptsJs)) {
|
|
12038
12316
|
try {
|
|
12039
12317
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
@@ -12075,7 +12353,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12075
12353
|
return;
|
|
12076
12354
|
}
|
|
12077
12355
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
12078
|
-
this.log(`File changed: ${
|
|
12356
|
+
this.log(`File changed: ${path13.basename(filePath)}, reloading...`);
|
|
12079
12357
|
this.reload();
|
|
12080
12358
|
}
|
|
12081
12359
|
};
|
|
@@ -12130,7 +12408,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12130
12408
|
}
|
|
12131
12409
|
const https = __require("https");
|
|
12132
12410
|
const { execSync: execSync7 } = __require("child_process");
|
|
12133
|
-
const metaPath =
|
|
12411
|
+
const metaPath = path13.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
12134
12412
|
let prevEtag = "";
|
|
12135
12413
|
let prevTimestamp = 0;
|
|
12136
12414
|
try {
|
|
@@ -12190,17 +12468,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12190
12468
|
return { updated: false };
|
|
12191
12469
|
}
|
|
12192
12470
|
this.log("Downloading latest providers from GitHub...");
|
|
12193
|
-
const tmpTar =
|
|
12194
|
-
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()}`);
|
|
12195
12473
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
12196
12474
|
fs6.mkdirSync(tmpExtract, { recursive: true });
|
|
12197
12475
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
12198
12476
|
const extracted = fs6.readdirSync(tmpExtract);
|
|
12199
12477
|
const rootDir = extracted.find(
|
|
12200
|
-
(d) => fs6.statSync(
|
|
12478
|
+
(d) => fs6.statSync(path13.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
12201
12479
|
);
|
|
12202
12480
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
12203
|
-
const sourceDir =
|
|
12481
|
+
const sourceDir = path13.join(tmpExtract, rootDir);
|
|
12204
12482
|
const backupDir = this.upstreamDir + ".bak";
|
|
12205
12483
|
if (fs6.existsSync(this.upstreamDir)) {
|
|
12206
12484
|
if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -12275,8 +12553,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12275
12553
|
copyDirRecursive(src, dest) {
|
|
12276
12554
|
fs6.mkdirSync(dest, { recursive: true });
|
|
12277
12555
|
for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
|
|
12278
|
-
const srcPath =
|
|
12279
|
-
const destPath =
|
|
12556
|
+
const srcPath = path13.join(src, entry.name);
|
|
12557
|
+
const destPath = path13.join(dest, entry.name);
|
|
12280
12558
|
if (entry.isDirectory()) {
|
|
12281
12559
|
this.copyDirRecursive(srcPath, destPath);
|
|
12282
12560
|
} else {
|
|
@@ -12287,7 +12565,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12287
12565
|
/** .meta.json save */
|
|
12288
12566
|
writeMeta(metaPath, etag, timestamp) {
|
|
12289
12567
|
try {
|
|
12290
|
-
fs6.mkdirSync(
|
|
12568
|
+
fs6.mkdirSync(path13.dirname(metaPath), { recursive: true });
|
|
12291
12569
|
fs6.writeFileSync(metaPath, JSON.stringify({
|
|
12292
12570
|
etag,
|
|
12293
12571
|
timestamp,
|
|
@@ -12304,7 +12582,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12304
12582
|
const scan = (d) => {
|
|
12305
12583
|
try {
|
|
12306
12584
|
for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
|
|
12307
|
-
if (entry.isDirectory()) scan(
|
|
12585
|
+
if (entry.isDirectory()) scan(path13.join(d, entry.name));
|
|
12308
12586
|
else if (entry.name === "provider.json") count++;
|
|
12309
12587
|
}
|
|
12310
12588
|
} catch {
|
|
@@ -12337,15 +12615,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12337
12615
|
*/
|
|
12338
12616
|
getSettingValue(type, key) {
|
|
12339
12617
|
const schemaDef = this.getSettingsSchema(type)[key];
|
|
12340
|
-
const defaultVal = schemaDef ? schemaDef.default : void 0;
|
|
12341
|
-
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
const userVal = config.providerSettings?.[type]?.[key];
|
|
12345
|
-
return userVal !== void 0 ? userVal : defaultVal;
|
|
12346
|
-
} catch {
|
|
12347
|
-
return defaultVal;
|
|
12348
|
-
}
|
|
12618
|
+
const defaultVal = schemaDef ? key === "autoApprove" && schemaDef.type === "boolean" ? true : schemaDef.default : void 0;
|
|
12619
|
+
const config = this.readConfig();
|
|
12620
|
+
const userVal = config?.providerSettings?.[type]?.[key];
|
|
12621
|
+
return userVal !== void 0 ? userVal : defaultVal;
|
|
12349
12622
|
}
|
|
12350
12623
|
/**
|
|
12351
12624
|
* All resolved settings for a provider (default + user override)
|
|
@@ -12373,13 +12646,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12373
12646
|
if (schemaDef.max !== void 0 && value > schemaDef.max) return false;
|
|
12374
12647
|
}
|
|
12375
12648
|
if (schemaDef.type === "select" && schemaDef.options && !schemaDef.options.includes(value)) return false;
|
|
12649
|
+
const config = this.readConfig();
|
|
12650
|
+
if (!config) return false;
|
|
12376
12651
|
try {
|
|
12377
|
-
const { loadConfig: loadConfig2, saveConfig: saveConfig3 } = (init_config(), __toCommonJS(config_exports));
|
|
12378
|
-
const config = loadConfig2();
|
|
12379
12652
|
if (!config.providerSettings) config.providerSettings = {};
|
|
12380
12653
|
if (!config.providerSettings[type]) config.providerSettings[type] = {};
|
|
12381
12654
|
config.providerSettings[type][key] = value;
|
|
12382
|
-
|
|
12655
|
+
this.writeConfig(config);
|
|
12383
12656
|
this.log(`Setting updated: ${type}.${key} = ${JSON.stringify(value)}`);
|
|
12384
12657
|
return true;
|
|
12385
12658
|
} catch (e) {
|
|
@@ -12393,16 +12666,63 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12393
12666
|
const trimmed = value.trim();
|
|
12394
12667
|
return trimmed ? trimmed : null;
|
|
12395
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
|
+
}
|
|
12396
12697
|
getSettingsSchema(type) {
|
|
12397
12698
|
const provider = this.providers.get(type);
|
|
12398
12699
|
if (!provider) return {};
|
|
12399
|
-
|
|
12700
|
+
const result = {
|
|
12400
12701
|
...this.getSyntheticSettings(type, provider),
|
|
12401
12702
|
...provider.settings || {}
|
|
12402
12703
|
};
|
|
12704
|
+
if (result.autoApprove?.type === "boolean") {
|
|
12705
|
+
result.autoApprove = {
|
|
12706
|
+
...result.autoApprove,
|
|
12707
|
+
default: true,
|
|
12708
|
+
public: true,
|
|
12709
|
+
label: result.autoApprove.label || "Auto Approve",
|
|
12710
|
+
description: result.autoApprove.description || "Automatically approve actionable prompts without sending approval alerts."
|
|
12711
|
+
};
|
|
12712
|
+
}
|
|
12713
|
+
return result;
|
|
12403
12714
|
}
|
|
12404
12715
|
getSyntheticSettings(type, provider) {
|
|
12405
12716
|
const result = {};
|
|
12717
|
+
if (!provider.settings?.autoApprove) {
|
|
12718
|
+
result.autoApprove = {
|
|
12719
|
+
type: "boolean",
|
|
12720
|
+
default: true,
|
|
12721
|
+
public: true,
|
|
12722
|
+
label: "Auto Approve",
|
|
12723
|
+
description: "Automatically approve actionable prompts without sending approval alerts."
|
|
12724
|
+
};
|
|
12725
|
+
}
|
|
12406
12726
|
if ((provider.category === "cli" || provider.category === "acp") && provider.spawn?.command && !provider.settings?.executablePath) {
|
|
12407
12727
|
result.executablePath = {
|
|
12408
12728
|
type: "string",
|
|
@@ -12447,17 +12767,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12447
12767
|
for (const root of searchRoots) {
|
|
12448
12768
|
if (!fs6.existsSync(root)) continue;
|
|
12449
12769
|
const candidate = this.getProviderDir(root, cat, type);
|
|
12450
|
-
if (fs6.existsSync(
|
|
12451
|
-
const catDir =
|
|
12770
|
+
if (fs6.existsSync(path13.join(candidate, "provider.json"))) return candidate;
|
|
12771
|
+
const catDir = path13.join(root, cat);
|
|
12452
12772
|
if (fs6.existsSync(catDir)) {
|
|
12453
12773
|
try {
|
|
12454
12774
|
for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
|
|
12455
12775
|
if (!entry.isDirectory()) continue;
|
|
12456
|
-
const jsonPath =
|
|
12776
|
+
const jsonPath = path13.join(catDir, entry.name, "provider.json");
|
|
12457
12777
|
if (fs6.existsSync(jsonPath)) {
|
|
12458
12778
|
try {
|
|
12459
12779
|
const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
|
|
12460
|
-
if (data.type === type) return
|
|
12780
|
+
if (data.type === type) return path13.join(catDir, entry.name);
|
|
12461
12781
|
} catch {
|
|
12462
12782
|
}
|
|
12463
12783
|
}
|
|
@@ -12474,7 +12794,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12474
12794
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
12475
12795
|
*/
|
|
12476
12796
|
buildScriptWrappersFromDir(dir) {
|
|
12477
|
-
const scriptsJs =
|
|
12797
|
+
const scriptsJs = path13.join(dir, "scripts.js");
|
|
12478
12798
|
if (fs6.existsSync(scriptsJs)) {
|
|
12479
12799
|
try {
|
|
12480
12800
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
@@ -12488,7 +12808,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12488
12808
|
for (const file of fs6.readdirSync(dir)) {
|
|
12489
12809
|
if (!file.endsWith(".js")) continue;
|
|
12490
12810
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
12491
|
-
const filePath =
|
|
12811
|
+
const filePath = path13.join(dir, file);
|
|
12492
12812
|
result[scriptName] = (...args) => {
|
|
12493
12813
|
try {
|
|
12494
12814
|
let content = fs6.readFileSync(filePath, "utf-8");
|
|
@@ -12548,35 +12868,39 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12548
12868
|
}
|
|
12549
12869
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
12550
12870
|
if (hasJson) {
|
|
12551
|
-
const jsonPath =
|
|
12871
|
+
const jsonPath = path13.join(d, "provider.json");
|
|
12552
12872
|
try {
|
|
12553
12873
|
const raw = fs6.readFileSync(jsonPath, "utf-8");
|
|
12554
12874
|
const mod = JSON.parse(raw);
|
|
12555
12875
|
if (!mod.type || !mod.name || !mod.category) {
|
|
12556
12876
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: missing type/name/category`);
|
|
12557
12877
|
} else {
|
|
12558
|
-
if (
|
|
12878
|
+
if (typeof mod.extensionIdPattern === "string") {
|
|
12559
12879
|
const flags = mod.extensionIdPattern_flags || "";
|
|
12560
12880
|
mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
|
|
12561
|
-
delete mod.extensionIdPattern_flags;
|
|
12562
12881
|
}
|
|
12563
|
-
const
|
|
12564
|
-
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");
|
|
12565
12889
|
if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
|
|
12566
12890
|
try {
|
|
12567
12891
|
delete __require.cache[__require.resolve(scriptsPath)];
|
|
12568
12892
|
const scripts = __require(scriptsPath);
|
|
12569
|
-
|
|
12893
|
+
normalizedProvider.scripts = scripts;
|
|
12570
12894
|
} catch (e) {
|
|
12571
12895
|
this.log(`\u26A0 Failed to load scripts: ${scriptsPath}: ${e.message}`);
|
|
12572
12896
|
}
|
|
12573
12897
|
}
|
|
12574
|
-
const existed = this.providers.has(
|
|
12575
|
-
this.providers.set(
|
|
12898
|
+
const existed = this.providers.has(normalizedProvider.type);
|
|
12899
|
+
this.providers.set(normalizedProvider.type, normalizedProvider);
|
|
12576
12900
|
count++;
|
|
12577
12901
|
const source = d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
|
|
12578
12902
|
const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
|
|
12579
|
-
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${
|
|
12903
|
+
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${source}]${overrideWarning}`);
|
|
12580
12904
|
}
|
|
12581
12905
|
} catch (e) {
|
|
12582
12906
|
this.log(`\u26A0 Failed to load ${jsonPath}: ${e.message}`);
|
|
@@ -12587,7 +12911,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12587
12911
|
if (!entry.isDirectory()) continue;
|
|
12588
12912
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
12589
12913
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
12590
|
-
scan(
|
|
12914
|
+
scan(path13.join(d, entry.name));
|
|
12591
12915
|
}
|
|
12592
12916
|
}
|
|
12593
12917
|
};
|
|
@@ -12657,9 +12981,9 @@ function getWinProcessNames() {
|
|
|
12657
12981
|
function getProviderMeta(ideId) {
|
|
12658
12982
|
return getProviderLoader().getMeta(ideId);
|
|
12659
12983
|
}
|
|
12660
|
-
function getPreferredLaunchMethod(ideId,
|
|
12984
|
+
function getPreferredLaunchMethod(ideId, platform10) {
|
|
12661
12985
|
const prefer = getProviderMeta(ideId)?.launch?.prefer;
|
|
12662
|
-
const value = prefer?.[
|
|
12986
|
+
const value = prefer?.[platform10];
|
|
12663
12987
|
return value === "cli" || value === "app" || value === "auto" ? value : "auto";
|
|
12664
12988
|
}
|
|
12665
12989
|
function getCdpStartupTimeoutMs(ideId) {
|
|
@@ -12716,7 +13040,7 @@ async function isCdpActive(port) {
|
|
|
12716
13040
|
});
|
|
12717
13041
|
}
|
|
12718
13042
|
async function killIdeProcess(ideId) {
|
|
12719
|
-
const plat =
|
|
13043
|
+
const plat = os14.platform();
|
|
12720
13044
|
const appName = getMacAppIdentifiers()[ideId];
|
|
12721
13045
|
const winProcesses = getWinProcessNames()[ideId];
|
|
12722
13046
|
try {
|
|
@@ -12775,7 +13099,7 @@ async function killIdeProcess(ideId) {
|
|
|
12775
13099
|
}
|
|
12776
13100
|
}
|
|
12777
13101
|
function isIdeRunning(ideId) {
|
|
12778
|
-
const plat =
|
|
13102
|
+
const plat = os14.platform();
|
|
12779
13103
|
try {
|
|
12780
13104
|
if (plat === "darwin") {
|
|
12781
13105
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -12826,7 +13150,7 @@ function isIdeRunning(ideId) {
|
|
|
12826
13150
|
}
|
|
12827
13151
|
}
|
|
12828
13152
|
function detectCurrentWorkspace(ideId) {
|
|
12829
|
-
const plat =
|
|
13153
|
+
const plat = os14.platform();
|
|
12830
13154
|
if (plat === "darwin") {
|
|
12831
13155
|
try {
|
|
12832
13156
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -12845,8 +13169,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
12845
13169
|
const appNameMap = getMacAppIdentifiers();
|
|
12846
13170
|
const appName = appNameMap[ideId];
|
|
12847
13171
|
if (appName) {
|
|
12848
|
-
const storagePath =
|
|
12849
|
-
process.env.APPDATA ||
|
|
13172
|
+
const storagePath = path14.join(
|
|
13173
|
+
process.env.APPDATA || path14.join(os14.homedir(), "AppData", "Roaming"),
|
|
12850
13174
|
appName,
|
|
12851
13175
|
"storage.json"
|
|
12852
13176
|
);
|
|
@@ -12868,7 +13192,7 @@ function detectCurrentWorkspace(ideId) {
|
|
|
12868
13192
|
return void 0;
|
|
12869
13193
|
}
|
|
12870
13194
|
async function launchWithCdp(options = {}) {
|
|
12871
|
-
const
|
|
13195
|
+
const platform10 = os14.platform();
|
|
12872
13196
|
let targetIde;
|
|
12873
13197
|
const ides = await detectIDEs(getProviderLoader());
|
|
12874
13198
|
if (options.ideId) {
|
|
@@ -12937,9 +13261,9 @@ async function launchWithCdp(options = {}) {
|
|
|
12937
13261
|
}
|
|
12938
13262
|
const port = await findFreePort(portPair);
|
|
12939
13263
|
try {
|
|
12940
|
-
if (
|
|
13264
|
+
if (platform10 === "darwin") {
|
|
12941
13265
|
await launchMacOS(targetIde, port, workspace, options.newWindow);
|
|
12942
|
-
} else if (
|
|
13266
|
+
} else if (platform10 === "win32") {
|
|
12943
13267
|
await launchWindows(targetIde, port, workspace, options.newWindow);
|
|
12944
13268
|
} else {
|
|
12945
13269
|
await launchLinux(targetIde, port, workspace, options.newWindow);
|
|
@@ -13024,9 +13348,9 @@ init_logger();
|
|
|
13024
13348
|
|
|
13025
13349
|
// src/logging/command-log.ts
|
|
13026
13350
|
import * as fs7 from "fs";
|
|
13027
|
-
import * as
|
|
13028
|
-
import * as
|
|
13029
|
-
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");
|
|
13030
13354
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
13031
13355
|
var MAX_DAYS = 7;
|
|
13032
13356
|
try {
|
|
@@ -13064,13 +13388,13 @@ function getDateStr2() {
|
|
|
13064
13388
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
13065
13389
|
}
|
|
13066
13390
|
var currentDate2 = getDateStr2();
|
|
13067
|
-
var currentFile =
|
|
13391
|
+
var currentFile = path15.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
13068
13392
|
var writeCount2 = 0;
|
|
13069
13393
|
function checkRotation() {
|
|
13070
13394
|
const today = getDateStr2();
|
|
13071
13395
|
if (today !== currentDate2) {
|
|
13072
13396
|
currentDate2 = today;
|
|
13073
|
-
currentFile =
|
|
13397
|
+
currentFile = path15.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
13074
13398
|
cleanOldFiles();
|
|
13075
13399
|
}
|
|
13076
13400
|
}
|
|
@@ -13084,7 +13408,7 @@ function cleanOldFiles() {
|
|
|
13084
13408
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
13085
13409
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
13086
13410
|
try {
|
|
13087
|
-
fs7.unlinkSync(
|
|
13411
|
+
fs7.unlinkSync(path15.join(LOG_DIR2, file));
|
|
13088
13412
|
} catch {
|
|
13089
13413
|
}
|
|
13090
13414
|
}
|
|
@@ -13162,7 +13486,7 @@ init_logger();
|
|
|
13162
13486
|
|
|
13163
13487
|
// src/status/snapshot.ts
|
|
13164
13488
|
init_config();
|
|
13165
|
-
import * as
|
|
13489
|
+
import * as os16 from "os";
|
|
13166
13490
|
init_terminal_screen();
|
|
13167
13491
|
init_logger();
|
|
13168
13492
|
var READ_DEBUG_ENABLED = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
@@ -13281,16 +13605,16 @@ function buildStatusSnapshot(options) {
|
|
|
13281
13605
|
version: options.version,
|
|
13282
13606
|
daemonMode: options.daemonMode,
|
|
13283
13607
|
machine: {
|
|
13284
|
-
hostname:
|
|
13285
|
-
platform:
|
|
13286
|
-
arch:
|
|
13287
|
-
cpus:
|
|
13608
|
+
hostname: os16.hostname(),
|
|
13609
|
+
platform: os16.platform(),
|
|
13610
|
+
arch: os16.arch(),
|
|
13611
|
+
cpus: os16.cpus().length,
|
|
13288
13612
|
totalMem: memSnap.totalMem,
|
|
13289
13613
|
freeMem: memSnap.freeMem,
|
|
13290
13614
|
availableMem: memSnap.availableMem,
|
|
13291
|
-
loadavg:
|
|
13292
|
-
uptime:
|
|
13293
|
-
release:
|
|
13615
|
+
loadavg: os16.loadavg(),
|
|
13616
|
+
uptime: os16.uptime(),
|
|
13617
|
+
release: os16.release()
|
|
13294
13618
|
},
|
|
13295
13619
|
machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
|
|
13296
13620
|
timestamp: options.timestamp ?? Date.now(),
|
|
@@ -13311,14 +13635,14 @@ function buildStatusSnapshot(options) {
|
|
|
13311
13635
|
import { execFileSync } from "child_process";
|
|
13312
13636
|
import { spawn as spawn3 } from "child_process";
|
|
13313
13637
|
import * as fs8 from "fs";
|
|
13314
|
-
import * as
|
|
13315
|
-
import * as
|
|
13638
|
+
import * as os17 from "os";
|
|
13639
|
+
import * as path16 from "path";
|
|
13316
13640
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
13317
13641
|
function getUpgradeLogPath() {
|
|
13318
|
-
const home =
|
|
13319
|
-
const dir =
|
|
13642
|
+
const home = os17.homedir();
|
|
13643
|
+
const dir = path16.join(home, ".adhdev");
|
|
13320
13644
|
fs8.mkdirSync(dir, { recursive: true });
|
|
13321
|
-
return
|
|
13645
|
+
return path16.join(dir, "daemon-upgrade.log");
|
|
13322
13646
|
}
|
|
13323
13647
|
function appendUpgradeLog(message) {
|
|
13324
13648
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -13358,7 +13682,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
13358
13682
|
}
|
|
13359
13683
|
}
|
|
13360
13684
|
function stopSessionHostProcesses(appName) {
|
|
13361
|
-
const pidFile =
|
|
13685
|
+
const pidFile = path16.join(os17.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
13362
13686
|
try {
|
|
13363
13687
|
if (fs8.existsSync(pidFile)) {
|
|
13364
13688
|
const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -13387,7 +13711,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
13387
13711
|
}
|
|
13388
13712
|
}
|
|
13389
13713
|
function removeDaemonPidFile() {
|
|
13390
|
-
const pidFile =
|
|
13714
|
+
const pidFile = path16.join(os17.homedir(), ".adhdev", "daemon.pid");
|
|
13391
13715
|
try {
|
|
13392
13716
|
fs8.unlinkSync(pidFile);
|
|
13393
13717
|
} catch {
|
|
@@ -13398,7 +13722,7 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
|
|
|
13398
13722
|
const npmRoot = execFileSync(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
13399
13723
|
if (!npmRoot) return;
|
|
13400
13724
|
const npmPrefix = execFileSync(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
13401
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
13725
|
+
const binDir = process.platform === "win32" ? npmPrefix : path16.join(npmPrefix, "bin");
|
|
13402
13726
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
13403
13727
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
13404
13728
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -13406,25 +13730,25 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
|
|
|
13406
13730
|
}
|
|
13407
13731
|
if (pkgName.startsWith("@")) {
|
|
13408
13732
|
const [scope, name] = pkgName.split("/");
|
|
13409
|
-
const scopeDir =
|
|
13733
|
+
const scopeDir = path16.join(npmRoot, scope);
|
|
13410
13734
|
if (!fs8.existsSync(scopeDir)) return;
|
|
13411
13735
|
for (const entry of fs8.readdirSync(scopeDir)) {
|
|
13412
13736
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
13413
|
-
fs8.rmSync(
|
|
13414
|
-
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)}`);
|
|
13415
13739
|
}
|
|
13416
13740
|
} else {
|
|
13417
13741
|
for (const entry of fs8.readdirSync(npmRoot)) {
|
|
13418
13742
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
13419
|
-
fs8.rmSync(
|
|
13420
|
-
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)}`);
|
|
13421
13745
|
}
|
|
13422
13746
|
}
|
|
13423
13747
|
if (fs8.existsSync(binDir)) {
|
|
13424
13748
|
for (const entry of fs8.readdirSync(binDir)) {
|
|
13425
13749
|
if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
13426
|
-
fs8.rmSync(
|
|
13427
|
-
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)}`);
|
|
13428
13752
|
}
|
|
13429
13753
|
}
|
|
13430
13754
|
}
|
|
@@ -13510,6 +13834,18 @@ var CHAT_COMMANDS = [
|
|
|
13510
13834
|
"change_model"
|
|
13511
13835
|
];
|
|
13512
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
|
+
}
|
|
13513
13849
|
function toHostedCliRuntimeDescriptor(record) {
|
|
13514
13850
|
if (!record || typeof record !== "object") return null;
|
|
13515
13851
|
const runtimeId = typeof record.sessionId === "string" ? record.sessionId : "";
|
|
@@ -13547,20 +13883,21 @@ var DaemonCommandRouter = class {
|
|
|
13547
13883
|
*/
|
|
13548
13884
|
async execute(cmd, args, source = "unknown") {
|
|
13549
13885
|
const cmdStart = Date.now();
|
|
13886
|
+
const logSource = normalizeCommandSource(source);
|
|
13550
13887
|
try {
|
|
13551
13888
|
const daemonResult = await this.executeDaemonCommand(cmd, args);
|
|
13552
13889
|
if (daemonResult) {
|
|
13553
|
-
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 });
|
|
13554
13891
|
return daemonResult;
|
|
13555
13892
|
}
|
|
13556
13893
|
const handlerResult = await this.deps.commandHandler.handle(cmd, args);
|
|
13557
|
-
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 });
|
|
13558
13895
|
if (CHAT_COMMANDS.includes(cmd) && this.deps.onPostChatCommand) {
|
|
13559
13896
|
this.deps.onPostChatCommand();
|
|
13560
13897
|
}
|
|
13561
13898
|
return handlerResult;
|
|
13562
13899
|
} catch (e) {
|
|
13563
|
-
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 });
|
|
13564
13901
|
throw e;
|
|
13565
13902
|
}
|
|
13566
13903
|
}
|
|
@@ -13830,7 +14167,7 @@ var DaemonCommandRouter = class {
|
|
|
13830
14167
|
} catch {
|
|
13831
14168
|
}
|
|
13832
14169
|
}
|
|
13833
|
-
return {
|
|
14170
|
+
return { ...result };
|
|
13834
14171
|
}
|
|
13835
14172
|
// ─── Detect IDEs ───
|
|
13836
14173
|
case "detect_ides": {
|
|
@@ -13960,16 +14297,14 @@ var DaemonCommandRouter = class {
|
|
|
13960
14297
|
}
|
|
13961
14298
|
}
|
|
13962
14299
|
for (const instanceKey of keysToRemove) {
|
|
13963
|
-
|
|
13964
|
-
if (ideInstance) {
|
|
14300
|
+
if (this.deps.instanceManager.getInstance(instanceKey)) {
|
|
13965
14301
|
this.deps.instanceManager.removeInstance(instanceKey);
|
|
13966
14302
|
LOG.info("StopIDE", `Instance removed: ${instanceKey}`);
|
|
13967
14303
|
}
|
|
13968
14304
|
}
|
|
13969
14305
|
if (keysToRemove.length === 0) {
|
|
13970
14306
|
const instanceKey = `ide:${ideType}`;
|
|
13971
|
-
|
|
13972
|
-
if (ideInstance) {
|
|
14307
|
+
if (this.deps.instanceManager.getInstance(instanceKey)) {
|
|
13973
14308
|
this.deps.instanceManager.removeInstance(instanceKey);
|
|
13974
14309
|
LOG.info("StopIDE", `Instance removed: ${instanceKey}`);
|
|
13975
14310
|
}
|
|
@@ -14184,11 +14519,11 @@ var DaemonStatusReporter = class {
|
|
|
14184
14519
|
// ─── P2P ─────────────────────────────────────────
|
|
14185
14520
|
sendP2PPayload(payload) {
|
|
14186
14521
|
const { timestamp: _ts, system: _sys, ...hashTarget } = payload;
|
|
14187
|
-
|
|
14522
|
+
const hashPayload = hashTarget.machine ? (() => {
|
|
14188
14523
|
const { freeMem: _f, availableMem: _a, loadavg: _l, uptime: _u, ...stableMachine } = hashTarget.machine;
|
|
14189
|
-
hashTarget
|
|
14190
|
-
}
|
|
14191
|
-
const h = this.simpleHash(JSON.stringify(
|
|
14524
|
+
return { ...hashTarget, machine: stableMachine };
|
|
14525
|
+
})() : hashTarget;
|
|
14526
|
+
const h = this.simpleHash(JSON.stringify(hashPayload));
|
|
14192
14527
|
if (h !== this.lastP2PStatusHash) {
|
|
14193
14528
|
this.lastP2PStatusHash = h;
|
|
14194
14529
|
this.deps.p2p?.sendStatus(payload);
|
|
@@ -14236,6 +14571,9 @@ var ProviderStreamAdapter = class {
|
|
|
14236
14571
|
hasScript(name) {
|
|
14237
14572
|
return typeof this.provider.scripts?.[name] === "function";
|
|
14238
14573
|
}
|
|
14574
|
+
getStateTitle(state) {
|
|
14575
|
+
return typeof state.title === "string" ? state.title : "";
|
|
14576
|
+
}
|
|
14239
14577
|
parseMaybeJson(raw) {
|
|
14240
14578
|
if (typeof raw !== "string") return raw;
|
|
14241
14579
|
try {
|
|
@@ -14439,7 +14777,7 @@ var ProviderStreamAdapter = class {
|
|
|
14439
14777
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
14440
14778
|
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
14441
14779
|
const state = await this.readChat(evaluate);
|
|
14442
|
-
const title =
|
|
14780
|
+
const title = this.getStateTitle(state);
|
|
14443
14781
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
14444
14782
|
}
|
|
14445
14783
|
return false;
|
|
@@ -14536,6 +14874,11 @@ var DaemonAgentStreamManager = class {
|
|
|
14536
14874
|
const child = (this.sessionRegistry?.listChildren(parentSessionId) || []).find((entry) => entry.transport === "cdp-webview" && entry.providerType === agentType);
|
|
14537
14875
|
return child?.sessionId || null;
|
|
14538
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
|
+
}
|
|
14539
14882
|
async connectManagedSession(cdp, parentSessionId, runtimeSessionId) {
|
|
14540
14883
|
const target = this.getSessionTarget(runtimeSessionId);
|
|
14541
14884
|
if (!target || target.transport !== "cdp-webview") return null;
|
|
@@ -14598,8 +14941,8 @@ var DaemonAgentStreamManager = class {
|
|
|
14598
14941
|
try {
|
|
14599
14942
|
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
14600
14943
|
const state = await agent.adapter.readChat(evaluate);
|
|
14601
|
-
|
|
14602
|
-
|
|
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) : ""}`);
|
|
14603
14946
|
if (state.status === "error" && this.isRecoverableSessionError(stateError)) {
|
|
14604
14947
|
throw new Error(stateError);
|
|
14605
14948
|
}
|
|
@@ -14888,7 +15231,43 @@ var AgentStreamPoller = class {
|
|
|
14888
15231
|
}
|
|
14889
15232
|
try {
|
|
14890
15233
|
await agentStreamManager.syncActiveSession(cdp, parentSessionId);
|
|
14891
|
-
|
|
15234
|
+
let stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
|
|
15235
|
+
if (stream?.status === "waiting_approval") {
|
|
15236
|
+
const autoApprove = providerLoader.getSettings(stream.agentType).autoApprove !== false;
|
|
15237
|
+
if (autoApprove && resolvedActiveSessionId) {
|
|
15238
|
+
const provider = providerLoader.getMeta(stream.agentType);
|
|
15239
|
+
const { label: buttonLabel } = pickApprovalButton(stream.activeModal?.buttons, provider);
|
|
15240
|
+
const approved = await agentStreamManager.resolveSessionAction(cdp, resolvedActiveSessionId, "approve", buttonLabel);
|
|
15241
|
+
if (approved) {
|
|
15242
|
+
const effectId = [
|
|
15243
|
+
"auto_approval",
|
|
15244
|
+
resolvedActiveSessionId,
|
|
15245
|
+
String(stream.messages?.length || 0),
|
|
15246
|
+
buttonLabel,
|
|
15247
|
+
String(stream.activeModal?.message || "").trim()
|
|
15248
|
+
].join(":");
|
|
15249
|
+
stream = {
|
|
15250
|
+
...stream,
|
|
15251
|
+
status: "streaming",
|
|
15252
|
+
activeModal: void 0,
|
|
15253
|
+
effects: [
|
|
15254
|
+
...stream.effects || [],
|
|
15255
|
+
{
|
|
15256
|
+
type: "message",
|
|
15257
|
+
id: effectId,
|
|
15258
|
+
persist: true,
|
|
15259
|
+
message: {
|
|
15260
|
+
role: "system",
|
|
15261
|
+
senderName: "System",
|
|
15262
|
+
kind: "system",
|
|
15263
|
+
content: formatAutoApprovalMessage(stream.activeModal?.message, buttonLabel)
|
|
15264
|
+
}
|
|
15265
|
+
}
|
|
15266
|
+
]
|
|
15267
|
+
};
|
|
15268
|
+
}
|
|
15269
|
+
}
|
|
15270
|
+
}
|
|
14892
15271
|
this.deps.onStreamsUpdated?.(ideType, stream ? [stream] : []);
|
|
14893
15272
|
} catch {
|
|
14894
15273
|
}
|
|
@@ -15132,11 +15511,11 @@ var ProviderInstanceManager = class {
|
|
|
15132
15511
|
|
|
15133
15512
|
// src/providers/version-archive.ts
|
|
15134
15513
|
import * as fs10 from "fs";
|
|
15135
|
-
import * as
|
|
15136
|
-
import * as
|
|
15514
|
+
import * as path17 from "path";
|
|
15515
|
+
import * as os18 from "os";
|
|
15137
15516
|
import { execSync as execSync5 } from "child_process";
|
|
15138
|
-
import { platform as
|
|
15139
|
-
var ARCHIVE_PATH =
|
|
15517
|
+
import { platform as platform8 } from "os";
|
|
15518
|
+
var ARCHIVE_PATH = path17.join(os18.homedir(), ".adhdev", "version-history.json");
|
|
15140
15519
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
15141
15520
|
var VersionArchive = class {
|
|
15142
15521
|
history = {};
|
|
@@ -15161,7 +15540,7 @@ var VersionArchive = class {
|
|
|
15161
15540
|
entries.push({
|
|
15162
15541
|
version,
|
|
15163
15542
|
detectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15164
|
-
os:
|
|
15543
|
+
os: platform8()
|
|
15165
15544
|
});
|
|
15166
15545
|
if (entries.length > MAX_ENTRIES_PER_PROVIDER) {
|
|
15167
15546
|
this.history[type] = entries.slice(-MAX_ENTRIES_PER_PROVIDER);
|
|
@@ -15183,7 +15562,7 @@ var VersionArchive = class {
|
|
|
15183
15562
|
}
|
|
15184
15563
|
save() {
|
|
15185
15564
|
try {
|
|
15186
|
-
fs10.mkdirSync(
|
|
15565
|
+
fs10.mkdirSync(path17.dirname(ARCHIVE_PATH), { recursive: true });
|
|
15187
15566
|
fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
15188
15567
|
} catch {
|
|
15189
15568
|
}
|
|
@@ -15201,7 +15580,7 @@ function runCommand(cmd, timeout = 1e4) {
|
|
|
15201
15580
|
}
|
|
15202
15581
|
}
|
|
15203
15582
|
function findBinary2(name) {
|
|
15204
|
-
const cmd =
|
|
15583
|
+
const cmd = platform8() === "win32" ? `where ${name}` : `which ${name}`;
|
|
15205
15584
|
const result = runCommand(cmd, 5e3);
|
|
15206
15585
|
return result ? result.split("\n")[0] : null;
|
|
15207
15586
|
}
|
|
@@ -15209,6 +15588,22 @@ function parseVersion2(raw) {
|
|
|
15209
15588
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
15210
15589
|
return match ? match[1] : raw.split("\n")[0].substring(0, 100);
|
|
15211
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
|
+
}
|
|
15212
15607
|
function getVersion(binary, versionCommand) {
|
|
15213
15608
|
if (versionCommand) {
|
|
15214
15609
|
const raw = runCommand(versionCommand);
|
|
@@ -15223,8 +15618,8 @@ function getVersion(binary, versionCommand) {
|
|
|
15223
15618
|
function checkPathExists2(paths) {
|
|
15224
15619
|
for (const p of paths) {
|
|
15225
15620
|
if (p.includes("*")) {
|
|
15226
|
-
const home =
|
|
15227
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
15621
|
+
const home = os18.homedir();
|
|
15622
|
+
const resolved = p.replace(/\*/g, home.split(path17.sep).pop() || "");
|
|
15228
15623
|
if (fs10.existsSync(resolved)) return resolved;
|
|
15229
15624
|
} else {
|
|
15230
15625
|
if (fs10.existsSync(p)) return p;
|
|
@@ -15233,15 +15628,15 @@ function checkPathExists2(paths) {
|
|
|
15233
15628
|
return null;
|
|
15234
15629
|
}
|
|
15235
15630
|
function getMacAppVersion(appPath) {
|
|
15236
|
-
if (
|
|
15237
|
-
const plistPath =
|
|
15631
|
+
if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
15632
|
+
const plistPath = path17.join(appPath, "Contents", "Info.plist");
|
|
15238
15633
|
if (!fs10.existsSync(plistPath)) return null;
|
|
15239
15634
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
15240
15635
|
return raw || null;
|
|
15241
15636
|
}
|
|
15242
15637
|
async function detectAllVersions(loader, archive) {
|
|
15243
15638
|
const results = [];
|
|
15244
|
-
const currentOs =
|
|
15639
|
+
const currentOs = platform8();
|
|
15245
15640
|
for (const provider of loader.getAll()) {
|
|
15246
15641
|
const info = {
|
|
15247
15642
|
type: provider.type,
|
|
@@ -15253,15 +15648,14 @@ async function detectAllVersions(loader, archive) {
|
|
|
15253
15648
|
binary: null,
|
|
15254
15649
|
detectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
15255
15650
|
};
|
|
15256
|
-
const
|
|
15257
|
-
const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[currentOs] : verCmdConfig;
|
|
15651
|
+
const versionCommand = getPlatformVersionCommand(provider.versionCommand, currentOs);
|
|
15258
15652
|
if (provider.category === "ide") {
|
|
15259
15653
|
const osPaths = provider.paths?.[currentOs] || [];
|
|
15260
15654
|
const appPath = checkPathExists2(osPaths);
|
|
15261
15655
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
15262
15656
|
let resolvedBin = cliBin;
|
|
15263
15657
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
15264
|
-
const bundled =
|
|
15658
|
+
const bundled = path17.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
15265
15659
|
if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
|
|
15266
15660
|
}
|
|
15267
15661
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -15302,7 +15696,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
15302
15696
|
// src/daemon/dev-server.ts
|
|
15303
15697
|
import * as http2 from "http";
|
|
15304
15698
|
import * as fs14 from "fs";
|
|
15305
|
-
import * as
|
|
15699
|
+
import * as path21 from "path";
|
|
15306
15700
|
|
|
15307
15701
|
// src/daemon/scaffold-template.ts
|
|
15308
15702
|
function generateFiles(type, name, category, opts = {}) {
|
|
@@ -15639,7 +16033,7 @@ init_logger();
|
|
|
15639
16033
|
// src/daemon/dev-cdp-handlers.ts
|
|
15640
16034
|
init_logger();
|
|
15641
16035
|
import * as fs11 from "fs";
|
|
15642
|
-
import * as
|
|
16036
|
+
import * as path18 from "path";
|
|
15643
16037
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
15644
16038
|
const body = await ctx.readBody(req);
|
|
15645
16039
|
const { expression, timeout, ideType } = body;
|
|
@@ -15817,17 +16211,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
15817
16211
|
return;
|
|
15818
16212
|
}
|
|
15819
16213
|
let scriptsPath = "";
|
|
15820
|
-
const directScripts =
|
|
16214
|
+
const directScripts = path18.join(dir, "scripts.js");
|
|
15821
16215
|
if (fs11.existsSync(directScripts)) {
|
|
15822
16216
|
scriptsPath = directScripts;
|
|
15823
16217
|
} else {
|
|
15824
|
-
const scriptsDir =
|
|
16218
|
+
const scriptsDir = path18.join(dir, "scripts");
|
|
15825
16219
|
if (fs11.existsSync(scriptsDir)) {
|
|
15826
16220
|
const versions = fs11.readdirSync(scriptsDir).filter((d) => {
|
|
15827
|
-
return fs11.statSync(
|
|
16221
|
+
return fs11.statSync(path18.join(scriptsDir, d)).isDirectory();
|
|
15828
16222
|
}).sort().reverse();
|
|
15829
16223
|
for (const ver of versions) {
|
|
15830
|
-
const p =
|
|
16224
|
+
const p = path18.join(scriptsDir, ver, "scripts.js");
|
|
15831
16225
|
if (fs11.existsSync(p)) {
|
|
15832
16226
|
scriptsPath = p;
|
|
15833
16227
|
break;
|
|
@@ -16646,7 +17040,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
16646
17040
|
|
|
16647
17041
|
// src/daemon/dev-cli-debug.ts
|
|
16648
17042
|
import * as fs12 from "fs";
|
|
16649
|
-
import * as
|
|
17043
|
+
import * as path19 from "path";
|
|
16650
17044
|
function slugifyFixtureName(value) {
|
|
16651
17045
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
16652
17046
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -16656,11 +17050,11 @@ function getCliFixtureDir(ctx, type) {
|
|
|
16656
17050
|
if (!providerDir) {
|
|
16657
17051
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
16658
17052
|
}
|
|
16659
|
-
return
|
|
17053
|
+
return path19.join(providerDir, "fixtures");
|
|
16660
17054
|
}
|
|
16661
17055
|
function readCliFixture(ctx, type, name) {
|
|
16662
17056
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
16663
|
-
const filePath =
|
|
17057
|
+
const filePath = path19.join(fixtureDir, `${name}.json`);
|
|
16664
17058
|
if (!fs12.existsSync(filePath)) {
|
|
16665
17059
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
16666
17060
|
}
|
|
@@ -16786,6 +17180,15 @@ function validateCliFixtureResult(result, assertions) {
|
|
|
16786
17180
|
}
|
|
16787
17181
|
return failures;
|
|
16788
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
|
+
}
|
|
16789
17192
|
function getCliProviderResolutionMeta(ctx, type, adapter) {
|
|
16790
17193
|
const adapterMeta = typeof adapter?.getProviderResolutionMeta === "function" ? adapter.getProviderResolutionMeta() : adapter?.getDebugState?.()?.providerResolution || null;
|
|
16791
17194
|
const resolvedProvider = ctx.providerLoader.resolve(type);
|
|
@@ -16803,7 +17206,7 @@ function getCliProviderResolutionMeta(ctx, type, adapter) {
|
|
|
16803
17206
|
}
|
|
16804
17207
|
function findCliTarget(ctx, type, instanceId) {
|
|
16805
17208
|
if (!ctx.instanceManager) return null;
|
|
16806
|
-
const cliStates = ctx.instanceManager.collectAllStates().filter(
|
|
17209
|
+
const cliStates = ctx.instanceManager.collectAllStates().filter(isCliTargetState);
|
|
16807
17210
|
if (instanceId) return cliStates.find((s) => s.instanceId === instanceId) || null;
|
|
16808
17211
|
if (!type) return cliStates[cliStates.length - 1] || null;
|
|
16809
17212
|
const matches = cliStates.filter((s) => s.type === type);
|
|
@@ -16815,7 +17218,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
|
|
|
16815
17218
|
if (!target) return null;
|
|
16816
17219
|
const instance = ctx.instanceManager.getInstance(target.instanceId);
|
|
16817
17220
|
if (!instance) return null;
|
|
16818
|
-
const adapter = instance
|
|
17221
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
16819
17222
|
if (!adapter) return null;
|
|
16820
17223
|
return { target, instance, adapter };
|
|
16821
17224
|
}
|
|
@@ -17290,7 +17693,7 @@ async function handleCliDebug(ctx, type, _req, res) {
|
|
|
17290
17693
|
return;
|
|
17291
17694
|
}
|
|
17292
17695
|
try {
|
|
17293
|
-
const adapter = instance
|
|
17696
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17294
17697
|
if (adapter && typeof adapter.getDebugState === "function") {
|
|
17295
17698
|
const debugState = adapter.getDebugState();
|
|
17296
17699
|
ctx.json(res, 200, {
|
|
@@ -17337,7 +17740,7 @@ async function handleCliTrace(ctx, type, req, res) {
|
|
|
17337
17740
|
return;
|
|
17338
17741
|
}
|
|
17339
17742
|
try {
|
|
17340
|
-
const adapter = instance
|
|
17743
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17341
17744
|
const url = new URL(req.url || "/", "http://127.0.0.1");
|
|
17342
17745
|
const limit = parseInt(url.searchParams.get("limit") || "120", 10);
|
|
17343
17746
|
if (adapter && typeof adapter.getTraceState === "function") {
|
|
@@ -17419,7 +17822,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
17419
17822
|
},
|
|
17420
17823
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
17421
17824
|
};
|
|
17422
|
-
const filePath =
|
|
17825
|
+
const filePath = path19.join(fixtureDir, `${name}.json`);
|
|
17423
17826
|
fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
17424
17827
|
ctx.json(res, 200, {
|
|
17425
17828
|
saved: true,
|
|
@@ -17443,7 +17846,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
|
|
|
17443
17846
|
return;
|
|
17444
17847
|
}
|
|
17445
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) => {
|
|
17446
|
-
const fullPath =
|
|
17849
|
+
const fullPath = path19.join(fixtureDir, file);
|
|
17447
17850
|
try {
|
|
17448
17851
|
const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
|
|
17449
17852
|
return {
|
|
@@ -17523,7 +17926,7 @@ async function handleCliResolve(ctx, req, res) {
|
|
|
17523
17926
|
return;
|
|
17524
17927
|
}
|
|
17525
17928
|
const instance = ctx.instanceManager.getInstance(target.instanceId);
|
|
17526
|
-
const adapter = instance
|
|
17929
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17527
17930
|
if (!adapter) {
|
|
17528
17931
|
ctx.json(res, 404, { error: `Adapter not found for instance: ${target.instanceId}` });
|
|
17529
17932
|
return;
|
|
@@ -17560,7 +17963,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
17560
17963
|
return;
|
|
17561
17964
|
}
|
|
17562
17965
|
const instance = ctx.instanceManager.getInstance(target.instanceId);
|
|
17563
|
-
const adapter = instance
|
|
17966
|
+
const adapter = getCliAdapterFromInstance(instance);
|
|
17564
17967
|
if (!adapter) {
|
|
17565
17968
|
ctx.json(res, 404, { error: `Adapter not found for instance: ${target.instanceId}` });
|
|
17566
17969
|
return;
|
|
@@ -17579,11 +17982,11 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
17579
17982
|
|
|
17580
17983
|
// src/daemon/dev-auto-implement.ts
|
|
17581
17984
|
import * as fs13 from "fs";
|
|
17582
|
-
import * as
|
|
17583
|
-
import * as
|
|
17985
|
+
import * as path20 from "path";
|
|
17986
|
+
import * as os19 from "os";
|
|
17584
17987
|
function getAutoImplPid(ctx) {
|
|
17585
|
-
const
|
|
17586
|
-
return
|
|
17988
|
+
const pid = ctx.autoImplProcess?.pid;
|
|
17989
|
+
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
17587
17990
|
}
|
|
17588
17991
|
function isPidAlive(pid) {
|
|
17589
17992
|
try {
|
|
@@ -17601,6 +18004,13 @@ function clearStaleAutoImplState(ctx, reason) {
|
|
|
17601
18004
|
ctx.autoImplProcess = null;
|
|
17602
18005
|
ctx.autoImplStatus.running = false;
|
|
17603
18006
|
}
|
|
18007
|
+
function tryKillAutoImplProcess(processRef, signal) {
|
|
18008
|
+
if (!processRef) return;
|
|
18009
|
+
try {
|
|
18010
|
+
processRef.kill(signal);
|
|
18011
|
+
} catch {
|
|
18012
|
+
}
|
|
18013
|
+
}
|
|
17604
18014
|
function getDefaultAutoImplReference(ctx, category, type) {
|
|
17605
18015
|
if (category === "cli") {
|
|
17606
18016
|
return type === "codex-cli" ? "claude-cli" : "codex-cli";
|
|
@@ -17619,22 +18029,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
17619
18029
|
if (!fs13.existsSync(scriptsDir)) return null;
|
|
17620
18030
|
const versions = fs13.readdirSync(scriptsDir).filter((d) => {
|
|
17621
18031
|
try {
|
|
17622
|
-
return fs13.statSync(
|
|
18032
|
+
return fs13.statSync(path20.join(scriptsDir, d)).isDirectory();
|
|
17623
18033
|
} catch {
|
|
17624
18034
|
return false;
|
|
17625
18035
|
}
|
|
17626
18036
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
17627
18037
|
if (versions.length === 0) return null;
|
|
17628
|
-
return
|
|
18038
|
+
return path20.join(scriptsDir, versions[0]);
|
|
17629
18039
|
}
|
|
17630
18040
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
17631
|
-
const canonicalUserDir =
|
|
17632
|
-
const desiredDir = requestedDir ?
|
|
17633
|
-
const upstreamRoot =
|
|
17634
|
-
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}`)) {
|
|
17635
18045
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
17636
18046
|
}
|
|
17637
|
-
if (
|
|
18047
|
+
if (path20.basename(desiredDir) !== type) {
|
|
17638
18048
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
17639
18049
|
}
|
|
17640
18050
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -17642,11 +18052,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
17642
18052
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
17643
18053
|
}
|
|
17644
18054
|
if (!fs13.existsSync(desiredDir)) {
|
|
17645
|
-
fs13.mkdirSync(
|
|
18055
|
+
fs13.mkdirSync(path20.dirname(desiredDir), { recursive: true });
|
|
17646
18056
|
fs13.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
17647
18057
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
17648
18058
|
}
|
|
17649
|
-
const providerJson =
|
|
18059
|
+
const providerJson = path20.join(desiredDir, "provider.json");
|
|
17650
18060
|
if (!fs13.existsSync(providerJson)) {
|
|
17651
18061
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
17652
18062
|
}
|
|
@@ -17669,13 +18079,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
17669
18079
|
const refDir = ctx.findProviderDir(referenceType);
|
|
17670
18080
|
if (!refDir || !fs13.existsSync(refDir)) return {};
|
|
17671
18081
|
const referenceScripts = {};
|
|
17672
|
-
const scriptsDir =
|
|
18082
|
+
const scriptsDir = path20.join(refDir, "scripts");
|
|
17673
18083
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
17674
18084
|
if (!latestDir) return referenceScripts;
|
|
17675
18085
|
for (const file of fs13.readdirSync(latestDir)) {
|
|
17676
18086
|
if (!file.endsWith(".js")) continue;
|
|
17677
18087
|
try {
|
|
17678
|
-
referenceScripts[file] = fs13.readFileSync(
|
|
18088
|
+
referenceScripts[file] = fs13.readFileSync(path20.join(latestDir, file), "utf-8");
|
|
17679
18089
|
} catch {
|
|
17680
18090
|
}
|
|
17681
18091
|
}
|
|
@@ -17783,9 +18193,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
17783
18193
|
});
|
|
17784
18194
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
17785
18195
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
17786
|
-
const tmpDir =
|
|
18196
|
+
const tmpDir = path20.join(os19.tmpdir(), "adhdev-autoimpl");
|
|
17787
18197
|
if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
|
|
17788
|
-
const promptFile =
|
|
18198
|
+
const promptFile = path20.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
17789
18199
|
fs13.writeFileSync(promptFile, prompt, "utf-8");
|
|
17790
18200
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
17791
18201
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -17937,7 +18347,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
17937
18347
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
17938
18348
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
17939
18349
|
let shellCmd;
|
|
17940
|
-
const isWin =
|
|
18350
|
+
const isWin = os19.platform() === "win32";
|
|
17941
18351
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
17942
18352
|
if (command === "claude") {
|
|
17943
18353
|
const args = [...baseArgs, "--dangerously-skip-permissions"];
|
|
@@ -17981,7 +18391,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
17981
18391
|
try {
|
|
17982
18392
|
const pty = __require("node-pty");
|
|
17983
18393
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
17984
|
-
const isWin2 =
|
|
18394
|
+
const isWin2 = os19.platform() === "win32";
|
|
17985
18395
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
17986
18396
|
name: "xterm-256color",
|
|
17987
18397
|
cols: 120,
|
|
@@ -18020,10 +18430,12 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18020
18430
|
let autoStopTimer = null;
|
|
18021
18431
|
let autoStopIssued = false;
|
|
18022
18432
|
try {
|
|
18023
|
-
|
|
18024
|
-
|
|
18025
|
-
|
|
18026
|
-
|
|
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
|
+
}
|
|
18027
18439
|
} catch (err) {
|
|
18028
18440
|
ctx.log(`Failed to load approval patterns: ${err.message}`);
|
|
18029
18441
|
}
|
|
@@ -18038,10 +18450,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18038
18450
|
[\u{1F916} ADHDev Pipeline] Completion token detected. Proceeding...
|
|
18039
18451
|
`, stream: "stdout" } });
|
|
18040
18452
|
approvalBuffer = "";
|
|
18041
|
-
|
|
18042
|
-
ctx.autoImplProcess.kill("SIGINT");
|
|
18043
|
-
} catch {
|
|
18044
|
-
}
|
|
18453
|
+
tryKillAutoImplProcess(ctx.autoImplProcess, "SIGINT");
|
|
18045
18454
|
return;
|
|
18046
18455
|
}
|
|
18047
18456
|
if (Date.now() - lastApprovalTime < 2e3) return;
|
|
@@ -18078,10 +18487,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18078
18487
|
stream: "stdout"
|
|
18079
18488
|
}
|
|
18080
18489
|
});
|
|
18081
|
-
|
|
18082
|
-
ctx.autoImplProcess.kill("SIGINT");
|
|
18083
|
-
} catch {
|
|
18084
|
-
}
|
|
18490
|
+
tryKillAutoImplProcess(ctx.autoImplProcess, "SIGINT");
|
|
18085
18491
|
}, 3e4);
|
|
18086
18492
|
};
|
|
18087
18493
|
const finalizeCliAutoImpl = async (code) => {
|
|
@@ -18212,7 +18618,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18212
18618
|
setMode: "set_mode.js"
|
|
18213
18619
|
};
|
|
18214
18620
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
18215
|
-
const scriptsDir =
|
|
18621
|
+
const scriptsDir = path20.join(providerDir, "scripts");
|
|
18216
18622
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
18217
18623
|
if (latestScriptsDir) {
|
|
18218
18624
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -18223,7 +18629,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18223
18629
|
for (const file of fs13.readdirSync(latestScriptsDir)) {
|
|
18224
18630
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
18225
18631
|
try {
|
|
18226
|
-
const content = fs13.readFileSync(
|
|
18632
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18227
18633
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
18228
18634
|
lines.push("```javascript");
|
|
18229
18635
|
lines.push(content);
|
|
@@ -18240,7 +18646,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18240
18646
|
lines.push("");
|
|
18241
18647
|
for (const file of refFiles) {
|
|
18242
18648
|
try {
|
|
18243
|
-
const content = fs13.readFileSync(
|
|
18649
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18244
18650
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
18245
18651
|
lines.push("```javascript");
|
|
18246
18652
|
lines.push(content);
|
|
@@ -18281,10 +18687,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18281
18687
|
lines.push("");
|
|
18282
18688
|
}
|
|
18283
18689
|
}
|
|
18284
|
-
const docsDir =
|
|
18690
|
+
const docsDir = path20.join(providerDir, "../../docs");
|
|
18285
18691
|
const loadGuide = (name) => {
|
|
18286
18692
|
try {
|
|
18287
|
-
const p =
|
|
18693
|
+
const p = path20.join(docsDir, name);
|
|
18288
18694
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
18289
18695
|
} catch {
|
|
18290
18696
|
}
|
|
@@ -18519,7 +18925,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18519
18925
|
parseApproval: "parse_approval.js"
|
|
18520
18926
|
};
|
|
18521
18927
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
18522
|
-
const scriptsDir =
|
|
18928
|
+
const scriptsDir = path20.join(providerDir, "scripts");
|
|
18523
18929
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
18524
18930
|
if (latestScriptsDir) {
|
|
18525
18931
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -18531,7 +18937,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18531
18937
|
if (!file.endsWith(".js")) continue;
|
|
18532
18938
|
if (!targetFileNames.has(file)) continue;
|
|
18533
18939
|
try {
|
|
18534
|
-
const content = fs13.readFileSync(
|
|
18940
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18535
18941
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
18536
18942
|
lines.push("```javascript");
|
|
18537
18943
|
lines.push(content);
|
|
@@ -18547,7 +18953,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18547
18953
|
lines.push("");
|
|
18548
18954
|
for (const file of refFiles) {
|
|
18549
18955
|
try {
|
|
18550
|
-
const content = fs13.readFileSync(
|
|
18956
|
+
const content = fs13.readFileSync(path20.join(latestScriptsDir, file), "utf-8");
|
|
18551
18957
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
18552
18958
|
lines.push("```javascript");
|
|
18553
18959
|
lines.push(content);
|
|
@@ -18580,10 +18986,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
18580
18986
|
lines.push("");
|
|
18581
18987
|
}
|
|
18582
18988
|
}
|
|
18583
|
-
const docsDir =
|
|
18989
|
+
const docsDir = path20.join(providerDir, "../../docs");
|
|
18584
18990
|
const loadGuide = (name) => {
|
|
18585
18991
|
try {
|
|
18586
|
-
const p =
|
|
18992
|
+
const p = path20.join(docsDir, name);
|
|
18587
18993
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
18588
18994
|
} catch {
|
|
18589
18995
|
}
|
|
@@ -18898,6 +19304,38 @@ data: ${JSON.stringify(msg.data)}
|
|
|
18898
19304
|
|
|
18899
19305
|
// src/daemon/dev-server.ts
|
|
18900
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
|
+
}
|
|
18901
19339
|
var DevServer = class _DevServer {
|
|
18902
19340
|
server = null;
|
|
18903
19341
|
providerLoader;
|
|
@@ -18994,8 +19432,8 @@ var DevServer = class _DevServer {
|
|
|
18994
19432
|
}
|
|
18995
19433
|
getEndpointList() {
|
|
18996
19434
|
return this.routes.map((r) => {
|
|
18997
|
-
const
|
|
18998
|
-
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}`;
|
|
18999
19437
|
});
|
|
19000
19438
|
}
|
|
19001
19439
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -19047,34 +19485,7 @@ var DevServer = class _DevServer {
|
|
|
19047
19485
|
}
|
|
19048
19486
|
// ─── Handlers ───
|
|
19049
19487
|
async handleListProviders(_req, res) {
|
|
19050
|
-
const providers = this.providerLoader.getAll().map(
|
|
19051
|
-
const base = {
|
|
19052
|
-
type: p.type,
|
|
19053
|
-
name: p.name,
|
|
19054
|
-
category: p.category,
|
|
19055
|
-
icon: p.icon || null,
|
|
19056
|
-
displayName: p.displayName || p.name
|
|
19057
|
-
};
|
|
19058
|
-
if (p.category === "ide" || p.category === "extension") {
|
|
19059
|
-
base.scripts = p.scripts ? Object.keys(p.scripts).filter((k) => typeof p.scripts[k] === "function") : [];
|
|
19060
|
-
base.inputMethod = p.inputMethod || null;
|
|
19061
|
-
base.inputSelector = p.inputSelector || null;
|
|
19062
|
-
base.extensionId = p.extensionId || null;
|
|
19063
|
-
base.cdpPorts = p.cdpPorts || [];
|
|
19064
|
-
}
|
|
19065
|
-
if (p.category === "acp") {
|
|
19066
|
-
base.spawn = p.spawn || null;
|
|
19067
|
-
base.auth = p.auth || null;
|
|
19068
|
-
base.install = p.install || null;
|
|
19069
|
-
base.hasSettings = !!p.settings;
|
|
19070
|
-
base.settingsCount = p.settings ? Object.keys(p.settings).length : 0;
|
|
19071
|
-
}
|
|
19072
|
-
if (p.category === "cli") {
|
|
19073
|
-
base.spawn = p.spawn || null;
|
|
19074
|
-
base.install = p.install || null;
|
|
19075
|
-
}
|
|
19076
|
-
return base;
|
|
19077
|
-
});
|
|
19488
|
+
const providers = this.providerLoader.getAll().map(toProviderListEntry);
|
|
19078
19489
|
this.json(res, 200, { providers, count: providers.length });
|
|
19079
19490
|
}
|
|
19080
19491
|
async handleProviderConfig(type, _req, res) {
|
|
@@ -19266,7 +19677,7 @@ var DevServer = class _DevServer {
|
|
|
19266
19677
|
}));
|
|
19267
19678
|
for (const cdp of this.cdpManagers.values()) {
|
|
19268
19679
|
if (!cdp.isConnected) {
|
|
19269
|
-
cdp.
|
|
19680
|
+
cdp.clearTargetId();
|
|
19270
19681
|
}
|
|
19271
19682
|
}
|
|
19272
19683
|
this.json(res, 200, { reloaded: true, providers });
|
|
@@ -19277,12 +19688,12 @@ var DevServer = class _DevServer {
|
|
|
19277
19688
|
// ─── DevConsole SPA ───
|
|
19278
19689
|
getConsoleDistDir() {
|
|
19279
19690
|
const candidates = [
|
|
19280
|
-
|
|
19281
|
-
|
|
19282
|
-
|
|
19691
|
+
path21.resolve(__dirname, "../../web-devconsole/dist"),
|
|
19692
|
+
path21.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
19693
|
+
path21.join(process.cwd(), "packages/web-devconsole/dist")
|
|
19283
19694
|
];
|
|
19284
19695
|
for (const dir of candidates) {
|
|
19285
|
-
if (fs14.existsSync(
|
|
19696
|
+
if (fs14.existsSync(path21.join(dir, "index.html"))) return dir;
|
|
19286
19697
|
}
|
|
19287
19698
|
return null;
|
|
19288
19699
|
}
|
|
@@ -19292,7 +19703,7 @@ var DevServer = class _DevServer {
|
|
|
19292
19703
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
19293
19704
|
return;
|
|
19294
19705
|
}
|
|
19295
|
-
const htmlPath =
|
|
19706
|
+
const htmlPath = path21.join(distDir, "index.html");
|
|
19296
19707
|
try {
|
|
19297
19708
|
const html = fs14.readFileSync(htmlPath, "utf-8");
|
|
19298
19709
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -19317,15 +19728,15 @@ var DevServer = class _DevServer {
|
|
|
19317
19728
|
this.json(res, 404, { error: "Not found" });
|
|
19318
19729
|
return;
|
|
19319
19730
|
}
|
|
19320
|
-
const safePath =
|
|
19321
|
-
const filePath =
|
|
19731
|
+
const safePath = path21.normalize(pathname).replace(/^\.\.\//, "");
|
|
19732
|
+
const filePath = path21.join(distDir, safePath);
|
|
19322
19733
|
if (!filePath.startsWith(distDir)) {
|
|
19323
19734
|
this.json(res, 403, { error: "Forbidden" });
|
|
19324
19735
|
return;
|
|
19325
19736
|
}
|
|
19326
19737
|
try {
|
|
19327
19738
|
const content = fs14.readFileSync(filePath);
|
|
19328
|
-
const ext =
|
|
19739
|
+
const ext = path21.extname(filePath);
|
|
19329
19740
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
19330
19741
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
19331
19742
|
res.end(content);
|
|
@@ -19438,9 +19849,9 @@ var DevServer = class _DevServer {
|
|
|
19438
19849
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
19439
19850
|
if (entry.isDirectory()) {
|
|
19440
19851
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
19441
|
-
scan(
|
|
19852
|
+
scan(path21.join(d, entry.name), rel);
|
|
19442
19853
|
} else {
|
|
19443
|
-
const stat = fs14.statSync(
|
|
19854
|
+
const stat = fs14.statSync(path21.join(d, entry.name));
|
|
19444
19855
|
files.push({ path: rel, size: stat.size, type: "file" });
|
|
19445
19856
|
}
|
|
19446
19857
|
}
|
|
@@ -19463,7 +19874,7 @@ var DevServer = class _DevServer {
|
|
|
19463
19874
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
19464
19875
|
return;
|
|
19465
19876
|
}
|
|
19466
|
-
const fullPath =
|
|
19877
|
+
const fullPath = path21.resolve(dir, path21.normalize(filePath));
|
|
19467
19878
|
if (!fullPath.startsWith(dir)) {
|
|
19468
19879
|
this.json(res, 403, { error: "Forbidden" });
|
|
19469
19880
|
return;
|
|
@@ -19488,14 +19899,14 @@ var DevServer = class _DevServer {
|
|
|
19488
19899
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
19489
19900
|
return;
|
|
19490
19901
|
}
|
|
19491
|
-
const fullPath =
|
|
19902
|
+
const fullPath = path21.resolve(dir, path21.normalize(filePath));
|
|
19492
19903
|
if (!fullPath.startsWith(dir)) {
|
|
19493
19904
|
this.json(res, 403, { error: "Forbidden" });
|
|
19494
19905
|
return;
|
|
19495
19906
|
}
|
|
19496
19907
|
try {
|
|
19497
19908
|
if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
|
|
19498
|
-
fs14.mkdirSync(
|
|
19909
|
+
fs14.mkdirSync(path21.dirname(fullPath), { recursive: true });
|
|
19499
19910
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
19500
19911
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
19501
19912
|
this.providerLoader.reload();
|
|
@@ -19512,7 +19923,7 @@ var DevServer = class _DevServer {
|
|
|
19512
19923
|
return;
|
|
19513
19924
|
}
|
|
19514
19925
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
19515
|
-
const p =
|
|
19926
|
+
const p = path21.join(dir, name);
|
|
19516
19927
|
if (fs14.existsSync(p)) {
|
|
19517
19928
|
const source = fs14.readFileSync(p, "utf-8");
|
|
19518
19929
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -19533,8 +19944,8 @@ var DevServer = class _DevServer {
|
|
|
19533
19944
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
19534
19945
|
return;
|
|
19535
19946
|
}
|
|
19536
|
-
const target = fs14.existsSync(
|
|
19537
|
-
const targetPath =
|
|
19947
|
+
const target = fs14.existsSync(path21.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
19948
|
+
const targetPath = path21.join(dir, target);
|
|
19538
19949
|
try {
|
|
19539
19950
|
if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
|
|
19540
19951
|
fs14.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -19694,7 +20105,7 @@ var DevServer = class _DevServer {
|
|
|
19694
20105
|
}
|
|
19695
20106
|
let targetDir;
|
|
19696
20107
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
19697
|
-
const jsonPath =
|
|
20108
|
+
const jsonPath = path21.join(targetDir, "provider.json");
|
|
19698
20109
|
if (fs14.existsSync(jsonPath)) {
|
|
19699
20110
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
19700
20111
|
return;
|
|
@@ -19706,8 +20117,8 @@ var DevServer = class _DevServer {
|
|
|
19706
20117
|
const createdFiles = ["provider.json"];
|
|
19707
20118
|
if (result.files) {
|
|
19708
20119
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
19709
|
-
const fullPath =
|
|
19710
|
-
fs14.mkdirSync(
|
|
20120
|
+
const fullPath = path21.join(targetDir, relPath);
|
|
20121
|
+
fs14.mkdirSync(path21.dirname(fullPath), { recursive: true });
|
|
19711
20122
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
19712
20123
|
createdFiles.push(relPath);
|
|
19713
20124
|
}
|
|
@@ -19760,22 +20171,22 @@ var DevServer = class _DevServer {
|
|
|
19760
20171
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
19761
20172
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
19762
20173
|
try {
|
|
19763
|
-
return fs14.statSync(
|
|
20174
|
+
return fs14.statSync(path21.join(scriptsDir, d)).isDirectory();
|
|
19764
20175
|
} catch {
|
|
19765
20176
|
return false;
|
|
19766
20177
|
}
|
|
19767
20178
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
19768
20179
|
if (versions.length === 0) return null;
|
|
19769
|
-
return
|
|
20180
|
+
return path21.join(scriptsDir, versions[0]);
|
|
19770
20181
|
}
|
|
19771
20182
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
19772
|
-
const canonicalUserDir =
|
|
19773
|
-
const desiredDir = requestedDir ?
|
|
19774
|
-
const upstreamRoot =
|
|
19775
|
-
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}`)) {
|
|
19776
20187
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
19777
20188
|
}
|
|
19778
|
-
if (
|
|
20189
|
+
if (path21.basename(desiredDir) !== type) {
|
|
19779
20190
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
19780
20191
|
}
|
|
19781
20192
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -19783,11 +20194,11 @@ var DevServer = class _DevServer {
|
|
|
19783
20194
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
19784
20195
|
}
|
|
19785
20196
|
if (!fs14.existsSync(desiredDir)) {
|
|
19786
|
-
fs14.mkdirSync(
|
|
20197
|
+
fs14.mkdirSync(path21.dirname(desiredDir), { recursive: true });
|
|
19787
20198
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
19788
20199
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
19789
20200
|
}
|
|
19790
|
-
const providerJson =
|
|
20201
|
+
const providerJson = path21.join(desiredDir, "provider.json");
|
|
19791
20202
|
if (!fs14.existsSync(providerJson)) {
|
|
19792
20203
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
19793
20204
|
}
|
|
@@ -19835,7 +20246,7 @@ var DevServer = class _DevServer {
|
|
|
19835
20246
|
setMode: "set_mode.js"
|
|
19836
20247
|
};
|
|
19837
20248
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
19838
|
-
const scriptsDir =
|
|
20249
|
+
const scriptsDir = path21.join(providerDir, "scripts");
|
|
19839
20250
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
19840
20251
|
if (latestScriptsDir) {
|
|
19841
20252
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -19846,7 +20257,7 @@ var DevServer = class _DevServer {
|
|
|
19846
20257
|
for (const file of fs14.readdirSync(latestScriptsDir)) {
|
|
19847
20258
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
19848
20259
|
try {
|
|
19849
|
-
const content = fs14.readFileSync(
|
|
20260
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19850
20261
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
19851
20262
|
lines.push("```javascript");
|
|
19852
20263
|
lines.push(content);
|
|
@@ -19863,7 +20274,7 @@ var DevServer = class _DevServer {
|
|
|
19863
20274
|
lines.push("");
|
|
19864
20275
|
for (const file of refFiles) {
|
|
19865
20276
|
try {
|
|
19866
|
-
const content = fs14.readFileSync(
|
|
20277
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19867
20278
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
19868
20279
|
lines.push("```javascript");
|
|
19869
20280
|
lines.push(content);
|
|
@@ -19904,10 +20315,10 @@ var DevServer = class _DevServer {
|
|
|
19904
20315
|
lines.push("");
|
|
19905
20316
|
}
|
|
19906
20317
|
}
|
|
19907
|
-
const docsDir =
|
|
20318
|
+
const docsDir = path21.join(providerDir, "../../docs");
|
|
19908
20319
|
const loadGuide = (name) => {
|
|
19909
20320
|
try {
|
|
19910
|
-
const p =
|
|
20321
|
+
const p = path21.join(docsDir, name);
|
|
19911
20322
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
19912
20323
|
} catch {
|
|
19913
20324
|
}
|
|
@@ -20081,7 +20492,7 @@ var DevServer = class _DevServer {
|
|
|
20081
20492
|
parseApproval: "parse_approval.js"
|
|
20082
20493
|
};
|
|
20083
20494
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
20084
|
-
const scriptsDir =
|
|
20495
|
+
const scriptsDir = path21.join(providerDir, "scripts");
|
|
20085
20496
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
20086
20497
|
if (latestScriptsDir) {
|
|
20087
20498
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -20093,7 +20504,7 @@ var DevServer = class _DevServer {
|
|
|
20093
20504
|
if (!file.endsWith(".js")) continue;
|
|
20094
20505
|
if (!targetFileNames.has(file)) continue;
|
|
20095
20506
|
try {
|
|
20096
|
-
const content = fs14.readFileSync(
|
|
20507
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
20097
20508
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
20098
20509
|
lines.push("```javascript");
|
|
20099
20510
|
lines.push(content);
|
|
@@ -20109,7 +20520,7 @@ var DevServer = class _DevServer {
|
|
|
20109
20520
|
lines.push("");
|
|
20110
20521
|
for (const file of refFiles) {
|
|
20111
20522
|
try {
|
|
20112
|
-
const content = fs14.readFileSync(
|
|
20523
|
+
const content = fs14.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
20113
20524
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
20114
20525
|
lines.push("```javascript");
|
|
20115
20526
|
lines.push(content);
|
|
@@ -20142,10 +20553,10 @@ var DevServer = class _DevServer {
|
|
|
20142
20553
|
lines.push("");
|
|
20143
20554
|
}
|
|
20144
20555
|
}
|
|
20145
|
-
const docsDir =
|
|
20556
|
+
const docsDir = path21.join(providerDir, "../../docs");
|
|
20146
20557
|
const loadGuide = (name) => {
|
|
20147
20558
|
try {
|
|
20148
|
-
const p =
|
|
20559
|
+
const p = path21.join(docsDir, name);
|
|
20149
20560
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
20150
20561
|
} catch {
|
|
20151
20562
|
}
|