@adhdev/daemon-core 0.7.43 → 0.7.45

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
@@ -691,11 +691,11 @@ var init_terminal_screen = __esm({
691
691
  });
692
692
 
693
693
  // src/cli-adapters/pty-transport.ts
694
- var os11, pty, NodePtyRuntimeTransport, NodePtyTransportFactory;
694
+ var os12, pty, NodePtyRuntimeTransport, NodePtyTransportFactory;
695
695
  var init_pty_transport = __esm({
696
696
  "src/cli-adapters/pty-transport.ts"() {
697
697
  "use strict";
698
- os11 = __toESM(require("os"));
698
+ os12 = __toESM(require("os"));
699
699
  try {
700
700
  pty = require("node-pty");
701
701
  } catch {
@@ -733,7 +733,7 @@ var init_pty_transport = __esm({
733
733
  spawn(command, args, options) {
734
734
  if (!pty) throw new Error("node-pty is not installed");
735
735
  const handle = pty.spawn(command, args, {
736
- name: os11.platform() === "win32" ? "xterm-color" : "xterm-256color",
736
+ name: os12.platform() === "win32" ? "xterm-color" : "xterm-256color",
737
737
  cols: options.cols,
738
738
  rows: options.rows,
739
739
  cwd: options.cwd,
@@ -787,23 +787,23 @@ function computeTerminalQueryTail(buffer) {
787
787
  return "";
788
788
  }
789
789
  function findBinary(name) {
790
- const isWin = os12.platform() === "win32";
790
+ const isWin = os13.platform() === "win32";
791
791
  try {
792
792
  const cmd = isWin ? `where ${name}` : `which ${name}`;
793
- return (0, import_child_process5.execSync)(cmd, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n")[0].trim();
793
+ return (0, import_child_process7.execSync)(cmd, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n")[0].trim();
794
794
  } catch {
795
795
  return isWin ? `${name}.cmd` : name;
796
796
  }
797
797
  }
798
798
  function isScriptBinary(binaryPath) {
799
- if (!path9.isAbsolute(binaryPath)) return false;
799
+ if (!path10.isAbsolute(binaryPath)) return false;
800
800
  try {
801
- const fs12 = require("fs");
802
- const resolved = fs12.realpathSync(binaryPath);
801
+ const fs13 = require("fs");
802
+ const resolved = fs13.realpathSync(binaryPath);
803
803
  const head = Buffer.alloc(8);
804
- const fd = fs12.openSync(resolved, "r");
805
- fs12.readSync(fd, head, 0, 8, 0);
806
- fs12.closeSync(fd);
804
+ const fd = fs13.openSync(resolved, "r");
805
+ fs13.readSync(fd, head, 0, 8, 0);
806
+ fs13.closeSync(fd);
807
807
  let i = 0;
808
808
  if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
809
809
  return head[i] === 35 && head[i + 1] === 33;
@@ -812,14 +812,14 @@ function isScriptBinary(binaryPath) {
812
812
  }
813
813
  }
814
814
  function looksLikeMachOOrElf(filePath) {
815
- if (!path9.isAbsolute(filePath)) return false;
815
+ if (!path10.isAbsolute(filePath)) return false;
816
816
  try {
817
- const fs12 = require("fs");
818
- const resolved = fs12.realpathSync(filePath);
817
+ const fs13 = require("fs");
818
+ const resolved = fs13.realpathSync(filePath);
819
819
  const buf = Buffer.alloc(8);
820
- const fd = fs12.openSync(resolved, "r");
821
- fs12.readSync(fd, buf, 0, 8, 0);
822
- fs12.closeSync(fd);
820
+ const fd = fs13.openSync(resolved, "r");
821
+ fs13.readSync(fd, buf, 0, 8, 0);
822
+ fs13.closeSync(fd);
823
823
  let i = 0;
824
824
  if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
825
825
  const b = buf.subarray(i);
@@ -835,12 +835,12 @@ function looksLikeMachOOrElf(filePath) {
835
835
  }
836
836
  function shSingleQuote(arg) {
837
837
  if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
838
- if (os12.platform() === "win32") {
838
+ if (os13.platform() === "win32") {
839
839
  return `"${arg.replace(/"/g, '""')}"`;
840
840
  }
841
841
  return `'${arg.replace(/'/g, `'\\''`)}'`;
842
842
  }
843
- function estimatePromptDisplayLines(text, cols = 100) {
843
+ function estimatePromptDisplayLines(text, cols = 80) {
844
844
  const normalized = String(text || "").replace(/\r/g, "");
845
845
  if (!normalized) return 1;
846
846
  return normalized.split("\n").reduce((sum, line) => sum + Math.max(1, Math.ceil(Math.max(1, line.length) / cols)), 0);
@@ -896,28 +896,28 @@ function normalizeCliProviderForRuntime(raw) {
896
896
  }
897
897
  };
898
898
  }
899
- var os12, path9, import_child_process5, pty2, ProviderCliAdapter;
899
+ var os13, path10, import_child_process7, pty2, ProviderCliAdapter;
900
900
  var init_provider_cli_adapter = __esm({
901
901
  "src/cli-adapters/provider-cli-adapter.ts"() {
902
902
  "use strict";
903
- os12 = __toESM(require("os"));
904
- path9 = __toESM(require("path"));
905
- import_child_process5 = require("child_process");
903
+ os13 = __toESM(require("os"));
904
+ path10 = __toESM(require("path"));
905
+ import_child_process7 = require("child_process");
906
906
  init_logger();
907
907
  init_terminal_screen();
908
908
  init_pty_transport();
909
909
  try {
910
910
  pty2 = require("node-pty");
911
- if (os12.platform() !== "win32") {
911
+ if (os13.platform() !== "win32") {
912
912
  try {
913
- const fs12 = require("fs");
914
- const ptyDir = path9.resolve(path9.dirname(require.resolve("node-pty")), "..");
915
- const platformArch = `${os12.platform()}-${os12.arch()}`;
916
- const helper = path9.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
917
- if (fs12.existsSync(helper)) {
918
- const stat = fs12.statSync(helper);
913
+ const fs13 = require("fs");
914
+ const ptyDir = path10.resolve(path10.dirname(require.resolve("node-pty")), "..");
915
+ const platformArch = `${os13.platform()}-${os13.arch()}`;
916
+ const helper = path10.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
917
+ if (fs13.existsSync(helper)) {
918
+ const stat = fs13.statSync(helper);
919
919
  if (!(stat.mode & 73)) {
920
- fs12.chmodSync(helper, stat.mode | 493);
920
+ fs13.chmodSync(helper, stat.mode | 493);
921
921
  LOG.info("CLI", "[node-pty] Fixed spawn-helper permissions");
922
922
  }
923
923
  }
@@ -934,7 +934,7 @@ var init_provider_cli_adapter = __esm({
934
934
  this.transportFactory = transportFactory;
935
935
  this.cliType = provider.type;
936
936
  this.cliName = provider.name;
937
- this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os12.homedir()) : workingDir;
937
+ this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os13.homedir()) : workingDir;
938
938
  const t = provider.timeouts || {};
939
939
  this.timeouts = {
940
940
  ptyFlush: t.ptyFlush ?? 50,
@@ -1101,12 +1101,12 @@ var init_provider_cli_adapter = __esm({
1101
1101
  if (this.ptyProcess) return;
1102
1102
  const { spawn: spawnConfig } = this.provider;
1103
1103
  const binaryPath = findBinary(spawnConfig.command);
1104
- const isWin = os12.platform() === "win32";
1104
+ const isWin = os13.platform() === "win32";
1105
1105
  const allArgs = [...spawnConfig.args, ...this.extraArgs];
1106
1106
  LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
1107
1107
  let shellCmd;
1108
1108
  let shellArgs;
1109
- const useShellUnix = !isWin && (!!spawnConfig.shell || !path9.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
1109
+ const useShellUnix = !isWin && (!!spawnConfig.shell || !path10.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
1110
1110
  const useShell = isWin ? !!spawnConfig.shell : useShellUnix;
1111
1111
  if (useShell) {
1112
1112
  if (!spawnConfig.shell && !isWin) {
@@ -1124,8 +1124,8 @@ var init_provider_cli_adapter = __esm({
1124
1124
  shellArgs = allArgs;
1125
1125
  }
1126
1126
  const ptyOpts = {
1127
- cols: 100,
1128
- rows: 30,
1127
+ cols: 80,
1128
+ rows: 24,
1129
1129
  cwd: this.workingDir,
1130
1130
  env: buildCliSpawnEnv(process.env, spawnConfig.env)
1131
1131
  };
@@ -1181,7 +1181,7 @@ var init_provider_cli_adapter = __esm({
1181
1181
  this.spawnAt = Date.now();
1182
1182
  this.startupParseGate = true;
1183
1183
  this.startupBuffer = "";
1184
- this.terminalScreen.reset(30, 100);
1184
+ this.terminalScreen.reset(24, 80);
1185
1185
  this.pendingTerminalQueryTail = "";
1186
1186
  this.currentTurnScope = null;
1187
1187
  this.ready = false;
@@ -1991,6 +1991,7 @@ __export(index_exports, {
1991
1991
  loadConfig: () => loadConfig,
1992
1992
  logCommand: () => logCommand,
1993
1993
  markSetupComplete: () => markSetupComplete,
1994
+ maybeRunDaemonUpgradeHelperFromEnv: () => maybeRunDaemonUpgradeHelperFromEnv,
1994
1995
  normalizeActiveChatData: () => normalizeActiveChatData,
1995
1996
  normalizeManagedStatus: () => normalizeManagedStatus,
1996
1997
  probeCdpPort: () => probeCdpPort,
@@ -2283,18 +2284,18 @@ function checkPathExists(paths) {
2283
2284
  return null;
2284
2285
  }
2285
2286
  async function detectIDEs() {
2286
- const os16 = (0, import_os2.platform)();
2287
+ const os17 = (0, import_os2.platform)();
2287
2288
  const results = [];
2288
2289
  for (const def of getMergedDefinitions()) {
2289
2290
  const cliPath = findCliCommand(def.cli);
2290
- const appPath = checkPathExists(def.paths[os16] || []);
2291
+ const appPath = checkPathExists(def.paths[os17] || []);
2291
2292
  const installed = !!(cliPath || appPath);
2292
2293
  let resolvedCli = cliPath;
2293
- if (!resolvedCli && appPath && os16 === "darwin") {
2294
+ if (!resolvedCli && appPath && os17 === "darwin") {
2294
2295
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
2295
2296
  if ((0, import_fs2.existsSync)(bundledCli)) resolvedCli = bundledCli;
2296
2297
  }
2297
- if (!resolvedCli && appPath && os16 === "win32") {
2298
+ if (!resolvedCli && appPath && os17 === "win32") {
2298
2299
  const { dirname: dirname7 } = await import("path");
2299
2300
  const appDir = dirname7(appPath);
2300
2301
  const candidates = [
@@ -8313,7 +8314,7 @@ function detectCurrentWorkspace(ideId) {
8313
8314
  }
8314
8315
  } else if (plat === "win32") {
8315
8316
  try {
8316
- const fs12 = require("fs");
8317
+ const fs13 = require("fs");
8317
8318
  const appNameMap = getMacAppIdentifiers();
8318
8319
  const appName = appNameMap[ideId];
8319
8320
  if (appName) {
@@ -8322,8 +8323,8 @@ function detectCurrentWorkspace(ideId) {
8322
8323
  appName,
8323
8324
  "storage.json"
8324
8325
  );
8325
- if (fs12.existsSync(storagePath)) {
8326
- const data = JSON.parse(fs12.readFileSync(storagePath, "utf-8"));
8326
+ if (fs13.existsSync(storagePath)) {
8327
+ const data = JSON.parse(fs13.readFileSync(storagePath, "utf-8"));
8327
8328
  const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
8328
8329
  if (workspaces.length > 0) {
8329
8330
  const recent = workspaces[0];
@@ -8768,8 +8769,191 @@ function buildStatusSnapshot(options) {
8768
8769
  };
8769
8770
  }
8770
8771
 
8771
- // src/commands/router.ts
8772
+ // src/commands/upgrade-helper.ts
8773
+ var import_child_process5 = require("child_process");
8774
+ var import_child_process6 = require("child_process");
8772
8775
  var fs7 = __toESM(require("fs"));
8776
+ var os11 = __toESM(require("os"));
8777
+ var path9 = __toESM(require("path"));
8778
+ var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
8779
+ function getUpgradeLogPath() {
8780
+ const home = os11.homedir();
8781
+ const dir = path9.join(home, ".adhdev");
8782
+ fs7.mkdirSync(dir, { recursive: true });
8783
+ return path9.join(dir, "daemon-upgrade.log");
8784
+ }
8785
+ function appendUpgradeLog(message) {
8786
+ const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
8787
+ `;
8788
+ try {
8789
+ fs7.appendFileSync(getUpgradeLogPath(), line, "utf8");
8790
+ } catch {
8791
+ }
8792
+ }
8793
+ function getNpmExecutable() {
8794
+ return process.platform === "win32" ? "npm.cmd" : "npm";
8795
+ }
8796
+ function killPid(pid) {
8797
+ try {
8798
+ if (process.platform === "win32") {
8799
+ (0, import_child_process5.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore" });
8800
+ } else {
8801
+ process.kill(pid, "SIGTERM");
8802
+ }
8803
+ return true;
8804
+ } catch {
8805
+ return false;
8806
+ }
8807
+ }
8808
+ async function waitForPidExit(pid, timeoutMs) {
8809
+ const start = Date.now();
8810
+ while (Date.now() - start < timeoutMs) {
8811
+ try {
8812
+ process.kill(pid, 0);
8813
+ await new Promise((resolve9) => setTimeout(resolve9, 250));
8814
+ } catch {
8815
+ return;
8816
+ }
8817
+ }
8818
+ }
8819
+ function stopSessionHostProcesses(appName) {
8820
+ const pidFile = path9.join(os11.homedir(), ".adhdev", `${appName}-session-host.pid`);
8821
+ try {
8822
+ if (fs7.existsSync(pidFile)) {
8823
+ const pid = Number.parseInt(fs7.readFileSync(pidFile, "utf8").trim(), 10);
8824
+ if (Number.isFinite(pid)) {
8825
+ killPid(pid);
8826
+ }
8827
+ }
8828
+ } catch {
8829
+ } finally {
8830
+ try {
8831
+ fs7.unlinkSync(pidFile);
8832
+ } catch {
8833
+ }
8834
+ }
8835
+ if (process.platform !== "win32") {
8836
+ try {
8837
+ const raw = (0, import_child_process5.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
8838
+ for (const line of raw.split("\n")) {
8839
+ const pid = Number.parseInt(line.trim(), 10);
8840
+ if (Number.isFinite(pid)) {
8841
+ killPid(pid);
8842
+ }
8843
+ }
8844
+ } catch {
8845
+ }
8846
+ }
8847
+ }
8848
+ function removeDaemonPidFile() {
8849
+ const pidFile = path9.join(os11.homedir(), ".adhdev", "daemon.pid");
8850
+ try {
8851
+ fs7.unlinkSync(pidFile);
8852
+ } catch {
8853
+ }
8854
+ }
8855
+ function cleanupStaleGlobalInstallDirs(pkgName) {
8856
+ const npmRoot = (0, import_child_process5.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8" }).trim();
8857
+ if (!npmRoot) return;
8858
+ const npmPrefix = (0, import_child_process5.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8" }).trim();
8859
+ const binDir = process.platform === "win32" ? npmPrefix : path9.join(npmPrefix, "bin");
8860
+ const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
8861
+ const binNames = /* @__PURE__ */ new Set([packageBaseName]);
8862
+ if (pkgName === "@adhdev/daemon-standalone") {
8863
+ binNames.add("adhdev-standalone");
8864
+ }
8865
+ if (pkgName.startsWith("@")) {
8866
+ const [scope, name] = pkgName.split("/");
8867
+ const scopeDir = path9.join(npmRoot, scope);
8868
+ if (!fs7.existsSync(scopeDir)) return;
8869
+ for (const entry of fs7.readdirSync(scopeDir)) {
8870
+ if (!entry.startsWith(`.${name}-`)) continue;
8871
+ fs7.rmSync(path9.join(scopeDir, entry), { recursive: true, force: true });
8872
+ appendUpgradeLog(`Removed stale scoped staging dir: ${path9.join(scopeDir, entry)}`);
8873
+ }
8874
+ } else {
8875
+ for (const entry of fs7.readdirSync(npmRoot)) {
8876
+ if (!entry.startsWith(`.${pkgName}-`)) continue;
8877
+ fs7.rmSync(path9.join(npmRoot, entry), { recursive: true, force: true });
8878
+ appendUpgradeLog(`Removed stale staging dir: ${path9.join(npmRoot, entry)}`);
8879
+ }
8880
+ }
8881
+ if (fs7.existsSync(binDir)) {
8882
+ for (const entry of fs7.readdirSync(binDir)) {
8883
+ if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
8884
+ fs7.rmSync(path9.join(binDir, entry), { recursive: true, force: true });
8885
+ appendUpgradeLog(`Removed stale bin staging entry: ${path9.join(binDir, entry)}`);
8886
+ }
8887
+ }
8888
+ }
8889
+ function spawnDetachedDaemonUpgradeHelper(payload) {
8890
+ const env = { ...process.env, [UPGRADE_HELPER_ENV]: JSON.stringify(payload) };
8891
+ const child = (0, import_child_process6.spawn)(process.execPath, process.argv.slice(1), {
8892
+ detached: true,
8893
+ stdio: "ignore",
8894
+ windowsHide: true,
8895
+ cwd: payload.cwd || process.cwd(),
8896
+ env
8897
+ });
8898
+ child.unref();
8899
+ }
8900
+ async function runDaemonUpgradeHelper(payload) {
8901
+ const restartArgv = Array.isArray(payload.restartArgv) ? payload.restartArgv : [];
8902
+ const sessionHostAppName = payload.sessionHostAppName || process.env.ADHDEV_SESSION_HOST_NAME || "adhdev";
8903
+ appendUpgradeLog(`Upgrade helper started for ${payload.packageName}@${payload.targetVersion}`);
8904
+ if (Number.isFinite(payload.parentPid) && payload.parentPid > 0) {
8905
+ appendUpgradeLog(`Waiting for parent pid ${payload.parentPid} to exit`);
8906
+ await waitForPidExit(payload.parentPid, 15e3);
8907
+ }
8908
+ stopSessionHostProcesses(sessionHostAppName);
8909
+ removeDaemonPidFile();
8910
+ cleanupStaleGlobalInstallDirs(payload.packageName);
8911
+ const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
8912
+ appendUpgradeLog(`Installing ${spec}`);
8913
+ const installOutput = (0, import_child_process5.execFileSync)(
8914
+ getNpmExecutable(),
8915
+ ["install", "-g", spec, "--force"],
8916
+ {
8917
+ encoding: "utf8",
8918
+ stdio: "pipe",
8919
+ maxBuffer: 20 * 1024 * 1024
8920
+ }
8921
+ );
8922
+ if (installOutput.trim()) {
8923
+ appendUpgradeLog(installOutput.trim());
8924
+ }
8925
+ if (restartArgv.length > 0) {
8926
+ const env = { ...process.env };
8927
+ delete env[UPGRADE_HELPER_ENV];
8928
+ appendUpgradeLog(`Restarting daemon with args: ${restartArgv.join(" ")}`);
8929
+ const child = (0, import_child_process6.spawn)(process.execPath, restartArgv, {
8930
+ detached: true,
8931
+ stdio: "ignore",
8932
+ windowsHide: true,
8933
+ cwd: payload.cwd || process.cwd(),
8934
+ env
8935
+ });
8936
+ child.unref();
8937
+ } else {
8938
+ appendUpgradeLog("No restart argv provided; upgrade completed without restart");
8939
+ }
8940
+ }
8941
+ async function maybeRunDaemonUpgradeHelperFromEnv() {
8942
+ const raw = process.env[UPGRADE_HELPER_ENV];
8943
+ if (!raw) return false;
8944
+ delete process.env[UPGRADE_HELPER_ENV];
8945
+ try {
8946
+ const payload = JSON.parse(raw);
8947
+ await runDaemonUpgradeHelper(payload);
8948
+ process.exit(0);
8949
+ } catch (error) {
8950
+ appendUpgradeLog(`Upgrade helper failed: ${error?.stack || error?.message || String(error)}`);
8951
+ process.exit(1);
8952
+ }
8953
+ }
8954
+
8955
+ // src/commands/router.ts
8956
+ var fs8 = __toESM(require("fs"));
8773
8957
  var CHAT_COMMANDS = [
8774
8958
  "send_chat",
8775
8959
  "new_chat",
@@ -8840,8 +9024,8 @@ var DaemonCommandRouter = class {
8840
9024
  if (logs.length > 0) {
8841
9025
  return { success: true, logs, totalBuffered: logs.length };
8842
9026
  }
8843
- if (fs7.existsSync(LOG_PATH)) {
8844
- const content = fs7.readFileSync(LOG_PATH, "utf-8");
9027
+ if (fs8.existsSync(LOG_PATH)) {
9028
+ const content = fs8.readFileSync(LOG_PATH, "utf-8");
8845
9029
  const allLines = content.split("\n");
8846
9030
  const recent = allLines.slice(-count).join("\n");
8847
9031
  return { success: true, logs: recent, totalLines: allLines.length };
@@ -8989,31 +9173,35 @@ var DaemonCommandRouter = class {
8989
9173
  const pkgName = isStandalone ? "@adhdev/daemon-standalone" : "adhdev";
8990
9174
  const latest = execSync7(`npm view ${pkgName} version`, { encoding: "utf-8", timeout: 1e4 }).trim();
8991
9175
  LOG.info("Upgrade", `Latest ${pkgName}: v${latest}`);
8992
- execSync7(`npm install -g ${pkgName}@latest --force`, {
8993
- encoding: "utf-8",
8994
- timeout: 12e4,
8995
- stdio: ["pipe", "pipe", "pipe"]
9176
+ let currentInstalled = null;
9177
+ try {
9178
+ const currentJson = execSync7(`npm ls -g ${pkgName} --depth=0 --json`, {
9179
+ encoding: "utf-8",
9180
+ timeout: 1e4,
9181
+ stdio: ["pipe", "pipe", "pipe"]
9182
+ }).trim();
9183
+ const parsed = JSON.parse(currentJson);
9184
+ currentInstalled = parsed?.dependencies?.[pkgName]?.version || null;
9185
+ } catch {
9186
+ }
9187
+ if (currentInstalled === latest) {
9188
+ LOG.info("Upgrade", `Already on latest version v${latest}; skipping install`);
9189
+ return { success: true, upgraded: false, alreadyLatest: true, version: latest };
9190
+ }
9191
+ spawnDetachedDaemonUpgradeHelper({
9192
+ packageName: pkgName,
9193
+ targetVersion: latest,
9194
+ parentPid: process.pid,
9195
+ restartArgv: process.argv.slice(1),
9196
+ cwd: process.cwd(),
9197
+ sessionHostAppName: process.env.ADHDEV_SESSION_HOST_NAME || "adhdev"
8996
9198
  });
8997
- LOG.info("Upgrade", `\u2705 Upgraded to v${latest}`);
9199
+ LOG.info("Upgrade", `Scheduled detached upgrade to v${latest}`);
8998
9200
  setTimeout(() => {
8999
- LOG.info("Upgrade", "Restarting daemon with new version...");
9000
- try {
9001
- const path15 = require("path");
9002
- const fs12 = require("fs");
9003
- const pidFile = path15.join(process.env.HOME || process.env.USERPROFILE || "", ".adhdev", "daemon.pid");
9004
- if (fs12.existsSync(pidFile)) fs12.unlinkSync(pidFile);
9005
- } catch {
9006
- }
9007
- const { spawn: spawn3 } = require("child_process");
9008
- const child = spawn3(process.execPath, process.argv.slice(1), {
9009
- detached: true,
9010
- stdio: "ignore",
9011
- env: { ...process.env }
9012
- });
9013
- child.unref();
9201
+ LOG.info("Upgrade", "Exiting daemon so detached upgrader can continue...");
9014
9202
  process.exit(0);
9015
9203
  }, 3e3);
9016
- return { success: true, upgraded: true, version: latest };
9204
+ return { success: true, upgraded: true, version: latest, restarting: true };
9017
9205
  } catch (e) {
9018
9206
  LOG.error("Upgrade", `Failed: ${e.message}`);
9019
9207
  return { success: false, error: e.message };
@@ -9309,8 +9497,8 @@ var DaemonStatusReporter = class {
9309
9497
  init_logger();
9310
9498
 
9311
9499
  // src/commands/cli-manager.ts
9312
- var os13 = __toESM(require("os"));
9313
- var path10 = __toESM(require("path"));
9500
+ var os14 = __toESM(require("os"));
9501
+ var path11 = __toESM(require("path"));
9314
9502
  var crypto4 = __toESM(require("crypto"));
9315
9503
  var import_chalk = __toESM(require("chalk"));
9316
9504
  init_provider_cli_adapter();
@@ -9557,7 +9745,7 @@ var CliProviderInstance = class {
9557
9745
 
9558
9746
  // src/providers/acp-provider-instance.ts
9559
9747
  var import_stream = require("stream");
9560
- var import_child_process6 = require("child_process");
9748
+ var import_child_process8 = require("child_process");
9561
9749
  var import_sdk = require("@agentclientprotocol/sdk");
9562
9750
 
9563
9751
  // src/providers/contracts.ts
@@ -9887,7 +10075,7 @@ var AcpProviderInstance = class {
9887
10075
  this.errorMessage = null;
9888
10076
  this.errorReason = null;
9889
10077
  this.stderrBuffer = [];
9890
- this.process = (0, import_child_process6.spawn)(command, args, {
10078
+ this.process = (0, import_child_process8.spawn)(command, args, {
9891
10079
  cwd: this.workingDir,
9892
10080
  env,
9893
10081
  stdio: ["pipe", "pipe", "pipe"],
@@ -10570,7 +10758,7 @@ var DaemonCliManager = class {
10570
10758
  async startSession(cliType, workingDir, cliArgs, initialModel) {
10571
10759
  const trimmed = (workingDir || "").trim();
10572
10760
  if (!trimmed) throw new Error("working directory required");
10573
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path10.resolve(trimmed);
10761
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os14.homedir()) : path11.resolve(trimmed);
10574
10762
  const normalizedType = this.providerLoader.resolveAlias(cliType);
10575
10763
  const provider = this.providerLoader.getByAlias(cliType);
10576
10764
  const key = crypto4.randomUUID();
@@ -11767,12 +11955,12 @@ var ProviderInstanceManager = class {
11767
11955
  };
11768
11956
 
11769
11957
  // src/providers/version-archive.ts
11770
- var fs8 = __toESM(require("fs"));
11771
- var path11 = __toESM(require("path"));
11772
- var os14 = __toESM(require("os"));
11773
- var import_child_process7 = require("child_process");
11958
+ var fs9 = __toESM(require("fs"));
11959
+ var path12 = __toESM(require("path"));
11960
+ var os15 = __toESM(require("os"));
11961
+ var import_child_process9 = require("child_process");
11774
11962
  var import_os3 = require("os");
11775
- var ARCHIVE_PATH = path11.join(os14.homedir(), ".adhdev", "version-history.json");
11963
+ var ARCHIVE_PATH = path12.join(os15.homedir(), ".adhdev", "version-history.json");
11776
11964
  var MAX_ENTRIES_PER_PROVIDER = 20;
11777
11965
  var VersionArchive = class {
11778
11966
  history = {};
@@ -11781,8 +11969,8 @@ var VersionArchive = class {
11781
11969
  }
11782
11970
  load() {
11783
11971
  try {
11784
- if (fs8.existsSync(ARCHIVE_PATH)) {
11785
- this.history = JSON.parse(fs8.readFileSync(ARCHIVE_PATH, "utf-8"));
11972
+ if (fs9.existsSync(ARCHIVE_PATH)) {
11973
+ this.history = JSON.parse(fs9.readFileSync(ARCHIVE_PATH, "utf-8"));
11786
11974
  }
11787
11975
  } catch {
11788
11976
  this.history = {};
@@ -11819,15 +12007,15 @@ var VersionArchive = class {
11819
12007
  }
11820
12008
  save() {
11821
12009
  try {
11822
- fs8.mkdirSync(path11.dirname(ARCHIVE_PATH), { recursive: true });
11823
- fs8.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
12010
+ fs9.mkdirSync(path12.dirname(ARCHIVE_PATH), { recursive: true });
12011
+ fs9.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
11824
12012
  } catch {
11825
12013
  }
11826
12014
  }
11827
12015
  };
11828
12016
  function runCommand(cmd, timeout = 1e4) {
11829
12017
  try {
11830
- return (0, import_child_process7.execSync)(cmd, {
12018
+ return (0, import_child_process9.execSync)(cmd, {
11831
12019
  encoding: "utf-8",
11832
12020
  timeout,
11833
12021
  stdio: ["pipe", "pipe", "pipe"]
@@ -11859,19 +12047,19 @@ function getVersion(binary, versionCommand) {
11859
12047
  function checkPathExists2(paths) {
11860
12048
  for (const p of paths) {
11861
12049
  if (p.includes("*")) {
11862
- const home = os14.homedir();
11863
- const resolved = p.replace(/\*/g, home.split(path11.sep).pop() || "");
11864
- if (fs8.existsSync(resolved)) return resolved;
12050
+ const home = os15.homedir();
12051
+ const resolved = p.replace(/\*/g, home.split(path12.sep).pop() || "");
12052
+ if (fs9.existsSync(resolved)) return resolved;
11865
12053
  } else {
11866
- if (fs8.existsSync(p)) return p;
12054
+ if (fs9.existsSync(p)) return p;
11867
12055
  }
11868
12056
  }
11869
12057
  return null;
11870
12058
  }
11871
12059
  function getMacAppVersion(appPath) {
11872
12060
  if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
11873
- const plistPath = path11.join(appPath, "Contents", "Info.plist");
11874
- if (!fs8.existsSync(plistPath)) return null;
12061
+ const plistPath = path12.join(appPath, "Contents", "Info.plist");
12062
+ if (!fs9.existsSync(plistPath)) return null;
11875
12063
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
11876
12064
  return raw || null;
11877
12065
  }
@@ -11897,8 +12085,8 @@ async function detectAllVersions(loader, archive) {
11897
12085
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
11898
12086
  let resolvedBin = cliBin;
11899
12087
  if (!resolvedBin && appPath && currentOs === "darwin") {
11900
- const bundled = path11.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
11901
- if (provider.cli && fs8.existsSync(bundled)) resolvedBin = bundled;
12088
+ const bundled = path12.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
12089
+ if (provider.cli && fs9.existsSync(bundled)) resolvedBin = bundled;
11902
12090
  }
11903
12091
  info.installed = !!(appPath || resolvedBin);
11904
12092
  info.path = appPath || null;
@@ -11937,8 +12125,8 @@ async function detectAllVersions(loader, archive) {
11937
12125
 
11938
12126
  // src/daemon/dev-server.ts
11939
12127
  var http2 = __toESM(require("http"));
11940
- var fs11 = __toESM(require("fs"));
11941
- var path14 = __toESM(require("path"));
12128
+ var fs12 = __toESM(require("fs"));
12129
+ var path15 = __toESM(require("path"));
11942
12130
 
11943
12131
  // src/daemon/scaffold-template.ts
11944
12132
  function generateFiles(type, name, category, opts = {}) {
@@ -12273,8 +12461,8 @@ async (params) => {
12273
12461
  init_logger();
12274
12462
 
12275
12463
  // src/daemon/dev-cdp-handlers.ts
12276
- var fs9 = __toESM(require("fs"));
12277
- var path12 = __toESM(require("path"));
12464
+ var fs10 = __toESM(require("fs"));
12465
+ var path13 = __toESM(require("path"));
12278
12466
  init_logger();
12279
12467
  async function handleCdpEvaluate(ctx, req, res) {
12280
12468
  const body = await ctx.readBody(req);
@@ -12453,18 +12641,18 @@ async function handleScriptHints(ctx, type, _req, res) {
12453
12641
  return;
12454
12642
  }
12455
12643
  let scriptsPath = "";
12456
- const directScripts = path12.join(dir, "scripts.js");
12457
- if (fs9.existsSync(directScripts)) {
12644
+ const directScripts = path13.join(dir, "scripts.js");
12645
+ if (fs10.existsSync(directScripts)) {
12458
12646
  scriptsPath = directScripts;
12459
12647
  } else {
12460
- const scriptsDir = path12.join(dir, "scripts");
12461
- if (fs9.existsSync(scriptsDir)) {
12462
- const versions = fs9.readdirSync(scriptsDir).filter((d) => {
12463
- return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
12648
+ const scriptsDir = path13.join(dir, "scripts");
12649
+ if (fs10.existsSync(scriptsDir)) {
12650
+ const versions = fs10.readdirSync(scriptsDir).filter((d) => {
12651
+ return fs10.statSync(path13.join(scriptsDir, d)).isDirectory();
12464
12652
  }).sort().reverse();
12465
12653
  for (const ver of versions) {
12466
- const p = path12.join(scriptsDir, ver, "scripts.js");
12467
- if (fs9.existsSync(p)) {
12654
+ const p = path13.join(scriptsDir, ver, "scripts.js");
12655
+ if (fs10.existsSync(p)) {
12468
12656
  scriptsPath = p;
12469
12657
  break;
12470
12658
  }
@@ -12476,7 +12664,7 @@ async function handleScriptHints(ctx, type, _req, res) {
12476
12664
  return;
12477
12665
  }
12478
12666
  try {
12479
- const source = fs9.readFileSync(scriptsPath, "utf-8");
12667
+ const source = fs10.readFileSync(scriptsPath, "utf-8");
12480
12668
  const hints = {};
12481
12669
  const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
12482
12670
  let match;
@@ -13517,9 +13705,9 @@ async function handleCliRaw(ctx, req, res) {
13517
13705
  }
13518
13706
 
13519
13707
  // src/daemon/dev-auto-implement.ts
13520
- var fs10 = __toESM(require("fs"));
13521
- var path13 = __toESM(require("path"));
13522
- var os15 = __toESM(require("os"));
13708
+ var fs11 = __toESM(require("fs"));
13709
+ var path14 = __toESM(require("path"));
13710
+ var os16 = __toESM(require("os"));
13523
13711
  function getDefaultAutoImplReference(ctx, category, type) {
13524
13712
  if (category === "cli") {
13525
13713
  return type === "codex-cli" ? "claude-cli" : "codex-cli";
@@ -13535,45 +13723,45 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
13535
13723
  return fallback?.type || null;
13536
13724
  }
13537
13725
  function getLatestScriptVersionDir(scriptsDir) {
13538
- if (!fs10.existsSync(scriptsDir)) return null;
13539
- const versions = fs10.readdirSync(scriptsDir).filter((d) => {
13726
+ if (!fs11.existsSync(scriptsDir)) return null;
13727
+ const versions = fs11.readdirSync(scriptsDir).filter((d) => {
13540
13728
  try {
13541
- return fs10.statSync(path13.join(scriptsDir, d)).isDirectory();
13729
+ return fs11.statSync(path14.join(scriptsDir, d)).isDirectory();
13542
13730
  } catch {
13543
13731
  return false;
13544
13732
  }
13545
13733
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
13546
13734
  if (versions.length === 0) return null;
13547
- return path13.join(scriptsDir, versions[0]);
13735
+ return path14.join(scriptsDir, versions[0]);
13548
13736
  }
13549
13737
  function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
13550
- const canonicalUserDir = path13.resolve(ctx.providerLoader.getUserProviderDir(category, type));
13551
- const desiredDir = requestedDir ? path13.resolve(requestedDir) : canonicalUserDir;
13552
- const upstreamRoot = path13.resolve(ctx.providerLoader.getUpstreamDir());
13553
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path13.sep}`)) {
13738
+ const canonicalUserDir = path14.resolve(ctx.providerLoader.getUserProviderDir(category, type));
13739
+ const desiredDir = requestedDir ? path14.resolve(requestedDir) : canonicalUserDir;
13740
+ const upstreamRoot = path14.resolve(ctx.providerLoader.getUpstreamDir());
13741
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path14.sep}`)) {
13554
13742
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
13555
13743
  }
13556
- if (path13.basename(desiredDir) !== type) {
13744
+ if (path14.basename(desiredDir) !== type) {
13557
13745
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
13558
13746
  }
13559
13747
  const sourceDir = ctx.findProviderDir(type);
13560
13748
  if (!sourceDir) {
13561
13749
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
13562
13750
  }
13563
- if (!fs10.existsSync(desiredDir)) {
13564
- fs10.mkdirSync(path13.dirname(desiredDir), { recursive: true });
13565
- fs10.cpSync(sourceDir, desiredDir, { recursive: true });
13751
+ if (!fs11.existsSync(desiredDir)) {
13752
+ fs11.mkdirSync(path14.dirname(desiredDir), { recursive: true });
13753
+ fs11.cpSync(sourceDir, desiredDir, { recursive: true });
13566
13754
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
13567
13755
  }
13568
- const providerJson = path13.join(desiredDir, "provider.json");
13569
- if (!fs10.existsSync(providerJson)) {
13756
+ const providerJson = path14.join(desiredDir, "provider.json");
13757
+ if (!fs11.existsSync(providerJson)) {
13570
13758
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
13571
13759
  }
13572
13760
  try {
13573
- const providerData = JSON.parse(fs10.readFileSync(providerJson, "utf-8"));
13761
+ const providerData = JSON.parse(fs11.readFileSync(providerJson, "utf-8"));
13574
13762
  if (providerData.disableUpstream !== true) {
13575
13763
  providerData.disableUpstream = true;
13576
- fs10.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
13764
+ fs11.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
13577
13765
  }
13578
13766
  } catch (error) {
13579
13767
  return {
@@ -13586,15 +13774,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
13586
13774
  function loadAutoImplReferenceScripts(ctx, referenceType) {
13587
13775
  if (!referenceType) return {};
13588
13776
  const refDir = ctx.findProviderDir(referenceType);
13589
- if (!refDir || !fs10.existsSync(refDir)) return {};
13777
+ if (!refDir || !fs11.existsSync(refDir)) return {};
13590
13778
  const referenceScripts = {};
13591
- const scriptsDir = path13.join(refDir, "scripts");
13779
+ const scriptsDir = path14.join(refDir, "scripts");
13592
13780
  const latestDir = getLatestScriptVersionDir(scriptsDir);
13593
13781
  if (!latestDir) return referenceScripts;
13594
- for (const file of fs10.readdirSync(latestDir)) {
13782
+ for (const file of fs11.readdirSync(latestDir)) {
13595
13783
  if (!file.endsWith(".js")) continue;
13596
13784
  try {
13597
- referenceScripts[file] = fs10.readFileSync(path13.join(latestDir, file), "utf-8");
13785
+ referenceScripts[file] = fs11.readFileSync(path14.join(latestDir, file), "utf-8");
13598
13786
  } catch {
13599
13787
  }
13600
13788
  }
@@ -13645,16 +13833,16 @@ async function handleAutoImplement(ctx, type, req, res) {
13645
13833
  });
13646
13834
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
13647
13835
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference);
13648
- const tmpDir = path13.join(os15.tmpdir(), "adhdev-autoimpl");
13649
- if (!fs10.existsSync(tmpDir)) fs10.mkdirSync(tmpDir, { recursive: true });
13650
- const promptFile = path13.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
13651
- fs10.writeFileSync(promptFile, prompt, "utf-8");
13836
+ const tmpDir = path14.join(os16.tmpdir(), "adhdev-autoimpl");
13837
+ if (!fs11.existsSync(tmpDir)) fs11.mkdirSync(tmpDir, { recursive: true });
13838
+ const promptFile = path14.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
13839
+ fs11.writeFileSync(promptFile, prompt, "utf-8");
13652
13840
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
13653
13841
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
13654
- const spawn3 = agentProvider?.spawn;
13655
- if (!spawn3?.command) {
13842
+ const spawn4 = agentProvider?.spawn;
13843
+ if (!spawn4?.command) {
13656
13844
  try {
13657
- fs10.unlinkSync(promptFile);
13845
+ fs11.unlinkSync(promptFile);
13658
13846
  } catch {
13659
13847
  }
13660
13848
  ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
@@ -13662,21 +13850,21 @@ async function handleAutoImplement(ctx, type, req, res) {
13662
13850
  }
13663
13851
  const agentCategory = agentProvider?.category;
13664
13852
  if (agentCategory === "acp") {
13665
- sendAutoImplSSE(ctx, { event: "progress", data: { function: "_init", status: "spawning", message: `Spawning ACP agent: ${spawn3.command} ${(spawn3.args || []).join(" ")}` } });
13853
+ sendAutoImplSSE(ctx, { event: "progress", data: { function: "_init", status: "spawning", message: `Spawning ACP agent: ${spawn4.command} ${(spawn4.args || []).join(" ")}` } });
13666
13854
  ctx.autoImplStatus = { running: true, type, progress: [] };
13667
13855
  const { ClientSideConnection: ClientSideConnection2, ndJsonStream: ndJsonStream2, PROTOCOL_VERSION: PROTOCOL_VERSION2 } = await import("@agentclientprotocol/sdk");
13668
13856
  const { Readable: Readable2, Writable: Writable2 } = await import("stream");
13669
13857
  const { spawn: spawnFn2 } = await import("child_process");
13670
- const acpArgs = [...spawn3.args || []];
13858
+ const acpArgs = [...spawn4.args || []];
13671
13859
  if (model) {
13672
13860
  acpArgs.push("--model", model);
13673
13861
  ctx.log(`Auto-implement ACP using model: ${model}`);
13674
13862
  }
13675
- const child2 = spawnFn2(spawn3.command, acpArgs, {
13863
+ const child2 = spawnFn2(spawn4.command, acpArgs, {
13676
13864
  cwd: providerDir,
13677
13865
  stdio: ["pipe", "pipe", "pipe"],
13678
- shell: spawn3.shell ?? false,
13679
- env: { ...process.env, ...spawn3.env || {} }
13866
+ shell: spawn4.shell ?? false,
13867
+ env: { ...process.env, ...spawn4.env || {} }
13680
13868
  });
13681
13869
  ctx.autoImplProcess = child2;
13682
13870
  child2.stderr?.on("data", (d) => {
@@ -13755,7 +13943,7 @@ async function handleAutoImplement(ctx, type, req, res) {
13755
13943
  } catch {
13756
13944
  }
13757
13945
  try {
13758
- fs10.unlinkSync(promptFile);
13946
+ fs11.unlinkSync(promptFile);
13759
13947
  } catch {
13760
13948
  }
13761
13949
  ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
@@ -13786,7 +13974,7 @@ async function handleAutoImplement(ctx, type, req, res) {
13786
13974
  ctx.json(res, 202, {
13787
13975
  started: true,
13788
13976
  type,
13789
- agent: spawn3.command,
13977
+ agent: spawn4.command,
13790
13978
  functions,
13791
13979
  providerDir,
13792
13980
  message: "ACP Auto-implement started. Connect to SSE for progress.",
@@ -13794,11 +13982,11 @@ async function handleAutoImplement(ctx, type, req, res) {
13794
13982
  });
13795
13983
  return;
13796
13984
  }
13797
- const command = spawn3.command;
13985
+ const command = spawn4.command;
13798
13986
  const interactiveFlags = ["--yolo", "--interactive", "-i"];
13799
- const baseArgs = [...spawn3.args || []].filter((a) => !interactiveFlags.includes(a));
13987
+ const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
13800
13988
  let shellCmd;
13801
- const isWin = os15.platform() === "win32";
13989
+ const isWin = os16.platform() === "win32";
13802
13990
  const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
13803
13991
  if (command === "claude") {
13804
13992
  const args = [...baseArgs, "--dangerously-skip-permissions"];
@@ -13841,13 +14029,13 @@ async function handleAutoImplement(ctx, type, req, res) {
13841
14029
  try {
13842
14030
  const pty3 = require("node-pty");
13843
14031
  ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
13844
- const isWin2 = os15.platform() === "win32";
14032
+ const isWin2 = os16.platform() === "win32";
13845
14033
  child = pty3.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
13846
14034
  name: "xterm-256color",
13847
14035
  cols: 120,
13848
14036
  rows: 40,
13849
14037
  cwd: providerDir,
13850
- env: { ...process.env, ...spawn3.env || {} }
14038
+ env: { ...process.env, ...spawn4.env || {} }
13851
14039
  });
13852
14040
  isPty = true;
13853
14041
  } catch (err) {
@@ -13859,7 +14047,7 @@ async function handleAutoImplement(ctx, type, req, res) {
13859
14047
  stdio: ["pipe", "pipe", "pipe"],
13860
14048
  env: {
13861
14049
  ...process.env,
13862
- ...spawn3.env || {},
14050
+ ...spawn4.env || {},
13863
14051
  ...command === "gemini" ? { SANDBOX: "1", GEMINI_CLI_NO_RELAUNCH: "1" } : {}
13864
14052
  }
13865
14053
  });
@@ -13935,7 +14123,7 @@ async function handleAutoImplement(ctx, type, req, res) {
13935
14123
  } catch {
13936
14124
  }
13937
14125
  try {
13938
- fs10.unlinkSync(promptFile);
14126
+ fs11.unlinkSync(promptFile);
13939
14127
  } catch {
13940
14128
  }
13941
14129
  });
@@ -13971,7 +14159,7 @@ async function handleAutoImplement(ctx, type, req, res) {
13971
14159
  } catch {
13972
14160
  }
13973
14161
  try {
13974
- fs10.unlinkSync(promptFile);
14162
+ fs11.unlinkSync(promptFile);
13975
14163
  } catch {
13976
14164
  }
13977
14165
  ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
@@ -14018,7 +14206,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
14018
14206
  setMode: "set_mode.js"
14019
14207
  };
14020
14208
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
14021
- const scriptsDir = path13.join(providerDir, "scripts");
14209
+ const scriptsDir = path14.join(providerDir, "scripts");
14022
14210
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
14023
14211
  if (latestScriptsDir) {
14024
14212
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -14026,10 +14214,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
14026
14214
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
14027
14215
  lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
14028
14216
  lines.push("");
14029
- for (const file of fs10.readdirSync(latestScriptsDir)) {
14217
+ for (const file of fs11.readdirSync(latestScriptsDir)) {
14030
14218
  if (file.endsWith(".js") && targetFileNames.has(file)) {
14031
14219
  try {
14032
- const content = fs10.readFileSync(path13.join(latestScriptsDir, file), "utf-8");
14220
+ const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
14033
14221
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
14034
14222
  lines.push("```javascript");
14035
14223
  lines.push(content);
@@ -14039,14 +14227,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
14039
14227
  }
14040
14228
  }
14041
14229
  }
14042
- const refFiles = fs10.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
14230
+ const refFiles = fs11.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
14043
14231
  if (refFiles.length > 0) {
14044
14232
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
14045
14233
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
14046
14234
  lines.push("");
14047
14235
  for (const file of refFiles) {
14048
14236
  try {
14049
- const content = fs10.readFileSync(path13.join(latestScriptsDir, file), "utf-8");
14237
+ const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
14050
14238
  lines.push(`### \`${file}\` \u{1F512}`);
14051
14239
  lines.push("```javascript");
14052
14240
  lines.push(content);
@@ -14087,11 +14275,11 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
14087
14275
  lines.push("");
14088
14276
  }
14089
14277
  }
14090
- const docsDir = path13.join(providerDir, "../../docs");
14278
+ const docsDir = path14.join(providerDir, "../../docs");
14091
14279
  const loadGuide = (name) => {
14092
14280
  try {
14093
- const p = path13.join(docsDir, name);
14094
- if (fs10.existsSync(p)) return fs10.readFileSync(p, "utf-8");
14281
+ const p = path14.join(docsDir, name);
14282
+ if (fs11.existsSync(p)) return fs11.readFileSync(p, "utf-8");
14095
14283
  } catch {
14096
14284
  }
14097
14285
  return null;
@@ -14264,7 +14452,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
14264
14452
  parseApproval: "parse_approval.js"
14265
14453
  };
14266
14454
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
14267
- const scriptsDir = path13.join(providerDir, "scripts");
14455
+ const scriptsDir = path14.join(providerDir, "scripts");
14268
14456
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
14269
14457
  if (latestScriptsDir) {
14270
14458
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -14272,11 +14460,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
14272
14460
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
14273
14461
  lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
14274
14462
  lines.push("");
14275
- for (const file of fs10.readdirSync(latestScriptsDir)) {
14463
+ for (const file of fs11.readdirSync(latestScriptsDir)) {
14276
14464
  if (!file.endsWith(".js")) continue;
14277
14465
  if (!targetFileNames.has(file)) continue;
14278
14466
  try {
14279
- const content = fs10.readFileSync(path13.join(latestScriptsDir, file), "utf-8");
14467
+ const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
14280
14468
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
14281
14469
  lines.push("```javascript");
14282
14470
  lines.push(content);
@@ -14285,14 +14473,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
14285
14473
  } catch {
14286
14474
  }
14287
14475
  }
14288
- const refFiles = fs10.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
14476
+ const refFiles = fs11.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
14289
14477
  if (refFiles.length > 0) {
14290
14478
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
14291
14479
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
14292
14480
  lines.push("");
14293
14481
  for (const file of refFiles) {
14294
14482
  try {
14295
- const content = fs10.readFileSync(path13.join(latestScriptsDir, file), "utf-8");
14483
+ const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
14296
14484
  lines.push(`### \`${file}\` \u{1F512}`);
14297
14485
  lines.push("```javascript");
14298
14486
  lines.push(content);
@@ -14325,11 +14513,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
14325
14513
  lines.push("");
14326
14514
  }
14327
14515
  }
14328
- const docsDir = path13.join(providerDir, "../../docs");
14516
+ const docsDir = path14.join(providerDir, "../../docs");
14329
14517
  const loadGuide = (name) => {
14330
14518
  try {
14331
- const p = path13.join(docsDir, name);
14332
- if (fs10.existsSync(p)) return fs10.readFileSync(p, "utf-8");
14519
+ const p = path14.join(docsDir, name);
14520
+ if (fs11.existsSync(p)) return fs11.readFileSync(p, "utf-8");
14333
14521
  } catch {
14334
14522
  }
14335
14523
  return null;
@@ -14586,8 +14774,8 @@ var DevServer = class _DevServer {
14586
14774
  }
14587
14775
  getEndpointList() {
14588
14776
  return this.routes.map((r) => {
14589
- const path15 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
14590
- return `${r.method.padEnd(5)} ${path15}`;
14777
+ const path16 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
14778
+ return `${r.method.padEnd(5)} ${path16}`;
14591
14779
  });
14592
14780
  }
14593
14781
  async start(port = DEV_SERVER_PORT) {
@@ -14688,16 +14876,16 @@ var DevServer = class _DevServer {
14688
14876
  this.json(res, 404, { error: `Provider not found: ${type}` });
14689
14877
  return;
14690
14878
  }
14691
- const spawn3 = provider.spawn;
14692
- if (!spawn3) {
14879
+ const spawn4 = provider.spawn;
14880
+ if (!spawn4) {
14693
14881
  this.json(res, 400, { error: `Provider ${type} has no spawn config` });
14694
14882
  return;
14695
14883
  }
14696
14884
  const { spawn: spawnFn } = await import("child_process");
14697
14885
  const start = Date.now();
14698
14886
  try {
14699
- const child = spawnFn(spawn3.command, [...spawn3.args || []], {
14700
- shell: spawn3.shell ?? false,
14887
+ const child = spawnFn(spawn4.command, [...spawn4.args || []], {
14888
+ shell: spawn4.shell ?? false,
14701
14889
  timeout: 5e3,
14702
14890
  stdio: ["pipe", "pipe", "pipe"]
14703
14891
  });
@@ -14729,7 +14917,7 @@ var DevServer = class _DevServer {
14729
14917
  const elapsed = Date.now() - start;
14730
14918
  this.json(res, 200, {
14731
14919
  success: true,
14732
- command: `${spawn3.command} ${(spawn3.args || []).join(" ")}`,
14920
+ command: `${spawn4.command} ${(spawn4.args || []).join(" ")}`,
14733
14921
  elapsed,
14734
14922
  stdout: stdout.trim(),
14735
14923
  stderr: stderr.trim(),
@@ -14739,7 +14927,7 @@ var DevServer = class _DevServer {
14739
14927
  const elapsed = Date.now() - start;
14740
14928
  this.json(res, 200, {
14741
14929
  success: false,
14742
- command: `${spawn3.command} ${(spawn3.args || []).join(" ")}`,
14930
+ command: `${spawn4.command} ${(spawn4.args || []).join(" ")}`,
14743
14931
  elapsed,
14744
14932
  error: e.message
14745
14933
  });
@@ -14869,12 +15057,12 @@ var DevServer = class _DevServer {
14869
15057
  // ─── DevConsole SPA ───
14870
15058
  getConsoleDistDir() {
14871
15059
  const candidates = [
14872
- path14.resolve(__dirname, "../../web-devconsole/dist"),
14873
- path14.resolve(__dirname, "../../../web-devconsole/dist"),
14874
- path14.join(process.cwd(), "packages/web-devconsole/dist")
15060
+ path15.resolve(__dirname, "../../web-devconsole/dist"),
15061
+ path15.resolve(__dirname, "../../../web-devconsole/dist"),
15062
+ path15.join(process.cwd(), "packages/web-devconsole/dist")
14875
15063
  ];
14876
15064
  for (const dir of candidates) {
14877
- if (fs11.existsSync(path14.join(dir, "index.html"))) return dir;
15065
+ if (fs12.existsSync(path15.join(dir, "index.html"))) return dir;
14878
15066
  }
14879
15067
  return null;
14880
15068
  }
@@ -14884,9 +15072,9 @@ var DevServer = class _DevServer {
14884
15072
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
14885
15073
  return;
14886
15074
  }
14887
- const htmlPath = path14.join(distDir, "index.html");
15075
+ const htmlPath = path15.join(distDir, "index.html");
14888
15076
  try {
14889
- const html = fs11.readFileSync(htmlPath, "utf-8");
15077
+ const html = fs12.readFileSync(htmlPath, "utf-8");
14890
15078
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
14891
15079
  res.end(html);
14892
15080
  } catch (e) {
@@ -14909,15 +15097,15 @@ var DevServer = class _DevServer {
14909
15097
  this.json(res, 404, { error: "Not found" });
14910
15098
  return;
14911
15099
  }
14912
- const safePath = path14.normalize(pathname).replace(/^\.\.\//, "");
14913
- const filePath = path14.join(distDir, safePath);
15100
+ const safePath = path15.normalize(pathname).replace(/^\.\.\//, "");
15101
+ const filePath = path15.join(distDir, safePath);
14914
15102
  if (!filePath.startsWith(distDir)) {
14915
15103
  this.json(res, 403, { error: "Forbidden" });
14916
15104
  return;
14917
15105
  }
14918
15106
  try {
14919
- const content = fs11.readFileSync(filePath);
14920
- const ext = path14.extname(filePath);
15107
+ const content = fs12.readFileSync(filePath);
15108
+ const ext = path15.extname(filePath);
14921
15109
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
14922
15110
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
14923
15111
  res.end(content);
@@ -15025,14 +15213,14 @@ var DevServer = class _DevServer {
15025
15213
  const files = [];
15026
15214
  const scan = (d, prefix) => {
15027
15215
  try {
15028
- for (const entry of fs11.readdirSync(d, { withFileTypes: true })) {
15216
+ for (const entry of fs12.readdirSync(d, { withFileTypes: true })) {
15029
15217
  if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
15030
15218
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
15031
15219
  if (entry.isDirectory()) {
15032
15220
  files.push({ path: rel, size: 0, type: "dir" });
15033
- scan(path14.join(d, entry.name), rel);
15221
+ scan(path15.join(d, entry.name), rel);
15034
15222
  } else {
15035
- const stat = fs11.statSync(path14.join(d, entry.name));
15223
+ const stat = fs12.statSync(path15.join(d, entry.name));
15036
15224
  files.push({ path: rel, size: stat.size, type: "file" });
15037
15225
  }
15038
15226
  }
@@ -15055,16 +15243,16 @@ var DevServer = class _DevServer {
15055
15243
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
15056
15244
  return;
15057
15245
  }
15058
- const fullPath = path14.resolve(dir, path14.normalize(filePath));
15246
+ const fullPath = path15.resolve(dir, path15.normalize(filePath));
15059
15247
  if (!fullPath.startsWith(dir)) {
15060
15248
  this.json(res, 403, { error: "Forbidden" });
15061
15249
  return;
15062
15250
  }
15063
- if (!fs11.existsSync(fullPath) || fs11.statSync(fullPath).isDirectory()) {
15251
+ if (!fs12.existsSync(fullPath) || fs12.statSync(fullPath).isDirectory()) {
15064
15252
  this.json(res, 404, { error: `File not found: ${filePath}` });
15065
15253
  return;
15066
15254
  }
15067
- const content = fs11.readFileSync(fullPath, "utf-8");
15255
+ const content = fs12.readFileSync(fullPath, "utf-8");
15068
15256
  this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
15069
15257
  }
15070
15258
  /** POST /api/providers/:type/file — write a file { path, content } */
@@ -15080,15 +15268,15 @@ var DevServer = class _DevServer {
15080
15268
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
15081
15269
  return;
15082
15270
  }
15083
- const fullPath = path14.resolve(dir, path14.normalize(filePath));
15271
+ const fullPath = path15.resolve(dir, path15.normalize(filePath));
15084
15272
  if (!fullPath.startsWith(dir)) {
15085
15273
  this.json(res, 403, { error: "Forbidden" });
15086
15274
  return;
15087
15275
  }
15088
15276
  try {
15089
- if (fs11.existsSync(fullPath)) fs11.copyFileSync(fullPath, fullPath + ".bak");
15090
- fs11.mkdirSync(path14.dirname(fullPath), { recursive: true });
15091
- fs11.writeFileSync(fullPath, content, "utf-8");
15277
+ if (fs12.existsSync(fullPath)) fs12.copyFileSync(fullPath, fullPath + ".bak");
15278
+ fs12.mkdirSync(path15.dirname(fullPath), { recursive: true });
15279
+ fs12.writeFileSync(fullPath, content, "utf-8");
15092
15280
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
15093
15281
  this.providerLoader.reload();
15094
15282
  this.json(res, 200, { saved: true, path: filePath, chars: content.length });
@@ -15104,9 +15292,9 @@ var DevServer = class _DevServer {
15104
15292
  return;
15105
15293
  }
15106
15294
  for (const name of ["scripts.js", "provider.json"]) {
15107
- const p = path14.join(dir, name);
15108
- if (fs11.existsSync(p)) {
15109
- const source = fs11.readFileSync(p, "utf-8");
15295
+ const p = path15.join(dir, name);
15296
+ if (fs12.existsSync(p)) {
15297
+ const source = fs12.readFileSync(p, "utf-8");
15110
15298
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
15111
15299
  return;
15112
15300
  }
@@ -15125,11 +15313,11 @@ var DevServer = class _DevServer {
15125
15313
  this.json(res, 404, { error: `Provider not found: ${type}` });
15126
15314
  return;
15127
15315
  }
15128
- const target = fs11.existsSync(path14.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
15129
- const targetPath = path14.join(dir, target);
15316
+ const target = fs12.existsSync(path15.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
15317
+ const targetPath = path15.join(dir, target);
15130
15318
  try {
15131
- if (fs11.existsSync(targetPath)) fs11.copyFileSync(targetPath, targetPath + ".bak");
15132
- fs11.writeFileSync(targetPath, source, "utf-8");
15319
+ if (fs12.existsSync(targetPath)) fs12.copyFileSync(targetPath, targetPath + ".bak");
15320
+ fs12.writeFileSync(targetPath, source, "utf-8");
15133
15321
  this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
15134
15322
  this.providerLoader.reload();
15135
15323
  this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
@@ -15208,20 +15396,20 @@ var DevServer = class _DevServer {
15208
15396
  this.json(res, 404, { error: `Provider not found: ${type}` });
15209
15397
  return;
15210
15398
  }
15211
- const spawn3 = provider.spawn;
15212
- if (!spawn3) {
15399
+ const spawn4 = provider.spawn;
15400
+ if (!spawn4) {
15213
15401
  this.json(res, 400, { error: `Provider ${type} has no spawn config` });
15214
15402
  return;
15215
15403
  }
15216
15404
  const { spawn: spawnFn } = await import("child_process");
15217
15405
  const start = Date.now();
15218
15406
  try {
15219
- const args = [...spawn3.args || [], message];
15220
- const child = spawnFn(spawn3.command, args, {
15221
- shell: spawn3.shell ?? false,
15407
+ const args = [...spawn4.args || [], message];
15408
+ const child = spawnFn(spawn4.command, args, {
15409
+ shell: spawn4.shell ?? false,
15222
15410
  timeout,
15223
15411
  stdio: ["pipe", "pipe", "pipe"],
15224
- env: { ...process.env, ...spawn3.env || {} }
15412
+ env: { ...process.env, ...spawn4.env || {} }
15225
15413
  });
15226
15414
  let stdout = "";
15227
15415
  let stderr = "";
@@ -15286,21 +15474,21 @@ var DevServer = class _DevServer {
15286
15474
  }
15287
15475
  let targetDir;
15288
15476
  targetDir = this.providerLoader.getUserProviderDir(category, type);
15289
- const jsonPath = path14.join(targetDir, "provider.json");
15290
- if (fs11.existsSync(jsonPath)) {
15477
+ const jsonPath = path15.join(targetDir, "provider.json");
15478
+ if (fs12.existsSync(jsonPath)) {
15291
15479
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
15292
15480
  return;
15293
15481
  }
15294
15482
  try {
15295
15483
  const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
15296
- fs11.mkdirSync(targetDir, { recursive: true });
15297
- fs11.writeFileSync(jsonPath, result["provider.json"], "utf-8");
15484
+ fs12.mkdirSync(targetDir, { recursive: true });
15485
+ fs12.writeFileSync(jsonPath, result["provider.json"], "utf-8");
15298
15486
  const createdFiles = ["provider.json"];
15299
15487
  if (result.files) {
15300
15488
  for (const [relPath, content] of Object.entries(result.files)) {
15301
- const fullPath = path14.join(targetDir, relPath);
15302
- fs11.mkdirSync(path14.dirname(fullPath), { recursive: true });
15303
- fs11.writeFileSync(fullPath, content, "utf-8");
15489
+ const fullPath = path15.join(targetDir, relPath);
15490
+ fs12.mkdirSync(path15.dirname(fullPath), { recursive: true });
15491
+ fs12.writeFileSync(fullPath, content, "utf-8");
15304
15492
  createdFiles.push(relPath);
15305
15493
  }
15306
15494
  }
@@ -15349,45 +15537,45 @@ var DevServer = class _DevServer {
15349
15537
  }
15350
15538
  // ─── Phase 2: Auto-Implement Backend ───
15351
15539
  getLatestScriptVersionDir(scriptsDir) {
15352
- if (!fs11.existsSync(scriptsDir)) return null;
15353
- const versions = fs11.readdirSync(scriptsDir).filter((d) => {
15540
+ if (!fs12.existsSync(scriptsDir)) return null;
15541
+ const versions = fs12.readdirSync(scriptsDir).filter((d) => {
15354
15542
  try {
15355
- return fs11.statSync(path14.join(scriptsDir, d)).isDirectory();
15543
+ return fs12.statSync(path15.join(scriptsDir, d)).isDirectory();
15356
15544
  } catch {
15357
15545
  return false;
15358
15546
  }
15359
15547
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
15360
15548
  if (versions.length === 0) return null;
15361
- return path14.join(scriptsDir, versions[0]);
15549
+ return path15.join(scriptsDir, versions[0]);
15362
15550
  }
15363
15551
  resolveAutoImplWritableProviderDir(category, type, requestedDir) {
15364
- const canonicalUserDir = path14.resolve(this.providerLoader.getUserProviderDir(category, type));
15365
- const desiredDir = requestedDir ? path14.resolve(requestedDir) : canonicalUserDir;
15366
- const upstreamRoot = path14.resolve(this.providerLoader.getUpstreamDir());
15367
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path14.sep}`)) {
15552
+ const canonicalUserDir = path15.resolve(this.providerLoader.getUserProviderDir(category, type));
15553
+ const desiredDir = requestedDir ? path15.resolve(requestedDir) : canonicalUserDir;
15554
+ const upstreamRoot = path15.resolve(this.providerLoader.getUpstreamDir());
15555
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path15.sep}`)) {
15368
15556
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
15369
15557
  }
15370
- if (path14.basename(desiredDir) !== type) {
15558
+ if (path15.basename(desiredDir) !== type) {
15371
15559
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
15372
15560
  }
15373
15561
  const sourceDir = this.findProviderDir(type);
15374
15562
  if (!sourceDir) {
15375
15563
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
15376
15564
  }
15377
- if (!fs11.existsSync(desiredDir)) {
15378
- fs11.mkdirSync(path14.dirname(desiredDir), { recursive: true });
15379
- fs11.cpSync(sourceDir, desiredDir, { recursive: true });
15565
+ if (!fs12.existsSync(desiredDir)) {
15566
+ fs12.mkdirSync(path15.dirname(desiredDir), { recursive: true });
15567
+ fs12.cpSync(sourceDir, desiredDir, { recursive: true });
15380
15568
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
15381
15569
  }
15382
- const providerJson = path14.join(desiredDir, "provider.json");
15383
- if (!fs11.existsSync(providerJson)) {
15570
+ const providerJson = path15.join(desiredDir, "provider.json");
15571
+ if (!fs12.existsSync(providerJson)) {
15384
15572
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
15385
15573
  }
15386
15574
  try {
15387
- const providerData = JSON.parse(fs11.readFileSync(providerJson, "utf-8"));
15575
+ const providerData = JSON.parse(fs12.readFileSync(providerJson, "utf-8"));
15388
15576
  if (providerData.disableUpstream !== true) {
15389
15577
  providerData.disableUpstream = true;
15390
- fs11.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
15578
+ fs12.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
15391
15579
  }
15392
15580
  } catch (error) {
15393
15581
  return {
@@ -15427,7 +15615,7 @@ var DevServer = class _DevServer {
15427
15615
  setMode: "set_mode.js"
15428
15616
  };
15429
15617
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
15430
- const scriptsDir = path14.join(providerDir, "scripts");
15618
+ const scriptsDir = path15.join(providerDir, "scripts");
15431
15619
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
15432
15620
  if (latestScriptsDir) {
15433
15621
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -15435,10 +15623,10 @@ var DevServer = class _DevServer {
15435
15623
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
15436
15624
  lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
15437
15625
  lines.push("");
15438
- for (const file of fs11.readdirSync(latestScriptsDir)) {
15626
+ for (const file of fs12.readdirSync(latestScriptsDir)) {
15439
15627
  if (file.endsWith(".js") && targetFileNames.has(file)) {
15440
15628
  try {
15441
- const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
15629
+ const content = fs12.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
15442
15630
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
15443
15631
  lines.push("```javascript");
15444
15632
  lines.push(content);
@@ -15448,14 +15636,14 @@ var DevServer = class _DevServer {
15448
15636
  }
15449
15637
  }
15450
15638
  }
15451
- const refFiles = fs11.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
15639
+ const refFiles = fs12.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
15452
15640
  if (refFiles.length > 0) {
15453
15641
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
15454
15642
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
15455
15643
  lines.push("");
15456
15644
  for (const file of refFiles) {
15457
15645
  try {
15458
- const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
15646
+ const content = fs12.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
15459
15647
  lines.push(`### \`${file}\` \u{1F512}`);
15460
15648
  lines.push("```javascript");
15461
15649
  lines.push(content);
@@ -15496,11 +15684,11 @@ var DevServer = class _DevServer {
15496
15684
  lines.push("");
15497
15685
  }
15498
15686
  }
15499
- const docsDir = path14.join(providerDir, "../../docs");
15687
+ const docsDir = path15.join(providerDir, "../../docs");
15500
15688
  const loadGuide = (name) => {
15501
15689
  try {
15502
- const p = path14.join(docsDir, name);
15503
- if (fs11.existsSync(p)) return fs11.readFileSync(p, "utf-8");
15690
+ const p = path15.join(docsDir, name);
15691
+ if (fs12.existsSync(p)) return fs12.readFileSync(p, "utf-8");
15504
15692
  } catch {
15505
15693
  }
15506
15694
  return null;
@@ -15673,7 +15861,7 @@ var DevServer = class _DevServer {
15673
15861
  parseApproval: "parse_approval.js"
15674
15862
  };
15675
15863
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
15676
- const scriptsDir = path14.join(providerDir, "scripts");
15864
+ const scriptsDir = path15.join(providerDir, "scripts");
15677
15865
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
15678
15866
  if (latestScriptsDir) {
15679
15867
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -15681,11 +15869,11 @@ var DevServer = class _DevServer {
15681
15869
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
15682
15870
  lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
15683
15871
  lines.push("");
15684
- for (const file of fs11.readdirSync(latestScriptsDir)) {
15872
+ for (const file of fs12.readdirSync(latestScriptsDir)) {
15685
15873
  if (!file.endsWith(".js")) continue;
15686
15874
  if (!targetFileNames.has(file)) continue;
15687
15875
  try {
15688
- const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
15876
+ const content = fs12.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
15689
15877
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
15690
15878
  lines.push("```javascript");
15691
15879
  lines.push(content);
@@ -15694,14 +15882,14 @@ var DevServer = class _DevServer {
15694
15882
  } catch {
15695
15883
  }
15696
15884
  }
15697
- const refFiles = fs11.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
15885
+ const refFiles = fs12.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
15698
15886
  if (refFiles.length > 0) {
15699
15887
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
15700
15888
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
15701
15889
  lines.push("");
15702
15890
  for (const file of refFiles) {
15703
15891
  try {
15704
- const content = fs11.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
15892
+ const content = fs12.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
15705
15893
  lines.push(`### \`${file}\` \u{1F512}`);
15706
15894
  lines.push("```javascript");
15707
15895
  lines.push(content);
@@ -15734,11 +15922,11 @@ var DevServer = class _DevServer {
15734
15922
  lines.push("");
15735
15923
  }
15736
15924
  }
15737
- const docsDir = path14.join(providerDir, "../../docs");
15925
+ const docsDir = path15.join(providerDir, "../../docs");
15738
15926
  const loadGuide = (name) => {
15739
15927
  try {
15740
- const p = path14.join(docsDir, name);
15741
- if (fs11.existsSync(p)) return fs11.readFileSync(p, "utf-8");
15928
+ const p = path15.join(docsDir, name);
15929
+ if (fs12.existsSync(p)) return fs12.readFileSync(p, "utf-8");
15742
15930
  } catch {
15743
15931
  }
15744
15932
  return null;
@@ -16358,7 +16546,7 @@ async function listHostedCliRuntimes(endpoint) {
16358
16546
  }
16359
16547
 
16360
16548
  // src/installer.ts
16361
- var import_child_process8 = require("child_process");
16549
+ var import_child_process10 = require("child_process");
16362
16550
  var EXTENSION_CATALOG = [
16363
16551
  // AI Agent extensions
16364
16552
  {
@@ -16435,7 +16623,7 @@ var EXTENSION_CATALOG = [
16435
16623
  function isExtensionInstalled(ide, marketplaceId) {
16436
16624
  if (!ide.cliCommand) return false;
16437
16625
  try {
16438
- const result = (0, import_child_process8.execSync)(`"${ide.cliCommand}" --list-extensions`, {
16626
+ const result = (0, import_child_process10.execSync)(`"${ide.cliCommand}" --list-extensions`, {
16439
16627
  encoding: "utf-8",
16440
16628
  timeout: 15e3,
16441
16629
  stdio: ["pipe", "pipe", "pipe"]
@@ -16472,11 +16660,11 @@ async function installExtension(ide, extension) {
16472
16660
  const res = await fetch(extension.vsixUrl);
16473
16661
  if (res.ok) {
16474
16662
  const buffer = Buffer.from(await res.arrayBuffer());
16475
- const fs12 = await import("fs");
16476
- fs12.writeFileSync(vsixPath, buffer);
16663
+ const fs13 = await import("fs");
16664
+ fs13.writeFileSync(vsixPath, buffer);
16477
16665
  return new Promise((resolve9) => {
16478
16666
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
16479
- (0, import_child_process8.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
16667
+ (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
16480
16668
  resolve9({
16481
16669
  extensionId: extension.id,
16482
16670
  marketplaceId: extension.marketplaceId,
@@ -16492,7 +16680,7 @@ async function installExtension(ide, extension) {
16492
16680
  }
16493
16681
  return new Promise((resolve9) => {
16494
16682
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
16495
- (0, import_child_process8.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
16683
+ (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
16496
16684
  if (error) {
16497
16685
  resolve9({
16498
16686
  extensionId: extension.id,
@@ -16529,7 +16717,7 @@ function launchIDE(ide, workspacePath) {
16529
16717
  if (!ide.cliCommand) return false;
16530
16718
  try {
16531
16719
  const args = workspacePath ? `"${workspacePath}"` : "";
16532
- (0, import_child_process8.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
16720
+ (0, import_child_process10.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
16533
16721
  return true;
16534
16722
  } catch {
16535
16723
  return false;
@@ -16841,6 +17029,7 @@ async function shutdownDaemonComponents(components) {
16841
17029
  loadConfig,
16842
17030
  logCommand,
16843
17031
  markSetupComplete,
17032
+ maybeRunDaemonUpgradeHelperFromEnv,
16844
17033
  normalizeActiveChatData,
16845
17034
  normalizeManagedStatus,
16846
17035
  probeCdpPort,