@adhdev/daemon-core 0.8.11 → 0.8.13

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.mjs CHANGED
@@ -632,6 +632,13 @@ function logTerminalBackendSelection(preference, ghosttyAvailable, backendKind)
632
632
  const key = `${preference}:${ghosttyAvailable}:${backendKind}`;
633
633
  if (loggedTerminalBackends.has(key)) return;
634
634
  loggedTerminalBackends.add(key);
635
+ if (backendKind === "xterm" && preference !== "xterm" && !ghosttyAvailable) {
636
+ LOG.warn(
637
+ "Terminal",
638
+ `[terminal-screen] ghostty-vt unavailable; using xterm fallback (preference=${preference})`
639
+ );
640
+ return;
641
+ }
635
642
  LOG.info(
636
643
  "Terminal",
637
644
  `[terminal-screen] backend=${backendKind} preference=${preference} ghosttyAvailable=${ghosttyAvailable}`
@@ -735,11 +742,21 @@ var init_pty_transport = __esm({
735
742
  NodePtyTransportFactory = class {
736
743
  spawn(command, args, options) {
737
744
  if (!pty) throw new Error("node-pty is not installed");
745
+ let cwd = options.cwd;
746
+ if (cwd) {
747
+ try {
748
+ const fs15 = __require("fs");
749
+ const stat = fs15.statSync(cwd);
750
+ if (!stat.isDirectory()) cwd = os7.homedir();
751
+ } catch {
752
+ cwd = os7.homedir();
753
+ }
754
+ }
738
755
  const handle = pty.spawn(command, args, {
739
- name: os7.platform() === "win32" ? "xterm-color" : "xterm-256color",
756
+ name: "xterm-256color",
740
757
  cols: options.cols,
741
758
  rows: options.rows,
742
- cwd: options.cwd,
759
+ cwd,
743
760
  env: options.env
744
761
  });
745
762
  return new NodePtyRuntimeTransport(handle);
@@ -748,6 +765,18 @@ var init_pty_transport = __esm({
748
765
  }
749
766
  });
750
767
 
768
+ // src/cli-adapters/spawn-env.ts
769
+ import {
770
+ sanitizeSpawnEnv,
771
+ applyTerminalColorEnv,
772
+ ensureNodePtySpawnHelperPermissions
773
+ } from "@adhdev/session-host-core";
774
+ var init_spawn_env = __esm({
775
+ "src/cli-adapters/spawn-env.ts"() {
776
+ "use strict";
777
+ }
778
+ });
779
+
751
780
  // src/cli-adapters/provider-cli-adapter.ts
752
781
  var provider_cli_adapter_exports = {};
753
782
  __export(provider_cli_adapter_exports, {
@@ -766,20 +795,6 @@ function stripTerminalNoise(str) {
766
795
  function sanitizeTerminalText(str) {
767
796
  return stripTerminalNoise(stripAnsi(str));
768
797
  }
769
- function buildCliSpawnEnv(baseEnv, overrides) {
770
- const env = {};
771
- const source = { ...baseEnv, ...overrides || {} };
772
- for (const [key, value] of Object.entries(source)) {
773
- if (typeof value !== "string") continue;
774
- env[key] = value;
775
- }
776
- for (const key of Object.keys(env)) {
777
- if (key === "INIT_CWD" || key === "NO_COLOR" || key === "FORCE_COLOR" || 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_")) {
778
- delete env[key];
779
- }
780
- }
781
- return env;
782
- }
783
798
  function computeTerminalQueryTail(buffer) {
784
799
  const prefixes = ["\x1B[6n", "\x1B[?6n"];
785
800
  const maxLength = prefixes.reduce((n, value) => Math.max(n, value.length), 0) - 1;
@@ -908,34 +923,21 @@ function normalizeCliProviderForRuntime(raw) {
908
923
  }
909
924
  };
910
925
  }
911
- var pty2, ProviderCliAdapter;
926
+ var pty2, buildCliSpawnEnv, ProviderCliAdapter;
912
927
  var init_provider_cli_adapter = __esm({
913
928
  "src/cli-adapters/provider-cli-adapter.ts"() {
914
929
  "use strict";
915
930
  init_logger();
916
931
  init_terminal_screen();
917
932
  init_pty_transport();
933
+ init_spawn_env();
918
934
  try {
919
935
  pty2 = __require("node-pty");
920
- if (os8.platform() !== "win32") {
921
- try {
922
- const fs15 = __require("fs");
923
- const ptyDir = path7.resolve(path7.dirname(__require.resolve("node-pty")), "..");
924
- const platformArch = `${os8.platform()}-${os8.arch()}`;
925
- const helper = path7.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
926
- if (fs15.existsSync(helper)) {
927
- const stat = fs15.statSync(helper);
928
- if (!(stat.mode & 73)) {
929
- fs15.chmodSync(helper, stat.mode | 493);
930
- LOG.info("CLI", "[node-pty] Fixed spawn-helper permissions");
931
- }
932
- }
933
- } catch {
934
- }
935
- }
936
+ ensureNodePtySpawnHelperPermissions((msg) => LOG.info("CLI", msg));
936
937
  } catch {
937
938
  LOG.error("CLI", "[ProviderCliAdapter] node-pty not found. Terminal features disabled.");
938
939
  }
940
+ buildCliSpawnEnv = sanitizeSpawnEnv;
939
941
  ProviderCliAdapter = class _ProviderCliAdapter {
940
942
  constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
941
943
  this.extraArgs = extraArgs;
@@ -1302,6 +1304,12 @@ var init_provider_cli_adapter = __esm({
1302
1304
  shellArgs = ["-l", "-c", fullCmd];
1303
1305
  this.ptyProcess = this.transportFactory.spawn(shellCmd, shellArgs, ptyOpts);
1304
1306
  } else {
1307
+ if (isWin) {
1308
+ 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})` : "";
1309
+ if (hint) {
1310
+ throw new Error(`Failed to spawn CLI${hint}: ${msg}`);
1311
+ }
1312
+ }
1305
1313
  throw err;
1306
1314
  }
1307
1315
  }
@@ -1476,7 +1484,7 @@ var init_provider_cli_adapter = __esm({
1476
1484
  `[${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)}`
1477
1485
  );
1478
1486
  }
1479
- await new Promise((resolve10) => setTimeout(resolve10, 50));
1487
+ await new Promise((resolve9) => setTimeout(resolve9, 50));
1480
1488
  }
1481
1489
  const finalScreenText = this.terminalScreen.getText() || "";
1482
1490
  LOG.warn(
@@ -1863,7 +1871,7 @@ ${data.message || ""}`.trim();
1863
1871
  if (this.startupParseGate) {
1864
1872
  const deadline = Date.now() + 1e4;
1865
1873
  while (this.startupParseGate && Date.now() < deadline) {
1866
- await new Promise((resolve10) => setTimeout(resolve10, 50));
1874
+ await new Promise((resolve9) => setTimeout(resolve9, 50));
1867
1875
  }
1868
1876
  }
1869
1877
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
@@ -2054,7 +2062,8 @@ ${data.message || ""}`.trim();
2054
2062
  const payload = stopCommand.endsWith("\r") || stopCommand.endsWith("\n") ? stopCommand : `${stopCommand}${this.sendKey}`;
2055
2063
  this.ptyProcess.write(payload);
2056
2064
  };
2057
- if (wasProcessing) setTimeout(writeCommand, 250);
2065
+ const interruptGraceMs = typeof resume.interruptGraceMs === "number" ? Math.max(100, resume.interruptGraceMs) : 500;
2066
+ if (wasProcessing) setTimeout(writeCommand, interruptGraceMs);
2058
2067
  else writeCommand();
2059
2068
  } else {
2060
2069
  this.ptyProcess.write("");
@@ -2070,17 +2079,17 @@ ${data.message || ""}`.trim();
2070
2079
  }
2071
2080
  }
2072
2081
  waitForStopped(timeoutMs) {
2073
- return new Promise((resolve10) => {
2082
+ return new Promise((resolve9) => {
2074
2083
  const startedAt = Date.now();
2075
2084
  const timer = setInterval(() => {
2076
2085
  if (!this.ptyProcess || this.currentStatus === "stopped") {
2077
2086
  clearInterval(timer);
2078
- resolve10(true);
2087
+ resolve9(true);
2079
2088
  return;
2080
2089
  }
2081
2090
  if (Date.now() - startedAt >= timeoutMs) {
2082
2091
  clearInterval(timer);
2083
- resolve10(false);
2092
+ resolve9(false);
2084
2093
  }
2085
2094
  }, 100);
2086
2095
  });
@@ -2099,6 +2108,18 @@ ${data.message || ""}`.trim();
2099
2108
  clearTimeout(this.submitRetryTimer);
2100
2109
  this.submitRetryTimer = null;
2101
2110
  }
2111
+ if (this.responseTimeout) {
2112
+ clearTimeout(this.responseTimeout);
2113
+ this.responseTimeout = null;
2114
+ }
2115
+ if (this.idleTimeout) {
2116
+ clearTimeout(this.idleTimeout);
2117
+ this.idleTimeout = null;
2118
+ }
2119
+ if (this.pendingScriptStatusTimer) {
2120
+ clearTimeout(this.pendingScriptStatusTimer);
2121
+ this.pendingScriptStatusTimer = null;
2122
+ }
2102
2123
  if (this.pendingOutputParseTimer) {
2103
2124
  clearTimeout(this.pendingOutputParseTimer);
2104
2125
  this.pendingOutputParseTimer = null;
@@ -2140,6 +2161,18 @@ ${data.message || ""}`.trim();
2140
2161
  clearTimeout(this.submitRetryTimer);
2141
2162
  this.submitRetryTimer = null;
2142
2163
  }
2164
+ if (this.responseTimeout) {
2165
+ clearTimeout(this.responseTimeout);
2166
+ this.responseTimeout = null;
2167
+ }
2168
+ if (this.idleTimeout) {
2169
+ clearTimeout(this.idleTimeout);
2170
+ this.idleTimeout = null;
2171
+ }
2172
+ if (this.pendingScriptStatusTimer) {
2173
+ clearTimeout(this.pendingScriptStatusTimer);
2174
+ this.pendingScriptStatusTimer = null;
2175
+ }
2143
2176
  if (this.pendingOutputParseTimer) {
2144
2177
  clearTimeout(this.pendingOutputParseTimer);
2145
2178
  this.pendingOutputParseTimer = null;
@@ -2666,8 +2699,8 @@ async function detectIDEs() {
2666
2699
  if (existsSync3(bundledCli)) resolvedCli = bundledCli;
2667
2700
  }
2668
2701
  if (!resolvedCli && appPath && os18 === "win32") {
2669
- const { dirname: dirname7 } = await import("path");
2670
- const appDir = dirname7(appPath);
2702
+ const { dirname: dirname6 } = await import("path");
2703
+ const appDir = dirname6(appPath);
2671
2704
  const candidates = [
2672
2705
  `${appDir}\\\\bin\\\\${def.cli}.cmd`,
2673
2706
  `${appDir}\\\\bin\\\\${def.cli}`,
@@ -2705,20 +2738,20 @@ function parseVersion(raw) {
2705
2738
  return match ? match[1] : raw.split("\n")[0].slice(0, 100);
2706
2739
  }
2707
2740
  function execAsync(cmd, timeoutMs = 5e3) {
2708
- return new Promise((resolve10) => {
2741
+ return new Promise((resolve9) => {
2709
2742
  const child = exec(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
2710
2743
  if (err || !stdout?.trim()) {
2711
- resolve10(null);
2744
+ resolve9(null);
2712
2745
  } else {
2713
- resolve10(stdout.trim());
2746
+ resolve9(stdout.trim());
2714
2747
  }
2715
2748
  });
2716
- child.on("error", () => resolve10(null));
2749
+ child.on("error", () => resolve9(null));
2717
2750
  });
2718
2751
  }
2719
2752
  async function detectCLIs(providerLoader) {
2720
- const platform10 = os2.platform();
2721
- const whichCmd = platform10 === "win32" ? "where" : "which";
2753
+ const platform9 = os2.platform();
2754
+ const whichCmd = platform9 === "win32" ? "where" : "which";
2722
2755
  const cliList = providerLoader ? providerLoader.getCliDetectionList() : [];
2723
2756
  const results = await Promise.all(
2724
2757
  cliList.map(async (cli) => {
@@ -2753,6 +2786,39 @@ async function detectCLIs(providerLoader) {
2753
2786
  }
2754
2787
  async function detectCLI(cliId, providerLoader) {
2755
2788
  const resolvedId = providerLoader ? providerLoader.resolveAlias(cliId) : cliId;
2789
+ if (providerLoader) {
2790
+ const cliList = providerLoader.getCliDetectionList();
2791
+ const target = cliList.find((c) => c.id === resolvedId);
2792
+ if (target) {
2793
+ const platform9 = os2.platform();
2794
+ const whichCmd = platform9 === "win32" ? "where" : "which";
2795
+ try {
2796
+ const pathResult = await execAsync(`${whichCmd} ${target.command}`);
2797
+ if (!pathResult) return null;
2798
+ const firstPath = pathResult.split("\n")[0];
2799
+ let version;
2800
+ try {
2801
+ const versionCommands = [
2802
+ target.versionCommand,
2803
+ `${target.command} --version`,
2804
+ `${target.command} -V`,
2805
+ `${target.command} -v`
2806
+ ].filter((v) => !!v);
2807
+ for (const versionCommand of versionCommands) {
2808
+ const versionResult = await execAsync(versionCommand, 3e3);
2809
+ if (versionResult) {
2810
+ version = parseVersion(versionResult);
2811
+ break;
2812
+ }
2813
+ }
2814
+ } catch {
2815
+ }
2816
+ return { ...target, installed: true, version, path: firstPath };
2817
+ } catch {
2818
+ return null;
2819
+ }
2820
+ }
2821
+ }
2756
2822
  const all = await detectCLIs(providerLoader);
2757
2823
  return all.find((c) => c.id === resolvedId && c.installed) || null;
2758
2824
  }
@@ -2880,7 +2946,7 @@ var DaemonCdpManager = class {
2880
2946
  * Returns multiple entries if multiple IDE windows are open on same port
2881
2947
  */
2882
2948
  static listAllTargets(port) {
2883
- return new Promise((resolve10) => {
2949
+ return new Promise((resolve9) => {
2884
2950
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
2885
2951
  let data = "";
2886
2952
  res.on("data", (chunk) => data += chunk.toString());
@@ -2896,16 +2962,16 @@ var DaemonCdpManager = class {
2896
2962
  (t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
2897
2963
  );
2898
2964
  const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
2899
- resolve10(mainPages.length > 0 ? mainPages : fallbackPages);
2965
+ resolve9(mainPages.length > 0 ? mainPages : fallbackPages);
2900
2966
  } catch {
2901
- resolve10([]);
2967
+ resolve9([]);
2902
2968
  }
2903
2969
  });
2904
2970
  });
2905
- req.on("error", () => resolve10([]));
2971
+ req.on("error", () => resolve9([]));
2906
2972
  req.setTimeout(2e3, () => {
2907
2973
  req.destroy();
2908
- resolve10([]);
2974
+ resolve9([]);
2909
2975
  });
2910
2976
  });
2911
2977
  }
@@ -2945,7 +3011,7 @@ var DaemonCdpManager = class {
2945
3011
  }
2946
3012
  }
2947
3013
  findTargetOnPort(port) {
2948
- return new Promise((resolve10) => {
3014
+ return new Promise((resolve9) => {
2949
3015
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
2950
3016
  let data = "";
2951
3017
  res.on("data", (chunk) => data += chunk.toString());
@@ -2956,7 +3022,7 @@ var DaemonCdpManager = class {
2956
3022
  (t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
2957
3023
  );
2958
3024
  if (pages.length === 0) {
2959
- resolve10(targets.find((t) => t.webSocketDebuggerUrl) || null);
3025
+ resolve9(targets.find((t) => t.webSocketDebuggerUrl) || null);
2960
3026
  return;
2961
3027
  }
2962
3028
  const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
@@ -2966,24 +3032,24 @@ var DaemonCdpManager = class {
2966
3032
  const specific = list.find((t) => t.id === this._targetId);
2967
3033
  if (specific) {
2968
3034
  this._pageTitle = specific.title || "";
2969
- resolve10(specific);
3035
+ resolve9(specific);
2970
3036
  } else {
2971
3037
  this.log(`[CDP] Target ${this._targetId} not found in page list`);
2972
- resolve10(null);
3038
+ resolve9(null);
2973
3039
  }
2974
3040
  return;
2975
3041
  }
2976
3042
  this._pageTitle = list[0]?.title || "";
2977
- resolve10(list[0]);
3043
+ resolve9(list[0]);
2978
3044
  } catch {
2979
- resolve10(null);
3045
+ resolve9(null);
2980
3046
  }
2981
3047
  });
2982
3048
  });
2983
- req.on("error", () => resolve10(null));
3049
+ req.on("error", () => resolve9(null));
2984
3050
  req.setTimeout(2e3, () => {
2985
3051
  req.destroy();
2986
- resolve10(null);
3052
+ resolve9(null);
2987
3053
  });
2988
3054
  });
2989
3055
  }
@@ -2994,7 +3060,7 @@ var DaemonCdpManager = class {
2994
3060
  this.extensionProviders = providers;
2995
3061
  }
2996
3062
  connectToTarget(wsUrl) {
2997
- return new Promise((resolve10) => {
3063
+ return new Promise((resolve9) => {
2998
3064
  this.ws = new WebSocket(wsUrl);
2999
3065
  this.ws.on("open", async () => {
3000
3066
  this._connected = true;
@@ -3004,17 +3070,17 @@ var DaemonCdpManager = class {
3004
3070
  }
3005
3071
  this.connectBrowserWs().catch(() => {
3006
3072
  });
3007
- resolve10(true);
3073
+ resolve9(true);
3008
3074
  });
3009
3075
  this.ws.on("message", (data) => {
3010
3076
  try {
3011
3077
  const msg = JSON.parse(data.toString());
3012
3078
  if (msg.id && this.pending.has(msg.id)) {
3013
- const { resolve: resolve11, reject } = this.pending.get(msg.id);
3079
+ const { resolve: resolve10, reject } = this.pending.get(msg.id);
3014
3080
  this.pending.delete(msg.id);
3015
3081
  this.failureCount = 0;
3016
3082
  if (msg.error) reject(new Error(msg.error.message));
3017
- else resolve11(msg.result);
3083
+ else resolve10(msg.result);
3018
3084
  } else if (msg.method === "Runtime.executionContextCreated") {
3019
3085
  this.contexts.add(msg.params.context.id);
3020
3086
  } else if (msg.method === "Runtime.executionContextDestroyed") {
@@ -3037,7 +3103,7 @@ var DaemonCdpManager = class {
3037
3103
  this.ws.on("error", (err) => {
3038
3104
  this.log(`[CDP] WebSocket error: ${err.message}`);
3039
3105
  this._connected = false;
3040
- resolve10(false);
3106
+ resolve9(false);
3041
3107
  });
3042
3108
  });
3043
3109
  }
@@ -3051,7 +3117,7 @@ var DaemonCdpManager = class {
3051
3117
  return;
3052
3118
  }
3053
3119
  this.log(`[CDP] Connecting browser WS for target discovery...`);
3054
- await new Promise((resolve10, reject) => {
3120
+ await new Promise((resolve9, reject) => {
3055
3121
  this.browserWs = new WebSocket(browserWsUrl);
3056
3122
  this.browserWs.on("open", async () => {
3057
3123
  this._browserConnected = true;
@@ -3061,16 +3127,16 @@ var DaemonCdpManager = class {
3061
3127
  } catch (e) {
3062
3128
  this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
3063
3129
  }
3064
- resolve10();
3130
+ resolve9();
3065
3131
  });
3066
3132
  this.browserWs.on("message", (data) => {
3067
3133
  try {
3068
3134
  const msg = JSON.parse(data.toString());
3069
3135
  if (msg.id && this.browserPending.has(msg.id)) {
3070
- const { resolve: resolve11, reject: reject2 } = this.browserPending.get(msg.id);
3136
+ const { resolve: resolve10, reject: reject2 } = this.browserPending.get(msg.id);
3071
3137
  this.browserPending.delete(msg.id);
3072
3138
  if (msg.error) reject2(new Error(msg.error.message));
3073
- else resolve11(msg.result);
3139
+ else resolve10(msg.result);
3074
3140
  }
3075
3141
  } catch {
3076
3142
  }
@@ -3090,31 +3156,31 @@ var DaemonCdpManager = class {
3090
3156
  }
3091
3157
  }
3092
3158
  getBrowserWsUrl() {
3093
- return new Promise((resolve10) => {
3159
+ return new Promise((resolve9) => {
3094
3160
  const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
3095
3161
  let data = "";
3096
3162
  res.on("data", (chunk) => data += chunk.toString());
3097
3163
  res.on("end", () => {
3098
3164
  try {
3099
3165
  const info = JSON.parse(data);
3100
- resolve10(info.webSocketDebuggerUrl || null);
3166
+ resolve9(info.webSocketDebuggerUrl || null);
3101
3167
  } catch {
3102
- resolve10(null);
3168
+ resolve9(null);
3103
3169
  }
3104
3170
  });
3105
3171
  });
3106
- req.on("error", () => resolve10(null));
3172
+ req.on("error", () => resolve9(null));
3107
3173
  req.setTimeout(3e3, () => {
3108
3174
  req.destroy();
3109
- resolve10(null);
3175
+ resolve9(null);
3110
3176
  });
3111
3177
  });
3112
3178
  }
3113
3179
  sendBrowser(method, params = {}, timeoutMs = 15e3) {
3114
- return new Promise((resolve10, reject) => {
3180
+ return new Promise((resolve9, reject) => {
3115
3181
  if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
3116
3182
  const id = this.browserMsgId++;
3117
- this.browserPending.set(id, { resolve: resolve10, reject });
3183
+ this.browserPending.set(id, { resolve: resolve9, reject });
3118
3184
  this.browserWs.send(JSON.stringify({ id, method, params }));
3119
3185
  setTimeout(() => {
3120
3186
  if (this.browserPending.has(id)) {
@@ -3154,11 +3220,11 @@ var DaemonCdpManager = class {
3154
3220
  }
3155
3221
  // ─── CDP Protocol ────────────────────────────────────────
3156
3222
  sendInternal(method, params = {}, timeoutMs = 15e3) {
3157
- return new Promise((resolve10, reject) => {
3223
+ return new Promise((resolve9, reject) => {
3158
3224
  if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
3159
3225
  if (this.ws.readyState !== WebSocket.OPEN) return reject(new Error("WebSocket not open"));
3160
3226
  const id = this.msgId++;
3161
- this.pending.set(id, { resolve: resolve10, reject });
3227
+ this.pending.set(id, { resolve: resolve9, reject });
3162
3228
  this.ws.send(JSON.stringify({ id, method, params }));
3163
3229
  setTimeout(() => {
3164
3230
  if (this.pending.has(id)) {
@@ -3407,7 +3473,7 @@ var DaemonCdpManager = class {
3407
3473
  const browserWs = this.browserWs;
3408
3474
  let msgId = this.browserMsgId;
3409
3475
  const sendWs = (method, params = {}, sessionId) => {
3410
- return new Promise((resolve10, reject) => {
3476
+ return new Promise((resolve9, reject) => {
3411
3477
  const mid = msgId++;
3412
3478
  this.browserMsgId = msgId;
3413
3479
  const handler = (raw) => {
@@ -3416,7 +3482,7 @@ var DaemonCdpManager = class {
3416
3482
  if (msg.id === mid) {
3417
3483
  browserWs.removeListener("message", handler);
3418
3484
  if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
3419
- else resolve10(msg.result);
3485
+ else resolve9(msg.result);
3420
3486
  }
3421
3487
  } catch {
3422
3488
  }
@@ -3607,14 +3673,14 @@ var DaemonCdpManager = class {
3607
3673
  if (!ws || ws.readyState !== WebSocket.OPEN) {
3608
3674
  throw new Error("CDP not connected");
3609
3675
  }
3610
- return new Promise((resolve10, reject) => {
3676
+ return new Promise((resolve9, reject) => {
3611
3677
  const id = getNextId();
3612
3678
  pendingMap.set(id, {
3613
3679
  resolve: (result) => {
3614
3680
  if (result?.result?.subtype === "error") {
3615
3681
  reject(new Error(result.result.description));
3616
3682
  } else {
3617
- resolve10(result?.result?.value);
3683
+ resolve9(result?.result?.value);
3618
3684
  }
3619
3685
  },
3620
3686
  reject
@@ -3646,10 +3712,10 @@ var DaemonCdpManager = class {
3646
3712
  throw new Error("CDP not connected");
3647
3713
  }
3648
3714
  const sendViaSession = (method, params = {}) => {
3649
- return new Promise((resolve10, reject) => {
3715
+ return new Promise((resolve9, reject) => {
3650
3716
  const pendingMap = this._browserConnected ? this.browserPending : this.pending;
3651
3717
  const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
3652
- pendingMap.set(id, { resolve: resolve10, reject });
3718
+ pendingMap.set(id, { resolve: resolve9, reject });
3653
3719
  ws.send(JSON.stringify({ id, sessionId, method, params }));
3654
3720
  setTimeout(() => {
3655
3721
  if (pendingMap.has(id)) {
@@ -6867,17 +6933,44 @@ async function handleDiscoverAgents(h, args) {
6867
6933
  const agents = await h.getCdp().discoverAgentWebviews();
6868
6934
  return { success: true, agents };
6869
6935
  }
6936
+ function normalizeWindowsRequestedPath(requestedPath) {
6937
+ const trimmed = requestedPath.trim();
6938
+ if (!trimmed) return ".";
6939
+ const slashDriveMatch = trimmed.match(/^[/\\]([A-Za-z])(?:[/\\](.*))?$/);
6940
+ if (slashDriveMatch) {
6941
+ const drive = slashDriveMatch[1].toUpperCase();
6942
+ const rest = (slashDriveMatch[2] || "").replace(/[/\\]+/g, "\\");
6943
+ return rest ? `${drive}:\\${rest}` : `${drive}:\\`;
6944
+ }
6945
+ if (/^[A-Za-z]:$/.test(trimmed)) {
6946
+ return `${trimmed[0].toUpperCase()}:\\`;
6947
+ }
6948
+ if (/^[A-Za-z]:[^/\\].*$/.test(trimmed)) {
6949
+ return `${trimmed[0].toUpperCase()}:\\${trimmed.slice(2).replace(/[/\\]+/g, "\\")}`;
6950
+ }
6951
+ if (/^[A-Za-z]:[/\\]/.test(trimmed)) {
6952
+ return `${trimmed[0].toUpperCase()}:${trimmed.slice(2)}`;
6953
+ }
6954
+ return trimmed;
6955
+ }
6870
6956
  function resolveSafePath(requestedPath) {
6957
+ const rawPath = typeof requestedPath === "string" ? requestedPath.trim() : "";
6958
+ const inputPath = rawPath || ".";
6871
6959
  const home = os6.homedir();
6872
- let resolved;
6873
- if (requestedPath.startsWith("~")) {
6874
- resolved = path6.join(home, requestedPath.slice(1));
6875
- } else if (path6.isAbsolute(requestedPath)) {
6876
- resolved = requestedPath;
6877
- } else {
6878
- resolved = path6.resolve(requestedPath);
6960
+ if (inputPath.startsWith("~")) {
6961
+ return path6.resolve(path6.join(home, inputPath.slice(1)));
6879
6962
  }
6880
- return resolved;
6963
+ if (process.platform === "win32") {
6964
+ const normalized = normalizeWindowsRequestedPath(inputPath);
6965
+ if (path6.win32.isAbsolute(normalized)) {
6966
+ return path6.win32.normalize(normalized);
6967
+ }
6968
+ return path6.win32.resolve(normalized);
6969
+ }
6970
+ if (path6.isAbsolute(inputPath)) {
6971
+ return path6.normalize(inputPath);
6972
+ }
6973
+ return path6.resolve(inputPath);
6881
6974
  }
6882
6975
  function listDirectoryEntriesSafe(dirPath) {
6883
6976
  const entries = fs4.readdirSync(dirPath, { withFileTypes: true });
@@ -7623,7 +7716,7 @@ var DaemonCommandHandler = class {
7623
7716
  try {
7624
7717
  const http3 = await import("http");
7625
7718
  const postData = JSON.stringify(body);
7626
- const result = await new Promise((resolve10, reject) => {
7719
+ const result = await new Promise((resolve9, reject) => {
7627
7720
  const req = http3.request({
7628
7721
  hostname: "127.0.0.1",
7629
7722
  port: 19280,
@@ -7635,9 +7728,9 @@ var DaemonCommandHandler = class {
7635
7728
  res.on("data", (chunk) => data += chunk);
7636
7729
  res.on("end", () => {
7637
7730
  try {
7638
- resolve10(JSON.parse(data));
7731
+ resolve9(JSON.parse(data));
7639
7732
  } catch {
7640
- resolve10({ raw: data });
7733
+ resolve9({ raw: data });
7641
7734
  }
7642
7735
  });
7643
7736
  });
@@ -7655,15 +7748,15 @@ var DaemonCommandHandler = class {
7655
7748
  if (!providerType) return { success: false, error: "providerType required" };
7656
7749
  try {
7657
7750
  const http3 = await import("http");
7658
- const result = await new Promise((resolve10, reject) => {
7751
+ const result = await new Promise((resolve9, reject) => {
7659
7752
  http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
7660
7753
  let data = "";
7661
7754
  res.on("data", (chunk) => data += chunk);
7662
7755
  res.on("end", () => {
7663
7756
  try {
7664
- resolve10(JSON.parse(data));
7757
+ resolve9(JSON.parse(data));
7665
7758
  } catch {
7666
- resolve10({ raw: data });
7759
+ resolve9({ raw: data });
7667
7760
  }
7668
7761
  });
7669
7762
  }).on("error", reject);
@@ -7677,7 +7770,7 @@ var DaemonCommandHandler = class {
7677
7770
  try {
7678
7771
  const http3 = await import("http");
7679
7772
  const postData = JSON.stringify(args || {});
7680
- const result = await new Promise((resolve10, reject) => {
7773
+ const result = await new Promise((resolve9, reject) => {
7681
7774
  const req = http3.request({
7682
7775
  hostname: "127.0.0.1",
7683
7776
  port: 19280,
@@ -7689,9 +7782,9 @@ var DaemonCommandHandler = class {
7689
7782
  res.on("data", (chunk) => data += chunk);
7690
7783
  res.on("end", () => {
7691
7784
  try {
7692
- resolve10(JSON.parse(data));
7785
+ resolve9(JSON.parse(data));
7693
7786
  } catch {
7694
- resolve10({ raw: data });
7787
+ resolve9({ raw: data });
7695
7788
  }
7696
7789
  });
7697
7790
  });
@@ -7804,17 +7897,60 @@ var CliProviderInstance = class {
7804
7897
  async onTick() {
7805
7898
  if (this.providerSessionId) return;
7806
7899
  let probedSessionId = null;
7807
- if (this.type === "opencode-cli") {
7808
- probedSessionId = this.probeOpenCodeSessionId();
7809
- } else if (this.type === "codex-cli") {
7810
- probedSessionId = this.probeCodexSessionId();
7811
- } else if (this.type === "goose-cli") {
7812
- probedSessionId = this.probeGooseSessionId();
7900
+ const probeConfig = this.provider.sessionProbe;
7901
+ if (probeConfig) {
7902
+ probedSessionId = this.probeSessionIdFromConfig(probeConfig);
7903
+ } else {
7904
+ if (this.type === "opencode-cli") {
7905
+ probedSessionId = this.probeSessionIdFromConfig({
7906
+ dbPath: "~/.local/share/opencode/opencode.db",
7907
+ query: "select id from session where directory in ({dirs}) and time_created >= ? and time_archived is null order by time_updated desc limit 1",
7908
+ timestampFormat: "unix_ms"
7909
+ });
7910
+ } else if (this.type === "codex-cli") {
7911
+ probedSessionId = this.probeSessionIdFromConfig({
7912
+ dbPath: "~/.codex/state_5.sqlite",
7913
+ query: "select id from threads where cwd in ({dirs}) and created_at >= ? and archived = 0 order by created_at desc limit 1",
7914
+ timestampFormat: "unix_s"
7915
+ });
7916
+ } else if (this.type === "goose-cli") {
7917
+ probedSessionId = this.probeSessionIdFromConfig({
7918
+ dbPath: "~/.local/share/goose/sessions/sessions.db",
7919
+ query: "select id from sessions where working_dir in ({dirs}) and created_at >= ? order by updated_at desc limit 1",
7920
+ timestampFormat: "iso"
7921
+ });
7922
+ }
7813
7923
  }
7814
7924
  if (probedSessionId) {
7815
7925
  this.promoteProviderSessionId(probedSessionId);
7816
7926
  }
7817
7927
  }
7928
+ /**
7929
+ * Generic session ID probe using declarative ProviderSessionProbe config.
7930
+ * Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
7931
+ */
7932
+ probeSessionIdFromConfig(probe) {
7933
+ const resolvedDbPath = probe.dbPath.replace(/^~/, os9.homedir());
7934
+ if (!fs5.existsSync(resolvedDbPath)) return null;
7935
+ const directories = this.getProbeDirectories();
7936
+ const minCreatedAt = Math.max(0, this.startedAt - 6e4);
7937
+ const tsFormat = probe.timestampFormat || "unix_ms";
7938
+ let timestampParam;
7939
+ if (tsFormat === "unix_s") {
7940
+ timestampParam = Math.floor(minCreatedAt / 1e3);
7941
+ } else if (tsFormat === "iso") {
7942
+ timestampParam = new Date(minCreatedAt).toISOString().slice(0, 19).replace("T", " ");
7943
+ } else {
7944
+ timestampParam = minCreatedAt;
7945
+ }
7946
+ const placeholders = this.buildSqlPlaceholderList(directories.length);
7947
+ const query = probe.query.replace("{dirs}", placeholders);
7948
+ try {
7949
+ return this.querySqliteText(resolvedDbPath, query, [...directories, timestampParam]);
7950
+ } catch {
7951
+ return null;
7952
+ }
7953
+ }
7818
7954
  getState() {
7819
7955
  const adapterStatus = this.adapter.getStatus();
7820
7956
  const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
@@ -8112,34 +8248,6 @@ var CliProviderInstance = class {
8112
8248
  });
8113
8249
  LOG.info("CLI", `[${this.type}] discovered provider session id: ${nextSessionId}`);
8114
8250
  }
8115
- probeOpenCodeSessionId() {
8116
- const dbPath = path8.join(os9.homedir(), ".local", "share", "opencode", "opencode.db");
8117
- if (!fs5.existsSync(dbPath)) return null;
8118
- const minCreatedAt = Math.max(0, this.startedAt - 6e4);
8119
- const directories = this.getProbeDirectories();
8120
- 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;`;
8121
- return this.querySqliteText(dbPath, query, [...directories, minCreatedAt]);
8122
- }
8123
- probeCodexSessionId() {
8124
- const dbPath = path8.join(os9.homedir(), ".codex", "state_5.sqlite");
8125
- if (!fs5.existsSync(dbPath)) return null;
8126
- const minCreatedAt = Math.max(0, Math.floor((this.startedAt - 6e4) / 1e3));
8127
- const directories = this.getProbeDirectories();
8128
- 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;`;
8129
- return this.querySqliteText(dbPath, query, [...directories, minCreatedAt]);
8130
- }
8131
- probeGooseSessionId() {
8132
- const dbPath = path8.join(os9.homedir(), ".local", "share", "goose", "sessions", "sessions.db");
8133
- if (!fs5.existsSync(dbPath)) return null;
8134
- const minCreatedAtIso = new Date(Math.max(0, this.startedAt - 6e4)).toISOString().slice(0, 19).replace("T", " ");
8135
- const directories = this.getProbeDirectories();
8136
- const query = `select id from sessions where working_dir in (${this.buildSqlPlaceholderList(directories.length)}) and created_at >= ? order by updated_at desc limit 1;`;
8137
- try {
8138
- return this.querySqliteText(dbPath, query, [...directories, minCreatedAtIso]);
8139
- } catch {
8140
- return null;
8141
- }
8142
- }
8143
8251
  getProbeDirectories() {
8144
8252
  const dirs = /* @__PURE__ */ new Set();
8145
8253
  const addDir = (value) => {
@@ -8616,13 +8724,13 @@ var AcpProviderInstance = class {
8616
8724
  }
8617
8725
  this.currentStatus = "waiting_approval";
8618
8726
  this.detectStatusTransition();
8619
- const approved = await new Promise((resolve10) => {
8620
- this.permissionResolvers.push(resolve10);
8727
+ const approved = await new Promise((resolve9) => {
8728
+ this.permissionResolvers.push(resolve9);
8621
8729
  setTimeout(() => {
8622
- const idx = this.permissionResolvers.indexOf(resolve10);
8730
+ const idx = this.permissionResolvers.indexOf(resolve9);
8623
8731
  if (idx >= 0) {
8624
8732
  this.permissionResolvers.splice(idx, 1);
8625
- resolve10(false);
8733
+ resolve9(false);
8626
8734
  }
8627
8735
  }, 3e5);
8628
8736
  });
@@ -9413,7 +9521,19 @@ ${installInfo}`
9413
9521
  return { runtimeSessionId: sessionId };
9414
9522
  }
9415
9523
  const cliInfo = await detectCLI(cliType, this.providerLoader);
9416
- if (!cliInfo) throw new Error(`${cliType} not found`);
9524
+ if (!cliInfo) {
9525
+ const installHint = provider?.install || "";
9526
+ const displayName = provider?.displayName || provider?.name || cliType;
9527
+ const spawnCmd = provider?.spawn?.command || cliType;
9528
+ throw new Error(
9529
+ `${displayName} is not installed.
9530
+ Command '${spawnCmd}' not found on PATH.
9531
+ ` + (installHint ? `
9532
+ ${installHint}
9533
+ ` : "") + `
9534
+ Run 'adhdev doctor' for detailed diagnostics.`
9535
+ );
9536
+ }
9417
9537
  console.log(colorize("yellow", ` \u26A1 Starting CLI ${cliType} in ${resolvedDir}...`));
9418
9538
  if (provider) {
9419
9539
  console.log(colorize("cyan", ` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
@@ -9729,8 +9849,9 @@ ${installInfo}`
9729
9849
  const dir = rdir.path;
9730
9850
  if (!cliType) throw new Error("cliType required");
9731
9851
  const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
9852
+ const prevCliArgs = found ? found.adapter.extraArgs : void 0;
9732
9853
  if (found) await this.stopSession(found.key);
9733
- await this.startSession(cliType, dir);
9854
+ await this.startSession(cliType, dir, args?.cliArgs || prevCliArgs, args?.initialModel);
9734
9855
  return { success: true, restarted: true };
9735
9856
  }
9736
9857
  case "agent_command": {
@@ -10348,7 +10469,7 @@ var ProviderLoader = class _ProviderLoader {
10348
10469
  return { updated: false };
10349
10470
  }
10350
10471
  try {
10351
- const etag = await new Promise((resolve10, reject) => {
10472
+ const etag = await new Promise((resolve9, reject) => {
10352
10473
  const options = {
10353
10474
  method: "HEAD",
10354
10475
  hostname: "github.com",
@@ -10366,7 +10487,7 @@ var ProviderLoader = class _ProviderLoader {
10366
10487
  headers: { "User-Agent": "adhdev-launcher" },
10367
10488
  timeout: 1e4
10368
10489
  }, (res2) => {
10369
- resolve10(res2.headers.etag || res2.headers["last-modified"] || "");
10490
+ resolve9(res2.headers.etag || res2.headers["last-modified"] || "");
10370
10491
  });
10371
10492
  req2.on("error", reject);
10372
10493
  req2.on("timeout", () => {
@@ -10375,7 +10496,7 @@ var ProviderLoader = class _ProviderLoader {
10375
10496
  });
10376
10497
  req2.end();
10377
10498
  } else {
10378
- resolve10(res.headers.etag || res.headers["last-modified"] || "");
10499
+ resolve9(res.headers.etag || res.headers["last-modified"] || "");
10379
10500
  }
10380
10501
  });
10381
10502
  req.on("error", reject);
@@ -10439,7 +10560,7 @@ var ProviderLoader = class _ProviderLoader {
10439
10560
  downloadFile(url, destPath) {
10440
10561
  const https = __require("https");
10441
10562
  const http3 = __require("http");
10442
- return new Promise((resolve10, reject) => {
10563
+ return new Promise((resolve9, reject) => {
10443
10564
  const doRequest = (reqUrl, redirectCount = 0) => {
10444
10565
  if (redirectCount > 5) {
10445
10566
  reject(new Error("Too many redirects"));
@@ -10459,7 +10580,7 @@ var ProviderLoader = class _ProviderLoader {
10459
10580
  res.pipe(ws);
10460
10581
  ws.on("finish", () => {
10461
10582
  ws.close();
10462
- resolve10();
10583
+ resolve9();
10463
10584
  });
10464
10585
  ws.on("error", reject);
10465
10586
  });
@@ -10779,9 +10900,9 @@ var ProviderLoader = class _ProviderLoader {
10779
10900
  }
10780
10901
  }
10781
10902
  compareVersions(a, b) {
10782
- const normalize2 = (v) => v.split(/[-_+]/)[0].split(".").map((x) => parseInt(x, 10) || 0);
10783
- const pa = normalize2(a);
10784
- const pb = normalize2(b);
10903
+ const normalize3 = (v) => v.split(/[-_+]/)[0].split(".").map((x) => parseInt(x, 10) || 0);
10904
+ const pa = normalize3(a);
10905
+ const pb = normalize3(b);
10785
10906
  for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
10786
10907
  const va = pa[i] || 0;
10787
10908
  const vb = pb[i] || 0;
@@ -10824,17 +10945,17 @@ async function findFreePort(ports) {
10824
10945
  throw new Error("No free port found");
10825
10946
  }
10826
10947
  function checkPortFree(port) {
10827
- return new Promise((resolve10) => {
10948
+ return new Promise((resolve9) => {
10828
10949
  const server = net.createServer();
10829
10950
  server.unref();
10830
- server.on("error", () => resolve10(false));
10951
+ server.on("error", () => resolve9(false));
10831
10952
  server.listen(port, "127.0.0.1", () => {
10832
- server.close(() => resolve10(true));
10953
+ server.close(() => resolve9(true));
10833
10954
  });
10834
10955
  });
10835
10956
  }
10836
10957
  async function isCdpActive(port) {
10837
- return new Promise((resolve10) => {
10958
+ return new Promise((resolve9) => {
10838
10959
  const req = __require("http").get(`http://127.0.0.1:${port}/json/version`, {
10839
10960
  timeout: 2e3
10840
10961
  }, (res) => {
@@ -10843,16 +10964,16 @@ async function isCdpActive(port) {
10843
10964
  res.on("end", () => {
10844
10965
  try {
10845
10966
  const info = JSON.parse(data);
10846
- resolve10(!!info["WebKit-Version"] || !!info["Browser"]);
10967
+ resolve9(!!info["WebKit-Version"] || !!info["Browser"]);
10847
10968
  } catch {
10848
- resolve10(false);
10969
+ resolve9(false);
10849
10970
  }
10850
10971
  });
10851
10972
  });
10852
- req.on("error", () => resolve10(false));
10973
+ req.on("error", () => resolve9(false));
10853
10974
  req.on("timeout", () => {
10854
10975
  req.destroy();
10855
- resolve10(false);
10976
+ resolve9(false);
10856
10977
  });
10857
10978
  });
10858
10979
  }
@@ -10994,7 +11115,7 @@ function detectCurrentWorkspace(ideId) {
10994
11115
  return void 0;
10995
11116
  }
10996
11117
  async function launchWithCdp(options = {}) {
10997
- const platform10 = os12.platform();
11118
+ const platform9 = os12.platform();
10998
11119
  let targetIde;
10999
11120
  const ides = await detectIDEs();
11000
11121
  if (options.ideId) {
@@ -11063,9 +11184,9 @@ async function launchWithCdp(options = {}) {
11063
11184
  }
11064
11185
  const port = await findFreePort(portPair);
11065
11186
  try {
11066
- if (platform10 === "darwin") {
11187
+ if (platform9 === "darwin") {
11067
11188
  await launchMacOS(targetIde, port, workspace, options.newWindow);
11068
- } else if (platform10 === "win32") {
11189
+ } else if (platform9 === "win32") {
11069
11190
  await launchWindows(targetIde, port, workspace, options.newWindow);
11070
11191
  } else {
11071
11192
  await launchLinux(targetIde, port, workspace, options.newWindow);
@@ -11464,7 +11585,7 @@ async function waitForPidExit(pid, timeoutMs) {
11464
11585
  while (Date.now() - start < timeoutMs) {
11465
11586
  try {
11466
11587
  process.kill(pid, 0);
11467
- await new Promise((resolve10) => setTimeout(resolve10, 250));
11588
+ await new Promise((resolve9) => setTimeout(resolve9, 250));
11468
11589
  } catch {
11469
11590
  return;
11470
11591
  }
@@ -13012,7 +13133,7 @@ import * as fs10 from "fs";
13012
13133
  import * as path14 from "path";
13013
13134
  import * as os16 from "os";
13014
13135
  import { execSync as execSync5 } from "child_process";
13015
- import { platform as platform8 } from "os";
13136
+ import { platform as platform7 } from "os";
13016
13137
  var ARCHIVE_PATH = path14.join(os16.homedir(), ".adhdev", "version-history.json");
13017
13138
  var MAX_ENTRIES_PER_PROVIDER = 20;
13018
13139
  var VersionArchive = class {
@@ -13038,7 +13159,7 @@ var VersionArchive = class {
13038
13159
  entries.push({
13039
13160
  version,
13040
13161
  detectedAt: (/* @__PURE__ */ new Date()).toISOString(),
13041
- os: platform8()
13162
+ os: platform7()
13042
13163
  });
13043
13164
  if (entries.length > MAX_ENTRIES_PER_PROVIDER) {
13044
13165
  this.history[type] = entries.slice(-MAX_ENTRIES_PER_PROVIDER);
@@ -13078,7 +13199,7 @@ function runCommand(cmd, timeout = 1e4) {
13078
13199
  }
13079
13200
  }
13080
13201
  function findBinary2(name) {
13081
- const cmd = platform8() === "win32" ? `where ${name}` : `which ${name}`;
13202
+ const cmd = platform7() === "win32" ? `where ${name}` : `which ${name}`;
13082
13203
  const result = runCommand(cmd, 5e3);
13083
13204
  return result ? result.split("\n")[0] : null;
13084
13205
  }
@@ -13110,7 +13231,7 @@ function checkPathExists2(paths) {
13110
13231
  return null;
13111
13232
  }
13112
13233
  function getMacAppVersion(appPath) {
13113
- if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
13234
+ if (platform7() !== "darwin" || !appPath.endsWith(".app")) return null;
13114
13235
  const plistPath = path14.join(appPath, "Contents", "Info.plist");
13115
13236
  if (!fs10.existsSync(plistPath)) return null;
13116
13237
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
@@ -13118,7 +13239,7 @@ function getMacAppVersion(appPath) {
13118
13239
  }
13119
13240
  async function detectAllVersions(loader, archive) {
13120
13241
  const results = [];
13121
- const currentOs = platform8();
13242
+ const currentOs = platform7();
13122
13243
  for (const provider of loader.getAll()) {
13123
13244
  const info = {
13124
13245
  type: provider.type,
@@ -14697,7 +14818,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
14697
14818
  return { target, instance, adapter };
14698
14819
  }
14699
14820
  function sleep(ms) {
14700
- return new Promise((resolve10) => setTimeout(resolve10, ms));
14821
+ return new Promise((resolve9) => setTimeout(resolve9, ms));
14701
14822
  }
14702
14823
  async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
14703
14824
  const startedAt = Date.now();
@@ -16867,15 +16988,15 @@ var DevServer = class _DevServer {
16867
16988
  this.json(res, 500, { error: e.message });
16868
16989
  }
16869
16990
  });
16870
- return new Promise((resolve10, reject) => {
16991
+ return new Promise((resolve9, reject) => {
16871
16992
  this.server.listen(port, "127.0.0.1", () => {
16872
16993
  this.log(`Dev server listening on http://127.0.0.1:${port}`);
16873
- resolve10();
16994
+ resolve9();
16874
16995
  });
16875
16996
  this.server.on("error", (e) => {
16876
16997
  if (e.code === "EADDRINUSE") {
16877
16998
  this.log(`Port ${port} in use, skipping dev server`);
16878
- resolve10();
16999
+ resolve9();
16879
17000
  } else {
16880
17001
  reject(e);
16881
17002
  }
@@ -16958,20 +17079,20 @@ var DevServer = class _DevServer {
16958
17079
  child.stderr?.on("data", (d) => {
16959
17080
  stderr += d.toString().slice(0, 2e3);
16960
17081
  });
16961
- await new Promise((resolve10) => {
17082
+ await new Promise((resolve9) => {
16962
17083
  const timer = setTimeout(() => {
16963
17084
  child.kill();
16964
- resolve10();
17085
+ resolve9();
16965
17086
  }, 3e3);
16966
17087
  child.on("exit", () => {
16967
17088
  clearTimeout(timer);
16968
- resolve10();
17089
+ resolve9();
16969
17090
  });
16970
17091
  child.stdout?.once("data", () => {
16971
17092
  setTimeout(() => {
16972
17093
  child.kill();
16973
17094
  clearTimeout(timer);
16974
- resolve10();
17095
+ resolve9();
16975
17096
  }, 500);
16976
17097
  });
16977
17098
  });
@@ -17480,14 +17601,14 @@ var DevServer = class _DevServer {
17480
17601
  child.stderr?.on("data", (d) => {
17481
17602
  stderr += d.toString();
17482
17603
  });
17483
- await new Promise((resolve10) => {
17604
+ await new Promise((resolve9) => {
17484
17605
  const timer = setTimeout(() => {
17485
17606
  child.kill();
17486
- resolve10();
17607
+ resolve9();
17487
17608
  }, timeout);
17488
17609
  child.on("exit", () => {
17489
17610
  clearTimeout(timer);
17490
- resolve10();
17611
+ resolve9();
17491
17612
  });
17492
17613
  });
17493
17614
  const elapsed = Date.now() - start;
@@ -18162,14 +18283,14 @@ data: ${JSON.stringify(msg.data)}
18162
18283
  res.end(JSON.stringify(data, null, 2));
18163
18284
  }
18164
18285
  async readBody(req) {
18165
- return new Promise((resolve10) => {
18286
+ return new Promise((resolve9) => {
18166
18287
  let body = "";
18167
18288
  req.on("data", (chunk) => body += chunk);
18168
18289
  req.on("end", () => {
18169
18290
  try {
18170
- resolve10(JSON.parse(body));
18291
+ resolve9(JSON.parse(body));
18171
18292
  } catch {
18172
- resolve10({});
18293
+ resolve9({});
18173
18294
  }
18174
18295
  });
18175
18296
  });
@@ -18638,7 +18759,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
18638
18759
  const deadline = Date.now() + timeoutMs;
18639
18760
  while (Date.now() < deadline) {
18640
18761
  if (await canConnect(endpoint)) return;
18641
- await new Promise((resolve10) => setTimeout(resolve10, STARTUP_POLL_MS));
18762
+ await new Promise((resolve9) => setTimeout(resolve9, STARTUP_POLL_MS));
18642
18763
  }
18643
18764
  throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
18644
18765
  }
@@ -18794,10 +18915,10 @@ async function installExtension(ide, extension) {
18794
18915
  const buffer = Buffer.from(await res.arrayBuffer());
18795
18916
  const fs15 = await import("fs");
18796
18917
  fs15.writeFileSync(vsixPath, buffer);
18797
- return new Promise((resolve10) => {
18918
+ return new Promise((resolve9) => {
18798
18919
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
18799
18920
  exec2(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
18800
- resolve10({
18921
+ resolve9({
18801
18922
  extensionId: extension.id,
18802
18923
  marketplaceId: extension.marketplaceId,
18803
18924
  success: !error,
@@ -18810,11 +18931,11 @@ async function installExtension(ide, extension) {
18810
18931
  } catch (e) {
18811
18932
  }
18812
18933
  }
18813
- return new Promise((resolve10) => {
18934
+ return new Promise((resolve9) => {
18814
18935
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
18815
18936
  exec2(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
18816
18937
  if (error) {
18817
- resolve10({
18938
+ resolve9({
18818
18939
  extensionId: extension.id,
18819
18940
  marketplaceId: extension.marketplaceId,
18820
18941
  success: false,
@@ -18822,7 +18943,7 @@ async function installExtension(ide, extension) {
18822
18943
  error: stderr || error.message
18823
18944
  });
18824
18945
  } else {
18825
- resolve10({
18946
+ resolve9({
18826
18947
  extensionId: extension.id,
18827
18948
  marketplaceId: extension.marketplaceId,
18828
18949
  success: true,