adhdev 0.8.27 → 0.8.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -605,9 +605,16 @@ function getMergedDefinitions() {
605
605
  return [...merged.values()];
606
606
  }
607
607
  function findCliCommand(command) {
608
+ const trimmed = String(command || "").trim();
609
+ if (!trimmed) return null;
610
+ if (path4.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
611
+ const candidate = trimmed.startsWith("~") ? path4.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
612
+ const resolved = path4.isAbsolute(candidate) ? candidate : path4.resolve(candidate);
613
+ return (0, import_fs3.existsSync)(resolved) ? resolved : null;
614
+ }
608
615
  try {
609
616
  const result = (0, import_child_process.execSync)(
610
- (0, import_os2.platform)() === "win32" ? `where ${command}` : `which ${command}`,
617
+ (0, import_os2.platform)() === "win32" ? `where ${trimmed}` : `which ${trimmed}`,
611
618
  { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }
612
619
  ).trim();
613
620
  return result.split("\n")[0] || null;
@@ -630,23 +637,23 @@ function getIdeVersion(cliCommand) {
630
637
  function checkPathExists(paths) {
631
638
  const home = (0, import_os2.homedir)();
632
639
  for (const p of paths) {
633
- if (p.includes("*")) {
640
+ const normalized = p.startsWith("~") ? path4.join(home, p.slice(1)) : p;
641
+ if (normalized.includes("*")) {
634
642
  const username = home.split(/[\\/]/).pop() || "";
635
- const resolved = p.replace("*", username);
643
+ const resolved = normalized.replace("*", username);
636
644
  if ((0, import_fs3.existsSync)(resolved)) return resolved;
637
645
  } else {
638
- if ((0, import_fs3.existsSync)(p)) return p;
646
+ if ((0, import_fs3.existsSync)(normalized)) return normalized;
639
647
  }
640
648
  }
641
649
  return null;
642
650
  }
643
- async function detectIDEs() {
651
+ async function detectIDEs(providerLoader) {
644
652
  const os23 = (0, import_os2.platform)();
645
653
  const results = [];
646
654
  for (const def of getMergedDefinitions()) {
647
- const cliPath = findCliCommand(def.cli);
648
- const appPath = checkPathExists(def.paths[os23] || []);
649
- const installed = !!(cliPath || appPath);
655
+ const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
656
+ const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os23] || []) || []);
650
657
  let resolvedCli = cliPath;
651
658
  if (!resolvedCli && appPath && os23 === "darwin") {
652
659
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
@@ -669,6 +676,7 @@ async function detectIDEs() {
669
676
  }
670
677
  }
671
678
  }
679
+ const installed = os23 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
672
680
  const version2 = resolvedCli ? getIdeVersion(resolvedCli) : null;
673
681
  results.push({
674
682
  id: def.id,
@@ -683,13 +691,14 @@ async function detectIDEs() {
683
691
  }
684
692
  return results;
685
693
  }
686
- var import_child_process, import_fs3, import_os2, BUILTIN_IDE_DEFINITIONS, registeredIDEs;
694
+ var import_child_process, import_fs3, import_os2, path4, BUILTIN_IDE_DEFINITIONS, registeredIDEs;
687
695
  var init_ide_detector = __esm({
688
696
  "../../oss/packages/daemon-core/src/detection/ide-detector.ts"() {
689
697
  "use strict";
690
698
  import_child_process = require("child_process");
691
699
  import_fs3 = require("fs");
692
700
  import_os2 = require("os");
701
+ path4 = __toESM(require("path"));
693
702
  BUILTIN_IDE_DEFINITIONS = [];
694
703
  registeredIDEs = /* @__PURE__ */ new Map();
695
704
  }
@@ -700,44 +709,71 @@ function parseVersion(raw) {
700
709
  const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
701
710
  return match ? match[1] : raw.split("\n")[0].slice(0, 100);
702
711
  }
712
+ function shellQuote(value) {
713
+ if (/^[a-zA-Z0-9_./:@%+=,-]+$/.test(value)) return value;
714
+ return `"${value.replace(/(["\\$`])/g, "\\$1")}"`;
715
+ }
716
+ function expandHome(value) {
717
+ const trimmed = value.trim();
718
+ if (!trimmed.startsWith("~")) return trimmed;
719
+ return path5.join(os2.homedir(), trimmed.slice(1));
720
+ }
721
+ function isExplicitCommandPath(command) {
722
+ const trimmed = command.trim();
723
+ return path5.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
724
+ }
725
+ function resolveCommandPath(command) {
726
+ const trimmed = command.trim();
727
+ if (!trimmed) return null;
728
+ if (isExplicitCommandPath(trimmed)) {
729
+ const expanded = expandHome(trimmed);
730
+ const candidate = path5.isAbsolute(expanded) ? expanded : path5.resolve(expanded);
731
+ return (0, import_fs4.existsSync)(candidate) ? candidate : null;
732
+ }
733
+ return null;
734
+ }
703
735
  function execAsync(cmd, timeoutMs = 5e3) {
704
- return new Promise((resolve13) => {
736
+ return new Promise((resolve16) => {
705
737
  const child = (0, import_child_process2.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
706
738
  if (err || !stdout?.trim()) {
707
- resolve13(null);
739
+ resolve16(null);
708
740
  } else {
709
- resolve13(stdout.trim());
741
+ resolve16(stdout.trim());
710
742
  }
711
743
  });
712
- child.on("error", () => resolve13(null));
744
+ child.on("error", () => resolve16(null));
713
745
  });
714
746
  }
715
- async function detectCLIs(providerLoader) {
747
+ async function detectCLIs(providerLoader, options) {
716
748
  const platform11 = os2.platform();
717
749
  const whichCmd = platform11 === "win32" ? "where" : "which";
750
+ const includeVersion = options?.includeVersion !== false;
718
751
  const cliList = providerLoader ? providerLoader.getCliDetectionList() : [];
719
752
  const results = await Promise.all(
720
753
  cliList.map(async (cli) => {
721
754
  try {
722
- const pathResult = await execAsync(`${whichCmd} ${cli.command}`);
755
+ const explicitPath = resolveCommandPath(cli.command);
756
+ const pathResult = explicitPath || await execAsync(`${whichCmd} ${shellQuote(cli.command)}`);
723
757
  if (!pathResult) return { ...cli, installed: false };
724
- const firstPath = pathResult.split("\n")[0];
758
+ const firstPath = explicitPath || pathResult.split("\n")[0];
725
759
  let version2;
726
- try {
760
+ if (includeVersion) {
727
761
  const versionCommands = [
728
- cli.versionCommand,
729
- `${cli.command} --version`,
730
- `${cli.command} -V`,
731
- `${cli.command} -v`
762
+ `"${firstPath}" --version`,
763
+ `"${firstPath}" -V`,
764
+ `"${firstPath}" -v`,
765
+ cli.versionCommand
732
766
  ].filter((v) => !!v);
733
- for (const versionCommand of versionCommands) {
734
- const versionResult = await execAsync(versionCommand, 3e3);
735
- if (versionResult) {
736
- version2 = parseVersion(versionResult);
737
- break;
767
+ try {
768
+ for (const versionCommand of versionCommands) {
769
+ const versionResult = await execAsync(versionCommand, 3e3);
770
+ if (versionResult) {
771
+ version2 = parseVersion(versionResult);
772
+ break;
773
+ }
738
774
  }
775
+ } catch {
739
776
  }
740
- } catch {
741
777
  }
742
778
  return { ...cli, installed: true, version: version2, path: firstPath };
743
779
  } catch {
@@ -747,7 +783,7 @@ async function detectCLIs(providerLoader) {
747
783
  );
748
784
  return results;
749
785
  }
750
- async function detectCLI(cliId, providerLoader) {
786
+ async function detectCLI(cliId, providerLoader, options) {
751
787
  const resolvedId = providerLoader ? providerLoader.resolveAlias(cliId) : cliId;
752
788
  if (providerLoader) {
753
789
  const cliList = providerLoader.getCliDetectionList();
@@ -756,25 +792,28 @@ async function detectCLI(cliId, providerLoader) {
756
792
  const platform11 = os2.platform();
757
793
  const whichCmd = platform11 === "win32" ? "where" : "which";
758
794
  try {
759
- const pathResult = await execAsync(`${whichCmd} ${target.command}`);
795
+ const explicitPath = resolveCommandPath(target.command);
796
+ const pathResult = explicitPath || await execAsync(`${whichCmd} ${shellQuote(target.command)}`);
760
797
  if (!pathResult) return null;
761
- const firstPath = pathResult.split("\n")[0];
798
+ const firstPath = explicitPath || pathResult.split("\n")[0];
762
799
  let version2;
763
- try {
800
+ if (options?.includeVersion !== false) {
764
801
  const versionCommands = [
765
- target.versionCommand,
766
- `${target.command} --version`,
767
- `${target.command} -V`,
768
- `${target.command} -v`
802
+ `"${firstPath}" --version`,
803
+ `"${firstPath}" -V`,
804
+ `"${firstPath}" -v`,
805
+ target.versionCommand
769
806
  ].filter((v) => !!v);
770
- for (const versionCommand of versionCommands) {
771
- const versionResult = await execAsync(versionCommand, 3e3);
772
- if (versionResult) {
773
- version2 = parseVersion(versionResult);
774
- break;
807
+ try {
808
+ for (const versionCommand of versionCommands) {
809
+ const versionResult = await execAsync(versionCommand, 3e3);
810
+ if (versionResult) {
811
+ version2 = parseVersion(versionResult);
812
+ break;
813
+ }
775
814
  }
815
+ } catch {
776
816
  }
777
- } catch {
778
817
  }
779
818
  return { ...target, installed: true, version: version2, path: firstPath };
780
819
  } catch {
@@ -782,15 +821,17 @@ async function detectCLI(cliId, providerLoader) {
782
821
  }
783
822
  }
784
823
  }
785
- const all = await detectCLIs(providerLoader);
824
+ const all = await detectCLIs(providerLoader, options);
786
825
  return all.find((c) => c.id === resolvedId && c.installed) || null;
787
826
  }
788
- var import_child_process2, os2;
827
+ var import_child_process2, os2, path5, import_fs4;
789
828
  var init_cli_detector = __esm({
790
829
  "../../oss/packages/daemon-core/src/detection/cli-detector.ts"() {
791
830
  "use strict";
792
831
  import_child_process2 = require("child_process");
793
832
  os2 = __toESM(require("os"));
833
+ path5 = __toESM(require("path"));
834
+ import_fs4 = require("fs");
794
835
  }
795
836
  });
796
837
 
@@ -857,13 +898,13 @@ function getDaemonLogDir() {
857
898
  return LOG_DIR;
858
899
  }
859
900
  function getCurrentDaemonLogPath(date5 = /* @__PURE__ */ new Date()) {
860
- return path4.join(LOG_DIR, `daemon-${date5.toISOString().slice(0, 10)}.log`);
901
+ return path6.join(LOG_DIR, `daemon-${date5.toISOString().slice(0, 10)}.log`);
861
902
  }
862
903
  function checkDateRotation() {
863
904
  const today = getDateStr();
864
905
  if (today !== currentDate) {
865
906
  currentDate = today;
866
- currentLogFile = path4.join(LOG_DIR, `daemon-${currentDate}.log`);
907
+ currentLogFile = path6.join(LOG_DIR, `daemon-${currentDate}.log`);
867
908
  cleanOldLogs();
868
909
  }
869
910
  }
@@ -877,7 +918,7 @@ function cleanOldLogs() {
877
918
  const dateMatch = file2.match(/daemon-(\d{4}-\d{2}-\d{2})/);
878
919
  if (dateMatch && dateMatch[1] < cutoffStr) {
879
920
  try {
880
- fs2.unlinkSync(path4.join(LOG_DIR, file2));
921
+ fs2.unlinkSync(path6.join(LOG_DIR, file2));
881
922
  } catch {
882
923
  }
883
924
  }
@@ -994,17 +1035,17 @@ function installGlobalInterceptor() {
994
1035
  writeToFile(`Log file: ${currentLogFile}`);
995
1036
  writeToFile(`Log level: ${currentLevel}`);
996
1037
  }
997
- var fs2, path4, os4, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
1038
+ var fs2, path6, os4, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
998
1039
  var init_logger = __esm({
999
1040
  "../../oss/packages/daemon-core/src/logging/logger.ts"() {
1000
1041
  "use strict";
1001
1042
  fs2 = __toESM(require("fs"));
1002
- path4 = __toESM(require("path"));
1043
+ path6 = __toESM(require("path"));
1003
1044
  os4 = __toESM(require("os"));
1004
1045
  LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
1005
1046
  LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
1006
1047
  currentLevel = "info";
1007
- LOG_DIR = process.platform === "win32" ? path4.join(process.env.LOCALAPPDATA || process.env.APPDATA || path4.join(os4.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path4.join(os4.homedir(), "Library", "Logs", "adhdev") : path4.join(os4.homedir(), ".local", "share", "adhdev", "logs");
1048
+ LOG_DIR = process.platform === "win32" ? path6.join(process.env.LOCALAPPDATA || process.env.APPDATA || path6.join(os4.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path6.join(os4.homedir(), "Library", "Logs", "adhdev") : path6.join(os4.homedir(), ".local", "share", "adhdev", "logs");
1008
1049
  MAX_LOG_SIZE = 5 * 1024 * 1024;
1009
1050
  MAX_LOG_DAYS = 7;
1010
1051
  try {
@@ -1012,16 +1053,16 @@ var init_logger = __esm({
1012
1053
  } catch {
1013
1054
  }
1014
1055
  currentDate = getDateStr();
1015
- currentLogFile = path4.join(LOG_DIR, `daemon-${currentDate}.log`);
1056
+ currentLogFile = path6.join(LOG_DIR, `daemon-${currentDate}.log`);
1016
1057
  cleanOldLogs();
1017
1058
  try {
1018
- const oldLog = path4.join(LOG_DIR, "daemon.log");
1059
+ const oldLog = path6.join(LOG_DIR, "daemon.log");
1019
1060
  if (fs2.existsSync(oldLog)) {
1020
1061
  const stat4 = fs2.statSync(oldLog);
1021
1062
  const oldDate = stat4.mtime.toISOString().slice(0, 10);
1022
- fs2.renameSync(oldLog, path4.join(LOG_DIR, `daemon-${oldDate}.log`));
1063
+ fs2.renameSync(oldLog, path6.join(LOG_DIR, `daemon-${oldDate}.log`));
1023
1064
  }
1024
- const oldLogBackup = path4.join(LOG_DIR, "daemon.log.old");
1065
+ const oldLogBackup = path6.join(LOG_DIR, "daemon.log.old");
1025
1066
  if (fs2.existsSync(oldLogBackup)) {
1026
1067
  fs2.unlinkSync(oldLogBackup);
1027
1068
  }
@@ -1053,7 +1094,7 @@ var init_logger = __esm({
1053
1094
  }
1054
1095
  };
1055
1096
  interceptorInstalled = false;
1056
- LOG_PATH = path4.join(LOG_DIR, `daemon-${getDateStr()}.log`);
1097
+ LOG_PATH = path6.join(LOG_DIR, `daemon-${getDateStr()}.log`);
1057
1098
  }
1058
1099
  });
1059
1100
 
@@ -1142,7 +1183,7 @@ var init_manager = __esm({
1142
1183
  * Returns multiple entries if multiple IDE windows are open on same port
1143
1184
  */
1144
1185
  static listAllTargets(port) {
1145
- return new Promise((resolve13) => {
1186
+ return new Promise((resolve16) => {
1146
1187
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
1147
1188
  let data = "";
1148
1189
  res.on("data", (chunk) => data += chunk.toString());
@@ -1158,16 +1199,16 @@ var init_manager = __esm({
1158
1199
  (t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
1159
1200
  );
1160
1201
  const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
1161
- resolve13(mainPages.length > 0 ? mainPages : fallbackPages);
1202
+ resolve16(mainPages.length > 0 ? mainPages : fallbackPages);
1162
1203
  } catch {
1163
- resolve13([]);
1204
+ resolve16([]);
1164
1205
  }
1165
1206
  });
1166
1207
  });
1167
- req.on("error", () => resolve13([]));
1208
+ req.on("error", () => resolve16([]));
1168
1209
  req.setTimeout(2e3, () => {
1169
1210
  req.destroy();
1170
- resolve13([]);
1211
+ resolve16([]);
1171
1212
  });
1172
1213
  });
1173
1214
  }
@@ -1207,7 +1248,7 @@ var init_manager = __esm({
1207
1248
  }
1208
1249
  }
1209
1250
  findTargetOnPort(port) {
1210
- return new Promise((resolve13) => {
1251
+ return new Promise((resolve16) => {
1211
1252
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
1212
1253
  let data = "";
1213
1254
  res.on("data", (chunk) => data += chunk.toString());
@@ -1218,7 +1259,7 @@ var init_manager = __esm({
1218
1259
  (t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
1219
1260
  );
1220
1261
  if (pages.length === 0) {
1221
- resolve13(targets.find((t) => t.webSocketDebuggerUrl) || null);
1262
+ resolve16(targets.find((t) => t.webSocketDebuggerUrl) || null);
1222
1263
  return;
1223
1264
  }
1224
1265
  const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
@@ -1228,24 +1269,24 @@ var init_manager = __esm({
1228
1269
  const specific = list.find((t) => t.id === this._targetId);
1229
1270
  if (specific) {
1230
1271
  this._pageTitle = specific.title || "";
1231
- resolve13(specific);
1272
+ resolve16(specific);
1232
1273
  } else {
1233
1274
  this.log(`[CDP] Target ${this._targetId} not found in page list`);
1234
- resolve13(null);
1275
+ resolve16(null);
1235
1276
  }
1236
1277
  return;
1237
1278
  }
1238
1279
  this._pageTitle = list[0]?.title || "";
1239
- resolve13(list[0]);
1280
+ resolve16(list[0]);
1240
1281
  } catch {
1241
- resolve13(null);
1282
+ resolve16(null);
1242
1283
  }
1243
1284
  });
1244
1285
  });
1245
- req.on("error", () => resolve13(null));
1286
+ req.on("error", () => resolve16(null));
1246
1287
  req.setTimeout(2e3, () => {
1247
1288
  req.destroy();
1248
- resolve13(null);
1289
+ resolve16(null);
1249
1290
  });
1250
1291
  });
1251
1292
  }
@@ -1256,7 +1297,7 @@ var init_manager = __esm({
1256
1297
  this.extensionProviders = providers;
1257
1298
  }
1258
1299
  connectToTarget(wsUrl) {
1259
- return new Promise((resolve13) => {
1300
+ return new Promise((resolve16) => {
1260
1301
  this.ws = new import_ws.default(wsUrl);
1261
1302
  this.ws.on("open", async () => {
1262
1303
  this._connected = true;
@@ -1266,17 +1307,17 @@ var init_manager = __esm({
1266
1307
  }
1267
1308
  this.connectBrowserWs().catch(() => {
1268
1309
  });
1269
- resolve13(true);
1310
+ resolve16(true);
1270
1311
  });
1271
1312
  this.ws.on("message", (data) => {
1272
1313
  try {
1273
1314
  const msg = JSON.parse(data.toString());
1274
1315
  if (msg.id && this.pending.has(msg.id)) {
1275
- const { resolve: resolve14, reject } = this.pending.get(msg.id);
1316
+ const { resolve: resolve17, reject } = this.pending.get(msg.id);
1276
1317
  this.pending.delete(msg.id);
1277
1318
  this.failureCount = 0;
1278
1319
  if (msg.error) reject(new Error(msg.error.message));
1279
- else resolve14(msg.result);
1320
+ else resolve17(msg.result);
1280
1321
  } else if (msg.method === "Runtime.executionContextCreated") {
1281
1322
  this.contexts.add(msg.params.context.id);
1282
1323
  } else if (msg.method === "Runtime.executionContextDestroyed") {
@@ -1299,7 +1340,7 @@ var init_manager = __esm({
1299
1340
  this.ws.on("error", (err) => {
1300
1341
  this.log(`[CDP] WebSocket error: ${err.message}`);
1301
1342
  this._connected = false;
1302
- resolve13(false);
1343
+ resolve16(false);
1303
1344
  });
1304
1345
  });
1305
1346
  }
@@ -1313,7 +1354,7 @@ var init_manager = __esm({
1313
1354
  return;
1314
1355
  }
1315
1356
  this.log(`[CDP] Connecting browser WS for target discovery...`);
1316
- await new Promise((resolve13, reject) => {
1357
+ await new Promise((resolve16, reject) => {
1317
1358
  this.browserWs = new import_ws.default(browserWsUrl);
1318
1359
  this.browserWs.on("open", async () => {
1319
1360
  this._browserConnected = true;
@@ -1323,16 +1364,16 @@ var init_manager = __esm({
1323
1364
  } catch (e) {
1324
1365
  this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
1325
1366
  }
1326
- resolve13();
1367
+ resolve16();
1327
1368
  });
1328
1369
  this.browserWs.on("message", (data) => {
1329
1370
  try {
1330
1371
  const msg = JSON.parse(data.toString());
1331
1372
  if (msg.id && this.browserPending.has(msg.id)) {
1332
- const { resolve: resolve14, reject: reject2 } = this.browserPending.get(msg.id);
1373
+ const { resolve: resolve17, reject: reject2 } = this.browserPending.get(msg.id);
1333
1374
  this.browserPending.delete(msg.id);
1334
1375
  if (msg.error) reject2(new Error(msg.error.message));
1335
- else resolve14(msg.result);
1376
+ else resolve17(msg.result);
1336
1377
  }
1337
1378
  } catch {
1338
1379
  }
@@ -1352,31 +1393,31 @@ var init_manager = __esm({
1352
1393
  }
1353
1394
  }
1354
1395
  getBrowserWsUrl() {
1355
- return new Promise((resolve13) => {
1396
+ return new Promise((resolve16) => {
1356
1397
  const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
1357
1398
  let data = "";
1358
1399
  res.on("data", (chunk) => data += chunk.toString());
1359
1400
  res.on("end", () => {
1360
1401
  try {
1361
1402
  const info = JSON.parse(data);
1362
- resolve13(info.webSocketDebuggerUrl || null);
1403
+ resolve16(info.webSocketDebuggerUrl || null);
1363
1404
  } catch {
1364
- resolve13(null);
1405
+ resolve16(null);
1365
1406
  }
1366
1407
  });
1367
1408
  });
1368
- req.on("error", () => resolve13(null));
1409
+ req.on("error", () => resolve16(null));
1369
1410
  req.setTimeout(3e3, () => {
1370
1411
  req.destroy();
1371
- resolve13(null);
1412
+ resolve16(null);
1372
1413
  });
1373
1414
  });
1374
1415
  }
1375
1416
  sendBrowser(method, params = {}, timeoutMs = 15e3) {
1376
- return new Promise((resolve13, reject) => {
1417
+ return new Promise((resolve16, reject) => {
1377
1418
  if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
1378
1419
  const id = this.browserMsgId++;
1379
- this.browserPending.set(id, { resolve: resolve13, reject });
1420
+ this.browserPending.set(id, { resolve: resolve16, reject });
1380
1421
  this.browserWs.send(JSON.stringify({ id, method, params }));
1381
1422
  setTimeout(() => {
1382
1423
  if (this.browserPending.has(id)) {
@@ -1416,11 +1457,11 @@ var init_manager = __esm({
1416
1457
  }
1417
1458
  // ─── CDP Protocol ────────────────────────────────────────
1418
1459
  sendInternal(method, params = {}, timeoutMs = 15e3) {
1419
- return new Promise((resolve13, reject) => {
1460
+ return new Promise((resolve16, reject) => {
1420
1461
  if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
1421
1462
  if (this.ws.readyState !== import_ws.default.OPEN) return reject(new Error("WebSocket not open"));
1422
1463
  const id = this.msgId++;
1423
- this.pending.set(id, { resolve: resolve13, reject });
1464
+ this.pending.set(id, { resolve: resolve16, reject });
1424
1465
  this.ws.send(JSON.stringify({ id, method, params }));
1425
1466
  setTimeout(() => {
1426
1467
  if (this.pending.has(id)) {
@@ -1669,7 +1710,7 @@ var init_manager = __esm({
1669
1710
  const browserWs = this.browserWs;
1670
1711
  let msgId = this.browserMsgId;
1671
1712
  const sendWs = (method, params = {}, sessionId) => {
1672
- return new Promise((resolve13, reject) => {
1713
+ return new Promise((resolve16, reject) => {
1673
1714
  const mid = msgId++;
1674
1715
  this.browserMsgId = msgId;
1675
1716
  const handler = (raw) => {
@@ -1678,7 +1719,7 @@ var init_manager = __esm({
1678
1719
  if (msg.id === mid) {
1679
1720
  browserWs.removeListener("message", handler);
1680
1721
  if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
1681
- else resolve13(msg.result);
1722
+ else resolve16(msg.result);
1682
1723
  }
1683
1724
  } catch {
1684
1725
  }
@@ -1869,14 +1910,14 @@ var init_manager = __esm({
1869
1910
  if (!ws || ws.readyState !== import_ws.default.OPEN) {
1870
1911
  throw new Error("CDP not connected");
1871
1912
  }
1872
- return new Promise((resolve13, reject) => {
1913
+ return new Promise((resolve16, reject) => {
1873
1914
  const id = getNextId();
1874
1915
  pendingMap.set(id, {
1875
1916
  resolve: (result) => {
1876
1917
  if (result?.result?.subtype === "error") {
1877
1918
  reject(new Error(result.result.description));
1878
1919
  } else {
1879
- resolve13(result?.result?.value);
1920
+ resolve16(result?.result?.value);
1880
1921
  }
1881
1922
  },
1882
1923
  reject
@@ -1908,10 +1949,10 @@ var init_manager = __esm({
1908
1949
  throw new Error("CDP not connected");
1909
1950
  }
1910
1951
  const sendViaSession = (method, params = {}) => {
1911
- return new Promise((resolve13, reject) => {
1952
+ return new Promise((resolve16, reject) => {
1912
1953
  const pendingMap = this._browserConnected ? this.browserPending : this.pending;
1913
1954
  const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
1914
- pendingMap.set(id, { resolve: resolve13, reject });
1955
+ pendingMap.set(id, { resolve: resolve16, reject });
1915
1956
  ws.send(JSON.stringify({ id, sessionId, method, params }));
1916
1957
  setTimeout(() => {
1917
1958
  if (pendingMap.has(id)) {
@@ -2557,7 +2598,7 @@ var init_control_effects = __esm({
2557
2598
  function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
2558
2599
  try {
2559
2600
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
2560
- const dir = path5.join(HISTORY_DIR, sanitized);
2601
+ const dir = path7.join(HISTORY_DIR, sanitized);
2561
2602
  if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
2562
2603
  const sanitizedInstance = historySessionId?.replace(/[^a-zA-Z0-9_-]/g, "_");
2563
2604
  const files = fs3.readdirSync(dir).filter((f) => {
@@ -2571,7 +2612,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
2571
2612
  const needed = offset + limit + 1;
2572
2613
  for (const file2 of files) {
2573
2614
  if (allMessages.length >= needed) break;
2574
- const filePath = path5.join(dir, file2);
2615
+ const filePath = path7.join(dir, file2);
2575
2616
  const content = fs3.readFileSync(filePath, "utf-8");
2576
2617
  const lines = content.trim().split("\n").filter(Boolean);
2577
2618
  for (let i = lines.length - 1; i >= 0; i--) {
@@ -2593,7 +2634,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
2593
2634
  function listSavedHistorySessions(agentType, options = {}) {
2594
2635
  try {
2595
2636
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
2596
- const dir = path5.join(HISTORY_DIR, sanitized);
2637
+ const dir = path7.join(HISTORY_DIR, sanitized);
2597
2638
  if (!fs3.existsSync(dir)) return { sessions: [], hasMore: false };
2598
2639
  const groupedFiles = /* @__PURE__ */ new Map();
2599
2640
  const filePattern = /^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/;
@@ -2614,7 +2655,7 @@ function listSavedHistorySessions(agentType, options = {}) {
2614
2655
  let sessionTitle = "";
2615
2656
  let preview = "";
2616
2657
  for (const file2 of files.sort()) {
2617
- const filePath = path5.join(dir, file2);
2658
+ const filePath = path7.join(dir, file2);
2618
2659
  const content = fs3.readFileSync(filePath, "utf-8");
2619
2660
  const lines = content.split("\n").filter(Boolean);
2620
2661
  for (const line of lines) {
@@ -2654,14 +2695,14 @@ function listSavedHistorySessions(agentType, options = {}) {
2654
2695
  return { sessions: [], hasMore: false };
2655
2696
  }
2656
2697
  }
2657
- var fs3, path5, os5, HISTORY_DIR, RETAIN_DAYS, ChatHistoryWriter;
2698
+ var fs3, path7, os5, HISTORY_DIR, RETAIN_DAYS, ChatHistoryWriter;
2658
2699
  var init_chat_history = __esm({
2659
2700
  "../../oss/packages/daemon-core/src/config/chat-history.ts"() {
2660
2701
  "use strict";
2661
2702
  fs3 = __toESM(require("fs"));
2662
- path5 = __toESM(require("path"));
2703
+ path7 = __toESM(require("path"));
2663
2704
  os5 = __toESM(require("os"));
2664
- HISTORY_DIR = path5.join(os5.homedir(), ".adhdev", "history");
2705
+ HISTORY_DIR = path7.join(os5.homedir(), ".adhdev", "history");
2665
2706
  RETAIN_DAYS = 30;
2666
2707
  ChatHistoryWriter = class {
2667
2708
  /** Last seen message count per agent (deduplication) */
@@ -2706,11 +2747,11 @@ var init_chat_history = __esm({
2706
2747
  });
2707
2748
  }
2708
2749
  if (newMessages.length === 0) return;
2709
- const dir = path5.join(HISTORY_DIR, this.sanitize(agentType));
2750
+ const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
2710
2751
  fs3.mkdirSync(dir, { recursive: true });
2711
2752
  const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2712
2753
  const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
2713
- const filePath = path5.join(dir, `${filePrefix}${date5}.jsonl`);
2754
+ const filePath = path7.join(dir, `${filePrefix}${date5}.jsonl`);
2714
2755
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
2715
2756
  fs3.appendFileSync(filePath, lines, "utf-8");
2716
2757
  const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
@@ -2764,14 +2805,14 @@ var init_chat_history = __esm({
2764
2805
  this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
2765
2806
  this.lastSeenCounts.delete(fromDedupKey);
2766
2807
  }
2767
- const dir = path5.join(HISTORY_DIR, this.sanitize(agentType));
2808
+ const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
2768
2809
  if (!fs3.existsSync(dir)) return;
2769
2810
  const fromPrefix = `${this.sanitize(fromId)}_`;
2770
2811
  const toPrefix = `${this.sanitize(toId)}_`;
2771
2812
  const files = fs3.readdirSync(dir).filter((file2) => file2.startsWith(fromPrefix) && file2.endsWith(".jsonl"));
2772
2813
  for (const file2 of files) {
2773
- const sourcePath = path5.join(dir, file2);
2774
- const targetPath = path5.join(dir, `${toPrefix}${file2.slice(fromPrefix.length)}`);
2814
+ const sourcePath = path7.join(dir, file2);
2815
+ const targetPath = path7.join(dir, `${toPrefix}${file2.slice(fromPrefix.length)}`);
2775
2816
  const sourceLines = fs3.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
2776
2817
  const rewritten = sourceLines.map((line) => {
2777
2818
  try {
@@ -2812,10 +2853,10 @@ var init_chat_history = __esm({
2812
2853
  const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
2813
2854
  const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
2814
2855
  for (const dir of agentDirs) {
2815
- const dirPath = path5.join(HISTORY_DIR, dir.name);
2856
+ const dirPath = path7.join(HISTORY_DIR, dir.name);
2816
2857
  const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
2817
2858
  for (const file2 of files) {
2818
- const filePath = path5.join(dirPath, file2);
2859
+ const filePath = path7.join(dirPath, file2);
2819
2860
  const stat4 = fs3.statSync(filePath);
2820
2861
  if (stat4.mtimeMs < cutoff) {
2821
2862
  fs3.unlinkSync(filePath);
@@ -5023,6 +5064,14 @@ async function handleListChats(h, args) {
5023
5064
  } catch {
5024
5065
  }
5025
5066
  }
5067
+ if (parsed?.sessions && Array.isArray(parsed.sessions)) {
5068
+ LOG.info("Command", `[list_chats] OK: ${parsed.sessions.length} chats`);
5069
+ return { success: true, chats: parsed.sessions };
5070
+ }
5071
+ if (parsed?.chats && Array.isArray(parsed.chats)) {
5072
+ LOG.info("Command", `[list_chats] OK: ${parsed.chats.length} chats`);
5073
+ return { success: true, chats: parsed.chats };
5074
+ }
5026
5075
  if (Array.isArray(parsed)) {
5027
5076
  LOG.info("Command", `[list_chats] OK: ${parsed.length} chats`);
5028
5077
  return { success: true, chats: parsed };
@@ -5092,7 +5141,13 @@ async function handleSwitchChat(h, args) {
5092
5141
  } catch (e) {
5093
5142
  return { success: false, error: `webviewSwitchSession failed: ${e.message}` };
5094
5143
  }
5095
- const script = h.getProviderScript("switchSession", { SESSION_ID: JSON.stringify(sessionId) }) || h.getProviderScript("switch_session", { SESSION_ID: JSON.stringify(sessionId) });
5144
+ const switchParams = {
5145
+ sessionId,
5146
+ title: sessionId,
5147
+ id: sessionId,
5148
+ SESSION_ID: JSON.stringify(sessionId)
5149
+ };
5150
+ const script = h.getProviderScript("switchSession", switchParams) || h.getProviderScript("switch_session", switchParams);
5096
5151
  if (!script) return { success: false, error: "switch_session script not available" };
5097
5152
  try {
5098
5153
  const raw = await cdp.evaluate(script, 15e3);
@@ -5171,8 +5226,8 @@ async function handleSetMode(h, args) {
5171
5226
  const adapter = getTargetedCliAdapter(h, args, provider?.type);
5172
5227
  if (adapter) {
5173
5228
  const acpInstance = adapter._acpInstance;
5174
- if (acpInstance && typeof acpInstance.onEvent === "function") {
5175
- acpInstance.onEvent("set_mode", { mode });
5229
+ if (acpInstance && typeof acpInstance.setMode === "function") {
5230
+ await acpInstance.setMode(mode);
5176
5231
  return { success: true, mode };
5177
5232
  }
5178
5233
  }
@@ -5229,9 +5284,9 @@ async function handleChangeModel(h, args) {
5229
5284
  LOG.info("Command", `[change_model] ACP adapter found: ${!!adapter}, type=${adapter?.cliType}, hasAcpInstance=${!!adapter?._acpInstance}`);
5230
5285
  if (adapter) {
5231
5286
  const acpInstance = adapter._acpInstance;
5232
- if (acpInstance && typeof acpInstance.onEvent === "function") {
5233
- acpInstance.onEvent("change_model", { model });
5234
- LOG.info("Command", `[change_model] Dispatched change_model event to ACP instance`);
5287
+ if (acpInstance && typeof acpInstance.setConfigOption === "function") {
5288
+ await acpInstance.setConfigOption("model", model);
5289
+ LOG.info("Command", `[change_model] Updated ACP model to ${model}`);
5235
5290
  return { success: true, model };
5236
5291
  }
5237
5292
  }
@@ -5351,6 +5406,18 @@ async function handleResolveAction(h, args) {
5351
5406
  const ok = await h.agentStream.resolveSessionAction(h.getCdp(), h.currentSession.sessionId, action);
5352
5407
  return { success: ok };
5353
5408
  }
5409
+ if (transport === "acp") {
5410
+ const adapter = getTargetedCliAdapter(h, args, provider?.type);
5411
+ const acpInstance = adapter?._acpInstance;
5412
+ if (!acpInstance) return { success: false, error: "ACP instance not found" };
5413
+ try {
5414
+ await acpInstance.resolvePermission(action === "approve" || action === "accept" || action === "always");
5415
+ LOG.info("Command", `[resolveAction] ACP \u2192 ${action}`);
5416
+ return { success: true, action };
5417
+ } catch (e) {
5418
+ return { success: false, error: e?.message || "ACP resolve action failed" };
5419
+ }
5420
+ }
5354
5421
  if (provider?.scripts?.webviewResolveAction || provider?.scripts?.webview_resolve_action) {
5355
5422
  const script = h.getProviderScript("webviewResolveAction", { action, button, buttonText: button }) || h.getProviderScript("webview_resolve_action", { action, button, buttonText: button });
5356
5423
  if (script) {
@@ -5653,25 +5720,25 @@ function resolveSafePath(requestedPath) {
5653
5720
  const inputPath = rawPath || ".";
5654
5721
  const home = os6.homedir();
5655
5722
  if (inputPath.startsWith("~")) {
5656
- return path6.resolve(path6.join(home, inputPath.slice(1)));
5723
+ return path8.resolve(path8.join(home, inputPath.slice(1)));
5657
5724
  }
5658
5725
  if (process.platform === "win32") {
5659
5726
  const normalized = normalizeWindowsRequestedPath(inputPath);
5660
- if (path6.win32.isAbsolute(normalized)) {
5661
- return path6.win32.normalize(normalized);
5727
+ if (path8.win32.isAbsolute(normalized)) {
5728
+ return path8.win32.normalize(normalized);
5662
5729
  }
5663
- return path6.win32.resolve(normalized);
5730
+ return path8.win32.resolve(normalized);
5664
5731
  }
5665
- if (path6.isAbsolute(inputPath)) {
5666
- return path6.normalize(inputPath);
5732
+ if (path8.isAbsolute(inputPath)) {
5733
+ return path8.normalize(inputPath);
5667
5734
  }
5668
- return path6.resolve(inputPath);
5735
+ return path8.resolve(inputPath);
5669
5736
  }
5670
5737
  function listDirectoryEntriesSafe(dirPath) {
5671
5738
  const entries = fs4.readdirSync(dirPath, { withFileTypes: true });
5672
5739
  const files = [];
5673
5740
  for (const entry of entries) {
5674
- const entryPath = path6.join(dirPath, entry.name);
5741
+ const entryPath = path8.join(dirPath, entry.name);
5675
5742
  try {
5676
5743
  if (entry.isDirectory()) {
5677
5744
  files.push({ name: entry.name, type: "directory" });
@@ -5710,7 +5777,7 @@ async function handleFileRead(h, args) {
5710
5777
  async function handleFileWrite(h, args) {
5711
5778
  try {
5712
5779
  const filePath = resolveSafePath(args?.path);
5713
- fs4.mkdirSync(path6.dirname(filePath), { recursive: true });
5780
+ fs4.mkdirSync(path8.dirname(filePath), { recursive: true });
5714
5781
  fs4.writeFileSync(filePath, args?.content || "", "utf-8");
5715
5782
  return { success: true, path: filePath };
5716
5783
  } catch (e) {
@@ -5735,12 +5802,12 @@ async function handleFileListBrowse(h, args) {
5735
5802
  return { success: false, error: e.message };
5736
5803
  }
5737
5804
  }
5738
- var fs4, path6, os6, KEY_TO_VK;
5805
+ var fs4, path8, os6, KEY_TO_VK;
5739
5806
  var init_cdp_commands = __esm({
5740
5807
  "../../oss/packages/daemon-core/src/commands/cdp-commands.ts"() {
5741
5808
  "use strict";
5742
5809
  fs4 = __toESM(require("fs"));
5743
- path6 = __toESM(require("path"));
5810
+ path8 = __toESM(require("path"));
5744
5811
  os6 = __toESM(require("os"));
5745
5812
  KEY_TO_VK = {
5746
5813
  Backspace: 8,
@@ -5841,7 +5908,7 @@ function handleGetProviderSettings(h, args) {
5841
5908
  }
5842
5909
  return { success: true, settings: allSettings, values: allValues };
5843
5910
  }
5844
- function handleSetProviderSetting(h, args) {
5911
+ async function handleSetProviderSetting(h, args) {
5845
5912
  const loader = h.ctx.providerLoader;
5846
5913
  const { providerType, key, value } = args || {};
5847
5914
  if (!providerType || !key || value === void 0) {
@@ -5854,6 +5921,7 @@ function handleSetProviderSetting(h, args) {
5854
5921
  const updated = h.ctx.instanceManager.updateInstanceSettings(providerType, allSettings);
5855
5922
  LOG.info("Command", `[set_provider_setting] ${providerType}.${key}=${JSON.stringify(value)} \u2192 ${updated} instance(s) updated`);
5856
5923
  }
5924
+ await h.ctx.onProviderSettingChanged?.(providerType, key, value);
5857
5925
  return { success: true, providerType, key, value };
5858
5926
  }
5859
5927
  return { success: false, error: `Failed to set ${providerType}.${key} \u2014 invalid key, value, or not a public setting` };
@@ -6640,7 +6708,7 @@ var init_handler = __esm({
6640
6708
  try {
6641
6709
  const http3 = await import("http");
6642
6710
  const postData = JSON.stringify(body);
6643
- const result = await new Promise((resolve13, reject) => {
6711
+ const result = await new Promise((resolve16, reject) => {
6644
6712
  const req = http3.request({
6645
6713
  hostname: "127.0.0.1",
6646
6714
  port: 19280,
@@ -6652,9 +6720,9 @@ var init_handler = __esm({
6652
6720
  res.on("data", (chunk) => data += chunk);
6653
6721
  res.on("end", () => {
6654
6722
  try {
6655
- resolve13(JSON.parse(data));
6723
+ resolve16(JSON.parse(data));
6656
6724
  } catch {
6657
- resolve13({ raw: data });
6725
+ resolve16({ raw: data });
6658
6726
  }
6659
6727
  });
6660
6728
  });
@@ -6672,15 +6740,15 @@ var init_handler = __esm({
6672
6740
  if (!providerType) return { success: false, error: "providerType required" };
6673
6741
  try {
6674
6742
  const http3 = await import("http");
6675
- const result = await new Promise((resolve13, reject) => {
6743
+ const result = await new Promise((resolve16, reject) => {
6676
6744
  http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
6677
6745
  let data = "";
6678
6746
  res.on("data", (chunk) => data += chunk);
6679
6747
  res.on("end", () => {
6680
6748
  try {
6681
- resolve13(JSON.parse(data));
6749
+ resolve16(JSON.parse(data));
6682
6750
  } catch {
6683
- resolve13({ raw: data });
6751
+ resolve16({ raw: data });
6684
6752
  }
6685
6753
  });
6686
6754
  }).on("error", reject);
@@ -6694,7 +6762,7 @@ var init_handler = __esm({
6694
6762
  try {
6695
6763
  const http3 = await import("http");
6696
6764
  const postData = JSON.stringify(args || {});
6697
- const result = await new Promise((resolve13, reject) => {
6765
+ const result = await new Promise((resolve16, reject) => {
6698
6766
  const req = http3.request({
6699
6767
  hostname: "127.0.0.1",
6700
6768
  port: 19280,
@@ -6706,9 +6774,9 @@ var init_handler = __esm({
6706
6774
  res.on("data", (chunk) => data += chunk);
6707
6775
  res.on("end", () => {
6708
6776
  try {
6709
- resolve13(JSON.parse(data));
6777
+ resolve16(JSON.parse(data));
6710
6778
  } catch {
6711
- resolve13({ raw: data });
6779
+ resolve16({ raw: data });
6712
6780
  }
6713
6781
  });
6714
6782
  });
@@ -7345,16 +7413,22 @@ function computeTerminalQueryTail(buffer) {
7345
7413
  return "";
7346
7414
  }
7347
7415
  function findBinary(name) {
7416
+ const trimmed = String(name || "").trim();
7417
+ if (!trimmed) return trimmed;
7418
+ const expanded = trimmed.startsWith("~") ? path9.join(os9.homedir(), trimmed.slice(1)) : trimmed;
7419
+ if (path9.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
7420
+ return path9.isAbsolute(expanded) ? expanded : path9.resolve(expanded);
7421
+ }
7348
7422
  const isWin = os9.platform() === "win32";
7349
7423
  try {
7350
- const cmd = isWin ? `where ${name}` : `which ${name}`;
7424
+ const cmd = isWin ? `where ${trimmed}` : `which ${trimmed}`;
7351
7425
  return (0, import_child_process4.execSync)(cmd, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n")[0].trim();
7352
7426
  } catch {
7353
- return isWin ? `${name}.cmd` : name;
7427
+ return isWin ? `${trimmed}.cmd` : trimmed;
7354
7428
  }
7355
7429
  }
7356
7430
  function isScriptBinary(binaryPath) {
7357
- if (!path7.isAbsolute(binaryPath)) return false;
7431
+ if (!path9.isAbsolute(binaryPath)) return false;
7358
7432
  try {
7359
7433
  const fs18 = require("fs");
7360
7434
  const resolved = fs18.realpathSync(binaryPath);
@@ -7370,7 +7444,7 @@ function isScriptBinary(binaryPath) {
7370
7444
  }
7371
7445
  }
7372
7446
  function looksLikeMachOOrElf(filePath) {
7373
- if (!path7.isAbsolute(filePath)) return false;
7447
+ if (!path9.isAbsolute(filePath)) return false;
7374
7448
  try {
7375
7449
  const fs18 = require("fs");
7376
7450
  const resolved = fs18.realpathSync(filePath);
@@ -7494,12 +7568,12 @@ function normalizeCliProviderForRuntime(raw) {
7494
7568
  }
7495
7569
  };
7496
7570
  }
7497
- var os9, path7, import_child_process4, buildCliSpawnEnv, ProviderCliAdapter;
7571
+ var os9, path9, import_child_process4, buildCliSpawnEnv, ProviderCliAdapter;
7498
7572
  var init_provider_cli_adapter = __esm({
7499
7573
  "../../oss/packages/daemon-core/src/cli-adapters/provider-cli-adapter.ts"() {
7500
7574
  "use strict";
7501
7575
  os9 = __toESM(require("os"));
7502
- path7 = __toESM(require("path"));
7576
+ path9 = __toESM(require("path"));
7503
7577
  import_child_process4 = require("child_process");
7504
7578
  init_logger();
7505
7579
  init_terminal_screen();
@@ -7854,16 +7928,17 @@ var init_provider_cli_adapter = __esm({
7854
7928
  async spawn() {
7855
7929
  if (this.ptyProcess) return;
7856
7930
  const { spawn: spawnConfig } = this.provider;
7857
- const binaryPath = findBinary(spawnConfig.command);
7931
+ const configuredCommand = typeof this.runtimeSettings.executablePath === "string" && this.runtimeSettings.executablePath.trim() ? this.runtimeSettings.executablePath.trim() : spawnConfig.command;
7932
+ const binaryPath = findBinary(configuredCommand);
7858
7933
  const isWin = os9.platform() === "win32";
7859
7934
  const allArgs = [...spawnConfig.args, ...this.extraArgs];
7860
7935
  LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
7861
7936
  this.resetTraceSession();
7862
7937
  let shellCmd;
7863
7938
  let shellArgs;
7864
- const useShellUnix = !isWin && (!!spawnConfig.shell || !path7.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
7939
+ const useShellUnix = !isWin && (!!spawnConfig.shell || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
7865
7940
  const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
7866
- const useShellWin = !!spawnConfig.shell || isCmdShim || !path7.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
7941
+ const useShellWin = !!spawnConfig.shell || isCmdShim || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
7867
7942
  const useShell = isWin ? useShellWin : useShellUnix;
7868
7943
  if (useShell) {
7869
7944
  if (!spawnConfig.shell && !isWin) {
@@ -8237,7 +8312,7 @@ var init_provider_cli_adapter = __esm({
8237
8312
  `[${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)}`
8238
8313
  );
8239
8314
  }
8240
- await new Promise((resolve13) => setTimeout(resolve13, 50));
8315
+ await new Promise((resolve16) => setTimeout(resolve16, 50));
8241
8316
  }
8242
8317
  const finalScreenText = this.terminalScreen.getText() || "";
8243
8318
  LOG.warn(
@@ -8748,7 +8823,7 @@ ${data.message || ""}`.trim();
8748
8823
  const deadline = Date.now() + 1e4;
8749
8824
  while (this.startupParseGate && Date.now() < deadline) {
8750
8825
  this.resolveStartupState("send_wait");
8751
- await new Promise((resolve13) => setTimeout(resolve13, 50));
8826
+ await new Promise((resolve16) => setTimeout(resolve16, 50));
8752
8827
  }
8753
8828
  }
8754
8829
  await this.waitForInteractivePrompt();
@@ -8973,17 +9048,17 @@ ${data.message || ""}`.trim();
8973
9048
  }
8974
9049
  }
8975
9050
  waitForStopped(timeoutMs) {
8976
- return new Promise((resolve13) => {
9051
+ return new Promise((resolve16) => {
8977
9052
  const startedAt = Date.now();
8978
9053
  const timer = setInterval(() => {
8979
9054
  if (!this.ptyProcess || this.currentStatus === "stopped") {
8980
9055
  clearInterval(timer);
8981
- resolve13(true);
9056
+ resolve16(true);
8982
9057
  return;
8983
9058
  }
8984
9059
  if (Date.now() - startedAt >= timeoutMs) {
8985
9060
  clearInterval(timer);
8986
- resolve13(false);
9061
+ resolve16(false);
8987
9062
  }
8988
9063
  }, 100);
8989
9064
  });
@@ -9271,7 +9346,7 @@ ${data.message || ""}`.trim();
9271
9346
  // ../../oss/packages/daemon-core/src/providers/cli-provider-instance.ts
9272
9347
  function getDatabaseSync() {
9273
9348
  if (CachedDatabaseSync) return CachedDatabaseSync;
9274
- const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path8.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
9349
+ const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path10.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
9275
9350
  const sqliteModule = requireFn(`node:${"sqlite"}`);
9276
9351
  CachedDatabaseSync = sqliteModule.DatabaseSync;
9277
9352
  if (!CachedDatabaseSync) {
@@ -9279,12 +9354,12 @@ function getDatabaseSync() {
9279
9354
  }
9280
9355
  return CachedDatabaseSync;
9281
9356
  }
9282
- var os10, path8, crypto3, fs5, import_node_module, CachedDatabaseSync, CliProviderInstance;
9357
+ var os10, path10, crypto3, fs5, import_node_module, CachedDatabaseSync, CliProviderInstance;
9283
9358
  var init_cli_provider_instance = __esm({
9284
9359
  "../../oss/packages/daemon-core/src/providers/cli-provider-instance.ts"() {
9285
9360
  "use strict";
9286
9361
  os10 = __toESM(require("os"));
9287
- path8 = __toESM(require("path"));
9362
+ path10 = __toESM(require("path"));
9288
9363
  crypto3 = __toESM(require("crypto"));
9289
9364
  fs5 = __toESM(require("fs"));
9290
9365
  import_node_module = require("module");
@@ -10153,10 +10228,10 @@ function mergeDefs(...defs) {
10153
10228
  function cloneDef(schema) {
10154
10229
  return mergeDefs(schema._zod.def);
10155
10230
  }
10156
- function getElementAtPath(obj, path23) {
10157
- if (!path23)
10231
+ function getElementAtPath(obj, path25) {
10232
+ if (!path25)
10158
10233
  return obj;
10159
- return path23.reduce((acc, key) => acc?.[key], obj);
10234
+ return path25.reduce((acc, key) => acc?.[key], obj);
10160
10235
  }
10161
10236
  function promiseAllObject(promisesObj) {
10162
10237
  const keys = Object.keys(promisesObj);
@@ -10468,11 +10543,11 @@ function aborted(x, startIndex = 0) {
10468
10543
  }
10469
10544
  return false;
10470
10545
  }
10471
- function prefixIssues(path23, issues) {
10546
+ function prefixIssues(path25, issues) {
10472
10547
  return issues.map((iss) => {
10473
10548
  var _a2;
10474
10549
  (_a2 = iss).path ?? (_a2.path = []);
10475
- iss.path.unshift(path23);
10550
+ iss.path.unshift(path25);
10476
10551
  return iss;
10477
10552
  });
10478
10553
  }
@@ -10715,7 +10790,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
10715
10790
  }
10716
10791
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
10717
10792
  const result = { errors: [] };
10718
- const processError = (error49, path23 = []) => {
10793
+ const processError = (error49, path25 = []) => {
10719
10794
  var _a2, _b;
10720
10795
  for (const issue2 of error49.issues) {
10721
10796
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -10725,7 +10800,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
10725
10800
  } else if (issue2.code === "invalid_element") {
10726
10801
  processError({ issues: issue2.issues }, issue2.path);
10727
10802
  } else {
10728
- const fullpath = [...path23, ...issue2.path];
10803
+ const fullpath = [...path25, ...issue2.path];
10729
10804
  if (fullpath.length === 0) {
10730
10805
  result.errors.push(mapper(issue2));
10731
10806
  continue;
@@ -10757,8 +10832,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
10757
10832
  }
10758
10833
  function toDotPath(_path) {
10759
10834
  const segs = [];
10760
- const path23 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
10761
- for (const seg of path23) {
10835
+ const path25 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
10836
+ for (const seg of path25) {
10762
10837
  if (typeof seg === "number")
10763
10838
  segs.push(`[${seg}]`);
10764
10839
  else if (typeof seg === "symbol")
@@ -23522,13 +23597,13 @@ function resolveRef(ref, ctx) {
23522
23597
  if (!ref.startsWith("#")) {
23523
23598
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
23524
23599
  }
23525
- const path23 = ref.slice(1).split("/").filter(Boolean);
23526
- if (path23.length === 0) {
23600
+ const path25 = ref.slice(1).split("/").filter(Boolean);
23601
+ if (path25.length === 0) {
23527
23602
  return ctx.rootSchema;
23528
23603
  }
23529
23604
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
23530
- if (path23[0] === defsKey) {
23531
- const key = path23[1];
23605
+ if (path25[0] === defsKey) {
23606
+ const key = path25[1];
23532
23607
  if (!key || !ctx.defs[key]) {
23533
23608
  throw new Error(`Reference not found: ${ref}`);
23534
23609
  }
@@ -25955,8 +26030,8 @@ var init_acp = __esm({
25955
26030
  this.#requestHandler = requestHandler;
25956
26031
  this.#notificationHandler = notificationHandler;
25957
26032
  this.#stream = stream;
25958
- this.#closedPromise = new Promise((resolve13) => {
25959
- this.#abortController.signal.addEventListener("abort", () => resolve13());
26033
+ this.#closedPromise = new Promise((resolve16) => {
26034
+ this.#abortController.signal.addEventListener("abort", () => resolve16());
25960
26035
  });
25961
26036
  this.#receive();
25962
26037
  }
@@ -26105,8 +26180,8 @@ var init_acp = __esm({
26105
26180
  }
26106
26181
  async sendRequest(method, params) {
26107
26182
  const id = this.#nextRequestId++;
26108
- const responsePromise = new Promise((resolve13, reject) => {
26109
- this.#pendingResponses.set(id, { resolve: resolve13, reject });
26183
+ const responsePromise = new Promise((resolve16, reject) => {
26184
+ this.#pendingResponses.set(id, { resolve: resolve16, reject });
26110
26185
  });
26111
26186
  await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
26112
26187
  return responsePromise;
@@ -26427,8 +26502,9 @@ var init_acp_provider_instance = __esm({
26427
26502
  async setConfigOption(category, value) {
26428
26503
  const opt = this.configOptions.find((c) => c.category === category);
26429
26504
  if (!opt) {
26430
- this.log.warn(`[${this.type}] No config option for category: ${category}`);
26431
- return;
26505
+ const message = `[${this.type}] No config option for category: ${category}`;
26506
+ this.log.warn(message);
26507
+ throw new Error(message);
26432
26508
  }
26433
26509
  if (this.useStaticConfig) {
26434
26510
  opt.currentValue = value;
@@ -26440,8 +26516,9 @@ var init_acp_provider_instance = __esm({
26440
26516
  return;
26441
26517
  }
26442
26518
  if (!this.connection || !this.sessionId) {
26443
- this.log.warn(`[${this.type}] Cannot set config: no active connection/session`);
26444
- return;
26519
+ const message = `[${this.type}] Cannot set config: no active connection/session`;
26520
+ this.log.warn(message);
26521
+ throw new Error(message);
26445
26522
  }
26446
26523
  try {
26447
26524
  this.log.info(`[${this.type}] Sending session/set_config_option: configId=${opt.configId} value=${value} sessionId=${this.sessionId}`);
@@ -26455,7 +26532,9 @@ var init_acp_provider_instance = __esm({
26455
26532
  if (result?.configOptions) this.parseConfigOptions(result.configOptions);
26456
26533
  this.log.info(`[${this.type}] Config ${category} set to: ${value} | response: ${JSON.stringify(result)?.slice(0, 300)}`);
26457
26534
  } catch (e) {
26458
- this.log.warn(`[${this.type}] set_config_option failed: ${e?.message}`);
26535
+ const message = e?.message || "Unknown ACP config error";
26536
+ this.log.warn(`[${this.type}] set_config_option failed: ${message}`);
26537
+ throw new Error(message);
26459
26538
  }
26460
26539
  }
26461
26540
  async setMode(modeId) {
@@ -26471,8 +26550,9 @@ var init_acp_provider_instance = __esm({
26471
26550
  return;
26472
26551
  }
26473
26552
  if (!this.connection || !this.sessionId) {
26474
- this.log.warn(`[${this.type}] Cannot set mode: no active connection/session`);
26475
- return;
26553
+ const message = `[${this.type}] Cannot set mode: no active connection/session`;
26554
+ this.log.warn(message);
26555
+ throw new Error(message);
26476
26556
  }
26477
26557
  try {
26478
26558
  await this.connection.setSessionMode({
@@ -26482,7 +26562,9 @@ var init_acp_provider_instance = __esm({
26482
26562
  this.currentMode = modeId;
26483
26563
  this.log.info(`[${this.type}] Mode set to: ${modeId}`);
26484
26564
  } catch (e) {
26485
- this.log.warn(`[${this.type}] set_mode failed: ${e?.message}`);
26565
+ const message = e?.message || "Unknown ACP mode error";
26566
+ this.log.warn(`[${this.type}] set_mode failed: ${message}`);
26567
+ throw new Error(message);
26486
26568
  }
26487
26569
  }
26488
26570
  /** Static config: kill process and restart with new args */
@@ -26530,7 +26612,7 @@ var init_acp_provider_instance = __esm({
26530
26612
  if (!spawnConfig) {
26531
26613
  throw new Error(`[ACP:${this.type}] No spawn config defined`);
26532
26614
  }
26533
- const command = spawnConfig.command;
26615
+ const command = typeof this.settings.executablePath === "string" && this.settings.executablePath.trim() ? this.settings.executablePath.trim() : spawnConfig.command;
26534
26616
  let baseArgs = spawnConfig.args || [];
26535
26617
  if (this.provider.spawnArgBuilder && Object.keys(this.selectedConfig).length > 0) {
26536
26618
  baseArgs = this.provider.spawnArgBuilder(this.selectedConfig);
@@ -26646,13 +26728,13 @@ var init_acp_provider_instance = __esm({
26646
26728
  }
26647
26729
  this.currentStatus = "waiting_approval";
26648
26730
  this.detectStatusTransition();
26649
- const approved = await new Promise((resolve13) => {
26650
- this.permissionResolvers.push(resolve13);
26731
+ const approved = await new Promise((resolve16) => {
26732
+ this.permissionResolvers.push(resolve16);
26651
26733
  setTimeout(() => {
26652
- const idx = this.permissionResolvers.indexOf(resolve13);
26734
+ const idx = this.permissionResolvers.indexOf(resolve16);
26653
26735
  if (idx >= 0) {
26654
26736
  this.permissionResolvers.splice(idx, 1);
26655
- resolve13(false);
26737
+ resolve16(false);
26656
26738
  }
26657
26739
  }, 3e5);
26658
26740
  });
@@ -27221,12 +27303,12 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
27221
27303
  launchMode: "new"
27222
27304
  };
27223
27305
  }
27224
- var os11, path9, crypto4, import_chalk, chalkApi, DaemonCliManager;
27306
+ var os11, path11, crypto4, import_chalk, chalkApi, DaemonCliManager;
27225
27307
  var init_cli_manager = __esm({
27226
27308
  "../../oss/packages/daemon-core/src/commands/cli-manager.ts"() {
27227
27309
  "use strict";
27228
27310
  os11 = __toESM(require("os"));
27229
- path9 = __toESM(require("path"));
27311
+ path11 = __toESM(require("path"));
27230
27312
  crypto4 = __toESM(require("crypto"));
27231
27313
  import_chalk = __toESM(require("chalk"));
27232
27314
  init_provider_cli_adapter();
@@ -27378,7 +27460,7 @@ var init_cli_manager = __esm({
27378
27460
  async startSession(cliType, workingDir, cliArgs, initialModel, options) {
27379
27461
  const trimmed = (workingDir || "").trim();
27380
27462
  if (!trimmed) throw new Error("working directory required");
27381
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os11.homedir()) : path9.resolve(trimmed);
27463
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os11.homedir()) : path11.resolve(trimmed);
27382
27464
  const normalizedType = this.providerLoader.resolveAlias(cliType);
27383
27465
  const provider = this.providerLoader.getByAlias(cliType);
27384
27466
  const key = crypto4.randomUUID();
@@ -27465,10 +27547,10 @@ ${installInfo}`
27465
27547
  if (!cliInfo) {
27466
27548
  const installHint = provider?.install || "";
27467
27549
  const displayName = provider?.displayName || provider?.name || cliType;
27468
- const spawnCmd = provider?.spawn?.command || cliType;
27550
+ const spawnCmd = this.providerLoader.getSpawnCommand(normalizedType, provider?.spawn?.command || cliType);
27469
27551
  throw new Error(
27470
27552
  `${displayName} is not installed.
27471
- Command '${spawnCmd}' not found on PATH.
27553
+ Command '${spawnCmd}' is not available.
27472
27554
  ` + (installHint ? `
27473
27555
  ${installHint}
27474
27556
  ` : "") + `
@@ -27930,7 +28012,7 @@ var init_readdirp = __esm({
27930
28012
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
27931
28013
  const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
27932
28014
  if (wantBigintFsStats) {
27933
- this._stat = (path23) => statMethod(path23, { bigint: true });
28015
+ this._stat = (path25) => statMethod(path25, { bigint: true });
27934
28016
  } else {
27935
28017
  this._stat = statMethod;
27936
28018
  }
@@ -27955,8 +28037,8 @@ var init_readdirp = __esm({
27955
28037
  const par = this.parent;
27956
28038
  const fil = par && par.files;
27957
28039
  if (fil && fil.length > 0) {
27958
- const { path: path23, depth } = par;
27959
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path23));
28040
+ const { path: path25, depth } = par;
28041
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path25));
27960
28042
  const awaited = await Promise.all(slice);
27961
28043
  for (const entry of awaited) {
27962
28044
  if (!entry)
@@ -27996,20 +28078,20 @@ var init_readdirp = __esm({
27996
28078
  this.reading = false;
27997
28079
  }
27998
28080
  }
27999
- async _exploreDir(path23, depth) {
28081
+ async _exploreDir(path25, depth) {
28000
28082
  let files;
28001
28083
  try {
28002
- files = await (0, import_promises.readdir)(path23, this._rdOptions);
28084
+ files = await (0, import_promises.readdir)(path25, this._rdOptions);
28003
28085
  } catch (error48) {
28004
28086
  this._onError(error48);
28005
28087
  }
28006
- return { files, depth, path: path23 };
28088
+ return { files, depth, path: path25 };
28007
28089
  }
28008
- async _formatEntry(dirent, path23) {
28090
+ async _formatEntry(dirent, path25) {
28009
28091
  let entry;
28010
28092
  const basename7 = this._isDirent ? dirent.name : dirent;
28011
28093
  try {
28012
- const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path23, basename7));
28094
+ const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path25, basename7));
28013
28095
  entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename7 };
28014
28096
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
28015
28097
  } catch (err) {
@@ -28066,16 +28148,16 @@ var init_readdirp = __esm({
28066
28148
  });
28067
28149
 
28068
28150
  // ../../oss/packages/daemon-core/node_modules/chokidar/handler.js
28069
- function createFsWatchInstance(path23, options, listener, errHandler, emitRaw) {
28151
+ function createFsWatchInstance(path25, options, listener, errHandler, emitRaw) {
28070
28152
  const handleEvent = (rawEvent, evPath) => {
28071
- listener(path23);
28072
- emitRaw(rawEvent, evPath, { watchedPath: path23 });
28073
- if (evPath && path23 !== evPath) {
28074
- fsWatchBroadcast(sp.resolve(path23, evPath), KEY_LISTENERS, sp.join(path23, evPath));
28153
+ listener(path25);
28154
+ emitRaw(rawEvent, evPath, { watchedPath: path25 });
28155
+ if (evPath && path25 !== evPath) {
28156
+ fsWatchBroadcast(sp.resolve(path25, evPath), KEY_LISTENERS, sp.join(path25, evPath));
28075
28157
  }
28076
28158
  };
28077
28159
  try {
28078
- return (0, import_node_fs.watch)(path23, {
28160
+ return (0, import_node_fs.watch)(path25, {
28079
28161
  persistent: options.persistent
28080
28162
  }, handleEvent);
28081
28163
  } catch (error48) {
@@ -28424,12 +28506,12 @@ var init_handler2 = __esm({
28424
28506
  listener(val1, val2, val3);
28425
28507
  });
28426
28508
  };
28427
- setFsWatchListener = (path23, fullPath, options, handlers) => {
28509
+ setFsWatchListener = (path25, fullPath, options, handlers) => {
28428
28510
  const { listener, errHandler, rawEmitter } = handlers;
28429
28511
  let cont = FsWatchInstances.get(fullPath);
28430
28512
  let watcher;
28431
28513
  if (!options.persistent) {
28432
- watcher = createFsWatchInstance(path23, options, listener, errHandler, rawEmitter);
28514
+ watcher = createFsWatchInstance(path25, options, listener, errHandler, rawEmitter);
28433
28515
  if (!watcher)
28434
28516
  return;
28435
28517
  return watcher.close.bind(watcher);
@@ -28440,7 +28522,7 @@ var init_handler2 = __esm({
28440
28522
  addAndConvert(cont, KEY_RAW, rawEmitter);
28441
28523
  } else {
28442
28524
  watcher = createFsWatchInstance(
28443
- path23,
28525
+ path25,
28444
28526
  options,
28445
28527
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
28446
28528
  errHandler,
@@ -28455,7 +28537,7 @@ var init_handler2 = __esm({
28455
28537
  cont.watcherUnusable = true;
28456
28538
  if (isWindows && error48.code === "EPERM") {
28457
28539
  try {
28458
- const fd = await (0, import_promises2.open)(path23, "r");
28540
+ const fd = await (0, import_promises2.open)(path25, "r");
28459
28541
  await fd.close();
28460
28542
  broadcastErr(error48);
28461
28543
  } catch (err) {
@@ -28486,7 +28568,7 @@ var init_handler2 = __esm({
28486
28568
  };
28487
28569
  };
28488
28570
  FsWatchFileInstances = /* @__PURE__ */ new Map();
28489
- setFsWatchFileListener = (path23, fullPath, options, handlers) => {
28571
+ setFsWatchFileListener = (path25, fullPath, options, handlers) => {
28490
28572
  const { listener, rawEmitter } = handlers;
28491
28573
  let cont = FsWatchFileInstances.get(fullPath);
28492
28574
  const copts = cont && cont.options;
@@ -28508,7 +28590,7 @@ var init_handler2 = __esm({
28508
28590
  });
28509
28591
  const currmtime = curr.mtimeMs;
28510
28592
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
28511
- foreach(cont.listeners, (listener2) => listener2(path23, curr));
28593
+ foreach(cont.listeners, (listener2) => listener2(path25, curr));
28512
28594
  }
28513
28595
  })
28514
28596
  };
@@ -28538,13 +28620,13 @@ var init_handler2 = __esm({
28538
28620
  * @param listener on fs change
28539
28621
  * @returns closer for the watcher instance
28540
28622
  */
28541
- _watchWithNodeFs(path23, listener) {
28623
+ _watchWithNodeFs(path25, listener) {
28542
28624
  const opts = this.fsw.options;
28543
- const directory = sp.dirname(path23);
28544
- const basename7 = sp.basename(path23);
28625
+ const directory = sp.dirname(path25);
28626
+ const basename7 = sp.basename(path25);
28545
28627
  const parent = this.fsw._getWatchedDir(directory);
28546
28628
  parent.add(basename7);
28547
- const absolutePath = sp.resolve(path23);
28629
+ const absolutePath = sp.resolve(path25);
28548
28630
  const options = {
28549
28631
  persistent: opts.persistent
28550
28632
  };
@@ -28554,12 +28636,12 @@ var init_handler2 = __esm({
28554
28636
  if (opts.usePolling) {
28555
28637
  const enableBin = opts.interval !== opts.binaryInterval;
28556
28638
  options.interval = enableBin && isBinaryPath(basename7) ? opts.binaryInterval : opts.interval;
28557
- closer = setFsWatchFileListener(path23, absolutePath, options, {
28639
+ closer = setFsWatchFileListener(path25, absolutePath, options, {
28558
28640
  listener,
28559
28641
  rawEmitter: this.fsw._emitRaw
28560
28642
  });
28561
28643
  } else {
28562
- closer = setFsWatchListener(path23, absolutePath, options, {
28644
+ closer = setFsWatchListener(path25, absolutePath, options, {
28563
28645
  listener,
28564
28646
  errHandler: this._boundHandleError,
28565
28647
  rawEmitter: this.fsw._emitRaw
@@ -28581,7 +28663,7 @@ var init_handler2 = __esm({
28581
28663
  let prevStats = stats;
28582
28664
  if (parent.has(basename7))
28583
28665
  return;
28584
- const listener = async (path23, newStats) => {
28666
+ const listener = async (path25, newStats) => {
28585
28667
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file2, 5))
28586
28668
  return;
28587
28669
  if (!newStats || newStats.mtimeMs === 0) {
@@ -28595,11 +28677,11 @@ var init_handler2 = __esm({
28595
28677
  this.fsw._emit(EV.CHANGE, file2, newStats2);
28596
28678
  }
28597
28679
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
28598
- this.fsw._closeFile(path23);
28680
+ this.fsw._closeFile(path25);
28599
28681
  prevStats = newStats2;
28600
28682
  const closer2 = this._watchWithNodeFs(file2, listener);
28601
28683
  if (closer2)
28602
- this.fsw._addPathCloser(path23, closer2);
28684
+ this.fsw._addPathCloser(path25, closer2);
28603
28685
  } else {
28604
28686
  prevStats = newStats2;
28605
28687
  }
@@ -28631,7 +28713,7 @@ var init_handler2 = __esm({
28631
28713
  * @param item basename of this item
28632
28714
  * @returns true if no more processing is needed for this entry.
28633
28715
  */
28634
- async _handleSymlink(entry, directory, path23, item) {
28716
+ async _handleSymlink(entry, directory, path25, item) {
28635
28717
  if (this.fsw.closed) {
28636
28718
  return;
28637
28719
  }
@@ -28641,7 +28723,7 @@ var init_handler2 = __esm({
28641
28723
  this.fsw._incrReadyCount();
28642
28724
  let linkPath;
28643
28725
  try {
28644
- linkPath = await (0, import_promises2.realpath)(path23);
28726
+ linkPath = await (0, import_promises2.realpath)(path25);
28645
28727
  } catch (e) {
28646
28728
  this.fsw._emitReady();
28647
28729
  return true;
@@ -28651,12 +28733,12 @@ var init_handler2 = __esm({
28651
28733
  if (dir.has(item)) {
28652
28734
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
28653
28735
  this.fsw._symlinkPaths.set(full, linkPath);
28654
- this.fsw._emit(EV.CHANGE, path23, entry.stats);
28736
+ this.fsw._emit(EV.CHANGE, path25, entry.stats);
28655
28737
  }
28656
28738
  } else {
28657
28739
  dir.add(item);
28658
28740
  this.fsw._symlinkPaths.set(full, linkPath);
28659
- this.fsw._emit(EV.ADD, path23, entry.stats);
28741
+ this.fsw._emit(EV.ADD, path25, entry.stats);
28660
28742
  }
28661
28743
  this.fsw._emitReady();
28662
28744
  return true;
@@ -28686,9 +28768,9 @@ var init_handler2 = __esm({
28686
28768
  return;
28687
28769
  }
28688
28770
  const item = entry.path;
28689
- let path23 = sp.join(directory, item);
28771
+ let path25 = sp.join(directory, item);
28690
28772
  current.add(item);
28691
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path23, item)) {
28773
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path25, item)) {
28692
28774
  return;
28693
28775
  }
28694
28776
  if (this.fsw.closed) {
@@ -28697,11 +28779,11 @@ var init_handler2 = __esm({
28697
28779
  }
28698
28780
  if (item === target || !target && !previous.has(item)) {
28699
28781
  this.fsw._incrReadyCount();
28700
- path23 = sp.join(dir, sp.relative(dir, path23));
28701
- this._addToNodeFs(path23, initialAdd, wh, depth + 1);
28782
+ path25 = sp.join(dir, sp.relative(dir, path25));
28783
+ this._addToNodeFs(path25, initialAdd, wh, depth + 1);
28702
28784
  }
28703
28785
  }).on(EV.ERROR, this._boundHandleError);
28704
- return new Promise((resolve13, reject) => {
28786
+ return new Promise((resolve16, reject) => {
28705
28787
  if (!stream)
28706
28788
  return reject();
28707
28789
  stream.once(STR_END, () => {
@@ -28710,7 +28792,7 @@ var init_handler2 = __esm({
28710
28792
  return;
28711
28793
  }
28712
28794
  const wasThrottled = throttler ? throttler.clear() : false;
28713
- resolve13(void 0);
28795
+ resolve16(void 0);
28714
28796
  previous.getChildren().filter((item) => {
28715
28797
  return item !== directory && !current.has(item);
28716
28798
  }).forEach((item) => {
@@ -28767,13 +28849,13 @@ var init_handler2 = __esm({
28767
28849
  * @param depth Child path actually targeted for watch
28768
28850
  * @param target Child path actually targeted for watch
28769
28851
  */
28770
- async _addToNodeFs(path23, initialAdd, priorWh, depth, target) {
28852
+ async _addToNodeFs(path25, initialAdd, priorWh, depth, target) {
28771
28853
  const ready = this.fsw._emitReady;
28772
- if (this.fsw._isIgnored(path23) || this.fsw.closed) {
28854
+ if (this.fsw._isIgnored(path25) || this.fsw.closed) {
28773
28855
  ready();
28774
28856
  return false;
28775
28857
  }
28776
- const wh = this.fsw._getWatchHelpers(path23);
28858
+ const wh = this.fsw._getWatchHelpers(path25);
28777
28859
  if (priorWh) {
28778
28860
  wh.filterPath = (entry) => priorWh.filterPath(entry);
28779
28861
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -28789,8 +28871,8 @@ var init_handler2 = __esm({
28789
28871
  const follow = this.fsw.options.followSymlinks;
28790
28872
  let closer;
28791
28873
  if (stats.isDirectory()) {
28792
- const absPath = sp.resolve(path23);
28793
- const targetPath = follow ? await (0, import_promises2.realpath)(path23) : path23;
28874
+ const absPath = sp.resolve(path25);
28875
+ const targetPath = follow ? await (0, import_promises2.realpath)(path25) : path25;
28794
28876
  if (this.fsw.closed)
28795
28877
  return;
28796
28878
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -28800,29 +28882,29 @@ var init_handler2 = __esm({
28800
28882
  this.fsw._symlinkPaths.set(absPath, targetPath);
28801
28883
  }
28802
28884
  } else if (stats.isSymbolicLink()) {
28803
- const targetPath = follow ? await (0, import_promises2.realpath)(path23) : path23;
28885
+ const targetPath = follow ? await (0, import_promises2.realpath)(path25) : path25;
28804
28886
  if (this.fsw.closed)
28805
28887
  return;
28806
28888
  const parent = sp.dirname(wh.watchPath);
28807
28889
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
28808
28890
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
28809
- closer = await this._handleDir(parent, stats, initialAdd, depth, path23, wh, targetPath);
28891
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path25, wh, targetPath);
28810
28892
  if (this.fsw.closed)
28811
28893
  return;
28812
28894
  if (targetPath !== void 0) {
28813
- this.fsw._symlinkPaths.set(sp.resolve(path23), targetPath);
28895
+ this.fsw._symlinkPaths.set(sp.resolve(path25), targetPath);
28814
28896
  }
28815
28897
  } else {
28816
28898
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
28817
28899
  }
28818
28900
  ready();
28819
28901
  if (closer)
28820
- this.fsw._addPathCloser(path23, closer);
28902
+ this.fsw._addPathCloser(path25, closer);
28821
28903
  return false;
28822
28904
  } catch (error48) {
28823
28905
  if (this.fsw._handleError(error48)) {
28824
28906
  ready();
28825
- return path23;
28907
+ return path25;
28826
28908
  }
28827
28909
  }
28828
28910
  }
@@ -28857,24 +28939,24 @@ function createPattern(matcher) {
28857
28939
  }
28858
28940
  return () => false;
28859
28941
  }
28860
- function normalizePath(path23) {
28861
- if (typeof path23 !== "string")
28942
+ function normalizePath(path25) {
28943
+ if (typeof path25 !== "string")
28862
28944
  throw new Error("string expected");
28863
- path23 = sp2.normalize(path23);
28864
- path23 = path23.replace(/\\/g, "/");
28945
+ path25 = sp2.normalize(path25);
28946
+ path25 = path25.replace(/\\/g, "/");
28865
28947
  let prepend = false;
28866
- if (path23.startsWith("//"))
28948
+ if (path25.startsWith("//"))
28867
28949
  prepend = true;
28868
- path23 = path23.replace(DOUBLE_SLASH_RE, "/");
28950
+ path25 = path25.replace(DOUBLE_SLASH_RE, "/");
28869
28951
  if (prepend)
28870
- path23 = "/" + path23;
28871
- return path23;
28952
+ path25 = "/" + path25;
28953
+ return path25;
28872
28954
  }
28873
28955
  function matchPatterns(patterns, testString, stats) {
28874
- const path23 = normalizePath(testString);
28956
+ const path25 = normalizePath(testString);
28875
28957
  for (let index = 0; index < patterns.length; index++) {
28876
28958
  const pattern = patterns[index];
28877
- if (pattern(path23, stats)) {
28959
+ if (pattern(path25, stats)) {
28878
28960
  return true;
28879
28961
  }
28880
28962
  }
@@ -28937,19 +29019,19 @@ var init_chokidar = __esm({
28937
29019
  }
28938
29020
  return str;
28939
29021
  };
28940
- normalizePathToUnix = (path23) => toUnix(sp2.normalize(toUnix(path23)));
28941
- normalizeIgnored = (cwd = "") => (path23) => {
28942
- if (typeof path23 === "string") {
28943
- return normalizePathToUnix(sp2.isAbsolute(path23) ? path23 : sp2.join(cwd, path23));
29022
+ normalizePathToUnix = (path25) => toUnix(sp2.normalize(toUnix(path25)));
29023
+ normalizeIgnored = (cwd = "") => (path25) => {
29024
+ if (typeof path25 === "string") {
29025
+ return normalizePathToUnix(sp2.isAbsolute(path25) ? path25 : sp2.join(cwd, path25));
28944
29026
  } else {
28945
- return path23;
29027
+ return path25;
28946
29028
  }
28947
29029
  };
28948
- getAbsolutePath = (path23, cwd) => {
28949
- if (sp2.isAbsolute(path23)) {
28950
- return path23;
29030
+ getAbsolutePath = (path25, cwd) => {
29031
+ if (sp2.isAbsolute(path25)) {
29032
+ return path25;
28951
29033
  }
28952
- return sp2.join(cwd, path23);
29034
+ return sp2.join(cwd, path25);
28953
29035
  };
28954
29036
  EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
28955
29037
  DirEntry = class {
@@ -29014,10 +29096,10 @@ var init_chokidar = __esm({
29014
29096
  dirParts;
29015
29097
  followSymlinks;
29016
29098
  statMethod;
29017
- constructor(path23, follow, fsw) {
29099
+ constructor(path25, follow, fsw) {
29018
29100
  this.fsw = fsw;
29019
- const watchPath = path23;
29020
- this.path = path23 = path23.replace(REPLACER_RE, "");
29101
+ const watchPath = path25;
29102
+ this.path = path25 = path25.replace(REPLACER_RE, "");
29021
29103
  this.watchPath = watchPath;
29022
29104
  this.fullWatchPath = sp2.resolve(watchPath);
29023
29105
  this.dirParts = [];
@@ -29157,20 +29239,20 @@ var init_chokidar = __esm({
29157
29239
  this._closePromise = void 0;
29158
29240
  let paths = unifyPaths(paths_);
29159
29241
  if (cwd) {
29160
- paths = paths.map((path23) => {
29161
- const absPath = getAbsolutePath(path23, cwd);
29242
+ paths = paths.map((path25) => {
29243
+ const absPath = getAbsolutePath(path25, cwd);
29162
29244
  return absPath;
29163
29245
  });
29164
29246
  }
29165
- paths.forEach((path23) => {
29166
- this._removeIgnoredPath(path23);
29247
+ paths.forEach((path25) => {
29248
+ this._removeIgnoredPath(path25);
29167
29249
  });
29168
29250
  this._userIgnored = void 0;
29169
29251
  if (!this._readyCount)
29170
29252
  this._readyCount = 0;
29171
29253
  this._readyCount += paths.length;
29172
- Promise.all(paths.map(async (path23) => {
29173
- const res = await this._nodeFsHandler._addToNodeFs(path23, !_internal, void 0, 0, _origAdd);
29254
+ Promise.all(paths.map(async (path25) => {
29255
+ const res = await this._nodeFsHandler._addToNodeFs(path25, !_internal, void 0, 0, _origAdd);
29174
29256
  if (res)
29175
29257
  this._emitReady();
29176
29258
  return res;
@@ -29192,17 +29274,17 @@ var init_chokidar = __esm({
29192
29274
  return this;
29193
29275
  const paths = unifyPaths(paths_);
29194
29276
  const { cwd } = this.options;
29195
- paths.forEach((path23) => {
29196
- if (!sp2.isAbsolute(path23) && !this._closers.has(path23)) {
29277
+ paths.forEach((path25) => {
29278
+ if (!sp2.isAbsolute(path25) && !this._closers.has(path25)) {
29197
29279
  if (cwd)
29198
- path23 = sp2.join(cwd, path23);
29199
- path23 = sp2.resolve(path23);
29280
+ path25 = sp2.join(cwd, path25);
29281
+ path25 = sp2.resolve(path25);
29200
29282
  }
29201
- this._closePath(path23);
29202
- this._addIgnoredPath(path23);
29203
- if (this._watched.has(path23)) {
29283
+ this._closePath(path25);
29284
+ this._addIgnoredPath(path25);
29285
+ if (this._watched.has(path25)) {
29204
29286
  this._addIgnoredPath({
29205
- path: path23,
29287
+ path: path25,
29206
29288
  recursive: true
29207
29289
  });
29208
29290
  }
@@ -29266,38 +29348,38 @@ var init_chokidar = __esm({
29266
29348
  * @param stats arguments to be passed with event
29267
29349
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
29268
29350
  */
29269
- async _emit(event, path23, stats) {
29351
+ async _emit(event, path25, stats) {
29270
29352
  if (this.closed)
29271
29353
  return;
29272
29354
  const opts = this.options;
29273
29355
  if (isWindows)
29274
- path23 = sp2.normalize(path23);
29356
+ path25 = sp2.normalize(path25);
29275
29357
  if (opts.cwd)
29276
- path23 = sp2.relative(opts.cwd, path23);
29277
- const args = [path23];
29358
+ path25 = sp2.relative(opts.cwd, path25);
29359
+ const args = [path25];
29278
29360
  if (stats != null)
29279
29361
  args.push(stats);
29280
29362
  const awf = opts.awaitWriteFinish;
29281
29363
  let pw;
29282
- if (awf && (pw = this._pendingWrites.get(path23))) {
29364
+ if (awf && (pw = this._pendingWrites.get(path25))) {
29283
29365
  pw.lastChange = /* @__PURE__ */ new Date();
29284
29366
  return this;
29285
29367
  }
29286
29368
  if (opts.atomic) {
29287
29369
  if (event === EVENTS.UNLINK) {
29288
- this._pendingUnlinks.set(path23, [event, ...args]);
29370
+ this._pendingUnlinks.set(path25, [event, ...args]);
29289
29371
  setTimeout(() => {
29290
- this._pendingUnlinks.forEach((entry, path24) => {
29372
+ this._pendingUnlinks.forEach((entry, path26) => {
29291
29373
  this.emit(...entry);
29292
29374
  this.emit(EVENTS.ALL, ...entry);
29293
- this._pendingUnlinks.delete(path24);
29375
+ this._pendingUnlinks.delete(path26);
29294
29376
  });
29295
29377
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
29296
29378
  return this;
29297
29379
  }
29298
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path23)) {
29380
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path25)) {
29299
29381
  event = EVENTS.CHANGE;
29300
- this._pendingUnlinks.delete(path23);
29382
+ this._pendingUnlinks.delete(path25);
29301
29383
  }
29302
29384
  }
29303
29385
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -29315,16 +29397,16 @@ var init_chokidar = __esm({
29315
29397
  this.emitWithAll(event, args);
29316
29398
  }
29317
29399
  };
29318
- this._awaitWriteFinish(path23, awf.stabilityThreshold, event, awfEmit);
29400
+ this._awaitWriteFinish(path25, awf.stabilityThreshold, event, awfEmit);
29319
29401
  return this;
29320
29402
  }
29321
29403
  if (event === EVENTS.CHANGE) {
29322
- const isThrottled = !this._throttle(EVENTS.CHANGE, path23, 50);
29404
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path25, 50);
29323
29405
  if (isThrottled)
29324
29406
  return this;
29325
29407
  }
29326
29408
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
29327
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path23) : path23;
29409
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path25) : path25;
29328
29410
  let stats2;
29329
29411
  try {
29330
29412
  stats2 = await (0, import_promises3.stat)(fullPath);
@@ -29355,23 +29437,23 @@ var init_chokidar = __esm({
29355
29437
  * @param timeout duration of time to suppress duplicate actions
29356
29438
  * @returns tracking object or false if action should be suppressed
29357
29439
  */
29358
- _throttle(actionType, path23, timeout) {
29440
+ _throttle(actionType, path25, timeout) {
29359
29441
  if (!this._throttled.has(actionType)) {
29360
29442
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
29361
29443
  }
29362
29444
  const action = this._throttled.get(actionType);
29363
29445
  if (!action)
29364
29446
  throw new Error("invalid throttle");
29365
- const actionPath = action.get(path23);
29447
+ const actionPath = action.get(path25);
29366
29448
  if (actionPath) {
29367
29449
  actionPath.count++;
29368
29450
  return false;
29369
29451
  }
29370
29452
  let timeoutObject;
29371
29453
  const clear = () => {
29372
- const item = action.get(path23);
29454
+ const item = action.get(path25);
29373
29455
  const count = item ? item.count : 0;
29374
- action.delete(path23);
29456
+ action.delete(path25);
29375
29457
  clearTimeout(timeoutObject);
29376
29458
  if (item)
29377
29459
  clearTimeout(item.timeoutObject);
@@ -29379,7 +29461,7 @@ var init_chokidar = __esm({
29379
29461
  };
29380
29462
  timeoutObject = setTimeout(clear, timeout);
29381
29463
  const thr = { timeoutObject, clear, count: 0 };
29382
- action.set(path23, thr);
29464
+ action.set(path25, thr);
29383
29465
  return thr;
29384
29466
  }
29385
29467
  _incrReadyCount() {
@@ -29393,44 +29475,44 @@ var init_chokidar = __esm({
29393
29475
  * @param event
29394
29476
  * @param awfEmit Callback to be called when ready for event to be emitted.
29395
29477
  */
29396
- _awaitWriteFinish(path23, threshold, event, awfEmit) {
29478
+ _awaitWriteFinish(path25, threshold, event, awfEmit) {
29397
29479
  const awf = this.options.awaitWriteFinish;
29398
29480
  if (typeof awf !== "object")
29399
29481
  return;
29400
29482
  const pollInterval = awf.pollInterval;
29401
29483
  let timeoutHandler;
29402
- let fullPath = path23;
29403
- if (this.options.cwd && !sp2.isAbsolute(path23)) {
29404
- fullPath = sp2.join(this.options.cwd, path23);
29484
+ let fullPath = path25;
29485
+ if (this.options.cwd && !sp2.isAbsolute(path25)) {
29486
+ fullPath = sp2.join(this.options.cwd, path25);
29405
29487
  }
29406
29488
  const now = /* @__PURE__ */ new Date();
29407
29489
  const writes = this._pendingWrites;
29408
29490
  function awaitWriteFinishFn(prevStat) {
29409
29491
  (0, import_node_fs2.stat)(fullPath, (err, curStat) => {
29410
- if (err || !writes.has(path23)) {
29492
+ if (err || !writes.has(path25)) {
29411
29493
  if (err && err.code !== "ENOENT")
29412
29494
  awfEmit(err);
29413
29495
  return;
29414
29496
  }
29415
29497
  const now2 = Number(/* @__PURE__ */ new Date());
29416
29498
  if (prevStat && curStat.size !== prevStat.size) {
29417
- writes.get(path23).lastChange = now2;
29499
+ writes.get(path25).lastChange = now2;
29418
29500
  }
29419
- const pw = writes.get(path23);
29501
+ const pw = writes.get(path25);
29420
29502
  const df = now2 - pw.lastChange;
29421
29503
  if (df >= threshold) {
29422
- writes.delete(path23);
29504
+ writes.delete(path25);
29423
29505
  awfEmit(void 0, curStat);
29424
29506
  } else {
29425
29507
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
29426
29508
  }
29427
29509
  });
29428
29510
  }
29429
- if (!writes.has(path23)) {
29430
- writes.set(path23, {
29511
+ if (!writes.has(path25)) {
29512
+ writes.set(path25, {
29431
29513
  lastChange: now,
29432
29514
  cancelWait: () => {
29433
- writes.delete(path23);
29515
+ writes.delete(path25);
29434
29516
  clearTimeout(timeoutHandler);
29435
29517
  return event;
29436
29518
  }
@@ -29441,8 +29523,8 @@ var init_chokidar = __esm({
29441
29523
  /**
29442
29524
  * Determines whether user has asked to ignore this path.
29443
29525
  */
29444
- _isIgnored(path23, stats) {
29445
- if (this.options.atomic && DOT_RE.test(path23))
29526
+ _isIgnored(path25, stats) {
29527
+ if (this.options.atomic && DOT_RE.test(path25))
29446
29528
  return true;
29447
29529
  if (!this._userIgnored) {
29448
29530
  const { cwd } = this.options;
@@ -29452,17 +29534,17 @@ var init_chokidar = __esm({
29452
29534
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
29453
29535
  this._userIgnored = anymatch(list, void 0);
29454
29536
  }
29455
- return this._userIgnored(path23, stats);
29537
+ return this._userIgnored(path25, stats);
29456
29538
  }
29457
- _isntIgnored(path23, stat4) {
29458
- return !this._isIgnored(path23, stat4);
29539
+ _isntIgnored(path25, stat4) {
29540
+ return !this._isIgnored(path25, stat4);
29459
29541
  }
29460
29542
  /**
29461
29543
  * Provides a set of common helpers and properties relating to symlink handling.
29462
29544
  * @param path file or directory pattern being watched
29463
29545
  */
29464
- _getWatchHelpers(path23) {
29465
- return new WatchHelper(path23, this.options.followSymlinks, this);
29546
+ _getWatchHelpers(path25) {
29547
+ return new WatchHelper(path25, this.options.followSymlinks, this);
29466
29548
  }
29467
29549
  // Directory helpers
29468
29550
  // -----------------
@@ -29494,63 +29576,63 @@ var init_chokidar = __esm({
29494
29576
  * @param item base path of item/directory
29495
29577
  */
29496
29578
  _remove(directory, item, isDirectory) {
29497
- const path23 = sp2.join(directory, item);
29498
- const fullPath = sp2.resolve(path23);
29499
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path23) || this._watched.has(fullPath);
29500
- if (!this._throttle("remove", path23, 100))
29579
+ const path25 = sp2.join(directory, item);
29580
+ const fullPath = sp2.resolve(path25);
29581
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path25) || this._watched.has(fullPath);
29582
+ if (!this._throttle("remove", path25, 100))
29501
29583
  return;
29502
29584
  if (!isDirectory && this._watched.size === 1) {
29503
29585
  this.add(directory, item, true);
29504
29586
  }
29505
- const wp = this._getWatchedDir(path23);
29587
+ const wp = this._getWatchedDir(path25);
29506
29588
  const nestedDirectoryChildren = wp.getChildren();
29507
- nestedDirectoryChildren.forEach((nested) => this._remove(path23, nested));
29589
+ nestedDirectoryChildren.forEach((nested) => this._remove(path25, nested));
29508
29590
  const parent = this._getWatchedDir(directory);
29509
29591
  const wasTracked = parent.has(item);
29510
29592
  parent.remove(item);
29511
29593
  if (this._symlinkPaths.has(fullPath)) {
29512
29594
  this._symlinkPaths.delete(fullPath);
29513
29595
  }
29514
- let relPath = path23;
29596
+ let relPath = path25;
29515
29597
  if (this.options.cwd)
29516
- relPath = sp2.relative(this.options.cwd, path23);
29598
+ relPath = sp2.relative(this.options.cwd, path25);
29517
29599
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
29518
29600
  const event = this._pendingWrites.get(relPath).cancelWait();
29519
29601
  if (event === EVENTS.ADD)
29520
29602
  return;
29521
29603
  }
29522
- this._watched.delete(path23);
29604
+ this._watched.delete(path25);
29523
29605
  this._watched.delete(fullPath);
29524
29606
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
29525
- if (wasTracked && !this._isIgnored(path23))
29526
- this._emit(eventName, path23);
29527
- this._closePath(path23);
29607
+ if (wasTracked && !this._isIgnored(path25))
29608
+ this._emit(eventName, path25);
29609
+ this._closePath(path25);
29528
29610
  }
29529
29611
  /**
29530
29612
  * Closes all watchers for a path
29531
29613
  */
29532
- _closePath(path23) {
29533
- this._closeFile(path23);
29534
- const dir = sp2.dirname(path23);
29535
- this._getWatchedDir(dir).remove(sp2.basename(path23));
29614
+ _closePath(path25) {
29615
+ this._closeFile(path25);
29616
+ const dir = sp2.dirname(path25);
29617
+ this._getWatchedDir(dir).remove(sp2.basename(path25));
29536
29618
  }
29537
29619
  /**
29538
29620
  * Closes only file-specific watchers
29539
29621
  */
29540
- _closeFile(path23) {
29541
- const closers = this._closers.get(path23);
29622
+ _closeFile(path25) {
29623
+ const closers = this._closers.get(path25);
29542
29624
  if (!closers)
29543
29625
  return;
29544
29626
  closers.forEach((closer) => closer());
29545
- this._closers.delete(path23);
29627
+ this._closers.delete(path25);
29546
29628
  }
29547
- _addPathCloser(path23, closer) {
29629
+ _addPathCloser(path25, closer) {
29548
29630
  if (!closer)
29549
29631
  return;
29550
- let list = this._closers.get(path23);
29632
+ let list = this._closers.get(path25);
29551
29633
  if (!list) {
29552
29634
  list = [];
29553
- this._closers.set(path23, list);
29635
+ this._closers.set(path25, list);
29554
29636
  }
29555
29637
  list.push(closer);
29556
29638
  }
@@ -29576,18 +29658,19 @@ var init_chokidar = __esm({
29576
29658
  });
29577
29659
 
29578
29660
  // ../../oss/packages/daemon-core/src/providers/provider-loader.ts
29579
- var fs6, path10, os12, ProviderLoader;
29661
+ var fs6, path12, os12, ProviderLoader;
29580
29662
  var init_provider_loader = __esm({
29581
29663
  "../../oss/packages/daemon-core/src/providers/provider-loader.ts"() {
29582
29664
  "use strict";
29583
29665
  fs6 = __toESM(require("fs"));
29584
- path10 = __toESM(require("path"));
29666
+ path12 = __toESM(require("path"));
29585
29667
  os12 = __toESM(require("os"));
29586
29668
  init_chokidar();
29587
29669
  init_ide_detector();
29588
29670
  init_logger();
29589
29671
  ProviderLoader = class _ProviderLoader {
29590
29672
  providers = /* @__PURE__ */ new Map();
29673
+ providerAvailability = /* @__PURE__ */ new Map();
29591
29674
  userDir;
29592
29675
  upstreamDir;
29593
29676
  disableUpstream;
@@ -29603,12 +29686,12 @@ var init_provider_loader = __esm({
29603
29686
  static META_FILE = ".meta.json";
29604
29687
  constructor(options) {
29605
29688
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
29606
- const defaultProvidersDir = path10.join(os12.homedir(), ".adhdev", "providers");
29689
+ const defaultProvidersDir = path12.join(os12.homedir(), ".adhdev", "providers");
29607
29690
  if (options?.userDir) {
29608
29691
  this.userDir = options.userDir;
29609
29692
  this.log(`Config 'providerDir' applied: ${this.userDir}`);
29610
29693
  } else {
29611
- const localRepoPath = path10.resolve(__dirname, "../../../../../adhdev-providers");
29694
+ const localRepoPath = path12.resolve(__dirname, "../../../../../adhdev-providers");
29612
29695
  if (fs6.existsSync(localRepoPath)) {
29613
29696
  this.userDir = localRepoPath;
29614
29697
  this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
@@ -29617,7 +29700,7 @@ var init_provider_loader = __esm({
29617
29700
  this.log(`Using default user providers directory: ${this.userDir}`);
29618
29701
  }
29619
29702
  }
29620
- this.upstreamDir = path10.join(defaultProvidersDir, ".upstream");
29703
+ this.upstreamDir = path12.join(defaultProvidersDir, ".upstream");
29621
29704
  this.disableUpstream = options?.disableUpstream ?? false;
29622
29705
  }
29623
29706
  log(msg) {
@@ -29647,7 +29730,7 @@ var init_provider_loader = __esm({
29647
29730
  * Canonical provider directory shape for a given root.
29648
29731
  */
29649
29732
  getProviderDir(root, category, type) {
29650
- return path10.join(root, category, type);
29733
+ return path12.join(root, category, type);
29651
29734
  }
29652
29735
  /**
29653
29736
  * Canonical user override directory for a provider.
@@ -29674,7 +29757,7 @@ var init_provider_loader = __esm({
29674
29757
  resolveProviderFile(type, ...segments) {
29675
29758
  const dir = this.findProviderDirInternal(type);
29676
29759
  if (!dir) return null;
29677
- return path10.join(dir, ...segments);
29760
+ return path12.join(dir, ...segments);
29678
29761
  }
29679
29762
  /**
29680
29763
  * Load all providers (3-tier priority)
@@ -29685,6 +29768,7 @@ var init_provider_loader = __esm({
29685
29768
  */
29686
29769
  loadAll() {
29687
29770
  this.providers.clear();
29771
+ this.providerAvailability.clear();
29688
29772
  let upstreamCount = 0;
29689
29773
  if (!this.disableUpstream && fs6.existsSync(this.upstreamDir)) {
29690
29774
  upstreamCount = this.loadDir(this.upstreamDir);
@@ -29712,7 +29796,7 @@ var init_provider_loader = __esm({
29712
29796
  if (!fs6.existsSync(this.upstreamDir)) return false;
29713
29797
  try {
29714
29798
  return fs6.readdirSync(this.upstreamDir).some(
29715
- (d) => fs6.statSync(path10.join(this.upstreamDir, d)).isDirectory()
29799
+ (d) => fs6.statSync(path12.join(this.upstreamDir, d)).isDirectory()
29716
29800
  );
29717
29801
  } catch {
29718
29802
  return false;
@@ -29755,11 +29839,12 @@ var init_provider_loader = __esm({
29755
29839
  if ((p.category === "cli" || p.category === "acp") && p.spawn?.command) {
29756
29840
  const verCmdConfig = p.versionCommand;
29757
29841
  const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[process.platform] : verCmdConfig;
29842
+ const command = this.getSpawnCommand(p.type, p.spawn.command);
29758
29843
  result.push({
29759
29844
  id: p.type,
29760
29845
  displayName: p.displayName || p.name,
29761
29846
  icon: p.icon || "\u{1F527}",
29762
- command: p.spawn.command,
29847
+ command,
29763
29848
  category: p.category,
29764
29849
  ...typeof versionCommand === "string" && versionCommand.trim() ? { versionCommand: versionCommand.trim() } : {}
29765
29850
  });
@@ -29888,6 +29973,71 @@ var init_provider_loader = __esm({
29888
29973
  getAvailableIdeTypes() {
29889
29974
  return [...this.providers.values()].filter((p) => p.category === "ide" && p.cdpPorts).map((p) => p.type);
29890
29975
  }
29976
+ getSpawnCommand(type, fallback) {
29977
+ const override = this.getOptionalStringSetting(type, "executablePath");
29978
+ if (override) return override;
29979
+ return fallback || this.providers.get(type)?.spawn?.command || type;
29980
+ }
29981
+ getIdeCliCommand(type, fallback) {
29982
+ const override = this.getOptionalStringSetting(type, "cliPathOverride");
29983
+ if (override) return override;
29984
+ return fallback || this.providers.get(type)?.cli || null;
29985
+ }
29986
+ getIdePathCandidates(type, fallback) {
29987
+ const override = this.getOptionalStringSetting(type, "appPathOverride");
29988
+ if (override) return [override];
29989
+ if (fallback && fallback.length > 0) return fallback;
29990
+ const osPaths = this.providers.get(type)?.paths?.[process.platform];
29991
+ return Array.isArray(osPaths) ? [...osPaths] : [];
29992
+ }
29993
+ setProviderAvailability(type, state) {
29994
+ this.providerAvailability.set(type, {
29995
+ installed: !!state.installed,
29996
+ detectedPath: state.detectedPath ?? null
29997
+ });
29998
+ }
29999
+ setCliDetectionResults(results, replace = true) {
30000
+ if (replace) {
30001
+ for (const provider of this.providers.values()) {
30002
+ if (provider.category === "cli" || provider.category === "acp") {
30003
+ this.providerAvailability.set(provider.type, { installed: false, detectedPath: null });
30004
+ }
30005
+ }
30006
+ }
30007
+ for (const result of results) {
30008
+ this.setProviderAvailability(result.id, {
30009
+ installed: !!result.installed,
30010
+ detectedPath: result.path || null
30011
+ });
30012
+ }
30013
+ }
30014
+ setIdeDetectionResults(results, replace = true) {
30015
+ if (replace) {
30016
+ for (const provider of this.providers.values()) {
30017
+ if (provider.category === "ide") {
30018
+ this.providerAvailability.set(provider.type, { installed: false, detectedPath: null });
30019
+ }
30020
+ }
30021
+ }
30022
+ for (const result of results) {
30023
+ this.setProviderAvailability(result.id, {
30024
+ installed: !!result.installed,
30025
+ detectedPath: result.cliCommand || result.path || null
30026
+ });
30027
+ }
30028
+ }
30029
+ getAvailableProviderInfos() {
30030
+ return this.getAll().map((provider) => {
30031
+ const availability = this.providerAvailability.get(provider.type);
30032
+ return {
30033
+ ...provider,
30034
+ ...availability ? {
30035
+ installed: availability.installed,
30036
+ detectedPath: availability.detectedPath
30037
+ } : {}
30038
+ };
30039
+ });
30040
+ }
29891
30041
  /**
29892
30042
  * Register IDE providers to core/detector registry
29893
30043
  * → Enables detectIDEs() to detect provider.js-based IDEs
@@ -29962,8 +30112,8 @@ var init_provider_loader = __esm({
29962
30112
  resolved._resolvedScriptDir = entry.scriptDir;
29963
30113
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
29964
30114
  if (providerDir) {
29965
- const fullDir = path10.join(providerDir, entry.scriptDir);
29966
- resolved._resolvedScriptsPath = fs6.existsSync(path10.join(fullDir, "scripts.js")) ? path10.join(fullDir, "scripts.js") : fullDir;
30115
+ const fullDir = path12.join(providerDir, entry.scriptDir);
30116
+ resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
29967
30117
  }
29968
30118
  matched = true;
29969
30119
  }
@@ -29978,8 +30128,8 @@ var init_provider_loader = __esm({
29978
30128
  resolved._resolvedScriptDir = base.defaultScriptDir;
29979
30129
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
29980
30130
  if (providerDir) {
29981
- const fullDir = path10.join(providerDir, base.defaultScriptDir);
29982
- resolved._resolvedScriptsPath = fs6.existsSync(path10.join(fullDir, "scripts.js")) ? path10.join(fullDir, "scripts.js") : fullDir;
30131
+ const fullDir = path12.join(providerDir, base.defaultScriptDir);
30132
+ resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
29983
30133
  }
29984
30134
  }
29985
30135
  resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
@@ -29996,8 +30146,8 @@ var init_provider_loader = __esm({
29996
30146
  resolved._resolvedScriptDir = dirOverride;
29997
30147
  resolved._resolvedScriptsSource = `versions:${range}`;
29998
30148
  if (providerDir) {
29999
- const fullDir = path10.join(providerDir, dirOverride);
30000
- resolved._resolvedScriptsPath = fs6.existsSync(path10.join(fullDir, "scripts.js")) ? path10.join(fullDir, "scripts.js") : fullDir;
30149
+ const fullDir = path12.join(providerDir, dirOverride);
30150
+ resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
30001
30151
  }
30002
30152
  }
30003
30153
  } else if (override.scripts) {
@@ -30013,8 +30163,8 @@ var init_provider_loader = __esm({
30013
30163
  resolved._resolvedScriptDir = base.defaultScriptDir;
30014
30164
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
30015
30165
  if (providerDir) {
30016
- const fullDir = path10.join(providerDir, base.defaultScriptDir);
30017
- resolved._resolvedScriptsPath = fs6.existsSync(path10.join(fullDir, "scripts.js")) ? path10.join(fullDir, "scripts.js") : fullDir;
30166
+ const fullDir = path12.join(providerDir, base.defaultScriptDir);
30167
+ resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
30018
30168
  }
30019
30169
  }
30020
30170
  }
@@ -30039,14 +30189,14 @@ var init_provider_loader = __esm({
30039
30189
  this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
30040
30190
  return null;
30041
30191
  }
30042
- const dir = path10.join(providerDir, scriptDir);
30192
+ const dir = path12.join(providerDir, scriptDir);
30043
30193
  if (!fs6.existsSync(dir)) {
30044
30194
  this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
30045
30195
  return null;
30046
30196
  }
30047
30197
  const cached2 = this.scriptsCache.get(dir);
30048
30198
  if (cached2) return cached2;
30049
- const scriptsJs = path10.join(dir, "scripts.js");
30199
+ const scriptsJs = path12.join(dir, "scripts.js");
30050
30200
  if (fs6.existsSync(scriptsJs)) {
30051
30201
  try {
30052
30202
  delete require.cache[require.resolve(scriptsJs)];
@@ -30088,7 +30238,7 @@ var init_provider_loader = __esm({
30088
30238
  return;
30089
30239
  }
30090
30240
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
30091
- this.log(`File changed: ${path10.basename(filePath)}, reloading...`);
30241
+ this.log(`File changed: ${path12.basename(filePath)}, reloading...`);
30092
30242
  this.reload();
30093
30243
  }
30094
30244
  };
@@ -30143,7 +30293,7 @@ var init_provider_loader = __esm({
30143
30293
  }
30144
30294
  const https = require("https");
30145
30295
  const { execSync: execSync7 } = require("child_process");
30146
- const metaPath = path10.join(this.upstreamDir, _ProviderLoader.META_FILE);
30296
+ const metaPath = path12.join(this.upstreamDir, _ProviderLoader.META_FILE);
30147
30297
  let prevEtag = "";
30148
30298
  let prevTimestamp = 0;
30149
30299
  try {
@@ -30160,7 +30310,7 @@ var init_provider_loader = __esm({
30160
30310
  return { updated: false };
30161
30311
  }
30162
30312
  try {
30163
- const etag = await new Promise((resolve13, reject) => {
30313
+ const etag = await new Promise((resolve16, reject) => {
30164
30314
  const options = {
30165
30315
  method: "HEAD",
30166
30316
  hostname: "github.com",
@@ -30178,7 +30328,7 @@ var init_provider_loader = __esm({
30178
30328
  headers: { "User-Agent": "adhdev-launcher" },
30179
30329
  timeout: 1e4
30180
30330
  }, (res2) => {
30181
- resolve13(res2.headers.etag || res2.headers["last-modified"] || "");
30331
+ resolve16(res2.headers.etag || res2.headers["last-modified"] || "");
30182
30332
  });
30183
30333
  req2.on("error", reject);
30184
30334
  req2.on("timeout", () => {
@@ -30187,7 +30337,7 @@ var init_provider_loader = __esm({
30187
30337
  });
30188
30338
  req2.end();
30189
30339
  } else {
30190
- resolve13(res.headers.etag || res.headers["last-modified"] || "");
30340
+ resolve16(res.headers.etag || res.headers["last-modified"] || "");
30191
30341
  }
30192
30342
  });
30193
30343
  req.on("error", reject);
@@ -30203,17 +30353,17 @@ var init_provider_loader = __esm({
30203
30353
  return { updated: false };
30204
30354
  }
30205
30355
  this.log("Downloading latest providers from GitHub...");
30206
- const tmpTar = path10.join(os12.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
30207
- const tmpExtract = path10.join(os12.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
30356
+ const tmpTar = path12.join(os12.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
30357
+ const tmpExtract = path12.join(os12.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
30208
30358
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
30209
30359
  fs6.mkdirSync(tmpExtract, { recursive: true });
30210
30360
  execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
30211
30361
  const extracted = fs6.readdirSync(tmpExtract);
30212
30362
  const rootDir = extracted.find(
30213
- (d) => fs6.statSync(path10.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
30363
+ (d) => fs6.statSync(path12.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
30214
30364
  );
30215
30365
  if (!rootDir) throw new Error("Unexpected tarball structure");
30216
- const sourceDir = path10.join(tmpExtract, rootDir);
30366
+ const sourceDir = path12.join(tmpExtract, rootDir);
30217
30367
  const backupDir = this.upstreamDir + ".bak";
30218
30368
  if (fs6.existsSync(this.upstreamDir)) {
30219
30369
  if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
@@ -30251,7 +30401,7 @@ var init_provider_loader = __esm({
30251
30401
  downloadFile(url2, destPath) {
30252
30402
  const https = require("https");
30253
30403
  const http3 = require("http");
30254
- return new Promise((resolve13, reject) => {
30404
+ return new Promise((resolve16, reject) => {
30255
30405
  const doRequest = (reqUrl, redirectCount = 0) => {
30256
30406
  if (redirectCount > 5) {
30257
30407
  reject(new Error("Too many redirects"));
@@ -30271,7 +30421,7 @@ var init_provider_loader = __esm({
30271
30421
  res.pipe(ws);
30272
30422
  ws.on("finish", () => {
30273
30423
  ws.close();
30274
- resolve13();
30424
+ resolve16();
30275
30425
  });
30276
30426
  ws.on("error", reject);
30277
30427
  });
@@ -30288,8 +30438,8 @@ var init_provider_loader = __esm({
30288
30438
  copyDirRecursive(src, dest) {
30289
30439
  fs6.mkdirSync(dest, { recursive: true });
30290
30440
  for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
30291
- const srcPath = path10.join(src, entry.name);
30292
- const destPath = path10.join(dest, entry.name);
30441
+ const srcPath = path12.join(src, entry.name);
30442
+ const destPath = path12.join(dest, entry.name);
30293
30443
  if (entry.isDirectory()) {
30294
30444
  this.copyDirRecursive(srcPath, destPath);
30295
30445
  } else {
@@ -30300,7 +30450,7 @@ var init_provider_loader = __esm({
30300
30450
  /** .meta.json save */
30301
30451
  writeMeta(metaPath, etag, timestamp) {
30302
30452
  try {
30303
- fs6.mkdirSync(path10.dirname(metaPath), { recursive: true });
30453
+ fs6.mkdirSync(path12.dirname(metaPath), { recursive: true });
30304
30454
  fs6.writeFileSync(metaPath, JSON.stringify({
30305
30455
  etag,
30306
30456
  timestamp,
@@ -30317,7 +30467,7 @@ var init_provider_loader = __esm({
30317
30467
  const scan = (d) => {
30318
30468
  try {
30319
30469
  for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
30320
- if (entry.isDirectory()) scan(path10.join(d, entry.name));
30470
+ if (entry.isDirectory()) scan(path12.join(d, entry.name));
30321
30471
  else if (entry.name === "provider.json") count++;
30322
30472
  }
30323
30473
  } catch {
@@ -30331,9 +30481,8 @@ var init_provider_loader = __esm({
30331
30481
  * Get public settings schema for a provider (for dashboard UI rendering)
30332
30482
  */
30333
30483
  getPublicSettings(type) {
30334
- const provider = this.providers.get(type);
30335
- if (!provider?.settings) return [];
30336
- return Object.entries(provider.settings).filter(([, def]) => def.public === true).map(([key, def]) => ({ key, ...def }));
30484
+ const settings = this.getSettingsSchema(type);
30485
+ return Object.entries(settings).filter(([, def]) => def.public === true).map(([key, def]) => ({ key, ...def }));
30337
30486
  }
30338
30487
  /**
30339
30488
  * Get public settings schema for all providers
@@ -30350,8 +30499,7 @@ var init_provider_loader = __esm({
30350
30499
  * Resolved setting value for a provider (default + user override)
30351
30500
  */
30352
30501
  getSettingValue(type, key) {
30353
- const provider = this.providers.get(type);
30354
- const schemaDef = provider?.settings?.[key];
30502
+ const schemaDef = this.getSettingsSchema(type)[key];
30355
30503
  const defaultVal = schemaDef ? schemaDef.default : void 0;
30356
30504
  try {
30357
30505
  const { loadConfig: loadConfig2 } = (init_config(), __toCommonJS(config_exports));
@@ -30366,10 +30514,9 @@ var init_provider_loader = __esm({
30366
30514
  * All resolved settings for a provider (default + user override)
30367
30515
  */
30368
30516
  getSettings(type) {
30369
- const provider = this.providers.get(type);
30370
- if (!provider?.settings) return {};
30517
+ const settings = this.getSettingsSchema(type);
30371
30518
  const result = {};
30372
- for (const [key, def] of Object.entries(provider.settings)) {
30519
+ for (const [key] of Object.entries(settings)) {
30373
30520
  result[key] = this.getSettingValue(type, key);
30374
30521
  }
30375
30522
  return result;
@@ -30378,11 +30525,11 @@ var init_provider_loader = __esm({
30378
30525
  * Save provider setting value (writes to config.json)
30379
30526
  */
30380
30527
  setSetting(type, key, value) {
30381
- const provider = this.providers.get(type);
30382
- const schemaDef = provider?.settings?.[key];
30528
+ const schemaDef = this.getSettingsSchema(type)[key];
30383
30529
  if (!schemaDef) return false;
30384
30530
  if (!schemaDef.public) return false;
30385
30531
  if (schemaDef.type === "boolean" && typeof value !== "boolean") return false;
30532
+ if (schemaDef.type === "string" && typeof value !== "string") return false;
30386
30533
  if (schemaDef.type === "number") {
30387
30534
  if (typeof value !== "number") return false;
30388
30535
  if (schemaDef.min !== void 0 && value < schemaDef.min) return false;
@@ -30403,6 +30550,53 @@ var init_provider_loader = __esm({
30403
30550
  return false;
30404
30551
  }
30405
30552
  }
30553
+ getOptionalStringSetting(type, key) {
30554
+ const value = this.getSettingValue(type, key);
30555
+ if (typeof value !== "string") return null;
30556
+ const trimmed = value.trim();
30557
+ return trimmed ? trimmed : null;
30558
+ }
30559
+ getSettingsSchema(type) {
30560
+ const provider = this.providers.get(type);
30561
+ if (!provider) return {};
30562
+ return {
30563
+ ...this.getSyntheticSettings(type, provider),
30564
+ ...provider.settings || {}
30565
+ };
30566
+ }
30567
+ getSyntheticSettings(type, provider) {
30568
+ const result = {};
30569
+ if ((provider.category === "cli" || provider.category === "acp") && provider.spawn?.command && !provider.settings?.executablePath) {
30570
+ result.executablePath = {
30571
+ type: "string",
30572
+ default: "",
30573
+ public: true,
30574
+ label: "Executable path",
30575
+ description: "Optional absolute path for this provider binary. Leave blank to use the default PATH lookup."
30576
+ };
30577
+ }
30578
+ if (provider.category === "ide") {
30579
+ if (provider.cli && !provider.settings?.cliPathOverride) {
30580
+ result.cliPathOverride = {
30581
+ type: "string",
30582
+ default: "",
30583
+ public: true,
30584
+ label: "CLI path override",
30585
+ description: "Optional absolute path for the IDE CLI launcher. Leave blank to use the detected default."
30586
+ };
30587
+ }
30588
+ if (provider.paths && !provider.settings?.appPathOverride) {
30589
+ result.appPathOverride = {
30590
+ type: "string",
30591
+ default: "",
30592
+ public: true,
30593
+ label: "App path override",
30594
+ description: "Optional absolute path for the IDE app bundle or executable. Leave blank to use the default install locations."
30595
+ };
30596
+ }
30597
+ }
30598
+ return result;
30599
+ }
30406
30600
  // ─── Private ───────────────────────────────────
30407
30601
  /**
30408
30602
  * Find the on-disk directory for a provider by type.
@@ -30416,17 +30610,17 @@ var init_provider_loader = __esm({
30416
30610
  for (const root of searchRoots) {
30417
30611
  if (!fs6.existsSync(root)) continue;
30418
30612
  const candidate = this.getProviderDir(root, cat, type);
30419
- if (fs6.existsSync(path10.join(candidate, "provider.json"))) return candidate;
30420
- const catDir = path10.join(root, cat);
30613
+ if (fs6.existsSync(path12.join(candidate, "provider.json"))) return candidate;
30614
+ const catDir = path12.join(root, cat);
30421
30615
  if (fs6.existsSync(catDir)) {
30422
30616
  try {
30423
30617
  for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
30424
30618
  if (!entry.isDirectory()) continue;
30425
- const jsonPath = path10.join(catDir, entry.name, "provider.json");
30619
+ const jsonPath = path12.join(catDir, entry.name, "provider.json");
30426
30620
  if (fs6.existsSync(jsonPath)) {
30427
30621
  try {
30428
30622
  const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
30429
- if (data.type === type) return path10.join(catDir, entry.name);
30623
+ if (data.type === type) return path12.join(catDir, entry.name);
30430
30624
  } catch {
30431
30625
  }
30432
30626
  }
@@ -30443,7 +30637,7 @@ var init_provider_loader = __esm({
30443
30637
  * (template substitution is NOT applied here — scripts.js handles that)
30444
30638
  */
30445
30639
  buildScriptWrappersFromDir(dir) {
30446
- const scriptsJs = path10.join(dir, "scripts.js");
30640
+ const scriptsJs = path12.join(dir, "scripts.js");
30447
30641
  if (fs6.existsSync(scriptsJs)) {
30448
30642
  try {
30449
30643
  delete require.cache[require.resolve(scriptsJs)];
@@ -30457,7 +30651,7 @@ var init_provider_loader = __esm({
30457
30651
  for (const file2 of fs6.readdirSync(dir)) {
30458
30652
  if (!file2.endsWith(".js")) continue;
30459
30653
  const scriptName = toCamel(file2.replace(".js", ""));
30460
- const filePath = path10.join(dir, file2);
30654
+ const filePath = path12.join(dir, file2);
30461
30655
  result[scriptName] = (...args) => {
30462
30656
  try {
30463
30657
  let content = fs6.readFileSync(filePath, "utf-8");
@@ -30517,7 +30711,7 @@ var init_provider_loader = __esm({
30517
30711
  }
30518
30712
  const hasJson = entries.some((e) => e.name === "provider.json");
30519
30713
  if (hasJson) {
30520
- const jsonPath = path10.join(d, "provider.json");
30714
+ const jsonPath = path12.join(d, "provider.json");
30521
30715
  try {
30522
30716
  const raw = fs6.readFileSync(jsonPath, "utf-8");
30523
30717
  const mod = JSON.parse(raw);
@@ -30530,7 +30724,7 @@ var init_provider_loader = __esm({
30530
30724
  delete mod.extensionIdPattern_flags;
30531
30725
  }
30532
30726
  const hasCompatibility = Array.isArray(mod.compatibility);
30533
- const scriptsPath = path10.join(d, "scripts.js");
30727
+ const scriptsPath = path12.join(d, "scripts.js");
30534
30728
  if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
30535
30729
  try {
30536
30730
  delete require.cache[require.resolve(scriptsPath)];
@@ -30556,7 +30750,7 @@ var init_provider_loader = __esm({
30556
30750
  if (!entry.isDirectory()) continue;
30557
30751
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
30558
30752
  if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
30559
- scan(path10.join(d, entry.name));
30753
+ scan(path12.join(d, entry.name));
30560
30754
  }
30561
30755
  }
30562
30756
  };
@@ -30653,17 +30847,17 @@ async function findFreePort(ports) {
30653
30847
  throw new Error("No free port found");
30654
30848
  }
30655
30849
  function checkPortFree(port) {
30656
- return new Promise((resolve13) => {
30850
+ return new Promise((resolve16) => {
30657
30851
  const server = net2.createServer();
30658
30852
  server.unref();
30659
- server.on("error", () => resolve13(false));
30853
+ server.on("error", () => resolve16(false));
30660
30854
  server.listen(port, "127.0.0.1", () => {
30661
- server.close(() => resolve13(true));
30855
+ server.close(() => resolve16(true));
30662
30856
  });
30663
30857
  });
30664
30858
  }
30665
30859
  async function isCdpActive(port) {
30666
- return new Promise((resolve13) => {
30860
+ return new Promise((resolve16) => {
30667
30861
  const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
30668
30862
  timeout: 2e3
30669
30863
  }, (res) => {
@@ -30672,16 +30866,16 @@ async function isCdpActive(port) {
30672
30866
  res.on("end", () => {
30673
30867
  try {
30674
30868
  const info = JSON.parse(data);
30675
- resolve13(!!info["WebKit-Version"] || !!info["Browser"]);
30869
+ resolve16(!!info["WebKit-Version"] || !!info["Browser"]);
30676
30870
  } catch {
30677
- resolve13(false);
30871
+ resolve16(false);
30678
30872
  }
30679
30873
  });
30680
30874
  });
30681
- req.on("error", () => resolve13(false));
30875
+ req.on("error", () => resolve16(false));
30682
30876
  req.on("timeout", () => {
30683
30877
  req.destroy();
30684
- resolve13(false);
30878
+ resolve16(false);
30685
30879
  });
30686
30880
  });
30687
30881
  }
@@ -30815,8 +31009,8 @@ function detectCurrentWorkspace(ideId) {
30815
31009
  const appNameMap = getMacAppIdentifiers();
30816
31010
  const appName = appNameMap[ideId];
30817
31011
  if (appName) {
30818
- const storagePath = path11.join(
30819
- process.env.APPDATA || path11.join(os13.homedir(), "AppData", "Roaming"),
31012
+ const storagePath = path13.join(
31013
+ process.env.APPDATA || path13.join(os13.homedir(), "AppData", "Roaming"),
30820
31014
  appName,
30821
31015
  "storage.json"
30822
31016
  );
@@ -30840,7 +31034,7 @@ function detectCurrentWorkspace(ideId) {
30840
31034
  async function launchWithCdp(options = {}) {
30841
31035
  const platform11 = os13.platform();
30842
31036
  let targetIde;
30843
- const ides = await detectIDEs();
31037
+ const ides = await detectIDEs(getProviderLoader());
30844
31038
  if (options.ideId) {
30845
31039
  targetIde = ides.find((i) => i.id === options.ideId && i.installed);
30846
31040
  if (!targetIde) {
@@ -30987,14 +31181,14 @@ async function launchLinux(ide, port, workspace, newWindow) {
30987
31181
  function getAvailableIdeIds() {
30988
31182
  return getProviderLoader().getAvailableIdeTypes();
30989
31183
  }
30990
- var import_child_process6, net2, os13, path11, _providerLoader;
31184
+ var import_child_process6, net2, os13, path13, _providerLoader;
30991
31185
  var init_launch = __esm({
30992
31186
  "../../oss/packages/daemon-core/src/launch.ts"() {
30993
31187
  "use strict";
30994
31188
  import_child_process6 = require("child_process");
30995
31189
  net2 = __toESM(require("net"));
30996
31190
  os13 = __toESM(require("os"));
30997
- path11 = __toESM(require("path"));
31191
+ path13 = __toESM(require("path"));
30998
31192
  init_ide_detector();
30999
31193
  init_provider_loader();
31000
31194
  _providerLoader = null;
@@ -31025,7 +31219,7 @@ function checkRotation() {
31025
31219
  const today = getDateStr2();
31026
31220
  if (today !== currentDate2) {
31027
31221
  currentDate2 = today;
31028
- currentFile = path12.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
31222
+ currentFile = path14.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
31029
31223
  cleanOldFiles();
31030
31224
  }
31031
31225
  }
@@ -31039,7 +31233,7 @@ function cleanOldFiles() {
31039
31233
  const dateMatch = file2.match(/commands-(\d{4}-\d{2}-\d{2})/);
31040
31234
  if (dateMatch && dateMatch[1] < cutoffStr) {
31041
31235
  try {
31042
- fs7.unlinkSync(path12.join(LOG_DIR2, file2));
31236
+ fs7.unlinkSync(path14.join(LOG_DIR2, file2));
31043
31237
  } catch {
31044
31238
  }
31045
31239
  }
@@ -31106,14 +31300,14 @@ function getRecentCommands(count = 50) {
31106
31300
  return [];
31107
31301
  }
31108
31302
  }
31109
- var fs7, path12, os14, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS;
31303
+ var fs7, path14, os14, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS;
31110
31304
  var init_command_log = __esm({
31111
31305
  "../../oss/packages/daemon-core/src/logging/command-log.ts"() {
31112
31306
  "use strict";
31113
31307
  fs7 = __toESM(require("fs"));
31114
- path12 = __toESM(require("path"));
31308
+ path14 = __toESM(require("path"));
31115
31309
  os14 = __toESM(require("os"));
31116
- LOG_DIR2 = process.platform === "win32" ? path12.join(process.env.LOCALAPPDATA || process.env.APPDATA || path12.join(os14.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path12.join(os14.homedir(), "Library", "Logs", "adhdev") : path12.join(os14.homedir(), ".local", "share", "adhdev", "logs");
31310
+ LOG_DIR2 = process.platform === "win32" ? path14.join(process.env.LOCALAPPDATA || process.env.APPDATA || path14.join(os14.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path14.join(os14.homedir(), "Library", "Logs", "adhdev") : path14.join(os14.homedir(), ".local", "share", "adhdev", "logs");
31117
31311
  MAX_FILE_SIZE = 5 * 1024 * 1024;
31118
31312
  MAX_DAYS = 7;
31119
31313
  try {
@@ -31132,7 +31326,7 @@ var init_command_log = __esm({
31132
31326
  "text"
31133
31327
  ]);
31134
31328
  currentDate2 = getDateStr2();
31135
- currentFile = path12.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
31329
+ currentFile = path14.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
31136
31330
  writeCount2 = 0;
31137
31331
  SKIP_COMMANDS = /* @__PURE__ */ new Set([
31138
31332
  "heartbeat",
@@ -31153,12 +31347,15 @@ function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
31153
31347
  }));
31154
31348
  }
31155
31349
  function buildAvailableProviders(providerLoader) {
31156
- return providerLoader.getAll().map((provider) => ({
31350
+ const providers = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
31351
+ return providers.map((provider) => ({
31157
31352
  type: provider.type,
31158
31353
  name: provider.displayName || provider.type,
31159
31354
  displayName: provider.displayName || provider.type,
31160
31355
  icon: provider.icon || "\u{1F4BB}",
31161
- category: provider.category
31356
+ category: provider.category,
31357
+ ...provider.installed !== void 0 ? { installed: provider.installed } : {},
31358
+ ...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {}
31162
31359
  }));
31163
31360
  }
31164
31361
  function parseMessageTime(value) {
@@ -31300,9 +31497,9 @@ var init_snapshot = __esm({
31300
31497
  // ../../oss/packages/daemon-core/src/commands/upgrade-helper.ts
31301
31498
  function getUpgradeLogPath() {
31302
31499
  const home = os16.homedir();
31303
- const dir = path13.join(home, ".adhdev");
31500
+ const dir = path15.join(home, ".adhdev");
31304
31501
  fs8.mkdirSync(dir, { recursive: true });
31305
- return path13.join(dir, "daemon-upgrade.log");
31502
+ return path15.join(dir, "daemon-upgrade.log");
31306
31503
  }
31307
31504
  function appendUpgradeLog(message) {
31308
31505
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
@@ -31335,14 +31532,14 @@ async function waitForPidExit(pid, timeoutMs) {
31335
31532
  while (Date.now() - start < timeoutMs) {
31336
31533
  try {
31337
31534
  process.kill(pid, 0);
31338
- await new Promise((resolve13) => setTimeout(resolve13, 250));
31535
+ await new Promise((resolve16) => setTimeout(resolve16, 250));
31339
31536
  } catch {
31340
31537
  return;
31341
31538
  }
31342
31539
  }
31343
31540
  }
31344
31541
  function stopSessionHostProcesses(appName) {
31345
- const pidFile = path13.join(os16.homedir(), ".adhdev", `${appName}-session-host.pid`);
31542
+ const pidFile = path15.join(os16.homedir(), ".adhdev", `${appName}-session-host.pid`);
31346
31543
  try {
31347
31544
  if (fs8.existsSync(pidFile)) {
31348
31545
  const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
@@ -31371,7 +31568,7 @@ function stopSessionHostProcesses(appName) {
31371
31568
  }
31372
31569
  }
31373
31570
  function removeDaemonPidFile() {
31374
- const pidFile = path13.join(os16.homedir(), ".adhdev", "daemon.pid");
31571
+ const pidFile = path15.join(os16.homedir(), ".adhdev", "daemon.pid");
31375
31572
  try {
31376
31573
  fs8.unlinkSync(pidFile);
31377
31574
  } catch {
@@ -31382,7 +31579,7 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
31382
31579
  const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
31383
31580
  if (!npmRoot) return;
31384
31581
  const npmPrefix = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
31385
- const binDir = process.platform === "win32" ? npmPrefix : path13.join(npmPrefix, "bin");
31582
+ const binDir = process.platform === "win32" ? npmPrefix : path15.join(npmPrefix, "bin");
31386
31583
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
31387
31584
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
31388
31585
  if (pkgName === "@adhdev/daemon-standalone") {
@@ -31390,25 +31587,25 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
31390
31587
  }
31391
31588
  if (pkgName.startsWith("@")) {
31392
31589
  const [scope, name] = pkgName.split("/");
31393
- const scopeDir = path13.join(npmRoot, scope);
31590
+ const scopeDir = path15.join(npmRoot, scope);
31394
31591
  if (!fs8.existsSync(scopeDir)) return;
31395
31592
  for (const entry of fs8.readdirSync(scopeDir)) {
31396
31593
  if (!entry.startsWith(`.${name}-`)) continue;
31397
- fs8.rmSync(path13.join(scopeDir, entry), { recursive: true, force: true });
31398
- appendUpgradeLog(`Removed stale scoped staging dir: ${path13.join(scopeDir, entry)}`);
31594
+ fs8.rmSync(path15.join(scopeDir, entry), { recursive: true, force: true });
31595
+ appendUpgradeLog(`Removed stale scoped staging dir: ${path15.join(scopeDir, entry)}`);
31399
31596
  }
31400
31597
  } else {
31401
31598
  for (const entry of fs8.readdirSync(npmRoot)) {
31402
31599
  if (!entry.startsWith(`.${pkgName}-`)) continue;
31403
- fs8.rmSync(path13.join(npmRoot, entry), { recursive: true, force: true });
31404
- appendUpgradeLog(`Removed stale staging dir: ${path13.join(npmRoot, entry)}`);
31600
+ fs8.rmSync(path15.join(npmRoot, entry), { recursive: true, force: true });
31601
+ appendUpgradeLog(`Removed stale staging dir: ${path15.join(npmRoot, entry)}`);
31405
31602
  }
31406
31603
  }
31407
31604
  if (fs8.existsSync(binDir)) {
31408
31605
  for (const entry of fs8.readdirSync(binDir)) {
31409
31606
  if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
31410
- fs8.rmSync(path13.join(binDir, entry), { recursive: true, force: true });
31411
- appendUpgradeLog(`Removed stale bin staging entry: ${path13.join(binDir, entry)}`);
31607
+ fs8.rmSync(path15.join(binDir, entry), { recursive: true, force: true });
31608
+ appendUpgradeLog(`Removed stale bin staging entry: ${path15.join(binDir, entry)}`);
31412
31609
  }
31413
31610
  }
31414
31611
  }
@@ -31450,7 +31647,7 @@ async function runDaemonUpgradeHelper(payload) {
31450
31647
  appendUpgradeLog(installOutput.trim());
31451
31648
  }
31452
31649
  if (process.platform === "win32") {
31453
- await new Promise((resolve13) => setTimeout(resolve13, 500));
31650
+ await new Promise((resolve16) => setTimeout(resolve16, 500));
31454
31651
  cleanupStaleGlobalInstallDirs(payload.packageName);
31455
31652
  appendUpgradeLog("Post-install staging cleanup complete");
31456
31653
  }
@@ -31483,7 +31680,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
31483
31680
  process.exit(1);
31484
31681
  }
31485
31682
  }
31486
- var import_child_process7, import_child_process8, fs8, os16, path13, UPGRADE_HELPER_ENV;
31683
+ var import_child_process7, import_child_process8, fs8, os16, path15, UPGRADE_HELPER_ENV;
31487
31684
  var init_upgrade_helper = __esm({
31488
31685
  "../../oss/packages/daemon-core/src/commands/upgrade-helper.ts"() {
31489
31686
  "use strict";
@@ -31491,7 +31688,7 @@ var init_upgrade_helper = __esm({
31491
31688
  import_child_process8 = require("child_process");
31492
31689
  fs8 = __toESM(require("fs"));
31493
31690
  os16 = __toESM(require("os"));
31494
- path13 = __toESM(require("path"));
31691
+ path15 = __toESM(require("path"));
31495
31692
  UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
31496
31693
  }
31497
31694
  });
@@ -31761,6 +31958,12 @@ var init_router = __esm({
31761
31958
  if (!ideType) throw new Error("ideType required");
31762
31959
  const killProcess = args?.killProcess !== false;
31763
31960
  await this.stopIde(ideType, killProcess);
31961
+ try {
31962
+ const results = await detectIDEs(this.deps.providerLoader);
31963
+ this.deps.detectedIdes.value = results;
31964
+ this.deps.providerLoader.setIdeDetectionResults(results, true);
31965
+ } catch {
31966
+ }
31764
31967
  return { success: true, ideType, stopped: true, processKilled: killProcess };
31765
31968
  }
31766
31969
  // ─── IDE restart ───
@@ -31803,6 +32006,12 @@ var init_router = __esm({
31803
32006
  }
31804
32007
  }
31805
32008
  this.deps.onIdeConnected?.();
32009
+ try {
32010
+ const results = await detectIDEs(this.deps.providerLoader);
32011
+ this.deps.detectedIdes.value = results;
32012
+ this.deps.providerLoader.setIdeDetectionResults(results, true);
32013
+ } catch {
32014
+ }
31806
32015
  if (result.success && resolvedWorkspace) {
31807
32016
  try {
31808
32017
  const next = appendRecentActivity(loadState(), {
@@ -31830,8 +32039,9 @@ var init_router = __esm({
31830
32039
  }
31831
32040
  // ─── Detect IDEs ───
31832
32041
  case "detect_ides": {
31833
- const results = await detectIDEs();
32042
+ const results = await detectIDEs(this.deps.providerLoader);
31834
32043
  this.deps.detectedIdes.value = results;
32044
+ this.deps.providerLoader.setIdeDetectionResults(results, true);
31835
32045
  return { success: true, detectedInfo: results };
31836
32046
  }
31837
32047
  // ─── Set User Name ───
@@ -32363,7 +32573,10 @@ var init_provider_adapter = __esm({
32363
32573
  const raw = await evaluate(script, 1e4);
32364
32574
  const data = typeof raw === "string" ? JSON.parse(raw) : raw;
32365
32575
  if (data?.error) return [];
32366
- return Array.isArray(data) ? data : [];
32576
+ if (Array.isArray(data)) return data;
32577
+ if (Array.isArray(data?.sessions)) return data.sessions;
32578
+ if (Array.isArray(data?.chats)) return data.chats;
32579
+ return [];
32367
32580
  } catch {
32368
32581
  return [];
32369
32582
  }
@@ -32371,7 +32584,17 @@ var init_provider_adapter = __esm({
32371
32584
  async switchSession(evaluate, sessionId) {
32372
32585
  const script = this.callScript("switchSession", sessionId);
32373
32586
  if (!script) return false;
32374
- return await evaluate(script, 1e4) === true;
32587
+ const raw = await evaluate(script, 1e4);
32588
+ const data = this.parseMaybeJson(raw);
32589
+ if (data === true) return true;
32590
+ if (typeof data === "string") {
32591
+ const normalized = data.trim().toLowerCase();
32592
+ return normalized === "true" || normalized === "ok" || normalized === "switched" || normalized === "success";
32593
+ }
32594
+ if (data && typeof data === "object") {
32595
+ return data.switched === true || data.success === true || data.ok === true;
32596
+ }
32597
+ return false;
32375
32598
  }
32376
32599
  async focusEditor(evaluate) {
32377
32600
  const script = this.callScript("focusEditor");
@@ -33141,7 +33364,7 @@ function checkPathExists2(paths) {
33141
33364
  for (const p of paths) {
33142
33365
  if (p.includes("*")) {
33143
33366
  const home = os17.homedir();
33144
- const resolved = p.replace(/\*/g, home.split(path14.sep).pop() || "");
33367
+ const resolved = p.replace(/\*/g, home.split(path16.sep).pop() || "");
33145
33368
  if (fs10.existsSync(resolved)) return resolved;
33146
33369
  } else {
33147
33370
  if (fs10.existsSync(p)) return p;
@@ -33151,7 +33374,7 @@ function checkPathExists2(paths) {
33151
33374
  }
33152
33375
  function getMacAppVersion(appPath) {
33153
33376
  if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
33154
- const plistPath = path14.join(appPath, "Contents", "Info.plist");
33377
+ const plistPath = path16.join(appPath, "Contents", "Info.plist");
33155
33378
  if (!fs10.existsSync(plistPath)) return null;
33156
33379
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
33157
33380
  return raw || null;
@@ -33178,7 +33401,7 @@ async function detectAllVersions(loader, archive) {
33178
33401
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
33179
33402
  let resolvedBin = cliBin;
33180
33403
  if (!resolvedBin && appPath && currentOs === "darwin") {
33181
- const bundled = path14.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
33404
+ const bundled = path16.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
33182
33405
  if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
33183
33406
  }
33184
33407
  info.installed = !!(appPath || resolvedBin);
@@ -33215,16 +33438,16 @@ async function detectAllVersions(loader, archive) {
33215
33438
  }
33216
33439
  return results;
33217
33440
  }
33218
- var fs10, path14, os17, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
33441
+ var fs10, path16, os17, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
33219
33442
  var init_version_archive = __esm({
33220
33443
  "../../oss/packages/daemon-core/src/providers/version-archive.ts"() {
33221
33444
  "use strict";
33222
33445
  fs10 = __toESM(require("fs"));
33223
- path14 = __toESM(require("path"));
33446
+ path16 = __toESM(require("path"));
33224
33447
  os17 = __toESM(require("os"));
33225
33448
  import_child_process9 = require("child_process");
33226
33449
  import_os3 = require("os");
33227
- ARCHIVE_PATH = path14.join(os17.homedir(), ".adhdev", "version-history.json");
33450
+ ARCHIVE_PATH = path16.join(os17.homedir(), ".adhdev", "version-history.json");
33228
33451
  MAX_ENTRIES_PER_PROVIDER = 20;
33229
33452
  VersionArchive = class {
33230
33453
  history = {};
@@ -33271,7 +33494,7 @@ var init_version_archive = __esm({
33271
33494
  }
33272
33495
  save() {
33273
33496
  try {
33274
- fs10.mkdirSync(path14.dirname(ARCHIVE_PATH), { recursive: true });
33497
+ fs10.mkdirSync(path16.dirname(ARCHIVE_PATH), { recursive: true });
33275
33498
  fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
33276
33499
  } catch {
33277
33500
  }
@@ -33792,17 +34015,17 @@ async function handleScriptHints(ctx, type, _req, res) {
33792
34015
  return;
33793
34016
  }
33794
34017
  let scriptsPath = "";
33795
- const directScripts = path15.join(dir, "scripts.js");
34018
+ const directScripts = path17.join(dir, "scripts.js");
33796
34019
  if (fs11.existsSync(directScripts)) {
33797
34020
  scriptsPath = directScripts;
33798
34021
  } else {
33799
- const scriptsDir = path15.join(dir, "scripts");
34022
+ const scriptsDir = path17.join(dir, "scripts");
33800
34023
  if (fs11.existsSync(scriptsDir)) {
33801
34024
  const versions = fs11.readdirSync(scriptsDir).filter((d) => {
33802
- return fs11.statSync(path15.join(scriptsDir, d)).isDirectory();
34025
+ return fs11.statSync(path17.join(scriptsDir, d)).isDirectory();
33803
34026
  }).sort().reverse();
33804
34027
  for (const ver of versions) {
33805
- const p = path15.join(scriptsDir, ver, "scripts.js");
34028
+ const p = path17.join(scriptsDir, ver, "scripts.js");
33806
34029
  if (fs11.existsSync(p)) {
33807
34030
  scriptsPath = p;
33808
34031
  break;
@@ -34618,12 +34841,12 @@ async function handleDomContext(ctx, type, req, res) {
34618
34841
  ctx.json(res, 500, { error: `DOM context collection failed: ${e.message}` });
34619
34842
  }
34620
34843
  }
34621
- var fs11, path15;
34844
+ var fs11, path17;
34622
34845
  var init_dev_cdp_handlers = __esm({
34623
34846
  "../../oss/packages/daemon-core/src/daemon/dev-cdp-handlers.ts"() {
34624
34847
  "use strict";
34625
34848
  fs11 = __toESM(require("fs"));
34626
- path15 = __toESM(require("path"));
34849
+ path17 = __toESM(require("path"));
34627
34850
  init_logger();
34628
34851
  }
34629
34852
  });
@@ -34638,11 +34861,11 @@ function getCliFixtureDir(ctx, type) {
34638
34861
  if (!providerDir) {
34639
34862
  throw new Error(`Provider directory not found for '${type}'`);
34640
34863
  }
34641
- return path16.join(providerDir, "fixtures");
34864
+ return path18.join(providerDir, "fixtures");
34642
34865
  }
34643
34866
  function readCliFixture(ctx, type, name) {
34644
34867
  const fixtureDir = getCliFixtureDir(ctx, type);
34645
- const filePath = path16.join(fixtureDir, `${name}.json`);
34868
+ const filePath = path18.join(fixtureDir, `${name}.json`);
34646
34869
  if (!fs12.existsSync(filePath)) {
34647
34870
  throw new Error(`Fixture not found: ${filePath}`);
34648
34871
  }
@@ -34802,7 +35025,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
34802
35025
  return { target, instance, adapter };
34803
35026
  }
34804
35027
  function sleep(ms) {
34805
- return new Promise((resolve13) => setTimeout(resolve13, ms));
35028
+ return new Promise((resolve16) => setTimeout(resolve16, ms));
34806
35029
  }
34807
35030
  async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
34808
35031
  const startedAt = Date.now();
@@ -35401,7 +35624,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
35401
35624
  },
35402
35625
  notes: typeof body?.notes === "string" ? body.notes : void 0
35403
35626
  };
35404
- const filePath = path16.join(fixtureDir, `${name}.json`);
35627
+ const filePath = path18.join(fixtureDir, `${name}.json`);
35405
35628
  fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
35406
35629
  ctx.json(res, 200, {
35407
35630
  saved: true,
@@ -35425,7 +35648,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
35425
35648
  return;
35426
35649
  }
35427
35650
  const fixtures = fs12.readdirSync(fixtureDir).filter((file2) => file2.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file2) => {
35428
- const fullPath = path16.join(fixtureDir, file2);
35651
+ const fullPath = path18.join(fixtureDir, file2);
35429
35652
  try {
35430
35653
  const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
35431
35654
  return {
@@ -35558,12 +35781,12 @@ async function handleCliRaw(ctx, req, res) {
35558
35781
  ctx.json(res, 500, { error: `Raw send failed: ${e.message}` });
35559
35782
  }
35560
35783
  }
35561
- var fs12, path16;
35784
+ var fs12, path18;
35562
35785
  var init_dev_cli_debug = __esm({
35563
35786
  "../../oss/packages/daemon-core/src/daemon/dev-cli-debug.ts"() {
35564
35787
  "use strict";
35565
35788
  fs12 = __toESM(require("fs"));
35566
- path16 = __toESM(require("path"));
35789
+ path18 = __toESM(require("path"));
35567
35790
  }
35568
35791
  });
35569
35792
 
@@ -35606,22 +35829,22 @@ function getLatestScriptVersionDir(scriptsDir) {
35606
35829
  if (!fs13.existsSync(scriptsDir)) return null;
35607
35830
  const versions = fs13.readdirSync(scriptsDir).filter((d) => {
35608
35831
  try {
35609
- return fs13.statSync(path17.join(scriptsDir, d)).isDirectory();
35832
+ return fs13.statSync(path19.join(scriptsDir, d)).isDirectory();
35610
35833
  } catch {
35611
35834
  return false;
35612
35835
  }
35613
35836
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
35614
35837
  if (versions.length === 0) return null;
35615
- return path17.join(scriptsDir, versions[0]);
35838
+ return path19.join(scriptsDir, versions[0]);
35616
35839
  }
35617
35840
  function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
35618
- const canonicalUserDir = path17.resolve(ctx.providerLoader.getUserProviderDir(category, type));
35619
- const desiredDir = requestedDir ? path17.resolve(requestedDir) : canonicalUserDir;
35620
- const upstreamRoot = path17.resolve(ctx.providerLoader.getUpstreamDir());
35621
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path17.sep}`)) {
35841
+ const canonicalUserDir = path19.resolve(ctx.providerLoader.getUserProviderDir(category, type));
35842
+ const desiredDir = requestedDir ? path19.resolve(requestedDir) : canonicalUserDir;
35843
+ const upstreamRoot = path19.resolve(ctx.providerLoader.getUpstreamDir());
35844
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path19.sep}`)) {
35622
35845
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
35623
35846
  }
35624
- if (path17.basename(desiredDir) !== type) {
35847
+ if (path19.basename(desiredDir) !== type) {
35625
35848
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
35626
35849
  }
35627
35850
  const sourceDir = ctx.findProviderDir(type);
@@ -35629,11 +35852,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
35629
35852
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
35630
35853
  }
35631
35854
  if (!fs13.existsSync(desiredDir)) {
35632
- fs13.mkdirSync(path17.dirname(desiredDir), { recursive: true });
35855
+ fs13.mkdirSync(path19.dirname(desiredDir), { recursive: true });
35633
35856
  fs13.cpSync(sourceDir, desiredDir, { recursive: true });
35634
35857
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
35635
35858
  }
35636
- const providerJson = path17.join(desiredDir, "provider.json");
35859
+ const providerJson = path19.join(desiredDir, "provider.json");
35637
35860
  if (!fs13.existsSync(providerJson)) {
35638
35861
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
35639
35862
  }
@@ -35656,13 +35879,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
35656
35879
  const refDir = ctx.findProviderDir(referenceType);
35657
35880
  if (!refDir || !fs13.existsSync(refDir)) return {};
35658
35881
  const referenceScripts = {};
35659
- const scriptsDir = path17.join(refDir, "scripts");
35882
+ const scriptsDir = path19.join(refDir, "scripts");
35660
35883
  const latestDir = getLatestScriptVersionDir(scriptsDir);
35661
35884
  if (!latestDir) return referenceScripts;
35662
35885
  for (const file2 of fs13.readdirSync(latestDir)) {
35663
35886
  if (!file2.endsWith(".js")) continue;
35664
35887
  try {
35665
- referenceScripts[file2] = fs13.readFileSync(path17.join(latestDir, file2), "utf-8");
35888
+ referenceScripts[file2] = fs13.readFileSync(path19.join(latestDir, file2), "utf-8");
35666
35889
  } catch {
35667
35890
  }
35668
35891
  }
@@ -35770,9 +35993,9 @@ async function handleAutoImplement(ctx, type, req, res) {
35770
35993
  });
35771
35994
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
35772
35995
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
35773
- const tmpDir = path17.join(os18.tmpdir(), "adhdev-autoimpl");
35996
+ const tmpDir = path19.join(os18.tmpdir(), "adhdev-autoimpl");
35774
35997
  if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
35775
- const promptFile = path17.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
35998
+ const promptFile = path19.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
35776
35999
  fs13.writeFileSync(promptFile, prompt, "utf-8");
35777
36000
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
35778
36001
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
@@ -36199,7 +36422,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
36199
36422
  setMode: "set_mode.js"
36200
36423
  };
36201
36424
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
36202
- const scriptsDir = path17.join(providerDir, "scripts");
36425
+ const scriptsDir = path19.join(providerDir, "scripts");
36203
36426
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
36204
36427
  if (latestScriptsDir) {
36205
36428
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -36210,7 +36433,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
36210
36433
  for (const file2 of fs13.readdirSync(latestScriptsDir)) {
36211
36434
  if (file2.endsWith(".js") && targetFileNames.has(file2)) {
36212
36435
  try {
36213
- const content = fs13.readFileSync(path17.join(latestScriptsDir, file2), "utf-8");
36436
+ const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
36214
36437
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
36215
36438
  lines.push("```javascript");
36216
36439
  lines.push(content);
@@ -36227,7 +36450,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
36227
36450
  lines.push("");
36228
36451
  for (const file2 of refFiles) {
36229
36452
  try {
36230
- const content = fs13.readFileSync(path17.join(latestScriptsDir, file2), "utf-8");
36453
+ const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
36231
36454
  lines.push(`### \`${file2}\` \u{1F512}`);
36232
36455
  lines.push("```javascript");
36233
36456
  lines.push(content);
@@ -36268,10 +36491,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
36268
36491
  lines.push("");
36269
36492
  }
36270
36493
  }
36271
- const docsDir = path17.join(providerDir, "../../docs");
36494
+ const docsDir = path19.join(providerDir, "../../docs");
36272
36495
  const loadGuide = (name) => {
36273
36496
  try {
36274
- const p = path17.join(docsDir, name);
36497
+ const p = path19.join(docsDir, name);
36275
36498
  if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
36276
36499
  } catch {
36277
36500
  }
@@ -36506,7 +36729,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
36506
36729
  parseApproval: "parse_approval.js"
36507
36730
  };
36508
36731
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
36509
- const scriptsDir = path17.join(providerDir, "scripts");
36732
+ const scriptsDir = path19.join(providerDir, "scripts");
36510
36733
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
36511
36734
  if (latestScriptsDir) {
36512
36735
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -36518,7 +36741,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
36518
36741
  if (!file2.endsWith(".js")) continue;
36519
36742
  if (!targetFileNames.has(file2)) continue;
36520
36743
  try {
36521
- const content = fs13.readFileSync(path17.join(latestScriptsDir, file2), "utf-8");
36744
+ const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
36522
36745
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
36523
36746
  lines.push("```javascript");
36524
36747
  lines.push(content);
@@ -36534,7 +36757,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
36534
36757
  lines.push("");
36535
36758
  for (const file2 of refFiles) {
36536
36759
  try {
36537
- const content = fs13.readFileSync(path17.join(latestScriptsDir, file2), "utf-8");
36760
+ const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
36538
36761
  lines.push(`### \`${file2}\` \u{1F512}`);
36539
36762
  lines.push("```javascript");
36540
36763
  lines.push(content);
@@ -36567,10 +36790,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
36567
36790
  lines.push("");
36568
36791
  }
36569
36792
  }
36570
- const docsDir = path17.join(providerDir, "../../docs");
36793
+ const docsDir = path19.join(providerDir, "../../docs");
36571
36794
  const loadGuide = (name) => {
36572
36795
  try {
36573
- const p = path17.join(docsDir, name);
36796
+ const p = path19.join(docsDir, name);
36574
36797
  if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
36575
36798
  } catch {
36576
36799
  }
@@ -36882,12 +37105,12 @@ data: ${JSON.stringify(msg.data)}
36882
37105
  }
36883
37106
  }
36884
37107
  }
36885
- var fs13, path17, os18;
37108
+ var fs13, path19, os18;
36886
37109
  var init_dev_auto_implement = __esm({
36887
37110
  "../../oss/packages/daemon-core/src/daemon/dev-auto-implement.ts"() {
36888
37111
  "use strict";
36889
37112
  fs13 = __toESM(require("fs"));
36890
- path17 = __toESM(require("path"));
37113
+ path19 = __toESM(require("path"));
36891
37114
  os18 = __toESM(require("os"));
36892
37115
  init_dev_server();
36893
37116
  init_dev_cli_debug();
@@ -36895,13 +37118,13 @@ var init_dev_auto_implement = __esm({
36895
37118
  });
36896
37119
 
36897
37120
  // ../../oss/packages/daemon-core/src/daemon/dev-server.ts
36898
- var http2, fs14, path18, DEV_SERVER_PORT, DevServer;
37121
+ var http2, fs14, path20, DEV_SERVER_PORT, DevServer;
36899
37122
  var init_dev_server = __esm({
36900
37123
  "../../oss/packages/daemon-core/src/daemon/dev-server.ts"() {
36901
37124
  "use strict";
36902
37125
  http2 = __toESM(require("http"));
36903
37126
  fs14 = __toESM(require("fs"));
36904
- path18 = __toESM(require("path"));
37127
+ path20 = __toESM(require("path"));
36905
37128
  init_scaffold_template();
36906
37129
  init_version_archive();
36907
37130
  init_logger();
@@ -37005,8 +37228,8 @@ var init_dev_server = __esm({
37005
37228
  }
37006
37229
  getEndpointList() {
37007
37230
  return this.routes.map((r) => {
37008
- const path23 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
37009
- return `${r.method.padEnd(5)} ${path23}`;
37231
+ const path25 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
37232
+ return `${r.method.padEnd(5)} ${path25}`;
37010
37233
  });
37011
37234
  }
37012
37235
  async start(port = DEV_SERVER_PORT) {
@@ -37037,15 +37260,15 @@ var init_dev_server = __esm({
37037
37260
  this.json(res, 500, { error: e.message });
37038
37261
  }
37039
37262
  });
37040
- return new Promise((resolve13, reject) => {
37263
+ return new Promise((resolve16, reject) => {
37041
37264
  this.server.listen(port, "127.0.0.1", () => {
37042
37265
  this.log(`Dev server listening on http://127.0.0.1:${port}`);
37043
- resolve13();
37266
+ resolve16();
37044
37267
  });
37045
37268
  this.server.on("error", (e) => {
37046
37269
  if (e.code === "EADDRINUSE") {
37047
37270
  this.log(`Port ${port} in use, skipping dev server`);
37048
- resolve13();
37271
+ resolve16();
37049
37272
  } else {
37050
37273
  reject(e);
37051
37274
  }
@@ -37128,20 +37351,20 @@ var init_dev_server = __esm({
37128
37351
  child.stderr?.on("data", (d) => {
37129
37352
  stderr += d.toString().slice(0, 2e3);
37130
37353
  });
37131
- await new Promise((resolve13) => {
37354
+ await new Promise((resolve16) => {
37132
37355
  const timer = setTimeout(() => {
37133
37356
  child.kill();
37134
- resolve13();
37357
+ resolve16();
37135
37358
  }, 3e3);
37136
37359
  child.on("exit", () => {
37137
37360
  clearTimeout(timer);
37138
- resolve13();
37361
+ resolve16();
37139
37362
  });
37140
37363
  child.stdout?.once("data", () => {
37141
37364
  setTimeout(() => {
37142
37365
  child.kill();
37143
37366
  clearTimeout(timer);
37144
- resolve13();
37367
+ resolve16();
37145
37368
  }, 500);
37146
37369
  });
37147
37370
  });
@@ -37288,12 +37511,12 @@ var init_dev_server = __esm({
37288
37511
  // ─── DevConsole SPA ───
37289
37512
  getConsoleDistDir() {
37290
37513
  const candidates = [
37291
- path18.resolve(__dirname, "../../web-devconsole/dist"),
37292
- path18.resolve(__dirname, "../../../web-devconsole/dist"),
37293
- path18.join(process.cwd(), "packages/web-devconsole/dist")
37514
+ path20.resolve(__dirname, "../../web-devconsole/dist"),
37515
+ path20.resolve(__dirname, "../../../web-devconsole/dist"),
37516
+ path20.join(process.cwd(), "packages/web-devconsole/dist")
37294
37517
  ];
37295
37518
  for (const dir of candidates) {
37296
- if (fs14.existsSync(path18.join(dir, "index.html"))) return dir;
37519
+ if (fs14.existsSync(path20.join(dir, "index.html"))) return dir;
37297
37520
  }
37298
37521
  return null;
37299
37522
  }
@@ -37303,7 +37526,7 @@ var init_dev_server = __esm({
37303
37526
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
37304
37527
  return;
37305
37528
  }
37306
- const htmlPath = path18.join(distDir, "index.html");
37529
+ const htmlPath = path20.join(distDir, "index.html");
37307
37530
  try {
37308
37531
  const html = fs14.readFileSync(htmlPath, "utf-8");
37309
37532
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -37328,15 +37551,15 @@ var init_dev_server = __esm({
37328
37551
  this.json(res, 404, { error: "Not found" });
37329
37552
  return;
37330
37553
  }
37331
- const safePath = path18.normalize(pathname).replace(/^\.\.\//, "");
37332
- const filePath = path18.join(distDir, safePath);
37554
+ const safePath = path20.normalize(pathname).replace(/^\.\.\//, "");
37555
+ const filePath = path20.join(distDir, safePath);
37333
37556
  if (!filePath.startsWith(distDir)) {
37334
37557
  this.json(res, 403, { error: "Forbidden" });
37335
37558
  return;
37336
37559
  }
37337
37560
  try {
37338
37561
  const content = fs14.readFileSync(filePath);
37339
- const ext = path18.extname(filePath);
37562
+ const ext = path20.extname(filePath);
37340
37563
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
37341
37564
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
37342
37565
  res.end(content);
@@ -37449,9 +37672,9 @@ var init_dev_server = __esm({
37449
37672
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
37450
37673
  if (entry.isDirectory()) {
37451
37674
  files.push({ path: rel, size: 0, type: "dir" });
37452
- scan(path18.join(d, entry.name), rel);
37675
+ scan(path20.join(d, entry.name), rel);
37453
37676
  } else {
37454
- const stat4 = fs14.statSync(path18.join(d, entry.name));
37677
+ const stat4 = fs14.statSync(path20.join(d, entry.name));
37455
37678
  files.push({ path: rel, size: stat4.size, type: "file" });
37456
37679
  }
37457
37680
  }
@@ -37474,7 +37697,7 @@ var init_dev_server = __esm({
37474
37697
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
37475
37698
  return;
37476
37699
  }
37477
- const fullPath = path18.resolve(dir, path18.normalize(filePath));
37700
+ const fullPath = path20.resolve(dir, path20.normalize(filePath));
37478
37701
  if (!fullPath.startsWith(dir)) {
37479
37702
  this.json(res, 403, { error: "Forbidden" });
37480
37703
  return;
@@ -37499,14 +37722,14 @@ var init_dev_server = __esm({
37499
37722
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
37500
37723
  return;
37501
37724
  }
37502
- const fullPath = path18.resolve(dir, path18.normalize(filePath));
37725
+ const fullPath = path20.resolve(dir, path20.normalize(filePath));
37503
37726
  if (!fullPath.startsWith(dir)) {
37504
37727
  this.json(res, 403, { error: "Forbidden" });
37505
37728
  return;
37506
37729
  }
37507
37730
  try {
37508
37731
  if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
37509
- fs14.mkdirSync(path18.dirname(fullPath), { recursive: true });
37732
+ fs14.mkdirSync(path20.dirname(fullPath), { recursive: true });
37510
37733
  fs14.writeFileSync(fullPath, content, "utf-8");
37511
37734
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
37512
37735
  this.providerLoader.reload();
@@ -37523,7 +37746,7 @@ var init_dev_server = __esm({
37523
37746
  return;
37524
37747
  }
37525
37748
  for (const name of ["scripts.js", "provider.json"]) {
37526
- const p = path18.join(dir, name);
37749
+ const p = path20.join(dir, name);
37527
37750
  if (fs14.existsSync(p)) {
37528
37751
  const source = fs14.readFileSync(p, "utf-8");
37529
37752
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
@@ -37544,8 +37767,8 @@ var init_dev_server = __esm({
37544
37767
  this.json(res, 404, { error: `Provider not found: ${type}` });
37545
37768
  return;
37546
37769
  }
37547
- const target = fs14.existsSync(path18.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
37548
- const targetPath = path18.join(dir, target);
37770
+ const target = fs14.existsSync(path20.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
37771
+ const targetPath = path20.join(dir, target);
37549
37772
  try {
37550
37773
  if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
37551
37774
  fs14.writeFileSync(targetPath, source, "utf-8");
@@ -37650,14 +37873,14 @@ var init_dev_server = __esm({
37650
37873
  child.stderr?.on("data", (d) => {
37651
37874
  stderr += d.toString();
37652
37875
  });
37653
- await new Promise((resolve13) => {
37876
+ await new Promise((resolve16) => {
37654
37877
  const timer = setTimeout(() => {
37655
37878
  child.kill();
37656
- resolve13();
37879
+ resolve16();
37657
37880
  }, timeout);
37658
37881
  child.on("exit", () => {
37659
37882
  clearTimeout(timer);
37660
- resolve13();
37883
+ resolve16();
37661
37884
  });
37662
37885
  });
37663
37886
  const elapsed = Date.now() - start;
@@ -37705,7 +37928,7 @@ var init_dev_server = __esm({
37705
37928
  }
37706
37929
  let targetDir;
37707
37930
  targetDir = this.providerLoader.getUserProviderDir(category, type);
37708
- const jsonPath = path18.join(targetDir, "provider.json");
37931
+ const jsonPath = path20.join(targetDir, "provider.json");
37709
37932
  if (fs14.existsSync(jsonPath)) {
37710
37933
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
37711
37934
  return;
@@ -37717,8 +37940,8 @@ var init_dev_server = __esm({
37717
37940
  const createdFiles = ["provider.json"];
37718
37941
  if (result.files) {
37719
37942
  for (const [relPath, content] of Object.entries(result.files)) {
37720
- const fullPath = path18.join(targetDir, relPath);
37721
- fs14.mkdirSync(path18.dirname(fullPath), { recursive: true });
37943
+ const fullPath = path20.join(targetDir, relPath);
37944
+ fs14.mkdirSync(path20.dirname(fullPath), { recursive: true });
37722
37945
  fs14.writeFileSync(fullPath, content, "utf-8");
37723
37946
  createdFiles.push(relPath);
37724
37947
  }
@@ -37771,22 +37994,22 @@ var init_dev_server = __esm({
37771
37994
  if (!fs14.existsSync(scriptsDir)) return null;
37772
37995
  const versions = fs14.readdirSync(scriptsDir).filter((d) => {
37773
37996
  try {
37774
- return fs14.statSync(path18.join(scriptsDir, d)).isDirectory();
37997
+ return fs14.statSync(path20.join(scriptsDir, d)).isDirectory();
37775
37998
  } catch {
37776
37999
  return false;
37777
38000
  }
37778
38001
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
37779
38002
  if (versions.length === 0) return null;
37780
- return path18.join(scriptsDir, versions[0]);
38003
+ return path20.join(scriptsDir, versions[0]);
37781
38004
  }
37782
38005
  resolveAutoImplWritableProviderDir(category, type, requestedDir) {
37783
- const canonicalUserDir = path18.resolve(this.providerLoader.getUserProviderDir(category, type));
37784
- const desiredDir = requestedDir ? path18.resolve(requestedDir) : canonicalUserDir;
37785
- const upstreamRoot = path18.resolve(this.providerLoader.getUpstreamDir());
37786
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path18.sep}`)) {
38006
+ const canonicalUserDir = path20.resolve(this.providerLoader.getUserProviderDir(category, type));
38007
+ const desiredDir = requestedDir ? path20.resolve(requestedDir) : canonicalUserDir;
38008
+ const upstreamRoot = path20.resolve(this.providerLoader.getUpstreamDir());
38009
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path20.sep}`)) {
37787
38010
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
37788
38011
  }
37789
- if (path18.basename(desiredDir) !== type) {
38012
+ if (path20.basename(desiredDir) !== type) {
37790
38013
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
37791
38014
  }
37792
38015
  const sourceDir = this.findProviderDir(type);
@@ -37794,11 +38017,11 @@ var init_dev_server = __esm({
37794
38017
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
37795
38018
  }
37796
38019
  if (!fs14.existsSync(desiredDir)) {
37797
- fs14.mkdirSync(path18.dirname(desiredDir), { recursive: true });
38020
+ fs14.mkdirSync(path20.dirname(desiredDir), { recursive: true });
37798
38021
  fs14.cpSync(sourceDir, desiredDir, { recursive: true });
37799
38022
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
37800
38023
  }
37801
- const providerJson = path18.join(desiredDir, "provider.json");
38024
+ const providerJson = path20.join(desiredDir, "provider.json");
37802
38025
  if (!fs14.existsSync(providerJson)) {
37803
38026
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
37804
38027
  }
@@ -37846,7 +38069,7 @@ var init_dev_server = __esm({
37846
38069
  setMode: "set_mode.js"
37847
38070
  };
37848
38071
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
37849
- const scriptsDir = path18.join(providerDir, "scripts");
38072
+ const scriptsDir = path20.join(providerDir, "scripts");
37850
38073
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
37851
38074
  if (latestScriptsDir) {
37852
38075
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -37857,7 +38080,7 @@ var init_dev_server = __esm({
37857
38080
  for (const file2 of fs14.readdirSync(latestScriptsDir)) {
37858
38081
  if (file2.endsWith(".js") && targetFileNames.has(file2)) {
37859
38082
  try {
37860
- const content = fs14.readFileSync(path18.join(latestScriptsDir, file2), "utf-8");
38083
+ const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
37861
38084
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
37862
38085
  lines.push("```javascript");
37863
38086
  lines.push(content);
@@ -37874,7 +38097,7 @@ var init_dev_server = __esm({
37874
38097
  lines.push("");
37875
38098
  for (const file2 of refFiles) {
37876
38099
  try {
37877
- const content = fs14.readFileSync(path18.join(latestScriptsDir, file2), "utf-8");
38100
+ const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
37878
38101
  lines.push(`### \`${file2}\` \u{1F512}`);
37879
38102
  lines.push("```javascript");
37880
38103
  lines.push(content);
@@ -37915,10 +38138,10 @@ var init_dev_server = __esm({
37915
38138
  lines.push("");
37916
38139
  }
37917
38140
  }
37918
- const docsDir = path18.join(providerDir, "../../docs");
38141
+ const docsDir = path20.join(providerDir, "../../docs");
37919
38142
  const loadGuide = (name) => {
37920
38143
  try {
37921
- const p = path18.join(docsDir, name);
38144
+ const p = path20.join(docsDir, name);
37922
38145
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
37923
38146
  } catch {
37924
38147
  }
@@ -38092,7 +38315,7 @@ var init_dev_server = __esm({
38092
38315
  parseApproval: "parse_approval.js"
38093
38316
  };
38094
38317
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
38095
- const scriptsDir = path18.join(providerDir, "scripts");
38318
+ const scriptsDir = path20.join(providerDir, "scripts");
38096
38319
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
38097
38320
  if (latestScriptsDir) {
38098
38321
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -38104,7 +38327,7 @@ var init_dev_server = __esm({
38104
38327
  if (!file2.endsWith(".js")) continue;
38105
38328
  if (!targetFileNames.has(file2)) continue;
38106
38329
  try {
38107
- const content = fs14.readFileSync(path18.join(latestScriptsDir, file2), "utf-8");
38330
+ const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
38108
38331
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
38109
38332
  lines.push("```javascript");
38110
38333
  lines.push(content);
@@ -38120,7 +38343,7 @@ var init_dev_server = __esm({
38120
38343
  lines.push("");
38121
38344
  for (const file2 of refFiles) {
38122
38345
  try {
38123
- const content = fs14.readFileSync(path18.join(latestScriptsDir, file2), "utf-8");
38346
+ const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
38124
38347
  lines.push(`### \`${file2}\` \u{1F512}`);
38125
38348
  lines.push("```javascript");
38126
38349
  lines.push(content);
@@ -38153,10 +38376,10 @@ var init_dev_server = __esm({
38153
38376
  lines.push("");
38154
38377
  }
38155
38378
  }
38156
- const docsDir = path18.join(providerDir, "../../docs");
38379
+ const docsDir = path20.join(providerDir, "../../docs");
38157
38380
  const loadGuide = (name) => {
38158
38381
  try {
38159
- const p = path18.join(docsDir, name);
38382
+ const p = path20.join(docsDir, name);
38160
38383
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
38161
38384
  } catch {
38162
38385
  }
@@ -38332,14 +38555,14 @@ data: ${JSON.stringify(msg.data)}
38332
38555
  res.end(JSON.stringify(data, null, 2));
38333
38556
  }
38334
38557
  async readBody(req) {
38335
- return new Promise((resolve13) => {
38558
+ return new Promise((resolve16) => {
38336
38559
  let body = "";
38337
38560
  req.on("data", (chunk) => body += chunk);
38338
38561
  req.on("end", () => {
38339
38562
  try {
38340
- resolve13(JSON.parse(body));
38563
+ resolve16(JSON.parse(body));
38341
38564
  } catch {
38342
- resolve13({});
38565
+ resolve16({});
38343
38566
  }
38344
38567
  });
38345
38568
  });
@@ -38808,7 +39031,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
38808
39031
  const deadline = Date.now() + timeoutMs;
38809
39032
  while (Date.now() < deadline) {
38810
39033
  if (await canConnect(endpoint)) return;
38811
- await new Promise((resolve13) => setTimeout(resolve13, STARTUP_POLL_MS));
39034
+ await new Promise((resolve16) => setTimeout(resolve16, STARTUP_POLL_MS));
38812
39035
  }
38813
39036
  throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
38814
39037
  }
@@ -38899,10 +39122,10 @@ async function installExtension(ide, extension) {
38899
39122
  const buffer = Buffer.from(await res.arrayBuffer());
38900
39123
  const fs18 = await import("fs");
38901
39124
  fs18.writeFileSync(vsixPath, buffer);
38902
- return new Promise((resolve13) => {
39125
+ return new Promise((resolve16) => {
38903
39126
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
38904
39127
  (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
38905
- resolve13({
39128
+ resolve16({
38906
39129
  extensionId: extension.id,
38907
39130
  marketplaceId: extension.marketplaceId,
38908
39131
  success: !error48,
@@ -38915,11 +39138,11 @@ async function installExtension(ide, extension) {
38915
39138
  } catch (e) {
38916
39139
  }
38917
39140
  }
38918
- return new Promise((resolve13) => {
39141
+ return new Promise((resolve16) => {
38919
39142
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
38920
39143
  (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
38921
39144
  if (error48) {
38922
- resolve13({
39145
+ resolve16({
38923
39146
  extensionId: extension.id,
38924
39147
  marketplaceId: extension.marketplaceId,
38925
39148
  success: false,
@@ -38927,7 +39150,7 @@ async function installExtension(ide, extension) {
38927
39150
  error: stderr || error48.message
38928
39151
  });
38929
39152
  } else {
38930
- resolve13({
39153
+ resolve16({
38931
39154
  extensionId: extension.id,
38932
39155
  marketplaceId: extension.marketplaceId,
38933
39156
  success: true,
@@ -39147,13 +39370,32 @@ async function initDaemonComponents(config2) {
39147
39370
  const detectedIdesRef = { value: [] };
39148
39371
  let agentStreamManager = null;
39149
39372
  let poller = null;
39373
+ const refreshProviderAvailability = async (providerType) => {
39374
+ const targetProvider = providerType ? providerLoader.getMeta(providerLoader.resolveAlias(providerType)) : null;
39375
+ const targetCategory = targetProvider?.category;
39376
+ if (!providerType || targetCategory === "cli" || targetCategory === "acp") {
39377
+ if (providerType && targetProvider) {
39378
+ const detected = await detectCLI(targetProvider.type, providerLoader, { includeVersion: false });
39379
+ providerLoader.setProviderAvailability(targetProvider.type, {
39380
+ installed: !!detected,
39381
+ detectedPath: detected?.path || null
39382
+ });
39383
+ } else {
39384
+ providerLoader.setCliDetectionResults(await detectCLIs(providerLoader, { includeVersion: false }), true);
39385
+ }
39386
+ }
39387
+ if (!providerType || targetCategory === "ide") {
39388
+ detectedIdesRef.value = await detectIDEs(providerLoader);
39389
+ providerLoader.setIdeDetectionResults(detectedIdesRef.value, true);
39390
+ }
39391
+ };
39150
39392
  const cliManager = new DaemonCliManager({
39151
39393
  ...config2.cliManagerDeps,
39152
39394
  getInstanceManager: () => instanceManager,
39153
39395
  getSessionRegistry: () => sessionRegistry
39154
39396
  }, providerLoader);
39155
39397
  LOG.info("Init", "Detecting IDEs...");
39156
- detectedIdesRef.value = await detectIDEs();
39398
+ await refreshProviderAvailability();
39157
39399
  const installed = detectedIdesRef.value.filter((i) => i.installed);
39158
39400
  LOG.info("Init", `Found ${installed.length} IDE(s): ${installed.map((i) => i.id).join(", ") || "none"}`);
39159
39401
  const cdpSetupContext = {
@@ -39193,7 +39435,11 @@ async function initDaemonComponents(config2) {
39193
39435
  adapters: cliManager.adapters,
39194
39436
  providerLoader,
39195
39437
  instanceManager,
39196
- sessionRegistry
39438
+ sessionRegistry,
39439
+ onProviderSettingChanged: async (providerType) => {
39440
+ await refreshProviderAvailability(providerType);
39441
+ config2.onStatusChange?.();
39442
+ }
39197
39443
  });
39198
39444
  agentStreamManager = new DaemonAgentStreamManager(
39199
39445
  LOG.forComponent("AgentStream").asLogFn(),
@@ -39308,6 +39554,7 @@ var init_daemon_lifecycle = __esm({
39308
39554
  init_provider_instance_manager();
39309
39555
  init_dev_server();
39310
39556
  init_ide_detector();
39557
+ init_cli_detector();
39311
39558
  init_registry();
39312
39559
  init_logger();
39313
39560
  init_config();
@@ -39745,17 +39992,17 @@ function canPeerUsePrivilegedShareCommand(commandType, permission) {
39745
39992
  return false;
39746
39993
  }
39747
39994
  }
39748
- var fs15, path19, os19, import_node_module2, esmRequire, logFile, log, logDebug, DaemonP2PSender;
39995
+ var fs15, path21, os19, import_node_module2, esmRequire, logFile, log, logDebug, DaemonP2PSender;
39749
39996
  var init_daemon_p2p = __esm({
39750
39997
  "src/daemon-p2p.ts"() {
39751
39998
  "use strict";
39752
39999
  fs15 = __toESM(require("fs"));
39753
40000
  init_src();
39754
- path19 = __toESM(require("path"));
40001
+ path21 = __toESM(require("path"));
39755
40002
  os19 = __toESM(require("os"));
39756
40003
  import_node_module2 = require("module");
39757
40004
  esmRequire = (0, import_node_module2.createRequire)(__filename);
39758
- logFile = path19.join(os19.tmpdir(), "adhdev_daemon_p2p.log");
40005
+ logFile = path21.join(os19.tmpdir(), "adhdev_daemon_p2p.log");
39759
40006
  log = (msg) => {
39760
40007
  LOG.info("P2P", `[${(/* @__PURE__ */ new Date()).toISOString()}] [P2P] ${msg}`);
39761
40008
  };
@@ -39823,15 +40070,15 @@ ${e?.stack || ""}`);
39823
40070
  const prebuildKey = `${platform11}-${arch3}`;
39824
40071
  try {
39825
40072
  const candidates = [
39826
- path19.join(__dirname, "node_modules", "node-datachannel"),
39827
- path19.join(__dirname, "..", "node_modules", "node-datachannel"),
39828
- path19.join(__dirname, "..", "..", "node_modules", "node-datachannel")
40073
+ path21.join(__dirname, "node_modules", "node-datachannel"),
40074
+ path21.join(__dirname, "..", "node_modules", "node-datachannel"),
40075
+ path21.join(__dirname, "..", "..", "node_modules", "node-datachannel")
39829
40076
  ];
39830
40077
  for (const candidate of candidates) {
39831
- const prebuildPath = path19.join(candidate, "prebuilds", prebuildKey, "node_datachannel.node");
40078
+ const prebuildPath = path21.join(candidate, "prebuilds", prebuildKey, "node_datachannel.node");
39832
40079
  if (fs15.existsSync(prebuildPath)) {
39833
- const targetDir = path19.join(candidate, "build", "Release");
39834
- const targetPath = path19.join(targetDir, "node_datachannel.node");
40080
+ const targetDir = path21.join(candidate, "build", "Release");
40081
+ const targetPath = path21.join(targetDir, "node_datachannel.node");
39835
40082
  fs15.mkdirSync(targetDir, { recursive: true });
39836
40083
  fs15.copyFileSync(prebuildPath, targetPath);
39837
40084
  try {
@@ -39914,13 +40161,13 @@ ${e?.stack || ""}`);
39914
40161
  } catch {
39915
40162
  }
39916
40163
  const http3 = esmRequire("https");
39917
- const data = await new Promise((resolve13, reject) => {
40164
+ const data = await new Promise((resolve16, reject) => {
39918
40165
  const req = http3.get(`${serverUrl}/api/v1/turn/credentials`, {
39919
40166
  headers: { "Authorization": `Bearer ${token}` }
39920
40167
  }, (res) => {
39921
40168
  let d = "";
39922
40169
  res.on("data", (c) => d += c);
39923
- res.on("end", () => resolve13(d));
40170
+ res.on("end", () => resolve16(d));
39924
40171
  });
39925
40172
  req.on("error", reject);
39926
40173
  req.setTimeout(5e3, () => {
@@ -40611,22 +40858,22 @@ var require_filesystem = __commonJS({
40611
40858
  var LDD_PATH = "/usr/bin/ldd";
40612
40859
  var SELF_PATH = "/proc/self/exe";
40613
40860
  var MAX_LENGTH = 2048;
40614
- var readFileSync17 = (path23) => {
40615
- const fd = fs18.openSync(path23, "r");
40861
+ var readFileSync17 = (path25) => {
40862
+ const fd = fs18.openSync(path25, "r");
40616
40863
  const buffer = Buffer.alloc(MAX_LENGTH);
40617
40864
  const bytesRead = fs18.readSync(fd, buffer, 0, MAX_LENGTH, 0);
40618
40865
  fs18.close(fd, () => {
40619
40866
  });
40620
40867
  return buffer.subarray(0, bytesRead);
40621
40868
  };
40622
- var readFile = (path23) => new Promise((resolve13, reject) => {
40623
- fs18.open(path23, "r", (err, fd) => {
40869
+ var readFile = (path25) => new Promise((resolve16, reject) => {
40870
+ fs18.open(path25, "r", (err, fd) => {
40624
40871
  if (err) {
40625
40872
  reject(err);
40626
40873
  } else {
40627
40874
  const buffer = Buffer.alloc(MAX_LENGTH);
40628
40875
  fs18.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
40629
- resolve13(buffer.subarray(0, bytesRead));
40876
+ resolve16(buffer.subarray(0, bytesRead));
40630
40877
  fs18.close(fd, () => {
40631
40878
  });
40632
40879
  });
@@ -40694,10 +40941,10 @@ var require_detect_libc = __commonJS({
40694
40941
  var commandOut = "";
40695
40942
  var safeCommand = () => {
40696
40943
  if (!commandOut) {
40697
- return new Promise((resolve13) => {
40944
+ return new Promise((resolve16) => {
40698
40945
  childProcess.exec(command, (err, out) => {
40699
40946
  commandOut = err ? " " : out;
40700
- resolve13(commandOut);
40947
+ resolve16(commandOut);
40701
40948
  });
40702
40949
  });
40703
40950
  }
@@ -40739,11 +40986,11 @@ var require_detect_libc = __commonJS({
40739
40986
  }
40740
40987
  return null;
40741
40988
  };
40742
- var familyFromInterpreterPath = (path23) => {
40743
- if (path23) {
40744
- if (path23.includes("/ld-musl-")) {
40989
+ var familyFromInterpreterPath = (path25) => {
40990
+ if (path25) {
40991
+ if (path25.includes("/ld-musl-")) {
40745
40992
  return MUSL;
40746
- } else if (path23.includes("/ld-linux-")) {
40993
+ } else if (path25.includes("/ld-linux-")) {
40747
40994
  return GLIBC;
40748
40995
  }
40749
40996
  }
@@ -40790,8 +41037,8 @@ var require_detect_libc = __commonJS({
40790
41037
  cachedFamilyInterpreter = null;
40791
41038
  try {
40792
41039
  const selfContent = await readFile(SELF_PATH);
40793
- const path23 = interpreterPath(selfContent);
40794
- cachedFamilyInterpreter = familyFromInterpreterPath(path23);
41040
+ const path25 = interpreterPath(selfContent);
41041
+ cachedFamilyInterpreter = familyFromInterpreterPath(path25);
40795
41042
  } catch (e) {
40796
41043
  }
40797
41044
  return cachedFamilyInterpreter;
@@ -40803,8 +41050,8 @@ var require_detect_libc = __commonJS({
40803
41050
  cachedFamilyInterpreter = null;
40804
41051
  try {
40805
41052
  const selfContent = readFileSync17(SELF_PATH);
40806
- const path23 = interpreterPath(selfContent);
40807
- cachedFamilyInterpreter = familyFromInterpreterPath(path23);
41053
+ const path25 = interpreterPath(selfContent);
41054
+ cachedFamilyInterpreter = familyFromInterpreterPath(path25);
40808
41055
  } catch (e) {
40809
41056
  }
40810
41057
  return cachedFamilyInterpreter;
@@ -42523,18 +42770,18 @@ var require_sharp = __commonJS({
42523
42770
  `@img/sharp-${runtimePlatform}/sharp.node`,
42524
42771
  "@img/sharp-wasm32/sharp.node"
42525
42772
  ];
42526
- var path23;
42773
+ var path25;
42527
42774
  var sharp;
42528
42775
  var errors = [];
42529
- for (path23 of paths) {
42776
+ for (path25 of paths) {
42530
42777
  try {
42531
- sharp = require(path23);
42778
+ sharp = require(path25);
42532
42779
  break;
42533
42780
  } catch (err) {
42534
42781
  errors.push(err);
42535
42782
  }
42536
42783
  }
42537
- if (sharp && path23.startsWith("@img/sharp-linux-x64") && !sharp._isUsingX64V2()) {
42784
+ if (sharp && path25.startsWith("@img/sharp-linux-x64") && !sharp._isUsingX64V2()) {
42538
42785
  const err = new Error("Prebuilt binaries for linux-x64 require v2 microarchitecture");
42539
42786
  err.code = "Unsupported CPU";
42540
42787
  errors.push(err);
@@ -43377,14 +43624,14 @@ var require_input = __commonJS({
43377
43624
  return this;
43378
43625
  } else {
43379
43626
  if (this._isStreamInput()) {
43380
- return new Promise((resolve13, reject) => {
43627
+ return new Promise((resolve16, reject) => {
43381
43628
  const finished = () => {
43382
43629
  this._flattenBufferIn();
43383
43630
  sharp.metadata(this.options, (err, metadata2) => {
43384
43631
  if (err) {
43385
43632
  reject(is.nativeError(err, stack));
43386
43633
  } else {
43387
- resolve13(metadata2);
43634
+ resolve16(metadata2);
43388
43635
  }
43389
43636
  });
43390
43637
  };
@@ -43395,12 +43642,12 @@ var require_input = __commonJS({
43395
43642
  }
43396
43643
  });
43397
43644
  } else {
43398
- return new Promise((resolve13, reject) => {
43645
+ return new Promise((resolve16, reject) => {
43399
43646
  sharp.metadata(this.options, (err, metadata2) => {
43400
43647
  if (err) {
43401
43648
  reject(is.nativeError(err, stack));
43402
43649
  } else {
43403
- resolve13(metadata2);
43650
+ resolve16(metadata2);
43404
43651
  }
43405
43652
  });
43406
43653
  });
@@ -43433,25 +43680,25 @@ var require_input = __commonJS({
43433
43680
  return this;
43434
43681
  } else {
43435
43682
  if (this._isStreamInput()) {
43436
- return new Promise((resolve13, reject) => {
43683
+ return new Promise((resolve16, reject) => {
43437
43684
  this.on("finish", function() {
43438
43685
  this._flattenBufferIn();
43439
43686
  sharp.stats(this.options, (err, stats2) => {
43440
43687
  if (err) {
43441
43688
  reject(is.nativeError(err, stack));
43442
43689
  } else {
43443
- resolve13(stats2);
43690
+ resolve16(stats2);
43444
43691
  }
43445
43692
  });
43446
43693
  });
43447
43694
  });
43448
43695
  } else {
43449
- return new Promise((resolve13, reject) => {
43696
+ return new Promise((resolve16, reject) => {
43450
43697
  sharp.stats(this.options, (err, stats2) => {
43451
43698
  if (err) {
43452
43699
  reject(is.nativeError(err, stack));
43453
43700
  } else {
43454
- resolve13(stats2);
43701
+ resolve16(stats2);
43455
43702
  }
43456
43703
  });
43457
43704
  });
@@ -45443,15 +45690,15 @@ var require_color = __commonJS({
45443
45690
  };
45444
45691
  }
45445
45692
  function wrapConversion(toModel, graph) {
45446
- const path23 = [graph[toModel].parent, toModel];
45693
+ const path25 = [graph[toModel].parent, toModel];
45447
45694
  let fn = conversions_default[graph[toModel].parent][toModel];
45448
45695
  let cur = graph[toModel].parent;
45449
45696
  while (graph[cur].parent) {
45450
- path23.unshift(graph[cur].parent);
45697
+ path25.unshift(graph[cur].parent);
45451
45698
  fn = link(conversions_default[graph[cur].parent][cur], fn);
45452
45699
  cur = graph[cur].parent;
45453
45700
  }
45454
- fn.conversion = path23;
45701
+ fn.conversion = path25;
45455
45702
  return fn;
45456
45703
  }
45457
45704
  function route(fromModel) {
@@ -46068,7 +46315,7 @@ var require_channel = __commonJS({
46068
46315
  var require_output = __commonJS({
46069
46316
  "../../node_modules/sharp/lib/output.js"(exports2, module2) {
46070
46317
  "use strict";
46071
- var path23 = require("path");
46318
+ var path25 = require("path");
46072
46319
  var is = require_is();
46073
46320
  var sharp = require_sharp();
46074
46321
  var formats = /* @__PURE__ */ new Map([
@@ -46099,9 +46346,9 @@ var require_output = __commonJS({
46099
46346
  let err;
46100
46347
  if (!is.string(fileOut)) {
46101
46348
  err = new Error("Missing output file path");
46102
- } else if (is.string(this.options.input.file) && path23.resolve(this.options.input.file) === path23.resolve(fileOut)) {
46349
+ } else if (is.string(this.options.input.file) && path25.resolve(this.options.input.file) === path25.resolve(fileOut)) {
46103
46350
  err = new Error("Cannot use same file for input and output");
46104
- } else if (jp2Regex.test(path23.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
46351
+ } else if (jp2Regex.test(path25.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
46105
46352
  err = errJp2Save();
46106
46353
  }
46107
46354
  if (err) {
@@ -46873,7 +47120,7 @@ var require_output = __commonJS({
46873
47120
  return this;
46874
47121
  } else {
46875
47122
  if (this._isStreamInput()) {
46876
- return new Promise((resolve13, reject) => {
47123
+ return new Promise((resolve16, reject) => {
46877
47124
  this.once("finish", () => {
46878
47125
  this._flattenBufferIn();
46879
47126
  sharp.pipeline(this.options, (err, data, info) => {
@@ -46881,24 +47128,24 @@ var require_output = __commonJS({
46881
47128
  reject(is.nativeError(err, stack));
46882
47129
  } else {
46883
47130
  if (this.options.resolveWithObject) {
46884
- resolve13({ data, info });
47131
+ resolve16({ data, info });
46885
47132
  } else {
46886
- resolve13(data);
47133
+ resolve16(data);
46887
47134
  }
46888
47135
  }
46889
47136
  });
46890
47137
  });
46891
47138
  });
46892
47139
  } else {
46893
- return new Promise((resolve13, reject) => {
47140
+ return new Promise((resolve16, reject) => {
46894
47141
  sharp.pipeline(this.options, (err, data, info) => {
46895
47142
  if (err) {
46896
47143
  reject(is.nativeError(err, stack));
46897
47144
  } else {
46898
47145
  if (this.options.resolveWithObject) {
46899
- resolve13({ data, info });
47146
+ resolve16({ data, info });
46900
47147
  } else {
46901
- resolve13(data);
47148
+ resolve16(data);
46902
47149
  }
46903
47150
  }
46904
47151
  });
@@ -47306,8 +47553,8 @@ function buildSessionHostEnv(baseEnv) {
47306
47553
  }
47307
47554
  function resolveSessionHostEntry() {
47308
47555
  const packagedCandidates = [
47309
- path20.resolve(__dirname, "../vendor/session-host-daemon/index.js"),
47310
- path20.resolve(__dirname, "../../vendor/session-host-daemon/index.js")
47556
+ path23.resolve(__dirname, "../vendor/session-host-daemon/index.js"),
47557
+ path23.resolve(__dirname, "../../vendor/session-host-daemon/index.js")
47311
47558
  ];
47312
47559
  for (const candidate of packagedCandidates) {
47313
47560
  if (fs16.existsSync(candidate)) {
@@ -47317,7 +47564,7 @@ function resolveSessionHostEntry() {
47317
47564
  return require.resolve("@adhdev/session-host-daemon");
47318
47565
  }
47319
47566
  function getSessionHostPidFile() {
47320
- return path20.join(os20.homedir(), ".adhdev", `${SESSION_HOST_APP_NAME}-session-host.pid`);
47567
+ return path23.join(os20.homedir(), ".adhdev", `${SESSION_HOST_APP_NAME}-session-host.pid`);
47321
47568
  }
47322
47569
  function killPid2(pid) {
47323
47570
  try {
@@ -47414,9 +47661,9 @@ function stopSessionHost() {
47414
47661
  async function ensureSessionHostReady2() {
47415
47662
  const spawnHost = () => {
47416
47663
  const entry = resolveSessionHostEntry();
47417
- const logDir = path20.join(os20.homedir(), ".adhdev", "logs");
47664
+ const logDir = path23.join(os20.homedir(), ".adhdev", "logs");
47418
47665
  fs16.mkdirSync(logDir, { recursive: true });
47419
- const logFd = fs16.openSync(path20.join(logDir, "session-host.log"), "a");
47666
+ const logFd = fs16.openSync(path23.join(logDir, "session-host.log"), "a");
47420
47667
  const child = (0, import_child_process11.spawn)(process.execPath, [entry], {
47421
47668
  detached: true,
47422
47669
  stdio: ["ignore", logFd, logFd],
@@ -47451,14 +47698,14 @@ async function ensureSessionHostReady2() {
47451
47698
  async function listHostedCliRuntimes2(endpoint) {
47452
47699
  return listHostedCliRuntimes(endpoint);
47453
47700
  }
47454
- var import_child_process11, fs16, os20, path20, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
47701
+ var import_child_process11, fs16, os20, path23, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
47455
47702
  var init_session_host = __esm({
47456
47703
  "src/session-host.ts"() {
47457
47704
  "use strict";
47458
47705
  import_child_process11 = require("child_process");
47459
47706
  fs16 = __toESM(require("fs"));
47460
47707
  os20 = __toESM(require("os"));
47461
- path20 = __toESM(require("path"));
47708
+ path23 = __toESM(require("path"));
47462
47709
  init_src();
47463
47710
  init_dist();
47464
47711
  SESSION_HOST_APP_NAME = process.env.ADHDEV_SESSION_HOST_NAME || "adhdev";
@@ -47622,18 +47869,18 @@ function resolvePackageVersion(options) {
47622
47869
  ];
47623
47870
  for (const p of possiblePaths) {
47624
47871
  try {
47625
- const data = JSON.parse((0, import_fs4.readFileSync)(p, "utf-8"));
47872
+ const data = JSON.parse((0, import_fs5.readFileSync)(p, "utf-8"));
47626
47873
  if (data.version) return data.version;
47627
47874
  } catch {
47628
47875
  }
47629
47876
  }
47630
47877
  return injectedVersion;
47631
47878
  }
47632
- var import_fs4, import_path3;
47879
+ var import_fs5, import_path3;
47633
47880
  var init_version = __esm({
47634
47881
  "src/version.ts"() {
47635
47882
  "use strict";
47636
- import_fs4 = require("fs");
47883
+ import_fs5 = require("fs");
47637
47884
  import_path3 = require("path");
47638
47885
  }
47639
47886
  });
@@ -47647,9 +47894,9 @@ __export(adhdev_daemon_exports, {
47647
47894
  stopDaemon: () => stopDaemon
47648
47895
  });
47649
47896
  function getDaemonPidFile() {
47650
- const dir = path21.join(os21.homedir(), ".adhdev");
47897
+ const dir = path24.join(os21.homedir(), ".adhdev");
47651
47898
  if (!fs17.existsSync(dir)) fs17.mkdirSync(dir, { recursive: true });
47652
- return path21.join(dir, "daemon.pid");
47899
+ return path24.join(dir, "daemon.pid");
47653
47900
  }
47654
47901
  function writeDaemonPid(pid) {
47655
47902
  fs17.writeFileSync(getDaemonPidFile(), String(pid), "utf-8");
@@ -47695,7 +47942,7 @@ function stopDaemon() {
47695
47942
  return false;
47696
47943
  }
47697
47944
  }
47698
- var os21, fs17, path21, import_http, import_ws3, import_chalk2, pkgVersion, DANGEROUS_PATTERNS, AdhdevDaemon;
47945
+ var os21, fs17, path24, import_http, import_ws3, import_chalk2, pkgVersion, DANGEROUS_PATTERNS, AdhdevDaemon;
47699
47946
  var init_adhdev_daemon = __esm({
47700
47947
  "src/adhdev-daemon.ts"() {
47701
47948
  "use strict";
@@ -47708,12 +47955,12 @@ var init_adhdev_daemon = __esm({
47708
47955
  init_session_host_controller();
47709
47956
  os21 = __toESM(require("os"));
47710
47957
  fs17 = __toESM(require("fs"));
47711
- path21 = __toESM(require("path"));
47958
+ path24 = __toESM(require("path"));
47712
47959
  import_http = require("http");
47713
47960
  import_ws3 = require("ws");
47714
47961
  import_chalk2 = __toESM(require("chalk"));
47715
47962
  init_version();
47716
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.27" });
47963
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.28" });
47717
47964
  DANGEROUS_PATTERNS = [
47718
47965
  /\brm\s+(-[a-z]*f|-[a-z]*r|--force|--recursive)/i,
47719
47966
  /\bsudo\b/i,
@@ -48144,7 +48391,7 @@ ${err?.stack || ""}`);
48144
48391
  this.localWss.emit("connection", ws, req);
48145
48392
  });
48146
48393
  });
48147
- await new Promise((resolve13, reject) => {
48394
+ await new Promise((resolve16, reject) => {
48148
48395
  const cleanup = () => {
48149
48396
  this.localHttpServer?.off("error", onError);
48150
48397
  this.localHttpServer?.off("listening", onListening);
@@ -48155,7 +48402,7 @@ ${err?.stack || ""}`);
48155
48402
  };
48156
48403
  const onListening = () => {
48157
48404
  cleanup();
48158
- resolve13();
48405
+ resolve16();
48159
48406
  };
48160
48407
  this.localHttpServer.once("error", onError);
48161
48408
  this.localHttpServer.once("listening", onListening);
@@ -48306,12 +48553,12 @@ ${err?.stack || ""}`);
48306
48553
  this.localClients.clear();
48307
48554
  this.localWss?.close();
48308
48555
  this.localWss = null;
48309
- await new Promise((resolve13) => {
48556
+ await new Promise((resolve16) => {
48310
48557
  if (!this.localHttpServer) {
48311
- resolve13();
48558
+ resolve16();
48312
48559
  return;
48313
48560
  }
48314
- this.localHttpServer.close(() => resolve13());
48561
+ this.localHttpServer.close(() => resolve16());
48315
48562
  this.localHttpServer = null;
48316
48563
  });
48317
48564
  } catch {