@adhdev/daemon-standalone 0.8.25 → 0.8.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +890 -378
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-B9NQFXHb.js +57 -0
- package/public/assets/index-DD_wrUJr.css +1 -0
- package/public/index.html +2 -2
- package/vendor/session-host-daemon/index.d.mts +16 -0
- package/vendor/session-host-daemon/index.d.ts +16 -0
- package/vendor/session-host-daemon/index.js +200 -4
- package/vendor/session-host-daemon/index.js.map +1 -1
- package/vendor/session-host-daemon/index.mjs +200 -4
- package/vendor/session-host-daemon/index.mjs.map +1 -1
- package/public/assets/index-CWSn3MY1.js +0 -55
- package/public/assets/index-DGZ1wx9R.css +0 -1
package/dist/index.js
CHANGED
|
@@ -28029,13 +28029,13 @@ var require_dist2 = __commonJS({
|
|
|
28029
28029
|
return LOG_DIR;
|
|
28030
28030
|
}
|
|
28031
28031
|
function getCurrentDaemonLogPath(date5 = /* @__PURE__ */ new Date()) {
|
|
28032
|
-
return
|
|
28032
|
+
return path6.join(LOG_DIR, `daemon-${date5.toISOString().slice(0, 10)}.log`);
|
|
28033
28033
|
}
|
|
28034
28034
|
function checkDateRotation() {
|
|
28035
28035
|
const today = getDateStr();
|
|
28036
28036
|
if (today !== currentDate) {
|
|
28037
28037
|
currentDate = today;
|
|
28038
|
-
currentLogFile =
|
|
28038
|
+
currentLogFile = path6.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
28039
28039
|
cleanOldLogs();
|
|
28040
28040
|
}
|
|
28041
28041
|
}
|
|
@@ -28049,7 +28049,7 @@ var require_dist2 = __commonJS({
|
|
|
28049
28049
|
const dateMatch = file2.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
28050
28050
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
28051
28051
|
try {
|
|
28052
|
-
fs22.unlinkSync(
|
|
28052
|
+
fs22.unlinkSync(path6.join(LOG_DIR, file2));
|
|
28053
28053
|
} catch {
|
|
28054
28054
|
}
|
|
28055
28055
|
}
|
|
@@ -28167,7 +28167,7 @@ var require_dist2 = __commonJS({
|
|
|
28167
28167
|
writeToFile(`Log level: ${currentLevel}`);
|
|
28168
28168
|
}
|
|
28169
28169
|
var fs22;
|
|
28170
|
-
var
|
|
28170
|
+
var path6;
|
|
28171
28171
|
var os42;
|
|
28172
28172
|
var LEVEL_NUM;
|
|
28173
28173
|
var LEVEL_LABEL;
|
|
@@ -28190,12 +28190,12 @@ var require_dist2 = __commonJS({
|
|
|
28190
28190
|
"src/logging/logger.ts"() {
|
|
28191
28191
|
"use strict";
|
|
28192
28192
|
fs22 = __toESM2(require("fs"));
|
|
28193
|
-
|
|
28193
|
+
path6 = __toESM2(require("path"));
|
|
28194
28194
|
os42 = __toESM2(require("os"));
|
|
28195
28195
|
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
28196
28196
|
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
28197
28197
|
currentLevel = "info";
|
|
28198
|
-
LOG_DIR = process.platform === "win32" ?
|
|
28198
|
+
LOG_DIR = process.platform === "win32" ? path6.join(process.env.LOCALAPPDATA || process.env.APPDATA || path6.join(os42.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path6.join(os42.homedir(), "Library", "Logs", "adhdev") : path6.join(os42.homedir(), ".local", "share", "adhdev", "logs");
|
|
28199
28199
|
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
28200
28200
|
MAX_LOG_DAYS = 7;
|
|
28201
28201
|
try {
|
|
@@ -28203,16 +28203,16 @@ var require_dist2 = __commonJS({
|
|
|
28203
28203
|
} catch {
|
|
28204
28204
|
}
|
|
28205
28205
|
currentDate = getDateStr();
|
|
28206
|
-
currentLogFile =
|
|
28206
|
+
currentLogFile = path6.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
28207
28207
|
cleanOldLogs();
|
|
28208
28208
|
try {
|
|
28209
|
-
const oldLog =
|
|
28209
|
+
const oldLog = path6.join(LOG_DIR, "daemon.log");
|
|
28210
28210
|
if (fs22.existsSync(oldLog)) {
|
|
28211
28211
|
const stat4 = fs22.statSync(oldLog);
|
|
28212
28212
|
const oldDate = stat4.mtime.toISOString().slice(0, 10);
|
|
28213
|
-
fs22.renameSync(oldLog,
|
|
28213
|
+
fs22.renameSync(oldLog, path6.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
28214
28214
|
}
|
|
28215
|
-
const oldLogBackup =
|
|
28215
|
+
const oldLogBackup = path6.join(LOG_DIR, "daemon.log.old");
|
|
28216
28216
|
if (fs22.existsSync(oldLogBackup)) {
|
|
28217
28217
|
fs22.unlinkSync(oldLogBackup);
|
|
28218
28218
|
}
|
|
@@ -28244,7 +28244,7 @@ var require_dist2 = __commonJS({
|
|
|
28244
28244
|
}
|
|
28245
28245
|
};
|
|
28246
28246
|
interceptorInstalled = false;
|
|
28247
|
-
LOG_PATH =
|
|
28247
|
+
LOG_PATH = path6.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
28248
28248
|
}
|
|
28249
28249
|
});
|
|
28250
28250
|
function isModuleNotFoundError(error48, ref) {
|
|
@@ -28512,18 +28512,18 @@ var require_dist2 = __commonJS({
|
|
|
28512
28512
|
};
|
|
28513
28513
|
}
|
|
28514
28514
|
});
|
|
28515
|
-
var
|
|
28515
|
+
var import_session_host_core3;
|
|
28516
28516
|
var init_spawn_env = __esm2({
|
|
28517
28517
|
"src/cli-adapters/spawn-env.ts"() {
|
|
28518
28518
|
"use strict";
|
|
28519
|
-
|
|
28519
|
+
import_session_host_core3 = require_dist();
|
|
28520
28520
|
}
|
|
28521
28521
|
});
|
|
28522
28522
|
function loadNodePty() {
|
|
28523
28523
|
if (cachedPty !== void 0) return cachedPty;
|
|
28524
28524
|
try {
|
|
28525
28525
|
cachedPty = require("node-pty");
|
|
28526
|
-
(0,
|
|
28526
|
+
(0, import_session_host_core3.ensureNodePtySpawnHelperPermissions)();
|
|
28527
28527
|
} catch {
|
|
28528
28528
|
cachedPty = null;
|
|
28529
28529
|
}
|
|
@@ -28666,16 +28666,22 @@ var require_dist2 = __commonJS({
|
|
|
28666
28666
|
return "";
|
|
28667
28667
|
}
|
|
28668
28668
|
function findBinary(name) {
|
|
28669
|
+
const trimmed = String(name || "").trim();
|
|
28670
|
+
if (!trimmed) return trimmed;
|
|
28671
|
+
const expanded = trimmed.startsWith("~") ? path9.join(os8.homedir(), trimmed.slice(1)) : trimmed;
|
|
28672
|
+
if (path9.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
28673
|
+
return path9.isAbsolute(expanded) ? expanded : path9.resolve(expanded);
|
|
28674
|
+
}
|
|
28669
28675
|
const isWin = os8.platform() === "win32";
|
|
28670
28676
|
try {
|
|
28671
|
-
const cmd = isWin ? `where ${
|
|
28677
|
+
const cmd = isWin ? `where ${trimmed}` : `which ${trimmed}`;
|
|
28672
28678
|
return (0, import_child_process4.execSync)(cmd, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n")[0].trim();
|
|
28673
28679
|
} catch {
|
|
28674
|
-
return isWin ? `${
|
|
28680
|
+
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
28675
28681
|
}
|
|
28676
28682
|
}
|
|
28677
28683
|
function isScriptBinary(binaryPath) {
|
|
28678
|
-
if (!
|
|
28684
|
+
if (!path9.isAbsolute(binaryPath)) return false;
|
|
28679
28685
|
try {
|
|
28680
28686
|
const fs15 = require("fs");
|
|
28681
28687
|
const resolved = fs15.realpathSync(binaryPath);
|
|
@@ -28691,7 +28697,7 @@ var require_dist2 = __commonJS({
|
|
|
28691
28697
|
}
|
|
28692
28698
|
}
|
|
28693
28699
|
function looksLikeMachOOrElf(filePath) {
|
|
28694
|
-
if (!
|
|
28700
|
+
if (!path9.isAbsolute(filePath)) return false;
|
|
28695
28701
|
try {
|
|
28696
28702
|
const fs15 = require("fs");
|
|
28697
28703
|
const resolved = fs15.realpathSync(filePath);
|
|
@@ -28816,7 +28822,7 @@ var require_dist2 = __commonJS({
|
|
|
28816
28822
|
};
|
|
28817
28823
|
}
|
|
28818
28824
|
var os8;
|
|
28819
|
-
var
|
|
28825
|
+
var path9;
|
|
28820
28826
|
var import_child_process4;
|
|
28821
28827
|
var buildCliSpawnEnv;
|
|
28822
28828
|
var ProviderCliAdapter;
|
|
@@ -28824,13 +28830,13 @@ var require_dist2 = __commonJS({
|
|
|
28824
28830
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
28825
28831
|
"use strict";
|
|
28826
28832
|
os8 = __toESM2(require("os"));
|
|
28827
|
-
|
|
28833
|
+
path9 = __toESM2(require("path"));
|
|
28828
28834
|
import_child_process4 = require("child_process");
|
|
28829
28835
|
init_logger();
|
|
28830
28836
|
init_terminal_screen();
|
|
28831
28837
|
init_pty_transport();
|
|
28832
28838
|
init_spawn_env();
|
|
28833
|
-
buildCliSpawnEnv =
|
|
28839
|
+
buildCliSpawnEnv = import_session_host_core3.sanitizeSpawnEnv;
|
|
28834
28840
|
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
28835
28841
|
constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
|
|
28836
28842
|
this.extraArgs = extraArgs;
|
|
@@ -29179,16 +29185,17 @@ var require_dist2 = __commonJS({
|
|
|
29179
29185
|
async spawn() {
|
|
29180
29186
|
if (this.ptyProcess) return;
|
|
29181
29187
|
const { spawn: spawnConfig } = this.provider;
|
|
29182
|
-
const
|
|
29188
|
+
const configuredCommand = typeof this.runtimeSettings.executablePath === "string" && this.runtimeSettings.executablePath.trim() ? this.runtimeSettings.executablePath.trim() : spawnConfig.command;
|
|
29189
|
+
const binaryPath = findBinary(configuredCommand);
|
|
29183
29190
|
const isWin = os8.platform() === "win32";
|
|
29184
29191
|
const allArgs = [...spawnConfig.args, ...this.extraArgs];
|
|
29185
29192
|
LOG2.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
29186
29193
|
this.resetTraceSession();
|
|
29187
29194
|
let shellCmd;
|
|
29188
29195
|
let shellArgs;
|
|
29189
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
29196
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
29190
29197
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
29191
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !
|
|
29198
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
29192
29199
|
const useShell = isWin ? useShellWin : useShellUnix;
|
|
29193
29200
|
if (useShell) {
|
|
29194
29201
|
if (!spawnConfig.shell && !isWin) {
|
|
@@ -29562,7 +29569,7 @@ var require_dist2 = __commonJS({
|
|
|
29562
29569
|
`[${this.cliType}] Waiting for interactive prompt: hasPrompt=${hasPrompt} stableMs=${stableMs} recentOutputMs=${recentlyOutput} status=${status} startup=${startupLikelyActive} screen=${JSON.stringify(this.summarizeTraceText(screenText, 220)).slice(0, 260)}`
|
|
29563
29570
|
);
|
|
29564
29571
|
}
|
|
29565
|
-
await new Promise((
|
|
29572
|
+
await new Promise((resolve12) => setTimeout(resolve12, 50));
|
|
29566
29573
|
}
|
|
29567
29574
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
29568
29575
|
LOG2.warn(
|
|
@@ -30073,7 +30080,7 @@ ${data.message || ""}`.trim();
|
|
|
30073
30080
|
const deadline = Date.now() + 1e4;
|
|
30074
30081
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
30075
30082
|
this.resolveStartupState("send_wait");
|
|
30076
|
-
await new Promise((
|
|
30083
|
+
await new Promise((resolve12) => setTimeout(resolve12, 50));
|
|
30077
30084
|
}
|
|
30078
30085
|
}
|
|
30079
30086
|
await this.waitForInteractivePrompt();
|
|
@@ -30298,17 +30305,17 @@ ${data.message || ""}`.trim();
|
|
|
30298
30305
|
}
|
|
30299
30306
|
}
|
|
30300
30307
|
waitForStopped(timeoutMs) {
|
|
30301
|
-
return new Promise((
|
|
30308
|
+
return new Promise((resolve12) => {
|
|
30302
30309
|
const startedAt = Date.now();
|
|
30303
30310
|
const timer = setInterval(() => {
|
|
30304
30311
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
30305
30312
|
clearInterval(timer);
|
|
30306
|
-
|
|
30313
|
+
resolve12(true);
|
|
30307
30314
|
return;
|
|
30308
30315
|
}
|
|
30309
30316
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
30310
30317
|
clearInterval(timer);
|
|
30311
|
-
|
|
30318
|
+
resolve12(false);
|
|
30312
30319
|
}
|
|
30313
30320
|
}, 100);
|
|
30314
30321
|
});
|
|
@@ -30995,6 +31002,7 @@ ${data.message || ""}`.trim();
|
|
|
30995
31002
|
var import_child_process2 = require("child_process");
|
|
30996
31003
|
var import_fs3 = require("fs");
|
|
30997
31004
|
var import_os22 = require("os");
|
|
31005
|
+
var path42 = __toESM2(require("path"));
|
|
30998
31006
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
30999
31007
|
var registeredIDEs = /* @__PURE__ */ new Map();
|
|
31000
31008
|
function registerIDEDefinition(def) {
|
|
@@ -31011,9 +31019,16 @@ ${data.message || ""}`.trim();
|
|
|
31011
31019
|
return [...merged.values()];
|
|
31012
31020
|
}
|
|
31013
31021
|
function findCliCommand(command) {
|
|
31022
|
+
const trimmed = String(command || "").trim();
|
|
31023
|
+
if (!trimmed) return null;
|
|
31024
|
+
if (path42.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
31025
|
+
const candidate = trimmed.startsWith("~") ? path42.join((0, import_os22.homedir)(), trimmed.slice(1)) : trimmed;
|
|
31026
|
+
const resolved = path42.isAbsolute(candidate) ? candidate : path42.resolve(candidate);
|
|
31027
|
+
return (0, import_fs3.existsSync)(resolved) ? resolved : null;
|
|
31028
|
+
}
|
|
31014
31029
|
try {
|
|
31015
31030
|
const result = (0, import_child_process2.execSync)(
|
|
31016
|
-
(0, import_os22.platform)() === "win32" ? `where ${
|
|
31031
|
+
(0, import_os22.platform)() === "win32" ? `where ${trimmed}` : `which ${trimmed}`,
|
|
31017
31032
|
{ encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }
|
|
31018
31033
|
).trim();
|
|
31019
31034
|
return result.split("\n")[0] || null;
|
|
@@ -31036,23 +31051,23 @@ ${data.message || ""}`.trim();
|
|
|
31036
31051
|
function checkPathExists(paths) {
|
|
31037
31052
|
const home = (0, import_os22.homedir)();
|
|
31038
31053
|
for (const p of paths) {
|
|
31039
|
-
|
|
31054
|
+
const normalized = p.startsWith("~") ? path42.join(home, p.slice(1)) : p;
|
|
31055
|
+
if (normalized.includes("*")) {
|
|
31040
31056
|
const username = home.split(/[\\/]/).pop() || "";
|
|
31041
|
-
const resolved =
|
|
31057
|
+
const resolved = normalized.replace("*", username);
|
|
31042
31058
|
if ((0, import_fs3.existsSync)(resolved)) return resolved;
|
|
31043
31059
|
} else {
|
|
31044
|
-
if ((0, import_fs3.existsSync)(
|
|
31060
|
+
if ((0, import_fs3.existsSync)(normalized)) return normalized;
|
|
31045
31061
|
}
|
|
31046
31062
|
}
|
|
31047
31063
|
return null;
|
|
31048
31064
|
}
|
|
31049
|
-
async function detectIDEs() {
|
|
31065
|
+
async function detectIDEs(providerLoader) {
|
|
31050
31066
|
const os18 = (0, import_os22.platform)();
|
|
31051
31067
|
const results = [];
|
|
31052
31068
|
for (const def of getMergedDefinitions()) {
|
|
31053
|
-
const cliPath = findCliCommand(def.cli);
|
|
31054
|
-
const appPath = checkPathExists(def.paths[os18] || []);
|
|
31055
|
-
const installed = !!(cliPath || appPath);
|
|
31069
|
+
const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
|
|
31070
|
+
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os18] || []) || []);
|
|
31056
31071
|
let resolvedCli = cliPath;
|
|
31057
31072
|
if (!resolvedCli && appPath && os18 === "darwin") {
|
|
31058
31073
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
@@ -31075,6 +31090,7 @@ ${data.message || ""}`.trim();
|
|
|
31075
31090
|
}
|
|
31076
31091
|
}
|
|
31077
31092
|
}
|
|
31093
|
+
const installed = os18 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
31078
31094
|
const version2 = resolvedCli ? getIdeVersion(resolvedCli) : null;
|
|
31079
31095
|
results.push({
|
|
31080
31096
|
id: def.id,
|
|
@@ -31091,48 +31107,77 @@ ${data.message || ""}`.trim();
|
|
|
31091
31107
|
}
|
|
31092
31108
|
var import_child_process22 = require("child_process");
|
|
31093
31109
|
var os22 = __toESM2(require("os"));
|
|
31110
|
+
var path52 = __toESM2(require("path"));
|
|
31111
|
+
var import_fs4 = require("fs");
|
|
31094
31112
|
function parseVersion(raw) {
|
|
31095
31113
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
31096
31114
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
31097
31115
|
}
|
|
31116
|
+
function shellQuote(value) {
|
|
31117
|
+
if (/^[a-zA-Z0-9_./:@%+=,-]+$/.test(value)) return value;
|
|
31118
|
+
return `"${value.replace(/(["\\$`])/g, "\\$1")}"`;
|
|
31119
|
+
}
|
|
31120
|
+
function expandHome(value) {
|
|
31121
|
+
const trimmed = value.trim();
|
|
31122
|
+
if (!trimmed.startsWith("~")) return trimmed;
|
|
31123
|
+
return path52.join(os22.homedir(), trimmed.slice(1));
|
|
31124
|
+
}
|
|
31125
|
+
function isExplicitCommandPath(command) {
|
|
31126
|
+
const trimmed = command.trim();
|
|
31127
|
+
return path52.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
31128
|
+
}
|
|
31129
|
+
function resolveCommandPath(command) {
|
|
31130
|
+
const trimmed = command.trim();
|
|
31131
|
+
if (!trimmed) return null;
|
|
31132
|
+
if (isExplicitCommandPath(trimmed)) {
|
|
31133
|
+
const expanded = expandHome(trimmed);
|
|
31134
|
+
const candidate = path52.isAbsolute(expanded) ? expanded : path52.resolve(expanded);
|
|
31135
|
+
return (0, import_fs4.existsSync)(candidate) ? candidate : null;
|
|
31136
|
+
}
|
|
31137
|
+
return null;
|
|
31138
|
+
}
|
|
31098
31139
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
31099
|
-
return new Promise((
|
|
31140
|
+
return new Promise((resolve12) => {
|
|
31100
31141
|
const child = (0, import_child_process22.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
|
|
31101
31142
|
if (err || !stdout?.trim()) {
|
|
31102
|
-
|
|
31143
|
+
resolve12(null);
|
|
31103
31144
|
} else {
|
|
31104
|
-
|
|
31145
|
+
resolve12(stdout.trim());
|
|
31105
31146
|
}
|
|
31106
31147
|
});
|
|
31107
|
-
child.on("error", () =>
|
|
31148
|
+
child.on("error", () => resolve12(null));
|
|
31108
31149
|
});
|
|
31109
31150
|
}
|
|
31110
|
-
async function detectCLIs(providerLoader) {
|
|
31151
|
+
async function detectCLIs(providerLoader, options) {
|
|
31111
31152
|
const platform9 = os22.platform();
|
|
31112
31153
|
const whichCmd = platform9 === "win32" ? "where" : "which";
|
|
31154
|
+
const includeVersion = options?.includeVersion !== false;
|
|
31113
31155
|
const cliList = providerLoader ? providerLoader.getCliDetectionList() : [];
|
|
31114
31156
|
const results = await Promise.all(
|
|
31115
31157
|
cliList.map(async (cli) => {
|
|
31116
31158
|
try {
|
|
31117
|
-
const
|
|
31159
|
+
const explicitPath = resolveCommandPath(cli.command);
|
|
31160
|
+
const pathResult = explicitPath || await execAsync(`${whichCmd} ${shellQuote(cli.command)}`);
|
|
31118
31161
|
if (!pathResult) return { ...cli, installed: false };
|
|
31119
|
-
const firstPath = pathResult.split("\n")[0];
|
|
31162
|
+
const firstPath = explicitPath || pathResult.split("\n")[0];
|
|
31120
31163
|
let version2;
|
|
31121
|
-
|
|
31164
|
+
if (includeVersion) {
|
|
31122
31165
|
const versionCommands = [
|
|
31123
|
-
|
|
31124
|
-
|
|
31125
|
-
|
|
31126
|
-
|
|
31166
|
+
`"${firstPath}" --version`,
|
|
31167
|
+
`"${firstPath}" -V`,
|
|
31168
|
+
`"${firstPath}" -v`,
|
|
31169
|
+
cli.versionCommand
|
|
31127
31170
|
].filter((v2) => !!v2);
|
|
31128
|
-
|
|
31129
|
-
const
|
|
31130
|
-
|
|
31131
|
-
|
|
31132
|
-
|
|
31171
|
+
try {
|
|
31172
|
+
for (const versionCommand of versionCommands) {
|
|
31173
|
+
const versionResult = await execAsync(versionCommand, 3e3);
|
|
31174
|
+
if (versionResult) {
|
|
31175
|
+
version2 = parseVersion(versionResult);
|
|
31176
|
+
break;
|
|
31177
|
+
}
|
|
31133
31178
|
}
|
|
31179
|
+
} catch {
|
|
31134
31180
|
}
|
|
31135
|
-
} catch {
|
|
31136
31181
|
}
|
|
31137
31182
|
return { ...cli, installed: true, version: version2, path: firstPath };
|
|
31138
31183
|
} catch {
|
|
@@ -31142,7 +31187,7 @@ ${data.message || ""}`.trim();
|
|
|
31142
31187
|
);
|
|
31143
31188
|
return results;
|
|
31144
31189
|
}
|
|
31145
|
-
async function detectCLI(cliId, providerLoader) {
|
|
31190
|
+
async function detectCLI(cliId, providerLoader, options) {
|
|
31146
31191
|
const resolvedId = providerLoader ? providerLoader.resolveAlias(cliId) : cliId;
|
|
31147
31192
|
if (providerLoader) {
|
|
31148
31193
|
const cliList = providerLoader.getCliDetectionList();
|
|
@@ -31151,25 +31196,28 @@ ${data.message || ""}`.trim();
|
|
|
31151
31196
|
const platform9 = os22.platform();
|
|
31152
31197
|
const whichCmd = platform9 === "win32" ? "where" : "which";
|
|
31153
31198
|
try {
|
|
31154
|
-
const
|
|
31199
|
+
const explicitPath = resolveCommandPath(target.command);
|
|
31200
|
+
const pathResult = explicitPath || await execAsync(`${whichCmd} ${shellQuote(target.command)}`);
|
|
31155
31201
|
if (!pathResult) return null;
|
|
31156
|
-
const firstPath = pathResult.split("\n")[0];
|
|
31202
|
+
const firstPath = explicitPath || pathResult.split("\n")[0];
|
|
31157
31203
|
let version2;
|
|
31158
|
-
|
|
31204
|
+
if (options?.includeVersion !== false) {
|
|
31159
31205
|
const versionCommands = [
|
|
31160
|
-
|
|
31161
|
-
|
|
31162
|
-
|
|
31163
|
-
|
|
31206
|
+
`"${firstPath}" --version`,
|
|
31207
|
+
`"${firstPath}" -V`,
|
|
31208
|
+
`"${firstPath}" -v`,
|
|
31209
|
+
target.versionCommand
|
|
31164
31210
|
].filter((v2) => !!v2);
|
|
31165
|
-
|
|
31166
|
-
const
|
|
31167
|
-
|
|
31168
|
-
|
|
31169
|
-
|
|
31211
|
+
try {
|
|
31212
|
+
for (const versionCommand of versionCommands) {
|
|
31213
|
+
const versionResult = await execAsync(versionCommand, 3e3);
|
|
31214
|
+
if (versionResult) {
|
|
31215
|
+
version2 = parseVersion(versionResult);
|
|
31216
|
+
break;
|
|
31217
|
+
}
|
|
31170
31218
|
}
|
|
31219
|
+
} catch {
|
|
31171
31220
|
}
|
|
31172
|
-
} catch {
|
|
31173
31221
|
}
|
|
31174
31222
|
return { ...target, installed: true, version: version2, path: firstPath };
|
|
31175
31223
|
} catch {
|
|
@@ -31177,7 +31225,7 @@ ${data.message || ""}`.trim();
|
|
|
31177
31225
|
}
|
|
31178
31226
|
}
|
|
31179
31227
|
}
|
|
31180
|
-
const all = await detectCLIs(providerLoader);
|
|
31228
|
+
const all = await detectCLIs(providerLoader, options);
|
|
31181
31229
|
return all.find((c) => c.id === resolvedId && c.installed) || null;
|
|
31182
31230
|
}
|
|
31183
31231
|
var os32 = __toESM2(require("os"));
|
|
@@ -31300,7 +31348,7 @@ ${data.message || ""}`.trim();
|
|
|
31300
31348
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
31301
31349
|
*/
|
|
31302
31350
|
static listAllTargets(port) {
|
|
31303
|
-
return new Promise((
|
|
31351
|
+
return new Promise((resolve12) => {
|
|
31304
31352
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
31305
31353
|
let data = "";
|
|
31306
31354
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -31316,16 +31364,16 @@ ${data.message || ""}`.trim();
|
|
|
31316
31364
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
31317
31365
|
);
|
|
31318
31366
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
31319
|
-
|
|
31367
|
+
resolve12(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
31320
31368
|
} catch {
|
|
31321
|
-
|
|
31369
|
+
resolve12([]);
|
|
31322
31370
|
}
|
|
31323
31371
|
});
|
|
31324
31372
|
});
|
|
31325
|
-
req.on("error", () =>
|
|
31373
|
+
req.on("error", () => resolve12([]));
|
|
31326
31374
|
req.setTimeout(2e3, () => {
|
|
31327
31375
|
req.destroy();
|
|
31328
|
-
|
|
31376
|
+
resolve12([]);
|
|
31329
31377
|
});
|
|
31330
31378
|
});
|
|
31331
31379
|
}
|
|
@@ -31365,7 +31413,7 @@ ${data.message || ""}`.trim();
|
|
|
31365
31413
|
}
|
|
31366
31414
|
}
|
|
31367
31415
|
findTargetOnPort(port) {
|
|
31368
|
-
return new Promise((
|
|
31416
|
+
return new Promise((resolve12) => {
|
|
31369
31417
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
31370
31418
|
let data = "";
|
|
31371
31419
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -31376,7 +31424,7 @@ ${data.message || ""}`.trim();
|
|
|
31376
31424
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
31377
31425
|
);
|
|
31378
31426
|
if (pages.length === 0) {
|
|
31379
|
-
|
|
31427
|
+
resolve12(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
31380
31428
|
return;
|
|
31381
31429
|
}
|
|
31382
31430
|
const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -31386,24 +31434,24 @@ ${data.message || ""}`.trim();
|
|
|
31386
31434
|
const specific = list.find((t) => t.id === this._targetId);
|
|
31387
31435
|
if (specific) {
|
|
31388
31436
|
this._pageTitle = specific.title || "";
|
|
31389
|
-
|
|
31437
|
+
resolve12(specific);
|
|
31390
31438
|
} else {
|
|
31391
31439
|
this.log(`[CDP] Target ${this._targetId} not found in page list`);
|
|
31392
|
-
|
|
31440
|
+
resolve12(null);
|
|
31393
31441
|
}
|
|
31394
31442
|
return;
|
|
31395
31443
|
}
|
|
31396
31444
|
this._pageTitle = list[0]?.title || "";
|
|
31397
|
-
|
|
31445
|
+
resolve12(list[0]);
|
|
31398
31446
|
} catch {
|
|
31399
|
-
|
|
31447
|
+
resolve12(null);
|
|
31400
31448
|
}
|
|
31401
31449
|
});
|
|
31402
31450
|
});
|
|
31403
|
-
req.on("error", () =>
|
|
31451
|
+
req.on("error", () => resolve12(null));
|
|
31404
31452
|
req.setTimeout(2e3, () => {
|
|
31405
31453
|
req.destroy();
|
|
31406
|
-
|
|
31454
|
+
resolve12(null);
|
|
31407
31455
|
});
|
|
31408
31456
|
});
|
|
31409
31457
|
}
|
|
@@ -31414,7 +31462,7 @@ ${data.message || ""}`.trim();
|
|
|
31414
31462
|
this.extensionProviders = providers;
|
|
31415
31463
|
}
|
|
31416
31464
|
connectToTarget(wsUrl) {
|
|
31417
|
-
return new Promise((
|
|
31465
|
+
return new Promise((resolve12) => {
|
|
31418
31466
|
this.ws = new import_ws2.default(wsUrl);
|
|
31419
31467
|
this.ws.on("open", async () => {
|
|
31420
31468
|
this._connected = true;
|
|
@@ -31424,17 +31472,17 @@ ${data.message || ""}`.trim();
|
|
|
31424
31472
|
}
|
|
31425
31473
|
this.connectBrowserWs().catch(() => {
|
|
31426
31474
|
});
|
|
31427
|
-
|
|
31475
|
+
resolve12(true);
|
|
31428
31476
|
});
|
|
31429
31477
|
this.ws.on("message", (data) => {
|
|
31430
31478
|
try {
|
|
31431
31479
|
const msg = JSON.parse(data.toString());
|
|
31432
31480
|
if (msg.id && this.pending.has(msg.id)) {
|
|
31433
|
-
const { resolve:
|
|
31481
|
+
const { resolve: resolve13, reject } = this.pending.get(msg.id);
|
|
31434
31482
|
this.pending.delete(msg.id);
|
|
31435
31483
|
this.failureCount = 0;
|
|
31436
31484
|
if (msg.error) reject(new Error(msg.error.message));
|
|
31437
|
-
else
|
|
31485
|
+
else resolve13(msg.result);
|
|
31438
31486
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
31439
31487
|
this.contexts.add(msg.params.context.id);
|
|
31440
31488
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -31457,7 +31505,7 @@ ${data.message || ""}`.trim();
|
|
|
31457
31505
|
this.ws.on("error", (err) => {
|
|
31458
31506
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
31459
31507
|
this._connected = false;
|
|
31460
|
-
|
|
31508
|
+
resolve12(false);
|
|
31461
31509
|
});
|
|
31462
31510
|
});
|
|
31463
31511
|
}
|
|
@@ -31471,7 +31519,7 @@ ${data.message || ""}`.trim();
|
|
|
31471
31519
|
return;
|
|
31472
31520
|
}
|
|
31473
31521
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
31474
|
-
await new Promise((
|
|
31522
|
+
await new Promise((resolve12, reject) => {
|
|
31475
31523
|
this.browserWs = new import_ws2.default(browserWsUrl);
|
|
31476
31524
|
this.browserWs.on("open", async () => {
|
|
31477
31525
|
this._browserConnected = true;
|
|
@@ -31481,16 +31529,16 @@ ${data.message || ""}`.trim();
|
|
|
31481
31529
|
} catch (e) {
|
|
31482
31530
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
31483
31531
|
}
|
|
31484
|
-
|
|
31532
|
+
resolve12();
|
|
31485
31533
|
});
|
|
31486
31534
|
this.browserWs.on("message", (data) => {
|
|
31487
31535
|
try {
|
|
31488
31536
|
const msg = JSON.parse(data.toString());
|
|
31489
31537
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
31490
|
-
const { resolve:
|
|
31538
|
+
const { resolve: resolve13, reject: reject2 } = this.browserPending.get(msg.id);
|
|
31491
31539
|
this.browserPending.delete(msg.id);
|
|
31492
31540
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
31493
|
-
else
|
|
31541
|
+
else resolve13(msg.result);
|
|
31494
31542
|
}
|
|
31495
31543
|
} catch {
|
|
31496
31544
|
}
|
|
@@ -31510,31 +31558,31 @@ ${data.message || ""}`.trim();
|
|
|
31510
31558
|
}
|
|
31511
31559
|
}
|
|
31512
31560
|
getBrowserWsUrl() {
|
|
31513
|
-
return new Promise((
|
|
31561
|
+
return new Promise((resolve12) => {
|
|
31514
31562
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
31515
31563
|
let data = "";
|
|
31516
31564
|
res.on("data", (chunk) => data += chunk.toString());
|
|
31517
31565
|
res.on("end", () => {
|
|
31518
31566
|
try {
|
|
31519
31567
|
const info = JSON.parse(data);
|
|
31520
|
-
|
|
31568
|
+
resolve12(info.webSocketDebuggerUrl || null);
|
|
31521
31569
|
} catch {
|
|
31522
|
-
|
|
31570
|
+
resolve12(null);
|
|
31523
31571
|
}
|
|
31524
31572
|
});
|
|
31525
31573
|
});
|
|
31526
|
-
req.on("error", () =>
|
|
31574
|
+
req.on("error", () => resolve12(null));
|
|
31527
31575
|
req.setTimeout(3e3, () => {
|
|
31528
31576
|
req.destroy();
|
|
31529
|
-
|
|
31577
|
+
resolve12(null);
|
|
31530
31578
|
});
|
|
31531
31579
|
});
|
|
31532
31580
|
}
|
|
31533
31581
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
31534
|
-
return new Promise((
|
|
31582
|
+
return new Promise((resolve12, reject) => {
|
|
31535
31583
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
31536
31584
|
const id = this.browserMsgId++;
|
|
31537
|
-
this.browserPending.set(id, { resolve:
|
|
31585
|
+
this.browserPending.set(id, { resolve: resolve12, reject });
|
|
31538
31586
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
31539
31587
|
setTimeout(() => {
|
|
31540
31588
|
if (this.browserPending.has(id)) {
|
|
@@ -31574,11 +31622,11 @@ ${data.message || ""}`.trim();
|
|
|
31574
31622
|
}
|
|
31575
31623
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
31576
31624
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
31577
|
-
return new Promise((
|
|
31625
|
+
return new Promise((resolve12, reject) => {
|
|
31578
31626
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
31579
31627
|
if (this.ws.readyState !== import_ws2.default.OPEN) return reject(new Error("WebSocket not open"));
|
|
31580
31628
|
const id = this.msgId++;
|
|
31581
|
-
this.pending.set(id, { resolve:
|
|
31629
|
+
this.pending.set(id, { resolve: resolve12, reject });
|
|
31582
31630
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
31583
31631
|
setTimeout(() => {
|
|
31584
31632
|
if (this.pending.has(id)) {
|
|
@@ -31827,7 +31875,7 @@ ${data.message || ""}`.trim();
|
|
|
31827
31875
|
const browserWs = this.browserWs;
|
|
31828
31876
|
let msgId = this.browserMsgId;
|
|
31829
31877
|
const sendWs = (method, params = {}, sessionId) => {
|
|
31830
|
-
return new Promise((
|
|
31878
|
+
return new Promise((resolve12, reject) => {
|
|
31831
31879
|
const mid = msgId++;
|
|
31832
31880
|
this.browserMsgId = msgId;
|
|
31833
31881
|
const handler = (raw) => {
|
|
@@ -31836,7 +31884,7 @@ ${data.message || ""}`.trim();
|
|
|
31836
31884
|
if (msg.id === mid) {
|
|
31837
31885
|
browserWs.removeListener("message", handler);
|
|
31838
31886
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
31839
|
-
else
|
|
31887
|
+
else resolve12(msg.result);
|
|
31840
31888
|
}
|
|
31841
31889
|
} catch {
|
|
31842
31890
|
}
|
|
@@ -32027,14 +32075,14 @@ ${data.message || ""}`.trim();
|
|
|
32027
32075
|
if (!ws2 || ws2.readyState !== import_ws2.default.OPEN) {
|
|
32028
32076
|
throw new Error("CDP not connected");
|
|
32029
32077
|
}
|
|
32030
|
-
return new Promise((
|
|
32078
|
+
return new Promise((resolve12, reject) => {
|
|
32031
32079
|
const id = getNextId();
|
|
32032
32080
|
pendingMap.set(id, {
|
|
32033
32081
|
resolve: (result) => {
|
|
32034
32082
|
if (result?.result?.subtype === "error") {
|
|
32035
32083
|
reject(new Error(result.result.description));
|
|
32036
32084
|
} else {
|
|
32037
|
-
|
|
32085
|
+
resolve12(result?.result?.value);
|
|
32038
32086
|
}
|
|
32039
32087
|
},
|
|
32040
32088
|
reject
|
|
@@ -32066,10 +32114,10 @@ ${data.message || ""}`.trim();
|
|
|
32066
32114
|
throw new Error("CDP not connected");
|
|
32067
32115
|
}
|
|
32068
32116
|
const sendViaSession = (method, params = {}) => {
|
|
32069
|
-
return new Promise((
|
|
32117
|
+
return new Promise((resolve12, reject) => {
|
|
32070
32118
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
32071
32119
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
32072
|
-
pendingMap.set(id, { resolve:
|
|
32120
|
+
pendingMap.set(id, { resolve: resolve12, reject });
|
|
32073
32121
|
ws2.send(JSON.stringify({ id, sessionId, method, params }));
|
|
32074
32122
|
setTimeout(() => {
|
|
32075
32123
|
if (pendingMap.has(id)) {
|
|
@@ -32687,9 +32735,9 @@ ${data.message || ""}`.trim();
|
|
|
32687
32735
|
return String(value);
|
|
32688
32736
|
}
|
|
32689
32737
|
var fs32 = __toESM2(require("fs"));
|
|
32690
|
-
var
|
|
32738
|
+
var path7 = __toESM2(require("path"));
|
|
32691
32739
|
var os52 = __toESM2(require("os"));
|
|
32692
|
-
var HISTORY_DIR =
|
|
32740
|
+
var HISTORY_DIR = path7.join(os52.homedir(), ".adhdev", "history");
|
|
32693
32741
|
var RETAIN_DAYS = 30;
|
|
32694
32742
|
var ChatHistoryWriter = class {
|
|
32695
32743
|
/** Last seen message count per agent (deduplication) */
|
|
@@ -32734,11 +32782,11 @@ ${data.message || ""}`.trim();
|
|
|
32734
32782
|
});
|
|
32735
32783
|
}
|
|
32736
32784
|
if (newMessages.length === 0) return;
|
|
32737
|
-
const dir =
|
|
32785
|
+
const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
|
|
32738
32786
|
fs32.mkdirSync(dir, { recursive: true });
|
|
32739
32787
|
const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
32740
32788
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
32741
|
-
const filePath =
|
|
32789
|
+
const filePath = path7.join(dir, `${filePrefix}${date5}.jsonl`);
|
|
32742
32790
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
32743
32791
|
fs32.appendFileSync(filePath, lines, "utf-8");
|
|
32744
32792
|
const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
|
|
@@ -32792,14 +32840,14 @@ ${data.message || ""}`.trim();
|
|
|
32792
32840
|
this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
|
|
32793
32841
|
this.lastSeenCounts.delete(fromDedupKey);
|
|
32794
32842
|
}
|
|
32795
|
-
const dir =
|
|
32843
|
+
const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
|
|
32796
32844
|
if (!fs32.existsSync(dir)) return;
|
|
32797
32845
|
const fromPrefix = `${this.sanitize(fromId)}_`;
|
|
32798
32846
|
const toPrefix = `${this.sanitize(toId)}_`;
|
|
32799
32847
|
const files = fs32.readdirSync(dir).filter((file2) => file2.startsWith(fromPrefix) && file2.endsWith(".jsonl"));
|
|
32800
32848
|
for (const file2 of files) {
|
|
32801
|
-
const sourcePath =
|
|
32802
|
-
const targetPath =
|
|
32849
|
+
const sourcePath = path7.join(dir, file2);
|
|
32850
|
+
const targetPath = path7.join(dir, `${toPrefix}${file2.slice(fromPrefix.length)}`);
|
|
32803
32851
|
const sourceLines = fs32.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
32804
32852
|
const rewritten = sourceLines.map((line) => {
|
|
32805
32853
|
try {
|
|
@@ -32840,10 +32888,10 @@ ${data.message || ""}`.trim();
|
|
|
32840
32888
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
32841
32889
|
const agentDirs = fs32.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
32842
32890
|
for (const dir of agentDirs) {
|
|
32843
|
-
const dirPath =
|
|
32891
|
+
const dirPath = path7.join(HISTORY_DIR, dir.name);
|
|
32844
32892
|
const files = fs32.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
32845
32893
|
for (const file2 of files) {
|
|
32846
|
-
const filePath =
|
|
32894
|
+
const filePath = path7.join(dirPath, file2);
|
|
32847
32895
|
const stat4 = fs32.statSync(filePath);
|
|
32848
32896
|
if (stat4.mtimeMs < cutoff) {
|
|
32849
32897
|
fs32.unlinkSync(filePath);
|
|
@@ -32861,7 +32909,7 @@ ${data.message || ""}`.trim();
|
|
|
32861
32909
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
|
|
32862
32910
|
try {
|
|
32863
32911
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
32864
|
-
const dir =
|
|
32912
|
+
const dir = path7.join(HISTORY_DIR, sanitized);
|
|
32865
32913
|
if (!fs32.existsSync(dir)) return { messages: [], hasMore: false };
|
|
32866
32914
|
const sanitizedInstance = historySessionId?.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
32867
32915
|
const files = fs32.readdirSync(dir).filter((f) => {
|
|
@@ -32875,7 +32923,7 @@ ${data.message || ""}`.trim();
|
|
|
32875
32923
|
const needed = offset + limit + 1;
|
|
32876
32924
|
for (const file2 of files) {
|
|
32877
32925
|
if (allMessages.length >= needed) break;
|
|
32878
|
-
const filePath =
|
|
32926
|
+
const filePath = path7.join(dir, file2);
|
|
32879
32927
|
const content = fs32.readFileSync(filePath, "utf-8");
|
|
32880
32928
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
32881
32929
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
@@ -32897,7 +32945,7 @@ ${data.message || ""}`.trim();
|
|
|
32897
32945
|
function listSavedHistorySessions(agentType, options = {}) {
|
|
32898
32946
|
try {
|
|
32899
32947
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
32900
|
-
const dir =
|
|
32948
|
+
const dir = path7.join(HISTORY_DIR, sanitized);
|
|
32901
32949
|
if (!fs32.existsSync(dir)) return { sessions: [], hasMore: false };
|
|
32902
32950
|
const groupedFiles = /* @__PURE__ */ new Map();
|
|
32903
32951
|
const filePattern = /^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/;
|
|
@@ -32918,7 +32966,7 @@ ${data.message || ""}`.trim();
|
|
|
32918
32966
|
let sessionTitle = "";
|
|
32919
32967
|
let preview = "";
|
|
32920
32968
|
for (const file2 of files.sort()) {
|
|
32921
|
-
const filePath =
|
|
32969
|
+
const filePath = path7.join(dir, file2);
|
|
32922
32970
|
const content = fs32.readFileSync(filePath, "utf-8");
|
|
32923
32971
|
const lines = content.split("\n").filter(Boolean);
|
|
32924
32972
|
for (const line of lines) {
|
|
@@ -32969,6 +33017,7 @@ ${data.message || ""}`.trim();
|
|
|
32969
33017
|
currentStatus = "idle";
|
|
32970
33018
|
agentStreams = [];
|
|
32971
33019
|
messages = [];
|
|
33020
|
+
prevMessageHashes = /* @__PURE__ */ new Map();
|
|
32972
33021
|
activeModal = null;
|
|
32973
33022
|
currentModel = "";
|
|
32974
33023
|
currentMode = "";
|
|
@@ -33034,7 +33083,7 @@ ${data.message || ""}`.trim();
|
|
|
33034
33083
|
onEvent(event, data) {
|
|
33035
33084
|
if (event === "stream_update") {
|
|
33036
33085
|
if (data?.streams) this.agentStreams = data.streams;
|
|
33037
|
-
if (data?.messages) this.messages = data.messages;
|
|
33086
|
+
if (data?.messages) this.messages = this.assignReceivedAt(data.messages);
|
|
33038
33087
|
if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
|
|
33039
33088
|
if (data?.model) this.currentModel = data.model;
|
|
33040
33089
|
if (data?.mode) this.currentMode = data.mode;
|
|
@@ -33060,6 +33109,7 @@ ${data.message || ""}`.trim();
|
|
|
33060
33109
|
dispose() {
|
|
33061
33110
|
this.agentStreams = [];
|
|
33062
33111
|
this.messages = [];
|
|
33112
|
+
this.prevMessageHashes.clear();
|
|
33063
33113
|
this.monitor.reset();
|
|
33064
33114
|
this.appliedEffectKeys.clear();
|
|
33065
33115
|
this.runtimeMessages = [];
|
|
@@ -33215,6 +33265,23 @@ ${data.message || ""}`.trim();
|
|
|
33215
33265
|
this.chatId || this.instanceId
|
|
33216
33266
|
);
|
|
33217
33267
|
}
|
|
33268
|
+
/**
|
|
33269
|
+
* Assign stable receivedAt to extension messages.
|
|
33270
|
+
* Same pattern as IdeProviderInstance.readChat() prevByHash —
|
|
33271
|
+
* preserves first-seen timestamp across polling cycles.
|
|
33272
|
+
*/
|
|
33273
|
+
assignReceivedAt(messages) {
|
|
33274
|
+
const now = Date.now();
|
|
33275
|
+
const nextHashes = /* @__PURE__ */ new Map();
|
|
33276
|
+
for (const msg of messages) {
|
|
33277
|
+
const hash2 = `${msg.role}:${(msg.content || "").slice(0, 100)}`;
|
|
33278
|
+
const prevTime = this.prevMessageHashes.get(hash2);
|
|
33279
|
+
msg.receivedAt = prevTime || now;
|
|
33280
|
+
nextHashes.set(hash2, msg.receivedAt);
|
|
33281
|
+
}
|
|
33282
|
+
this.prevMessageHashes = nextHashes;
|
|
33283
|
+
return messages;
|
|
33284
|
+
}
|
|
33218
33285
|
mergeConversationMessages(messages) {
|
|
33219
33286
|
if (this.runtimeMessages.length === 0) return messages;
|
|
33220
33287
|
return [...messages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b2) => {
|
|
@@ -33271,6 +33338,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
33271
33338
|
}
|
|
33272
33339
|
this.agentStreams = [];
|
|
33273
33340
|
this.messages = [];
|
|
33341
|
+
this.prevMessageHashes.clear();
|
|
33274
33342
|
this.activeModal = null;
|
|
33275
33343
|
this.currentModel = "";
|
|
33276
33344
|
this.currentMode = "";
|
|
@@ -34246,16 +34314,28 @@ ${effect.notification.body || ""}`.trim();
|
|
|
34246
34314
|
if (!message || typeof message !== "object") return message;
|
|
34247
34315
|
return trimStructuredStrings(message, stringLimit);
|
|
34248
34316
|
}
|
|
34317
|
+
function normalizeMessageTime(message) {
|
|
34318
|
+
if (!message || typeof message !== "object") return message;
|
|
34319
|
+
const msg = message;
|
|
34320
|
+
if (msg.receivedAt == null) {
|
|
34321
|
+
const fallback = msg.timestamp ?? msg.createdAt;
|
|
34322
|
+
if (fallback != null) {
|
|
34323
|
+
const ts22 = typeof fallback === "string" ? Date.parse(fallback) : Number(fallback);
|
|
34324
|
+
if (Number.isFinite(ts22) && ts22 > 0) msg.receivedAt = ts22;
|
|
34325
|
+
}
|
|
34326
|
+
}
|
|
34327
|
+
return msg;
|
|
34328
|
+
}
|
|
34249
34329
|
function trimMessagesForStatus(messages) {
|
|
34250
34330
|
if (!Array.isArray(messages) || messages.length === 0) return [];
|
|
34251
34331
|
const recent = messages.slice(-STATUS_ACTIVE_CHAT_MESSAGE_LIMIT);
|
|
34252
34332
|
const kept = [];
|
|
34253
34333
|
let totalBytes = 0;
|
|
34254
34334
|
for (let i = recent.length - 1; i >= 0; i -= 1) {
|
|
34255
|
-
let normalized = trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_STRING_LIMIT);
|
|
34335
|
+
let normalized = normalizeMessageTime(trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_STRING_LIMIT));
|
|
34256
34336
|
let size = estimateBytes(normalized);
|
|
34257
34337
|
if (size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
|
|
34258
|
-
normalized = trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT);
|
|
34338
|
+
normalized = normalizeMessageTime(trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT));
|
|
34259
34339
|
size = estimateBytes(normalized);
|
|
34260
34340
|
}
|
|
34261
34341
|
if (kept.length > 0 && totalBytes + size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
|
|
@@ -34870,7 +34950,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
34870
34950
|
if (isExtensionTransport(transport)) {
|
|
34871
34951
|
_log(`Extension: ${provider?.type || "unknown_extension"}`);
|
|
34872
34952
|
try {
|
|
34873
|
-
const evalResult = await h.evaluateProviderScript("sendMessage", {
|
|
34953
|
+
const evalResult = await h.evaluateProviderScript("sendMessage", { message: text }, 3e4);
|
|
34874
34954
|
if (evalResult?.result) {
|
|
34875
34955
|
const parsed = parseMaybeJson(evalResult.result);
|
|
34876
34956
|
if (didProviderConfirmSend(parsed)) {
|
|
@@ -34901,7 +34981,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
34901
34981
|
return { success: false, error: `CDP for ${managerKey || "unknown"} not connected` };
|
|
34902
34982
|
}
|
|
34903
34983
|
_log(`Targeting IDE: ${getCurrentManagerKey(h)}`);
|
|
34904
|
-
const sendScript = h.getProviderScript("sendMessage", {
|
|
34984
|
+
const sendScript = h.getProviderScript("sendMessage", { message: text });
|
|
34905
34985
|
if (sendScript) {
|
|
34906
34986
|
try {
|
|
34907
34987
|
const result = await targetCdp.evaluate(sendScript, 3e4);
|
|
@@ -35041,6 +35121,14 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35041
35121
|
} catch {
|
|
35042
35122
|
}
|
|
35043
35123
|
}
|
|
35124
|
+
if (parsed?.sessions && Array.isArray(parsed.sessions)) {
|
|
35125
|
+
LOG2.info("Command", `[list_chats] OK: ${parsed.sessions.length} chats`);
|
|
35126
|
+
return { success: true, chats: parsed.sessions };
|
|
35127
|
+
}
|
|
35128
|
+
if (parsed?.chats && Array.isArray(parsed.chats)) {
|
|
35129
|
+
LOG2.info("Command", `[list_chats] OK: ${parsed.chats.length} chats`);
|
|
35130
|
+
return { success: true, chats: parsed.chats };
|
|
35131
|
+
}
|
|
35044
35132
|
if (Array.isArray(parsed)) {
|
|
35045
35133
|
LOG2.info("Command", `[list_chats] OK: ${parsed.length} chats`);
|
|
35046
35134
|
return { success: true, chats: parsed };
|
|
@@ -35110,7 +35198,13 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35110
35198
|
} catch (e) {
|
|
35111
35199
|
return { success: false, error: `webviewSwitchSession failed: ${e.message}` };
|
|
35112
35200
|
}
|
|
35113
|
-
const
|
|
35201
|
+
const switchParams = {
|
|
35202
|
+
sessionId,
|
|
35203
|
+
title: sessionId,
|
|
35204
|
+
id: sessionId,
|
|
35205
|
+
SESSION_ID: JSON.stringify(sessionId)
|
|
35206
|
+
};
|
|
35207
|
+
const script = h.getProviderScript("switchSession", switchParams) || h.getProviderScript("switch_session", switchParams);
|
|
35114
35208
|
if (!script) return { success: false, error: "switch_session script not available" };
|
|
35115
35209
|
try {
|
|
35116
35210
|
const raw = await cdp.evaluate(script, 15e3);
|
|
@@ -35189,8 +35283,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35189
35283
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
35190
35284
|
if (adapter) {
|
|
35191
35285
|
const acpInstance = adapter._acpInstance;
|
|
35192
|
-
if (acpInstance && typeof acpInstance.
|
|
35193
|
-
acpInstance.
|
|
35286
|
+
if (acpInstance && typeof acpInstance.setMode === "function") {
|
|
35287
|
+
await acpInstance.setMode(mode);
|
|
35194
35288
|
return { success: true, mode };
|
|
35195
35289
|
}
|
|
35196
35290
|
}
|
|
@@ -35247,9 +35341,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35247
35341
|
LOG2.info("Command", `[change_model] ACP adapter found: ${!!adapter}, type=${adapter?.cliType}, hasAcpInstance=${!!adapter?._acpInstance}`);
|
|
35248
35342
|
if (adapter) {
|
|
35249
35343
|
const acpInstance = adapter._acpInstance;
|
|
35250
|
-
if (acpInstance && typeof acpInstance.
|
|
35251
|
-
acpInstance.
|
|
35252
|
-
LOG2.info("Command", `[change_model]
|
|
35344
|
+
if (acpInstance && typeof acpInstance.setConfigOption === "function") {
|
|
35345
|
+
await acpInstance.setConfigOption("model", model);
|
|
35346
|
+
LOG2.info("Command", `[change_model] Updated ACP model to ${model}`);
|
|
35253
35347
|
return { success: true, model };
|
|
35254
35348
|
}
|
|
35255
35349
|
}
|
|
@@ -35369,6 +35463,18 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35369
35463
|
const ok = await h.agentStream.resolveSessionAction(h.getCdp(), h.currentSession.sessionId, action);
|
|
35370
35464
|
return { success: ok };
|
|
35371
35465
|
}
|
|
35466
|
+
if (transport === "acp") {
|
|
35467
|
+
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
35468
|
+
const acpInstance = adapter?._acpInstance;
|
|
35469
|
+
if (!acpInstance) return { success: false, error: "ACP instance not found" };
|
|
35470
|
+
try {
|
|
35471
|
+
await acpInstance.resolvePermission(action === "approve" || action === "accept" || action === "always");
|
|
35472
|
+
LOG2.info("Command", `[resolveAction] ACP \u2192 ${action}`);
|
|
35473
|
+
return { success: true, action };
|
|
35474
|
+
} catch (e) {
|
|
35475
|
+
return { success: false, error: e?.message || "ACP resolve action failed" };
|
|
35476
|
+
}
|
|
35477
|
+
}
|
|
35372
35478
|
if (provider?.scripts?.webviewResolveAction || provider?.scripts?.webview_resolve_action) {
|
|
35373
35479
|
const script = h.getProviderScript("webviewResolveAction", { action, button, buttonText: button }) || h.getProviderScript("webview_resolve_action", { action, button, buttonText: button });
|
|
35374
35480
|
if (script) {
|
|
@@ -35445,7 +35551,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35445
35551
|
return { success: false, error: "resolveAction script not available for this provider" };
|
|
35446
35552
|
}
|
|
35447
35553
|
var fs42 = __toESM2(require("fs"));
|
|
35448
|
-
var
|
|
35554
|
+
var path8 = __toESM2(require("path"));
|
|
35449
35555
|
var os62 = __toESM2(require("os"));
|
|
35450
35556
|
var KEY_TO_VK = {
|
|
35451
35557
|
Backspace: 8,
|
|
@@ -35697,25 +35803,25 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35697
35803
|
const inputPath = rawPath || ".";
|
|
35698
35804
|
const home = os62.homedir();
|
|
35699
35805
|
if (inputPath.startsWith("~")) {
|
|
35700
|
-
return
|
|
35806
|
+
return path8.resolve(path8.join(home, inputPath.slice(1)));
|
|
35701
35807
|
}
|
|
35702
35808
|
if (process.platform === "win32") {
|
|
35703
35809
|
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
35704
|
-
if (
|
|
35705
|
-
return
|
|
35810
|
+
if (path8.win32.isAbsolute(normalized)) {
|
|
35811
|
+
return path8.win32.normalize(normalized);
|
|
35706
35812
|
}
|
|
35707
|
-
return
|
|
35813
|
+
return path8.win32.resolve(normalized);
|
|
35708
35814
|
}
|
|
35709
|
-
if (
|
|
35710
|
-
return
|
|
35815
|
+
if (path8.isAbsolute(inputPath)) {
|
|
35816
|
+
return path8.normalize(inputPath);
|
|
35711
35817
|
}
|
|
35712
|
-
return
|
|
35818
|
+
return path8.resolve(inputPath);
|
|
35713
35819
|
}
|
|
35714
35820
|
function listDirectoryEntriesSafe(dirPath) {
|
|
35715
35821
|
const entries = fs42.readdirSync(dirPath, { withFileTypes: true });
|
|
35716
35822
|
const files = [];
|
|
35717
35823
|
for (const entry of entries) {
|
|
35718
|
-
const entryPath =
|
|
35824
|
+
const entryPath = path8.join(dirPath, entry.name);
|
|
35719
35825
|
try {
|
|
35720
35826
|
if (entry.isDirectory()) {
|
|
35721
35827
|
files.push({ name: entry.name, type: "directory" });
|
|
@@ -35754,7 +35860,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35754
35860
|
async function handleFileWrite(h, args) {
|
|
35755
35861
|
try {
|
|
35756
35862
|
const filePath = resolveSafePath(args?.path);
|
|
35757
|
-
fs42.mkdirSync(
|
|
35863
|
+
fs42.mkdirSync(path8.dirname(filePath), { recursive: true });
|
|
35758
35864
|
fs42.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
35759
35865
|
return { success: true, path: filePath };
|
|
35760
35866
|
} catch (e) {
|
|
@@ -35840,7 +35946,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35840
35946
|
}
|
|
35841
35947
|
return { success: true, settings: allSettings, values: allValues };
|
|
35842
35948
|
}
|
|
35843
|
-
function handleSetProviderSetting(h, args) {
|
|
35949
|
+
async function handleSetProviderSetting(h, args) {
|
|
35844
35950
|
const loader = h.ctx.providerLoader;
|
|
35845
35951
|
const { providerType, key, value } = args || {};
|
|
35846
35952
|
if (!providerType || !key || value === void 0) {
|
|
@@ -35853,6 +35959,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35853
35959
|
const updated = h.ctx.instanceManager.updateInstanceSettings(providerType, allSettings);
|
|
35854
35960
|
LOG2.info("Command", `[set_provider_setting] ${providerType}.${key}=${JSON.stringify(value)} \u2192 ${updated} instance(s) updated`);
|
|
35855
35961
|
}
|
|
35962
|
+
await h.ctx.onProviderSettingChanged?.(providerType, key, value);
|
|
35856
35963
|
return { success: true, providerType, key, value };
|
|
35857
35964
|
}
|
|
35858
35965
|
return { success: false, error: `Failed to set ${providerType}.${key} \u2014 invalid key, value, or not a public setting` };
|
|
@@ -35890,10 +35997,10 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35890
35997
|
}
|
|
35891
35998
|
const command = payload.command;
|
|
35892
35999
|
if (!command || typeof command !== "object") return null;
|
|
35893
|
-
if (command.type !== "send_message") return null;
|
|
36000
|
+
if (command.type !== "send_message" && command.type !== "pty_write") return null;
|
|
35894
36001
|
const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
|
|
35895
36002
|
if (!text) return null;
|
|
35896
|
-
return { type:
|
|
36003
|
+
return { type: command.type, text };
|
|
35897
36004
|
}
|
|
35898
36005
|
function applyProviderPatch(h, args, payload) {
|
|
35899
36006
|
if (!payload || typeof payload !== "object") return;
|
|
@@ -35934,6 +36041,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35934
36041
|
const cliCommand = getCliScriptCommand(parsed.payload);
|
|
35935
36042
|
if (cliCommand?.type === "send_message" && cliCommand.text) {
|
|
35936
36043
|
await adapter.sendMessage(cliCommand.text);
|
|
36044
|
+
} else if (cliCommand?.type === "pty_write" && cliCommand.text && adapter.writeRaw) {
|
|
36045
|
+
adapter.writeRaw(cliCommand.text + "\r");
|
|
35937
36046
|
}
|
|
35938
36047
|
applyProviderPatch(h, args, parsed.payload);
|
|
35939
36048
|
return { success: true, ...parsed.payload && typeof parsed.payload === "object" ? parsed.payload : { result: parsed.payload } };
|
|
@@ -36295,9 +36404,26 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36295
36404
|
if (provider?.scripts) {
|
|
36296
36405
|
const fn2 = provider.scripts[scriptName];
|
|
36297
36406
|
if (typeof fn2 === "function") {
|
|
36298
|
-
|
|
36299
|
-
|
|
36300
|
-
|
|
36407
|
+
if (params && Object.keys(params).length > 0) {
|
|
36408
|
+
const firstVal = Object.values(params)[0];
|
|
36409
|
+
if (scriptName === "sendMessage" && typeof firstVal === "string") {
|
|
36410
|
+
const legacyScript = fn2(firstVal);
|
|
36411
|
+
if (legacyScript) return legacyScript;
|
|
36412
|
+
}
|
|
36413
|
+
const script = fn2(params);
|
|
36414
|
+
if (script) {
|
|
36415
|
+
const likelyLegacyObjectLeak = typeof script === "string" && script.includes("[object Object]") && typeof firstVal === "string";
|
|
36416
|
+
if (!likelyLegacyObjectLeak) return script;
|
|
36417
|
+
}
|
|
36418
|
+
if (firstVal !== void 0) {
|
|
36419
|
+
const legacyScript = fn2(firstVal);
|
|
36420
|
+
if (legacyScript) return legacyScript;
|
|
36421
|
+
}
|
|
36422
|
+
if (script) return script;
|
|
36423
|
+
} else {
|
|
36424
|
+
const script = fn2();
|
|
36425
|
+
if (script) return script;
|
|
36426
|
+
}
|
|
36301
36427
|
}
|
|
36302
36428
|
}
|
|
36303
36429
|
return null;
|
|
@@ -36591,7 +36717,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36591
36717
|
try {
|
|
36592
36718
|
const http3 = await import("http");
|
|
36593
36719
|
const postData = JSON.stringify(body);
|
|
36594
|
-
const result = await new Promise((
|
|
36720
|
+
const result = await new Promise((resolve12, reject) => {
|
|
36595
36721
|
const req = http3.request({
|
|
36596
36722
|
hostname: "127.0.0.1",
|
|
36597
36723
|
port: 19280,
|
|
@@ -36603,9 +36729,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36603
36729
|
res.on("data", (chunk) => data += chunk);
|
|
36604
36730
|
res.on("end", () => {
|
|
36605
36731
|
try {
|
|
36606
|
-
|
|
36732
|
+
resolve12(JSON.parse(data));
|
|
36607
36733
|
} catch {
|
|
36608
|
-
|
|
36734
|
+
resolve12({ raw: data });
|
|
36609
36735
|
}
|
|
36610
36736
|
});
|
|
36611
36737
|
});
|
|
@@ -36623,15 +36749,15 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36623
36749
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
36624
36750
|
try {
|
|
36625
36751
|
const http3 = await import("http");
|
|
36626
|
-
const result = await new Promise((
|
|
36752
|
+
const result = await new Promise((resolve12, reject) => {
|
|
36627
36753
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
36628
36754
|
let data = "";
|
|
36629
36755
|
res.on("data", (chunk) => data += chunk);
|
|
36630
36756
|
res.on("end", () => {
|
|
36631
36757
|
try {
|
|
36632
|
-
|
|
36758
|
+
resolve12(JSON.parse(data));
|
|
36633
36759
|
} catch {
|
|
36634
|
-
|
|
36760
|
+
resolve12({ raw: data });
|
|
36635
36761
|
}
|
|
36636
36762
|
});
|
|
36637
36763
|
}).on("error", reject);
|
|
@@ -36645,7 +36771,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36645
36771
|
try {
|
|
36646
36772
|
const http3 = await import("http");
|
|
36647
36773
|
const postData = JSON.stringify(args || {});
|
|
36648
|
-
const result = await new Promise((
|
|
36774
|
+
const result = await new Promise((resolve12, reject) => {
|
|
36649
36775
|
const req = http3.request({
|
|
36650
36776
|
hostname: "127.0.0.1",
|
|
36651
36777
|
port: 19280,
|
|
@@ -36657,9 +36783,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36657
36783
|
res.on("data", (chunk) => data += chunk);
|
|
36658
36784
|
res.on("end", () => {
|
|
36659
36785
|
try {
|
|
36660
|
-
|
|
36786
|
+
resolve12(JSON.parse(data));
|
|
36661
36787
|
} catch {
|
|
36662
|
-
|
|
36788
|
+
resolve12({ raw: data });
|
|
36663
36789
|
}
|
|
36664
36790
|
});
|
|
36665
36791
|
});
|
|
@@ -36674,13 +36800,13 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36674
36800
|
}
|
|
36675
36801
|
};
|
|
36676
36802
|
var os10 = __toESM2(require("os"));
|
|
36677
|
-
var
|
|
36803
|
+
var path11 = __toESM2(require("path"));
|
|
36678
36804
|
var crypto4 = __toESM2(require("crypto"));
|
|
36679
36805
|
var import_chalk = __toESM2(require("chalk"));
|
|
36680
36806
|
init_provider_cli_adapter();
|
|
36681
36807
|
init_config();
|
|
36682
36808
|
var os9 = __toESM2(require("os"));
|
|
36683
|
-
var
|
|
36809
|
+
var path10 = __toESM2(require("path"));
|
|
36684
36810
|
var crypto3 = __toESM2(require("crypto"));
|
|
36685
36811
|
var fs5 = __toESM2(require("fs"));
|
|
36686
36812
|
var import_node_module = require("module");
|
|
@@ -36689,7 +36815,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36689
36815
|
var CachedDatabaseSync = null;
|
|
36690
36816
|
function getDatabaseSync() {
|
|
36691
36817
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
36692
|
-
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(
|
|
36818
|
+
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path10.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
36693
36819
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
36694
36820
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
36695
36821
|
if (!CachedDatabaseSync) {
|
|
@@ -36754,6 +36880,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36754
36880
|
this.detectStatusTransition();
|
|
36755
36881
|
});
|
|
36756
36882
|
await this.adapter.spawn();
|
|
36883
|
+
this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
|
|
36757
36884
|
if (this.providerSessionId) {
|
|
36758
36885
|
const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
|
|
36759
36886
|
if (restoredHistory.messages.length > 0) {
|
|
@@ -36848,6 +36975,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36848
36975
|
this.promoteProviderSessionId(parsedProviderSessionId);
|
|
36849
36976
|
}
|
|
36850
36977
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
36978
|
+
this.maybeAppendRuntimeRecoveryMessage(runtime);
|
|
36851
36979
|
const parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
|
|
36852
36980
|
const controlValues = extractProviderControlValues(this.provider.controls, parsedStatus);
|
|
36853
36981
|
if (controlValues) {
|
|
@@ -37174,6 +37302,28 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37174
37302
|
const pad = (value) => String(value).padStart(2, "0");
|
|
37175
37303
|
return `${date5.getFullYear()}-${pad(date5.getMonth() + 1)}-${pad(date5.getDate())} ${pad(date5.getHours())}:${pad(date5.getMinutes())}:${pad(date5.getSeconds())}`;
|
|
37176
37304
|
}
|
|
37305
|
+
maybeAppendRuntimeRecoveryMessage(runtime) {
|
|
37306
|
+
if (!runtime?.restoredFromStorage || !runtime.runtimeId) return;
|
|
37307
|
+
const recoveryState = String(runtime.recoveryState || "").trim();
|
|
37308
|
+
if (!recoveryState) return;
|
|
37309
|
+
let content = "";
|
|
37310
|
+
if (recoveryState === "auto_resumed") {
|
|
37311
|
+
content = "Session host restored this CLI after restart and reattached it from a saved snapshot.";
|
|
37312
|
+
} else if (recoveryState === "resume_failed") {
|
|
37313
|
+
const errorSuffix = runtime.recoveryError ? ` Resume failed: ${runtime.recoveryError}` : "";
|
|
37314
|
+
content = `Session host found this CLI after restart, but automatic resume failed.${errorSuffix}`;
|
|
37315
|
+
} else if (recoveryState === "host_restart_interrupted") {
|
|
37316
|
+
content = "Session host found this CLI in interrupted state after restart and is attempting to resume it.";
|
|
37317
|
+
} else if (recoveryState === "orphan_snapshot") {
|
|
37318
|
+
content = "Session host restored the last snapshot for this CLI, but the original runtime was not resumed automatically.";
|
|
37319
|
+
} else {
|
|
37320
|
+
content = `Session host restored this CLI after restart (${recoveryState}).`;
|
|
37321
|
+
}
|
|
37322
|
+
this.appendRuntimeSystemMessage(
|
|
37323
|
+
content,
|
|
37324
|
+
`runtime_recovery:${runtime.runtimeId}:${recoveryState}`
|
|
37325
|
+
);
|
|
37326
|
+
}
|
|
37177
37327
|
appendRuntimeSystemMessage(content, dedupKey, receivedAt = Date.now()) {
|
|
37178
37328
|
const normalizedContent = String(content || "").trim();
|
|
37179
37329
|
if (!normalizedContent) return;
|
|
@@ -37488,8 +37638,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37488
37638
|
async setConfigOption(category, value) {
|
|
37489
37639
|
const opt = this.configOptions.find((c) => c.category === category);
|
|
37490
37640
|
if (!opt) {
|
|
37491
|
-
|
|
37492
|
-
|
|
37641
|
+
const message = `[${this.type}] No config option for category: ${category}`;
|
|
37642
|
+
this.log.warn(message);
|
|
37643
|
+
throw new Error(message);
|
|
37493
37644
|
}
|
|
37494
37645
|
if (this.useStaticConfig) {
|
|
37495
37646
|
opt.currentValue = value;
|
|
@@ -37501,8 +37652,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37501
37652
|
return;
|
|
37502
37653
|
}
|
|
37503
37654
|
if (!this.connection || !this.sessionId) {
|
|
37504
|
-
|
|
37505
|
-
|
|
37655
|
+
const message = `[${this.type}] Cannot set config: no active connection/session`;
|
|
37656
|
+
this.log.warn(message);
|
|
37657
|
+
throw new Error(message);
|
|
37506
37658
|
}
|
|
37507
37659
|
try {
|
|
37508
37660
|
this.log.info(`[${this.type}] Sending session/set_config_option: configId=${opt.configId} value=${value} sessionId=${this.sessionId}`);
|
|
@@ -37516,7 +37668,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37516
37668
|
if (result?.configOptions) this.parseConfigOptions(result.configOptions);
|
|
37517
37669
|
this.log.info(`[${this.type}] Config ${category} set to: ${value} | response: ${JSON.stringify(result)?.slice(0, 300)}`);
|
|
37518
37670
|
} catch (e) {
|
|
37519
|
-
|
|
37671
|
+
const message = e?.message || "Unknown ACP config error";
|
|
37672
|
+
this.log.warn(`[${this.type}] set_config_option failed: ${message}`);
|
|
37673
|
+
throw new Error(message);
|
|
37520
37674
|
}
|
|
37521
37675
|
}
|
|
37522
37676
|
async setMode(modeId) {
|
|
@@ -37532,8 +37686,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37532
37686
|
return;
|
|
37533
37687
|
}
|
|
37534
37688
|
if (!this.connection || !this.sessionId) {
|
|
37535
|
-
|
|
37536
|
-
|
|
37689
|
+
const message = `[${this.type}] Cannot set mode: no active connection/session`;
|
|
37690
|
+
this.log.warn(message);
|
|
37691
|
+
throw new Error(message);
|
|
37537
37692
|
}
|
|
37538
37693
|
try {
|
|
37539
37694
|
await this.connection.setSessionMode({
|
|
@@ -37543,7 +37698,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37543
37698
|
this.currentMode = modeId;
|
|
37544
37699
|
this.log.info(`[${this.type}] Mode set to: ${modeId}`);
|
|
37545
37700
|
} catch (e) {
|
|
37546
|
-
|
|
37701
|
+
const message = e?.message || "Unknown ACP mode error";
|
|
37702
|
+
this.log.warn(`[${this.type}] set_mode failed: ${message}`);
|
|
37703
|
+
throw new Error(message);
|
|
37547
37704
|
}
|
|
37548
37705
|
}
|
|
37549
37706
|
/** Static config: kill process and restart with new args */
|
|
@@ -37591,7 +37748,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37591
37748
|
if (!spawnConfig) {
|
|
37592
37749
|
throw new Error(`[ACP:${this.type}] No spawn config defined`);
|
|
37593
37750
|
}
|
|
37594
|
-
const command = spawnConfig.command;
|
|
37751
|
+
const command = typeof this.settings.executablePath === "string" && this.settings.executablePath.trim() ? this.settings.executablePath.trim() : spawnConfig.command;
|
|
37595
37752
|
let baseArgs = spawnConfig.args || [];
|
|
37596
37753
|
if (this.provider.spawnArgBuilder && Object.keys(this.selectedConfig).length > 0) {
|
|
37597
37754
|
baseArgs = this.provider.spawnArgBuilder(this.selectedConfig);
|
|
@@ -37707,13 +37864,13 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37707
37864
|
}
|
|
37708
37865
|
this.currentStatus = "waiting_approval";
|
|
37709
37866
|
this.detectStatusTransition();
|
|
37710
|
-
const approved = await new Promise((
|
|
37711
|
-
this.permissionResolvers.push(
|
|
37867
|
+
const approved = await new Promise((resolve12) => {
|
|
37868
|
+
this.permissionResolvers.push(resolve12);
|
|
37712
37869
|
setTimeout(() => {
|
|
37713
|
-
const idx = this.permissionResolvers.indexOf(
|
|
37870
|
+
const idx = this.permissionResolvers.indexOf(resolve12);
|
|
37714
37871
|
if (idx >= 0) {
|
|
37715
37872
|
this.permissionResolvers.splice(idx, 1);
|
|
37716
|
-
|
|
37873
|
+
resolve12(false);
|
|
37717
37874
|
}
|
|
37718
37875
|
}, 3e5);
|
|
37719
37876
|
});
|
|
@@ -38418,7 +38575,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38418
38575
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
38419
38576
|
const trimmed = (workingDir || "").trim();
|
|
38420
38577
|
if (!trimmed) throw new Error("working directory required");
|
|
38421
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os10.homedir()) :
|
|
38578
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os10.homedir()) : path11.resolve(trimmed);
|
|
38422
38579
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
38423
38580
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
38424
38581
|
const key = crypto4.randomUUID();
|
|
@@ -38505,10 +38662,10 @@ ${installInfo}`
|
|
|
38505
38662
|
if (!cliInfo) {
|
|
38506
38663
|
const installHint = provider?.install || "";
|
|
38507
38664
|
const displayName = provider?.displayName || provider?.name || cliType;
|
|
38508
|
-
const spawnCmd = provider?.spawn?.command || cliType;
|
|
38665
|
+
const spawnCmd = this.providerLoader.getSpawnCommand(normalizedType, provider?.spawn?.command || cliType);
|
|
38509
38666
|
throw new Error(
|
|
38510
38667
|
`${displayName} is not installed.
|
|
38511
|
-
Command '${spawnCmd}' not
|
|
38668
|
+
Command '${spawnCmd}' is not available.
|
|
38512
38669
|
` + (installHint ? `
|
|
38513
38670
|
${installHint}
|
|
38514
38671
|
` : "") + `
|
|
@@ -38866,14 +39023,15 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
38866
39023
|
var import_child_process6 = require("child_process");
|
|
38867
39024
|
var net3 = __toESM2(require("net"));
|
|
38868
39025
|
var os12 = __toESM2(require("os"));
|
|
38869
|
-
var
|
|
39026
|
+
var path13 = __toESM2(require("path"));
|
|
38870
39027
|
var fs6 = __toESM2(require("fs"));
|
|
38871
|
-
var
|
|
39028
|
+
var path12 = __toESM2(require("path"));
|
|
38872
39029
|
var os11 = __toESM2(require("os"));
|
|
38873
39030
|
var chokidar = __toESM2((init_chokidar(), __toCommonJS(chokidar_exports)));
|
|
38874
39031
|
init_logger();
|
|
38875
39032
|
var ProviderLoader = class _ProviderLoader {
|
|
38876
39033
|
providers = /* @__PURE__ */ new Map();
|
|
39034
|
+
providerAvailability = /* @__PURE__ */ new Map();
|
|
38877
39035
|
userDir;
|
|
38878
39036
|
upstreamDir;
|
|
38879
39037
|
disableUpstream;
|
|
@@ -38889,12 +39047,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
38889
39047
|
static META_FILE = ".meta.json";
|
|
38890
39048
|
constructor(options) {
|
|
38891
39049
|
this.logFn = options?.logFn || LOG2.forComponent("Provider").asLogFn();
|
|
38892
|
-
const defaultProvidersDir =
|
|
39050
|
+
const defaultProvidersDir = path12.join(os11.homedir(), ".adhdev", "providers");
|
|
38893
39051
|
if (options?.userDir) {
|
|
38894
39052
|
this.userDir = options.userDir;
|
|
38895
39053
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
38896
39054
|
} else {
|
|
38897
|
-
const localRepoPath =
|
|
39055
|
+
const localRepoPath = path12.resolve(__dirname, "../../../../../adhdev-providers");
|
|
38898
39056
|
if (fs6.existsSync(localRepoPath)) {
|
|
38899
39057
|
this.userDir = localRepoPath;
|
|
38900
39058
|
this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
|
|
@@ -38903,7 +39061,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
38903
39061
|
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
38904
39062
|
}
|
|
38905
39063
|
}
|
|
38906
|
-
this.upstreamDir =
|
|
39064
|
+
this.upstreamDir = path12.join(defaultProvidersDir, ".upstream");
|
|
38907
39065
|
this.disableUpstream = options?.disableUpstream ?? false;
|
|
38908
39066
|
}
|
|
38909
39067
|
log(msg) {
|
|
@@ -38933,7 +39091,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
38933
39091
|
* Canonical provider directory shape for a given root.
|
|
38934
39092
|
*/
|
|
38935
39093
|
getProviderDir(root, category, type) {
|
|
38936
|
-
return
|
|
39094
|
+
return path12.join(root, category, type);
|
|
38937
39095
|
}
|
|
38938
39096
|
/**
|
|
38939
39097
|
* Canonical user override directory for a provider.
|
|
@@ -38960,7 +39118,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
38960
39118
|
resolveProviderFile(type, ...segments) {
|
|
38961
39119
|
const dir = this.findProviderDirInternal(type);
|
|
38962
39120
|
if (!dir) return null;
|
|
38963
|
-
return
|
|
39121
|
+
return path12.join(dir, ...segments);
|
|
38964
39122
|
}
|
|
38965
39123
|
/**
|
|
38966
39124
|
* Load all providers (3-tier priority)
|
|
@@ -38971,6 +39129,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
38971
39129
|
*/
|
|
38972
39130
|
loadAll() {
|
|
38973
39131
|
this.providers.clear();
|
|
39132
|
+
this.providerAvailability.clear();
|
|
38974
39133
|
let upstreamCount = 0;
|
|
38975
39134
|
if (!this.disableUpstream && fs6.existsSync(this.upstreamDir)) {
|
|
38976
39135
|
upstreamCount = this.loadDir(this.upstreamDir);
|
|
@@ -38998,7 +39157,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
38998
39157
|
if (!fs6.existsSync(this.upstreamDir)) return false;
|
|
38999
39158
|
try {
|
|
39000
39159
|
return fs6.readdirSync(this.upstreamDir).some(
|
|
39001
|
-
(d) => fs6.statSync(
|
|
39160
|
+
(d) => fs6.statSync(path12.join(this.upstreamDir, d)).isDirectory()
|
|
39002
39161
|
);
|
|
39003
39162
|
} catch {
|
|
39004
39163
|
return false;
|
|
@@ -39041,11 +39200,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39041
39200
|
if ((p.category === "cli" || p.category === "acp") && p.spawn?.command) {
|
|
39042
39201
|
const verCmdConfig = p.versionCommand;
|
|
39043
39202
|
const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[process.platform] : verCmdConfig;
|
|
39203
|
+
const command = this.getSpawnCommand(p.type, p.spawn.command);
|
|
39044
39204
|
result.push({
|
|
39045
39205
|
id: p.type,
|
|
39046
39206
|
displayName: p.displayName || p.name,
|
|
39047
39207
|
icon: p.icon || "\u{1F527}",
|
|
39048
|
-
command
|
|
39208
|
+
command,
|
|
39049
39209
|
category: p.category,
|
|
39050
39210
|
...typeof versionCommand === "string" && versionCommand.trim() ? { versionCommand: versionCommand.trim() } : {}
|
|
39051
39211
|
});
|
|
@@ -39174,6 +39334,71 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39174
39334
|
getAvailableIdeTypes() {
|
|
39175
39335
|
return [...this.providers.values()].filter((p) => p.category === "ide" && p.cdpPorts).map((p) => p.type);
|
|
39176
39336
|
}
|
|
39337
|
+
getSpawnCommand(type, fallback) {
|
|
39338
|
+
const override = this.getOptionalStringSetting(type, "executablePath");
|
|
39339
|
+
if (override) return override;
|
|
39340
|
+
return fallback || this.providers.get(type)?.spawn?.command || type;
|
|
39341
|
+
}
|
|
39342
|
+
getIdeCliCommand(type, fallback) {
|
|
39343
|
+
const override = this.getOptionalStringSetting(type, "cliPathOverride");
|
|
39344
|
+
if (override) return override;
|
|
39345
|
+
return fallback || this.providers.get(type)?.cli || null;
|
|
39346
|
+
}
|
|
39347
|
+
getIdePathCandidates(type, fallback) {
|
|
39348
|
+
const override = this.getOptionalStringSetting(type, "appPathOverride");
|
|
39349
|
+
if (override) return [override];
|
|
39350
|
+
if (fallback && fallback.length > 0) return fallback;
|
|
39351
|
+
const osPaths = this.providers.get(type)?.paths?.[process.platform];
|
|
39352
|
+
return Array.isArray(osPaths) ? [...osPaths] : [];
|
|
39353
|
+
}
|
|
39354
|
+
setProviderAvailability(type, state) {
|
|
39355
|
+
this.providerAvailability.set(type, {
|
|
39356
|
+
installed: !!state.installed,
|
|
39357
|
+
detectedPath: state.detectedPath ?? null
|
|
39358
|
+
});
|
|
39359
|
+
}
|
|
39360
|
+
setCliDetectionResults(results, replace = true) {
|
|
39361
|
+
if (replace) {
|
|
39362
|
+
for (const provider of this.providers.values()) {
|
|
39363
|
+
if (provider.category === "cli" || provider.category === "acp") {
|
|
39364
|
+
this.providerAvailability.set(provider.type, { installed: false, detectedPath: null });
|
|
39365
|
+
}
|
|
39366
|
+
}
|
|
39367
|
+
}
|
|
39368
|
+
for (const result of results) {
|
|
39369
|
+
this.setProviderAvailability(result.id, {
|
|
39370
|
+
installed: !!result.installed,
|
|
39371
|
+
detectedPath: result.path || null
|
|
39372
|
+
});
|
|
39373
|
+
}
|
|
39374
|
+
}
|
|
39375
|
+
setIdeDetectionResults(results, replace = true) {
|
|
39376
|
+
if (replace) {
|
|
39377
|
+
for (const provider of this.providers.values()) {
|
|
39378
|
+
if (provider.category === "ide") {
|
|
39379
|
+
this.providerAvailability.set(provider.type, { installed: false, detectedPath: null });
|
|
39380
|
+
}
|
|
39381
|
+
}
|
|
39382
|
+
}
|
|
39383
|
+
for (const result of results) {
|
|
39384
|
+
this.setProviderAvailability(result.id, {
|
|
39385
|
+
installed: !!result.installed,
|
|
39386
|
+
detectedPath: result.cliCommand || result.path || null
|
|
39387
|
+
});
|
|
39388
|
+
}
|
|
39389
|
+
}
|
|
39390
|
+
getAvailableProviderInfos() {
|
|
39391
|
+
return this.getAll().map((provider) => {
|
|
39392
|
+
const availability = this.providerAvailability.get(provider.type);
|
|
39393
|
+
return {
|
|
39394
|
+
...provider,
|
|
39395
|
+
...availability ? {
|
|
39396
|
+
installed: availability.installed,
|
|
39397
|
+
detectedPath: availability.detectedPath
|
|
39398
|
+
} : {}
|
|
39399
|
+
};
|
|
39400
|
+
});
|
|
39401
|
+
}
|
|
39177
39402
|
/**
|
|
39178
39403
|
* Register IDE providers to core/detector registry
|
|
39179
39404
|
* → Enables detectIDEs() to detect provider.js-based IDEs
|
|
@@ -39248,8 +39473,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39248
39473
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
39249
39474
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
39250
39475
|
if (providerDir) {
|
|
39251
|
-
const fullDir =
|
|
39252
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
39476
|
+
const fullDir = path12.join(providerDir, entry.scriptDir);
|
|
39477
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
|
|
39253
39478
|
}
|
|
39254
39479
|
matched = true;
|
|
39255
39480
|
}
|
|
@@ -39264,8 +39489,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39264
39489
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
39265
39490
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
39266
39491
|
if (providerDir) {
|
|
39267
|
-
const fullDir =
|
|
39268
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
39492
|
+
const fullDir = path12.join(providerDir, base.defaultScriptDir);
|
|
39493
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
|
|
39269
39494
|
}
|
|
39270
39495
|
}
|
|
39271
39496
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -39282,8 +39507,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39282
39507
|
resolved._resolvedScriptDir = dirOverride;
|
|
39283
39508
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
39284
39509
|
if (providerDir) {
|
|
39285
|
-
const fullDir =
|
|
39286
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
39510
|
+
const fullDir = path12.join(providerDir, dirOverride);
|
|
39511
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
|
|
39287
39512
|
}
|
|
39288
39513
|
}
|
|
39289
39514
|
} else if (override.scripts) {
|
|
@@ -39299,8 +39524,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39299
39524
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
39300
39525
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
39301
39526
|
if (providerDir) {
|
|
39302
|
-
const fullDir =
|
|
39303
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
39527
|
+
const fullDir = path12.join(providerDir, base.defaultScriptDir);
|
|
39528
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
|
|
39304
39529
|
}
|
|
39305
39530
|
}
|
|
39306
39531
|
}
|
|
@@ -39325,14 +39550,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39325
39550
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
39326
39551
|
return null;
|
|
39327
39552
|
}
|
|
39328
|
-
const dir =
|
|
39553
|
+
const dir = path12.join(providerDir, scriptDir);
|
|
39329
39554
|
if (!fs6.existsSync(dir)) {
|
|
39330
39555
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
39331
39556
|
return null;
|
|
39332
39557
|
}
|
|
39333
39558
|
const cached2 = this.scriptsCache.get(dir);
|
|
39334
39559
|
if (cached2) return cached2;
|
|
39335
|
-
const scriptsJs =
|
|
39560
|
+
const scriptsJs = path12.join(dir, "scripts.js");
|
|
39336
39561
|
if (fs6.existsSync(scriptsJs)) {
|
|
39337
39562
|
try {
|
|
39338
39563
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -39374,7 +39599,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39374
39599
|
return;
|
|
39375
39600
|
}
|
|
39376
39601
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
39377
|
-
this.log(`File changed: ${
|
|
39602
|
+
this.log(`File changed: ${path12.basename(filePath)}, reloading...`);
|
|
39378
39603
|
this.reload();
|
|
39379
39604
|
}
|
|
39380
39605
|
};
|
|
@@ -39429,7 +39654,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39429
39654
|
}
|
|
39430
39655
|
const https = require("https");
|
|
39431
39656
|
const { execSync: execSync7 } = require("child_process");
|
|
39432
|
-
const metaPath =
|
|
39657
|
+
const metaPath = path12.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
39433
39658
|
let prevEtag = "";
|
|
39434
39659
|
let prevTimestamp = 0;
|
|
39435
39660
|
try {
|
|
@@ -39446,7 +39671,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39446
39671
|
return { updated: false };
|
|
39447
39672
|
}
|
|
39448
39673
|
try {
|
|
39449
|
-
const etag = await new Promise((
|
|
39674
|
+
const etag = await new Promise((resolve12, reject) => {
|
|
39450
39675
|
const options = {
|
|
39451
39676
|
method: "HEAD",
|
|
39452
39677
|
hostname: "github.com",
|
|
@@ -39464,7 +39689,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39464
39689
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
39465
39690
|
timeout: 1e4
|
|
39466
39691
|
}, (res2) => {
|
|
39467
|
-
|
|
39692
|
+
resolve12(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
39468
39693
|
});
|
|
39469
39694
|
req2.on("error", reject);
|
|
39470
39695
|
req2.on("timeout", () => {
|
|
@@ -39473,7 +39698,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39473
39698
|
});
|
|
39474
39699
|
req2.end();
|
|
39475
39700
|
} else {
|
|
39476
|
-
|
|
39701
|
+
resolve12(res.headers.etag || res.headers["last-modified"] || "");
|
|
39477
39702
|
}
|
|
39478
39703
|
});
|
|
39479
39704
|
req.on("error", reject);
|
|
@@ -39489,17 +39714,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39489
39714
|
return { updated: false };
|
|
39490
39715
|
}
|
|
39491
39716
|
this.log("Downloading latest providers from GitHub...");
|
|
39492
|
-
const tmpTar =
|
|
39493
|
-
const tmpExtract =
|
|
39717
|
+
const tmpTar = path12.join(os11.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
39718
|
+
const tmpExtract = path12.join(os11.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
39494
39719
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
39495
39720
|
fs6.mkdirSync(tmpExtract, { recursive: true });
|
|
39496
39721
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
39497
39722
|
const extracted = fs6.readdirSync(tmpExtract);
|
|
39498
39723
|
const rootDir = extracted.find(
|
|
39499
|
-
(d) => fs6.statSync(
|
|
39724
|
+
(d) => fs6.statSync(path12.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
39500
39725
|
);
|
|
39501
39726
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
39502
|
-
const sourceDir =
|
|
39727
|
+
const sourceDir = path12.join(tmpExtract, rootDir);
|
|
39503
39728
|
const backupDir = this.upstreamDir + ".bak";
|
|
39504
39729
|
if (fs6.existsSync(this.upstreamDir)) {
|
|
39505
39730
|
if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -39537,7 +39762,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39537
39762
|
downloadFile(url2, destPath) {
|
|
39538
39763
|
const https = require("https");
|
|
39539
39764
|
const http3 = require("http");
|
|
39540
|
-
return new Promise((
|
|
39765
|
+
return new Promise((resolve12, reject) => {
|
|
39541
39766
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
39542
39767
|
if (redirectCount > 5) {
|
|
39543
39768
|
reject(new Error("Too many redirects"));
|
|
@@ -39557,7 +39782,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39557
39782
|
res.pipe(ws2);
|
|
39558
39783
|
ws2.on("finish", () => {
|
|
39559
39784
|
ws2.close();
|
|
39560
|
-
|
|
39785
|
+
resolve12();
|
|
39561
39786
|
});
|
|
39562
39787
|
ws2.on("error", reject);
|
|
39563
39788
|
});
|
|
@@ -39574,8 +39799,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39574
39799
|
copyDirRecursive(src, dest) {
|
|
39575
39800
|
fs6.mkdirSync(dest, { recursive: true });
|
|
39576
39801
|
for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
|
|
39577
|
-
const srcPath =
|
|
39578
|
-
const destPath =
|
|
39802
|
+
const srcPath = path12.join(src, entry.name);
|
|
39803
|
+
const destPath = path12.join(dest, entry.name);
|
|
39579
39804
|
if (entry.isDirectory()) {
|
|
39580
39805
|
this.copyDirRecursive(srcPath, destPath);
|
|
39581
39806
|
} else {
|
|
@@ -39586,7 +39811,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39586
39811
|
/** .meta.json save */
|
|
39587
39812
|
writeMeta(metaPath, etag, timestamp) {
|
|
39588
39813
|
try {
|
|
39589
|
-
fs6.mkdirSync(
|
|
39814
|
+
fs6.mkdirSync(path12.dirname(metaPath), { recursive: true });
|
|
39590
39815
|
fs6.writeFileSync(metaPath, JSON.stringify({
|
|
39591
39816
|
etag,
|
|
39592
39817
|
timestamp,
|
|
@@ -39603,7 +39828,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39603
39828
|
const scan = (d) => {
|
|
39604
39829
|
try {
|
|
39605
39830
|
for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
|
|
39606
|
-
if (entry.isDirectory()) scan(
|
|
39831
|
+
if (entry.isDirectory()) scan(path12.join(d, entry.name));
|
|
39607
39832
|
else if (entry.name === "provider.json") count++;
|
|
39608
39833
|
}
|
|
39609
39834
|
} catch {
|
|
@@ -39617,9 +39842,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39617
39842
|
* Get public settings schema for a provider (for dashboard UI rendering)
|
|
39618
39843
|
*/
|
|
39619
39844
|
getPublicSettings(type) {
|
|
39620
|
-
const
|
|
39621
|
-
|
|
39622
|
-
return Object.entries(provider.settings).filter(([, def]) => def.public === true).map(([key, def]) => ({ key, ...def }));
|
|
39845
|
+
const settings = this.getSettingsSchema(type);
|
|
39846
|
+
return Object.entries(settings).filter(([, def]) => def.public === true).map(([key, def]) => ({ key, ...def }));
|
|
39623
39847
|
}
|
|
39624
39848
|
/**
|
|
39625
39849
|
* Get public settings schema for all providers
|
|
@@ -39636,8 +39860,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39636
39860
|
* Resolved setting value for a provider (default + user override)
|
|
39637
39861
|
*/
|
|
39638
39862
|
getSettingValue(type, key) {
|
|
39639
|
-
const
|
|
39640
|
-
const schemaDef = provider?.settings?.[key];
|
|
39863
|
+
const schemaDef = this.getSettingsSchema(type)[key];
|
|
39641
39864
|
const defaultVal = schemaDef ? schemaDef.default : void 0;
|
|
39642
39865
|
try {
|
|
39643
39866
|
const { loadConfig: loadConfig22 } = (init_config(), __toCommonJS2(config_exports));
|
|
@@ -39652,10 +39875,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39652
39875
|
* All resolved settings for a provider (default + user override)
|
|
39653
39876
|
*/
|
|
39654
39877
|
getSettings(type) {
|
|
39655
|
-
const
|
|
39656
|
-
if (!provider?.settings) return {};
|
|
39878
|
+
const settings = this.getSettingsSchema(type);
|
|
39657
39879
|
const result = {};
|
|
39658
|
-
for (const [key
|
|
39880
|
+
for (const [key] of Object.entries(settings)) {
|
|
39659
39881
|
result[key] = this.getSettingValue(type, key);
|
|
39660
39882
|
}
|
|
39661
39883
|
return result;
|
|
@@ -39664,11 +39886,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39664
39886
|
* Save provider setting value (writes to config.json)
|
|
39665
39887
|
*/
|
|
39666
39888
|
setSetting(type, key, value) {
|
|
39667
|
-
const
|
|
39668
|
-
const schemaDef = provider?.settings?.[key];
|
|
39889
|
+
const schemaDef = this.getSettingsSchema(type)[key];
|
|
39669
39890
|
if (!schemaDef) return false;
|
|
39670
39891
|
if (!schemaDef.public) return false;
|
|
39671
39892
|
if (schemaDef.type === "boolean" && typeof value !== "boolean") return false;
|
|
39893
|
+
if (schemaDef.type === "string" && typeof value !== "string") return false;
|
|
39672
39894
|
if (schemaDef.type === "number") {
|
|
39673
39895
|
if (typeof value !== "number") return false;
|
|
39674
39896
|
if (schemaDef.min !== void 0 && value < schemaDef.min) return false;
|
|
@@ -39689,6 +39911,53 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39689
39911
|
return false;
|
|
39690
39912
|
}
|
|
39691
39913
|
}
|
|
39914
|
+
getOptionalStringSetting(type, key) {
|
|
39915
|
+
const value = this.getSettingValue(type, key);
|
|
39916
|
+
if (typeof value !== "string") return null;
|
|
39917
|
+
const trimmed = value.trim();
|
|
39918
|
+
return trimmed ? trimmed : null;
|
|
39919
|
+
}
|
|
39920
|
+
getSettingsSchema(type) {
|
|
39921
|
+
const provider = this.providers.get(type);
|
|
39922
|
+
if (!provider) return {};
|
|
39923
|
+
return {
|
|
39924
|
+
...this.getSyntheticSettings(type, provider),
|
|
39925
|
+
...provider.settings || {}
|
|
39926
|
+
};
|
|
39927
|
+
}
|
|
39928
|
+
getSyntheticSettings(type, provider) {
|
|
39929
|
+
const result = {};
|
|
39930
|
+
if ((provider.category === "cli" || provider.category === "acp") && provider.spawn?.command && !provider.settings?.executablePath) {
|
|
39931
|
+
result.executablePath = {
|
|
39932
|
+
type: "string",
|
|
39933
|
+
default: "",
|
|
39934
|
+
public: true,
|
|
39935
|
+
label: "Executable path",
|
|
39936
|
+
description: "Optional absolute path for this provider binary. Leave blank to use the default PATH lookup."
|
|
39937
|
+
};
|
|
39938
|
+
}
|
|
39939
|
+
if (provider.category === "ide") {
|
|
39940
|
+
if (provider.cli && !provider.settings?.cliPathOverride) {
|
|
39941
|
+
result.cliPathOverride = {
|
|
39942
|
+
type: "string",
|
|
39943
|
+
default: "",
|
|
39944
|
+
public: true,
|
|
39945
|
+
label: "CLI path override",
|
|
39946
|
+
description: "Optional absolute path for the IDE CLI launcher. Leave blank to use the detected default."
|
|
39947
|
+
};
|
|
39948
|
+
}
|
|
39949
|
+
if (provider.paths && !provider.settings?.appPathOverride) {
|
|
39950
|
+
result.appPathOverride = {
|
|
39951
|
+
type: "string",
|
|
39952
|
+
default: "",
|
|
39953
|
+
public: true,
|
|
39954
|
+
label: "App path override",
|
|
39955
|
+
description: "Optional absolute path for the IDE app bundle or executable. Leave blank to use the default install locations."
|
|
39956
|
+
};
|
|
39957
|
+
}
|
|
39958
|
+
}
|
|
39959
|
+
return result;
|
|
39960
|
+
}
|
|
39692
39961
|
// ─── Private ───────────────────────────────────
|
|
39693
39962
|
/**
|
|
39694
39963
|
* Find the on-disk directory for a provider by type.
|
|
@@ -39702,17 +39971,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39702
39971
|
for (const root of searchRoots) {
|
|
39703
39972
|
if (!fs6.existsSync(root)) continue;
|
|
39704
39973
|
const candidate = this.getProviderDir(root, cat, type);
|
|
39705
|
-
if (fs6.existsSync(
|
|
39706
|
-
const catDir =
|
|
39974
|
+
if (fs6.existsSync(path12.join(candidate, "provider.json"))) return candidate;
|
|
39975
|
+
const catDir = path12.join(root, cat);
|
|
39707
39976
|
if (fs6.existsSync(catDir)) {
|
|
39708
39977
|
try {
|
|
39709
39978
|
for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
|
|
39710
39979
|
if (!entry.isDirectory()) continue;
|
|
39711
|
-
const jsonPath =
|
|
39980
|
+
const jsonPath = path12.join(catDir, entry.name, "provider.json");
|
|
39712
39981
|
if (fs6.existsSync(jsonPath)) {
|
|
39713
39982
|
try {
|
|
39714
39983
|
const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
|
|
39715
|
-
if (data.type === type) return
|
|
39984
|
+
if (data.type === type) return path12.join(catDir, entry.name);
|
|
39716
39985
|
} catch {
|
|
39717
39986
|
}
|
|
39718
39987
|
}
|
|
@@ -39729,7 +39998,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39729
39998
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
39730
39999
|
*/
|
|
39731
40000
|
buildScriptWrappersFromDir(dir) {
|
|
39732
|
-
const scriptsJs =
|
|
40001
|
+
const scriptsJs = path12.join(dir, "scripts.js");
|
|
39733
40002
|
if (fs6.existsSync(scriptsJs)) {
|
|
39734
40003
|
try {
|
|
39735
40004
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -39743,7 +40012,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39743
40012
|
for (const file2 of fs6.readdirSync(dir)) {
|
|
39744
40013
|
if (!file2.endsWith(".js")) continue;
|
|
39745
40014
|
const scriptName = toCamel(file2.replace(".js", ""));
|
|
39746
|
-
const filePath =
|
|
40015
|
+
const filePath = path12.join(dir, file2);
|
|
39747
40016
|
result[scriptName] = (...args) => {
|
|
39748
40017
|
try {
|
|
39749
40018
|
let content = fs6.readFileSync(filePath, "utf-8");
|
|
@@ -39803,7 +40072,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39803
40072
|
}
|
|
39804
40073
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
39805
40074
|
if (hasJson) {
|
|
39806
|
-
const jsonPath =
|
|
40075
|
+
const jsonPath = path12.join(d, "provider.json");
|
|
39807
40076
|
try {
|
|
39808
40077
|
const raw = fs6.readFileSync(jsonPath, "utf-8");
|
|
39809
40078
|
const mod = JSON.parse(raw);
|
|
@@ -39816,7 +40085,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39816
40085
|
delete mod.extensionIdPattern_flags;
|
|
39817
40086
|
}
|
|
39818
40087
|
const hasCompatibility = Array.isArray(mod.compatibility);
|
|
39819
|
-
const scriptsPath =
|
|
40088
|
+
const scriptsPath = path12.join(d, "scripts.js");
|
|
39820
40089
|
if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
|
|
39821
40090
|
try {
|
|
39822
40091
|
delete require.cache[require.resolve(scriptsPath)];
|
|
@@ -39842,7 +40111,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39842
40111
|
if (!entry.isDirectory()) continue;
|
|
39843
40112
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
39844
40113
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
39845
|
-
scan(
|
|
40114
|
+
scan(path12.join(d, entry.name));
|
|
39846
40115
|
}
|
|
39847
40116
|
}
|
|
39848
40117
|
};
|
|
@@ -39936,17 +40205,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39936
40205
|
throw new Error("No free port found");
|
|
39937
40206
|
}
|
|
39938
40207
|
function checkPortFree(port) {
|
|
39939
|
-
return new Promise((
|
|
40208
|
+
return new Promise((resolve12) => {
|
|
39940
40209
|
const server = net3.createServer();
|
|
39941
40210
|
server.unref();
|
|
39942
|
-
server.on("error", () =>
|
|
40211
|
+
server.on("error", () => resolve12(false));
|
|
39943
40212
|
server.listen(port, "127.0.0.1", () => {
|
|
39944
|
-
server.close(() =>
|
|
40213
|
+
server.close(() => resolve12(true));
|
|
39945
40214
|
});
|
|
39946
40215
|
});
|
|
39947
40216
|
}
|
|
39948
40217
|
async function isCdpActive(port) {
|
|
39949
|
-
return new Promise((
|
|
40218
|
+
return new Promise((resolve12) => {
|
|
39950
40219
|
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
39951
40220
|
timeout: 2e3
|
|
39952
40221
|
}, (res) => {
|
|
@@ -39955,16 +40224,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
39955
40224
|
res.on("end", () => {
|
|
39956
40225
|
try {
|
|
39957
40226
|
const info = JSON.parse(data);
|
|
39958
|
-
|
|
40227
|
+
resolve12(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
39959
40228
|
} catch {
|
|
39960
|
-
|
|
40229
|
+
resolve12(false);
|
|
39961
40230
|
}
|
|
39962
40231
|
});
|
|
39963
40232
|
});
|
|
39964
|
-
req.on("error", () =>
|
|
40233
|
+
req.on("error", () => resolve12(false));
|
|
39965
40234
|
req.on("timeout", () => {
|
|
39966
40235
|
req.destroy();
|
|
39967
|
-
|
|
40236
|
+
resolve12(false);
|
|
39968
40237
|
});
|
|
39969
40238
|
});
|
|
39970
40239
|
}
|
|
@@ -40098,8 +40367,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40098
40367
|
const appNameMap = getMacAppIdentifiers();
|
|
40099
40368
|
const appName = appNameMap[ideId];
|
|
40100
40369
|
if (appName) {
|
|
40101
|
-
const storagePath =
|
|
40102
|
-
process.env.APPDATA ||
|
|
40370
|
+
const storagePath = path13.join(
|
|
40371
|
+
process.env.APPDATA || path13.join(os12.homedir(), "AppData", "Roaming"),
|
|
40103
40372
|
appName,
|
|
40104
40373
|
"storage.json"
|
|
40105
40374
|
);
|
|
@@ -40123,7 +40392,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40123
40392
|
async function launchWithCdp(options = {}) {
|
|
40124
40393
|
const platform9 = os12.platform();
|
|
40125
40394
|
let targetIde;
|
|
40126
|
-
const ides = await detectIDEs();
|
|
40395
|
+
const ides = await detectIDEs(getProviderLoader());
|
|
40127
40396
|
if (options.ideId) {
|
|
40128
40397
|
targetIde = ides.find((i) => i.id === options.ideId && i.installed);
|
|
40129
40398
|
if (!targetIde) {
|
|
@@ -40273,9 +40542,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40273
40542
|
init_config();
|
|
40274
40543
|
init_logger();
|
|
40275
40544
|
var fs7 = __toESM2(require("fs"));
|
|
40276
|
-
var
|
|
40545
|
+
var path14 = __toESM2(require("path"));
|
|
40277
40546
|
var os13 = __toESM2(require("os"));
|
|
40278
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
40547
|
+
var LOG_DIR2 = process.platform === "win32" ? path14.join(process.env.LOCALAPPDATA || process.env.APPDATA || path14.join(os13.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path14.join(os13.homedir(), "Library", "Logs", "adhdev") : path14.join(os13.homedir(), ".local", "share", "adhdev", "logs");
|
|
40279
40548
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
40280
40549
|
var MAX_DAYS = 7;
|
|
40281
40550
|
try {
|
|
@@ -40313,13 +40582,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40313
40582
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
40314
40583
|
}
|
|
40315
40584
|
var currentDate2 = getDateStr2();
|
|
40316
|
-
var currentFile =
|
|
40585
|
+
var currentFile = path14.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
40317
40586
|
var writeCount2 = 0;
|
|
40318
40587
|
function checkRotation() {
|
|
40319
40588
|
const today = getDateStr2();
|
|
40320
40589
|
if (today !== currentDate2) {
|
|
40321
40590
|
currentDate2 = today;
|
|
40322
|
-
currentFile =
|
|
40591
|
+
currentFile = path14.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
40323
40592
|
cleanOldFiles();
|
|
40324
40593
|
}
|
|
40325
40594
|
}
|
|
@@ -40333,7 +40602,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40333
40602
|
const dateMatch = file2.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
40334
40603
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
40335
40604
|
try {
|
|
40336
|
-
fs7.unlinkSync(
|
|
40605
|
+
fs7.unlinkSync(path14.join(LOG_DIR2, file2));
|
|
40337
40606
|
} catch {
|
|
40338
40607
|
}
|
|
40339
40608
|
}
|
|
@@ -40421,12 +40690,15 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40421
40690
|
}));
|
|
40422
40691
|
}
|
|
40423
40692
|
function buildAvailableProviders(providerLoader) {
|
|
40424
|
-
|
|
40693
|
+
const providers = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
|
|
40694
|
+
return providers.map((provider) => ({
|
|
40425
40695
|
type: provider.type,
|
|
40426
40696
|
name: provider.displayName || provider.type,
|
|
40427
40697
|
displayName: provider.displayName || provider.type,
|
|
40428
40698
|
icon: provider.icon || "\u{1F4BB}",
|
|
40429
|
-
category: provider.category
|
|
40699
|
+
category: provider.category,
|
|
40700
|
+
...provider.installed !== void 0 ? { installed: provider.installed } : {},
|
|
40701
|
+
...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {}
|
|
40430
40702
|
}));
|
|
40431
40703
|
}
|
|
40432
40704
|
function parseMessageTime(value) {
|
|
@@ -40440,17 +40712,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40440
40712
|
function getSessionMessageUpdatedAt(session) {
|
|
40441
40713
|
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
40442
40714
|
if (!lastMessage) return 0;
|
|
40443
|
-
return parseMessageTime(lastMessage.
|
|
40715
|
+
return parseMessageTime(lastMessage.receivedAt) || 0;
|
|
40444
40716
|
}
|
|
40445
40717
|
function getSessionCompletionMarker(session) {
|
|
40446
40718
|
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
40447
40719
|
if (!lastMessage) return "";
|
|
40448
40720
|
const role = typeof lastMessage.role === "string" ? lastMessage.role : "";
|
|
40449
|
-
if (role === "user" || role === "human") return "";
|
|
40721
|
+
if (role === "user" || role === "human" || role === "system") return "";
|
|
40450
40722
|
if (typeof lastMessage._turnKey === "string" && lastMessage._turnKey) return `turn:${lastMessage._turnKey}`;
|
|
40451
40723
|
if (typeof lastMessage.id === "string" && lastMessage.id) return `id:${lastMessage.id}`;
|
|
40452
40724
|
if (typeof lastMessage.index === "number" && Number.isFinite(lastMessage.index)) return `idx:${lastMessage.index}`;
|
|
40453
|
-
const timestamp = parseMessageTime(lastMessage.
|
|
40725
|
+
const timestamp = parseMessageTime(lastMessage.receivedAt);
|
|
40454
40726
|
return timestamp > 0 ? `ts:${timestamp}` : "";
|
|
40455
40727
|
}
|
|
40456
40728
|
function getSessionLastUsedAt(session) {
|
|
@@ -40467,7 +40739,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40467
40739
|
if (status === "generating" || status === "starting") {
|
|
40468
40740
|
return { unread: false, inboxBucket: "working" };
|
|
40469
40741
|
}
|
|
40470
|
-
const unread = completionMarker ? completionMarker !== seenCompletionMarker : hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human";
|
|
40742
|
+
const unread = completionMarker ? completionMarker !== seenCompletionMarker : hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human" && lastRole !== "system";
|
|
40471
40743
|
return { unread, inboxBucket: unread ? "task_complete" : "idle" };
|
|
40472
40744
|
}
|
|
40473
40745
|
function buildRecentLaunches(recentActivity) {
|
|
@@ -40552,13 +40824,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40552
40824
|
var import_child_process8 = require("child_process");
|
|
40553
40825
|
var fs8 = __toESM2(require("fs"));
|
|
40554
40826
|
var os15 = __toESM2(require("os"));
|
|
40555
|
-
var
|
|
40827
|
+
var path15 = __toESM2(require("path"));
|
|
40556
40828
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
40557
40829
|
function getUpgradeLogPath() {
|
|
40558
40830
|
const home = os15.homedir();
|
|
40559
|
-
const dir =
|
|
40831
|
+
const dir = path15.join(home, ".adhdev");
|
|
40560
40832
|
fs8.mkdirSync(dir, { recursive: true });
|
|
40561
|
-
return
|
|
40833
|
+
return path15.join(dir, "daemon-upgrade.log");
|
|
40562
40834
|
}
|
|
40563
40835
|
function appendUpgradeLog(message) {
|
|
40564
40836
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -40591,14 +40863,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40591
40863
|
while (Date.now() - start < timeoutMs) {
|
|
40592
40864
|
try {
|
|
40593
40865
|
process.kill(pid, 0);
|
|
40594
|
-
await new Promise((
|
|
40866
|
+
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
40595
40867
|
} catch {
|
|
40596
40868
|
return;
|
|
40597
40869
|
}
|
|
40598
40870
|
}
|
|
40599
40871
|
}
|
|
40600
40872
|
function stopSessionHostProcesses(appName) {
|
|
40601
|
-
const pidFile =
|
|
40873
|
+
const pidFile = path15.join(os15.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
40602
40874
|
try {
|
|
40603
40875
|
if (fs8.existsSync(pidFile)) {
|
|
40604
40876
|
const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -40627,7 +40899,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40627
40899
|
}
|
|
40628
40900
|
}
|
|
40629
40901
|
function removeDaemonPidFile() {
|
|
40630
|
-
const pidFile =
|
|
40902
|
+
const pidFile = path15.join(os15.homedir(), ".adhdev", "daemon.pid");
|
|
40631
40903
|
try {
|
|
40632
40904
|
fs8.unlinkSync(pidFile);
|
|
40633
40905
|
} catch {
|
|
@@ -40638,7 +40910,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40638
40910
|
const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
40639
40911
|
if (!npmRoot) return;
|
|
40640
40912
|
const npmPrefix = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
40641
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
40913
|
+
const binDir = process.platform === "win32" ? npmPrefix : path15.join(npmPrefix, "bin");
|
|
40642
40914
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
40643
40915
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
40644
40916
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -40646,25 +40918,25 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40646
40918
|
}
|
|
40647
40919
|
if (pkgName.startsWith("@")) {
|
|
40648
40920
|
const [scope, name] = pkgName.split("/");
|
|
40649
|
-
const scopeDir =
|
|
40921
|
+
const scopeDir = path15.join(npmRoot, scope);
|
|
40650
40922
|
if (!fs8.existsSync(scopeDir)) return;
|
|
40651
40923
|
for (const entry of fs8.readdirSync(scopeDir)) {
|
|
40652
40924
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
40653
|
-
fs8.rmSync(
|
|
40654
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
40925
|
+
fs8.rmSync(path15.join(scopeDir, entry), { recursive: true, force: true });
|
|
40926
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path15.join(scopeDir, entry)}`);
|
|
40655
40927
|
}
|
|
40656
40928
|
} else {
|
|
40657
40929
|
for (const entry of fs8.readdirSync(npmRoot)) {
|
|
40658
40930
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
40659
|
-
fs8.rmSync(
|
|
40660
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
40931
|
+
fs8.rmSync(path15.join(npmRoot, entry), { recursive: true, force: true });
|
|
40932
|
+
appendUpgradeLog(`Removed stale staging dir: ${path15.join(npmRoot, entry)}`);
|
|
40661
40933
|
}
|
|
40662
40934
|
}
|
|
40663
40935
|
if (fs8.existsSync(binDir)) {
|
|
40664
40936
|
for (const entry of fs8.readdirSync(binDir)) {
|
|
40665
40937
|
if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
40666
|
-
fs8.rmSync(
|
|
40667
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
40938
|
+
fs8.rmSync(path15.join(binDir, entry), { recursive: true, force: true });
|
|
40939
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path15.join(binDir, entry)}`);
|
|
40668
40940
|
}
|
|
40669
40941
|
}
|
|
40670
40942
|
}
|
|
@@ -40706,7 +40978,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40706
40978
|
appendUpgradeLog(installOutput.trim());
|
|
40707
40979
|
}
|
|
40708
40980
|
if (process.platform === "win32") {
|
|
40709
|
-
await new Promise((
|
|
40981
|
+
await new Promise((resolve12) => setTimeout(resolve12, 500));
|
|
40710
40982
|
cleanupStaleGlobalInstallDirs(payload.packageName);
|
|
40711
40983
|
appendUpgradeLog("Post-install staging cleanup complete");
|
|
40712
40984
|
}
|
|
@@ -40748,6 +41020,25 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40748
41020
|
"change_model"
|
|
40749
41021
|
];
|
|
40750
41022
|
var READ_DEBUG_ENABLED2 = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
41023
|
+
function toHostedCliRuntimeDescriptor(record2) {
|
|
41024
|
+
if (!record2 || typeof record2 !== "object") return null;
|
|
41025
|
+
const runtimeId = typeof record2.sessionId === "string" ? record2.sessionId : "";
|
|
41026
|
+
const cliType = typeof record2.providerType === "string" ? record2.providerType : "";
|
|
41027
|
+
const workspace = typeof record2.workspace === "string" ? record2.workspace : "";
|
|
41028
|
+
if (!runtimeId || !cliType || !workspace) return null;
|
|
41029
|
+
return {
|
|
41030
|
+
runtimeId,
|
|
41031
|
+
runtimeKey: typeof record2.runtimeKey === "string" ? record2.runtimeKey : void 0,
|
|
41032
|
+
displayName: typeof record2.displayName === "string" ? record2.displayName : void 0,
|
|
41033
|
+
workspaceLabel: typeof record2.workspaceLabel === "string" ? record2.workspaceLabel : void 0,
|
|
41034
|
+
lifecycle: typeof record2.lifecycle === "string" ? record2.lifecycle : void 0,
|
|
41035
|
+
recoveryState: typeof record2.meta?.runtimeRecoveryState === "string" ? String(record2.meta.runtimeRecoveryState) : null,
|
|
41036
|
+
cliType,
|
|
41037
|
+
workspace,
|
|
41038
|
+
cliArgs: Array.isArray(record2.meta?.cliArgs) ? record2.meta.cliArgs : [],
|
|
41039
|
+
providerSessionId: typeof record2.meta?.providerSessionId === "string" ? String(record2.meta.providerSessionId) : void 0
|
|
41040
|
+
};
|
|
41041
|
+
}
|
|
40751
41042
|
var DaemonCommandRouter = class {
|
|
40752
41043
|
deps;
|
|
40753
41044
|
constructor(deps) {
|
|
@@ -40821,6 +41112,90 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40821
41112
|
return { success: false, error: e.message };
|
|
40822
41113
|
}
|
|
40823
41114
|
}
|
|
41115
|
+
case "session_host_get_diagnostics": {
|
|
41116
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41117
|
+
const diagnostics = await this.deps.sessionHostControl.getDiagnostics({
|
|
41118
|
+
includeSessions: args?.includeSessions !== false,
|
|
41119
|
+
limit: Number(args?.limit) || void 0
|
|
41120
|
+
});
|
|
41121
|
+
return { success: true, diagnostics };
|
|
41122
|
+
}
|
|
41123
|
+
case "session_host_list_sessions": {
|
|
41124
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41125
|
+
const sessions = await this.deps.sessionHostControl.listSessions();
|
|
41126
|
+
return { success: true, sessions };
|
|
41127
|
+
}
|
|
41128
|
+
case "session_host_stop_session": {
|
|
41129
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41130
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
41131
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
41132
|
+
const record2 = await this.deps.sessionHostControl.stopSession(sessionId);
|
|
41133
|
+
return { success: true, record: record2 };
|
|
41134
|
+
}
|
|
41135
|
+
case "session_host_resume_session": {
|
|
41136
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41137
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
41138
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
41139
|
+
const record2 = await this.deps.sessionHostControl.resumeSession(sessionId);
|
|
41140
|
+
const hosted = toHostedCliRuntimeDescriptor(record2);
|
|
41141
|
+
if (hosted) {
|
|
41142
|
+
await this.deps.cliManager.restoreHostedSessions([hosted]);
|
|
41143
|
+
}
|
|
41144
|
+
return { success: true, record: record2 };
|
|
41145
|
+
}
|
|
41146
|
+
case "session_host_restart_session": {
|
|
41147
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41148
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
41149
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
41150
|
+
const record2 = await this.deps.sessionHostControl.restartSession(sessionId);
|
|
41151
|
+
const hosted = toHostedCliRuntimeDescriptor(record2);
|
|
41152
|
+
if (hosted) {
|
|
41153
|
+
await this.deps.cliManager.restoreHostedSessions([hosted]);
|
|
41154
|
+
}
|
|
41155
|
+
return { success: true, record: record2 };
|
|
41156
|
+
}
|
|
41157
|
+
case "session_host_send_signal": {
|
|
41158
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41159
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
41160
|
+
const signal = typeof args?.signal === "string" ? args.signal : "";
|
|
41161
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
41162
|
+
if (!signal) return { success: false, error: "signal required" };
|
|
41163
|
+
const record2 = await this.deps.sessionHostControl.sendSignal(sessionId, signal);
|
|
41164
|
+
return { success: true, record: record2 };
|
|
41165
|
+
}
|
|
41166
|
+
case "session_host_force_detach_client": {
|
|
41167
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41168
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
41169
|
+
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
41170
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
41171
|
+
if (!clientId) return { success: false, error: "clientId required" };
|
|
41172
|
+
const record2 = await this.deps.sessionHostControl.forceDetachClient(sessionId, clientId);
|
|
41173
|
+
return { success: true, record: record2 };
|
|
41174
|
+
}
|
|
41175
|
+
case "session_host_acquire_write": {
|
|
41176
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41177
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
41178
|
+
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
41179
|
+
const ownerType = args?.ownerType === "agent" ? "agent" : "user";
|
|
41180
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
41181
|
+
if (!clientId) return { success: false, error: "clientId required" };
|
|
41182
|
+
const record2 = await this.deps.sessionHostControl.acquireWrite({
|
|
41183
|
+
sessionId,
|
|
41184
|
+
clientId,
|
|
41185
|
+
ownerType,
|
|
41186
|
+
force: args?.force !== false
|
|
41187
|
+
});
|
|
41188
|
+
return { success: true, record: record2 };
|
|
41189
|
+
}
|
|
41190
|
+
case "session_host_release_write": {
|
|
41191
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41192
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
41193
|
+
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
41194
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
41195
|
+
if (!clientId) return { success: false, error: "clientId required" };
|
|
41196
|
+
const record2 = await this.deps.sessionHostControl.releaseWrite({ sessionId, clientId });
|
|
41197
|
+
return { success: true, record: record2 };
|
|
41198
|
+
}
|
|
40824
41199
|
case "list_saved_sessions": {
|
|
40825
41200
|
const providerType = typeof args?.providerType === "string" ? args.providerType.trim() : typeof args?.agentType === "string" ? args.agentType.trim() : "";
|
|
40826
41201
|
const kind = args?.kind === "acp" ? "acp" : "cli";
|
|
@@ -40879,6 +41254,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40879
41254
|
if (!ideType) throw new Error("ideType required");
|
|
40880
41255
|
const killProcess = args?.killProcess !== false;
|
|
40881
41256
|
await this.stopIde(ideType, killProcess);
|
|
41257
|
+
try {
|
|
41258
|
+
const results = await detectIDEs(this.deps.providerLoader);
|
|
41259
|
+
this.deps.detectedIdes.value = results;
|
|
41260
|
+
this.deps.providerLoader.setIdeDetectionResults(results, true);
|
|
41261
|
+
} catch {
|
|
41262
|
+
}
|
|
40882
41263
|
return { success: true, ideType, stopped: true, processKilled: killProcess };
|
|
40883
41264
|
}
|
|
40884
41265
|
// ─── IDE restart ───
|
|
@@ -40921,6 +41302,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40921
41302
|
}
|
|
40922
41303
|
}
|
|
40923
41304
|
this.deps.onIdeConnected?.();
|
|
41305
|
+
try {
|
|
41306
|
+
const results = await detectIDEs(this.deps.providerLoader);
|
|
41307
|
+
this.deps.detectedIdes.value = results;
|
|
41308
|
+
this.deps.providerLoader.setIdeDetectionResults(results, true);
|
|
41309
|
+
} catch {
|
|
41310
|
+
}
|
|
40924
41311
|
if (result.success && resolvedWorkspace) {
|
|
40925
41312
|
try {
|
|
40926
41313
|
const next = appendRecentActivity(loadState(), {
|
|
@@ -40948,8 +41335,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
40948
41335
|
}
|
|
40949
41336
|
// ─── Detect IDEs ───
|
|
40950
41337
|
case "detect_ides": {
|
|
40951
|
-
const results = await detectIDEs();
|
|
41338
|
+
const results = await detectIDEs(this.deps.providerLoader);
|
|
40952
41339
|
this.deps.detectedIdes.value = results;
|
|
41340
|
+
this.deps.providerLoader.setIdeDetectionResults(results, true);
|
|
40953
41341
|
return { success: true, detectedInfo: results };
|
|
40954
41342
|
}
|
|
40955
41343
|
// ─── Set User Name ───
|
|
@@ -41341,6 +41729,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41341
41729
|
hasScript(name) {
|
|
41342
41730
|
return typeof this.provider.scripts?.[name] === "function";
|
|
41343
41731
|
}
|
|
41732
|
+
parseMaybeJson(raw) {
|
|
41733
|
+
if (typeof raw !== "string") return raw;
|
|
41734
|
+
try {
|
|
41735
|
+
return JSON.parse(raw);
|
|
41736
|
+
} catch {
|
|
41737
|
+
return raw;
|
|
41738
|
+
}
|
|
41739
|
+
}
|
|
41344
41740
|
summarizeRaw(raw) {
|
|
41345
41741
|
try {
|
|
41346
41742
|
if (typeof raw === "string") return raw.replace(/\s+/g, " ").trim().slice(0, 240);
|
|
@@ -41401,12 +41797,30 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41401
41797
|
}
|
|
41402
41798
|
}
|
|
41403
41799
|
async sendMessage(evaluate, text) {
|
|
41404
|
-
const
|
|
41800
|
+
const params = { message: text };
|
|
41801
|
+
const script = this.callScript("sendMessage", params) || this.callScript("sendMessage", text);
|
|
41405
41802
|
if (!script) throw new Error(`[${this.agentName}] sendMessage script not available`);
|
|
41406
41803
|
const result = await evaluate(script);
|
|
41407
41804
|
if (result && typeof result === "string" && result.startsWith("error:")) {
|
|
41408
41805
|
throw new Error(`[${this.agentName}] sendMessage failed: ${result}`);
|
|
41409
41806
|
}
|
|
41807
|
+
const parsed = this.parseMaybeJson(result);
|
|
41808
|
+
if (parsed === true) return;
|
|
41809
|
+
if (typeof parsed === "string") {
|
|
41810
|
+
const normalized = parsed.trim().toLowerCase();
|
|
41811
|
+
if (normalized === "ok" || normalized === "sent" || normalized === "success" || normalized === "true") {
|
|
41812
|
+
return;
|
|
41813
|
+
}
|
|
41814
|
+
}
|
|
41815
|
+
if (parsed && typeof parsed === "object") {
|
|
41816
|
+
if (parsed.sent === true || parsed.success === true || parsed.ok === true || parsed.submitted === true || parsed.dispatched === true) {
|
|
41817
|
+
return;
|
|
41818
|
+
}
|
|
41819
|
+
if (typeof parsed.error === "string" && parsed.error.trim()) {
|
|
41820
|
+
throw new Error(`[${this.agentName}] sendMessage failed: ${parsed.error}`);
|
|
41821
|
+
}
|
|
41822
|
+
}
|
|
41823
|
+
throw new Error(`[${this.agentName}] sendMessage was not confirmed`);
|
|
41410
41824
|
}
|
|
41411
41825
|
async resolveAction(evaluate, action, button) {
|
|
41412
41826
|
const script = this.callScript("resolveAction", { action, button });
|
|
@@ -41429,7 +41843,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41429
41843
|
const raw = await evaluate(script, 1e4);
|
|
41430
41844
|
const data = typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
41431
41845
|
if (data?.error) return [];
|
|
41432
|
-
|
|
41846
|
+
if (Array.isArray(data)) return data;
|
|
41847
|
+
if (Array.isArray(data?.sessions)) return data.sessions;
|
|
41848
|
+
if (Array.isArray(data?.chats)) return data.chats;
|
|
41849
|
+
return [];
|
|
41433
41850
|
} catch {
|
|
41434
41851
|
return [];
|
|
41435
41852
|
}
|
|
@@ -41437,7 +41854,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41437
41854
|
async switchSession(evaluate, sessionId) {
|
|
41438
41855
|
const script = this.callScript("switchSession", sessionId);
|
|
41439
41856
|
if (!script) return false;
|
|
41440
|
-
|
|
41857
|
+
const raw = await evaluate(script, 1e4);
|
|
41858
|
+
const data = this.parseMaybeJson(raw);
|
|
41859
|
+
if (data === true) return true;
|
|
41860
|
+
if (typeof data === "string") {
|
|
41861
|
+
const normalized = data.trim().toLowerCase();
|
|
41862
|
+
return normalized === "true" || normalized === "ok" || normalized === "switched" || normalized === "success";
|
|
41863
|
+
}
|
|
41864
|
+
if (data && typeof data === "object") {
|
|
41865
|
+
return data.switched === true || data.success === true || data.ok === true;
|
|
41866
|
+
}
|
|
41867
|
+
return false;
|
|
41441
41868
|
}
|
|
41442
41869
|
async focusEditor(evaluate) {
|
|
41443
41870
|
const script = this.callScript("focusEditor");
|
|
@@ -42117,11 +42544,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
42117
42544
|
}
|
|
42118
42545
|
};
|
|
42119
42546
|
var fs10 = __toESM2(require("fs"));
|
|
42120
|
-
var
|
|
42547
|
+
var path16 = __toESM2(require("path"));
|
|
42121
42548
|
var os16 = __toESM2(require("os"));
|
|
42122
42549
|
var import_child_process9 = require("child_process");
|
|
42123
42550
|
var import_os3 = require("os");
|
|
42124
|
-
var ARCHIVE_PATH =
|
|
42551
|
+
var ARCHIVE_PATH = path16.join(os16.homedir(), ".adhdev", "version-history.json");
|
|
42125
42552
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
42126
42553
|
var VersionArchive = class {
|
|
42127
42554
|
history = {};
|
|
@@ -42168,7 +42595,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
42168
42595
|
}
|
|
42169
42596
|
save() {
|
|
42170
42597
|
try {
|
|
42171
|
-
fs10.mkdirSync(
|
|
42598
|
+
fs10.mkdirSync(path16.dirname(ARCHIVE_PATH), { recursive: true });
|
|
42172
42599
|
fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
42173
42600
|
} catch {
|
|
42174
42601
|
}
|
|
@@ -42209,7 +42636,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
42209
42636
|
for (const p of paths) {
|
|
42210
42637
|
if (p.includes("*")) {
|
|
42211
42638
|
const home = os16.homedir();
|
|
42212
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
42639
|
+
const resolved = p.replace(/\*/g, home.split(path16.sep).pop() || "");
|
|
42213
42640
|
if (fs10.existsSync(resolved)) return resolved;
|
|
42214
42641
|
} else {
|
|
42215
42642
|
if (fs10.existsSync(p)) return p;
|
|
@@ -42219,7 +42646,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
42219
42646
|
}
|
|
42220
42647
|
function getMacAppVersion(appPath) {
|
|
42221
42648
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
42222
|
-
const plistPath =
|
|
42649
|
+
const plistPath = path16.join(appPath, "Contents", "Info.plist");
|
|
42223
42650
|
if (!fs10.existsSync(plistPath)) return null;
|
|
42224
42651
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
42225
42652
|
return raw || null;
|
|
@@ -42246,7 +42673,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
42246
42673
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
42247
42674
|
let resolvedBin = cliBin;
|
|
42248
42675
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
42249
|
-
const bundled =
|
|
42676
|
+
const bundled = path16.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
42250
42677
|
if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
|
|
42251
42678
|
}
|
|
42252
42679
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -42285,7 +42712,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
42285
42712
|
}
|
|
42286
42713
|
var http2 = __toESM2(require("http"));
|
|
42287
42714
|
var fs14 = __toESM2(require("fs"));
|
|
42288
|
-
var
|
|
42715
|
+
var path20 = __toESM2(require("path"));
|
|
42289
42716
|
function generateFiles(type, name, category, opts = {}) {
|
|
42290
42717
|
const { cdpPorts, cli, processName, installPath, binary, extensionId, version: version2 = "0.1" } = opts;
|
|
42291
42718
|
if (category === "cli" || category === "acp") {
|
|
@@ -42615,7 +43042,7 @@ async (params) => {
|
|
|
42615
43042
|
}
|
|
42616
43043
|
init_logger();
|
|
42617
43044
|
var fs11 = __toESM2(require("fs"));
|
|
42618
|
-
var
|
|
43045
|
+
var path17 = __toESM2(require("path"));
|
|
42619
43046
|
init_logger();
|
|
42620
43047
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
42621
43048
|
const body = await ctx.readBody(req);
|
|
@@ -42794,17 +43221,17 @@ async (params) => {
|
|
|
42794
43221
|
return;
|
|
42795
43222
|
}
|
|
42796
43223
|
let scriptsPath = "";
|
|
42797
|
-
const directScripts =
|
|
43224
|
+
const directScripts = path17.join(dir, "scripts.js");
|
|
42798
43225
|
if (fs11.existsSync(directScripts)) {
|
|
42799
43226
|
scriptsPath = directScripts;
|
|
42800
43227
|
} else {
|
|
42801
|
-
const scriptsDir =
|
|
43228
|
+
const scriptsDir = path17.join(dir, "scripts");
|
|
42802
43229
|
if (fs11.existsSync(scriptsDir)) {
|
|
42803
43230
|
const versions = fs11.readdirSync(scriptsDir).filter((d) => {
|
|
42804
|
-
return fs11.statSync(
|
|
43231
|
+
return fs11.statSync(path17.join(scriptsDir, d)).isDirectory();
|
|
42805
43232
|
}).sort().reverse();
|
|
42806
43233
|
for (const ver of versions) {
|
|
42807
|
-
const p =
|
|
43234
|
+
const p = path17.join(scriptsDir, ver, "scripts.js");
|
|
42808
43235
|
if (fs11.existsSync(p)) {
|
|
42809
43236
|
scriptsPath = p;
|
|
42810
43237
|
break;
|
|
@@ -43621,7 +44048,7 @@ async (params) => {
|
|
|
43621
44048
|
}
|
|
43622
44049
|
}
|
|
43623
44050
|
var fs12 = __toESM2(require("fs"));
|
|
43624
|
-
var
|
|
44051
|
+
var path18 = __toESM2(require("path"));
|
|
43625
44052
|
function slugifyFixtureName(value) {
|
|
43626
44053
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
43627
44054
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -43631,11 +44058,11 @@ async (params) => {
|
|
|
43631
44058
|
if (!providerDir) {
|
|
43632
44059
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
43633
44060
|
}
|
|
43634
|
-
return
|
|
44061
|
+
return path18.join(providerDir, "fixtures");
|
|
43635
44062
|
}
|
|
43636
44063
|
function readCliFixture(ctx, type, name) {
|
|
43637
44064
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43638
|
-
const filePath =
|
|
44065
|
+
const filePath = path18.join(fixtureDir, `${name}.json`);
|
|
43639
44066
|
if (!fs12.existsSync(filePath)) {
|
|
43640
44067
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
43641
44068
|
}
|
|
@@ -43795,7 +44222,7 @@ async (params) => {
|
|
|
43795
44222
|
return { target, instance, adapter };
|
|
43796
44223
|
}
|
|
43797
44224
|
function sleep(ms2) {
|
|
43798
|
-
return new Promise((
|
|
44225
|
+
return new Promise((resolve12) => setTimeout(resolve12, ms2));
|
|
43799
44226
|
}
|
|
43800
44227
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
43801
44228
|
const startedAt = Date.now();
|
|
@@ -44394,7 +44821,7 @@ async (params) => {
|
|
|
44394
44821
|
},
|
|
44395
44822
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
44396
44823
|
};
|
|
44397
|
-
const filePath =
|
|
44824
|
+
const filePath = path18.join(fixtureDir, `${name}.json`);
|
|
44398
44825
|
fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
44399
44826
|
ctx.json(res, 200, {
|
|
44400
44827
|
saved: true,
|
|
@@ -44418,7 +44845,7 @@ async (params) => {
|
|
|
44418
44845
|
return;
|
|
44419
44846
|
}
|
|
44420
44847
|
const fixtures = fs12.readdirSync(fixtureDir).filter((file2) => file2.endsWith(".json")).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file2) => {
|
|
44421
|
-
const fullPath =
|
|
44848
|
+
const fullPath = path18.join(fixtureDir, file2);
|
|
44422
44849
|
try {
|
|
44423
44850
|
const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
|
|
44424
44851
|
return {
|
|
@@ -44552,7 +44979,7 @@ async (params) => {
|
|
|
44552
44979
|
}
|
|
44553
44980
|
}
|
|
44554
44981
|
var fs13 = __toESM2(require("fs"));
|
|
44555
|
-
var
|
|
44982
|
+
var path19 = __toESM2(require("path"));
|
|
44556
44983
|
var os17 = __toESM2(require("os"));
|
|
44557
44984
|
function getAutoImplPid(ctx) {
|
|
44558
44985
|
const proc = ctx.autoImplProcess;
|
|
@@ -44592,22 +45019,22 @@ async (params) => {
|
|
|
44592
45019
|
if (!fs13.existsSync(scriptsDir)) return null;
|
|
44593
45020
|
const versions = fs13.readdirSync(scriptsDir).filter((d) => {
|
|
44594
45021
|
try {
|
|
44595
|
-
return fs13.statSync(
|
|
45022
|
+
return fs13.statSync(path19.join(scriptsDir, d)).isDirectory();
|
|
44596
45023
|
} catch {
|
|
44597
45024
|
return false;
|
|
44598
45025
|
}
|
|
44599
45026
|
}).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
44600
45027
|
if (versions.length === 0) return null;
|
|
44601
|
-
return
|
|
45028
|
+
return path19.join(scriptsDir, versions[0]);
|
|
44602
45029
|
}
|
|
44603
45030
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
44604
|
-
const canonicalUserDir =
|
|
44605
|
-
const desiredDir = requestedDir ?
|
|
44606
|
-
const upstreamRoot =
|
|
44607
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
45031
|
+
const canonicalUserDir = path19.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
45032
|
+
const desiredDir = requestedDir ? path19.resolve(requestedDir) : canonicalUserDir;
|
|
45033
|
+
const upstreamRoot = path19.resolve(ctx.providerLoader.getUpstreamDir());
|
|
45034
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path19.sep}`)) {
|
|
44608
45035
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
44609
45036
|
}
|
|
44610
|
-
if (
|
|
45037
|
+
if (path19.basename(desiredDir) !== type) {
|
|
44611
45038
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
44612
45039
|
}
|
|
44613
45040
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -44615,11 +45042,11 @@ async (params) => {
|
|
|
44615
45042
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
44616
45043
|
}
|
|
44617
45044
|
if (!fs13.existsSync(desiredDir)) {
|
|
44618
|
-
fs13.mkdirSync(
|
|
45045
|
+
fs13.mkdirSync(path19.dirname(desiredDir), { recursive: true });
|
|
44619
45046
|
fs13.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
44620
45047
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
44621
45048
|
}
|
|
44622
|
-
const providerJson =
|
|
45049
|
+
const providerJson = path19.join(desiredDir, "provider.json");
|
|
44623
45050
|
if (!fs13.existsSync(providerJson)) {
|
|
44624
45051
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
44625
45052
|
}
|
|
@@ -44642,13 +45069,13 @@ async (params) => {
|
|
|
44642
45069
|
const refDir = ctx.findProviderDir(referenceType);
|
|
44643
45070
|
if (!refDir || !fs13.existsSync(refDir)) return {};
|
|
44644
45071
|
const referenceScripts = {};
|
|
44645
|
-
const scriptsDir =
|
|
45072
|
+
const scriptsDir = path19.join(refDir, "scripts");
|
|
44646
45073
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
44647
45074
|
if (!latestDir) return referenceScripts;
|
|
44648
45075
|
for (const file2 of fs13.readdirSync(latestDir)) {
|
|
44649
45076
|
if (!file2.endsWith(".js")) continue;
|
|
44650
45077
|
try {
|
|
44651
|
-
referenceScripts[file2] = fs13.readFileSync(
|
|
45078
|
+
referenceScripts[file2] = fs13.readFileSync(path19.join(latestDir, file2), "utf-8");
|
|
44652
45079
|
} catch {
|
|
44653
45080
|
}
|
|
44654
45081
|
}
|
|
@@ -44756,9 +45183,9 @@ async (params) => {
|
|
|
44756
45183
|
});
|
|
44757
45184
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
44758
45185
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
44759
|
-
const tmpDir =
|
|
45186
|
+
const tmpDir = path19.join(os17.tmpdir(), "adhdev-autoimpl");
|
|
44760
45187
|
if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
|
|
44761
|
-
const promptFile =
|
|
45188
|
+
const promptFile = path19.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
44762
45189
|
fs13.writeFileSync(promptFile, prompt, "utf-8");
|
|
44763
45190
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
44764
45191
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -45185,7 +45612,7 @@ async (params) => {
|
|
|
45185
45612
|
setMode: "set_mode.js"
|
|
45186
45613
|
};
|
|
45187
45614
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
45188
|
-
const scriptsDir =
|
|
45615
|
+
const scriptsDir = path19.join(providerDir, "scripts");
|
|
45189
45616
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
45190
45617
|
if (latestScriptsDir) {
|
|
45191
45618
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -45196,7 +45623,7 @@ async (params) => {
|
|
|
45196
45623
|
for (const file2 of fs13.readdirSync(latestScriptsDir)) {
|
|
45197
45624
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
45198
45625
|
try {
|
|
45199
|
-
const content = fs13.readFileSync(
|
|
45626
|
+
const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
|
|
45200
45627
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
45201
45628
|
lines.push("```javascript");
|
|
45202
45629
|
lines.push(content);
|
|
@@ -45213,7 +45640,7 @@ async (params) => {
|
|
|
45213
45640
|
lines.push("");
|
|
45214
45641
|
for (const file2 of refFiles) {
|
|
45215
45642
|
try {
|
|
45216
|
-
const content = fs13.readFileSync(
|
|
45643
|
+
const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
|
|
45217
45644
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
45218
45645
|
lines.push("```javascript");
|
|
45219
45646
|
lines.push(content);
|
|
@@ -45254,10 +45681,10 @@ async (params) => {
|
|
|
45254
45681
|
lines.push("");
|
|
45255
45682
|
}
|
|
45256
45683
|
}
|
|
45257
|
-
const docsDir =
|
|
45684
|
+
const docsDir = path19.join(providerDir, "../../docs");
|
|
45258
45685
|
const loadGuide = (name) => {
|
|
45259
45686
|
try {
|
|
45260
|
-
const p =
|
|
45687
|
+
const p = path19.join(docsDir, name);
|
|
45261
45688
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
45262
45689
|
} catch {
|
|
45263
45690
|
}
|
|
@@ -45492,7 +45919,7 @@ async (params) => {
|
|
|
45492
45919
|
parseApproval: "parse_approval.js"
|
|
45493
45920
|
};
|
|
45494
45921
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
45495
|
-
const scriptsDir =
|
|
45922
|
+
const scriptsDir = path19.join(providerDir, "scripts");
|
|
45496
45923
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
45497
45924
|
if (latestScriptsDir) {
|
|
45498
45925
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -45504,7 +45931,7 @@ async (params) => {
|
|
|
45504
45931
|
if (!file2.endsWith(".js")) continue;
|
|
45505
45932
|
if (!targetFileNames.has(file2)) continue;
|
|
45506
45933
|
try {
|
|
45507
|
-
const content = fs13.readFileSync(
|
|
45934
|
+
const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
|
|
45508
45935
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
45509
45936
|
lines.push("```javascript");
|
|
45510
45937
|
lines.push(content);
|
|
@@ -45520,7 +45947,7 @@ async (params) => {
|
|
|
45520
45947
|
lines.push("");
|
|
45521
45948
|
for (const file2 of refFiles) {
|
|
45522
45949
|
try {
|
|
45523
|
-
const content = fs13.readFileSync(
|
|
45950
|
+
const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
|
|
45524
45951
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
45525
45952
|
lines.push("```javascript");
|
|
45526
45953
|
lines.push(content);
|
|
@@ -45553,10 +45980,10 @@ async (params) => {
|
|
|
45553
45980
|
lines.push("");
|
|
45554
45981
|
}
|
|
45555
45982
|
}
|
|
45556
|
-
const docsDir =
|
|
45983
|
+
const docsDir = path19.join(providerDir, "../../docs");
|
|
45557
45984
|
const loadGuide = (name) => {
|
|
45558
45985
|
try {
|
|
45559
|
-
const p =
|
|
45986
|
+
const p = path19.join(docsDir, name);
|
|
45560
45987
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
45561
45988
|
} catch {
|
|
45562
45989
|
}
|
|
@@ -45965,8 +46392,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
45965
46392
|
}
|
|
45966
46393
|
getEndpointList() {
|
|
45967
46394
|
return this.routes.map((r) => {
|
|
45968
|
-
const
|
|
45969
|
-
return `${r.method.padEnd(5)} ${
|
|
46395
|
+
const path21 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
46396
|
+
return `${r.method.padEnd(5)} ${path21}`;
|
|
45970
46397
|
});
|
|
45971
46398
|
}
|
|
45972
46399
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -45997,15 +46424,15 @@ data: ${JSON.stringify(msg.data)}
|
|
|
45997
46424
|
this.json(res, 500, { error: e.message });
|
|
45998
46425
|
}
|
|
45999
46426
|
});
|
|
46000
|
-
return new Promise((
|
|
46427
|
+
return new Promise((resolve12, reject) => {
|
|
46001
46428
|
this.server.listen(port, "127.0.0.1", () => {
|
|
46002
46429
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
46003
|
-
|
|
46430
|
+
resolve12();
|
|
46004
46431
|
});
|
|
46005
46432
|
this.server.on("error", (e) => {
|
|
46006
46433
|
if (e.code === "EADDRINUSE") {
|
|
46007
46434
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
46008
|
-
|
|
46435
|
+
resolve12();
|
|
46009
46436
|
} else {
|
|
46010
46437
|
reject(e);
|
|
46011
46438
|
}
|
|
@@ -46088,20 +46515,20 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46088
46515
|
child.stderr?.on("data", (d) => {
|
|
46089
46516
|
stderr += d.toString().slice(0, 2e3);
|
|
46090
46517
|
});
|
|
46091
|
-
await new Promise((
|
|
46518
|
+
await new Promise((resolve12) => {
|
|
46092
46519
|
const timer = setTimeout(() => {
|
|
46093
46520
|
child.kill();
|
|
46094
|
-
|
|
46521
|
+
resolve12();
|
|
46095
46522
|
}, 3e3);
|
|
46096
46523
|
child.on("exit", () => {
|
|
46097
46524
|
clearTimeout(timer);
|
|
46098
|
-
|
|
46525
|
+
resolve12();
|
|
46099
46526
|
});
|
|
46100
46527
|
child.stdout?.once("data", () => {
|
|
46101
46528
|
setTimeout(() => {
|
|
46102
46529
|
child.kill();
|
|
46103
46530
|
clearTimeout(timer);
|
|
46104
|
-
|
|
46531
|
+
resolve12();
|
|
46105
46532
|
}, 500);
|
|
46106
46533
|
});
|
|
46107
46534
|
});
|
|
@@ -46248,12 +46675,12 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46248
46675
|
// ─── DevConsole SPA ───
|
|
46249
46676
|
getConsoleDistDir() {
|
|
46250
46677
|
const candidates = [
|
|
46251
|
-
|
|
46252
|
-
|
|
46253
|
-
|
|
46678
|
+
path20.resolve(__dirname, "../../web-devconsole/dist"),
|
|
46679
|
+
path20.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
46680
|
+
path20.join(process.cwd(), "packages/web-devconsole/dist")
|
|
46254
46681
|
];
|
|
46255
46682
|
for (const dir of candidates) {
|
|
46256
|
-
if (fs14.existsSync(
|
|
46683
|
+
if (fs14.existsSync(path20.join(dir, "index.html"))) return dir;
|
|
46257
46684
|
}
|
|
46258
46685
|
return null;
|
|
46259
46686
|
}
|
|
@@ -46263,7 +46690,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46263
46690
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
46264
46691
|
return;
|
|
46265
46692
|
}
|
|
46266
|
-
const htmlPath =
|
|
46693
|
+
const htmlPath = path20.join(distDir, "index.html");
|
|
46267
46694
|
try {
|
|
46268
46695
|
const html = fs14.readFileSync(htmlPath, "utf-8");
|
|
46269
46696
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -46288,15 +46715,15 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46288
46715
|
this.json(res, 404, { error: "Not found" });
|
|
46289
46716
|
return;
|
|
46290
46717
|
}
|
|
46291
|
-
const safePath =
|
|
46292
|
-
const filePath =
|
|
46718
|
+
const safePath = path20.normalize(pathname).replace(/^\.\.\//, "");
|
|
46719
|
+
const filePath = path20.join(distDir, safePath);
|
|
46293
46720
|
if (!filePath.startsWith(distDir)) {
|
|
46294
46721
|
this.json(res, 403, { error: "Forbidden" });
|
|
46295
46722
|
return;
|
|
46296
46723
|
}
|
|
46297
46724
|
try {
|
|
46298
46725
|
const content = fs14.readFileSync(filePath);
|
|
46299
|
-
const ext =
|
|
46726
|
+
const ext = path20.extname(filePath);
|
|
46300
46727
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
46301
46728
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
46302
46729
|
res.end(content);
|
|
@@ -46409,9 +46836,9 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46409
46836
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
46410
46837
|
if (entry.isDirectory()) {
|
|
46411
46838
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
46412
|
-
scan(
|
|
46839
|
+
scan(path20.join(d, entry.name), rel);
|
|
46413
46840
|
} else {
|
|
46414
|
-
const stat4 = fs14.statSync(
|
|
46841
|
+
const stat4 = fs14.statSync(path20.join(d, entry.name));
|
|
46415
46842
|
files.push({ path: rel, size: stat4.size, type: "file" });
|
|
46416
46843
|
}
|
|
46417
46844
|
}
|
|
@@ -46434,7 +46861,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46434
46861
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
46435
46862
|
return;
|
|
46436
46863
|
}
|
|
46437
|
-
const fullPath =
|
|
46864
|
+
const fullPath = path20.resolve(dir, path20.normalize(filePath));
|
|
46438
46865
|
if (!fullPath.startsWith(dir)) {
|
|
46439
46866
|
this.json(res, 403, { error: "Forbidden" });
|
|
46440
46867
|
return;
|
|
@@ -46459,14 +46886,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46459
46886
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
46460
46887
|
return;
|
|
46461
46888
|
}
|
|
46462
|
-
const fullPath =
|
|
46889
|
+
const fullPath = path20.resolve(dir, path20.normalize(filePath));
|
|
46463
46890
|
if (!fullPath.startsWith(dir)) {
|
|
46464
46891
|
this.json(res, 403, { error: "Forbidden" });
|
|
46465
46892
|
return;
|
|
46466
46893
|
}
|
|
46467
46894
|
try {
|
|
46468
46895
|
if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
|
|
46469
|
-
fs14.mkdirSync(
|
|
46896
|
+
fs14.mkdirSync(path20.dirname(fullPath), { recursive: true });
|
|
46470
46897
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
46471
46898
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
46472
46899
|
this.providerLoader.reload();
|
|
@@ -46483,7 +46910,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46483
46910
|
return;
|
|
46484
46911
|
}
|
|
46485
46912
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
46486
|
-
const p =
|
|
46913
|
+
const p = path20.join(dir, name);
|
|
46487
46914
|
if (fs14.existsSync(p)) {
|
|
46488
46915
|
const source = fs14.readFileSync(p, "utf-8");
|
|
46489
46916
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -46504,8 +46931,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46504
46931
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
46505
46932
|
return;
|
|
46506
46933
|
}
|
|
46507
|
-
const target = fs14.existsSync(
|
|
46508
|
-
const targetPath =
|
|
46934
|
+
const target = fs14.existsSync(path20.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
46935
|
+
const targetPath = path20.join(dir, target);
|
|
46509
46936
|
try {
|
|
46510
46937
|
if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
|
|
46511
46938
|
fs14.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -46610,14 +47037,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46610
47037
|
child.stderr?.on("data", (d) => {
|
|
46611
47038
|
stderr += d.toString();
|
|
46612
47039
|
});
|
|
46613
|
-
await new Promise((
|
|
47040
|
+
await new Promise((resolve12) => {
|
|
46614
47041
|
const timer = setTimeout(() => {
|
|
46615
47042
|
child.kill();
|
|
46616
|
-
|
|
47043
|
+
resolve12();
|
|
46617
47044
|
}, timeout);
|
|
46618
47045
|
child.on("exit", () => {
|
|
46619
47046
|
clearTimeout(timer);
|
|
46620
|
-
|
|
47047
|
+
resolve12();
|
|
46621
47048
|
});
|
|
46622
47049
|
});
|
|
46623
47050
|
const elapsed = Date.now() - start;
|
|
@@ -46665,7 +47092,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46665
47092
|
}
|
|
46666
47093
|
let targetDir;
|
|
46667
47094
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
46668
|
-
const jsonPath =
|
|
47095
|
+
const jsonPath = path20.join(targetDir, "provider.json");
|
|
46669
47096
|
if (fs14.existsSync(jsonPath)) {
|
|
46670
47097
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
46671
47098
|
return;
|
|
@@ -46677,8 +47104,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46677
47104
|
const createdFiles = ["provider.json"];
|
|
46678
47105
|
if (result.files) {
|
|
46679
47106
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
46680
|
-
const fullPath =
|
|
46681
|
-
fs14.mkdirSync(
|
|
47107
|
+
const fullPath = path20.join(targetDir, relPath);
|
|
47108
|
+
fs14.mkdirSync(path20.dirname(fullPath), { recursive: true });
|
|
46682
47109
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
46683
47110
|
createdFiles.push(relPath);
|
|
46684
47111
|
}
|
|
@@ -46731,22 +47158,22 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46731
47158
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
46732
47159
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
46733
47160
|
try {
|
|
46734
|
-
return fs14.statSync(
|
|
47161
|
+
return fs14.statSync(path20.join(scriptsDir, d)).isDirectory();
|
|
46735
47162
|
} catch {
|
|
46736
47163
|
return false;
|
|
46737
47164
|
}
|
|
46738
47165
|
}).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
46739
47166
|
if (versions.length === 0) return null;
|
|
46740
|
-
return
|
|
47167
|
+
return path20.join(scriptsDir, versions[0]);
|
|
46741
47168
|
}
|
|
46742
47169
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
46743
|
-
const canonicalUserDir =
|
|
46744
|
-
const desiredDir = requestedDir ?
|
|
46745
|
-
const upstreamRoot =
|
|
46746
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
47170
|
+
const canonicalUserDir = path20.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
47171
|
+
const desiredDir = requestedDir ? path20.resolve(requestedDir) : canonicalUserDir;
|
|
47172
|
+
const upstreamRoot = path20.resolve(this.providerLoader.getUpstreamDir());
|
|
47173
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path20.sep}`)) {
|
|
46747
47174
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
46748
47175
|
}
|
|
46749
|
-
if (
|
|
47176
|
+
if (path20.basename(desiredDir) !== type) {
|
|
46750
47177
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
46751
47178
|
}
|
|
46752
47179
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -46754,11 +47181,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46754
47181
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
46755
47182
|
}
|
|
46756
47183
|
if (!fs14.existsSync(desiredDir)) {
|
|
46757
|
-
fs14.mkdirSync(
|
|
47184
|
+
fs14.mkdirSync(path20.dirname(desiredDir), { recursive: true });
|
|
46758
47185
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
46759
47186
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
46760
47187
|
}
|
|
46761
|
-
const providerJson =
|
|
47188
|
+
const providerJson = path20.join(desiredDir, "provider.json");
|
|
46762
47189
|
if (!fs14.existsSync(providerJson)) {
|
|
46763
47190
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
46764
47191
|
}
|
|
@@ -46806,7 +47233,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46806
47233
|
setMode: "set_mode.js"
|
|
46807
47234
|
};
|
|
46808
47235
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
46809
|
-
const scriptsDir =
|
|
47236
|
+
const scriptsDir = path20.join(providerDir, "scripts");
|
|
46810
47237
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
46811
47238
|
if (latestScriptsDir) {
|
|
46812
47239
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -46817,7 +47244,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46817
47244
|
for (const file2 of fs14.readdirSync(latestScriptsDir)) {
|
|
46818
47245
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
46819
47246
|
try {
|
|
46820
|
-
const content = fs14.readFileSync(
|
|
47247
|
+
const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
|
|
46821
47248
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
46822
47249
|
lines.push("```javascript");
|
|
46823
47250
|
lines.push(content);
|
|
@@ -46834,7 +47261,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46834
47261
|
lines.push("");
|
|
46835
47262
|
for (const file2 of refFiles) {
|
|
46836
47263
|
try {
|
|
46837
|
-
const content = fs14.readFileSync(
|
|
47264
|
+
const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
|
|
46838
47265
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
46839
47266
|
lines.push("```javascript");
|
|
46840
47267
|
lines.push(content);
|
|
@@ -46875,10 +47302,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
46875
47302
|
lines.push("");
|
|
46876
47303
|
}
|
|
46877
47304
|
}
|
|
46878
|
-
const docsDir =
|
|
47305
|
+
const docsDir = path20.join(providerDir, "../../docs");
|
|
46879
47306
|
const loadGuide = (name) => {
|
|
46880
47307
|
try {
|
|
46881
|
-
const p =
|
|
47308
|
+
const p = path20.join(docsDir, name);
|
|
46882
47309
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
46883
47310
|
} catch {
|
|
46884
47311
|
}
|
|
@@ -47052,7 +47479,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47052
47479
|
parseApproval: "parse_approval.js"
|
|
47053
47480
|
};
|
|
47054
47481
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
47055
|
-
const scriptsDir =
|
|
47482
|
+
const scriptsDir = path20.join(providerDir, "scripts");
|
|
47056
47483
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
47057
47484
|
if (latestScriptsDir) {
|
|
47058
47485
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -47064,7 +47491,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47064
47491
|
if (!file2.endsWith(".js")) continue;
|
|
47065
47492
|
if (!targetFileNames.has(file2)) continue;
|
|
47066
47493
|
try {
|
|
47067
|
-
const content = fs14.readFileSync(
|
|
47494
|
+
const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
|
|
47068
47495
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
47069
47496
|
lines.push("```javascript");
|
|
47070
47497
|
lines.push(content);
|
|
@@ -47080,7 +47507,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47080
47507
|
lines.push("");
|
|
47081
47508
|
for (const file2 of refFiles) {
|
|
47082
47509
|
try {
|
|
47083
|
-
const content = fs14.readFileSync(
|
|
47510
|
+
const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
|
|
47084
47511
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
47085
47512
|
lines.push("```javascript");
|
|
47086
47513
|
lines.push(content);
|
|
@@ -47113,10 +47540,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47113
47540
|
lines.push("");
|
|
47114
47541
|
}
|
|
47115
47542
|
}
|
|
47116
|
-
const docsDir =
|
|
47543
|
+
const docsDir = path20.join(providerDir, "../../docs");
|
|
47117
47544
|
const loadGuide = (name) => {
|
|
47118
47545
|
try {
|
|
47119
|
-
const p =
|
|
47546
|
+
const p = path20.join(docsDir, name);
|
|
47120
47547
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
47121
47548
|
} catch {
|
|
47122
47549
|
}
|
|
@@ -47292,14 +47719,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47292
47719
|
res.end(JSON.stringify(data, null, 2));
|
|
47293
47720
|
}
|
|
47294
47721
|
async readBody(req) {
|
|
47295
|
-
return new Promise((
|
|
47722
|
+
return new Promise((resolve12) => {
|
|
47296
47723
|
let body = "";
|
|
47297
47724
|
req.on("data", (chunk) => body += chunk);
|
|
47298
47725
|
req.on("end", () => {
|
|
47299
47726
|
try {
|
|
47300
|
-
|
|
47727
|
+
resolve12(JSON.parse(body));
|
|
47301
47728
|
} catch {
|
|
47302
|
-
|
|
47729
|
+
resolve12({});
|
|
47303
47730
|
}
|
|
47304
47731
|
});
|
|
47305
47732
|
});
|
|
@@ -47629,6 +48056,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47629
48056
|
}
|
|
47630
48057
|
}
|
|
47631
48058
|
handleEvent(event) {
|
|
48059
|
+
if (!("sessionId" in event)) return;
|
|
47632
48060
|
if (event.sessionId !== this.options.runtimeId) return;
|
|
47633
48061
|
if ((event.type === "session_started" || event.type === "session_resumed") && typeof event.pid === "number") {
|
|
47634
48062
|
this.currentPid = event.pid;
|
|
@@ -47704,7 +48132,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47704
48132
|
clientId: client.clientId,
|
|
47705
48133
|
type: client.type,
|
|
47706
48134
|
readOnly: client.readOnly
|
|
47707
|
-
}))
|
|
48135
|
+
})),
|
|
48136
|
+
restoredFromStorage: record2.meta?.restoredFromStorage === true,
|
|
48137
|
+
recoveryState: typeof record2.meta?.runtimeRecoveryState === "string" ? String(record2.meta.runtimeRecoveryState) : null,
|
|
48138
|
+
recoveryError: typeof record2.meta?.runtimeRecoveryError === "string" ? String(record2.meta.runtimeRecoveryError) : null
|
|
47708
48139
|
};
|
|
47709
48140
|
}
|
|
47710
48141
|
enqueue(action) {
|
|
@@ -47740,11 +48171,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47740
48171
|
});
|
|
47741
48172
|
}
|
|
47742
48173
|
};
|
|
47743
|
-
var
|
|
48174
|
+
var import_session_host_core32 = require_dist();
|
|
47744
48175
|
var STARTUP_TIMEOUT_MS = 8e3;
|
|
47745
48176
|
var STARTUP_POLL_MS = 200;
|
|
47746
48177
|
async function canConnect(endpoint) {
|
|
47747
|
-
const client = new
|
|
48178
|
+
const client = new import_session_host_core32.SessionHostClient({ endpoint });
|
|
47748
48179
|
try {
|
|
47749
48180
|
await client.connect();
|
|
47750
48181
|
await client.close();
|
|
@@ -47757,19 +48188,19 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47757
48188
|
const deadline = Date.now() + timeoutMs;
|
|
47758
48189
|
while (Date.now() < deadline) {
|
|
47759
48190
|
if (await canConnect(endpoint)) return;
|
|
47760
|
-
await new Promise((
|
|
48191
|
+
await new Promise((resolve12) => setTimeout(resolve12, STARTUP_POLL_MS));
|
|
47761
48192
|
}
|
|
47762
48193
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
47763
48194
|
}
|
|
47764
48195
|
async function ensureSessionHostReady2(options) {
|
|
47765
|
-
const endpoint = (0,
|
|
48196
|
+
const endpoint = (0, import_session_host_core32.getDefaultSessionHostEndpoint)(options.appName || "adhdev");
|
|
47766
48197
|
if (await canConnect(endpoint)) return endpoint;
|
|
47767
48198
|
options.spawnHost();
|
|
47768
48199
|
await waitForReady(endpoint, options.timeoutMs);
|
|
47769
48200
|
return endpoint;
|
|
47770
48201
|
}
|
|
47771
48202
|
async function listHostedCliRuntimes2(endpoint) {
|
|
47772
|
-
const client = new
|
|
48203
|
+
const client = new import_session_host_core32.SessionHostClient({ endpoint });
|
|
47773
48204
|
try {
|
|
47774
48205
|
const response = await client.request({
|
|
47775
48206
|
type: "list_sessions",
|
|
@@ -47911,10 +48342,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47911
48342
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
47912
48343
|
const fs15 = await import("fs");
|
|
47913
48344
|
fs15.writeFileSync(vsixPath, buffer);
|
|
47914
|
-
return new Promise((
|
|
48345
|
+
return new Promise((resolve12) => {
|
|
47915
48346
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
47916
48347
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
|
|
47917
|
-
|
|
48348
|
+
resolve12({
|
|
47918
48349
|
extensionId: extension.id,
|
|
47919
48350
|
marketplaceId: extension.marketplaceId,
|
|
47920
48351
|
success: !error48,
|
|
@@ -47927,11 +48358,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47927
48358
|
} catch (e) {
|
|
47928
48359
|
}
|
|
47929
48360
|
}
|
|
47930
|
-
return new Promise((
|
|
48361
|
+
return new Promise((resolve12) => {
|
|
47931
48362
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
47932
48363
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
|
|
47933
48364
|
if (error48) {
|
|
47934
|
-
|
|
48365
|
+
resolve12({
|
|
47935
48366
|
extensionId: extension.id,
|
|
47936
48367
|
marketplaceId: extension.marketplaceId,
|
|
47937
48368
|
success: false,
|
|
@@ -47939,7 +48370,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
47939
48370
|
error: stderr || error48.message
|
|
47940
48371
|
});
|
|
47941
48372
|
} else {
|
|
47942
|
-
|
|
48373
|
+
resolve12({
|
|
47943
48374
|
extensionId: extension.id,
|
|
47944
48375
|
marketplaceId: extension.marketplaceId,
|
|
47945
48376
|
success: true,
|
|
@@ -48071,13 +48502,32 @@ data: ${JSON.stringify(msg.data)}
|
|
|
48071
48502
|
const detectedIdesRef = { value: [] };
|
|
48072
48503
|
let agentStreamManager = null;
|
|
48073
48504
|
let poller = null;
|
|
48505
|
+
const refreshProviderAvailability = async (providerType) => {
|
|
48506
|
+
const targetProvider = providerType ? providerLoader.getMeta(providerLoader.resolveAlias(providerType)) : null;
|
|
48507
|
+
const targetCategory = targetProvider?.category;
|
|
48508
|
+
if (!providerType || targetCategory === "cli" || targetCategory === "acp") {
|
|
48509
|
+
if (providerType && targetProvider) {
|
|
48510
|
+
const detected = await detectCLI(targetProvider.type, providerLoader, { includeVersion: false });
|
|
48511
|
+
providerLoader.setProviderAvailability(targetProvider.type, {
|
|
48512
|
+
installed: !!detected,
|
|
48513
|
+
detectedPath: detected?.path || null
|
|
48514
|
+
});
|
|
48515
|
+
} else {
|
|
48516
|
+
providerLoader.setCliDetectionResults(await detectCLIs(providerLoader, { includeVersion: false }), true);
|
|
48517
|
+
}
|
|
48518
|
+
}
|
|
48519
|
+
if (!providerType || targetCategory === "ide") {
|
|
48520
|
+
detectedIdesRef.value = await detectIDEs(providerLoader);
|
|
48521
|
+
providerLoader.setIdeDetectionResults(detectedIdesRef.value, true);
|
|
48522
|
+
}
|
|
48523
|
+
};
|
|
48074
48524
|
const cliManager = new DaemonCliManager({
|
|
48075
48525
|
...config2.cliManagerDeps,
|
|
48076
48526
|
getInstanceManager: () => instanceManager,
|
|
48077
48527
|
getSessionRegistry: () => sessionRegistry
|
|
48078
48528
|
}, providerLoader);
|
|
48079
48529
|
LOG2.info("Init", "Detecting IDEs...");
|
|
48080
|
-
|
|
48530
|
+
await refreshProviderAvailability();
|
|
48081
48531
|
const installed = detectedIdesRef.value.filter((i) => i.installed);
|
|
48082
48532
|
LOG2.info("Init", `Found ${installed.length} IDE(s): ${installed.map((i) => i.id).join(", ") || "none"}`);
|
|
48083
48533
|
const cdpSetupContext = {
|
|
@@ -48117,7 +48567,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
48117
48567
|
adapters: cliManager.adapters,
|
|
48118
48568
|
providerLoader,
|
|
48119
48569
|
instanceManager,
|
|
48120
|
-
sessionRegistry
|
|
48570
|
+
sessionRegistry,
|
|
48571
|
+
onProviderSettingChanged: async (providerType) => {
|
|
48572
|
+
await refreshProviderAvailability(providerType);
|
|
48573
|
+
config2.onStatusChange?.();
|
|
48574
|
+
}
|
|
48121
48575
|
});
|
|
48122
48576
|
agentStreamManager = new DaemonAgentStreamManager(
|
|
48123
48577
|
LOG2.forComponent("AgentStream").asLogFn(),
|
|
@@ -48140,6 +48594,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
48140
48594
|
onIdeConnected: () => poller?.start(),
|
|
48141
48595
|
onStatusChange: config2.onStatusChange,
|
|
48142
48596
|
onPostChatCommand: config2.onPostChatCommand,
|
|
48597
|
+
sessionHostControl: config2.sessionHostControl,
|
|
48143
48598
|
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG2.forComponent(`CDP:${ideType}`).asLogFn())
|
|
48144
48599
|
});
|
|
48145
48600
|
poller = new AgentStreamPoller({
|
|
@@ -48514,6 +48969,58 @@ var SessionHostClient = class {
|
|
|
48514
48969
|
}
|
|
48515
48970
|
};
|
|
48516
48971
|
|
|
48972
|
+
// src/session-host-control.ts
|
|
48973
|
+
var StandaloneSessionHostControlPlane = class {
|
|
48974
|
+
constructor(getEndpoint) {
|
|
48975
|
+
this.getEndpoint = getEndpoint;
|
|
48976
|
+
}
|
|
48977
|
+
async getDiagnostics(payload = {}) {
|
|
48978
|
+
return this.request("get_host_diagnostics", payload);
|
|
48979
|
+
}
|
|
48980
|
+
async listSessions() {
|
|
48981
|
+
return this.request("list_sessions", {});
|
|
48982
|
+
}
|
|
48983
|
+
async stopSession(sessionId) {
|
|
48984
|
+
return this.request("stop_session", { sessionId });
|
|
48985
|
+
}
|
|
48986
|
+
async resumeSession(sessionId) {
|
|
48987
|
+
return this.request("resume_session", { sessionId });
|
|
48988
|
+
}
|
|
48989
|
+
async restartSession(sessionId) {
|
|
48990
|
+
return this.request("restart_session", { sessionId });
|
|
48991
|
+
}
|
|
48992
|
+
async sendSignal(sessionId, signal) {
|
|
48993
|
+
return this.request("send_signal", { sessionId, signal });
|
|
48994
|
+
}
|
|
48995
|
+
async forceDetachClient(sessionId, clientId) {
|
|
48996
|
+
return this.request("force_detach_client", { sessionId, clientId });
|
|
48997
|
+
}
|
|
48998
|
+
async acquireWrite(payload) {
|
|
48999
|
+
return this.request("acquire_write", payload);
|
|
49000
|
+
}
|
|
49001
|
+
async releaseWrite(payload) {
|
|
49002
|
+
return this.request("release_write", payload);
|
|
49003
|
+
}
|
|
49004
|
+
async request(type, payload) {
|
|
49005
|
+
const endpoint = await this.getEndpoint();
|
|
49006
|
+
const client = new SessionHostClient({ endpoint });
|
|
49007
|
+
try {
|
|
49008
|
+
await client.connect();
|
|
49009
|
+
const response = await client.request({
|
|
49010
|
+
type,
|
|
49011
|
+
payload
|
|
49012
|
+
});
|
|
49013
|
+
if (!response.success) {
|
|
49014
|
+
throw new Error(response.error || `Session host request failed: ${type}`);
|
|
49015
|
+
}
|
|
49016
|
+
return response.result ?? null;
|
|
49017
|
+
} finally {
|
|
49018
|
+
await client.close().catch(() => {
|
|
49019
|
+
});
|
|
49020
|
+
}
|
|
49021
|
+
}
|
|
49022
|
+
};
|
|
49023
|
+
|
|
48517
49024
|
// ../terminal-mux-control/dist/chunk-7RNMRPVZ.mjs
|
|
48518
49025
|
var import_os = __toESM(require("os"), 1);
|
|
48519
49026
|
var import_path = __toESM(require("path"), 1);
|
|
@@ -48773,6 +49280,9 @@ var StandaloneServer = class {
|
|
|
48773
49280
|
const host = options.host || "127.0.0.1";
|
|
48774
49281
|
const sessionHostEndpoint = await ensureSessionHostReady();
|
|
48775
49282
|
this.sessionHostEndpoint = sessionHostEndpoint;
|
|
49283
|
+
const sessionHostControl = new StandaloneSessionHostControlPlane(
|
|
49284
|
+
async () => this.ensureActiveSessionHostEndpoint()
|
|
49285
|
+
);
|
|
48776
49286
|
this.authToken = options.token || process.env.ADHDEV_TOKEN || null;
|
|
48777
49287
|
this.components = await (0, import_daemon_core2.initDaemonComponents)({
|
|
48778
49288
|
cliManagerDeps: {
|
|
@@ -48811,6 +49321,7 @@ var StandaloneServer = class {
|
|
|
48811
49321
|
listHostedCliRuntimes: async () => listHostedCliRuntimes(sessionHostEndpoint)
|
|
48812
49322
|
},
|
|
48813
49323
|
onStatusChange: () => this.scheduleBroadcastStatus(),
|
|
49324
|
+
sessionHostControl,
|
|
48814
49325
|
onStreamsUpdated: (ideType, streams) => {
|
|
48815
49326
|
if (!this.components) return;
|
|
48816
49327
|
(0, import_daemon_core2.forwardAgentStreamsToIdeInstance)(this.components.instanceManager, ideType, streams);
|
|
@@ -49149,6 +49660,7 @@ var StandaloneServer = class {
|
|
|
49149
49660
|
`);
|
|
49150
49661
|
}
|
|
49151
49662
|
const writeEvent = (event) => {
|
|
49663
|
+
if (!("sessionId" in event)) return;
|
|
49152
49664
|
if (event.sessionId !== sessionId) return;
|
|
49153
49665
|
if (!this.isCliSession(sessionId)) return;
|
|
49154
49666
|
res.write(`event: ${event.type}
|
|
@@ -49301,7 +49813,7 @@ var StandaloneServer = class {
|
|
|
49301
49813
|
return { success: false, error: "command type required" };
|
|
49302
49814
|
}
|
|
49303
49815
|
const result = await this.components.router.execute(type, args, "standalone");
|
|
49304
|
-
if (type.startsWith("workspace_")) this.scheduleBroadcastStatus();
|
|
49816
|
+
if (type.startsWith("workspace_") || type.startsWith("session_host_")) this.scheduleBroadcastStatus();
|
|
49305
49817
|
return result;
|
|
49306
49818
|
}
|
|
49307
49819
|
scheduleBroadcastStatus() {
|