@adhdev/daemon-core 0.8.12 → 0.8.14
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/cli-adapters/spawn-env.d.ts +8 -0
- package/dist/cli-adapters/terminal-screen.d.ts +5 -3
- package/dist/detection/cli-detector.d.ts +1 -1
- package/dist/index.js +347 -236
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +343 -229
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +5 -3
- package/dist/providers/contracts.d.ts +38 -0
- package/node_modules/@adhdev/session-host-core/dist/index.d.mts +30 -1
- package/node_modules/@adhdev/session-host-core/dist/index.d.ts +30 -1
- package/node_modules/@adhdev/session-host-core/dist/index.js +73 -6
- package/node_modules/@adhdev/session-host-core/dist/index.js.map +1 -1
- package/node_modules/@adhdev/session-host-core/dist/index.mjs +77 -6
- package/node_modules/@adhdev/session-host-core/dist/index.mjs.map +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +3 -3
- package/src/cli-adapters/provider-cli-adapter.ts +36 -62
- package/src/cli-adapters/pty-transport.ts +13 -1
- package/src/cli-adapters/spawn-env.ts +12 -0
- package/src/cli-adapters/terminal-screen.ts +12 -3
- package/src/commands/cli-manager.ts +13 -2
- package/src/commands/workspace-commands.ts +37 -9
- package/src/detection/cli-detector.ts +36 -2
- package/src/providers/cli-provider-instance.ts +62 -36
- package/src/providers/contracts.ts +39 -0
package/dist/index.js
CHANGED
|
@@ -637,6 +637,13 @@ function logTerminalBackendSelection(preference, ghosttyAvailable, backendKind)
|
|
|
637
637
|
const key = `${preference}:${ghosttyAvailable}:${backendKind}`;
|
|
638
638
|
if (loggedTerminalBackends.has(key)) return;
|
|
639
639
|
loggedTerminalBackends.add(key);
|
|
640
|
+
if (backendKind === "xterm" && preference !== "xterm" && !ghosttyAvailable) {
|
|
641
|
+
LOG.warn(
|
|
642
|
+
"Terminal",
|
|
643
|
+
`[terminal-screen] ghostty-vt unavailable; using xterm fallback (preference=${preference})`
|
|
644
|
+
);
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
640
647
|
LOG.info(
|
|
641
648
|
"Terminal",
|
|
642
649
|
`[terminal-screen] backend=${backendKind} preference=${preference} ghosttyAvailable=${ghosttyAvailable}`
|
|
@@ -699,10 +706,11 @@ var init_terminal_screen = __esm({
|
|
|
699
706
|
});
|
|
700
707
|
|
|
701
708
|
// src/cli-adapters/pty-transport.ts
|
|
702
|
-
var pty, NodePtyRuntimeTransport, NodePtyTransportFactory;
|
|
709
|
+
var os7, pty, NodePtyRuntimeTransport, NodePtyTransportFactory;
|
|
703
710
|
var init_pty_transport = __esm({
|
|
704
711
|
"src/cli-adapters/pty-transport.ts"() {
|
|
705
712
|
"use strict";
|
|
713
|
+
os7 = __toESM(require("os"));
|
|
706
714
|
try {
|
|
707
715
|
pty = require("node-pty");
|
|
708
716
|
} catch {
|
|
@@ -739,11 +747,21 @@ var init_pty_transport = __esm({
|
|
|
739
747
|
NodePtyTransportFactory = class {
|
|
740
748
|
spawn(command, args, options) {
|
|
741
749
|
if (!pty) throw new Error("node-pty is not installed");
|
|
750
|
+
let cwd = options.cwd;
|
|
751
|
+
if (cwd) {
|
|
752
|
+
try {
|
|
753
|
+
const fs15 = require("fs");
|
|
754
|
+
const stat = fs15.statSync(cwd);
|
|
755
|
+
if (!stat.isDirectory()) cwd = os7.homedir();
|
|
756
|
+
} catch {
|
|
757
|
+
cwd = os7.homedir();
|
|
758
|
+
}
|
|
759
|
+
}
|
|
742
760
|
const handle = pty.spawn(command, args, {
|
|
743
761
|
name: "xterm-256color",
|
|
744
762
|
cols: options.cols,
|
|
745
763
|
rows: options.rows,
|
|
746
|
-
cwd
|
|
764
|
+
cwd,
|
|
747
765
|
env: options.env
|
|
748
766
|
});
|
|
749
767
|
return new NodePtyRuntimeTransport(handle);
|
|
@@ -752,6 +770,15 @@ var init_pty_transport = __esm({
|
|
|
752
770
|
}
|
|
753
771
|
});
|
|
754
772
|
|
|
773
|
+
// src/cli-adapters/spawn-env.ts
|
|
774
|
+
var import_session_host_core;
|
|
775
|
+
var init_spawn_env = __esm({
|
|
776
|
+
"src/cli-adapters/spawn-env.ts"() {
|
|
777
|
+
"use strict";
|
|
778
|
+
import_session_host_core = require("@adhdev/session-host-core");
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
|
|
755
782
|
// src/cli-adapters/provider-cli-adapter.ts
|
|
756
783
|
var provider_cli_adapter_exports = {};
|
|
757
784
|
__export(provider_cli_adapter_exports, {
|
|
@@ -767,32 +794,6 @@ function stripTerminalNoise(str) {
|
|
|
767
794
|
function sanitizeTerminalText(str) {
|
|
768
795
|
return stripTerminalNoise(stripAnsi(str));
|
|
769
796
|
}
|
|
770
|
-
function applyPreferredTerminalColorEnv(env) {
|
|
771
|
-
if (env.NO_COLOR) return;
|
|
772
|
-
if (!env.TERM || env.TERM === "xterm-color") {
|
|
773
|
-
env.TERM = "xterm-256color";
|
|
774
|
-
}
|
|
775
|
-
if (!env.COLORTERM) env.COLORTERM = "truecolor";
|
|
776
|
-
if (process.platform === "win32") {
|
|
777
|
-
if (!env.FORCE_COLOR) env.FORCE_COLOR = "1";
|
|
778
|
-
if (!env.CLICOLOR) env.CLICOLOR = "1";
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
function buildCliSpawnEnv(baseEnv, overrides) {
|
|
782
|
-
const env = {};
|
|
783
|
-
const source = { ...baseEnv, ...overrides || {} };
|
|
784
|
-
for (const [key, value] of Object.entries(source)) {
|
|
785
|
-
if (typeof value !== "string") continue;
|
|
786
|
-
env[key] = value;
|
|
787
|
-
}
|
|
788
|
-
for (const key of Object.keys(env)) {
|
|
789
|
-
if (key === "INIT_CWD" || key === "npm_command" || key === "npm_execpath" || key === "npm_node_execpath" || key.startsWith("npm_") || key.startsWith("npm_config_") || key.startsWith("npm_package_") || key.startsWith("npm_lifecycle_") || key.startsWith("PNPM_") || key.startsWith("YARN_") || key.startsWith("BUN_")) {
|
|
790
|
-
delete env[key];
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
applyPreferredTerminalColorEnv(env);
|
|
794
|
-
return env;
|
|
795
|
-
}
|
|
796
797
|
function computeTerminalQueryTail(buffer) {
|
|
797
798
|
const prefixes = ["\x1B[6n", "\x1B[?6n"];
|
|
798
799
|
const maxLength = prefixes.reduce((n, value) => Math.max(n, value.length), 0) - 1;
|
|
@@ -806,7 +807,7 @@ function computeTerminalQueryTail(buffer) {
|
|
|
806
807
|
return "";
|
|
807
808
|
}
|
|
808
809
|
function findBinary(name) {
|
|
809
|
-
const isWin =
|
|
810
|
+
const isWin = os8.platform() === "win32";
|
|
810
811
|
try {
|
|
811
812
|
const cmd = isWin ? `where ${name}` : `which ${name}`;
|
|
812
813
|
return (0, import_child_process4.execSync)(cmd, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n")[0].trim();
|
|
@@ -854,7 +855,7 @@ function looksLikeMachOOrElf(filePath) {
|
|
|
854
855
|
}
|
|
855
856
|
function shSingleQuote(arg) {
|
|
856
857
|
if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
|
|
857
|
-
if (
|
|
858
|
+
if (os8.platform() === "win32") {
|
|
858
859
|
return `"${arg.replace(/"/g, '""')}"`;
|
|
859
860
|
}
|
|
860
861
|
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
@@ -921,37 +922,24 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
921
922
|
}
|
|
922
923
|
};
|
|
923
924
|
}
|
|
924
|
-
var
|
|
925
|
+
var os8, path7, import_child_process4, pty2, buildCliSpawnEnv, ProviderCliAdapter;
|
|
925
926
|
var init_provider_cli_adapter = __esm({
|
|
926
927
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
927
928
|
"use strict";
|
|
928
|
-
|
|
929
|
+
os8 = __toESM(require("os"));
|
|
929
930
|
path7 = __toESM(require("path"));
|
|
930
931
|
import_child_process4 = require("child_process");
|
|
931
932
|
init_logger();
|
|
932
933
|
init_terminal_screen();
|
|
933
934
|
init_pty_transport();
|
|
935
|
+
init_spawn_env();
|
|
934
936
|
try {
|
|
935
937
|
pty2 = require("node-pty");
|
|
936
|
-
|
|
937
|
-
try {
|
|
938
|
-
const fs15 = require("fs");
|
|
939
|
-
const ptyDir = path7.resolve(path7.dirname(require.resolve("node-pty")), "..");
|
|
940
|
-
const platformArch = `${os7.platform()}-${os7.arch()}`;
|
|
941
|
-
const helper = path7.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
|
|
942
|
-
if (fs15.existsSync(helper)) {
|
|
943
|
-
const stat = fs15.statSync(helper);
|
|
944
|
-
if (!(stat.mode & 73)) {
|
|
945
|
-
fs15.chmodSync(helper, stat.mode | 493);
|
|
946
|
-
LOG.info("CLI", "[node-pty] Fixed spawn-helper permissions");
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
} catch {
|
|
950
|
-
}
|
|
951
|
-
}
|
|
938
|
+
(0, import_session_host_core.ensureNodePtySpawnHelperPermissions)((msg) => LOG.info("CLI", msg));
|
|
952
939
|
} catch {
|
|
953
940
|
LOG.error("CLI", "[ProviderCliAdapter] node-pty not found. Terminal features disabled.");
|
|
954
941
|
}
|
|
942
|
+
buildCliSpawnEnv = import_session_host_core.sanitizeSpawnEnv;
|
|
955
943
|
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
956
944
|
constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
|
|
957
945
|
this.extraArgs = extraArgs;
|
|
@@ -959,7 +947,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
959
947
|
this.transportFactory = transportFactory;
|
|
960
948
|
this.cliType = provider.type;
|
|
961
949
|
this.cliName = provider.name;
|
|
962
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
950
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os8.homedir()) : workingDir;
|
|
963
951
|
const t = provider.timeouts || {};
|
|
964
952
|
this.timeouts = {
|
|
965
953
|
ptyFlush: t.ptyFlush ?? 50,
|
|
@@ -1266,7 +1254,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1266
1254
|
if (this.ptyProcess) return;
|
|
1267
1255
|
const { spawn: spawnConfig } = this.provider;
|
|
1268
1256
|
const binaryPath = findBinary(spawnConfig.command);
|
|
1269
|
-
const isWin =
|
|
1257
|
+
const isWin = os8.platform() === "win32";
|
|
1270
1258
|
const allArgs = [...spawnConfig.args, ...this.extraArgs];
|
|
1271
1259
|
LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
1272
1260
|
this.resetTraceSession();
|
|
@@ -1274,13 +1262,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
1274
1262
|
let shellArgs;
|
|
1275
1263
|
const useShellUnix = !isWin && (!!spawnConfig.shell || !path7.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
1276
1264
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
1277
|
-
const
|
|
1265
|
+
const useShellWin = isCmdShim || !path7.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
1266
|
+
const useShell = isWin ? useShellWin : useShellUnix;
|
|
1278
1267
|
if (useShell) {
|
|
1279
1268
|
if (!spawnConfig.shell && !isWin) {
|
|
1280
1269
|
LOG.info("CLI", `[${this.cliType}] Using login shell (script shim or non-native binary)`);
|
|
1281
1270
|
}
|
|
1282
1271
|
if (isCmdShim) {
|
|
1283
1272
|
LOG.info("CLI", `[${this.cliType}] Using cmd.exe shell for .cmd/.bat shim: ${binaryPath}`);
|
|
1273
|
+
} else if (isWin) {
|
|
1274
|
+
LOG.info("CLI", `[${this.cliType}] Using cmd.exe shell on Windows: ${binaryPath}`);
|
|
1284
1275
|
}
|
|
1285
1276
|
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
1286
1277
|
if (isWin) {
|
|
@@ -1290,6 +1281,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
1290
1281
|
shellArgs = ["-l", "-c", fullCmd];
|
|
1291
1282
|
}
|
|
1292
1283
|
} else {
|
|
1284
|
+
if (isWin && spawnConfig.shell) {
|
|
1285
|
+
LOG.info("CLI", `[${this.cliType}] Spawning Windows binary directly without cmd.exe: ${binaryPath}`);
|
|
1286
|
+
}
|
|
1293
1287
|
shellCmd = binaryPath;
|
|
1294
1288
|
shellArgs = allArgs;
|
|
1295
1289
|
}
|
|
@@ -1318,6 +1312,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
1318
1312
|
shellArgs = ["-l", "-c", fullCmd];
|
|
1319
1313
|
this.ptyProcess = this.transportFactory.spawn(shellCmd, shellArgs, ptyOpts);
|
|
1320
1314
|
} else {
|
|
1315
|
+
if (isWin) {
|
|
1316
|
+
const hint = /error code 267|ERROR_DIRECTORY/i.test(msg) ? " (working directory does not exist or is not a directory)" : /error code 740|elevation/i.test(msg) ? " (requires administrator privileges)" : /error code 2|ENOENT|not found/i.test(msg) ? ` (executable not found: ${shellCmd})` : "";
|
|
1317
|
+
if (hint) {
|
|
1318
|
+
throw new Error(`Failed to spawn CLI${hint}: ${msg}`);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
1321
|
throw err;
|
|
1322
1322
|
}
|
|
1323
1323
|
}
|
|
@@ -1492,7 +1492,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1492
1492
|
`[${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)}`
|
|
1493
1493
|
);
|
|
1494
1494
|
}
|
|
1495
|
-
await new Promise((
|
|
1495
|
+
await new Promise((resolve9) => setTimeout(resolve9, 50));
|
|
1496
1496
|
}
|
|
1497
1497
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
1498
1498
|
LOG.warn(
|
|
@@ -1879,7 +1879,7 @@ ${data.message || ""}`.trim();
|
|
|
1879
1879
|
if (this.startupParseGate) {
|
|
1880
1880
|
const deadline = Date.now() + 1e4;
|
|
1881
1881
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
1882
|
-
await new Promise((
|
|
1882
|
+
await new Promise((resolve9) => setTimeout(resolve9, 50));
|
|
1883
1883
|
}
|
|
1884
1884
|
}
|
|
1885
1885
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
@@ -2070,7 +2070,8 @@ ${data.message || ""}`.trim();
|
|
|
2070
2070
|
const payload = stopCommand.endsWith("\r") || stopCommand.endsWith("\n") ? stopCommand : `${stopCommand}${this.sendKey}`;
|
|
2071
2071
|
this.ptyProcess.write(payload);
|
|
2072
2072
|
};
|
|
2073
|
-
|
|
2073
|
+
const interruptGraceMs = typeof resume.interruptGraceMs === "number" ? Math.max(100, resume.interruptGraceMs) : 500;
|
|
2074
|
+
if (wasProcessing) setTimeout(writeCommand, interruptGraceMs);
|
|
2074
2075
|
else writeCommand();
|
|
2075
2076
|
} else {
|
|
2076
2077
|
this.ptyProcess.write("");
|
|
@@ -2086,17 +2087,17 @@ ${data.message || ""}`.trim();
|
|
|
2086
2087
|
}
|
|
2087
2088
|
}
|
|
2088
2089
|
waitForStopped(timeoutMs) {
|
|
2089
|
-
return new Promise((
|
|
2090
|
+
return new Promise((resolve9) => {
|
|
2090
2091
|
const startedAt = Date.now();
|
|
2091
2092
|
const timer = setInterval(() => {
|
|
2092
2093
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
2093
2094
|
clearInterval(timer);
|
|
2094
|
-
|
|
2095
|
+
resolve9(true);
|
|
2095
2096
|
return;
|
|
2096
2097
|
}
|
|
2097
2098
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
2098
2099
|
clearInterval(timer);
|
|
2099
|
-
|
|
2100
|
+
resolve9(false);
|
|
2100
2101
|
}
|
|
2101
2102
|
}, 100);
|
|
2102
2103
|
});
|
|
@@ -2115,6 +2116,18 @@ ${data.message || ""}`.trim();
|
|
|
2115
2116
|
clearTimeout(this.submitRetryTimer);
|
|
2116
2117
|
this.submitRetryTimer = null;
|
|
2117
2118
|
}
|
|
2119
|
+
if (this.responseTimeout) {
|
|
2120
|
+
clearTimeout(this.responseTimeout);
|
|
2121
|
+
this.responseTimeout = null;
|
|
2122
|
+
}
|
|
2123
|
+
if (this.idleTimeout) {
|
|
2124
|
+
clearTimeout(this.idleTimeout);
|
|
2125
|
+
this.idleTimeout = null;
|
|
2126
|
+
}
|
|
2127
|
+
if (this.pendingScriptStatusTimer) {
|
|
2128
|
+
clearTimeout(this.pendingScriptStatusTimer);
|
|
2129
|
+
this.pendingScriptStatusTimer = null;
|
|
2130
|
+
}
|
|
2118
2131
|
if (this.pendingOutputParseTimer) {
|
|
2119
2132
|
clearTimeout(this.pendingOutputParseTimer);
|
|
2120
2133
|
this.pendingOutputParseTimer = null;
|
|
@@ -2156,6 +2169,18 @@ ${data.message || ""}`.trim();
|
|
|
2156
2169
|
clearTimeout(this.submitRetryTimer);
|
|
2157
2170
|
this.submitRetryTimer = null;
|
|
2158
2171
|
}
|
|
2172
|
+
if (this.responseTimeout) {
|
|
2173
|
+
clearTimeout(this.responseTimeout);
|
|
2174
|
+
this.responseTimeout = null;
|
|
2175
|
+
}
|
|
2176
|
+
if (this.idleTimeout) {
|
|
2177
|
+
clearTimeout(this.idleTimeout);
|
|
2178
|
+
this.idleTimeout = null;
|
|
2179
|
+
}
|
|
2180
|
+
if (this.pendingScriptStatusTimer) {
|
|
2181
|
+
clearTimeout(this.pendingScriptStatusTimer);
|
|
2182
|
+
this.pendingScriptStatusTimer = null;
|
|
2183
|
+
}
|
|
2159
2184
|
if (this.pendingOutputParseTimer) {
|
|
2160
2185
|
clearTimeout(this.pendingOutputParseTimer);
|
|
2161
2186
|
this.pendingOutputParseTimer = null;
|
|
@@ -2749,20 +2774,20 @@ function checkPathExists(paths) {
|
|
|
2749
2774
|
return null;
|
|
2750
2775
|
}
|
|
2751
2776
|
async function detectIDEs() {
|
|
2752
|
-
const
|
|
2777
|
+
const os18 = (0, import_os2.platform)();
|
|
2753
2778
|
const results = [];
|
|
2754
2779
|
for (const def of getMergedDefinitions()) {
|
|
2755
2780
|
const cliPath = findCliCommand(def.cli);
|
|
2756
|
-
const appPath = checkPathExists(def.paths[
|
|
2781
|
+
const appPath = checkPathExists(def.paths[os18] || []);
|
|
2757
2782
|
const installed = !!(cliPath || appPath);
|
|
2758
2783
|
let resolvedCli = cliPath;
|
|
2759
|
-
if (!resolvedCli && appPath &&
|
|
2784
|
+
if (!resolvedCli && appPath && os18 === "darwin") {
|
|
2760
2785
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
2761
2786
|
if ((0, import_fs2.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
2762
2787
|
}
|
|
2763
|
-
if (!resolvedCli && appPath &&
|
|
2764
|
-
const { dirname:
|
|
2765
|
-
const appDir =
|
|
2788
|
+
if (!resolvedCli && appPath && os18 === "win32") {
|
|
2789
|
+
const { dirname: dirname6 } = await import("path");
|
|
2790
|
+
const appDir = dirname6(appPath);
|
|
2766
2791
|
const candidates = [
|
|
2767
2792
|
`${appDir}\\\\bin\\\\${def.cli}.cmd`,
|
|
2768
2793
|
`${appDir}\\\\bin\\\\${def.cli}`,
|
|
@@ -2800,15 +2825,15 @@ function parseVersion(raw) {
|
|
|
2800
2825
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
2801
2826
|
}
|
|
2802
2827
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
2803
|
-
return new Promise((
|
|
2828
|
+
return new Promise((resolve9) => {
|
|
2804
2829
|
const child = (0, import_child_process2.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
|
|
2805
2830
|
if (err || !stdout?.trim()) {
|
|
2806
|
-
|
|
2831
|
+
resolve9(null);
|
|
2807
2832
|
} else {
|
|
2808
|
-
|
|
2833
|
+
resolve9(stdout.trim());
|
|
2809
2834
|
}
|
|
2810
2835
|
});
|
|
2811
|
-
child.on("error", () =>
|
|
2836
|
+
child.on("error", () => resolve9(null));
|
|
2812
2837
|
});
|
|
2813
2838
|
}
|
|
2814
2839
|
async function detectCLIs(providerLoader) {
|
|
@@ -2848,6 +2873,39 @@ async function detectCLIs(providerLoader) {
|
|
|
2848
2873
|
}
|
|
2849
2874
|
async function detectCLI(cliId, providerLoader) {
|
|
2850
2875
|
const resolvedId = providerLoader ? providerLoader.resolveAlias(cliId) : cliId;
|
|
2876
|
+
if (providerLoader) {
|
|
2877
|
+
const cliList = providerLoader.getCliDetectionList();
|
|
2878
|
+
const target = cliList.find((c) => c.id === resolvedId);
|
|
2879
|
+
if (target) {
|
|
2880
|
+
const platform9 = os2.platform();
|
|
2881
|
+
const whichCmd = platform9 === "win32" ? "where" : "which";
|
|
2882
|
+
try {
|
|
2883
|
+
const pathResult = await execAsync(`${whichCmd} ${target.command}`);
|
|
2884
|
+
if (!pathResult) return null;
|
|
2885
|
+
const firstPath = pathResult.split("\n")[0];
|
|
2886
|
+
let version;
|
|
2887
|
+
try {
|
|
2888
|
+
const versionCommands = [
|
|
2889
|
+
target.versionCommand,
|
|
2890
|
+
`${target.command} --version`,
|
|
2891
|
+
`${target.command} -V`,
|
|
2892
|
+
`${target.command} -v`
|
|
2893
|
+
].filter((v) => !!v);
|
|
2894
|
+
for (const versionCommand of versionCommands) {
|
|
2895
|
+
const versionResult = await execAsync(versionCommand, 3e3);
|
|
2896
|
+
if (versionResult) {
|
|
2897
|
+
version = parseVersion(versionResult);
|
|
2898
|
+
break;
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
} catch {
|
|
2902
|
+
}
|
|
2903
|
+
return { ...target, installed: true, version, path: firstPath };
|
|
2904
|
+
} catch {
|
|
2905
|
+
return null;
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2851
2909
|
const all = await detectCLIs(providerLoader);
|
|
2852
2910
|
return all.find((c) => c.id === resolvedId && c.installed) || null;
|
|
2853
2911
|
}
|
|
@@ -2975,7 +3033,7 @@ var DaemonCdpManager = class {
|
|
|
2975
3033
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
2976
3034
|
*/
|
|
2977
3035
|
static listAllTargets(port) {
|
|
2978
|
-
return new Promise((
|
|
3036
|
+
return new Promise((resolve9) => {
|
|
2979
3037
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
2980
3038
|
let data = "";
|
|
2981
3039
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -2991,16 +3049,16 @@ var DaemonCdpManager = class {
|
|
|
2991
3049
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
2992
3050
|
);
|
|
2993
3051
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
2994
|
-
|
|
3052
|
+
resolve9(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
2995
3053
|
} catch {
|
|
2996
|
-
|
|
3054
|
+
resolve9([]);
|
|
2997
3055
|
}
|
|
2998
3056
|
});
|
|
2999
3057
|
});
|
|
3000
|
-
req.on("error", () =>
|
|
3058
|
+
req.on("error", () => resolve9([]));
|
|
3001
3059
|
req.setTimeout(2e3, () => {
|
|
3002
3060
|
req.destroy();
|
|
3003
|
-
|
|
3061
|
+
resolve9([]);
|
|
3004
3062
|
});
|
|
3005
3063
|
});
|
|
3006
3064
|
}
|
|
@@ -3040,7 +3098,7 @@ var DaemonCdpManager = class {
|
|
|
3040
3098
|
}
|
|
3041
3099
|
}
|
|
3042
3100
|
findTargetOnPort(port) {
|
|
3043
|
-
return new Promise((
|
|
3101
|
+
return new Promise((resolve9) => {
|
|
3044
3102
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
3045
3103
|
let data = "";
|
|
3046
3104
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -3051,7 +3109,7 @@ var DaemonCdpManager = class {
|
|
|
3051
3109
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
3052
3110
|
);
|
|
3053
3111
|
if (pages.length === 0) {
|
|
3054
|
-
|
|
3112
|
+
resolve9(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
3055
3113
|
return;
|
|
3056
3114
|
}
|
|
3057
3115
|
const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -3061,24 +3119,24 @@ var DaemonCdpManager = class {
|
|
|
3061
3119
|
const specific = list.find((t) => t.id === this._targetId);
|
|
3062
3120
|
if (specific) {
|
|
3063
3121
|
this._pageTitle = specific.title || "";
|
|
3064
|
-
|
|
3122
|
+
resolve9(specific);
|
|
3065
3123
|
} else {
|
|
3066
3124
|
this.log(`[CDP] Target ${this._targetId} not found in page list`);
|
|
3067
|
-
|
|
3125
|
+
resolve9(null);
|
|
3068
3126
|
}
|
|
3069
3127
|
return;
|
|
3070
3128
|
}
|
|
3071
3129
|
this._pageTitle = list[0]?.title || "";
|
|
3072
|
-
|
|
3130
|
+
resolve9(list[0]);
|
|
3073
3131
|
} catch {
|
|
3074
|
-
|
|
3132
|
+
resolve9(null);
|
|
3075
3133
|
}
|
|
3076
3134
|
});
|
|
3077
3135
|
});
|
|
3078
|
-
req.on("error", () =>
|
|
3136
|
+
req.on("error", () => resolve9(null));
|
|
3079
3137
|
req.setTimeout(2e3, () => {
|
|
3080
3138
|
req.destroy();
|
|
3081
|
-
|
|
3139
|
+
resolve9(null);
|
|
3082
3140
|
});
|
|
3083
3141
|
});
|
|
3084
3142
|
}
|
|
@@ -3089,7 +3147,7 @@ var DaemonCdpManager = class {
|
|
|
3089
3147
|
this.extensionProviders = providers;
|
|
3090
3148
|
}
|
|
3091
3149
|
connectToTarget(wsUrl) {
|
|
3092
|
-
return new Promise((
|
|
3150
|
+
return new Promise((resolve9) => {
|
|
3093
3151
|
this.ws = new import_ws.default(wsUrl);
|
|
3094
3152
|
this.ws.on("open", async () => {
|
|
3095
3153
|
this._connected = true;
|
|
@@ -3099,17 +3157,17 @@ var DaemonCdpManager = class {
|
|
|
3099
3157
|
}
|
|
3100
3158
|
this.connectBrowserWs().catch(() => {
|
|
3101
3159
|
});
|
|
3102
|
-
|
|
3160
|
+
resolve9(true);
|
|
3103
3161
|
});
|
|
3104
3162
|
this.ws.on("message", (data) => {
|
|
3105
3163
|
try {
|
|
3106
3164
|
const msg = JSON.parse(data.toString());
|
|
3107
3165
|
if (msg.id && this.pending.has(msg.id)) {
|
|
3108
|
-
const { resolve:
|
|
3166
|
+
const { resolve: resolve10, reject } = this.pending.get(msg.id);
|
|
3109
3167
|
this.pending.delete(msg.id);
|
|
3110
3168
|
this.failureCount = 0;
|
|
3111
3169
|
if (msg.error) reject(new Error(msg.error.message));
|
|
3112
|
-
else
|
|
3170
|
+
else resolve10(msg.result);
|
|
3113
3171
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
3114
3172
|
this.contexts.add(msg.params.context.id);
|
|
3115
3173
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -3132,7 +3190,7 @@ var DaemonCdpManager = class {
|
|
|
3132
3190
|
this.ws.on("error", (err) => {
|
|
3133
3191
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
3134
3192
|
this._connected = false;
|
|
3135
|
-
|
|
3193
|
+
resolve9(false);
|
|
3136
3194
|
});
|
|
3137
3195
|
});
|
|
3138
3196
|
}
|
|
@@ -3146,7 +3204,7 @@ var DaemonCdpManager = class {
|
|
|
3146
3204
|
return;
|
|
3147
3205
|
}
|
|
3148
3206
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
3149
|
-
await new Promise((
|
|
3207
|
+
await new Promise((resolve9, reject) => {
|
|
3150
3208
|
this.browserWs = new import_ws.default(browserWsUrl);
|
|
3151
3209
|
this.browserWs.on("open", async () => {
|
|
3152
3210
|
this._browserConnected = true;
|
|
@@ -3156,16 +3214,16 @@ var DaemonCdpManager = class {
|
|
|
3156
3214
|
} catch (e) {
|
|
3157
3215
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
3158
3216
|
}
|
|
3159
|
-
|
|
3217
|
+
resolve9();
|
|
3160
3218
|
});
|
|
3161
3219
|
this.browserWs.on("message", (data) => {
|
|
3162
3220
|
try {
|
|
3163
3221
|
const msg = JSON.parse(data.toString());
|
|
3164
3222
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
3165
|
-
const { resolve:
|
|
3223
|
+
const { resolve: resolve10, reject: reject2 } = this.browserPending.get(msg.id);
|
|
3166
3224
|
this.browserPending.delete(msg.id);
|
|
3167
3225
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
3168
|
-
else
|
|
3226
|
+
else resolve10(msg.result);
|
|
3169
3227
|
}
|
|
3170
3228
|
} catch {
|
|
3171
3229
|
}
|
|
@@ -3185,31 +3243,31 @@ var DaemonCdpManager = class {
|
|
|
3185
3243
|
}
|
|
3186
3244
|
}
|
|
3187
3245
|
getBrowserWsUrl() {
|
|
3188
|
-
return new Promise((
|
|
3246
|
+
return new Promise((resolve9) => {
|
|
3189
3247
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
3190
3248
|
let data = "";
|
|
3191
3249
|
res.on("data", (chunk) => data += chunk.toString());
|
|
3192
3250
|
res.on("end", () => {
|
|
3193
3251
|
try {
|
|
3194
3252
|
const info = JSON.parse(data);
|
|
3195
|
-
|
|
3253
|
+
resolve9(info.webSocketDebuggerUrl || null);
|
|
3196
3254
|
} catch {
|
|
3197
|
-
|
|
3255
|
+
resolve9(null);
|
|
3198
3256
|
}
|
|
3199
3257
|
});
|
|
3200
3258
|
});
|
|
3201
|
-
req.on("error", () =>
|
|
3259
|
+
req.on("error", () => resolve9(null));
|
|
3202
3260
|
req.setTimeout(3e3, () => {
|
|
3203
3261
|
req.destroy();
|
|
3204
|
-
|
|
3262
|
+
resolve9(null);
|
|
3205
3263
|
});
|
|
3206
3264
|
});
|
|
3207
3265
|
}
|
|
3208
3266
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
3209
|
-
return new Promise((
|
|
3267
|
+
return new Promise((resolve9, reject) => {
|
|
3210
3268
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
3211
3269
|
const id = this.browserMsgId++;
|
|
3212
|
-
this.browserPending.set(id, { resolve:
|
|
3270
|
+
this.browserPending.set(id, { resolve: resolve9, reject });
|
|
3213
3271
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
3214
3272
|
setTimeout(() => {
|
|
3215
3273
|
if (this.browserPending.has(id)) {
|
|
@@ -3249,11 +3307,11 @@ var DaemonCdpManager = class {
|
|
|
3249
3307
|
}
|
|
3250
3308
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
3251
3309
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
3252
|
-
return new Promise((
|
|
3310
|
+
return new Promise((resolve9, reject) => {
|
|
3253
3311
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
3254
3312
|
if (this.ws.readyState !== import_ws.default.OPEN) return reject(new Error("WebSocket not open"));
|
|
3255
3313
|
const id = this.msgId++;
|
|
3256
|
-
this.pending.set(id, { resolve:
|
|
3314
|
+
this.pending.set(id, { resolve: resolve9, reject });
|
|
3257
3315
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
3258
3316
|
setTimeout(() => {
|
|
3259
3317
|
if (this.pending.has(id)) {
|
|
@@ -3502,7 +3560,7 @@ var DaemonCdpManager = class {
|
|
|
3502
3560
|
const browserWs = this.browserWs;
|
|
3503
3561
|
let msgId = this.browserMsgId;
|
|
3504
3562
|
const sendWs = (method, params = {}, sessionId) => {
|
|
3505
|
-
return new Promise((
|
|
3563
|
+
return new Promise((resolve9, reject) => {
|
|
3506
3564
|
const mid = msgId++;
|
|
3507
3565
|
this.browserMsgId = msgId;
|
|
3508
3566
|
const handler = (raw) => {
|
|
@@ -3511,7 +3569,7 @@ var DaemonCdpManager = class {
|
|
|
3511
3569
|
if (msg.id === mid) {
|
|
3512
3570
|
browserWs.removeListener("message", handler);
|
|
3513
3571
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
3514
|
-
else
|
|
3572
|
+
else resolve9(msg.result);
|
|
3515
3573
|
}
|
|
3516
3574
|
} catch {
|
|
3517
3575
|
}
|
|
@@ -3702,14 +3760,14 @@ var DaemonCdpManager = class {
|
|
|
3702
3760
|
if (!ws || ws.readyState !== import_ws.default.OPEN) {
|
|
3703
3761
|
throw new Error("CDP not connected");
|
|
3704
3762
|
}
|
|
3705
|
-
return new Promise((
|
|
3763
|
+
return new Promise((resolve9, reject) => {
|
|
3706
3764
|
const id = getNextId();
|
|
3707
3765
|
pendingMap.set(id, {
|
|
3708
3766
|
resolve: (result) => {
|
|
3709
3767
|
if (result?.result?.subtype === "error") {
|
|
3710
3768
|
reject(new Error(result.result.description));
|
|
3711
3769
|
} else {
|
|
3712
|
-
|
|
3770
|
+
resolve9(result?.result?.value);
|
|
3713
3771
|
}
|
|
3714
3772
|
},
|
|
3715
3773
|
reject
|
|
@@ -3741,10 +3799,10 @@ var DaemonCdpManager = class {
|
|
|
3741
3799
|
throw new Error("CDP not connected");
|
|
3742
3800
|
}
|
|
3743
3801
|
const sendViaSession = (method, params = {}) => {
|
|
3744
|
-
return new Promise((
|
|
3802
|
+
return new Promise((resolve9, reject) => {
|
|
3745
3803
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
3746
3804
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
3747
|
-
pendingMap.set(id, { resolve:
|
|
3805
|
+
pendingMap.set(id, { resolve: resolve9, reject });
|
|
3748
3806
|
ws.send(JSON.stringify({ id, sessionId, method, params }));
|
|
3749
3807
|
setTimeout(() => {
|
|
3750
3808
|
if (pendingMap.has(id)) {
|
|
@@ -7276,8 +7334,24 @@ function handleSetIdeExtension(h, args) {
|
|
|
7276
7334
|
|
|
7277
7335
|
// src/commands/workspace-commands.ts
|
|
7278
7336
|
init_config();
|
|
7337
|
+
function loadWorkspaceConfig() {
|
|
7338
|
+
try {
|
|
7339
|
+
return loadConfig();
|
|
7340
|
+
} catch (e) {
|
|
7341
|
+
return { error: `Could not load config: ${e?.message || "unknown error"}` };
|
|
7342
|
+
}
|
|
7343
|
+
}
|
|
7344
|
+
function persistWorkspaceConfig(config) {
|
|
7345
|
+
try {
|
|
7346
|
+
saveConfig(config);
|
|
7347
|
+
return { ok: true };
|
|
7348
|
+
} catch (e) {
|
|
7349
|
+
return { error: `Could not save config: ${e?.message || "unknown error"}` };
|
|
7350
|
+
}
|
|
7351
|
+
}
|
|
7279
7352
|
function handleWorkspaceList() {
|
|
7280
|
-
const config =
|
|
7353
|
+
const config = loadWorkspaceConfig();
|
|
7354
|
+
if ("error" in config) return { success: false, error: config.error };
|
|
7281
7355
|
const state = getWorkspaceState(config);
|
|
7282
7356
|
return {
|
|
7283
7357
|
success: true,
|
|
@@ -7291,31 +7365,37 @@ function handleWorkspaceAdd(args) {
|
|
|
7291
7365
|
const label = (args?.label || "").trim() || void 0;
|
|
7292
7366
|
const createIfMissing = args?.createIfMissing === true;
|
|
7293
7367
|
if (!rawPath) return { success: false, error: "path required" };
|
|
7294
|
-
const config =
|
|
7368
|
+
const config = loadWorkspaceConfig();
|
|
7369
|
+
if ("error" in config) return { success: false, error: config.error };
|
|
7295
7370
|
const result = addWorkspaceEntry(config, rawPath, label, { createIfMissing });
|
|
7296
7371
|
if ("error" in result) return { success: false, error: result.error };
|
|
7297
|
-
|
|
7372
|
+
const saveResult = persistWorkspaceConfig(result.config);
|
|
7373
|
+
if ("error" in saveResult) return { success: false, error: saveResult.error };
|
|
7298
7374
|
const state = getWorkspaceState(result.config);
|
|
7299
7375
|
return { success: true, entry: result.entry, ...state };
|
|
7300
7376
|
}
|
|
7301
7377
|
function handleWorkspaceRemove(args) {
|
|
7302
7378
|
const id = (args?.id || "").trim();
|
|
7303
7379
|
if (!id) return { success: false, error: "id required" };
|
|
7304
|
-
const config =
|
|
7380
|
+
const config = loadWorkspaceConfig();
|
|
7381
|
+
if ("error" in config) return { success: false, error: config.error };
|
|
7305
7382
|
const removed = (config.workspaces || []).find((w) => w.id === id);
|
|
7306
7383
|
const result = removeWorkspaceEntry(config, id);
|
|
7307
7384
|
if ("error" in result) return { success: false, error: result.error };
|
|
7308
|
-
|
|
7385
|
+
const saveResult = persistWorkspaceConfig(result.config);
|
|
7386
|
+
if ("error" in saveResult) return { success: false, error: saveResult.error };
|
|
7309
7387
|
const state = getWorkspaceState(result.config);
|
|
7310
7388
|
return { success: true, removedId: id, ...state };
|
|
7311
7389
|
}
|
|
7312
7390
|
function handleWorkspaceSetDefault(args) {
|
|
7313
7391
|
const clear = args?.clear === true || args?.id === null || args?.id === "";
|
|
7314
7392
|
if (clear) {
|
|
7315
|
-
const config2 =
|
|
7393
|
+
const config2 = loadWorkspaceConfig();
|
|
7394
|
+
if ("error" in config2) return { success: false, error: config2.error };
|
|
7316
7395
|
const result2 = setDefaultWorkspaceId(config2, null);
|
|
7317
7396
|
if ("error" in result2) return { success: false, error: result2.error };
|
|
7318
|
-
|
|
7397
|
+
const saveResult2 = persistWorkspaceConfig(result2.config);
|
|
7398
|
+
if ("error" in saveResult2) return { success: false, error: saveResult2.error };
|
|
7319
7399
|
const state2 = getWorkspaceState(result2.config);
|
|
7320
7400
|
return {
|
|
7321
7401
|
success: true,
|
|
@@ -7327,7 +7407,9 @@ function handleWorkspaceSetDefault(args) {
|
|
|
7327
7407
|
if (!pathArg && !idArg) {
|
|
7328
7408
|
return { success: false, error: "id or path required (or clear: true)" };
|
|
7329
7409
|
}
|
|
7330
|
-
|
|
7410
|
+
const configResult = loadWorkspaceConfig();
|
|
7411
|
+
if ("error" in configResult) return { success: false, error: configResult.error };
|
|
7412
|
+
let config = configResult;
|
|
7331
7413
|
let nextId;
|
|
7332
7414
|
if (pathArg) {
|
|
7333
7415
|
let w = findWorkspaceByPath(config, pathArg);
|
|
@@ -7343,7 +7425,8 @@ function handleWorkspaceSetDefault(args) {
|
|
|
7343
7425
|
}
|
|
7344
7426
|
const result = setDefaultWorkspaceId(config, nextId);
|
|
7345
7427
|
if ("error" in result) return { success: false, error: result.error };
|
|
7346
|
-
|
|
7428
|
+
const saveResult = persistWorkspaceConfig(result.config);
|
|
7429
|
+
if ("error" in saveResult) return { success: false, error: saveResult.error };
|
|
7347
7430
|
const state = getWorkspaceState(result.config);
|
|
7348
7431
|
return { success: true, ...state };
|
|
7349
7432
|
}
|
|
@@ -7745,7 +7828,7 @@ var DaemonCommandHandler = class {
|
|
|
7745
7828
|
try {
|
|
7746
7829
|
const http3 = await import("http");
|
|
7747
7830
|
const postData = JSON.stringify(body);
|
|
7748
|
-
const result = await new Promise((
|
|
7831
|
+
const result = await new Promise((resolve9, reject) => {
|
|
7749
7832
|
const req = http3.request({
|
|
7750
7833
|
hostname: "127.0.0.1",
|
|
7751
7834
|
port: 19280,
|
|
@@ -7757,9 +7840,9 @@ var DaemonCommandHandler = class {
|
|
|
7757
7840
|
res.on("data", (chunk) => data += chunk);
|
|
7758
7841
|
res.on("end", () => {
|
|
7759
7842
|
try {
|
|
7760
|
-
|
|
7843
|
+
resolve9(JSON.parse(data));
|
|
7761
7844
|
} catch {
|
|
7762
|
-
|
|
7845
|
+
resolve9({ raw: data });
|
|
7763
7846
|
}
|
|
7764
7847
|
});
|
|
7765
7848
|
});
|
|
@@ -7777,15 +7860,15 @@ var DaemonCommandHandler = class {
|
|
|
7777
7860
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
7778
7861
|
try {
|
|
7779
7862
|
const http3 = await import("http");
|
|
7780
|
-
const result = await new Promise((
|
|
7863
|
+
const result = await new Promise((resolve9, reject) => {
|
|
7781
7864
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
7782
7865
|
let data = "";
|
|
7783
7866
|
res.on("data", (chunk) => data += chunk);
|
|
7784
7867
|
res.on("end", () => {
|
|
7785
7868
|
try {
|
|
7786
|
-
|
|
7869
|
+
resolve9(JSON.parse(data));
|
|
7787
7870
|
} catch {
|
|
7788
|
-
|
|
7871
|
+
resolve9({ raw: data });
|
|
7789
7872
|
}
|
|
7790
7873
|
});
|
|
7791
7874
|
}).on("error", reject);
|
|
@@ -7799,7 +7882,7 @@ var DaemonCommandHandler = class {
|
|
|
7799
7882
|
try {
|
|
7800
7883
|
const http3 = await import("http");
|
|
7801
7884
|
const postData = JSON.stringify(args || {});
|
|
7802
|
-
const result = await new Promise((
|
|
7885
|
+
const result = await new Promise((resolve9, reject) => {
|
|
7803
7886
|
const req = http3.request({
|
|
7804
7887
|
hostname: "127.0.0.1",
|
|
7805
7888
|
port: 19280,
|
|
@@ -7811,9 +7894,9 @@ var DaemonCommandHandler = class {
|
|
|
7811
7894
|
res.on("data", (chunk) => data += chunk);
|
|
7812
7895
|
res.on("end", () => {
|
|
7813
7896
|
try {
|
|
7814
|
-
|
|
7897
|
+
resolve9(JSON.parse(data));
|
|
7815
7898
|
} catch {
|
|
7816
|
-
|
|
7899
|
+
resolve9({ raw: data });
|
|
7817
7900
|
}
|
|
7818
7901
|
});
|
|
7819
7902
|
});
|
|
@@ -7829,7 +7912,7 @@ var DaemonCommandHandler = class {
|
|
|
7829
7912
|
};
|
|
7830
7913
|
|
|
7831
7914
|
// src/commands/cli-manager.ts
|
|
7832
|
-
var
|
|
7915
|
+
var os10 = __toESM(require("os"));
|
|
7833
7916
|
var path9 = __toESM(require("path"));
|
|
7834
7917
|
var crypto4 = __toESM(require("crypto"));
|
|
7835
7918
|
var import_chalk = __toESM(require("chalk"));
|
|
@@ -7837,7 +7920,7 @@ init_provider_cli_adapter();
|
|
|
7837
7920
|
init_config();
|
|
7838
7921
|
|
|
7839
7922
|
// src/providers/cli-provider-instance.ts
|
|
7840
|
-
var
|
|
7923
|
+
var os9 = __toESM(require("os"));
|
|
7841
7924
|
var path8 = __toESM(require("path"));
|
|
7842
7925
|
var crypto3 = __toESM(require("crypto"));
|
|
7843
7926
|
var fs5 = __toESM(require("fs"));
|
|
@@ -7926,17 +8009,60 @@ var CliProviderInstance = class {
|
|
|
7926
8009
|
async onTick() {
|
|
7927
8010
|
if (this.providerSessionId) return;
|
|
7928
8011
|
let probedSessionId = null;
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
8012
|
+
const probeConfig = this.provider.sessionProbe;
|
|
8013
|
+
if (probeConfig) {
|
|
8014
|
+
probedSessionId = this.probeSessionIdFromConfig(probeConfig);
|
|
8015
|
+
} else {
|
|
8016
|
+
if (this.type === "opencode-cli") {
|
|
8017
|
+
probedSessionId = this.probeSessionIdFromConfig({
|
|
8018
|
+
dbPath: "~/.local/share/opencode/opencode.db",
|
|
8019
|
+
query: "select id from session where directory in ({dirs}) and time_created >= ? and time_archived is null order by time_updated desc limit 1",
|
|
8020
|
+
timestampFormat: "unix_ms"
|
|
8021
|
+
});
|
|
8022
|
+
} else if (this.type === "codex-cli") {
|
|
8023
|
+
probedSessionId = this.probeSessionIdFromConfig({
|
|
8024
|
+
dbPath: "~/.codex/state_5.sqlite",
|
|
8025
|
+
query: "select id from threads where cwd in ({dirs}) and created_at >= ? and archived = 0 order by created_at desc limit 1",
|
|
8026
|
+
timestampFormat: "unix_s"
|
|
8027
|
+
});
|
|
8028
|
+
} else if (this.type === "goose-cli") {
|
|
8029
|
+
probedSessionId = this.probeSessionIdFromConfig({
|
|
8030
|
+
dbPath: "~/.local/share/goose/sessions/sessions.db",
|
|
8031
|
+
query: "select id from sessions where working_dir in ({dirs}) and created_at >= ? order by updated_at desc limit 1",
|
|
8032
|
+
timestampFormat: "iso"
|
|
8033
|
+
});
|
|
8034
|
+
}
|
|
7935
8035
|
}
|
|
7936
8036
|
if (probedSessionId) {
|
|
7937
8037
|
this.promoteProviderSessionId(probedSessionId);
|
|
7938
8038
|
}
|
|
7939
8039
|
}
|
|
8040
|
+
/**
|
|
8041
|
+
* Generic session ID probe using declarative ProviderSessionProbe config.
|
|
8042
|
+
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
8043
|
+
*/
|
|
8044
|
+
probeSessionIdFromConfig(probe) {
|
|
8045
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os9.homedir());
|
|
8046
|
+
if (!fs5.existsSync(resolvedDbPath)) return null;
|
|
8047
|
+
const directories = this.getProbeDirectories();
|
|
8048
|
+
const minCreatedAt = Math.max(0, this.startedAt - 6e4);
|
|
8049
|
+
const tsFormat = probe.timestampFormat || "unix_ms";
|
|
8050
|
+
let timestampParam;
|
|
8051
|
+
if (tsFormat === "unix_s") {
|
|
8052
|
+
timestampParam = Math.floor(minCreatedAt / 1e3);
|
|
8053
|
+
} else if (tsFormat === "iso") {
|
|
8054
|
+
timestampParam = new Date(minCreatedAt).toISOString().slice(0, 19).replace("T", " ");
|
|
8055
|
+
} else {
|
|
8056
|
+
timestampParam = minCreatedAt;
|
|
8057
|
+
}
|
|
8058
|
+
const placeholders = this.buildSqlPlaceholderList(directories.length);
|
|
8059
|
+
const query = probe.query.replace("{dirs}", placeholders);
|
|
8060
|
+
try {
|
|
8061
|
+
return this.querySqliteText(resolvedDbPath, query, [...directories, timestampParam]);
|
|
8062
|
+
} catch {
|
|
8063
|
+
return null;
|
|
8064
|
+
}
|
|
8065
|
+
}
|
|
7940
8066
|
getState() {
|
|
7941
8067
|
const adapterStatus = this.adapter.getStatus();
|
|
7942
8068
|
const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
|
|
@@ -8234,34 +8360,6 @@ var CliProviderInstance = class {
|
|
|
8234
8360
|
});
|
|
8235
8361
|
LOG.info("CLI", `[${this.type}] discovered provider session id: ${nextSessionId}`);
|
|
8236
8362
|
}
|
|
8237
|
-
probeOpenCodeSessionId() {
|
|
8238
|
-
const dbPath = path8.join(os8.homedir(), ".local", "share", "opencode", "opencode.db");
|
|
8239
|
-
if (!fs5.existsSync(dbPath)) return null;
|
|
8240
|
-
const minCreatedAt = Math.max(0, this.startedAt - 6e4);
|
|
8241
|
-
const directories = this.getProbeDirectories();
|
|
8242
|
-
const query = `select id from session where directory in (${this.buildSqlPlaceholderList(directories.length)}) and time_created >= ? and time_archived is null order by time_updated desc limit 1;`;
|
|
8243
|
-
return this.querySqliteText(dbPath, query, [...directories, minCreatedAt]);
|
|
8244
|
-
}
|
|
8245
|
-
probeCodexSessionId() {
|
|
8246
|
-
const dbPath = path8.join(os8.homedir(), ".codex", "state_5.sqlite");
|
|
8247
|
-
if (!fs5.existsSync(dbPath)) return null;
|
|
8248
|
-
const minCreatedAt = Math.max(0, Math.floor((this.startedAt - 6e4) / 1e3));
|
|
8249
|
-
const directories = this.getProbeDirectories();
|
|
8250
|
-
const query = `select id from threads where cwd in (${this.buildSqlPlaceholderList(directories.length)}) and created_at >= ? and archived = 0 order by created_at desc limit 1;`;
|
|
8251
|
-
return this.querySqliteText(dbPath, query, [...directories, minCreatedAt]);
|
|
8252
|
-
}
|
|
8253
|
-
probeGooseSessionId() {
|
|
8254
|
-
const dbPath = path8.join(os8.homedir(), ".local", "share", "goose", "sessions", "sessions.db");
|
|
8255
|
-
if (!fs5.existsSync(dbPath)) return null;
|
|
8256
|
-
const minCreatedAtIso = new Date(Math.max(0, this.startedAt - 6e4)).toISOString().slice(0, 19).replace("T", " ");
|
|
8257
|
-
const directories = this.getProbeDirectories();
|
|
8258
|
-
const query = `select id from sessions where working_dir in (${this.buildSqlPlaceholderList(directories.length)}) and created_at >= ? order by updated_at desc limit 1;`;
|
|
8259
|
-
try {
|
|
8260
|
-
return this.querySqliteText(dbPath, query, [...directories, minCreatedAtIso]);
|
|
8261
|
-
} catch {
|
|
8262
|
-
return null;
|
|
8263
|
-
}
|
|
8264
|
-
}
|
|
8265
8363
|
getProbeDirectories() {
|
|
8266
8364
|
const dirs = /* @__PURE__ */ new Set();
|
|
8267
8365
|
const addDir = (value) => {
|
|
@@ -8733,13 +8831,13 @@ var AcpProviderInstance = class {
|
|
|
8733
8831
|
}
|
|
8734
8832
|
this.currentStatus = "waiting_approval";
|
|
8735
8833
|
this.detectStatusTransition();
|
|
8736
|
-
const approved = await new Promise((
|
|
8737
|
-
this.permissionResolvers.push(
|
|
8834
|
+
const approved = await new Promise((resolve9) => {
|
|
8835
|
+
this.permissionResolvers.push(resolve9);
|
|
8738
8836
|
setTimeout(() => {
|
|
8739
|
-
const idx = this.permissionResolvers.indexOf(
|
|
8837
|
+
const idx = this.permissionResolvers.indexOf(resolve9);
|
|
8740
8838
|
if (idx >= 0) {
|
|
8741
8839
|
this.permissionResolvers.splice(idx, 1);
|
|
8742
|
-
|
|
8840
|
+
resolve9(false);
|
|
8743
8841
|
}
|
|
8744
8842
|
}, 3e5);
|
|
8745
8843
|
});
|
|
@@ -9446,7 +9544,7 @@ var DaemonCliManager = class {
|
|
|
9446
9544
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
9447
9545
|
const trimmed = (workingDir || "").trim();
|
|
9448
9546
|
if (!trimmed) throw new Error("working directory required");
|
|
9449
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
9547
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os10.homedir()) : path9.resolve(trimmed);
|
|
9450
9548
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
9451
9549
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
9452
9550
|
const key = crypto4.randomUUID();
|
|
@@ -9530,7 +9628,19 @@ ${installInfo}`
|
|
|
9530
9628
|
return { runtimeSessionId: sessionId };
|
|
9531
9629
|
}
|
|
9532
9630
|
const cliInfo = await detectCLI(cliType, this.providerLoader);
|
|
9533
|
-
if (!cliInfo)
|
|
9631
|
+
if (!cliInfo) {
|
|
9632
|
+
const installHint = provider?.install || "";
|
|
9633
|
+
const displayName = provider?.displayName || provider?.name || cliType;
|
|
9634
|
+
const spawnCmd = provider?.spawn?.command || cliType;
|
|
9635
|
+
throw new Error(
|
|
9636
|
+
`${displayName} is not installed.
|
|
9637
|
+
Command '${spawnCmd}' not found on PATH.
|
|
9638
|
+
` + (installHint ? `
|
|
9639
|
+
${installHint}
|
|
9640
|
+
` : "") + `
|
|
9641
|
+
Run 'adhdev doctor' for detailed diagnostics.`
|
|
9642
|
+
);
|
|
9643
|
+
}
|
|
9534
9644
|
console.log(colorize("yellow", ` \u26A1 Starting CLI ${cliType} in ${resolvedDir}...`));
|
|
9535
9645
|
if (provider) {
|
|
9536
9646
|
console.log(colorize("cyan", ` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
|
|
@@ -9846,8 +9956,9 @@ ${installInfo}`
|
|
|
9846
9956
|
const dir = rdir.path;
|
|
9847
9957
|
if (!cliType) throw new Error("cliType required");
|
|
9848
9958
|
const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
|
|
9959
|
+
const prevCliArgs = found ? found.adapter.extraArgs : void 0;
|
|
9849
9960
|
if (found) await this.stopSession(found.key);
|
|
9850
|
-
await this.startSession(cliType, dir);
|
|
9961
|
+
await this.startSession(cliType, dir, args?.cliArgs || prevCliArgs, args?.initialModel);
|
|
9851
9962
|
return { success: true, restarted: true };
|
|
9852
9963
|
}
|
|
9853
9964
|
case "agent_command": {
|
|
@@ -9882,13 +9993,13 @@ ${installInfo}`
|
|
|
9882
9993
|
// src/launch.ts
|
|
9883
9994
|
var import_child_process6 = require("child_process");
|
|
9884
9995
|
var net = __toESM(require("net"));
|
|
9885
|
-
var
|
|
9996
|
+
var os12 = __toESM(require("os"));
|
|
9886
9997
|
var path11 = __toESM(require("path"));
|
|
9887
9998
|
|
|
9888
9999
|
// src/providers/provider-loader.ts
|
|
9889
10000
|
var fs6 = __toESM(require("fs"));
|
|
9890
10001
|
var path10 = __toESM(require("path"));
|
|
9891
|
-
var
|
|
10002
|
+
var os11 = __toESM(require("os"));
|
|
9892
10003
|
var chokidar = __toESM(require("chokidar"));
|
|
9893
10004
|
init_logger();
|
|
9894
10005
|
var ProviderLoader = class _ProviderLoader {
|
|
@@ -9908,7 +10019,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
9908
10019
|
static META_FILE = ".meta.json";
|
|
9909
10020
|
constructor(options) {
|
|
9910
10021
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
9911
|
-
const defaultProvidersDir = path10.join(
|
|
10022
|
+
const defaultProvidersDir = path10.join(os11.homedir(), ".adhdev", "providers");
|
|
9912
10023
|
if (options?.userDir) {
|
|
9913
10024
|
this.userDir = options.userDir;
|
|
9914
10025
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -10465,7 +10576,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
10465
10576
|
return { updated: false };
|
|
10466
10577
|
}
|
|
10467
10578
|
try {
|
|
10468
|
-
const etag = await new Promise((
|
|
10579
|
+
const etag = await new Promise((resolve9, reject) => {
|
|
10469
10580
|
const options = {
|
|
10470
10581
|
method: "HEAD",
|
|
10471
10582
|
hostname: "github.com",
|
|
@@ -10483,7 +10594,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
10483
10594
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
10484
10595
|
timeout: 1e4
|
|
10485
10596
|
}, (res2) => {
|
|
10486
|
-
|
|
10597
|
+
resolve9(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
10487
10598
|
});
|
|
10488
10599
|
req2.on("error", reject);
|
|
10489
10600
|
req2.on("timeout", () => {
|
|
@@ -10492,7 +10603,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
10492
10603
|
});
|
|
10493
10604
|
req2.end();
|
|
10494
10605
|
} else {
|
|
10495
|
-
|
|
10606
|
+
resolve9(res.headers.etag || res.headers["last-modified"] || "");
|
|
10496
10607
|
}
|
|
10497
10608
|
});
|
|
10498
10609
|
req.on("error", reject);
|
|
@@ -10508,8 +10619,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
10508
10619
|
return { updated: false };
|
|
10509
10620
|
}
|
|
10510
10621
|
this.log("Downloading latest providers from GitHub...");
|
|
10511
|
-
const tmpTar = path10.join(
|
|
10512
|
-
const tmpExtract = path10.join(
|
|
10622
|
+
const tmpTar = path10.join(os11.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
10623
|
+
const tmpExtract = path10.join(os11.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
10513
10624
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
10514
10625
|
fs6.mkdirSync(tmpExtract, { recursive: true });
|
|
10515
10626
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
@@ -10556,7 +10667,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
10556
10667
|
downloadFile(url, destPath) {
|
|
10557
10668
|
const https = require("https");
|
|
10558
10669
|
const http3 = require("http");
|
|
10559
|
-
return new Promise((
|
|
10670
|
+
return new Promise((resolve9, reject) => {
|
|
10560
10671
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
10561
10672
|
if (redirectCount > 5) {
|
|
10562
10673
|
reject(new Error("Too many redirects"));
|
|
@@ -10576,7 +10687,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
10576
10687
|
res.pipe(ws);
|
|
10577
10688
|
ws.on("finish", () => {
|
|
10578
10689
|
ws.close();
|
|
10579
|
-
|
|
10690
|
+
resolve9();
|
|
10580
10691
|
});
|
|
10581
10692
|
ws.on("error", reject);
|
|
10582
10693
|
});
|
|
@@ -10941,17 +11052,17 @@ async function findFreePort(ports) {
|
|
|
10941
11052
|
throw new Error("No free port found");
|
|
10942
11053
|
}
|
|
10943
11054
|
function checkPortFree(port) {
|
|
10944
|
-
return new Promise((
|
|
11055
|
+
return new Promise((resolve9) => {
|
|
10945
11056
|
const server = net.createServer();
|
|
10946
11057
|
server.unref();
|
|
10947
|
-
server.on("error", () =>
|
|
11058
|
+
server.on("error", () => resolve9(false));
|
|
10948
11059
|
server.listen(port, "127.0.0.1", () => {
|
|
10949
|
-
server.close(() =>
|
|
11060
|
+
server.close(() => resolve9(true));
|
|
10950
11061
|
});
|
|
10951
11062
|
});
|
|
10952
11063
|
}
|
|
10953
11064
|
async function isCdpActive(port) {
|
|
10954
|
-
return new Promise((
|
|
11065
|
+
return new Promise((resolve9) => {
|
|
10955
11066
|
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
10956
11067
|
timeout: 2e3
|
|
10957
11068
|
}, (res) => {
|
|
@@ -10960,21 +11071,21 @@ async function isCdpActive(port) {
|
|
|
10960
11071
|
res.on("end", () => {
|
|
10961
11072
|
try {
|
|
10962
11073
|
const info = JSON.parse(data);
|
|
10963
|
-
|
|
11074
|
+
resolve9(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
10964
11075
|
} catch {
|
|
10965
|
-
|
|
11076
|
+
resolve9(false);
|
|
10966
11077
|
}
|
|
10967
11078
|
});
|
|
10968
11079
|
});
|
|
10969
|
-
req.on("error", () =>
|
|
11080
|
+
req.on("error", () => resolve9(false));
|
|
10970
11081
|
req.on("timeout", () => {
|
|
10971
11082
|
req.destroy();
|
|
10972
|
-
|
|
11083
|
+
resolve9(false);
|
|
10973
11084
|
});
|
|
10974
11085
|
});
|
|
10975
11086
|
}
|
|
10976
11087
|
async function killIdeProcess(ideId) {
|
|
10977
|
-
const plat =
|
|
11088
|
+
const plat = os12.platform();
|
|
10978
11089
|
const appName = getMacAppIdentifiers()[ideId];
|
|
10979
11090
|
const winProcesses = getWinProcessNames()[ideId];
|
|
10980
11091
|
try {
|
|
@@ -11033,7 +11144,7 @@ async function killIdeProcess(ideId) {
|
|
|
11033
11144
|
}
|
|
11034
11145
|
}
|
|
11035
11146
|
function isIdeRunning(ideId) {
|
|
11036
|
-
const plat =
|
|
11147
|
+
const plat = os12.platform();
|
|
11037
11148
|
try {
|
|
11038
11149
|
if (plat === "darwin") {
|
|
11039
11150
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -11069,7 +11180,7 @@ function isIdeRunning(ideId) {
|
|
|
11069
11180
|
}
|
|
11070
11181
|
}
|
|
11071
11182
|
function detectCurrentWorkspace(ideId) {
|
|
11072
|
-
const plat =
|
|
11183
|
+
const plat = os12.platform();
|
|
11073
11184
|
if (plat === "darwin") {
|
|
11074
11185
|
try {
|
|
11075
11186
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -11089,7 +11200,7 @@ function detectCurrentWorkspace(ideId) {
|
|
|
11089
11200
|
const appName = appNameMap[ideId];
|
|
11090
11201
|
if (appName) {
|
|
11091
11202
|
const storagePath = path11.join(
|
|
11092
|
-
process.env.APPDATA || path11.join(
|
|
11203
|
+
process.env.APPDATA || path11.join(os12.homedir(), "AppData", "Roaming"),
|
|
11093
11204
|
appName,
|
|
11094
11205
|
"storage.json"
|
|
11095
11206
|
);
|
|
@@ -11111,7 +11222,7 @@ function detectCurrentWorkspace(ideId) {
|
|
|
11111
11222
|
return void 0;
|
|
11112
11223
|
}
|
|
11113
11224
|
async function launchWithCdp(options = {}) {
|
|
11114
|
-
const platform9 =
|
|
11225
|
+
const platform9 = os12.platform();
|
|
11115
11226
|
let targetIde;
|
|
11116
11227
|
const ides = await detectIDEs();
|
|
11117
11228
|
if (options.ideId) {
|
|
@@ -11263,8 +11374,8 @@ init_logger();
|
|
|
11263
11374
|
// src/logging/command-log.ts
|
|
11264
11375
|
var fs7 = __toESM(require("fs"));
|
|
11265
11376
|
var path12 = __toESM(require("path"));
|
|
11266
|
-
var
|
|
11267
|
-
var LOG_DIR2 = process.platform === "win32" ? path12.join(process.env.LOCALAPPDATA || process.env.APPDATA || path12.join(
|
|
11377
|
+
var os13 = __toESM(require("os"));
|
|
11378
|
+
var LOG_DIR2 = process.platform === "win32" ? path12.join(process.env.LOCALAPPDATA || process.env.APPDATA || path12.join(os13.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path12.join(os13.homedir(), "Library", "Logs", "adhdev") : path12.join(os13.homedir(), ".local", "share", "adhdev", "logs");
|
|
11268
11379
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
11269
11380
|
var MAX_DAYS = 7;
|
|
11270
11381
|
try {
|
|
@@ -11399,7 +11510,7 @@ cleanOldFiles();
|
|
|
11399
11510
|
init_logger();
|
|
11400
11511
|
|
|
11401
11512
|
// src/status/snapshot.ts
|
|
11402
|
-
var
|
|
11513
|
+
var os14 = __toESM(require("os"));
|
|
11403
11514
|
init_config();
|
|
11404
11515
|
init_terminal_screen();
|
|
11405
11516
|
init_logger();
|
|
@@ -11515,16 +11626,16 @@ function buildStatusSnapshot(options) {
|
|
|
11515
11626
|
version: options.version,
|
|
11516
11627
|
daemonMode: options.daemonMode,
|
|
11517
11628
|
machine: {
|
|
11518
|
-
hostname:
|
|
11519
|
-
platform:
|
|
11520
|
-
arch:
|
|
11521
|
-
cpus:
|
|
11629
|
+
hostname: os14.hostname(),
|
|
11630
|
+
platform: os14.platform(),
|
|
11631
|
+
arch: os14.arch(),
|
|
11632
|
+
cpus: os14.cpus().length,
|
|
11522
11633
|
totalMem: memSnap.totalMem,
|
|
11523
11634
|
freeMem: memSnap.freeMem,
|
|
11524
11635
|
availableMem: memSnap.availableMem,
|
|
11525
|
-
loadavg:
|
|
11526
|
-
uptime:
|
|
11527
|
-
release:
|
|
11636
|
+
loadavg: os14.loadavg(),
|
|
11637
|
+
uptime: os14.uptime(),
|
|
11638
|
+
release: os14.release()
|
|
11528
11639
|
},
|
|
11529
11640
|
machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
|
|
11530
11641
|
timestamp: options.timestamp ?? Date.now(),
|
|
@@ -11544,11 +11655,11 @@ function buildStatusSnapshot(options) {
|
|
|
11544
11655
|
var import_child_process7 = require("child_process");
|
|
11545
11656
|
var import_child_process8 = require("child_process");
|
|
11546
11657
|
var fs8 = __toESM(require("fs"));
|
|
11547
|
-
var
|
|
11658
|
+
var os15 = __toESM(require("os"));
|
|
11548
11659
|
var path13 = __toESM(require("path"));
|
|
11549
11660
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
11550
11661
|
function getUpgradeLogPath() {
|
|
11551
|
-
const home =
|
|
11662
|
+
const home = os15.homedir();
|
|
11552
11663
|
const dir = path13.join(home, ".adhdev");
|
|
11553
11664
|
fs8.mkdirSync(dir, { recursive: true });
|
|
11554
11665
|
return path13.join(dir, "daemon-upgrade.log");
|
|
@@ -11581,14 +11692,14 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
11581
11692
|
while (Date.now() - start < timeoutMs) {
|
|
11582
11693
|
try {
|
|
11583
11694
|
process.kill(pid, 0);
|
|
11584
|
-
await new Promise((
|
|
11695
|
+
await new Promise((resolve9) => setTimeout(resolve9, 250));
|
|
11585
11696
|
} catch {
|
|
11586
11697
|
return;
|
|
11587
11698
|
}
|
|
11588
11699
|
}
|
|
11589
11700
|
}
|
|
11590
11701
|
function stopSessionHostProcesses(appName) {
|
|
11591
|
-
const pidFile = path13.join(
|
|
11702
|
+
const pidFile = path13.join(os15.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
11592
11703
|
try {
|
|
11593
11704
|
if (fs8.existsSync(pidFile)) {
|
|
11594
11705
|
const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -11617,7 +11728,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
11617
11728
|
}
|
|
11618
11729
|
}
|
|
11619
11730
|
function removeDaemonPidFile() {
|
|
11620
|
-
const pidFile = path13.join(
|
|
11731
|
+
const pidFile = path13.join(os15.homedir(), ".adhdev", "daemon.pid");
|
|
11621
11732
|
try {
|
|
11622
11733
|
fs8.unlinkSync(pidFile);
|
|
11623
11734
|
} catch {
|
|
@@ -13127,10 +13238,10 @@ var ProviderInstanceManager = class {
|
|
|
13127
13238
|
// src/providers/version-archive.ts
|
|
13128
13239
|
var fs10 = __toESM(require("fs"));
|
|
13129
13240
|
var path14 = __toESM(require("path"));
|
|
13130
|
-
var
|
|
13241
|
+
var os16 = __toESM(require("os"));
|
|
13131
13242
|
var import_child_process9 = require("child_process");
|
|
13132
13243
|
var import_os3 = require("os");
|
|
13133
|
-
var ARCHIVE_PATH = path14.join(
|
|
13244
|
+
var ARCHIVE_PATH = path14.join(os16.homedir(), ".adhdev", "version-history.json");
|
|
13134
13245
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
13135
13246
|
var VersionArchive = class {
|
|
13136
13247
|
history = {};
|
|
@@ -13217,7 +13328,7 @@ function getVersion(binary, versionCommand) {
|
|
|
13217
13328
|
function checkPathExists2(paths) {
|
|
13218
13329
|
for (const p of paths) {
|
|
13219
13330
|
if (p.includes("*")) {
|
|
13220
|
-
const home =
|
|
13331
|
+
const home = os16.homedir();
|
|
13221
13332
|
const resolved = p.replace(/\*/g, home.split(path14.sep).pop() || "");
|
|
13222
13333
|
if (fs10.existsSync(resolved)) return resolved;
|
|
13223
13334
|
} else {
|
|
@@ -14814,7 +14925,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
|
|
|
14814
14925
|
return { target, instance, adapter };
|
|
14815
14926
|
}
|
|
14816
14927
|
function sleep(ms) {
|
|
14817
|
-
return new Promise((
|
|
14928
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
14818
14929
|
}
|
|
14819
14930
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
14820
14931
|
const startedAt = Date.now();
|
|
@@ -15545,7 +15656,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
15545
15656
|
// src/daemon/dev-auto-implement.ts
|
|
15546
15657
|
var fs13 = __toESM(require("fs"));
|
|
15547
15658
|
var path17 = __toESM(require("path"));
|
|
15548
|
-
var
|
|
15659
|
+
var os17 = __toESM(require("os"));
|
|
15549
15660
|
function getAutoImplPid(ctx) {
|
|
15550
15661
|
const proc = ctx.autoImplProcess;
|
|
15551
15662
|
return proc && typeof proc.pid === "number" && proc.pid > 0 ? proc.pid : null;
|
|
@@ -15748,7 +15859,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
15748
15859
|
});
|
|
15749
15860
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
15750
15861
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
15751
|
-
const tmpDir = path17.join(
|
|
15862
|
+
const tmpDir = path17.join(os17.tmpdir(), "adhdev-autoimpl");
|
|
15752
15863
|
if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
|
|
15753
15864
|
const promptFile = path17.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
15754
15865
|
fs13.writeFileSync(promptFile, prompt, "utf-8");
|
|
@@ -15902,7 +16013,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
15902
16013
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
15903
16014
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
15904
16015
|
let shellCmd;
|
|
15905
|
-
const isWin =
|
|
16016
|
+
const isWin = os17.platform() === "win32";
|
|
15906
16017
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
15907
16018
|
if (command === "claude") {
|
|
15908
16019
|
const args = [...baseArgs, "--dangerously-skip-permissions"];
|
|
@@ -15946,7 +16057,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
15946
16057
|
try {
|
|
15947
16058
|
const pty3 = require("node-pty");
|
|
15948
16059
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
15949
|
-
const isWin2 =
|
|
16060
|
+
const isWin2 = os17.platform() === "win32";
|
|
15950
16061
|
child = pty3.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
15951
16062
|
name: "xterm-256color",
|
|
15952
16063
|
cols: 120,
|
|
@@ -16984,15 +17095,15 @@ var DevServer = class _DevServer {
|
|
|
16984
17095
|
this.json(res, 500, { error: e.message });
|
|
16985
17096
|
}
|
|
16986
17097
|
});
|
|
16987
|
-
return new Promise((
|
|
17098
|
+
return new Promise((resolve9, reject) => {
|
|
16988
17099
|
this.server.listen(port, "127.0.0.1", () => {
|
|
16989
17100
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
16990
|
-
|
|
17101
|
+
resolve9();
|
|
16991
17102
|
});
|
|
16992
17103
|
this.server.on("error", (e) => {
|
|
16993
17104
|
if (e.code === "EADDRINUSE") {
|
|
16994
17105
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
16995
|
-
|
|
17106
|
+
resolve9();
|
|
16996
17107
|
} else {
|
|
16997
17108
|
reject(e);
|
|
16998
17109
|
}
|
|
@@ -17075,20 +17186,20 @@ var DevServer = class _DevServer {
|
|
|
17075
17186
|
child.stderr?.on("data", (d) => {
|
|
17076
17187
|
stderr += d.toString().slice(0, 2e3);
|
|
17077
17188
|
});
|
|
17078
|
-
await new Promise((
|
|
17189
|
+
await new Promise((resolve9) => {
|
|
17079
17190
|
const timer = setTimeout(() => {
|
|
17080
17191
|
child.kill();
|
|
17081
|
-
|
|
17192
|
+
resolve9();
|
|
17082
17193
|
}, 3e3);
|
|
17083
17194
|
child.on("exit", () => {
|
|
17084
17195
|
clearTimeout(timer);
|
|
17085
|
-
|
|
17196
|
+
resolve9();
|
|
17086
17197
|
});
|
|
17087
17198
|
child.stdout?.once("data", () => {
|
|
17088
17199
|
setTimeout(() => {
|
|
17089
17200
|
child.kill();
|
|
17090
17201
|
clearTimeout(timer);
|
|
17091
|
-
|
|
17202
|
+
resolve9();
|
|
17092
17203
|
}, 500);
|
|
17093
17204
|
});
|
|
17094
17205
|
});
|
|
@@ -17597,14 +17708,14 @@ var DevServer = class _DevServer {
|
|
|
17597
17708
|
child.stderr?.on("data", (d) => {
|
|
17598
17709
|
stderr += d.toString();
|
|
17599
17710
|
});
|
|
17600
|
-
await new Promise((
|
|
17711
|
+
await new Promise((resolve9) => {
|
|
17601
17712
|
const timer = setTimeout(() => {
|
|
17602
17713
|
child.kill();
|
|
17603
|
-
|
|
17714
|
+
resolve9();
|
|
17604
17715
|
}, timeout);
|
|
17605
17716
|
child.on("exit", () => {
|
|
17606
17717
|
clearTimeout(timer);
|
|
17607
|
-
|
|
17718
|
+
resolve9();
|
|
17608
17719
|
});
|
|
17609
17720
|
});
|
|
17610
17721
|
const elapsed = Date.now() - start;
|
|
@@ -18279,14 +18390,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
18279
18390
|
res.end(JSON.stringify(data, null, 2));
|
|
18280
18391
|
}
|
|
18281
18392
|
async readBody(req) {
|
|
18282
|
-
return new Promise((
|
|
18393
|
+
return new Promise((resolve9) => {
|
|
18283
18394
|
let body = "";
|
|
18284
18395
|
req.on("data", (chunk) => body += chunk);
|
|
18285
18396
|
req.on("end", () => {
|
|
18286
18397
|
try {
|
|
18287
|
-
|
|
18398
|
+
resolve9(JSON.parse(body));
|
|
18288
18399
|
} catch {
|
|
18289
|
-
|
|
18400
|
+
resolve9({});
|
|
18290
18401
|
}
|
|
18291
18402
|
});
|
|
18292
18403
|
});
|
|
@@ -18359,12 +18470,12 @@ init_provider_cli_adapter();
|
|
|
18359
18470
|
init_pty_transport();
|
|
18360
18471
|
|
|
18361
18472
|
// src/cli-adapters/session-host-transport.ts
|
|
18362
|
-
var
|
|
18473
|
+
var import_session_host_core2 = require("@adhdev/session-host-core");
|
|
18363
18474
|
init_logger();
|
|
18364
18475
|
var SessionHostRuntimeTransport = class {
|
|
18365
18476
|
constructor(options) {
|
|
18366
18477
|
this.options = options;
|
|
18367
|
-
this.client = new
|
|
18478
|
+
this.client = new import_session_host_core2.SessionHostClient({
|
|
18368
18479
|
endpoint: options.endpoint,
|
|
18369
18480
|
appName: options.appName
|
|
18370
18481
|
});
|
|
@@ -18733,11 +18844,11 @@ var SessionHostPtyTransportFactory = class {
|
|
|
18733
18844
|
};
|
|
18734
18845
|
|
|
18735
18846
|
// src/session-host/runtime-support.ts
|
|
18736
|
-
var
|
|
18847
|
+
var import_session_host_core3 = require("@adhdev/session-host-core");
|
|
18737
18848
|
var STARTUP_TIMEOUT_MS = 8e3;
|
|
18738
18849
|
var STARTUP_POLL_MS = 200;
|
|
18739
18850
|
async function canConnect(endpoint) {
|
|
18740
|
-
const client = new
|
|
18851
|
+
const client = new import_session_host_core3.SessionHostClient({ endpoint });
|
|
18741
18852
|
try {
|
|
18742
18853
|
await client.connect();
|
|
18743
18854
|
await client.close();
|
|
@@ -18750,19 +18861,19 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
|
|
|
18750
18861
|
const deadline = Date.now() + timeoutMs;
|
|
18751
18862
|
while (Date.now() < deadline) {
|
|
18752
18863
|
if (await canConnect(endpoint)) return;
|
|
18753
|
-
await new Promise((
|
|
18864
|
+
await new Promise((resolve9) => setTimeout(resolve9, STARTUP_POLL_MS));
|
|
18754
18865
|
}
|
|
18755
18866
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
18756
18867
|
}
|
|
18757
18868
|
async function ensureSessionHostReady(options) {
|
|
18758
|
-
const endpoint = (0,
|
|
18869
|
+
const endpoint = (0, import_session_host_core3.getDefaultSessionHostEndpoint)(options.appName || "adhdev");
|
|
18759
18870
|
if (await canConnect(endpoint)) return endpoint;
|
|
18760
18871
|
options.spawnHost();
|
|
18761
18872
|
await waitForReady(endpoint, options.timeoutMs);
|
|
18762
18873
|
return endpoint;
|
|
18763
18874
|
}
|
|
18764
18875
|
async function listHostedCliRuntimes(endpoint) {
|
|
18765
|
-
const client = new
|
|
18876
|
+
const client = new import_session_host_core3.SessionHostClient({ endpoint });
|
|
18766
18877
|
try {
|
|
18767
18878
|
const response = await client.request({
|
|
18768
18879
|
type: "list_sessions",
|
|
@@ -18906,10 +19017,10 @@ async function installExtension(ide, extension) {
|
|
|
18906
19017
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
18907
19018
|
const fs15 = await import("fs");
|
|
18908
19019
|
fs15.writeFileSync(vsixPath, buffer);
|
|
18909
|
-
return new Promise((
|
|
19020
|
+
return new Promise((resolve9) => {
|
|
18910
19021
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
18911
19022
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
18912
|
-
|
|
19023
|
+
resolve9({
|
|
18913
19024
|
extensionId: extension.id,
|
|
18914
19025
|
marketplaceId: extension.marketplaceId,
|
|
18915
19026
|
success: !error,
|
|
@@ -18922,11 +19033,11 @@ async function installExtension(ide, extension) {
|
|
|
18922
19033
|
} catch (e) {
|
|
18923
19034
|
}
|
|
18924
19035
|
}
|
|
18925
|
-
return new Promise((
|
|
19036
|
+
return new Promise((resolve9) => {
|
|
18926
19037
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
18927
19038
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
|
|
18928
19039
|
if (error) {
|
|
18929
|
-
|
|
19040
|
+
resolve9({
|
|
18930
19041
|
extensionId: extension.id,
|
|
18931
19042
|
marketplaceId: extension.marketplaceId,
|
|
18932
19043
|
success: false,
|
|
@@ -18934,7 +19045,7 @@ async function installExtension(ide, extension) {
|
|
|
18934
19045
|
error: stderr || error.message
|
|
18935
19046
|
});
|
|
18936
19047
|
} else {
|
|
18937
|
-
|
|
19048
|
+
resolve9({
|
|
18938
19049
|
extensionId: extension.id,
|
|
18939
19050
|
marketplaceId: extension.marketplaceId,
|
|
18940
19051
|
success: true,
|