adhdev 0.8.27 → 0.8.29

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)) {
@@ -2554,10 +2595,66 @@ var init_control_effects = __esm({
2554
2595
  });
2555
2596
 
2556
2597
  // ../../oss/packages/daemon-core/src/config/chat-history.ts
2598
+ function normalizeHistoryComparable(text) {
2599
+ return String(text || "").replace(/\s+/g, " ").trim();
2600
+ }
2601
+ function cleanupHistoryContent(agentType, role, content) {
2602
+ let value = String(content || "").replace(/\r\n/g, "\n").trim();
2603
+ if (!value) return "";
2604
+ if (agentType === "codex-cli" && role === "assistant") {
2605
+ const filtered = value.split("\n").filter((line) => !CODEX_STARTER_PROMPT_RE.test(line.trim())).join("\n").replace(/\n{3,}/g, "\n\n").trim();
2606
+ value = filtered;
2607
+ }
2608
+ return value;
2609
+ }
2610
+ function buildHistoryMessageHash(agentType, message) {
2611
+ if (message.historyDedupKey) return message.historyDedupKey;
2612
+ const cleaned = cleanupHistoryContent(agentType, message.role, message.content);
2613
+ return `${message.kind || "standard"}:${message.role}:${message.receivedAt || 0}:${normalizeHistoryComparable(cleaned)}`;
2614
+ }
2615
+ function buildHistoryMessageSignature(agentType, message) {
2616
+ const cleaned = cleanupHistoryContent(agentType, message.role, message.content);
2617
+ return `${message.kind || "standard"}:${message.role}:${normalizeHistoryComparable(cleaned)}`;
2618
+ }
2619
+ function isAdjacentHistoryDuplicate(agentType, previous, next) {
2620
+ if (!previous || !next) return false;
2621
+ return buildHistoryMessageSignature(agentType, previous) === buildHistoryMessageSignature(agentType, next);
2622
+ }
2623
+ function collapseReplayAssistantTurns(agentType, messages) {
2624
+ if (agentType !== "codex-cli") return messages;
2625
+ const collapsed = [];
2626
+ let sawAssistantSinceLastUser = false;
2627
+ for (const message of messages) {
2628
+ if (message.role === "user") {
2629
+ sawAssistantSinceLastUser = false;
2630
+ collapsed.push(message);
2631
+ continue;
2632
+ }
2633
+ if (message.role === "assistant") {
2634
+ if (sawAssistantSinceLastUser) continue;
2635
+ sawAssistantSinceLastUser = true;
2636
+ collapsed.push(message);
2637
+ continue;
2638
+ }
2639
+ collapsed.push(message);
2640
+ }
2641
+ return collapsed;
2642
+ }
2643
+ function sanitizeHistoryMessage(agentType, message) {
2644
+ if (!message || message.role !== "user" && message.role !== "assistant" && message.role !== "system") {
2645
+ return null;
2646
+ }
2647
+ const content = cleanupHistoryContent(agentType, message.role, message.content);
2648
+ if (!content) return null;
2649
+ return {
2650
+ ...message,
2651
+ content
2652
+ };
2653
+ }
2557
2654
  function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
2558
2655
  try {
2559
2656
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
2560
- const dir = path5.join(HISTORY_DIR, sanitized);
2657
+ const dir = path7.join(HISTORY_DIR, sanitized);
2561
2658
  if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
2562
2659
  const sanitizedInstance = historySessionId?.replace(/[^a-zA-Z0-9_-]/g, "_");
2563
2660
  const files = fs3.readdirSync(dir).filter((f) => {
@@ -2568,23 +2665,37 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
2568
2665
  return true;
2569
2666
  }).sort().reverse();
2570
2667
  const allMessages = [];
2571
- const needed = offset + limit + 1;
2668
+ const seen = /* @__PURE__ */ new Set();
2572
2669
  for (const file2 of files) {
2573
- if (allMessages.length >= needed) break;
2574
- const filePath = path5.join(dir, file2);
2670
+ const filePath = path7.join(dir, file2);
2575
2671
  const content = fs3.readFileSync(filePath, "utf-8");
2576
2672
  const lines = content.trim().split("\n").filter(Boolean);
2577
- for (let i = lines.length - 1; i >= 0; i--) {
2578
- if (allMessages.length >= needed) break;
2673
+ for (let i = 0; i < lines.length; i++) {
2579
2674
  try {
2580
- allMessages.push(JSON.parse(lines[i]));
2675
+ const parsed = JSON.parse(lines[i]);
2676
+ const sanitizedMessage = sanitizeHistoryMessage(agentType, parsed);
2677
+ if (!sanitizedMessage) continue;
2678
+ const hash2 = buildHistoryMessageHash(agentType, sanitizedMessage);
2679
+ if (seen.has(hash2)) continue;
2680
+ seen.add(hash2);
2681
+ allMessages.push(sanitizedMessage);
2581
2682
  } catch {
2582
2683
  }
2583
2684
  }
2584
2685
  }
2585
- const sliced = allMessages.slice(offset, offset + limit);
2586
- const hasMore = allMessages.length > offset + limit;
2587
- sliced.reverse();
2686
+ allMessages.sort((a, b) => a.receivedAt - b.receivedAt);
2687
+ const chronological = [];
2688
+ let lastTurn = null;
2689
+ for (const message of allMessages) {
2690
+ const previous = chronological[chronological.length - 1];
2691
+ if (isAdjacentHistoryDuplicate(agentType, previous, message)) continue;
2692
+ if (message.role !== "system" && isAdjacentHistoryDuplicate(agentType, lastTurn, message)) continue;
2693
+ chronological.push(message);
2694
+ if (message.role !== "system") lastTurn = message;
2695
+ }
2696
+ const collapsed = collapseReplayAssistantTurns(agentType, chronological);
2697
+ const sliced = collapsed.slice(offset, offset + limit);
2698
+ const hasMore = collapsed.length > offset + limit;
2588
2699
  return { messages: sliced, hasMore };
2589
2700
  } catch {
2590
2701
  return { messages: [], hasMore: false };
@@ -2593,7 +2704,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId) {
2593
2704
  function listSavedHistorySessions(agentType, options = {}) {
2594
2705
  try {
2595
2706
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
2596
- const dir = path5.join(HISTORY_DIR, sanitized);
2707
+ const dir = path7.join(HISTORY_DIR, sanitized);
2597
2708
  if (!fs3.existsSync(dir)) return { sessions: [], hasMore: false };
2598
2709
  const groupedFiles = /* @__PURE__ */ new Map();
2599
2710
  const filePattern = /^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/;
@@ -2614,7 +2725,7 @@ function listSavedHistorySessions(agentType, options = {}) {
2614
2725
  let sessionTitle = "";
2615
2726
  let preview = "";
2616
2727
  for (const file2 of files.sort()) {
2617
- const filePath = path5.join(dir, file2);
2728
+ const filePath = path7.join(dir, file2);
2618
2729
  const content = fs3.readFileSync(filePath, "utf-8");
2619
2730
  const lines = content.split("\n").filter(Boolean);
2620
2731
  for (const line of lines) {
@@ -2654,20 +2765,25 @@ function listSavedHistorySessions(agentType, options = {}) {
2654
2765
  return { sessions: [], hasMore: false };
2655
2766
  }
2656
2767
  }
2657
- var fs3, path5, os5, HISTORY_DIR, RETAIN_DAYS, ChatHistoryWriter;
2768
+ var fs3, path7, os5, HISTORY_DIR, RETAIN_DAYS, CODEX_STARTER_PROMPT_RE, ChatHistoryWriter;
2658
2769
  var init_chat_history = __esm({
2659
2770
  "../../oss/packages/daemon-core/src/config/chat-history.ts"() {
2660
2771
  "use strict";
2661
2772
  fs3 = __toESM(require("fs"));
2662
- path5 = __toESM(require("path"));
2773
+ path7 = __toESM(require("path"));
2663
2774
  os5 = __toESM(require("os"));
2664
- HISTORY_DIR = path5.join(os5.homedir(), ".adhdev", "history");
2775
+ HISTORY_DIR = path7.join(os5.homedir(), ".adhdev", "history");
2665
2776
  RETAIN_DAYS = 30;
2777
+ CODEX_STARTER_PROMPT_RE = /^(?:[›❯]\s*)?(?:Find and fix a bug in @filename|Improve documentation in @filename|Write tests for @filename|Explain this codebase|Summarize recent commits|Implement \{feature\}|Use \/skills(?: to list available skills)?|Run \/review on my current changes)$/i;
2666
2778
  ChatHistoryWriter = class {
2667
2779
  /** Last seen message count per agent (deduplication) */
2668
2780
  lastSeenCounts = /* @__PURE__ */ new Map();
2669
2781
  /** Last seen message hash per agent (deduplication) */
2670
2782
  lastSeenHashes = /* @__PURE__ */ new Map();
2783
+ /** Last appended normalized message signature per agent/session */
2784
+ lastSeenSignatures = /* @__PURE__ */ new Map();
2785
+ /** Last appended normalized non-system turn signature per agent/session */
2786
+ lastSeenTurnSignatures = /* @__PURE__ */ new Map();
2671
2787
  rotated = false;
2672
2788
  /**
2673
2789
  * Append new messages to history
@@ -2689,14 +2805,36 @@ var init_chat_history = __esm({
2689
2805
  }
2690
2806
  const newMessages = [];
2691
2807
  for (const msg of messages) {
2692
- const hash2 = msg.historyDedupKey || `${msg.kind || "standard"}:${msg.role}:${(msg.content || "").slice(0, 50)}`;
2808
+ const role = msg.role;
2809
+ if (role !== "user" && role !== "assistant" && role !== "system") continue;
2810
+ const content = cleanupHistoryContent(agentType, role, msg.content || "");
2811
+ if (!content) continue;
2812
+ const receivedAt = msg.receivedAt || Date.now();
2813
+ const hash2 = buildHistoryMessageHash(agentType, {
2814
+ role,
2815
+ content,
2816
+ receivedAt,
2817
+ kind: typeof msg.kind === "string" ? msg.kind : void 0,
2818
+ historyDedupKey: msg.historyDedupKey
2819
+ });
2820
+ const signature = buildHistoryMessageSignature(agentType, {
2821
+ role,
2822
+ content,
2823
+ kind: typeof msg.kind === "string" ? msg.kind : void 0
2824
+ });
2693
2825
  if (seenHashes.has(hash2)) continue;
2826
+ if (this.lastSeenSignatures.get(dedupKey) === signature) continue;
2827
+ if (role !== "system" && this.lastSeenTurnSignatures.get(dedupKey) === signature) continue;
2694
2828
  seenHashes.add(hash2);
2829
+ this.lastSeenSignatures.set(dedupKey, signature);
2830
+ if (role !== "system") {
2831
+ this.lastSeenTurnSignatures.set(dedupKey, signature);
2832
+ }
2695
2833
  newMessages.push({
2696
- ts: new Date(msg.receivedAt || Date.now()).toISOString(),
2697
- receivedAt: msg.receivedAt || Date.now(),
2698
- role: msg.role,
2699
- content: msg.content || "",
2834
+ ts: new Date(receivedAt).toISOString(),
2835
+ receivedAt,
2836
+ role,
2837
+ content,
2700
2838
  kind: typeof msg.kind === "string" ? msg.kind : void 0,
2701
2839
  senderName: typeof msg.senderName === "string" ? msg.senderName : void 0,
2702
2840
  agent: agentType,
@@ -2706,16 +2844,18 @@ var init_chat_history = __esm({
2706
2844
  });
2707
2845
  }
2708
2846
  if (newMessages.length === 0) return;
2709
- const dir = path5.join(HISTORY_DIR, this.sanitize(agentType));
2847
+ const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
2710
2848
  fs3.mkdirSync(dir, { recursive: true });
2711
2849
  const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2712
2850
  const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
2713
- const filePath = path5.join(dir, `${filePrefix}${date5}.jsonl`);
2851
+ const filePath = path7.join(dir, `${filePrefix}${date5}.jsonl`);
2714
2852
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
2715
2853
  fs3.appendFileSync(filePath, lines, "utf-8");
2716
2854
  const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
2717
2855
  if (messages.length < prevCount * 0.5 && prevCount > 3) {
2718
2856
  seenHashes.clear();
2857
+ this.lastSeenSignatures.delete(dedupKey);
2858
+ this.lastSeenTurnSignatures.delete(dedupKey);
2719
2859
  for (const msg of messages) {
2720
2860
  seenHashes.add(msg.historyDedupKey || `${msg.kind || "standard"}:${msg.role}:${(msg.content || "").slice(0, 50)}`);
2721
2861
  }
@@ -2729,6 +2869,54 @@ var init_chat_history = __esm({
2729
2869
  } catch {
2730
2870
  }
2731
2871
  }
2872
+ seedSessionHistory(agentType, messages = [], historySessionId, instanceId) {
2873
+ const effectiveHistoryKey = historySessionId || instanceId;
2874
+ const dedupKey = effectiveHistoryKey ? `${agentType}:${effectiveHistoryKey}` : agentType;
2875
+ const seenHashes = /* @__PURE__ */ new Set();
2876
+ for (const raw of messages) {
2877
+ const role = raw?.role;
2878
+ if (role !== "user" && role !== "assistant" && role !== "system") continue;
2879
+ const content = cleanupHistoryContent(agentType, role, raw?.content || "");
2880
+ if (!content) continue;
2881
+ seenHashes.add(buildHistoryMessageHash(agentType, {
2882
+ role,
2883
+ content,
2884
+ receivedAt: raw?.receivedAt || 0,
2885
+ kind: typeof raw?.kind === "string" ? raw.kind : void 0,
2886
+ historyDedupKey: raw?.historyDedupKey
2887
+ }));
2888
+ }
2889
+ this.lastSeenHashes.set(dedupKey, seenHashes);
2890
+ this.lastSeenCounts.set(dedupKey, messages.length);
2891
+ const lastMessage = [...messages].reverse().find((raw) => {
2892
+ const role = raw?.role;
2893
+ if (role !== "user" && role !== "assistant" && role !== "system") return false;
2894
+ return !!cleanupHistoryContent(agentType, role, raw?.content || "");
2895
+ });
2896
+ const lastTurnMessage = [...messages].reverse().find((raw) => {
2897
+ const role = raw?.role;
2898
+ if (role !== "user" && role !== "assistant") return false;
2899
+ return !!cleanupHistoryContent(agentType, role, raw?.content || "");
2900
+ });
2901
+ if (lastMessage) {
2902
+ this.lastSeenSignatures.set(dedupKey, buildHistoryMessageSignature(agentType, {
2903
+ role: lastMessage.role,
2904
+ content: lastMessage.content,
2905
+ kind: typeof lastMessage.kind === "string" ? lastMessage.kind : void 0
2906
+ }));
2907
+ } else {
2908
+ this.lastSeenSignatures.delete(dedupKey);
2909
+ }
2910
+ if (lastTurnMessage) {
2911
+ this.lastSeenTurnSignatures.set(dedupKey, buildHistoryMessageSignature(agentType, {
2912
+ role: lastTurnMessage.role,
2913
+ content: lastTurnMessage.content,
2914
+ kind: typeof lastTurnMessage.kind === "string" ? lastTurnMessage.kind : void 0
2915
+ }));
2916
+ } else {
2917
+ this.lastSeenTurnSignatures.delete(dedupKey);
2918
+ }
2919
+ }
2732
2920
  appendSystemMarker(agentType, content, options = {}) {
2733
2921
  this.appendNewMessages(
2734
2922
  agentType,
@@ -2759,19 +2947,29 @@ var init_chat_history = __esm({
2759
2947
  this.lastSeenHashes.set(toDedupKey, nextHashes);
2760
2948
  this.lastSeenHashes.delete(fromDedupKey);
2761
2949
  }
2950
+ const fromSignature = this.lastSeenSignatures.get(fromDedupKey);
2951
+ if (fromSignature) {
2952
+ this.lastSeenSignatures.set(toDedupKey, fromSignature);
2953
+ this.lastSeenSignatures.delete(fromDedupKey);
2954
+ }
2955
+ const fromTurnSignature = this.lastSeenTurnSignatures.get(fromDedupKey);
2956
+ if (fromTurnSignature) {
2957
+ this.lastSeenTurnSignatures.set(toDedupKey, fromTurnSignature);
2958
+ this.lastSeenTurnSignatures.delete(fromDedupKey);
2959
+ }
2762
2960
  const fromCount = this.lastSeenCounts.get(fromDedupKey);
2763
2961
  if (typeof fromCount === "number") {
2764
2962
  this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
2765
2963
  this.lastSeenCounts.delete(fromDedupKey);
2766
2964
  }
2767
- const dir = path5.join(HISTORY_DIR, this.sanitize(agentType));
2965
+ const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
2768
2966
  if (!fs3.existsSync(dir)) return;
2769
2967
  const fromPrefix = `${this.sanitize(fromId)}_`;
2770
2968
  const toPrefix = `${this.sanitize(toId)}_`;
2771
2969
  const files = fs3.readdirSync(dir).filter((file2) => file2.startsWith(fromPrefix) && file2.endsWith(".jsonl"));
2772
2970
  for (const file2 of files) {
2773
- const sourcePath = path5.join(dir, file2);
2774
- const targetPath = path5.join(dir, `${toPrefix}${file2.slice(fromPrefix.length)}`);
2971
+ const sourcePath = path7.join(dir, file2);
2972
+ const targetPath = path7.join(dir, `${toPrefix}${file2.slice(fromPrefix.length)}`);
2775
2973
  const sourceLines = fs3.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
2776
2974
  const rewritten = sourceLines.map((line) => {
2777
2975
  try {
@@ -2800,10 +2998,61 @@ var init_chat_history = __esm({
2800
2998
  } catch {
2801
2999
  }
2802
3000
  }
3001
+ compactHistorySession(agentType, historySessionId) {
3002
+ const sessionId = String(historySessionId || "").trim();
3003
+ if (!sessionId) return;
3004
+ try {
3005
+ const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
3006
+ if (!fs3.existsSync(dir)) return;
3007
+ const prefix = `${this.sanitize(sessionId)}_`;
3008
+ const files = fs3.readdirSync(dir).filter((file2) => file2.startsWith(prefix) && file2.endsWith(".jsonl")).sort();
3009
+ const seen = /* @__PURE__ */ new Set();
3010
+ for (const file2 of files) {
3011
+ const filePath = path7.join(dir, file2);
3012
+ const lines = fs3.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
3013
+ const next = [];
3014
+ for (const line of lines) {
3015
+ let parsed = null;
3016
+ try {
3017
+ parsed = JSON.parse(line);
3018
+ } catch {
3019
+ parsed = null;
3020
+ }
3021
+ if (!parsed || parsed.historySessionId !== sessionId) continue;
3022
+ const sanitized = sanitizeHistoryMessage(agentType, parsed);
3023
+ if (!sanitized) continue;
3024
+ const hash2 = buildHistoryMessageHash(agentType, sanitized);
3025
+ if (seen.has(hash2)) continue;
3026
+ seen.add(hash2);
3027
+ next.push(sanitized);
3028
+ }
3029
+ next.sort((a, b) => a.receivedAt - b.receivedAt);
3030
+ const dedupedAdjacent = [];
3031
+ let lastTurn = null;
3032
+ for (const entry of next) {
3033
+ const previous = dedupedAdjacent[dedupedAdjacent.length - 1];
3034
+ if (isAdjacentHistoryDuplicate(agentType, previous, entry)) continue;
3035
+ if (entry.role !== "system" && isAdjacentHistoryDuplicate(agentType, lastTurn, entry)) continue;
3036
+ dedupedAdjacent.push(entry);
3037
+ if (entry.role !== "system") lastTurn = entry;
3038
+ }
3039
+ const collapsed = collapseReplayAssistantTurns(agentType, dedupedAdjacent);
3040
+ if (collapsed.length === 0) {
3041
+ fs3.unlinkSync(filePath);
3042
+ continue;
3043
+ }
3044
+ fs3.writeFileSync(filePath, `${collapsed.map((entry) => JSON.stringify(entry)).join("\n")}
3045
+ `, "utf-8");
3046
+ }
3047
+ } catch {
3048
+ }
3049
+ }
2803
3050
  /** Called when agent session is explicitly changed */
2804
3051
  onSessionChange(agentType) {
2805
3052
  this.lastSeenHashes.delete(agentType);
2806
3053
  this.lastSeenCounts.delete(agentType);
3054
+ this.lastSeenSignatures.delete(agentType);
3055
+ this.lastSeenTurnSignatures.delete(agentType);
2807
3056
  }
2808
3057
  /** Delete history files older than 30 days */
2809
3058
  async rotateOldFiles() {
@@ -2812,10 +3061,10 @@ var init_chat_history = __esm({
2812
3061
  const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
2813
3062
  const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
2814
3063
  for (const dir of agentDirs) {
2815
- const dirPath = path5.join(HISTORY_DIR, dir.name);
3064
+ const dirPath = path7.join(HISTORY_DIR, dir.name);
2816
3065
  const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
2817
3066
  for (const file2 of files) {
2818
- const filePath = path5.join(dirPath, file2);
3067
+ const filePath = path7.join(dirPath, file2);
2819
3068
  const stat4 = fs3.statSync(filePath);
2820
3069
  if (stat4.mtimeMs < cutoff) {
2821
3070
  fs3.unlinkSync(filePath);
@@ -4672,6 +4921,46 @@ function didProviderConfirmSend(result) {
4672
4921
  if (!parsed || typeof parsed !== "object") return false;
4673
4922
  return parsed.sent === true || parsed.success === true || parsed.ok === true || parsed.submitted === true || parsed.dispatched === true;
4674
4923
  }
4924
+ async function readExtensionChatState(h) {
4925
+ try {
4926
+ const evalResult = await h.evaluateProviderScript("readChat", void 0, 5e4);
4927
+ if (!evalResult?.result) return null;
4928
+ const parsed = parseMaybeJson(evalResult.result);
4929
+ return parsed && typeof parsed === "object" ? parsed : null;
4930
+ } catch {
4931
+ return null;
4932
+ }
4933
+ }
4934
+ function getStateMessageCount(state) {
4935
+ return Array.isArray(state?.messages) ? state.messages.length : 0;
4936
+ }
4937
+ function getStateLastSignature(state) {
4938
+ const messages = Array.isArray(state?.messages) ? state.messages : [];
4939
+ const last = messages[messages.length - 1];
4940
+ if (!last) return "";
4941
+ return `${last.role || ""}:${String(last.content || "").replace(/\s+/g, " ").trim()}`;
4942
+ }
4943
+ async function getStableExtensionBaseline(h) {
4944
+ const first = await readExtensionChatState(h);
4945
+ if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
4946
+ await new Promise((resolve16) => setTimeout(resolve16, 150));
4947
+ const second = await readExtensionChatState(h);
4948
+ return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
4949
+ }
4950
+ async function verifyExtensionSendObserved(h, before) {
4951
+ const beforeCount = getStateMessageCount(before);
4952
+ const beforeSignature = getStateLastSignature(before);
4953
+ for (let attempt = 0; attempt < 12; attempt += 1) {
4954
+ await new Promise((resolve16) => setTimeout(resolve16, 250));
4955
+ const state = await readExtensionChatState(h);
4956
+ if (state?.status === "waiting_approval") return true;
4957
+ const afterCount = getStateMessageCount(state);
4958
+ const afterSignature = getStateLastSignature(state);
4959
+ if (afterCount > beforeCount) return true;
4960
+ if (afterSignature && afterSignature !== beforeSignature) return true;
4961
+ }
4962
+ return false;
4963
+ }
4675
4964
  async function handleChatHistory(h, args) {
4676
4965
  const { agentType, offset, limit } = args;
4677
4966
  const historySessionId = getHistorySessionId(h, args);
@@ -4852,12 +5141,17 @@ async function handleSendChat(h, args) {
4852
5141
  if (isExtensionTransport(transport)) {
4853
5142
  _log(`Extension: ${provider?.type || "unknown_extension"}`);
4854
5143
  try {
5144
+ const beforeState = await getStableExtensionBaseline(h);
4855
5145
  const evalResult = await h.evaluateProviderScript("sendMessage", { message: text }, 3e4);
4856
5146
  if (evalResult?.result) {
4857
5147
  const parsed = parseMaybeJson(evalResult.result);
4858
5148
  if (didProviderConfirmSend(parsed)) {
4859
- _log(`Extension script sent OK`);
4860
- return _logSendSuccess("extension-script");
5149
+ const observed = await verifyExtensionSendObserved(h, beforeState);
5150
+ if (observed) {
5151
+ _log(`Extension script sent OK`);
5152
+ return _logSendSuccess("extension-script");
5153
+ }
5154
+ _log(`Extension script reported send but no chat-state change was observed`);
4861
5155
  }
4862
5156
  if (parsed?.needsTypeAndSend) {
4863
5157
  _log(`Extension needsTypeAndSend \u2192 AgentStreamManager`);
@@ -5023,6 +5317,14 @@ async function handleListChats(h, args) {
5023
5317
  } catch {
5024
5318
  }
5025
5319
  }
5320
+ if (parsed?.sessions && Array.isArray(parsed.sessions)) {
5321
+ LOG.info("Command", `[list_chats] OK: ${parsed.sessions.length} chats`);
5322
+ return { success: true, chats: parsed.sessions };
5323
+ }
5324
+ if (parsed?.chats && Array.isArray(parsed.chats)) {
5325
+ LOG.info("Command", `[list_chats] OK: ${parsed.chats.length} chats`);
5326
+ return { success: true, chats: parsed.chats };
5327
+ }
5026
5328
  if (Array.isArray(parsed)) {
5027
5329
  LOG.info("Command", `[list_chats] OK: ${parsed.length} chats`);
5028
5330
  return { success: true, chats: parsed };
@@ -5092,7 +5394,13 @@ async function handleSwitchChat(h, args) {
5092
5394
  } catch (e) {
5093
5395
  return { success: false, error: `webviewSwitchSession failed: ${e.message}` };
5094
5396
  }
5095
- const script = h.getProviderScript("switchSession", { SESSION_ID: JSON.stringify(sessionId) }) || h.getProviderScript("switch_session", { SESSION_ID: JSON.stringify(sessionId) });
5397
+ const switchParams = {
5398
+ sessionId,
5399
+ title: sessionId,
5400
+ id: sessionId,
5401
+ SESSION_ID: JSON.stringify(sessionId)
5402
+ };
5403
+ const script = h.getProviderScript("switchSession", switchParams) || h.getProviderScript("switch_session", switchParams);
5096
5404
  if (!script) return { success: false, error: "switch_session script not available" };
5097
5405
  try {
5098
5406
  const raw = await cdp.evaluate(script, 15e3);
@@ -5171,8 +5479,8 @@ async function handleSetMode(h, args) {
5171
5479
  const adapter = getTargetedCliAdapter(h, args, provider?.type);
5172
5480
  if (adapter) {
5173
5481
  const acpInstance = adapter._acpInstance;
5174
- if (acpInstance && typeof acpInstance.onEvent === "function") {
5175
- acpInstance.onEvent("set_mode", { mode });
5482
+ if (acpInstance && typeof acpInstance.setMode === "function") {
5483
+ await acpInstance.setMode(mode);
5176
5484
  return { success: true, mode };
5177
5485
  }
5178
5486
  }
@@ -5229,9 +5537,9 @@ async function handleChangeModel(h, args) {
5229
5537
  LOG.info("Command", `[change_model] ACP adapter found: ${!!adapter}, type=${adapter?.cliType}, hasAcpInstance=${!!adapter?._acpInstance}`);
5230
5538
  if (adapter) {
5231
5539
  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`);
5540
+ if (acpInstance && typeof acpInstance.setConfigOption === "function") {
5541
+ await acpInstance.setConfigOption("model", model);
5542
+ LOG.info("Command", `[change_model] Updated ACP model to ${model}`);
5235
5543
  return { success: true, model };
5236
5544
  }
5237
5545
  }
@@ -5348,9 +5656,21 @@ async function handleResolveAction(h, args) {
5348
5656
  return { success: true, buttonIndex, button: buttons[buttonIndex] ?? button };
5349
5657
  }
5350
5658
  if (isExtensionTransport(transport) && h.agentStream && h.getCdp() && h.currentSession?.sessionId) {
5351
- const ok = await h.agentStream.resolveSessionAction(h.getCdp(), h.currentSession.sessionId, action);
5659
+ const ok = await h.agentStream.resolveSessionAction(h.getCdp(), h.currentSession.sessionId, action, button);
5352
5660
  return { success: ok };
5353
5661
  }
5662
+ if (transport === "acp") {
5663
+ const adapter = getTargetedCliAdapter(h, args, provider?.type);
5664
+ const acpInstance = adapter?._acpInstance;
5665
+ if (!acpInstance) return { success: false, error: "ACP instance not found" };
5666
+ try {
5667
+ await acpInstance.resolvePermission(action === "approve" || action === "accept" || action === "always");
5668
+ LOG.info("Command", `[resolveAction] ACP \u2192 ${action}`);
5669
+ return { success: true, action };
5670
+ } catch (e) {
5671
+ return { success: false, error: e?.message || "ACP resolve action failed" };
5672
+ }
5673
+ }
5354
5674
  if (provider?.scripts?.webviewResolveAction || provider?.scripts?.webview_resolve_action) {
5355
5675
  const script = h.getProviderScript("webviewResolveAction", { action, button, buttonText: button }) || h.getProviderScript("webview_resolve_action", { action, button, buttonText: button });
5356
5676
  if (script) {
@@ -5653,25 +5973,25 @@ function resolveSafePath(requestedPath) {
5653
5973
  const inputPath = rawPath || ".";
5654
5974
  const home = os6.homedir();
5655
5975
  if (inputPath.startsWith("~")) {
5656
- return path6.resolve(path6.join(home, inputPath.slice(1)));
5976
+ return path8.resolve(path8.join(home, inputPath.slice(1)));
5657
5977
  }
5658
5978
  if (process.platform === "win32") {
5659
5979
  const normalized = normalizeWindowsRequestedPath(inputPath);
5660
- if (path6.win32.isAbsolute(normalized)) {
5661
- return path6.win32.normalize(normalized);
5980
+ if (path8.win32.isAbsolute(normalized)) {
5981
+ return path8.win32.normalize(normalized);
5662
5982
  }
5663
- return path6.win32.resolve(normalized);
5983
+ return path8.win32.resolve(normalized);
5664
5984
  }
5665
- if (path6.isAbsolute(inputPath)) {
5666
- return path6.normalize(inputPath);
5985
+ if (path8.isAbsolute(inputPath)) {
5986
+ return path8.normalize(inputPath);
5667
5987
  }
5668
- return path6.resolve(inputPath);
5988
+ return path8.resolve(inputPath);
5669
5989
  }
5670
5990
  function listDirectoryEntriesSafe(dirPath) {
5671
5991
  const entries = fs4.readdirSync(dirPath, { withFileTypes: true });
5672
5992
  const files = [];
5673
5993
  for (const entry of entries) {
5674
- const entryPath = path6.join(dirPath, entry.name);
5994
+ const entryPath = path8.join(dirPath, entry.name);
5675
5995
  try {
5676
5996
  if (entry.isDirectory()) {
5677
5997
  files.push({ name: entry.name, type: "directory" });
@@ -5710,7 +6030,7 @@ async function handleFileRead(h, args) {
5710
6030
  async function handleFileWrite(h, args) {
5711
6031
  try {
5712
6032
  const filePath = resolveSafePath(args?.path);
5713
- fs4.mkdirSync(path6.dirname(filePath), { recursive: true });
6033
+ fs4.mkdirSync(path8.dirname(filePath), { recursive: true });
5714
6034
  fs4.writeFileSync(filePath, args?.content || "", "utf-8");
5715
6035
  return { success: true, path: filePath };
5716
6036
  } catch (e) {
@@ -5735,12 +6055,12 @@ async function handleFileListBrowse(h, args) {
5735
6055
  return { success: false, error: e.message };
5736
6056
  }
5737
6057
  }
5738
- var fs4, path6, os6, KEY_TO_VK;
6058
+ var fs4, path8, os6, KEY_TO_VK;
5739
6059
  var init_cdp_commands = __esm({
5740
6060
  "../../oss/packages/daemon-core/src/commands/cdp-commands.ts"() {
5741
6061
  "use strict";
5742
6062
  fs4 = __toESM(require("fs"));
5743
- path6 = __toESM(require("path"));
6063
+ path8 = __toESM(require("path"));
5744
6064
  os6 = __toESM(require("os"));
5745
6065
  KEY_TO_VK = {
5746
6066
  Backspace: 8,
@@ -5841,7 +6161,7 @@ function handleGetProviderSettings(h, args) {
5841
6161
  }
5842
6162
  return { success: true, settings: allSettings, values: allValues };
5843
6163
  }
5844
- function handleSetProviderSetting(h, args) {
6164
+ async function handleSetProviderSetting(h, args) {
5845
6165
  const loader = h.ctx.providerLoader;
5846
6166
  const { providerType, key, value } = args || {};
5847
6167
  if (!providerType || !key || value === void 0) {
@@ -5854,6 +6174,7 @@ function handleSetProviderSetting(h, args) {
5854
6174
  const updated = h.ctx.instanceManager.updateInstanceSettings(providerType, allSettings);
5855
6175
  LOG.info("Command", `[set_provider_setting] ${providerType}.${key}=${JSON.stringify(value)} \u2192 ${updated} instance(s) updated`);
5856
6176
  }
6177
+ await h.ctx.onProviderSettingChanged?.(providerType, key, value);
5857
6178
  return { success: true, providerType, key, value };
5858
6179
  }
5859
6180
  return { success: false, error: `Failed to set ${providerType}.${key} \u2014 invalid key, value, or not a public setting` };
@@ -6640,7 +6961,7 @@ var init_handler = __esm({
6640
6961
  try {
6641
6962
  const http3 = await import("http");
6642
6963
  const postData = JSON.stringify(body);
6643
- const result = await new Promise((resolve13, reject) => {
6964
+ const result = await new Promise((resolve16, reject) => {
6644
6965
  const req = http3.request({
6645
6966
  hostname: "127.0.0.1",
6646
6967
  port: 19280,
@@ -6652,9 +6973,9 @@ var init_handler = __esm({
6652
6973
  res.on("data", (chunk) => data += chunk);
6653
6974
  res.on("end", () => {
6654
6975
  try {
6655
- resolve13(JSON.parse(data));
6976
+ resolve16(JSON.parse(data));
6656
6977
  } catch {
6657
- resolve13({ raw: data });
6978
+ resolve16({ raw: data });
6658
6979
  }
6659
6980
  });
6660
6981
  });
@@ -6672,15 +6993,15 @@ var init_handler = __esm({
6672
6993
  if (!providerType) return { success: false, error: "providerType required" };
6673
6994
  try {
6674
6995
  const http3 = await import("http");
6675
- const result = await new Promise((resolve13, reject) => {
6996
+ const result = await new Promise((resolve16, reject) => {
6676
6997
  http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
6677
6998
  let data = "";
6678
6999
  res.on("data", (chunk) => data += chunk);
6679
7000
  res.on("end", () => {
6680
7001
  try {
6681
- resolve13(JSON.parse(data));
7002
+ resolve16(JSON.parse(data));
6682
7003
  } catch {
6683
- resolve13({ raw: data });
7004
+ resolve16({ raw: data });
6684
7005
  }
6685
7006
  });
6686
7007
  }).on("error", reject);
@@ -6694,7 +7015,7 @@ var init_handler = __esm({
6694
7015
  try {
6695
7016
  const http3 = await import("http");
6696
7017
  const postData = JSON.stringify(args || {});
6697
- const result = await new Promise((resolve13, reject) => {
7018
+ const result = await new Promise((resolve16, reject) => {
6698
7019
  const req = http3.request({
6699
7020
  hostname: "127.0.0.1",
6700
7021
  port: 19280,
@@ -6706,9 +7027,9 @@ var init_handler = __esm({
6706
7027
  res.on("data", (chunk) => data += chunk);
6707
7028
  res.on("end", () => {
6708
7029
  try {
6709
- resolve13(JSON.parse(data));
7030
+ resolve16(JSON.parse(data));
6710
7031
  } catch {
6711
- resolve13({ raw: data });
7032
+ resolve16({ raw: data });
6712
7033
  }
6713
7034
  });
6714
7035
  });
@@ -7030,10 +7351,12 @@ function sanitizeSpawnEnv(baseEnv, overrides) {
7030
7351
  env[key] = value;
7031
7352
  }
7032
7353
  for (const key of Object.keys(env)) {
7033
- if (key === "INIT_CWD" || key === "npm_command" || key === "npm_execpath" || key === "npm_node_execpath" || key.startsWith("npm_") || key.startsWith("npm_config_") || key.startsWith("npm_package_") || key.startsWith("npm_lifecycle_") || key.startsWith("PNPM_") || key.startsWith("YARN_") || key.startsWith("BUN_")) {
7354
+ if (key === "INIT_CWD" || key === "npm_command" || key === "npm_execpath" || key === "npm_node_execpath" || key.startsWith("npm_") || key.startsWith("npm_config_") || key.startsWith("npm_package_") || key.startsWith("npm_lifecycle_") || key.startsWith("PNPM_") || key.startsWith("YARN_") || key.startsWith("BUN_") || key.startsWith("VSCODE_") || key.startsWith("ELECTRON_")) {
7034
7355
  delete env[key];
7035
7356
  }
7036
7357
  }
7358
+ delete env.CODEX_THREAD_ID;
7359
+ delete env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE;
7037
7360
  applyTerminalColorEnv(env);
7038
7361
  return env;
7039
7362
  }
@@ -7345,16 +7668,22 @@ function computeTerminalQueryTail(buffer) {
7345
7668
  return "";
7346
7669
  }
7347
7670
  function findBinary(name) {
7671
+ const trimmed = String(name || "").trim();
7672
+ if (!trimmed) return trimmed;
7673
+ const expanded = trimmed.startsWith("~") ? path9.join(os9.homedir(), trimmed.slice(1)) : trimmed;
7674
+ if (path9.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
7675
+ return path9.isAbsolute(expanded) ? expanded : path9.resolve(expanded);
7676
+ }
7348
7677
  const isWin = os9.platform() === "win32";
7349
7678
  try {
7350
- const cmd = isWin ? `where ${name}` : `which ${name}`;
7679
+ const cmd = isWin ? `where ${trimmed}` : `which ${trimmed}`;
7351
7680
  return (0, import_child_process4.execSync)(cmd, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n")[0].trim();
7352
7681
  } catch {
7353
- return isWin ? `${name}.cmd` : name;
7682
+ return isWin ? `${trimmed}.cmd` : trimmed;
7354
7683
  }
7355
7684
  }
7356
7685
  function isScriptBinary(binaryPath) {
7357
- if (!path7.isAbsolute(binaryPath)) return false;
7686
+ if (!path9.isAbsolute(binaryPath)) return false;
7358
7687
  try {
7359
7688
  const fs18 = require("fs");
7360
7689
  const resolved = fs18.realpathSync(binaryPath);
@@ -7370,7 +7699,7 @@ function isScriptBinary(binaryPath) {
7370
7699
  }
7371
7700
  }
7372
7701
  function looksLikeMachOOrElf(filePath) {
7373
- if (!path7.isAbsolute(filePath)) return false;
7702
+ if (!path9.isAbsolute(filePath)) return false;
7374
7703
  try {
7375
7704
  const fs18 = require("fs");
7376
7705
  const resolved = fs18.realpathSync(filePath);
@@ -7494,12 +7823,12 @@ function normalizeCliProviderForRuntime(raw) {
7494
7823
  }
7495
7824
  };
7496
7825
  }
7497
- var os9, path7, import_child_process4, buildCliSpawnEnv, ProviderCliAdapter;
7826
+ var os9, path9, import_child_process4, buildCliSpawnEnv, ProviderCliAdapter;
7498
7827
  var init_provider_cli_adapter = __esm({
7499
7828
  "../../oss/packages/daemon-core/src/cli-adapters/provider-cli-adapter.ts"() {
7500
7829
  "use strict";
7501
7830
  os9 = __toESM(require("os"));
7502
- path7 = __toESM(require("path"));
7831
+ path9 = __toESM(require("path"));
7503
7832
  import_child_process4 = require("child_process");
7504
7833
  init_logger();
7505
7834
  init_terminal_screen();
@@ -7854,16 +8183,17 @@ var init_provider_cli_adapter = __esm({
7854
8183
  async spawn() {
7855
8184
  if (this.ptyProcess) return;
7856
8185
  const { spawn: spawnConfig } = this.provider;
7857
- const binaryPath = findBinary(spawnConfig.command);
8186
+ const configuredCommand = typeof this.runtimeSettings.executablePath === "string" && this.runtimeSettings.executablePath.trim() ? this.runtimeSettings.executablePath.trim() : spawnConfig.command;
8187
+ const binaryPath = findBinary(configuredCommand);
7858
8188
  const isWin = os9.platform() === "win32";
7859
8189
  const allArgs = [...spawnConfig.args, ...this.extraArgs];
7860
8190
  LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
7861
8191
  this.resetTraceSession();
7862
8192
  let shellCmd;
7863
8193
  let shellArgs;
7864
- const useShellUnix = !isWin && (!!spawnConfig.shell || !path7.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
8194
+ const useShellUnix = !isWin && (!!spawnConfig.shell || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
7865
8195
  const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
7866
- const useShellWin = !!spawnConfig.shell || isCmdShim || !path7.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
8196
+ const useShellWin = !!spawnConfig.shell || isCmdShim || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
7867
8197
  const useShell = isWin ? useShellWin : useShellUnix;
7868
8198
  if (useShell) {
7869
8199
  if (!spawnConfig.shell && !isWin) {
@@ -8108,6 +8438,9 @@ var init_provider_cli_adapter = __esm({
8108
8438
  looksLikeVisibleIdlePrompt(screenText) {
8109
8439
  const text = String(screenText || "");
8110
8440
  if (!text.trim()) return false;
8441
+ if (this.cliType === "codex-cli" && /(^|\n)\s*[❯›>]\s+(?:Find and fix a bug in @filename|Improve documentation in @filename|Use \/skills|Write tests for @filename|Explain this codebase|Summarize recent commits|Implement \{feature\}|Run \/review on my current changes)(?:\n|$)/im.test(text)) {
8442
+ return true;
8443
+ }
8111
8444
  return /(^|\n)\s*[❯›>]\s*(?:\n|$)/m.test(text) || /⏎\s+send/i.test(text) || /\?\s*for\s*shortcuts/i.test(text) || /Type your message(?:\s+or\s+@path\/to\/file)?/i.test(text) || /workspace\s*\(\/directory\)/i.test(text) || /for\s*shortcuts/i.test(text);
8112
8445
  }
8113
8446
  findLastMatchingLineIndex(lines, predicate) {
@@ -8237,7 +8570,7 @@ var init_provider_cli_adapter = __esm({
8237
8570
  `[${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
8571
  );
8239
8572
  }
8240
- await new Promise((resolve13) => setTimeout(resolve13, 50));
8573
+ await new Promise((resolve16) => setTimeout(resolve16, 50));
8241
8574
  }
8242
8575
  const finalScreenText = this.terminalScreen.getText() || "";
8243
8576
  LOG.warn(
@@ -8748,7 +9081,7 @@ ${data.message || ""}`.trim();
8748
9081
  const deadline = Date.now() + 1e4;
8749
9082
  while (this.startupParseGate && Date.now() < deadline) {
8750
9083
  this.resolveStartupState("send_wait");
8751
- await new Promise((resolve13) => setTimeout(resolve13, 50));
9084
+ await new Promise((resolve16) => setTimeout(resolve16, 50));
8752
9085
  }
8753
9086
  }
8754
9087
  await this.waitForInteractivePrompt();
@@ -8973,17 +9306,17 @@ ${data.message || ""}`.trim();
8973
9306
  }
8974
9307
  }
8975
9308
  waitForStopped(timeoutMs) {
8976
- return new Promise((resolve13) => {
9309
+ return new Promise((resolve16) => {
8977
9310
  const startedAt = Date.now();
8978
9311
  const timer = setInterval(() => {
8979
9312
  if (!this.ptyProcess || this.currentStatus === "stopped") {
8980
9313
  clearInterval(timer);
8981
- resolve13(true);
9314
+ resolve16(true);
8982
9315
  return;
8983
9316
  }
8984
9317
  if (Date.now() - startedAt >= timeoutMs) {
8985
9318
  clearInterval(timer);
8986
- resolve13(false);
9319
+ resolve16(false);
8987
9320
  }
8988
9321
  }, 100);
8989
9322
  });
@@ -9271,7 +9604,7 @@ ${data.message || ""}`.trim();
9271
9604
  // ../../oss/packages/daemon-core/src/providers/cli-provider-instance.ts
9272
9605
  function getDatabaseSync() {
9273
9606
  if (CachedDatabaseSync) return CachedDatabaseSync;
9274
- const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path8.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
9607
+ const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path10.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
9275
9608
  const sqliteModule = requireFn(`node:${"sqlite"}`);
9276
9609
  CachedDatabaseSync = sqliteModule.DatabaseSync;
9277
9610
  if (!CachedDatabaseSync) {
@@ -9279,12 +9612,12 @@ function getDatabaseSync() {
9279
9612
  }
9280
9613
  return CachedDatabaseSync;
9281
9614
  }
9282
- var os10, path8, crypto3, fs5, import_node_module, CachedDatabaseSync, CliProviderInstance;
9615
+ var os10, path10, crypto3, fs5, import_node_module, CachedDatabaseSync, CliProviderInstance;
9283
9616
  var init_cli_provider_instance = __esm({
9284
9617
  "../../oss/packages/daemon-core/src/providers/cli-provider-instance.ts"() {
9285
9618
  "use strict";
9286
9619
  os10 = __toESM(require("os"));
9287
- path8 = __toESM(require("path"));
9620
+ path10 = __toESM(require("path"));
9288
9621
  crypto3 = __toESM(require("crypto"));
9289
9622
  fs5 = __toESM(require("fs"));
9290
9623
  import_node_module = require("module");
@@ -9326,6 +9659,7 @@ var init_cli_provider_instance = __esm({
9326
9659
  historyWriter;
9327
9660
  runtimeMessages = [];
9328
9661
  instanceId;
9662
+ suppressIdleHistoryReplay = false;
9329
9663
  presentationMode;
9330
9664
  providerSessionId;
9331
9665
  launchMode;
@@ -9353,7 +9687,15 @@ var init_cli_provider_instance = __esm({
9353
9687
  await this.adapter.spawn();
9354
9688
  this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
9355
9689
  if (this.providerSessionId) {
9690
+ this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
9356
9691
  const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
9692
+ this.historyWriter.seedSessionHistory(
9693
+ this.type,
9694
+ restoredHistory.messages,
9695
+ this.providerSessionId,
9696
+ this.instanceId
9697
+ );
9698
+ this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
9357
9699
  if (restoredHistory.messages.length > 0) {
9358
9700
  this.adapter.seedCommittedMessages(
9359
9701
  restoredHistory.messages.map((message) => ({
@@ -9397,7 +9739,7 @@ var init_cli_provider_instance = __esm({
9397
9739
  } else if (this.type === "codex-cli") {
9398
9740
  probedSessionId = this.probeSessionIdFromConfig({
9399
9741
  dbPath: "~/.codex/state_5.sqlite",
9400
- query: "select id from threads where cwd in ({dirs}) and created_at >= ? and archived = 0 order by created_at desc limit 1",
9742
+ query: "select id from threads where cwd in ({dirs}) and updated_at >= ? and archived = 0 order by updated_at desc limit 1",
9401
9743
  timestampFormat: "unix_s"
9402
9744
  });
9403
9745
  } else if (this.type === "goose-cli") {
@@ -9457,6 +9799,7 @@ var init_cli_provider_instance = __esm({
9457
9799
  const mergedMessages = this.mergeConversationMessages(parsedMessages);
9458
9800
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
9459
9801
  if (parsedMessages.length > 0) {
9802
+ const shouldSkipReplayPersist = this.suppressIdleHistoryReplay && adapterStatus.status === "idle" && parsedStatus?.status === "idle";
9460
9803
  let messagesToSave = parsedMessages;
9461
9804
  if (parsedStatus?.status === "generating" || parsedStatus?.status === "long_generating") {
9462
9805
  const lastIdx = messagesToSave.length - 1;
@@ -9464,7 +9807,7 @@ var init_cli_provider_instance = __esm({
9464
9807
  messagesToSave = messagesToSave.slice(0, lastIdx);
9465
9808
  }
9466
9809
  }
9467
- if (messagesToSave.length > 0) {
9810
+ if (!shouldSkipReplayPersist && messagesToSave.length > 0) {
9468
9811
  this.historyWriter.appendNewMessages(
9469
9812
  this.type,
9470
9813
  messagesToSave,
@@ -9559,6 +9902,7 @@ var init_cli_provider_instance = __esm({
9559
9902
  if (newStatus !== this.lastStatus) {
9560
9903
  LOG.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
9561
9904
  if (this.lastStatus === "idle" && newStatus === "generating") {
9905
+ this.suppressIdleHistoryReplay = false;
9562
9906
  if (this.completedDebouncePending) {
9563
9907
  LOG.info("CLI", `[${this.type}] cancelled pending completed (resumed generating)`);
9564
9908
  if (this.completedDebounceTimer) {
@@ -9578,6 +9922,7 @@ var init_cli_provider_instance = __esm({
9578
9922
  this.generatingDebounceTimer = null;
9579
9923
  }, 1e3);
9580
9924
  } else if (newStatus === "waiting_approval") {
9925
+ this.suppressIdleHistoryReplay = false;
9581
9926
  if (this.generatingDebouncePending) {
9582
9927
  if (this.generatingDebounceTimer) {
9583
9928
  clearTimeout(this.generatingDebounceTimer);
@@ -10153,10 +10498,10 @@ function mergeDefs(...defs) {
10153
10498
  function cloneDef(schema) {
10154
10499
  return mergeDefs(schema._zod.def);
10155
10500
  }
10156
- function getElementAtPath(obj, path23) {
10157
- if (!path23)
10501
+ function getElementAtPath(obj, path25) {
10502
+ if (!path25)
10158
10503
  return obj;
10159
- return path23.reduce((acc, key) => acc?.[key], obj);
10504
+ return path25.reduce((acc, key) => acc?.[key], obj);
10160
10505
  }
10161
10506
  function promiseAllObject(promisesObj) {
10162
10507
  const keys = Object.keys(promisesObj);
@@ -10468,11 +10813,11 @@ function aborted(x, startIndex = 0) {
10468
10813
  }
10469
10814
  return false;
10470
10815
  }
10471
- function prefixIssues(path23, issues) {
10816
+ function prefixIssues(path25, issues) {
10472
10817
  return issues.map((iss) => {
10473
10818
  var _a2;
10474
10819
  (_a2 = iss).path ?? (_a2.path = []);
10475
- iss.path.unshift(path23);
10820
+ iss.path.unshift(path25);
10476
10821
  return iss;
10477
10822
  });
10478
10823
  }
@@ -10715,7 +11060,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
10715
11060
  }
10716
11061
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
10717
11062
  const result = { errors: [] };
10718
- const processError = (error49, path23 = []) => {
11063
+ const processError = (error49, path25 = []) => {
10719
11064
  var _a2, _b;
10720
11065
  for (const issue2 of error49.issues) {
10721
11066
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -10725,7 +11070,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
10725
11070
  } else if (issue2.code === "invalid_element") {
10726
11071
  processError({ issues: issue2.issues }, issue2.path);
10727
11072
  } else {
10728
- const fullpath = [...path23, ...issue2.path];
11073
+ const fullpath = [...path25, ...issue2.path];
10729
11074
  if (fullpath.length === 0) {
10730
11075
  result.errors.push(mapper(issue2));
10731
11076
  continue;
@@ -10757,8 +11102,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
10757
11102
  }
10758
11103
  function toDotPath(_path) {
10759
11104
  const segs = [];
10760
- const path23 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
10761
- for (const seg of path23) {
11105
+ const path25 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11106
+ for (const seg of path25) {
10762
11107
  if (typeof seg === "number")
10763
11108
  segs.push(`[${seg}]`);
10764
11109
  else if (typeof seg === "symbol")
@@ -23522,13 +23867,13 @@ function resolveRef(ref, ctx) {
23522
23867
  if (!ref.startsWith("#")) {
23523
23868
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
23524
23869
  }
23525
- const path23 = ref.slice(1).split("/").filter(Boolean);
23526
- if (path23.length === 0) {
23870
+ const path25 = ref.slice(1).split("/").filter(Boolean);
23871
+ if (path25.length === 0) {
23527
23872
  return ctx.rootSchema;
23528
23873
  }
23529
23874
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
23530
- if (path23[0] === defsKey) {
23531
- const key = path23[1];
23875
+ if (path25[0] === defsKey) {
23876
+ const key = path25[1];
23532
23877
  if (!key || !ctx.defs[key]) {
23533
23878
  throw new Error(`Reference not found: ${ref}`);
23534
23879
  }
@@ -25955,8 +26300,8 @@ var init_acp = __esm({
25955
26300
  this.#requestHandler = requestHandler;
25956
26301
  this.#notificationHandler = notificationHandler;
25957
26302
  this.#stream = stream;
25958
- this.#closedPromise = new Promise((resolve13) => {
25959
- this.#abortController.signal.addEventListener("abort", () => resolve13());
26303
+ this.#closedPromise = new Promise((resolve16) => {
26304
+ this.#abortController.signal.addEventListener("abort", () => resolve16());
25960
26305
  });
25961
26306
  this.#receive();
25962
26307
  }
@@ -26105,8 +26450,8 @@ var init_acp = __esm({
26105
26450
  }
26106
26451
  async sendRequest(method, params) {
26107
26452
  const id = this.#nextRequestId++;
26108
- const responsePromise = new Promise((resolve13, reject) => {
26109
- this.#pendingResponses.set(id, { resolve: resolve13, reject });
26453
+ const responsePromise = new Promise((resolve16, reject) => {
26454
+ this.#pendingResponses.set(id, { resolve: resolve16, reject });
26110
26455
  });
26111
26456
  await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
26112
26457
  return responsePromise;
@@ -26427,8 +26772,9 @@ var init_acp_provider_instance = __esm({
26427
26772
  async setConfigOption(category, value) {
26428
26773
  const opt = this.configOptions.find((c) => c.category === category);
26429
26774
  if (!opt) {
26430
- this.log.warn(`[${this.type}] No config option for category: ${category}`);
26431
- return;
26775
+ const message = `[${this.type}] No config option for category: ${category}`;
26776
+ this.log.warn(message);
26777
+ throw new Error(message);
26432
26778
  }
26433
26779
  if (this.useStaticConfig) {
26434
26780
  opt.currentValue = value;
@@ -26440,8 +26786,9 @@ var init_acp_provider_instance = __esm({
26440
26786
  return;
26441
26787
  }
26442
26788
  if (!this.connection || !this.sessionId) {
26443
- this.log.warn(`[${this.type}] Cannot set config: no active connection/session`);
26444
- return;
26789
+ const message = `[${this.type}] Cannot set config: no active connection/session`;
26790
+ this.log.warn(message);
26791
+ throw new Error(message);
26445
26792
  }
26446
26793
  try {
26447
26794
  this.log.info(`[${this.type}] Sending session/set_config_option: configId=${opt.configId} value=${value} sessionId=${this.sessionId}`);
@@ -26455,7 +26802,9 @@ var init_acp_provider_instance = __esm({
26455
26802
  if (result?.configOptions) this.parseConfigOptions(result.configOptions);
26456
26803
  this.log.info(`[${this.type}] Config ${category} set to: ${value} | response: ${JSON.stringify(result)?.slice(0, 300)}`);
26457
26804
  } catch (e) {
26458
- this.log.warn(`[${this.type}] set_config_option failed: ${e?.message}`);
26805
+ const message = e?.message || "Unknown ACP config error";
26806
+ this.log.warn(`[${this.type}] set_config_option failed: ${message}`);
26807
+ throw new Error(message);
26459
26808
  }
26460
26809
  }
26461
26810
  async setMode(modeId) {
@@ -26471,8 +26820,9 @@ var init_acp_provider_instance = __esm({
26471
26820
  return;
26472
26821
  }
26473
26822
  if (!this.connection || !this.sessionId) {
26474
- this.log.warn(`[${this.type}] Cannot set mode: no active connection/session`);
26475
- return;
26823
+ const message = `[${this.type}] Cannot set mode: no active connection/session`;
26824
+ this.log.warn(message);
26825
+ throw new Error(message);
26476
26826
  }
26477
26827
  try {
26478
26828
  await this.connection.setSessionMode({
@@ -26482,7 +26832,9 @@ var init_acp_provider_instance = __esm({
26482
26832
  this.currentMode = modeId;
26483
26833
  this.log.info(`[${this.type}] Mode set to: ${modeId}`);
26484
26834
  } catch (e) {
26485
- this.log.warn(`[${this.type}] set_mode failed: ${e?.message}`);
26835
+ const message = e?.message || "Unknown ACP mode error";
26836
+ this.log.warn(`[${this.type}] set_mode failed: ${message}`);
26837
+ throw new Error(message);
26486
26838
  }
26487
26839
  }
26488
26840
  /** Static config: kill process and restart with new args */
@@ -26530,7 +26882,7 @@ var init_acp_provider_instance = __esm({
26530
26882
  if (!spawnConfig) {
26531
26883
  throw new Error(`[ACP:${this.type}] No spawn config defined`);
26532
26884
  }
26533
- const command = spawnConfig.command;
26885
+ const command = typeof this.settings.executablePath === "string" && this.settings.executablePath.trim() ? this.settings.executablePath.trim() : spawnConfig.command;
26534
26886
  let baseArgs = spawnConfig.args || [];
26535
26887
  if (this.provider.spawnArgBuilder && Object.keys(this.selectedConfig).length > 0) {
26536
26888
  baseArgs = this.provider.spawnArgBuilder(this.selectedConfig);
@@ -26646,13 +26998,13 @@ var init_acp_provider_instance = __esm({
26646
26998
  }
26647
26999
  this.currentStatus = "waiting_approval";
26648
27000
  this.detectStatusTransition();
26649
- const approved = await new Promise((resolve13) => {
26650
- this.permissionResolvers.push(resolve13);
27001
+ const approved = await new Promise((resolve16) => {
27002
+ this.permissionResolvers.push(resolve16);
26651
27003
  setTimeout(() => {
26652
- const idx = this.permissionResolvers.indexOf(resolve13);
27004
+ const idx = this.permissionResolvers.indexOf(resolve16);
26653
27005
  if (idx >= 0) {
26654
27006
  this.permissionResolvers.splice(idx, 1);
26655
- resolve13(false);
27007
+ resolve16(false);
26656
27008
  }
26657
27009
  }, 3e5);
26658
27010
  });
@@ -27221,12 +27573,12 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
27221
27573
  launchMode: "new"
27222
27574
  };
27223
27575
  }
27224
- var os11, path9, crypto4, import_chalk, chalkApi, DaemonCliManager;
27576
+ var os11, path11, crypto4, import_chalk, chalkApi, DaemonCliManager;
27225
27577
  var init_cli_manager = __esm({
27226
27578
  "../../oss/packages/daemon-core/src/commands/cli-manager.ts"() {
27227
27579
  "use strict";
27228
27580
  os11 = __toESM(require("os"));
27229
- path9 = __toESM(require("path"));
27581
+ path11 = __toESM(require("path"));
27230
27582
  crypto4 = __toESM(require("crypto"));
27231
27583
  import_chalk = __toESM(require("chalk"));
27232
27584
  init_provider_cli_adapter();
@@ -27378,7 +27730,7 @@ var init_cli_manager = __esm({
27378
27730
  async startSession(cliType, workingDir, cliArgs, initialModel, options) {
27379
27731
  const trimmed = (workingDir || "").trim();
27380
27732
  if (!trimmed) throw new Error("working directory required");
27381
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os11.homedir()) : path9.resolve(trimmed);
27733
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os11.homedir()) : path11.resolve(trimmed);
27382
27734
  const normalizedType = this.providerLoader.resolveAlias(cliType);
27383
27735
  const provider = this.providerLoader.getByAlias(cliType);
27384
27736
  const key = crypto4.randomUUID();
@@ -27465,10 +27817,10 @@ ${installInfo}`
27465
27817
  if (!cliInfo) {
27466
27818
  const installHint = provider?.install || "";
27467
27819
  const displayName = provider?.displayName || provider?.name || cliType;
27468
- const spawnCmd = provider?.spawn?.command || cliType;
27820
+ const spawnCmd = this.providerLoader.getSpawnCommand(normalizedType, provider?.spawn?.command || cliType);
27469
27821
  throw new Error(
27470
27822
  `${displayName} is not installed.
27471
- Command '${spawnCmd}' not found on PATH.
27823
+ Command '${spawnCmd}' is not available.
27472
27824
  ` + (installHint ? `
27473
27825
  ${installHint}
27474
27826
  ` : "") + `
@@ -27614,6 +27966,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
27614
27966
  if (!instanceManager) return 0;
27615
27967
  const sessions = records || await this.deps.listHostedCliRuntimes?.() || [];
27616
27968
  let restored = 0;
27969
+ const restoredBindings = /* @__PURE__ */ new Set();
27617
27970
  for (const record2 of sessions) {
27618
27971
  if (!record2?.runtimeId || !record2?.cliType || !record2?.workspace) continue;
27619
27972
  if (this.adapters.has(record2.runtimeId) || instanceManager.getInstance(record2.runtimeId)) continue;
@@ -27627,6 +27980,18 @@ Run 'adhdev doctor' for detailed diagnostics.`
27627
27980
  record2.cliArgs,
27628
27981
  record2.providerSessionId
27629
27982
  );
27983
+ const bindingKey = [
27984
+ normalizedType,
27985
+ record2.workspace,
27986
+ sessionBinding.providerSessionId || record2.runtimeId
27987
+ ].join("::");
27988
+ if (restoredBindings.has(bindingKey)) {
27989
+ LOG.info(
27990
+ "CLI",
27991
+ `\u21B7 Skipping duplicate hosted runtime restore: ${record2.runtimeKey || record2.runtimeId} (${normalizedType} @ ${record2.workspace}) binding=${sessionBinding.providerSessionId || "runtime"}`
27992
+ );
27993
+ continue;
27994
+ }
27630
27995
  try {
27631
27996
  await this.registerCliInstance(
27632
27997
  record2.runtimeId,
@@ -27642,6 +28007,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
27642
28007
  launchMode: "manual"
27643
28008
  }
27644
28009
  );
28010
+ restoredBindings.add(bindingKey);
27645
28011
  restored += 1;
27646
28012
  LOG.info("CLI", `\u267B Restored hosted runtime: ${record2.runtimeKey || record2.runtimeId} (${record2.displayName || record2.workspace})`);
27647
28013
  } catch (error48) {
@@ -27930,7 +28296,7 @@ var init_readdirp = __esm({
27930
28296
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
27931
28297
  const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
27932
28298
  if (wantBigintFsStats) {
27933
- this._stat = (path23) => statMethod(path23, { bigint: true });
28299
+ this._stat = (path25) => statMethod(path25, { bigint: true });
27934
28300
  } else {
27935
28301
  this._stat = statMethod;
27936
28302
  }
@@ -27955,8 +28321,8 @@ var init_readdirp = __esm({
27955
28321
  const par = this.parent;
27956
28322
  const fil = par && par.files;
27957
28323
  if (fil && fil.length > 0) {
27958
- const { path: path23, depth } = par;
27959
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path23));
28324
+ const { path: path25, depth } = par;
28325
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path25));
27960
28326
  const awaited = await Promise.all(slice);
27961
28327
  for (const entry of awaited) {
27962
28328
  if (!entry)
@@ -27996,20 +28362,20 @@ var init_readdirp = __esm({
27996
28362
  this.reading = false;
27997
28363
  }
27998
28364
  }
27999
- async _exploreDir(path23, depth) {
28365
+ async _exploreDir(path25, depth) {
28000
28366
  let files;
28001
28367
  try {
28002
- files = await (0, import_promises.readdir)(path23, this._rdOptions);
28368
+ files = await (0, import_promises.readdir)(path25, this._rdOptions);
28003
28369
  } catch (error48) {
28004
28370
  this._onError(error48);
28005
28371
  }
28006
- return { files, depth, path: path23 };
28372
+ return { files, depth, path: path25 };
28007
28373
  }
28008
- async _formatEntry(dirent, path23) {
28374
+ async _formatEntry(dirent, path25) {
28009
28375
  let entry;
28010
28376
  const basename7 = this._isDirent ? dirent.name : dirent;
28011
28377
  try {
28012
- const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path23, basename7));
28378
+ const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path25, basename7));
28013
28379
  entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename7 };
28014
28380
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
28015
28381
  } catch (err) {
@@ -28066,16 +28432,16 @@ var init_readdirp = __esm({
28066
28432
  });
28067
28433
 
28068
28434
  // ../../oss/packages/daemon-core/node_modules/chokidar/handler.js
28069
- function createFsWatchInstance(path23, options, listener, errHandler, emitRaw) {
28435
+ function createFsWatchInstance(path25, options, listener, errHandler, emitRaw) {
28070
28436
  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));
28437
+ listener(path25);
28438
+ emitRaw(rawEvent, evPath, { watchedPath: path25 });
28439
+ if (evPath && path25 !== evPath) {
28440
+ fsWatchBroadcast(sp.resolve(path25, evPath), KEY_LISTENERS, sp.join(path25, evPath));
28075
28441
  }
28076
28442
  };
28077
28443
  try {
28078
- return (0, import_node_fs.watch)(path23, {
28444
+ return (0, import_node_fs.watch)(path25, {
28079
28445
  persistent: options.persistent
28080
28446
  }, handleEvent);
28081
28447
  } catch (error48) {
@@ -28424,12 +28790,12 @@ var init_handler2 = __esm({
28424
28790
  listener(val1, val2, val3);
28425
28791
  });
28426
28792
  };
28427
- setFsWatchListener = (path23, fullPath, options, handlers) => {
28793
+ setFsWatchListener = (path25, fullPath, options, handlers) => {
28428
28794
  const { listener, errHandler, rawEmitter } = handlers;
28429
28795
  let cont = FsWatchInstances.get(fullPath);
28430
28796
  let watcher;
28431
28797
  if (!options.persistent) {
28432
- watcher = createFsWatchInstance(path23, options, listener, errHandler, rawEmitter);
28798
+ watcher = createFsWatchInstance(path25, options, listener, errHandler, rawEmitter);
28433
28799
  if (!watcher)
28434
28800
  return;
28435
28801
  return watcher.close.bind(watcher);
@@ -28440,7 +28806,7 @@ var init_handler2 = __esm({
28440
28806
  addAndConvert(cont, KEY_RAW, rawEmitter);
28441
28807
  } else {
28442
28808
  watcher = createFsWatchInstance(
28443
- path23,
28809
+ path25,
28444
28810
  options,
28445
28811
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
28446
28812
  errHandler,
@@ -28455,7 +28821,7 @@ var init_handler2 = __esm({
28455
28821
  cont.watcherUnusable = true;
28456
28822
  if (isWindows && error48.code === "EPERM") {
28457
28823
  try {
28458
- const fd = await (0, import_promises2.open)(path23, "r");
28824
+ const fd = await (0, import_promises2.open)(path25, "r");
28459
28825
  await fd.close();
28460
28826
  broadcastErr(error48);
28461
28827
  } catch (err) {
@@ -28486,7 +28852,7 @@ var init_handler2 = __esm({
28486
28852
  };
28487
28853
  };
28488
28854
  FsWatchFileInstances = /* @__PURE__ */ new Map();
28489
- setFsWatchFileListener = (path23, fullPath, options, handlers) => {
28855
+ setFsWatchFileListener = (path25, fullPath, options, handlers) => {
28490
28856
  const { listener, rawEmitter } = handlers;
28491
28857
  let cont = FsWatchFileInstances.get(fullPath);
28492
28858
  const copts = cont && cont.options;
@@ -28508,7 +28874,7 @@ var init_handler2 = __esm({
28508
28874
  });
28509
28875
  const currmtime = curr.mtimeMs;
28510
28876
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
28511
- foreach(cont.listeners, (listener2) => listener2(path23, curr));
28877
+ foreach(cont.listeners, (listener2) => listener2(path25, curr));
28512
28878
  }
28513
28879
  })
28514
28880
  };
@@ -28538,13 +28904,13 @@ var init_handler2 = __esm({
28538
28904
  * @param listener on fs change
28539
28905
  * @returns closer for the watcher instance
28540
28906
  */
28541
- _watchWithNodeFs(path23, listener) {
28907
+ _watchWithNodeFs(path25, listener) {
28542
28908
  const opts = this.fsw.options;
28543
- const directory = sp.dirname(path23);
28544
- const basename7 = sp.basename(path23);
28909
+ const directory = sp.dirname(path25);
28910
+ const basename7 = sp.basename(path25);
28545
28911
  const parent = this.fsw._getWatchedDir(directory);
28546
28912
  parent.add(basename7);
28547
- const absolutePath = sp.resolve(path23);
28913
+ const absolutePath = sp.resolve(path25);
28548
28914
  const options = {
28549
28915
  persistent: opts.persistent
28550
28916
  };
@@ -28554,12 +28920,12 @@ var init_handler2 = __esm({
28554
28920
  if (opts.usePolling) {
28555
28921
  const enableBin = opts.interval !== opts.binaryInterval;
28556
28922
  options.interval = enableBin && isBinaryPath(basename7) ? opts.binaryInterval : opts.interval;
28557
- closer = setFsWatchFileListener(path23, absolutePath, options, {
28923
+ closer = setFsWatchFileListener(path25, absolutePath, options, {
28558
28924
  listener,
28559
28925
  rawEmitter: this.fsw._emitRaw
28560
28926
  });
28561
28927
  } else {
28562
- closer = setFsWatchListener(path23, absolutePath, options, {
28928
+ closer = setFsWatchListener(path25, absolutePath, options, {
28563
28929
  listener,
28564
28930
  errHandler: this._boundHandleError,
28565
28931
  rawEmitter: this.fsw._emitRaw
@@ -28581,7 +28947,7 @@ var init_handler2 = __esm({
28581
28947
  let prevStats = stats;
28582
28948
  if (parent.has(basename7))
28583
28949
  return;
28584
- const listener = async (path23, newStats) => {
28950
+ const listener = async (path25, newStats) => {
28585
28951
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file2, 5))
28586
28952
  return;
28587
28953
  if (!newStats || newStats.mtimeMs === 0) {
@@ -28595,11 +28961,11 @@ var init_handler2 = __esm({
28595
28961
  this.fsw._emit(EV.CHANGE, file2, newStats2);
28596
28962
  }
28597
28963
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
28598
- this.fsw._closeFile(path23);
28964
+ this.fsw._closeFile(path25);
28599
28965
  prevStats = newStats2;
28600
28966
  const closer2 = this._watchWithNodeFs(file2, listener);
28601
28967
  if (closer2)
28602
- this.fsw._addPathCloser(path23, closer2);
28968
+ this.fsw._addPathCloser(path25, closer2);
28603
28969
  } else {
28604
28970
  prevStats = newStats2;
28605
28971
  }
@@ -28631,7 +28997,7 @@ var init_handler2 = __esm({
28631
28997
  * @param item basename of this item
28632
28998
  * @returns true if no more processing is needed for this entry.
28633
28999
  */
28634
- async _handleSymlink(entry, directory, path23, item) {
29000
+ async _handleSymlink(entry, directory, path25, item) {
28635
29001
  if (this.fsw.closed) {
28636
29002
  return;
28637
29003
  }
@@ -28641,7 +29007,7 @@ var init_handler2 = __esm({
28641
29007
  this.fsw._incrReadyCount();
28642
29008
  let linkPath;
28643
29009
  try {
28644
- linkPath = await (0, import_promises2.realpath)(path23);
29010
+ linkPath = await (0, import_promises2.realpath)(path25);
28645
29011
  } catch (e) {
28646
29012
  this.fsw._emitReady();
28647
29013
  return true;
@@ -28651,12 +29017,12 @@ var init_handler2 = __esm({
28651
29017
  if (dir.has(item)) {
28652
29018
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
28653
29019
  this.fsw._symlinkPaths.set(full, linkPath);
28654
- this.fsw._emit(EV.CHANGE, path23, entry.stats);
29020
+ this.fsw._emit(EV.CHANGE, path25, entry.stats);
28655
29021
  }
28656
29022
  } else {
28657
29023
  dir.add(item);
28658
29024
  this.fsw._symlinkPaths.set(full, linkPath);
28659
- this.fsw._emit(EV.ADD, path23, entry.stats);
29025
+ this.fsw._emit(EV.ADD, path25, entry.stats);
28660
29026
  }
28661
29027
  this.fsw._emitReady();
28662
29028
  return true;
@@ -28686,9 +29052,9 @@ var init_handler2 = __esm({
28686
29052
  return;
28687
29053
  }
28688
29054
  const item = entry.path;
28689
- let path23 = sp.join(directory, item);
29055
+ let path25 = sp.join(directory, item);
28690
29056
  current.add(item);
28691
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path23, item)) {
29057
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path25, item)) {
28692
29058
  return;
28693
29059
  }
28694
29060
  if (this.fsw.closed) {
@@ -28697,11 +29063,11 @@ var init_handler2 = __esm({
28697
29063
  }
28698
29064
  if (item === target || !target && !previous.has(item)) {
28699
29065
  this.fsw._incrReadyCount();
28700
- path23 = sp.join(dir, sp.relative(dir, path23));
28701
- this._addToNodeFs(path23, initialAdd, wh, depth + 1);
29066
+ path25 = sp.join(dir, sp.relative(dir, path25));
29067
+ this._addToNodeFs(path25, initialAdd, wh, depth + 1);
28702
29068
  }
28703
29069
  }).on(EV.ERROR, this._boundHandleError);
28704
- return new Promise((resolve13, reject) => {
29070
+ return new Promise((resolve16, reject) => {
28705
29071
  if (!stream)
28706
29072
  return reject();
28707
29073
  stream.once(STR_END, () => {
@@ -28710,7 +29076,7 @@ var init_handler2 = __esm({
28710
29076
  return;
28711
29077
  }
28712
29078
  const wasThrottled = throttler ? throttler.clear() : false;
28713
- resolve13(void 0);
29079
+ resolve16(void 0);
28714
29080
  previous.getChildren().filter((item) => {
28715
29081
  return item !== directory && !current.has(item);
28716
29082
  }).forEach((item) => {
@@ -28767,13 +29133,13 @@ var init_handler2 = __esm({
28767
29133
  * @param depth Child path actually targeted for watch
28768
29134
  * @param target Child path actually targeted for watch
28769
29135
  */
28770
- async _addToNodeFs(path23, initialAdd, priorWh, depth, target) {
29136
+ async _addToNodeFs(path25, initialAdd, priorWh, depth, target) {
28771
29137
  const ready = this.fsw._emitReady;
28772
- if (this.fsw._isIgnored(path23) || this.fsw.closed) {
29138
+ if (this.fsw._isIgnored(path25) || this.fsw.closed) {
28773
29139
  ready();
28774
29140
  return false;
28775
29141
  }
28776
- const wh = this.fsw._getWatchHelpers(path23);
29142
+ const wh = this.fsw._getWatchHelpers(path25);
28777
29143
  if (priorWh) {
28778
29144
  wh.filterPath = (entry) => priorWh.filterPath(entry);
28779
29145
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -28789,8 +29155,8 @@ var init_handler2 = __esm({
28789
29155
  const follow = this.fsw.options.followSymlinks;
28790
29156
  let closer;
28791
29157
  if (stats.isDirectory()) {
28792
- const absPath = sp.resolve(path23);
28793
- const targetPath = follow ? await (0, import_promises2.realpath)(path23) : path23;
29158
+ const absPath = sp.resolve(path25);
29159
+ const targetPath = follow ? await (0, import_promises2.realpath)(path25) : path25;
28794
29160
  if (this.fsw.closed)
28795
29161
  return;
28796
29162
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -28800,29 +29166,29 @@ var init_handler2 = __esm({
28800
29166
  this.fsw._symlinkPaths.set(absPath, targetPath);
28801
29167
  }
28802
29168
  } else if (stats.isSymbolicLink()) {
28803
- const targetPath = follow ? await (0, import_promises2.realpath)(path23) : path23;
29169
+ const targetPath = follow ? await (0, import_promises2.realpath)(path25) : path25;
28804
29170
  if (this.fsw.closed)
28805
29171
  return;
28806
29172
  const parent = sp.dirname(wh.watchPath);
28807
29173
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
28808
29174
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
28809
- closer = await this._handleDir(parent, stats, initialAdd, depth, path23, wh, targetPath);
29175
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path25, wh, targetPath);
28810
29176
  if (this.fsw.closed)
28811
29177
  return;
28812
29178
  if (targetPath !== void 0) {
28813
- this.fsw._symlinkPaths.set(sp.resolve(path23), targetPath);
29179
+ this.fsw._symlinkPaths.set(sp.resolve(path25), targetPath);
28814
29180
  }
28815
29181
  } else {
28816
29182
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
28817
29183
  }
28818
29184
  ready();
28819
29185
  if (closer)
28820
- this.fsw._addPathCloser(path23, closer);
29186
+ this.fsw._addPathCloser(path25, closer);
28821
29187
  return false;
28822
29188
  } catch (error48) {
28823
29189
  if (this.fsw._handleError(error48)) {
28824
29190
  ready();
28825
- return path23;
29191
+ return path25;
28826
29192
  }
28827
29193
  }
28828
29194
  }
@@ -28857,24 +29223,24 @@ function createPattern(matcher) {
28857
29223
  }
28858
29224
  return () => false;
28859
29225
  }
28860
- function normalizePath(path23) {
28861
- if (typeof path23 !== "string")
29226
+ function normalizePath(path25) {
29227
+ if (typeof path25 !== "string")
28862
29228
  throw new Error("string expected");
28863
- path23 = sp2.normalize(path23);
28864
- path23 = path23.replace(/\\/g, "/");
29229
+ path25 = sp2.normalize(path25);
29230
+ path25 = path25.replace(/\\/g, "/");
28865
29231
  let prepend = false;
28866
- if (path23.startsWith("//"))
29232
+ if (path25.startsWith("//"))
28867
29233
  prepend = true;
28868
- path23 = path23.replace(DOUBLE_SLASH_RE, "/");
29234
+ path25 = path25.replace(DOUBLE_SLASH_RE, "/");
28869
29235
  if (prepend)
28870
- path23 = "/" + path23;
28871
- return path23;
29236
+ path25 = "/" + path25;
29237
+ return path25;
28872
29238
  }
28873
29239
  function matchPatterns(patterns, testString, stats) {
28874
- const path23 = normalizePath(testString);
29240
+ const path25 = normalizePath(testString);
28875
29241
  for (let index = 0; index < patterns.length; index++) {
28876
29242
  const pattern = patterns[index];
28877
- if (pattern(path23, stats)) {
29243
+ if (pattern(path25, stats)) {
28878
29244
  return true;
28879
29245
  }
28880
29246
  }
@@ -28937,19 +29303,19 @@ var init_chokidar = __esm({
28937
29303
  }
28938
29304
  return str;
28939
29305
  };
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));
29306
+ normalizePathToUnix = (path25) => toUnix(sp2.normalize(toUnix(path25)));
29307
+ normalizeIgnored = (cwd = "") => (path25) => {
29308
+ if (typeof path25 === "string") {
29309
+ return normalizePathToUnix(sp2.isAbsolute(path25) ? path25 : sp2.join(cwd, path25));
28944
29310
  } else {
28945
- return path23;
29311
+ return path25;
28946
29312
  }
28947
29313
  };
28948
- getAbsolutePath = (path23, cwd) => {
28949
- if (sp2.isAbsolute(path23)) {
28950
- return path23;
29314
+ getAbsolutePath = (path25, cwd) => {
29315
+ if (sp2.isAbsolute(path25)) {
29316
+ return path25;
28951
29317
  }
28952
- return sp2.join(cwd, path23);
29318
+ return sp2.join(cwd, path25);
28953
29319
  };
28954
29320
  EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
28955
29321
  DirEntry = class {
@@ -29014,10 +29380,10 @@ var init_chokidar = __esm({
29014
29380
  dirParts;
29015
29381
  followSymlinks;
29016
29382
  statMethod;
29017
- constructor(path23, follow, fsw) {
29383
+ constructor(path25, follow, fsw) {
29018
29384
  this.fsw = fsw;
29019
- const watchPath = path23;
29020
- this.path = path23 = path23.replace(REPLACER_RE, "");
29385
+ const watchPath = path25;
29386
+ this.path = path25 = path25.replace(REPLACER_RE, "");
29021
29387
  this.watchPath = watchPath;
29022
29388
  this.fullWatchPath = sp2.resolve(watchPath);
29023
29389
  this.dirParts = [];
@@ -29157,20 +29523,20 @@ var init_chokidar = __esm({
29157
29523
  this._closePromise = void 0;
29158
29524
  let paths = unifyPaths(paths_);
29159
29525
  if (cwd) {
29160
- paths = paths.map((path23) => {
29161
- const absPath = getAbsolutePath(path23, cwd);
29526
+ paths = paths.map((path25) => {
29527
+ const absPath = getAbsolutePath(path25, cwd);
29162
29528
  return absPath;
29163
29529
  });
29164
29530
  }
29165
- paths.forEach((path23) => {
29166
- this._removeIgnoredPath(path23);
29531
+ paths.forEach((path25) => {
29532
+ this._removeIgnoredPath(path25);
29167
29533
  });
29168
29534
  this._userIgnored = void 0;
29169
29535
  if (!this._readyCount)
29170
29536
  this._readyCount = 0;
29171
29537
  this._readyCount += paths.length;
29172
- Promise.all(paths.map(async (path23) => {
29173
- const res = await this._nodeFsHandler._addToNodeFs(path23, !_internal, void 0, 0, _origAdd);
29538
+ Promise.all(paths.map(async (path25) => {
29539
+ const res = await this._nodeFsHandler._addToNodeFs(path25, !_internal, void 0, 0, _origAdd);
29174
29540
  if (res)
29175
29541
  this._emitReady();
29176
29542
  return res;
@@ -29192,17 +29558,17 @@ var init_chokidar = __esm({
29192
29558
  return this;
29193
29559
  const paths = unifyPaths(paths_);
29194
29560
  const { cwd } = this.options;
29195
- paths.forEach((path23) => {
29196
- if (!sp2.isAbsolute(path23) && !this._closers.has(path23)) {
29561
+ paths.forEach((path25) => {
29562
+ if (!sp2.isAbsolute(path25) && !this._closers.has(path25)) {
29197
29563
  if (cwd)
29198
- path23 = sp2.join(cwd, path23);
29199
- path23 = sp2.resolve(path23);
29564
+ path25 = sp2.join(cwd, path25);
29565
+ path25 = sp2.resolve(path25);
29200
29566
  }
29201
- this._closePath(path23);
29202
- this._addIgnoredPath(path23);
29203
- if (this._watched.has(path23)) {
29567
+ this._closePath(path25);
29568
+ this._addIgnoredPath(path25);
29569
+ if (this._watched.has(path25)) {
29204
29570
  this._addIgnoredPath({
29205
- path: path23,
29571
+ path: path25,
29206
29572
  recursive: true
29207
29573
  });
29208
29574
  }
@@ -29266,38 +29632,38 @@ var init_chokidar = __esm({
29266
29632
  * @param stats arguments to be passed with event
29267
29633
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
29268
29634
  */
29269
- async _emit(event, path23, stats) {
29635
+ async _emit(event, path25, stats) {
29270
29636
  if (this.closed)
29271
29637
  return;
29272
29638
  const opts = this.options;
29273
29639
  if (isWindows)
29274
- path23 = sp2.normalize(path23);
29640
+ path25 = sp2.normalize(path25);
29275
29641
  if (opts.cwd)
29276
- path23 = sp2.relative(opts.cwd, path23);
29277
- const args = [path23];
29642
+ path25 = sp2.relative(opts.cwd, path25);
29643
+ const args = [path25];
29278
29644
  if (stats != null)
29279
29645
  args.push(stats);
29280
29646
  const awf = opts.awaitWriteFinish;
29281
29647
  let pw;
29282
- if (awf && (pw = this._pendingWrites.get(path23))) {
29648
+ if (awf && (pw = this._pendingWrites.get(path25))) {
29283
29649
  pw.lastChange = /* @__PURE__ */ new Date();
29284
29650
  return this;
29285
29651
  }
29286
29652
  if (opts.atomic) {
29287
29653
  if (event === EVENTS.UNLINK) {
29288
- this._pendingUnlinks.set(path23, [event, ...args]);
29654
+ this._pendingUnlinks.set(path25, [event, ...args]);
29289
29655
  setTimeout(() => {
29290
- this._pendingUnlinks.forEach((entry, path24) => {
29656
+ this._pendingUnlinks.forEach((entry, path26) => {
29291
29657
  this.emit(...entry);
29292
29658
  this.emit(EVENTS.ALL, ...entry);
29293
- this._pendingUnlinks.delete(path24);
29659
+ this._pendingUnlinks.delete(path26);
29294
29660
  });
29295
29661
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
29296
29662
  return this;
29297
29663
  }
29298
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path23)) {
29664
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path25)) {
29299
29665
  event = EVENTS.CHANGE;
29300
- this._pendingUnlinks.delete(path23);
29666
+ this._pendingUnlinks.delete(path25);
29301
29667
  }
29302
29668
  }
29303
29669
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -29315,16 +29681,16 @@ var init_chokidar = __esm({
29315
29681
  this.emitWithAll(event, args);
29316
29682
  }
29317
29683
  };
29318
- this._awaitWriteFinish(path23, awf.stabilityThreshold, event, awfEmit);
29684
+ this._awaitWriteFinish(path25, awf.stabilityThreshold, event, awfEmit);
29319
29685
  return this;
29320
29686
  }
29321
29687
  if (event === EVENTS.CHANGE) {
29322
- const isThrottled = !this._throttle(EVENTS.CHANGE, path23, 50);
29688
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path25, 50);
29323
29689
  if (isThrottled)
29324
29690
  return this;
29325
29691
  }
29326
29692
  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;
29693
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path25) : path25;
29328
29694
  let stats2;
29329
29695
  try {
29330
29696
  stats2 = await (0, import_promises3.stat)(fullPath);
@@ -29355,23 +29721,23 @@ var init_chokidar = __esm({
29355
29721
  * @param timeout duration of time to suppress duplicate actions
29356
29722
  * @returns tracking object or false if action should be suppressed
29357
29723
  */
29358
- _throttle(actionType, path23, timeout) {
29724
+ _throttle(actionType, path25, timeout) {
29359
29725
  if (!this._throttled.has(actionType)) {
29360
29726
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
29361
29727
  }
29362
29728
  const action = this._throttled.get(actionType);
29363
29729
  if (!action)
29364
29730
  throw new Error("invalid throttle");
29365
- const actionPath = action.get(path23);
29731
+ const actionPath = action.get(path25);
29366
29732
  if (actionPath) {
29367
29733
  actionPath.count++;
29368
29734
  return false;
29369
29735
  }
29370
29736
  let timeoutObject;
29371
29737
  const clear = () => {
29372
- const item = action.get(path23);
29738
+ const item = action.get(path25);
29373
29739
  const count = item ? item.count : 0;
29374
- action.delete(path23);
29740
+ action.delete(path25);
29375
29741
  clearTimeout(timeoutObject);
29376
29742
  if (item)
29377
29743
  clearTimeout(item.timeoutObject);
@@ -29379,7 +29745,7 @@ var init_chokidar = __esm({
29379
29745
  };
29380
29746
  timeoutObject = setTimeout(clear, timeout);
29381
29747
  const thr = { timeoutObject, clear, count: 0 };
29382
- action.set(path23, thr);
29748
+ action.set(path25, thr);
29383
29749
  return thr;
29384
29750
  }
29385
29751
  _incrReadyCount() {
@@ -29393,44 +29759,44 @@ var init_chokidar = __esm({
29393
29759
  * @param event
29394
29760
  * @param awfEmit Callback to be called when ready for event to be emitted.
29395
29761
  */
29396
- _awaitWriteFinish(path23, threshold, event, awfEmit) {
29762
+ _awaitWriteFinish(path25, threshold, event, awfEmit) {
29397
29763
  const awf = this.options.awaitWriteFinish;
29398
29764
  if (typeof awf !== "object")
29399
29765
  return;
29400
29766
  const pollInterval = awf.pollInterval;
29401
29767
  let timeoutHandler;
29402
- let fullPath = path23;
29403
- if (this.options.cwd && !sp2.isAbsolute(path23)) {
29404
- fullPath = sp2.join(this.options.cwd, path23);
29768
+ let fullPath = path25;
29769
+ if (this.options.cwd && !sp2.isAbsolute(path25)) {
29770
+ fullPath = sp2.join(this.options.cwd, path25);
29405
29771
  }
29406
29772
  const now = /* @__PURE__ */ new Date();
29407
29773
  const writes = this._pendingWrites;
29408
29774
  function awaitWriteFinishFn(prevStat) {
29409
29775
  (0, import_node_fs2.stat)(fullPath, (err, curStat) => {
29410
- if (err || !writes.has(path23)) {
29776
+ if (err || !writes.has(path25)) {
29411
29777
  if (err && err.code !== "ENOENT")
29412
29778
  awfEmit(err);
29413
29779
  return;
29414
29780
  }
29415
29781
  const now2 = Number(/* @__PURE__ */ new Date());
29416
29782
  if (prevStat && curStat.size !== prevStat.size) {
29417
- writes.get(path23).lastChange = now2;
29783
+ writes.get(path25).lastChange = now2;
29418
29784
  }
29419
- const pw = writes.get(path23);
29785
+ const pw = writes.get(path25);
29420
29786
  const df = now2 - pw.lastChange;
29421
29787
  if (df >= threshold) {
29422
- writes.delete(path23);
29788
+ writes.delete(path25);
29423
29789
  awfEmit(void 0, curStat);
29424
29790
  } else {
29425
29791
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
29426
29792
  }
29427
29793
  });
29428
29794
  }
29429
- if (!writes.has(path23)) {
29430
- writes.set(path23, {
29795
+ if (!writes.has(path25)) {
29796
+ writes.set(path25, {
29431
29797
  lastChange: now,
29432
29798
  cancelWait: () => {
29433
- writes.delete(path23);
29799
+ writes.delete(path25);
29434
29800
  clearTimeout(timeoutHandler);
29435
29801
  return event;
29436
29802
  }
@@ -29441,8 +29807,8 @@ var init_chokidar = __esm({
29441
29807
  /**
29442
29808
  * Determines whether user has asked to ignore this path.
29443
29809
  */
29444
- _isIgnored(path23, stats) {
29445
- if (this.options.atomic && DOT_RE.test(path23))
29810
+ _isIgnored(path25, stats) {
29811
+ if (this.options.atomic && DOT_RE.test(path25))
29446
29812
  return true;
29447
29813
  if (!this._userIgnored) {
29448
29814
  const { cwd } = this.options;
@@ -29452,17 +29818,17 @@ var init_chokidar = __esm({
29452
29818
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
29453
29819
  this._userIgnored = anymatch(list, void 0);
29454
29820
  }
29455
- return this._userIgnored(path23, stats);
29821
+ return this._userIgnored(path25, stats);
29456
29822
  }
29457
- _isntIgnored(path23, stat4) {
29458
- return !this._isIgnored(path23, stat4);
29823
+ _isntIgnored(path25, stat4) {
29824
+ return !this._isIgnored(path25, stat4);
29459
29825
  }
29460
29826
  /**
29461
29827
  * Provides a set of common helpers and properties relating to symlink handling.
29462
29828
  * @param path file or directory pattern being watched
29463
29829
  */
29464
- _getWatchHelpers(path23) {
29465
- return new WatchHelper(path23, this.options.followSymlinks, this);
29830
+ _getWatchHelpers(path25) {
29831
+ return new WatchHelper(path25, this.options.followSymlinks, this);
29466
29832
  }
29467
29833
  // Directory helpers
29468
29834
  // -----------------
@@ -29494,63 +29860,63 @@ var init_chokidar = __esm({
29494
29860
  * @param item base path of item/directory
29495
29861
  */
29496
29862
  _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))
29863
+ const path25 = sp2.join(directory, item);
29864
+ const fullPath = sp2.resolve(path25);
29865
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path25) || this._watched.has(fullPath);
29866
+ if (!this._throttle("remove", path25, 100))
29501
29867
  return;
29502
29868
  if (!isDirectory && this._watched.size === 1) {
29503
29869
  this.add(directory, item, true);
29504
29870
  }
29505
- const wp = this._getWatchedDir(path23);
29871
+ const wp = this._getWatchedDir(path25);
29506
29872
  const nestedDirectoryChildren = wp.getChildren();
29507
- nestedDirectoryChildren.forEach((nested) => this._remove(path23, nested));
29873
+ nestedDirectoryChildren.forEach((nested) => this._remove(path25, nested));
29508
29874
  const parent = this._getWatchedDir(directory);
29509
29875
  const wasTracked = parent.has(item);
29510
29876
  parent.remove(item);
29511
29877
  if (this._symlinkPaths.has(fullPath)) {
29512
29878
  this._symlinkPaths.delete(fullPath);
29513
29879
  }
29514
- let relPath = path23;
29880
+ let relPath = path25;
29515
29881
  if (this.options.cwd)
29516
- relPath = sp2.relative(this.options.cwd, path23);
29882
+ relPath = sp2.relative(this.options.cwd, path25);
29517
29883
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
29518
29884
  const event = this._pendingWrites.get(relPath).cancelWait();
29519
29885
  if (event === EVENTS.ADD)
29520
29886
  return;
29521
29887
  }
29522
- this._watched.delete(path23);
29888
+ this._watched.delete(path25);
29523
29889
  this._watched.delete(fullPath);
29524
29890
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
29525
- if (wasTracked && !this._isIgnored(path23))
29526
- this._emit(eventName, path23);
29527
- this._closePath(path23);
29891
+ if (wasTracked && !this._isIgnored(path25))
29892
+ this._emit(eventName, path25);
29893
+ this._closePath(path25);
29528
29894
  }
29529
29895
  /**
29530
29896
  * Closes all watchers for a path
29531
29897
  */
29532
- _closePath(path23) {
29533
- this._closeFile(path23);
29534
- const dir = sp2.dirname(path23);
29535
- this._getWatchedDir(dir).remove(sp2.basename(path23));
29898
+ _closePath(path25) {
29899
+ this._closeFile(path25);
29900
+ const dir = sp2.dirname(path25);
29901
+ this._getWatchedDir(dir).remove(sp2.basename(path25));
29536
29902
  }
29537
29903
  /**
29538
29904
  * Closes only file-specific watchers
29539
29905
  */
29540
- _closeFile(path23) {
29541
- const closers = this._closers.get(path23);
29906
+ _closeFile(path25) {
29907
+ const closers = this._closers.get(path25);
29542
29908
  if (!closers)
29543
29909
  return;
29544
29910
  closers.forEach((closer) => closer());
29545
- this._closers.delete(path23);
29911
+ this._closers.delete(path25);
29546
29912
  }
29547
- _addPathCloser(path23, closer) {
29913
+ _addPathCloser(path25, closer) {
29548
29914
  if (!closer)
29549
29915
  return;
29550
- let list = this._closers.get(path23);
29916
+ let list = this._closers.get(path25);
29551
29917
  if (!list) {
29552
29918
  list = [];
29553
- this._closers.set(path23, list);
29919
+ this._closers.set(path25, list);
29554
29920
  }
29555
29921
  list.push(closer);
29556
29922
  }
@@ -29576,18 +29942,19 @@ var init_chokidar = __esm({
29576
29942
  });
29577
29943
 
29578
29944
  // ../../oss/packages/daemon-core/src/providers/provider-loader.ts
29579
- var fs6, path10, os12, ProviderLoader;
29945
+ var fs6, path12, os12, ProviderLoader;
29580
29946
  var init_provider_loader = __esm({
29581
29947
  "../../oss/packages/daemon-core/src/providers/provider-loader.ts"() {
29582
29948
  "use strict";
29583
29949
  fs6 = __toESM(require("fs"));
29584
- path10 = __toESM(require("path"));
29950
+ path12 = __toESM(require("path"));
29585
29951
  os12 = __toESM(require("os"));
29586
29952
  init_chokidar();
29587
29953
  init_ide_detector();
29588
29954
  init_logger();
29589
29955
  ProviderLoader = class _ProviderLoader {
29590
29956
  providers = /* @__PURE__ */ new Map();
29957
+ providerAvailability = /* @__PURE__ */ new Map();
29591
29958
  userDir;
29592
29959
  upstreamDir;
29593
29960
  disableUpstream;
@@ -29603,12 +29970,12 @@ var init_provider_loader = __esm({
29603
29970
  static META_FILE = ".meta.json";
29604
29971
  constructor(options) {
29605
29972
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
29606
- const defaultProvidersDir = path10.join(os12.homedir(), ".adhdev", "providers");
29973
+ const defaultProvidersDir = path12.join(os12.homedir(), ".adhdev", "providers");
29607
29974
  if (options?.userDir) {
29608
29975
  this.userDir = options.userDir;
29609
29976
  this.log(`Config 'providerDir' applied: ${this.userDir}`);
29610
29977
  } else {
29611
- const localRepoPath = path10.resolve(__dirname, "../../../../../adhdev-providers");
29978
+ const localRepoPath = path12.resolve(__dirname, "../../../../../adhdev-providers");
29612
29979
  if (fs6.existsSync(localRepoPath)) {
29613
29980
  this.userDir = localRepoPath;
29614
29981
  this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
@@ -29617,7 +29984,7 @@ var init_provider_loader = __esm({
29617
29984
  this.log(`Using default user providers directory: ${this.userDir}`);
29618
29985
  }
29619
29986
  }
29620
- this.upstreamDir = path10.join(defaultProvidersDir, ".upstream");
29987
+ this.upstreamDir = path12.join(defaultProvidersDir, ".upstream");
29621
29988
  this.disableUpstream = options?.disableUpstream ?? false;
29622
29989
  }
29623
29990
  log(msg) {
@@ -29647,7 +30014,7 @@ var init_provider_loader = __esm({
29647
30014
  * Canonical provider directory shape for a given root.
29648
30015
  */
29649
30016
  getProviderDir(root, category, type) {
29650
- return path10.join(root, category, type);
30017
+ return path12.join(root, category, type);
29651
30018
  }
29652
30019
  /**
29653
30020
  * Canonical user override directory for a provider.
@@ -29674,7 +30041,7 @@ var init_provider_loader = __esm({
29674
30041
  resolveProviderFile(type, ...segments) {
29675
30042
  const dir = this.findProviderDirInternal(type);
29676
30043
  if (!dir) return null;
29677
- return path10.join(dir, ...segments);
30044
+ return path12.join(dir, ...segments);
29678
30045
  }
29679
30046
  /**
29680
30047
  * Load all providers (3-tier priority)
@@ -29685,6 +30052,7 @@ var init_provider_loader = __esm({
29685
30052
  */
29686
30053
  loadAll() {
29687
30054
  this.providers.clear();
30055
+ this.providerAvailability.clear();
29688
30056
  let upstreamCount = 0;
29689
30057
  if (!this.disableUpstream && fs6.existsSync(this.upstreamDir)) {
29690
30058
  upstreamCount = this.loadDir(this.upstreamDir);
@@ -29712,7 +30080,7 @@ var init_provider_loader = __esm({
29712
30080
  if (!fs6.existsSync(this.upstreamDir)) return false;
29713
30081
  try {
29714
30082
  return fs6.readdirSync(this.upstreamDir).some(
29715
- (d) => fs6.statSync(path10.join(this.upstreamDir, d)).isDirectory()
30083
+ (d) => fs6.statSync(path12.join(this.upstreamDir, d)).isDirectory()
29716
30084
  );
29717
30085
  } catch {
29718
30086
  return false;
@@ -29755,11 +30123,12 @@ var init_provider_loader = __esm({
29755
30123
  if ((p.category === "cli" || p.category === "acp") && p.spawn?.command) {
29756
30124
  const verCmdConfig = p.versionCommand;
29757
30125
  const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[process.platform] : verCmdConfig;
30126
+ const command = this.getSpawnCommand(p.type, p.spawn.command);
29758
30127
  result.push({
29759
30128
  id: p.type,
29760
30129
  displayName: p.displayName || p.name,
29761
30130
  icon: p.icon || "\u{1F527}",
29762
- command: p.spawn.command,
30131
+ command,
29763
30132
  category: p.category,
29764
30133
  ...typeof versionCommand === "string" && versionCommand.trim() ? { versionCommand: versionCommand.trim() } : {}
29765
30134
  });
@@ -29888,6 +30257,71 @@ var init_provider_loader = __esm({
29888
30257
  getAvailableIdeTypes() {
29889
30258
  return [...this.providers.values()].filter((p) => p.category === "ide" && p.cdpPorts).map((p) => p.type);
29890
30259
  }
30260
+ getSpawnCommand(type, fallback) {
30261
+ const override = this.getOptionalStringSetting(type, "executablePath");
30262
+ if (override) return override;
30263
+ return fallback || this.providers.get(type)?.spawn?.command || type;
30264
+ }
30265
+ getIdeCliCommand(type, fallback) {
30266
+ const override = this.getOptionalStringSetting(type, "cliPathOverride");
30267
+ if (override) return override;
30268
+ return fallback || this.providers.get(type)?.cli || null;
30269
+ }
30270
+ getIdePathCandidates(type, fallback) {
30271
+ const override = this.getOptionalStringSetting(type, "appPathOverride");
30272
+ if (override) return [override];
30273
+ if (fallback && fallback.length > 0) return fallback;
30274
+ const osPaths = this.providers.get(type)?.paths?.[process.platform];
30275
+ return Array.isArray(osPaths) ? [...osPaths] : [];
30276
+ }
30277
+ setProviderAvailability(type, state) {
30278
+ this.providerAvailability.set(type, {
30279
+ installed: !!state.installed,
30280
+ detectedPath: state.detectedPath ?? null
30281
+ });
30282
+ }
30283
+ setCliDetectionResults(results, replace = true) {
30284
+ if (replace) {
30285
+ for (const provider of this.providers.values()) {
30286
+ if (provider.category === "cli" || provider.category === "acp") {
30287
+ this.providerAvailability.set(provider.type, { installed: false, detectedPath: null });
30288
+ }
30289
+ }
30290
+ }
30291
+ for (const result of results) {
30292
+ this.setProviderAvailability(result.id, {
30293
+ installed: !!result.installed,
30294
+ detectedPath: result.path || null
30295
+ });
30296
+ }
30297
+ }
30298
+ setIdeDetectionResults(results, replace = true) {
30299
+ if (replace) {
30300
+ for (const provider of this.providers.values()) {
30301
+ if (provider.category === "ide") {
30302
+ this.providerAvailability.set(provider.type, { installed: false, detectedPath: null });
30303
+ }
30304
+ }
30305
+ }
30306
+ for (const result of results) {
30307
+ this.setProviderAvailability(result.id, {
30308
+ installed: !!result.installed,
30309
+ detectedPath: result.cliCommand || result.path || null
30310
+ });
30311
+ }
30312
+ }
30313
+ getAvailableProviderInfos() {
30314
+ return this.getAll().map((provider) => {
30315
+ const availability = this.providerAvailability.get(provider.type);
30316
+ return {
30317
+ ...provider,
30318
+ ...availability ? {
30319
+ installed: availability.installed,
30320
+ detectedPath: availability.detectedPath
30321
+ } : {}
30322
+ };
30323
+ });
30324
+ }
29891
30325
  /**
29892
30326
  * Register IDE providers to core/detector registry
29893
30327
  * → Enables detectIDEs() to detect provider.js-based IDEs
@@ -29962,8 +30396,8 @@ var init_provider_loader = __esm({
29962
30396
  resolved._resolvedScriptDir = entry.scriptDir;
29963
30397
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
29964
30398
  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;
30399
+ const fullDir = path12.join(providerDir, entry.scriptDir);
30400
+ resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
29967
30401
  }
29968
30402
  matched = true;
29969
30403
  }
@@ -29978,8 +30412,8 @@ var init_provider_loader = __esm({
29978
30412
  resolved._resolvedScriptDir = base.defaultScriptDir;
29979
30413
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
29980
30414
  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;
30415
+ const fullDir = path12.join(providerDir, base.defaultScriptDir);
30416
+ resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
29983
30417
  }
29984
30418
  }
29985
30419
  resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
@@ -29996,8 +30430,8 @@ var init_provider_loader = __esm({
29996
30430
  resolved._resolvedScriptDir = dirOverride;
29997
30431
  resolved._resolvedScriptsSource = `versions:${range}`;
29998
30432
  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;
30433
+ const fullDir = path12.join(providerDir, dirOverride);
30434
+ resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
30001
30435
  }
30002
30436
  }
30003
30437
  } else if (override.scripts) {
@@ -30013,8 +30447,8 @@ var init_provider_loader = __esm({
30013
30447
  resolved._resolvedScriptDir = base.defaultScriptDir;
30014
30448
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
30015
30449
  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;
30450
+ const fullDir = path12.join(providerDir, base.defaultScriptDir);
30451
+ resolved._resolvedScriptsPath = fs6.existsSync(path12.join(fullDir, "scripts.js")) ? path12.join(fullDir, "scripts.js") : fullDir;
30018
30452
  }
30019
30453
  }
30020
30454
  }
@@ -30039,14 +30473,14 @@ var init_provider_loader = __esm({
30039
30473
  this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
30040
30474
  return null;
30041
30475
  }
30042
- const dir = path10.join(providerDir, scriptDir);
30476
+ const dir = path12.join(providerDir, scriptDir);
30043
30477
  if (!fs6.existsSync(dir)) {
30044
30478
  this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
30045
30479
  return null;
30046
30480
  }
30047
30481
  const cached2 = this.scriptsCache.get(dir);
30048
30482
  if (cached2) return cached2;
30049
- const scriptsJs = path10.join(dir, "scripts.js");
30483
+ const scriptsJs = path12.join(dir, "scripts.js");
30050
30484
  if (fs6.existsSync(scriptsJs)) {
30051
30485
  try {
30052
30486
  delete require.cache[require.resolve(scriptsJs)];
@@ -30088,7 +30522,7 @@ var init_provider_loader = __esm({
30088
30522
  return;
30089
30523
  }
30090
30524
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
30091
- this.log(`File changed: ${path10.basename(filePath)}, reloading...`);
30525
+ this.log(`File changed: ${path12.basename(filePath)}, reloading...`);
30092
30526
  this.reload();
30093
30527
  }
30094
30528
  };
@@ -30143,7 +30577,7 @@ var init_provider_loader = __esm({
30143
30577
  }
30144
30578
  const https = require("https");
30145
30579
  const { execSync: execSync7 } = require("child_process");
30146
- const metaPath = path10.join(this.upstreamDir, _ProviderLoader.META_FILE);
30580
+ const metaPath = path12.join(this.upstreamDir, _ProviderLoader.META_FILE);
30147
30581
  let prevEtag = "";
30148
30582
  let prevTimestamp = 0;
30149
30583
  try {
@@ -30160,7 +30594,7 @@ var init_provider_loader = __esm({
30160
30594
  return { updated: false };
30161
30595
  }
30162
30596
  try {
30163
- const etag = await new Promise((resolve13, reject) => {
30597
+ const etag = await new Promise((resolve16, reject) => {
30164
30598
  const options = {
30165
30599
  method: "HEAD",
30166
30600
  hostname: "github.com",
@@ -30178,7 +30612,7 @@ var init_provider_loader = __esm({
30178
30612
  headers: { "User-Agent": "adhdev-launcher" },
30179
30613
  timeout: 1e4
30180
30614
  }, (res2) => {
30181
- resolve13(res2.headers.etag || res2.headers["last-modified"] || "");
30615
+ resolve16(res2.headers.etag || res2.headers["last-modified"] || "");
30182
30616
  });
30183
30617
  req2.on("error", reject);
30184
30618
  req2.on("timeout", () => {
@@ -30187,7 +30621,7 @@ var init_provider_loader = __esm({
30187
30621
  });
30188
30622
  req2.end();
30189
30623
  } else {
30190
- resolve13(res.headers.etag || res.headers["last-modified"] || "");
30624
+ resolve16(res.headers.etag || res.headers["last-modified"] || "");
30191
30625
  }
30192
30626
  });
30193
30627
  req.on("error", reject);
@@ -30203,17 +30637,17 @@ var init_provider_loader = __esm({
30203
30637
  return { updated: false };
30204
30638
  }
30205
30639
  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()}`);
30640
+ const tmpTar = path12.join(os12.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
30641
+ const tmpExtract = path12.join(os12.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
30208
30642
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
30209
30643
  fs6.mkdirSync(tmpExtract, { recursive: true });
30210
30644
  execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
30211
30645
  const extracted = fs6.readdirSync(tmpExtract);
30212
30646
  const rootDir = extracted.find(
30213
- (d) => fs6.statSync(path10.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
30647
+ (d) => fs6.statSync(path12.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
30214
30648
  );
30215
30649
  if (!rootDir) throw new Error("Unexpected tarball structure");
30216
- const sourceDir = path10.join(tmpExtract, rootDir);
30650
+ const sourceDir = path12.join(tmpExtract, rootDir);
30217
30651
  const backupDir = this.upstreamDir + ".bak";
30218
30652
  if (fs6.existsSync(this.upstreamDir)) {
30219
30653
  if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
@@ -30251,7 +30685,7 @@ var init_provider_loader = __esm({
30251
30685
  downloadFile(url2, destPath) {
30252
30686
  const https = require("https");
30253
30687
  const http3 = require("http");
30254
- return new Promise((resolve13, reject) => {
30688
+ return new Promise((resolve16, reject) => {
30255
30689
  const doRequest = (reqUrl, redirectCount = 0) => {
30256
30690
  if (redirectCount > 5) {
30257
30691
  reject(new Error("Too many redirects"));
@@ -30271,7 +30705,7 @@ var init_provider_loader = __esm({
30271
30705
  res.pipe(ws);
30272
30706
  ws.on("finish", () => {
30273
30707
  ws.close();
30274
- resolve13();
30708
+ resolve16();
30275
30709
  });
30276
30710
  ws.on("error", reject);
30277
30711
  });
@@ -30288,8 +30722,8 @@ var init_provider_loader = __esm({
30288
30722
  copyDirRecursive(src, dest) {
30289
30723
  fs6.mkdirSync(dest, { recursive: true });
30290
30724
  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);
30725
+ const srcPath = path12.join(src, entry.name);
30726
+ const destPath = path12.join(dest, entry.name);
30293
30727
  if (entry.isDirectory()) {
30294
30728
  this.copyDirRecursive(srcPath, destPath);
30295
30729
  } else {
@@ -30300,7 +30734,7 @@ var init_provider_loader = __esm({
30300
30734
  /** .meta.json save */
30301
30735
  writeMeta(metaPath, etag, timestamp) {
30302
30736
  try {
30303
- fs6.mkdirSync(path10.dirname(metaPath), { recursive: true });
30737
+ fs6.mkdirSync(path12.dirname(metaPath), { recursive: true });
30304
30738
  fs6.writeFileSync(metaPath, JSON.stringify({
30305
30739
  etag,
30306
30740
  timestamp,
@@ -30317,7 +30751,7 @@ var init_provider_loader = __esm({
30317
30751
  const scan = (d) => {
30318
30752
  try {
30319
30753
  for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
30320
- if (entry.isDirectory()) scan(path10.join(d, entry.name));
30754
+ if (entry.isDirectory()) scan(path12.join(d, entry.name));
30321
30755
  else if (entry.name === "provider.json") count++;
30322
30756
  }
30323
30757
  } catch {
@@ -30331,9 +30765,8 @@ var init_provider_loader = __esm({
30331
30765
  * Get public settings schema for a provider (for dashboard UI rendering)
30332
30766
  */
30333
30767
  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 }));
30768
+ const settings = this.getSettingsSchema(type);
30769
+ return Object.entries(settings).filter(([, def]) => def.public === true).map(([key, def]) => ({ key, ...def }));
30337
30770
  }
30338
30771
  /**
30339
30772
  * Get public settings schema for all providers
@@ -30350,8 +30783,7 @@ var init_provider_loader = __esm({
30350
30783
  * Resolved setting value for a provider (default + user override)
30351
30784
  */
30352
30785
  getSettingValue(type, key) {
30353
- const provider = this.providers.get(type);
30354
- const schemaDef = provider?.settings?.[key];
30786
+ const schemaDef = this.getSettingsSchema(type)[key];
30355
30787
  const defaultVal = schemaDef ? schemaDef.default : void 0;
30356
30788
  try {
30357
30789
  const { loadConfig: loadConfig2 } = (init_config(), __toCommonJS(config_exports));
@@ -30366,10 +30798,9 @@ var init_provider_loader = __esm({
30366
30798
  * All resolved settings for a provider (default + user override)
30367
30799
  */
30368
30800
  getSettings(type) {
30369
- const provider = this.providers.get(type);
30370
- if (!provider?.settings) return {};
30801
+ const settings = this.getSettingsSchema(type);
30371
30802
  const result = {};
30372
- for (const [key, def] of Object.entries(provider.settings)) {
30803
+ for (const [key] of Object.entries(settings)) {
30373
30804
  result[key] = this.getSettingValue(type, key);
30374
30805
  }
30375
30806
  return result;
@@ -30378,11 +30809,11 @@ var init_provider_loader = __esm({
30378
30809
  * Save provider setting value (writes to config.json)
30379
30810
  */
30380
30811
  setSetting(type, key, value) {
30381
- const provider = this.providers.get(type);
30382
- const schemaDef = provider?.settings?.[key];
30812
+ const schemaDef = this.getSettingsSchema(type)[key];
30383
30813
  if (!schemaDef) return false;
30384
30814
  if (!schemaDef.public) return false;
30385
30815
  if (schemaDef.type === "boolean" && typeof value !== "boolean") return false;
30816
+ if (schemaDef.type === "string" && typeof value !== "string") return false;
30386
30817
  if (schemaDef.type === "number") {
30387
30818
  if (typeof value !== "number") return false;
30388
30819
  if (schemaDef.min !== void 0 && value < schemaDef.min) return false;
@@ -30403,6 +30834,53 @@ var init_provider_loader = __esm({
30403
30834
  return false;
30404
30835
  }
30405
30836
  }
30837
+ getOptionalStringSetting(type, key) {
30838
+ const value = this.getSettingValue(type, key);
30839
+ if (typeof value !== "string") return null;
30840
+ const trimmed = value.trim();
30841
+ return trimmed ? trimmed : null;
30842
+ }
30843
+ getSettingsSchema(type) {
30844
+ const provider = this.providers.get(type);
30845
+ if (!provider) return {};
30846
+ return {
30847
+ ...this.getSyntheticSettings(type, provider),
30848
+ ...provider.settings || {}
30849
+ };
30850
+ }
30851
+ getSyntheticSettings(type, provider) {
30852
+ const result = {};
30853
+ if ((provider.category === "cli" || provider.category === "acp") && provider.spawn?.command && !provider.settings?.executablePath) {
30854
+ result.executablePath = {
30855
+ type: "string",
30856
+ default: "",
30857
+ public: true,
30858
+ label: "Executable path",
30859
+ description: "Optional absolute path for this provider binary. Leave blank to use the default PATH lookup."
30860
+ };
30861
+ }
30862
+ if (provider.category === "ide") {
30863
+ if (provider.cli && !provider.settings?.cliPathOverride) {
30864
+ result.cliPathOverride = {
30865
+ type: "string",
30866
+ default: "",
30867
+ public: true,
30868
+ label: "CLI path override",
30869
+ description: "Optional absolute path for the IDE CLI launcher. Leave blank to use the detected default."
30870
+ };
30871
+ }
30872
+ if (provider.paths && !provider.settings?.appPathOverride) {
30873
+ result.appPathOverride = {
30874
+ type: "string",
30875
+ default: "",
30876
+ public: true,
30877
+ label: "App path override",
30878
+ description: "Optional absolute path for the IDE app bundle or executable. Leave blank to use the default install locations."
30879
+ };
30880
+ }
30881
+ }
30882
+ return result;
30883
+ }
30406
30884
  // ─── Private ───────────────────────────────────
30407
30885
  /**
30408
30886
  * Find the on-disk directory for a provider by type.
@@ -30416,17 +30894,17 @@ var init_provider_loader = __esm({
30416
30894
  for (const root of searchRoots) {
30417
30895
  if (!fs6.existsSync(root)) continue;
30418
30896
  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);
30897
+ if (fs6.existsSync(path12.join(candidate, "provider.json"))) return candidate;
30898
+ const catDir = path12.join(root, cat);
30421
30899
  if (fs6.existsSync(catDir)) {
30422
30900
  try {
30423
30901
  for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
30424
30902
  if (!entry.isDirectory()) continue;
30425
- const jsonPath = path10.join(catDir, entry.name, "provider.json");
30903
+ const jsonPath = path12.join(catDir, entry.name, "provider.json");
30426
30904
  if (fs6.existsSync(jsonPath)) {
30427
30905
  try {
30428
30906
  const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
30429
- if (data.type === type) return path10.join(catDir, entry.name);
30907
+ if (data.type === type) return path12.join(catDir, entry.name);
30430
30908
  } catch {
30431
30909
  }
30432
30910
  }
@@ -30443,7 +30921,7 @@ var init_provider_loader = __esm({
30443
30921
  * (template substitution is NOT applied here — scripts.js handles that)
30444
30922
  */
30445
30923
  buildScriptWrappersFromDir(dir) {
30446
- const scriptsJs = path10.join(dir, "scripts.js");
30924
+ const scriptsJs = path12.join(dir, "scripts.js");
30447
30925
  if (fs6.existsSync(scriptsJs)) {
30448
30926
  try {
30449
30927
  delete require.cache[require.resolve(scriptsJs)];
@@ -30457,7 +30935,7 @@ var init_provider_loader = __esm({
30457
30935
  for (const file2 of fs6.readdirSync(dir)) {
30458
30936
  if (!file2.endsWith(".js")) continue;
30459
30937
  const scriptName = toCamel(file2.replace(".js", ""));
30460
- const filePath = path10.join(dir, file2);
30938
+ const filePath = path12.join(dir, file2);
30461
30939
  result[scriptName] = (...args) => {
30462
30940
  try {
30463
30941
  let content = fs6.readFileSync(filePath, "utf-8");
@@ -30517,7 +30995,7 @@ var init_provider_loader = __esm({
30517
30995
  }
30518
30996
  const hasJson = entries.some((e) => e.name === "provider.json");
30519
30997
  if (hasJson) {
30520
- const jsonPath = path10.join(d, "provider.json");
30998
+ const jsonPath = path12.join(d, "provider.json");
30521
30999
  try {
30522
31000
  const raw = fs6.readFileSync(jsonPath, "utf-8");
30523
31001
  const mod = JSON.parse(raw);
@@ -30530,7 +31008,7 @@ var init_provider_loader = __esm({
30530
31008
  delete mod.extensionIdPattern_flags;
30531
31009
  }
30532
31010
  const hasCompatibility = Array.isArray(mod.compatibility);
30533
- const scriptsPath = path10.join(d, "scripts.js");
31011
+ const scriptsPath = path12.join(d, "scripts.js");
30534
31012
  if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
30535
31013
  try {
30536
31014
  delete require.cache[require.resolve(scriptsPath)];
@@ -30556,7 +31034,7 @@ var init_provider_loader = __esm({
30556
31034
  if (!entry.isDirectory()) continue;
30557
31035
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
30558
31036
  if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
30559
- scan(path10.join(d, entry.name));
31037
+ scan(path12.join(d, entry.name));
30560
31038
  }
30561
31039
  }
30562
31040
  };
@@ -30653,17 +31131,17 @@ async function findFreePort(ports) {
30653
31131
  throw new Error("No free port found");
30654
31132
  }
30655
31133
  function checkPortFree(port) {
30656
- return new Promise((resolve13) => {
31134
+ return new Promise((resolve16) => {
30657
31135
  const server = net2.createServer();
30658
31136
  server.unref();
30659
- server.on("error", () => resolve13(false));
31137
+ server.on("error", () => resolve16(false));
30660
31138
  server.listen(port, "127.0.0.1", () => {
30661
- server.close(() => resolve13(true));
31139
+ server.close(() => resolve16(true));
30662
31140
  });
30663
31141
  });
30664
31142
  }
30665
31143
  async function isCdpActive(port) {
30666
- return new Promise((resolve13) => {
31144
+ return new Promise((resolve16) => {
30667
31145
  const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
30668
31146
  timeout: 2e3
30669
31147
  }, (res) => {
@@ -30672,16 +31150,16 @@ async function isCdpActive(port) {
30672
31150
  res.on("end", () => {
30673
31151
  try {
30674
31152
  const info = JSON.parse(data);
30675
- resolve13(!!info["WebKit-Version"] || !!info["Browser"]);
31153
+ resolve16(!!info["WebKit-Version"] || !!info["Browser"]);
30676
31154
  } catch {
30677
- resolve13(false);
31155
+ resolve16(false);
30678
31156
  }
30679
31157
  });
30680
31158
  });
30681
- req.on("error", () => resolve13(false));
31159
+ req.on("error", () => resolve16(false));
30682
31160
  req.on("timeout", () => {
30683
31161
  req.destroy();
30684
- resolve13(false);
31162
+ resolve16(false);
30685
31163
  });
30686
31164
  });
30687
31165
  }
@@ -30815,8 +31293,8 @@ function detectCurrentWorkspace(ideId) {
30815
31293
  const appNameMap = getMacAppIdentifiers();
30816
31294
  const appName = appNameMap[ideId];
30817
31295
  if (appName) {
30818
- const storagePath = path11.join(
30819
- process.env.APPDATA || path11.join(os13.homedir(), "AppData", "Roaming"),
31296
+ const storagePath = path13.join(
31297
+ process.env.APPDATA || path13.join(os13.homedir(), "AppData", "Roaming"),
30820
31298
  appName,
30821
31299
  "storage.json"
30822
31300
  );
@@ -30840,7 +31318,7 @@ function detectCurrentWorkspace(ideId) {
30840
31318
  async function launchWithCdp(options = {}) {
30841
31319
  const platform11 = os13.platform();
30842
31320
  let targetIde;
30843
- const ides = await detectIDEs();
31321
+ const ides = await detectIDEs(getProviderLoader());
30844
31322
  if (options.ideId) {
30845
31323
  targetIde = ides.find((i) => i.id === options.ideId && i.installed);
30846
31324
  if (!targetIde) {
@@ -30987,14 +31465,14 @@ async function launchLinux(ide, port, workspace, newWindow) {
30987
31465
  function getAvailableIdeIds() {
30988
31466
  return getProviderLoader().getAvailableIdeTypes();
30989
31467
  }
30990
- var import_child_process6, net2, os13, path11, _providerLoader;
31468
+ var import_child_process6, net2, os13, path13, _providerLoader;
30991
31469
  var init_launch = __esm({
30992
31470
  "../../oss/packages/daemon-core/src/launch.ts"() {
30993
31471
  "use strict";
30994
31472
  import_child_process6 = require("child_process");
30995
31473
  net2 = __toESM(require("net"));
30996
31474
  os13 = __toESM(require("os"));
30997
- path11 = __toESM(require("path"));
31475
+ path13 = __toESM(require("path"));
30998
31476
  init_ide_detector();
30999
31477
  init_provider_loader();
31000
31478
  _providerLoader = null;
@@ -31025,7 +31503,7 @@ function checkRotation() {
31025
31503
  const today = getDateStr2();
31026
31504
  if (today !== currentDate2) {
31027
31505
  currentDate2 = today;
31028
- currentFile = path12.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
31506
+ currentFile = path14.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
31029
31507
  cleanOldFiles();
31030
31508
  }
31031
31509
  }
@@ -31039,7 +31517,7 @@ function cleanOldFiles() {
31039
31517
  const dateMatch = file2.match(/commands-(\d{4}-\d{2}-\d{2})/);
31040
31518
  if (dateMatch && dateMatch[1] < cutoffStr) {
31041
31519
  try {
31042
- fs7.unlinkSync(path12.join(LOG_DIR2, file2));
31520
+ fs7.unlinkSync(path14.join(LOG_DIR2, file2));
31043
31521
  } catch {
31044
31522
  }
31045
31523
  }
@@ -31106,14 +31584,14 @@ function getRecentCommands(count = 50) {
31106
31584
  return [];
31107
31585
  }
31108
31586
  }
31109
- var fs7, path12, os14, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS;
31587
+ var fs7, path14, os14, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS;
31110
31588
  var init_command_log = __esm({
31111
31589
  "../../oss/packages/daemon-core/src/logging/command-log.ts"() {
31112
31590
  "use strict";
31113
31591
  fs7 = __toESM(require("fs"));
31114
- path12 = __toESM(require("path"));
31592
+ path14 = __toESM(require("path"));
31115
31593
  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");
31594
+ 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
31595
  MAX_FILE_SIZE = 5 * 1024 * 1024;
31118
31596
  MAX_DAYS = 7;
31119
31597
  try {
@@ -31132,7 +31610,7 @@ var init_command_log = __esm({
31132
31610
  "text"
31133
31611
  ]);
31134
31612
  currentDate2 = getDateStr2();
31135
- currentFile = path12.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
31613
+ currentFile = path14.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
31136
31614
  writeCount2 = 0;
31137
31615
  SKIP_COMMANDS = /* @__PURE__ */ new Set([
31138
31616
  "heartbeat",
@@ -31153,12 +31631,15 @@ function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
31153
31631
  }));
31154
31632
  }
31155
31633
  function buildAvailableProviders(providerLoader) {
31156
- return providerLoader.getAll().map((provider) => ({
31634
+ const providers = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
31635
+ return providers.map((provider) => ({
31157
31636
  type: provider.type,
31158
31637
  name: provider.displayName || provider.type,
31159
31638
  displayName: provider.displayName || provider.type,
31160
31639
  icon: provider.icon || "\u{1F4BB}",
31161
- category: provider.category
31640
+ category: provider.category,
31641
+ ...provider.installed !== void 0 ? { installed: provider.installed } : {},
31642
+ ...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {}
31162
31643
  }));
31163
31644
  }
31164
31645
  function parseMessageTime(value) {
@@ -31300,9 +31781,9 @@ var init_snapshot = __esm({
31300
31781
  // ../../oss/packages/daemon-core/src/commands/upgrade-helper.ts
31301
31782
  function getUpgradeLogPath() {
31302
31783
  const home = os16.homedir();
31303
- const dir = path13.join(home, ".adhdev");
31784
+ const dir = path15.join(home, ".adhdev");
31304
31785
  fs8.mkdirSync(dir, { recursive: true });
31305
- return path13.join(dir, "daemon-upgrade.log");
31786
+ return path15.join(dir, "daemon-upgrade.log");
31306
31787
  }
31307
31788
  function appendUpgradeLog(message) {
31308
31789
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
@@ -31335,14 +31816,14 @@ async function waitForPidExit(pid, timeoutMs) {
31335
31816
  while (Date.now() - start < timeoutMs) {
31336
31817
  try {
31337
31818
  process.kill(pid, 0);
31338
- await new Promise((resolve13) => setTimeout(resolve13, 250));
31819
+ await new Promise((resolve16) => setTimeout(resolve16, 250));
31339
31820
  } catch {
31340
31821
  return;
31341
31822
  }
31342
31823
  }
31343
31824
  }
31344
31825
  function stopSessionHostProcesses(appName) {
31345
- const pidFile = path13.join(os16.homedir(), ".adhdev", `${appName}-session-host.pid`);
31826
+ const pidFile = path15.join(os16.homedir(), ".adhdev", `${appName}-session-host.pid`);
31346
31827
  try {
31347
31828
  if (fs8.existsSync(pidFile)) {
31348
31829
  const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
@@ -31371,7 +31852,7 @@ function stopSessionHostProcesses(appName) {
31371
31852
  }
31372
31853
  }
31373
31854
  function removeDaemonPidFile() {
31374
- const pidFile = path13.join(os16.homedir(), ".adhdev", "daemon.pid");
31855
+ const pidFile = path15.join(os16.homedir(), ".adhdev", "daemon.pid");
31375
31856
  try {
31376
31857
  fs8.unlinkSync(pidFile);
31377
31858
  } catch {
@@ -31382,7 +31863,7 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
31382
31863
  const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
31383
31864
  if (!npmRoot) return;
31384
31865
  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");
31866
+ const binDir = process.platform === "win32" ? npmPrefix : path15.join(npmPrefix, "bin");
31386
31867
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
31387
31868
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
31388
31869
  if (pkgName === "@adhdev/daemon-standalone") {
@@ -31390,25 +31871,25 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
31390
31871
  }
31391
31872
  if (pkgName.startsWith("@")) {
31392
31873
  const [scope, name] = pkgName.split("/");
31393
- const scopeDir = path13.join(npmRoot, scope);
31874
+ const scopeDir = path15.join(npmRoot, scope);
31394
31875
  if (!fs8.existsSync(scopeDir)) return;
31395
31876
  for (const entry of fs8.readdirSync(scopeDir)) {
31396
31877
  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)}`);
31878
+ fs8.rmSync(path15.join(scopeDir, entry), { recursive: true, force: true });
31879
+ appendUpgradeLog(`Removed stale scoped staging dir: ${path15.join(scopeDir, entry)}`);
31399
31880
  }
31400
31881
  } else {
31401
31882
  for (const entry of fs8.readdirSync(npmRoot)) {
31402
31883
  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)}`);
31884
+ fs8.rmSync(path15.join(npmRoot, entry), { recursive: true, force: true });
31885
+ appendUpgradeLog(`Removed stale staging dir: ${path15.join(npmRoot, entry)}`);
31405
31886
  }
31406
31887
  }
31407
31888
  if (fs8.existsSync(binDir)) {
31408
31889
  for (const entry of fs8.readdirSync(binDir)) {
31409
31890
  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)}`);
31891
+ fs8.rmSync(path15.join(binDir, entry), { recursive: true, force: true });
31892
+ appendUpgradeLog(`Removed stale bin staging entry: ${path15.join(binDir, entry)}`);
31412
31893
  }
31413
31894
  }
31414
31895
  }
@@ -31450,7 +31931,7 @@ async function runDaemonUpgradeHelper(payload) {
31450
31931
  appendUpgradeLog(installOutput.trim());
31451
31932
  }
31452
31933
  if (process.platform === "win32") {
31453
- await new Promise((resolve13) => setTimeout(resolve13, 500));
31934
+ await new Promise((resolve16) => setTimeout(resolve16, 500));
31454
31935
  cleanupStaleGlobalInstallDirs(payload.packageName);
31455
31936
  appendUpgradeLog("Post-install staging cleanup complete");
31456
31937
  }
@@ -31483,7 +31964,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
31483
31964
  process.exit(1);
31484
31965
  }
31485
31966
  }
31486
- var import_child_process7, import_child_process8, fs8, os16, path13, UPGRADE_HELPER_ENV;
31967
+ var import_child_process7, import_child_process8, fs8, os16, path15, UPGRADE_HELPER_ENV;
31487
31968
  var init_upgrade_helper = __esm({
31488
31969
  "../../oss/packages/daemon-core/src/commands/upgrade-helper.ts"() {
31489
31970
  "use strict";
@@ -31491,7 +31972,7 @@ var init_upgrade_helper = __esm({
31491
31972
  import_child_process8 = require("child_process");
31492
31973
  fs8 = __toESM(require("fs"));
31493
31974
  os16 = __toESM(require("os"));
31494
- path13 = __toESM(require("path"));
31975
+ path15 = __toESM(require("path"));
31495
31976
  UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
31496
31977
  }
31497
31978
  });
@@ -31679,6 +32160,15 @@ var init_router = __esm({
31679
32160
  const record2 = await this.deps.sessionHostControl.forceDetachClient(sessionId, clientId);
31680
32161
  return { success: true, record: record2 };
31681
32162
  }
32163
+ case "session_host_prune_duplicate_sessions": {
32164
+ if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
32165
+ const result = await this.deps.sessionHostControl.pruneDuplicateSessions({
32166
+ providerType: typeof args?.providerType === "string" ? args.providerType : void 0,
32167
+ workspace: typeof args?.workspace === "string" ? args.workspace : void 0,
32168
+ dryRun: args?.dryRun === true
32169
+ });
32170
+ return { success: true, result };
32171
+ }
31682
32172
  case "session_host_acquire_write": {
31683
32173
  if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
31684
32174
  const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
@@ -31761,6 +32251,12 @@ var init_router = __esm({
31761
32251
  if (!ideType) throw new Error("ideType required");
31762
32252
  const killProcess = args?.killProcess !== false;
31763
32253
  await this.stopIde(ideType, killProcess);
32254
+ try {
32255
+ const results = await detectIDEs(this.deps.providerLoader);
32256
+ this.deps.detectedIdes.value = results;
32257
+ this.deps.providerLoader.setIdeDetectionResults(results, true);
32258
+ } catch {
32259
+ }
31764
32260
  return { success: true, ideType, stopped: true, processKilled: killProcess };
31765
32261
  }
31766
32262
  // ─── IDE restart ───
@@ -31803,6 +32299,12 @@ var init_router = __esm({
31803
32299
  }
31804
32300
  }
31805
32301
  this.deps.onIdeConnected?.();
32302
+ try {
32303
+ const results = await detectIDEs(this.deps.providerLoader);
32304
+ this.deps.detectedIdes.value = results;
32305
+ this.deps.providerLoader.setIdeDetectionResults(results, true);
32306
+ } catch {
32307
+ }
31806
32308
  if (result.success && resolvedWorkspace) {
31807
32309
  try {
31808
32310
  const next = appendRecentActivity(loadState(), {
@@ -31830,8 +32332,9 @@ var init_router = __esm({
31830
32332
  }
31831
32333
  // ─── Detect IDEs ───
31832
32334
  case "detect_ides": {
31833
- const results = await detectIDEs();
32335
+ const results = await detectIDEs(this.deps.providerLoader);
31834
32336
  this.deps.detectedIdes.value = results;
32337
+ this.deps.providerLoader.setIdeDetectionResults(results, true);
31835
32338
  return { success: true, detectedInfo: results };
31836
32339
  }
31837
32340
  // ─── Set User Name ───
@@ -32269,6 +32772,51 @@ var init_provider_adapter = __esm({
32269
32772
  isTransportError(reason) {
32270
32773
  return /Session with given id not found/i.test(reason) || /CDP not connected/i.test(reason) || /Target closed/i.test(reason) || /WebSocket not open/i.test(reason) || /not connected/i.test(reason) || /execution context/i.test(reason) || /Cannot find context with specified id/i.test(reason);
32271
32774
  }
32775
+ titlesMatch(actual, expected) {
32776
+ const lhs = actual.trim().toLowerCase();
32777
+ const rhs = expected.trim().toLowerCase();
32778
+ if (!lhs || !rhs) return false;
32779
+ return lhs === rhs || lhs.includes(rhs) || rhs.includes(lhs);
32780
+ }
32781
+ messageCount(state) {
32782
+ return Array.isArray(state?.messages) ? state.messages.length : 0;
32783
+ }
32784
+ lastMessageSignature(state) {
32785
+ const messages = Array.isArray(state?.messages) ? state.messages : [];
32786
+ const last = messages[messages.length - 1];
32787
+ if (!last) return "";
32788
+ return `${last.role || ""}:${String(last.content || "").replace(/\s+/g, " ").trim()}`;
32789
+ }
32790
+ async verifySendOutcome(evaluate, before) {
32791
+ const beforeCount = this.messageCount(before);
32792
+ const beforeSignature = this.lastMessageSignature(before);
32793
+ for (let attempt = 0; attempt < 12; attempt += 1) {
32794
+ await new Promise((resolve16) => setTimeout(resolve16, 250));
32795
+ let state;
32796
+ try {
32797
+ state = await this.readChat(evaluate);
32798
+ } catch {
32799
+ continue;
32800
+ }
32801
+ if (state.status === "waiting_approval") {
32802
+ return true;
32803
+ }
32804
+ const afterCount = this.messageCount(state);
32805
+ const afterSignature = this.lastMessageSignature(state);
32806
+ if (afterCount > beforeCount) return true;
32807
+ if (afterSignature && afterSignature !== beforeSignature) return true;
32808
+ }
32809
+ return false;
32810
+ }
32811
+ async readStableBaselineState(evaluate) {
32812
+ const first = await this.readChat(evaluate);
32813
+ if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
32814
+ return first;
32815
+ }
32816
+ await new Promise((resolve16) => setTimeout(resolve16, 150));
32817
+ const second = await this.readChat(evaluate);
32818
+ return this.messageCount(second) >= this.messageCount(first) ? second : first;
32819
+ }
32272
32820
  async readChat(evaluate) {
32273
32821
  const script = this.callScript("readChat");
32274
32822
  if (!script) return this.errorState("readChat script not available");
@@ -32294,6 +32842,9 @@ var init_provider_adapter = __esm({
32294
32842
  mode: data.mode,
32295
32843
  activeModal: data.activeModal
32296
32844
  };
32845
+ if (typeof data.title === "string" && data.title.trim()) {
32846
+ state.title = data.title.trim();
32847
+ }
32297
32848
  const controlValues = extractProviderControlValues(this.provider.controls, data);
32298
32849
  if (controlValues) state.controlValues = controlValues;
32299
32850
  const effects = normalizeProviderEffects(data);
@@ -32317,6 +32868,12 @@ var init_provider_adapter = __esm({
32317
32868
  }
32318
32869
  }
32319
32870
  async sendMessage(evaluate, text) {
32871
+ let beforeState = null;
32872
+ try {
32873
+ beforeState = await this.readStableBaselineState(evaluate);
32874
+ } catch {
32875
+ beforeState = null;
32876
+ }
32320
32877
  const params = { message: text };
32321
32878
  const script = this.callScript("sendMessage", params) || this.callScript("sendMessage", text);
32322
32879
  if (!script) throw new Error(`[${this.agentName}] sendMessage script not available`);
@@ -32334,7 +32891,9 @@ var init_provider_adapter = __esm({
32334
32891
  }
32335
32892
  if (parsed && typeof parsed === "object") {
32336
32893
  if (parsed.sent === true || parsed.success === true || parsed.ok === true || parsed.submitted === true || parsed.dispatched === true) {
32337
- return;
32894
+ const verified = await this.verifySendOutcome(evaluate, beforeState);
32895
+ if (verified) return;
32896
+ throw new Error(`[${this.agentName}] sendMessage was not observed in chat state`);
32338
32897
  }
32339
32898
  if (typeof parsed.error === "string" && parsed.error.trim()) {
32340
32899
  throw new Error(`[${this.agentName}] sendMessage failed: ${parsed.error}`);
@@ -32345,7 +32904,15 @@ var init_provider_adapter = __esm({
32345
32904
  async resolveAction(evaluate, action, button) {
32346
32905
  const script = this.callScript("resolveAction", { action, button });
32347
32906
  if (!script) return false;
32348
- return await evaluate(script) === true;
32907
+ const result = await evaluate(script);
32908
+ const parsed = this.parseMaybeJson(result);
32909
+ if (parsed === true) return true;
32910
+ if (typeof parsed === "string") {
32911
+ const normalized = parsed.trim().toLowerCase();
32912
+ return normalized === "ok" || normalized === "success" || normalized === "true" || normalized === "resolved" || normalized === "approved" || normalized === "rejected";
32913
+ }
32914
+ if (!parsed || typeof parsed !== "object") return false;
32915
+ return parsed.resolved === true || parsed.success === true || parsed.ok === true || parsed.found === true;
32349
32916
  }
32350
32917
  async newSession(evaluate) {
32351
32918
  const script = this.callScript("newSession");
@@ -32363,7 +32930,10 @@ var init_provider_adapter = __esm({
32363
32930
  const raw = await evaluate(script, 1e4);
32364
32931
  const data = typeof raw === "string" ? JSON.parse(raw) : raw;
32365
32932
  if (data?.error) return [];
32366
- return Array.isArray(data) ? data : [];
32933
+ if (Array.isArray(data)) return data;
32934
+ if (Array.isArray(data?.sessions)) return data.sessions;
32935
+ if (Array.isArray(data?.chats)) return data.chats;
32936
+ return [];
32367
32937
  } catch {
32368
32938
  return [];
32369
32939
  }
@@ -32371,7 +32941,24 @@ var init_provider_adapter = __esm({
32371
32941
  async switchSession(evaluate, sessionId) {
32372
32942
  const script = this.callScript("switchSession", sessionId);
32373
32943
  if (!script) return false;
32374
- return await evaluate(script, 1e4) === true;
32944
+ const raw = await evaluate(script, 1e4);
32945
+ const data = this.parseMaybeJson(raw);
32946
+ if (data === true) return true;
32947
+ if (typeof data === "string") {
32948
+ const normalized = data.trim().toLowerCase();
32949
+ return normalized === "true" || normalized === "ok" || normalized === "switched" || normalized === "success";
32950
+ }
32951
+ if (data && typeof data === "object") {
32952
+ if (data.switched === true || data.success === true || data.ok === true) return true;
32953
+ if (typeof data.error === "string" && data.error.trim()) return false;
32954
+ }
32955
+ for (let attempt = 0; attempt < 6; attempt += 1) {
32956
+ await new Promise((resolve16) => setTimeout(resolve16, 250));
32957
+ const state = await this.readChat(evaluate);
32958
+ const title = typeof state.title === "string" ? state.title : "";
32959
+ if (this.titlesMatch(title, sessionId)) return true;
32960
+ }
32961
+ return false;
32375
32962
  }
32376
32963
  async focusEditor(evaluate) {
32377
32964
  const script = this.callScript("focusEditor");
@@ -32584,7 +33171,7 @@ var init_manager2 = __esm({
32584
33171
  return false;
32585
33172
  }
32586
33173
  }
32587
- async resolveSessionAction(cdp, sessionId, action) {
33174
+ async resolveSessionAction(cdp, sessionId, action, button) {
32588
33175
  await this.ensureSessionPanelOpen(sessionId);
32589
33176
  const target = this.getSessionTarget(sessionId);
32590
33177
  if (!target?.parentSessionId) return false;
@@ -32594,7 +33181,7 @@ var init_manager2 = __esm({
32594
33181
  if (!agent) return false;
32595
33182
  try {
32596
33183
  const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
32597
- return await agent.adapter.resolveAction(evaluate, action);
33184
+ return await agent.adapter.resolveAction(evaluate, action, button);
32598
33185
  } catch (e) {
32599
33186
  this.logFn(`[AgentStream] resolveAction(${sessionId}) error: ${e.message}`);
32600
33187
  return false;
@@ -33141,7 +33728,7 @@ function checkPathExists2(paths) {
33141
33728
  for (const p of paths) {
33142
33729
  if (p.includes("*")) {
33143
33730
  const home = os17.homedir();
33144
- const resolved = p.replace(/\*/g, home.split(path14.sep).pop() || "");
33731
+ const resolved = p.replace(/\*/g, home.split(path16.sep).pop() || "");
33145
33732
  if (fs10.existsSync(resolved)) return resolved;
33146
33733
  } else {
33147
33734
  if (fs10.existsSync(p)) return p;
@@ -33151,7 +33738,7 @@ function checkPathExists2(paths) {
33151
33738
  }
33152
33739
  function getMacAppVersion(appPath) {
33153
33740
  if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
33154
- const plistPath = path14.join(appPath, "Contents", "Info.plist");
33741
+ const plistPath = path16.join(appPath, "Contents", "Info.plist");
33155
33742
  if (!fs10.existsSync(plistPath)) return null;
33156
33743
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
33157
33744
  return raw || null;
@@ -33178,7 +33765,7 @@ async function detectAllVersions(loader, archive) {
33178
33765
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
33179
33766
  let resolvedBin = cliBin;
33180
33767
  if (!resolvedBin && appPath && currentOs === "darwin") {
33181
- const bundled = path14.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
33768
+ const bundled = path16.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
33182
33769
  if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
33183
33770
  }
33184
33771
  info.installed = !!(appPath || resolvedBin);
@@ -33215,16 +33802,16 @@ async function detectAllVersions(loader, archive) {
33215
33802
  }
33216
33803
  return results;
33217
33804
  }
33218
- var fs10, path14, os17, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
33805
+ var fs10, path16, os17, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
33219
33806
  var init_version_archive = __esm({
33220
33807
  "../../oss/packages/daemon-core/src/providers/version-archive.ts"() {
33221
33808
  "use strict";
33222
33809
  fs10 = __toESM(require("fs"));
33223
- path14 = __toESM(require("path"));
33810
+ path16 = __toESM(require("path"));
33224
33811
  os17 = __toESM(require("os"));
33225
33812
  import_child_process9 = require("child_process");
33226
33813
  import_os3 = require("os");
33227
- ARCHIVE_PATH = path14.join(os17.homedir(), ".adhdev", "version-history.json");
33814
+ ARCHIVE_PATH = path16.join(os17.homedir(), ".adhdev", "version-history.json");
33228
33815
  MAX_ENTRIES_PER_PROVIDER = 20;
33229
33816
  VersionArchive = class {
33230
33817
  history = {};
@@ -33271,7 +33858,7 @@ var init_version_archive = __esm({
33271
33858
  }
33272
33859
  save() {
33273
33860
  try {
33274
- fs10.mkdirSync(path14.dirname(ARCHIVE_PATH), { recursive: true });
33861
+ fs10.mkdirSync(path16.dirname(ARCHIVE_PATH), { recursive: true });
33275
33862
  fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
33276
33863
  } catch {
33277
33864
  }
@@ -33792,17 +34379,17 @@ async function handleScriptHints(ctx, type, _req, res) {
33792
34379
  return;
33793
34380
  }
33794
34381
  let scriptsPath = "";
33795
- const directScripts = path15.join(dir, "scripts.js");
34382
+ const directScripts = path17.join(dir, "scripts.js");
33796
34383
  if (fs11.existsSync(directScripts)) {
33797
34384
  scriptsPath = directScripts;
33798
34385
  } else {
33799
- const scriptsDir = path15.join(dir, "scripts");
34386
+ const scriptsDir = path17.join(dir, "scripts");
33800
34387
  if (fs11.existsSync(scriptsDir)) {
33801
34388
  const versions = fs11.readdirSync(scriptsDir).filter((d) => {
33802
- return fs11.statSync(path15.join(scriptsDir, d)).isDirectory();
34389
+ return fs11.statSync(path17.join(scriptsDir, d)).isDirectory();
33803
34390
  }).sort().reverse();
33804
34391
  for (const ver of versions) {
33805
- const p = path15.join(scriptsDir, ver, "scripts.js");
34392
+ const p = path17.join(scriptsDir, ver, "scripts.js");
33806
34393
  if (fs11.existsSync(p)) {
33807
34394
  scriptsPath = p;
33808
34395
  break;
@@ -34618,12 +35205,12 @@ async function handleDomContext(ctx, type, req, res) {
34618
35205
  ctx.json(res, 500, { error: `DOM context collection failed: ${e.message}` });
34619
35206
  }
34620
35207
  }
34621
- var fs11, path15;
35208
+ var fs11, path17;
34622
35209
  var init_dev_cdp_handlers = __esm({
34623
35210
  "../../oss/packages/daemon-core/src/daemon/dev-cdp-handlers.ts"() {
34624
35211
  "use strict";
34625
35212
  fs11 = __toESM(require("fs"));
34626
- path15 = __toESM(require("path"));
35213
+ path17 = __toESM(require("path"));
34627
35214
  init_logger();
34628
35215
  }
34629
35216
  });
@@ -34638,11 +35225,11 @@ function getCliFixtureDir(ctx, type) {
34638
35225
  if (!providerDir) {
34639
35226
  throw new Error(`Provider directory not found for '${type}'`);
34640
35227
  }
34641
- return path16.join(providerDir, "fixtures");
35228
+ return path18.join(providerDir, "fixtures");
34642
35229
  }
34643
35230
  function readCliFixture(ctx, type, name) {
34644
35231
  const fixtureDir = getCliFixtureDir(ctx, type);
34645
- const filePath = path16.join(fixtureDir, `${name}.json`);
35232
+ const filePath = path18.join(fixtureDir, `${name}.json`);
34646
35233
  if (!fs12.existsSync(filePath)) {
34647
35234
  throw new Error(`Fixture not found: ${filePath}`);
34648
35235
  }
@@ -34802,7 +35389,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
34802
35389
  return { target, instance, adapter };
34803
35390
  }
34804
35391
  function sleep(ms) {
34805
- return new Promise((resolve13) => setTimeout(resolve13, ms));
35392
+ return new Promise((resolve16) => setTimeout(resolve16, ms));
34806
35393
  }
34807
35394
  async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
34808
35395
  const startedAt = Date.now();
@@ -35401,7 +35988,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
35401
35988
  },
35402
35989
  notes: typeof body?.notes === "string" ? body.notes : void 0
35403
35990
  };
35404
- const filePath = path16.join(fixtureDir, `${name}.json`);
35991
+ const filePath = path18.join(fixtureDir, `${name}.json`);
35405
35992
  fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
35406
35993
  ctx.json(res, 200, {
35407
35994
  saved: true,
@@ -35425,7 +36012,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
35425
36012
  return;
35426
36013
  }
35427
36014
  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);
36015
+ const fullPath = path18.join(fixtureDir, file2);
35429
36016
  try {
35430
36017
  const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
35431
36018
  return {
@@ -35558,12 +36145,12 @@ async function handleCliRaw(ctx, req, res) {
35558
36145
  ctx.json(res, 500, { error: `Raw send failed: ${e.message}` });
35559
36146
  }
35560
36147
  }
35561
- var fs12, path16;
36148
+ var fs12, path18;
35562
36149
  var init_dev_cli_debug = __esm({
35563
36150
  "../../oss/packages/daemon-core/src/daemon/dev-cli-debug.ts"() {
35564
36151
  "use strict";
35565
36152
  fs12 = __toESM(require("fs"));
35566
- path16 = __toESM(require("path"));
36153
+ path18 = __toESM(require("path"));
35567
36154
  }
35568
36155
  });
35569
36156
 
@@ -35606,22 +36193,22 @@ function getLatestScriptVersionDir(scriptsDir) {
35606
36193
  if (!fs13.existsSync(scriptsDir)) return null;
35607
36194
  const versions = fs13.readdirSync(scriptsDir).filter((d) => {
35608
36195
  try {
35609
- return fs13.statSync(path17.join(scriptsDir, d)).isDirectory();
36196
+ return fs13.statSync(path19.join(scriptsDir, d)).isDirectory();
35610
36197
  } catch {
35611
36198
  return false;
35612
36199
  }
35613
36200
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
35614
36201
  if (versions.length === 0) return null;
35615
- return path17.join(scriptsDir, versions[0]);
36202
+ return path19.join(scriptsDir, versions[0]);
35616
36203
  }
35617
36204
  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}`)) {
36205
+ const canonicalUserDir = path19.resolve(ctx.providerLoader.getUserProviderDir(category, type));
36206
+ const desiredDir = requestedDir ? path19.resolve(requestedDir) : canonicalUserDir;
36207
+ const upstreamRoot = path19.resolve(ctx.providerLoader.getUpstreamDir());
36208
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path19.sep}`)) {
35622
36209
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
35623
36210
  }
35624
- if (path17.basename(desiredDir) !== type) {
36211
+ if (path19.basename(desiredDir) !== type) {
35625
36212
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
35626
36213
  }
35627
36214
  const sourceDir = ctx.findProviderDir(type);
@@ -35629,11 +36216,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
35629
36216
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
35630
36217
  }
35631
36218
  if (!fs13.existsSync(desiredDir)) {
35632
- fs13.mkdirSync(path17.dirname(desiredDir), { recursive: true });
36219
+ fs13.mkdirSync(path19.dirname(desiredDir), { recursive: true });
35633
36220
  fs13.cpSync(sourceDir, desiredDir, { recursive: true });
35634
36221
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
35635
36222
  }
35636
- const providerJson = path17.join(desiredDir, "provider.json");
36223
+ const providerJson = path19.join(desiredDir, "provider.json");
35637
36224
  if (!fs13.existsSync(providerJson)) {
35638
36225
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
35639
36226
  }
@@ -35656,13 +36243,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
35656
36243
  const refDir = ctx.findProviderDir(referenceType);
35657
36244
  if (!refDir || !fs13.existsSync(refDir)) return {};
35658
36245
  const referenceScripts = {};
35659
- const scriptsDir = path17.join(refDir, "scripts");
36246
+ const scriptsDir = path19.join(refDir, "scripts");
35660
36247
  const latestDir = getLatestScriptVersionDir(scriptsDir);
35661
36248
  if (!latestDir) return referenceScripts;
35662
36249
  for (const file2 of fs13.readdirSync(latestDir)) {
35663
36250
  if (!file2.endsWith(".js")) continue;
35664
36251
  try {
35665
- referenceScripts[file2] = fs13.readFileSync(path17.join(latestDir, file2), "utf-8");
36252
+ referenceScripts[file2] = fs13.readFileSync(path19.join(latestDir, file2), "utf-8");
35666
36253
  } catch {
35667
36254
  }
35668
36255
  }
@@ -35770,9 +36357,9 @@ async function handleAutoImplement(ctx, type, req, res) {
35770
36357
  });
35771
36358
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
35772
36359
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
35773
- const tmpDir = path17.join(os18.tmpdir(), "adhdev-autoimpl");
36360
+ const tmpDir = path19.join(os18.tmpdir(), "adhdev-autoimpl");
35774
36361
  if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
35775
- const promptFile = path17.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
36362
+ const promptFile = path19.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
35776
36363
  fs13.writeFileSync(promptFile, prompt, "utf-8");
35777
36364
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
35778
36365
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
@@ -36199,7 +36786,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
36199
36786
  setMode: "set_mode.js"
36200
36787
  };
36201
36788
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
36202
- const scriptsDir = path17.join(providerDir, "scripts");
36789
+ const scriptsDir = path19.join(providerDir, "scripts");
36203
36790
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
36204
36791
  if (latestScriptsDir) {
36205
36792
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -36210,7 +36797,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
36210
36797
  for (const file2 of fs13.readdirSync(latestScriptsDir)) {
36211
36798
  if (file2.endsWith(".js") && targetFileNames.has(file2)) {
36212
36799
  try {
36213
- const content = fs13.readFileSync(path17.join(latestScriptsDir, file2), "utf-8");
36800
+ const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
36214
36801
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
36215
36802
  lines.push("```javascript");
36216
36803
  lines.push(content);
@@ -36227,7 +36814,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
36227
36814
  lines.push("");
36228
36815
  for (const file2 of refFiles) {
36229
36816
  try {
36230
- const content = fs13.readFileSync(path17.join(latestScriptsDir, file2), "utf-8");
36817
+ const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
36231
36818
  lines.push(`### \`${file2}\` \u{1F512}`);
36232
36819
  lines.push("```javascript");
36233
36820
  lines.push(content);
@@ -36268,10 +36855,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
36268
36855
  lines.push("");
36269
36856
  }
36270
36857
  }
36271
- const docsDir = path17.join(providerDir, "../../docs");
36858
+ const docsDir = path19.join(providerDir, "../../docs");
36272
36859
  const loadGuide = (name) => {
36273
36860
  try {
36274
- const p = path17.join(docsDir, name);
36861
+ const p = path19.join(docsDir, name);
36275
36862
  if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
36276
36863
  } catch {
36277
36864
  }
@@ -36506,7 +37093,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
36506
37093
  parseApproval: "parse_approval.js"
36507
37094
  };
36508
37095
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
36509
- const scriptsDir = path17.join(providerDir, "scripts");
37096
+ const scriptsDir = path19.join(providerDir, "scripts");
36510
37097
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
36511
37098
  if (latestScriptsDir) {
36512
37099
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -36518,7 +37105,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
36518
37105
  if (!file2.endsWith(".js")) continue;
36519
37106
  if (!targetFileNames.has(file2)) continue;
36520
37107
  try {
36521
- const content = fs13.readFileSync(path17.join(latestScriptsDir, file2), "utf-8");
37108
+ const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
36522
37109
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
36523
37110
  lines.push("```javascript");
36524
37111
  lines.push(content);
@@ -36534,7 +37121,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
36534
37121
  lines.push("");
36535
37122
  for (const file2 of refFiles) {
36536
37123
  try {
36537
- const content = fs13.readFileSync(path17.join(latestScriptsDir, file2), "utf-8");
37124
+ const content = fs13.readFileSync(path19.join(latestScriptsDir, file2), "utf-8");
36538
37125
  lines.push(`### \`${file2}\` \u{1F512}`);
36539
37126
  lines.push("```javascript");
36540
37127
  lines.push(content);
@@ -36567,10 +37154,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
36567
37154
  lines.push("");
36568
37155
  }
36569
37156
  }
36570
- const docsDir = path17.join(providerDir, "../../docs");
37157
+ const docsDir = path19.join(providerDir, "../../docs");
36571
37158
  const loadGuide = (name) => {
36572
37159
  try {
36573
- const p = path17.join(docsDir, name);
37160
+ const p = path19.join(docsDir, name);
36574
37161
  if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
36575
37162
  } catch {
36576
37163
  }
@@ -36882,12 +37469,12 @@ data: ${JSON.stringify(msg.data)}
36882
37469
  }
36883
37470
  }
36884
37471
  }
36885
- var fs13, path17, os18;
37472
+ var fs13, path19, os18;
36886
37473
  var init_dev_auto_implement = __esm({
36887
37474
  "../../oss/packages/daemon-core/src/daemon/dev-auto-implement.ts"() {
36888
37475
  "use strict";
36889
37476
  fs13 = __toESM(require("fs"));
36890
- path17 = __toESM(require("path"));
37477
+ path19 = __toESM(require("path"));
36891
37478
  os18 = __toESM(require("os"));
36892
37479
  init_dev_server();
36893
37480
  init_dev_cli_debug();
@@ -36895,13 +37482,13 @@ var init_dev_auto_implement = __esm({
36895
37482
  });
36896
37483
 
36897
37484
  // ../../oss/packages/daemon-core/src/daemon/dev-server.ts
36898
- var http2, fs14, path18, DEV_SERVER_PORT, DevServer;
37485
+ var http2, fs14, path20, DEV_SERVER_PORT, DevServer;
36899
37486
  var init_dev_server = __esm({
36900
37487
  "../../oss/packages/daemon-core/src/daemon/dev-server.ts"() {
36901
37488
  "use strict";
36902
37489
  http2 = __toESM(require("http"));
36903
37490
  fs14 = __toESM(require("fs"));
36904
- path18 = __toESM(require("path"));
37491
+ path20 = __toESM(require("path"));
36905
37492
  init_scaffold_template();
36906
37493
  init_version_archive();
36907
37494
  init_logger();
@@ -37005,8 +37592,8 @@ var init_dev_server = __esm({
37005
37592
  }
37006
37593
  getEndpointList() {
37007
37594
  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}`;
37595
+ const path25 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
37596
+ return `${r.method.padEnd(5)} ${path25}`;
37010
37597
  });
37011
37598
  }
37012
37599
  async start(port = DEV_SERVER_PORT) {
@@ -37037,15 +37624,15 @@ var init_dev_server = __esm({
37037
37624
  this.json(res, 500, { error: e.message });
37038
37625
  }
37039
37626
  });
37040
- return new Promise((resolve13, reject) => {
37627
+ return new Promise((resolve16, reject) => {
37041
37628
  this.server.listen(port, "127.0.0.1", () => {
37042
37629
  this.log(`Dev server listening on http://127.0.0.1:${port}`);
37043
- resolve13();
37630
+ resolve16();
37044
37631
  });
37045
37632
  this.server.on("error", (e) => {
37046
37633
  if (e.code === "EADDRINUSE") {
37047
37634
  this.log(`Port ${port} in use, skipping dev server`);
37048
- resolve13();
37635
+ resolve16();
37049
37636
  } else {
37050
37637
  reject(e);
37051
37638
  }
@@ -37128,20 +37715,20 @@ var init_dev_server = __esm({
37128
37715
  child.stderr?.on("data", (d) => {
37129
37716
  stderr += d.toString().slice(0, 2e3);
37130
37717
  });
37131
- await new Promise((resolve13) => {
37718
+ await new Promise((resolve16) => {
37132
37719
  const timer = setTimeout(() => {
37133
37720
  child.kill();
37134
- resolve13();
37721
+ resolve16();
37135
37722
  }, 3e3);
37136
37723
  child.on("exit", () => {
37137
37724
  clearTimeout(timer);
37138
- resolve13();
37725
+ resolve16();
37139
37726
  });
37140
37727
  child.stdout?.once("data", () => {
37141
37728
  setTimeout(() => {
37142
37729
  child.kill();
37143
37730
  clearTimeout(timer);
37144
- resolve13();
37731
+ resolve16();
37145
37732
  }, 500);
37146
37733
  });
37147
37734
  });
@@ -37288,12 +37875,12 @@ var init_dev_server = __esm({
37288
37875
  // ─── DevConsole SPA ───
37289
37876
  getConsoleDistDir() {
37290
37877
  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")
37878
+ path20.resolve(__dirname, "../../web-devconsole/dist"),
37879
+ path20.resolve(__dirname, "../../../web-devconsole/dist"),
37880
+ path20.join(process.cwd(), "packages/web-devconsole/dist")
37294
37881
  ];
37295
37882
  for (const dir of candidates) {
37296
- if (fs14.existsSync(path18.join(dir, "index.html"))) return dir;
37883
+ if (fs14.existsSync(path20.join(dir, "index.html"))) return dir;
37297
37884
  }
37298
37885
  return null;
37299
37886
  }
@@ -37303,7 +37890,7 @@ var init_dev_server = __esm({
37303
37890
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
37304
37891
  return;
37305
37892
  }
37306
- const htmlPath = path18.join(distDir, "index.html");
37893
+ const htmlPath = path20.join(distDir, "index.html");
37307
37894
  try {
37308
37895
  const html = fs14.readFileSync(htmlPath, "utf-8");
37309
37896
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -37328,15 +37915,15 @@ var init_dev_server = __esm({
37328
37915
  this.json(res, 404, { error: "Not found" });
37329
37916
  return;
37330
37917
  }
37331
- const safePath = path18.normalize(pathname).replace(/^\.\.\//, "");
37332
- const filePath = path18.join(distDir, safePath);
37918
+ const safePath = path20.normalize(pathname).replace(/^\.\.\//, "");
37919
+ const filePath = path20.join(distDir, safePath);
37333
37920
  if (!filePath.startsWith(distDir)) {
37334
37921
  this.json(res, 403, { error: "Forbidden" });
37335
37922
  return;
37336
37923
  }
37337
37924
  try {
37338
37925
  const content = fs14.readFileSync(filePath);
37339
- const ext = path18.extname(filePath);
37926
+ const ext = path20.extname(filePath);
37340
37927
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
37341
37928
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
37342
37929
  res.end(content);
@@ -37449,9 +38036,9 @@ var init_dev_server = __esm({
37449
38036
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
37450
38037
  if (entry.isDirectory()) {
37451
38038
  files.push({ path: rel, size: 0, type: "dir" });
37452
- scan(path18.join(d, entry.name), rel);
38039
+ scan(path20.join(d, entry.name), rel);
37453
38040
  } else {
37454
- const stat4 = fs14.statSync(path18.join(d, entry.name));
38041
+ const stat4 = fs14.statSync(path20.join(d, entry.name));
37455
38042
  files.push({ path: rel, size: stat4.size, type: "file" });
37456
38043
  }
37457
38044
  }
@@ -37474,7 +38061,7 @@ var init_dev_server = __esm({
37474
38061
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
37475
38062
  return;
37476
38063
  }
37477
- const fullPath = path18.resolve(dir, path18.normalize(filePath));
38064
+ const fullPath = path20.resolve(dir, path20.normalize(filePath));
37478
38065
  if (!fullPath.startsWith(dir)) {
37479
38066
  this.json(res, 403, { error: "Forbidden" });
37480
38067
  return;
@@ -37499,14 +38086,14 @@ var init_dev_server = __esm({
37499
38086
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
37500
38087
  return;
37501
38088
  }
37502
- const fullPath = path18.resolve(dir, path18.normalize(filePath));
38089
+ const fullPath = path20.resolve(dir, path20.normalize(filePath));
37503
38090
  if (!fullPath.startsWith(dir)) {
37504
38091
  this.json(res, 403, { error: "Forbidden" });
37505
38092
  return;
37506
38093
  }
37507
38094
  try {
37508
38095
  if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
37509
- fs14.mkdirSync(path18.dirname(fullPath), { recursive: true });
38096
+ fs14.mkdirSync(path20.dirname(fullPath), { recursive: true });
37510
38097
  fs14.writeFileSync(fullPath, content, "utf-8");
37511
38098
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
37512
38099
  this.providerLoader.reload();
@@ -37523,7 +38110,7 @@ var init_dev_server = __esm({
37523
38110
  return;
37524
38111
  }
37525
38112
  for (const name of ["scripts.js", "provider.json"]) {
37526
- const p = path18.join(dir, name);
38113
+ const p = path20.join(dir, name);
37527
38114
  if (fs14.existsSync(p)) {
37528
38115
  const source = fs14.readFileSync(p, "utf-8");
37529
38116
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
@@ -37544,8 +38131,8 @@ var init_dev_server = __esm({
37544
38131
  this.json(res, 404, { error: `Provider not found: ${type}` });
37545
38132
  return;
37546
38133
  }
37547
- const target = fs14.existsSync(path18.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
37548
- const targetPath = path18.join(dir, target);
38134
+ const target = fs14.existsSync(path20.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
38135
+ const targetPath = path20.join(dir, target);
37549
38136
  try {
37550
38137
  if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
37551
38138
  fs14.writeFileSync(targetPath, source, "utf-8");
@@ -37650,14 +38237,14 @@ var init_dev_server = __esm({
37650
38237
  child.stderr?.on("data", (d) => {
37651
38238
  stderr += d.toString();
37652
38239
  });
37653
- await new Promise((resolve13) => {
38240
+ await new Promise((resolve16) => {
37654
38241
  const timer = setTimeout(() => {
37655
38242
  child.kill();
37656
- resolve13();
38243
+ resolve16();
37657
38244
  }, timeout);
37658
38245
  child.on("exit", () => {
37659
38246
  clearTimeout(timer);
37660
- resolve13();
38247
+ resolve16();
37661
38248
  });
37662
38249
  });
37663
38250
  const elapsed = Date.now() - start;
@@ -37705,7 +38292,7 @@ var init_dev_server = __esm({
37705
38292
  }
37706
38293
  let targetDir;
37707
38294
  targetDir = this.providerLoader.getUserProviderDir(category, type);
37708
- const jsonPath = path18.join(targetDir, "provider.json");
38295
+ const jsonPath = path20.join(targetDir, "provider.json");
37709
38296
  if (fs14.existsSync(jsonPath)) {
37710
38297
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
37711
38298
  return;
@@ -37717,8 +38304,8 @@ var init_dev_server = __esm({
37717
38304
  const createdFiles = ["provider.json"];
37718
38305
  if (result.files) {
37719
38306
  for (const [relPath, content] of Object.entries(result.files)) {
37720
- const fullPath = path18.join(targetDir, relPath);
37721
- fs14.mkdirSync(path18.dirname(fullPath), { recursive: true });
38307
+ const fullPath = path20.join(targetDir, relPath);
38308
+ fs14.mkdirSync(path20.dirname(fullPath), { recursive: true });
37722
38309
  fs14.writeFileSync(fullPath, content, "utf-8");
37723
38310
  createdFiles.push(relPath);
37724
38311
  }
@@ -37771,22 +38358,22 @@ var init_dev_server = __esm({
37771
38358
  if (!fs14.existsSync(scriptsDir)) return null;
37772
38359
  const versions = fs14.readdirSync(scriptsDir).filter((d) => {
37773
38360
  try {
37774
- return fs14.statSync(path18.join(scriptsDir, d)).isDirectory();
38361
+ return fs14.statSync(path20.join(scriptsDir, d)).isDirectory();
37775
38362
  } catch {
37776
38363
  return false;
37777
38364
  }
37778
38365
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
37779
38366
  if (versions.length === 0) return null;
37780
- return path18.join(scriptsDir, versions[0]);
38367
+ return path20.join(scriptsDir, versions[0]);
37781
38368
  }
37782
38369
  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}`)) {
38370
+ const canonicalUserDir = path20.resolve(this.providerLoader.getUserProviderDir(category, type));
38371
+ const desiredDir = requestedDir ? path20.resolve(requestedDir) : canonicalUserDir;
38372
+ const upstreamRoot = path20.resolve(this.providerLoader.getUpstreamDir());
38373
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path20.sep}`)) {
37787
38374
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
37788
38375
  }
37789
- if (path18.basename(desiredDir) !== type) {
38376
+ if (path20.basename(desiredDir) !== type) {
37790
38377
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
37791
38378
  }
37792
38379
  const sourceDir = this.findProviderDir(type);
@@ -37794,11 +38381,11 @@ var init_dev_server = __esm({
37794
38381
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
37795
38382
  }
37796
38383
  if (!fs14.existsSync(desiredDir)) {
37797
- fs14.mkdirSync(path18.dirname(desiredDir), { recursive: true });
38384
+ fs14.mkdirSync(path20.dirname(desiredDir), { recursive: true });
37798
38385
  fs14.cpSync(sourceDir, desiredDir, { recursive: true });
37799
38386
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
37800
38387
  }
37801
- const providerJson = path18.join(desiredDir, "provider.json");
38388
+ const providerJson = path20.join(desiredDir, "provider.json");
37802
38389
  if (!fs14.existsSync(providerJson)) {
37803
38390
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
37804
38391
  }
@@ -37846,7 +38433,7 @@ var init_dev_server = __esm({
37846
38433
  setMode: "set_mode.js"
37847
38434
  };
37848
38435
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
37849
- const scriptsDir = path18.join(providerDir, "scripts");
38436
+ const scriptsDir = path20.join(providerDir, "scripts");
37850
38437
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
37851
38438
  if (latestScriptsDir) {
37852
38439
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -37857,7 +38444,7 @@ var init_dev_server = __esm({
37857
38444
  for (const file2 of fs14.readdirSync(latestScriptsDir)) {
37858
38445
  if (file2.endsWith(".js") && targetFileNames.has(file2)) {
37859
38446
  try {
37860
- const content = fs14.readFileSync(path18.join(latestScriptsDir, file2), "utf-8");
38447
+ const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
37861
38448
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
37862
38449
  lines.push("```javascript");
37863
38450
  lines.push(content);
@@ -37874,7 +38461,7 @@ var init_dev_server = __esm({
37874
38461
  lines.push("");
37875
38462
  for (const file2 of refFiles) {
37876
38463
  try {
37877
- const content = fs14.readFileSync(path18.join(latestScriptsDir, file2), "utf-8");
38464
+ const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
37878
38465
  lines.push(`### \`${file2}\` \u{1F512}`);
37879
38466
  lines.push("```javascript");
37880
38467
  lines.push(content);
@@ -37915,10 +38502,10 @@ var init_dev_server = __esm({
37915
38502
  lines.push("");
37916
38503
  }
37917
38504
  }
37918
- const docsDir = path18.join(providerDir, "../../docs");
38505
+ const docsDir = path20.join(providerDir, "../../docs");
37919
38506
  const loadGuide = (name) => {
37920
38507
  try {
37921
- const p = path18.join(docsDir, name);
38508
+ const p = path20.join(docsDir, name);
37922
38509
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
37923
38510
  } catch {
37924
38511
  }
@@ -38092,7 +38679,7 @@ var init_dev_server = __esm({
38092
38679
  parseApproval: "parse_approval.js"
38093
38680
  };
38094
38681
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
38095
- const scriptsDir = path18.join(providerDir, "scripts");
38682
+ const scriptsDir = path20.join(providerDir, "scripts");
38096
38683
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
38097
38684
  if (latestScriptsDir) {
38098
38685
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -38104,7 +38691,7 @@ var init_dev_server = __esm({
38104
38691
  if (!file2.endsWith(".js")) continue;
38105
38692
  if (!targetFileNames.has(file2)) continue;
38106
38693
  try {
38107
- const content = fs14.readFileSync(path18.join(latestScriptsDir, file2), "utf-8");
38694
+ const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
38108
38695
  lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
38109
38696
  lines.push("```javascript");
38110
38697
  lines.push(content);
@@ -38120,7 +38707,7 @@ var init_dev_server = __esm({
38120
38707
  lines.push("");
38121
38708
  for (const file2 of refFiles) {
38122
38709
  try {
38123
- const content = fs14.readFileSync(path18.join(latestScriptsDir, file2), "utf-8");
38710
+ const content = fs14.readFileSync(path20.join(latestScriptsDir, file2), "utf-8");
38124
38711
  lines.push(`### \`${file2}\` \u{1F512}`);
38125
38712
  lines.push("```javascript");
38126
38713
  lines.push(content);
@@ -38153,10 +38740,10 @@ var init_dev_server = __esm({
38153
38740
  lines.push("");
38154
38741
  }
38155
38742
  }
38156
- const docsDir = path18.join(providerDir, "../../docs");
38743
+ const docsDir = path20.join(providerDir, "../../docs");
38157
38744
  const loadGuide = (name) => {
38158
38745
  try {
38159
- const p = path18.join(docsDir, name);
38746
+ const p = path20.join(docsDir, name);
38160
38747
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
38161
38748
  } catch {
38162
38749
  }
@@ -38332,14 +38919,14 @@ data: ${JSON.stringify(msg.data)}
38332
38919
  res.end(JSON.stringify(data, null, 2));
38333
38920
  }
38334
38921
  async readBody(req) {
38335
- return new Promise((resolve13) => {
38922
+ return new Promise((resolve16) => {
38336
38923
  let body = "";
38337
38924
  req.on("data", (chunk) => body += chunk);
38338
38925
  req.on("end", () => {
38339
38926
  try {
38340
- resolve13(JSON.parse(body));
38927
+ resolve16(JSON.parse(body));
38341
38928
  } catch {
38342
- resolve13({});
38929
+ resolve16({});
38343
38930
  }
38344
38931
  });
38345
38932
  });
@@ -38808,7 +39395,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
38808
39395
  const deadline = Date.now() + timeoutMs;
38809
39396
  while (Date.now() < deadline) {
38810
39397
  if (await canConnect(endpoint)) return;
38811
- await new Promise((resolve13) => setTimeout(resolve13, STARTUP_POLL_MS));
39398
+ await new Promise((resolve16) => setTimeout(resolve16, STARTUP_POLL_MS));
38812
39399
  }
38813
39400
  throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
38814
39401
  }
@@ -38899,10 +39486,10 @@ async function installExtension(ide, extension) {
38899
39486
  const buffer = Buffer.from(await res.arrayBuffer());
38900
39487
  const fs18 = await import("fs");
38901
39488
  fs18.writeFileSync(vsixPath, buffer);
38902
- return new Promise((resolve13) => {
39489
+ return new Promise((resolve16) => {
38903
39490
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
38904
39491
  (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
38905
- resolve13({
39492
+ resolve16({
38906
39493
  extensionId: extension.id,
38907
39494
  marketplaceId: extension.marketplaceId,
38908
39495
  success: !error48,
@@ -38915,11 +39502,11 @@ async function installExtension(ide, extension) {
38915
39502
  } catch (e) {
38916
39503
  }
38917
39504
  }
38918
- return new Promise((resolve13) => {
39505
+ return new Promise((resolve16) => {
38919
39506
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
38920
39507
  (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
38921
39508
  if (error48) {
38922
- resolve13({
39509
+ resolve16({
38923
39510
  extensionId: extension.id,
38924
39511
  marketplaceId: extension.marketplaceId,
38925
39512
  success: false,
@@ -38927,7 +39514,7 @@ async function installExtension(ide, extension) {
38927
39514
  error: stderr || error48.message
38928
39515
  });
38929
39516
  } else {
38930
- resolve13({
39517
+ resolve16({
38931
39518
  extensionId: extension.id,
38932
39519
  marketplaceId: extension.marketplaceId,
38933
39520
  success: true,
@@ -39147,13 +39734,32 @@ async function initDaemonComponents(config2) {
39147
39734
  const detectedIdesRef = { value: [] };
39148
39735
  let agentStreamManager = null;
39149
39736
  let poller = null;
39737
+ const refreshProviderAvailability = async (providerType) => {
39738
+ const targetProvider = providerType ? providerLoader.getMeta(providerLoader.resolveAlias(providerType)) : null;
39739
+ const targetCategory = targetProvider?.category;
39740
+ if (!providerType || targetCategory === "cli" || targetCategory === "acp") {
39741
+ if (providerType && targetProvider) {
39742
+ const detected = await detectCLI(targetProvider.type, providerLoader, { includeVersion: false });
39743
+ providerLoader.setProviderAvailability(targetProvider.type, {
39744
+ installed: !!detected,
39745
+ detectedPath: detected?.path || null
39746
+ });
39747
+ } else {
39748
+ providerLoader.setCliDetectionResults(await detectCLIs(providerLoader, { includeVersion: false }), true);
39749
+ }
39750
+ }
39751
+ if (!providerType || targetCategory === "ide") {
39752
+ detectedIdesRef.value = await detectIDEs(providerLoader);
39753
+ providerLoader.setIdeDetectionResults(detectedIdesRef.value, true);
39754
+ }
39755
+ };
39150
39756
  const cliManager = new DaemonCliManager({
39151
39757
  ...config2.cliManagerDeps,
39152
39758
  getInstanceManager: () => instanceManager,
39153
39759
  getSessionRegistry: () => sessionRegistry
39154
39760
  }, providerLoader);
39155
39761
  LOG.info("Init", "Detecting IDEs...");
39156
- detectedIdesRef.value = await detectIDEs();
39762
+ await refreshProviderAvailability();
39157
39763
  const installed = detectedIdesRef.value.filter((i) => i.installed);
39158
39764
  LOG.info("Init", `Found ${installed.length} IDE(s): ${installed.map((i) => i.id).join(", ") || "none"}`);
39159
39765
  const cdpSetupContext = {
@@ -39193,7 +39799,11 @@ async function initDaemonComponents(config2) {
39193
39799
  adapters: cliManager.adapters,
39194
39800
  providerLoader,
39195
39801
  instanceManager,
39196
- sessionRegistry
39802
+ sessionRegistry,
39803
+ onProviderSettingChanged: async (providerType) => {
39804
+ await refreshProviderAvailability(providerType);
39805
+ config2.onStatusChange?.();
39806
+ }
39197
39807
  });
39198
39808
  agentStreamManager = new DaemonAgentStreamManager(
39199
39809
  LOG.forComponent("AgentStream").asLogFn(),
@@ -39308,6 +39918,7 @@ var init_daemon_lifecycle = __esm({
39308
39918
  init_provider_instance_manager();
39309
39919
  init_dev_server();
39310
39920
  init_ide_detector();
39921
+ init_cli_detector();
39311
39922
  init_registry();
39312
39923
  init_logger();
39313
39924
  init_config();
@@ -39745,17 +40356,17 @@ function canPeerUsePrivilegedShareCommand(commandType, permission) {
39745
40356
  return false;
39746
40357
  }
39747
40358
  }
39748
- var fs15, path19, os19, import_node_module2, esmRequire, logFile, log, logDebug, DaemonP2PSender;
40359
+ var fs15, path21, os19, import_node_module2, esmRequire, logFile, log, logDebug, DaemonP2PSender;
39749
40360
  var init_daemon_p2p = __esm({
39750
40361
  "src/daemon-p2p.ts"() {
39751
40362
  "use strict";
39752
40363
  fs15 = __toESM(require("fs"));
39753
40364
  init_src();
39754
- path19 = __toESM(require("path"));
40365
+ path21 = __toESM(require("path"));
39755
40366
  os19 = __toESM(require("os"));
39756
40367
  import_node_module2 = require("module");
39757
40368
  esmRequire = (0, import_node_module2.createRequire)(__filename);
39758
- logFile = path19.join(os19.tmpdir(), "adhdev_daemon_p2p.log");
40369
+ logFile = path21.join(os19.tmpdir(), "adhdev_daemon_p2p.log");
39759
40370
  log = (msg) => {
39760
40371
  LOG.info("P2P", `[${(/* @__PURE__ */ new Date()).toISOString()}] [P2P] ${msg}`);
39761
40372
  };
@@ -39823,15 +40434,15 @@ ${e?.stack || ""}`);
39823
40434
  const prebuildKey = `${platform11}-${arch3}`;
39824
40435
  try {
39825
40436
  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")
40437
+ path21.join(__dirname, "node_modules", "node-datachannel"),
40438
+ path21.join(__dirname, "..", "node_modules", "node-datachannel"),
40439
+ path21.join(__dirname, "..", "..", "node_modules", "node-datachannel")
39829
40440
  ];
39830
40441
  for (const candidate of candidates) {
39831
- const prebuildPath = path19.join(candidate, "prebuilds", prebuildKey, "node_datachannel.node");
40442
+ const prebuildPath = path21.join(candidate, "prebuilds", prebuildKey, "node_datachannel.node");
39832
40443
  if (fs15.existsSync(prebuildPath)) {
39833
- const targetDir = path19.join(candidate, "build", "Release");
39834
- const targetPath = path19.join(targetDir, "node_datachannel.node");
40444
+ const targetDir = path21.join(candidate, "build", "Release");
40445
+ const targetPath = path21.join(targetDir, "node_datachannel.node");
39835
40446
  fs15.mkdirSync(targetDir, { recursive: true });
39836
40447
  fs15.copyFileSync(prebuildPath, targetPath);
39837
40448
  try {
@@ -39914,13 +40525,13 @@ ${e?.stack || ""}`);
39914
40525
  } catch {
39915
40526
  }
39916
40527
  const http3 = esmRequire("https");
39917
- const data = await new Promise((resolve13, reject) => {
40528
+ const data = await new Promise((resolve16, reject) => {
39918
40529
  const req = http3.get(`${serverUrl}/api/v1/turn/credentials`, {
39919
40530
  headers: { "Authorization": `Bearer ${token}` }
39920
40531
  }, (res) => {
39921
40532
  let d = "";
39922
40533
  res.on("data", (c) => d += c);
39923
- res.on("end", () => resolve13(d));
40534
+ res.on("end", () => resolve16(d));
39924
40535
  });
39925
40536
  req.on("error", reject);
39926
40537
  req.setTimeout(5e3, () => {
@@ -40611,22 +41222,22 @@ var require_filesystem = __commonJS({
40611
41222
  var LDD_PATH = "/usr/bin/ldd";
40612
41223
  var SELF_PATH = "/proc/self/exe";
40613
41224
  var MAX_LENGTH = 2048;
40614
- var readFileSync17 = (path23) => {
40615
- const fd = fs18.openSync(path23, "r");
41225
+ var readFileSync17 = (path25) => {
41226
+ const fd = fs18.openSync(path25, "r");
40616
41227
  const buffer = Buffer.alloc(MAX_LENGTH);
40617
41228
  const bytesRead = fs18.readSync(fd, buffer, 0, MAX_LENGTH, 0);
40618
41229
  fs18.close(fd, () => {
40619
41230
  });
40620
41231
  return buffer.subarray(0, bytesRead);
40621
41232
  };
40622
- var readFile = (path23) => new Promise((resolve13, reject) => {
40623
- fs18.open(path23, "r", (err, fd) => {
41233
+ var readFile = (path25) => new Promise((resolve16, reject) => {
41234
+ fs18.open(path25, "r", (err, fd) => {
40624
41235
  if (err) {
40625
41236
  reject(err);
40626
41237
  } else {
40627
41238
  const buffer = Buffer.alloc(MAX_LENGTH);
40628
41239
  fs18.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
40629
- resolve13(buffer.subarray(0, bytesRead));
41240
+ resolve16(buffer.subarray(0, bytesRead));
40630
41241
  fs18.close(fd, () => {
40631
41242
  });
40632
41243
  });
@@ -40694,10 +41305,10 @@ var require_detect_libc = __commonJS({
40694
41305
  var commandOut = "";
40695
41306
  var safeCommand = () => {
40696
41307
  if (!commandOut) {
40697
- return new Promise((resolve13) => {
41308
+ return new Promise((resolve16) => {
40698
41309
  childProcess.exec(command, (err, out) => {
40699
41310
  commandOut = err ? " " : out;
40700
- resolve13(commandOut);
41311
+ resolve16(commandOut);
40701
41312
  });
40702
41313
  });
40703
41314
  }
@@ -40739,11 +41350,11 @@ var require_detect_libc = __commonJS({
40739
41350
  }
40740
41351
  return null;
40741
41352
  };
40742
- var familyFromInterpreterPath = (path23) => {
40743
- if (path23) {
40744
- if (path23.includes("/ld-musl-")) {
41353
+ var familyFromInterpreterPath = (path25) => {
41354
+ if (path25) {
41355
+ if (path25.includes("/ld-musl-")) {
40745
41356
  return MUSL;
40746
- } else if (path23.includes("/ld-linux-")) {
41357
+ } else if (path25.includes("/ld-linux-")) {
40747
41358
  return GLIBC;
40748
41359
  }
40749
41360
  }
@@ -40790,8 +41401,8 @@ var require_detect_libc = __commonJS({
40790
41401
  cachedFamilyInterpreter = null;
40791
41402
  try {
40792
41403
  const selfContent = await readFile(SELF_PATH);
40793
- const path23 = interpreterPath(selfContent);
40794
- cachedFamilyInterpreter = familyFromInterpreterPath(path23);
41404
+ const path25 = interpreterPath(selfContent);
41405
+ cachedFamilyInterpreter = familyFromInterpreterPath(path25);
40795
41406
  } catch (e) {
40796
41407
  }
40797
41408
  return cachedFamilyInterpreter;
@@ -40803,8 +41414,8 @@ var require_detect_libc = __commonJS({
40803
41414
  cachedFamilyInterpreter = null;
40804
41415
  try {
40805
41416
  const selfContent = readFileSync17(SELF_PATH);
40806
- const path23 = interpreterPath(selfContent);
40807
- cachedFamilyInterpreter = familyFromInterpreterPath(path23);
41417
+ const path25 = interpreterPath(selfContent);
41418
+ cachedFamilyInterpreter = familyFromInterpreterPath(path25);
40808
41419
  } catch (e) {
40809
41420
  }
40810
41421
  return cachedFamilyInterpreter;
@@ -42523,18 +43134,18 @@ var require_sharp = __commonJS({
42523
43134
  `@img/sharp-${runtimePlatform}/sharp.node`,
42524
43135
  "@img/sharp-wasm32/sharp.node"
42525
43136
  ];
42526
- var path23;
43137
+ var path25;
42527
43138
  var sharp;
42528
43139
  var errors = [];
42529
- for (path23 of paths) {
43140
+ for (path25 of paths) {
42530
43141
  try {
42531
- sharp = require(path23);
43142
+ sharp = require(path25);
42532
43143
  break;
42533
43144
  } catch (err) {
42534
43145
  errors.push(err);
42535
43146
  }
42536
43147
  }
42537
- if (sharp && path23.startsWith("@img/sharp-linux-x64") && !sharp._isUsingX64V2()) {
43148
+ if (sharp && path25.startsWith("@img/sharp-linux-x64") && !sharp._isUsingX64V2()) {
42538
43149
  const err = new Error("Prebuilt binaries for linux-x64 require v2 microarchitecture");
42539
43150
  err.code = "Unsupported CPU";
42540
43151
  errors.push(err);
@@ -43377,14 +43988,14 @@ var require_input = __commonJS({
43377
43988
  return this;
43378
43989
  } else {
43379
43990
  if (this._isStreamInput()) {
43380
- return new Promise((resolve13, reject) => {
43991
+ return new Promise((resolve16, reject) => {
43381
43992
  const finished = () => {
43382
43993
  this._flattenBufferIn();
43383
43994
  sharp.metadata(this.options, (err, metadata2) => {
43384
43995
  if (err) {
43385
43996
  reject(is.nativeError(err, stack));
43386
43997
  } else {
43387
- resolve13(metadata2);
43998
+ resolve16(metadata2);
43388
43999
  }
43389
44000
  });
43390
44001
  };
@@ -43395,12 +44006,12 @@ var require_input = __commonJS({
43395
44006
  }
43396
44007
  });
43397
44008
  } else {
43398
- return new Promise((resolve13, reject) => {
44009
+ return new Promise((resolve16, reject) => {
43399
44010
  sharp.metadata(this.options, (err, metadata2) => {
43400
44011
  if (err) {
43401
44012
  reject(is.nativeError(err, stack));
43402
44013
  } else {
43403
- resolve13(metadata2);
44014
+ resolve16(metadata2);
43404
44015
  }
43405
44016
  });
43406
44017
  });
@@ -43433,25 +44044,25 @@ var require_input = __commonJS({
43433
44044
  return this;
43434
44045
  } else {
43435
44046
  if (this._isStreamInput()) {
43436
- return new Promise((resolve13, reject) => {
44047
+ return new Promise((resolve16, reject) => {
43437
44048
  this.on("finish", function() {
43438
44049
  this._flattenBufferIn();
43439
44050
  sharp.stats(this.options, (err, stats2) => {
43440
44051
  if (err) {
43441
44052
  reject(is.nativeError(err, stack));
43442
44053
  } else {
43443
- resolve13(stats2);
44054
+ resolve16(stats2);
43444
44055
  }
43445
44056
  });
43446
44057
  });
43447
44058
  });
43448
44059
  } else {
43449
- return new Promise((resolve13, reject) => {
44060
+ return new Promise((resolve16, reject) => {
43450
44061
  sharp.stats(this.options, (err, stats2) => {
43451
44062
  if (err) {
43452
44063
  reject(is.nativeError(err, stack));
43453
44064
  } else {
43454
- resolve13(stats2);
44065
+ resolve16(stats2);
43455
44066
  }
43456
44067
  });
43457
44068
  });
@@ -45443,15 +46054,15 @@ var require_color = __commonJS({
45443
46054
  };
45444
46055
  }
45445
46056
  function wrapConversion(toModel, graph) {
45446
- const path23 = [graph[toModel].parent, toModel];
46057
+ const path25 = [graph[toModel].parent, toModel];
45447
46058
  let fn = conversions_default[graph[toModel].parent][toModel];
45448
46059
  let cur = graph[toModel].parent;
45449
46060
  while (graph[cur].parent) {
45450
- path23.unshift(graph[cur].parent);
46061
+ path25.unshift(graph[cur].parent);
45451
46062
  fn = link(conversions_default[graph[cur].parent][cur], fn);
45452
46063
  cur = graph[cur].parent;
45453
46064
  }
45454
- fn.conversion = path23;
46065
+ fn.conversion = path25;
45455
46066
  return fn;
45456
46067
  }
45457
46068
  function route(fromModel) {
@@ -46068,7 +46679,7 @@ var require_channel = __commonJS({
46068
46679
  var require_output = __commonJS({
46069
46680
  "../../node_modules/sharp/lib/output.js"(exports2, module2) {
46070
46681
  "use strict";
46071
- var path23 = require("path");
46682
+ var path25 = require("path");
46072
46683
  var is = require_is();
46073
46684
  var sharp = require_sharp();
46074
46685
  var formats = /* @__PURE__ */ new Map([
@@ -46099,9 +46710,9 @@ var require_output = __commonJS({
46099
46710
  let err;
46100
46711
  if (!is.string(fileOut)) {
46101
46712
  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)) {
46713
+ } else if (is.string(this.options.input.file) && path25.resolve(this.options.input.file) === path25.resolve(fileOut)) {
46103
46714
  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) {
46715
+ } else if (jp2Regex.test(path25.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
46105
46716
  err = errJp2Save();
46106
46717
  }
46107
46718
  if (err) {
@@ -46873,7 +47484,7 @@ var require_output = __commonJS({
46873
47484
  return this;
46874
47485
  } else {
46875
47486
  if (this._isStreamInput()) {
46876
- return new Promise((resolve13, reject) => {
47487
+ return new Promise((resolve16, reject) => {
46877
47488
  this.once("finish", () => {
46878
47489
  this._flattenBufferIn();
46879
47490
  sharp.pipeline(this.options, (err, data, info) => {
@@ -46881,24 +47492,24 @@ var require_output = __commonJS({
46881
47492
  reject(is.nativeError(err, stack));
46882
47493
  } else {
46883
47494
  if (this.options.resolveWithObject) {
46884
- resolve13({ data, info });
47495
+ resolve16({ data, info });
46885
47496
  } else {
46886
- resolve13(data);
47497
+ resolve16(data);
46887
47498
  }
46888
47499
  }
46889
47500
  });
46890
47501
  });
46891
47502
  });
46892
47503
  } else {
46893
- return new Promise((resolve13, reject) => {
47504
+ return new Promise((resolve16, reject) => {
46894
47505
  sharp.pipeline(this.options, (err, data, info) => {
46895
47506
  if (err) {
46896
47507
  reject(is.nativeError(err, stack));
46897
47508
  } else {
46898
47509
  if (this.options.resolveWithObject) {
46899
- resolve13({ data, info });
47510
+ resolve16({ data, info });
46900
47511
  } else {
46901
- resolve13(data);
47512
+ resolve16(data);
46902
47513
  }
46903
47514
  }
46904
47515
  });
@@ -47306,8 +47917,8 @@ function buildSessionHostEnv(baseEnv) {
47306
47917
  }
47307
47918
  function resolveSessionHostEntry() {
47308
47919
  const packagedCandidates = [
47309
- path20.resolve(__dirname, "../vendor/session-host-daemon/index.js"),
47310
- path20.resolve(__dirname, "../../vendor/session-host-daemon/index.js")
47920
+ path23.resolve(__dirname, "../vendor/session-host-daemon/index.js"),
47921
+ path23.resolve(__dirname, "../../vendor/session-host-daemon/index.js")
47311
47922
  ];
47312
47923
  for (const candidate of packagedCandidates) {
47313
47924
  if (fs16.existsSync(candidate)) {
@@ -47317,7 +47928,7 @@ function resolveSessionHostEntry() {
47317
47928
  return require.resolve("@adhdev/session-host-daemon");
47318
47929
  }
47319
47930
  function getSessionHostPidFile() {
47320
- return path20.join(os20.homedir(), ".adhdev", `${SESSION_HOST_APP_NAME}-session-host.pid`);
47931
+ return path23.join(os20.homedir(), ".adhdev", `${SESSION_HOST_APP_NAME}-session-host.pid`);
47321
47932
  }
47322
47933
  function killPid2(pid) {
47323
47934
  try {
@@ -47414,9 +48025,9 @@ function stopSessionHost() {
47414
48025
  async function ensureSessionHostReady2() {
47415
48026
  const spawnHost = () => {
47416
48027
  const entry = resolveSessionHostEntry();
47417
- const logDir = path20.join(os20.homedir(), ".adhdev", "logs");
48028
+ const logDir = path23.join(os20.homedir(), ".adhdev", "logs");
47418
48029
  fs16.mkdirSync(logDir, { recursive: true });
47419
- const logFd = fs16.openSync(path20.join(logDir, "session-host.log"), "a");
48030
+ const logFd = fs16.openSync(path23.join(logDir, "session-host.log"), "a");
47420
48031
  const child = (0, import_child_process11.spawn)(process.execPath, [entry], {
47421
48032
  detached: true,
47422
48033
  stdio: ["ignore", logFd, logFd],
@@ -47451,14 +48062,14 @@ async function ensureSessionHostReady2() {
47451
48062
  async function listHostedCliRuntimes2(endpoint) {
47452
48063
  return listHostedCliRuntimes(endpoint);
47453
48064
  }
47454
- var import_child_process11, fs16, os20, path20, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
48065
+ var import_child_process11, fs16, os20, path23, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
47455
48066
  var init_session_host = __esm({
47456
48067
  "src/session-host.ts"() {
47457
48068
  "use strict";
47458
48069
  import_child_process11 = require("child_process");
47459
48070
  fs16 = __toESM(require("fs"));
47460
48071
  os20 = __toESM(require("os"));
47461
- path20 = __toESM(require("path"));
48072
+ path23 = __toESM(require("path"));
47462
48073
  init_src();
47463
48074
  init_dist();
47464
48075
  SESSION_HOST_APP_NAME = process.env.ADHDEV_SESSION_HOST_NAME || "adhdev";
@@ -47547,6 +48158,12 @@ var init_session_host_controller = __esm({
47547
48158
  payload: { sessionId, clientId }
47548
48159
  });
47549
48160
  }
48161
+ async pruneDuplicateSessions(payload = {}) {
48162
+ return this.request({
48163
+ type: "prune_duplicate_sessions",
48164
+ payload
48165
+ });
48166
+ }
47550
48167
  async acquireWrite(payload) {
47551
48168
  return this.request({
47552
48169
  type: "acquire_write",
@@ -47622,18 +48239,18 @@ function resolvePackageVersion(options) {
47622
48239
  ];
47623
48240
  for (const p of possiblePaths) {
47624
48241
  try {
47625
- const data = JSON.parse((0, import_fs4.readFileSync)(p, "utf-8"));
48242
+ const data = JSON.parse((0, import_fs5.readFileSync)(p, "utf-8"));
47626
48243
  if (data.version) return data.version;
47627
48244
  } catch {
47628
48245
  }
47629
48246
  }
47630
48247
  return injectedVersion;
47631
48248
  }
47632
- var import_fs4, import_path3;
48249
+ var import_fs5, import_path3;
47633
48250
  var init_version = __esm({
47634
48251
  "src/version.ts"() {
47635
48252
  "use strict";
47636
- import_fs4 = require("fs");
48253
+ import_fs5 = require("fs");
47637
48254
  import_path3 = require("path");
47638
48255
  }
47639
48256
  });
@@ -47647,9 +48264,9 @@ __export(adhdev_daemon_exports, {
47647
48264
  stopDaemon: () => stopDaemon
47648
48265
  });
47649
48266
  function getDaemonPidFile() {
47650
- const dir = path21.join(os21.homedir(), ".adhdev");
48267
+ const dir = path24.join(os21.homedir(), ".adhdev");
47651
48268
  if (!fs17.existsSync(dir)) fs17.mkdirSync(dir, { recursive: true });
47652
- return path21.join(dir, "daemon.pid");
48269
+ return path24.join(dir, "daemon.pid");
47653
48270
  }
47654
48271
  function writeDaemonPid(pid) {
47655
48272
  fs17.writeFileSync(getDaemonPidFile(), String(pid), "utf-8");
@@ -47695,7 +48312,7 @@ function stopDaemon() {
47695
48312
  return false;
47696
48313
  }
47697
48314
  }
47698
- var os21, fs17, path21, import_http, import_ws3, import_chalk2, pkgVersion, DANGEROUS_PATTERNS, AdhdevDaemon;
48315
+ var os21, fs17, path24, import_http, import_ws3, import_chalk2, pkgVersion, DANGEROUS_PATTERNS, AdhdevDaemon;
47699
48316
  var init_adhdev_daemon = __esm({
47700
48317
  "src/adhdev-daemon.ts"() {
47701
48318
  "use strict";
@@ -47708,12 +48325,12 @@ var init_adhdev_daemon = __esm({
47708
48325
  init_session_host_controller();
47709
48326
  os21 = __toESM(require("os"));
47710
48327
  fs17 = __toESM(require("fs"));
47711
- path21 = __toESM(require("path"));
48328
+ path24 = __toESM(require("path"));
47712
48329
  import_http = require("http");
47713
48330
  import_ws3 = require("ws");
47714
48331
  import_chalk2 = __toESM(require("chalk"));
47715
48332
  init_version();
47716
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.27" });
48333
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.29" });
47717
48334
  DANGEROUS_PATTERNS = [
47718
48335
  /\brm\s+(-[a-z]*f|-[a-z]*r|--force|--recursive)/i,
47719
48336
  /\bsudo\b/i,
@@ -48144,7 +48761,7 @@ ${err?.stack || ""}`);
48144
48761
  this.localWss.emit("connection", ws, req);
48145
48762
  });
48146
48763
  });
48147
- await new Promise((resolve13, reject) => {
48764
+ await new Promise((resolve16, reject) => {
48148
48765
  const cleanup = () => {
48149
48766
  this.localHttpServer?.off("error", onError);
48150
48767
  this.localHttpServer?.off("listening", onListening);
@@ -48155,7 +48772,7 @@ ${err?.stack || ""}`);
48155
48772
  };
48156
48773
  const onListening = () => {
48157
48774
  cleanup();
48158
- resolve13();
48775
+ resolve16();
48159
48776
  };
48160
48777
  this.localHttpServer.once("error", onError);
48161
48778
  this.localHttpServer.once("listening", onListening);
@@ -48306,12 +48923,12 @@ ${err?.stack || ""}`);
48306
48923
  this.localClients.clear();
48307
48924
  this.localWss?.close();
48308
48925
  this.localWss = null;
48309
- await new Promise((resolve13) => {
48926
+ await new Promise((resolve16) => {
48310
48927
  if (!this.localHttpServer) {
48311
- resolve13();
48928
+ resolve16();
48312
48929
  return;
48313
48930
  }
48314
- this.localHttpServer.close(() => resolve13());
48931
+ this.localHttpServer.close(() => resolve16());
48315
48932
  this.localHttpServer = null;
48316
48933
  });
48317
48934
  } catch {