adhdev 0.8.40 → 0.8.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -41438,6 +41438,7 @@ var init_server_connection = __esm({
41438
41438
  userPlan = "free";
41439
41439
  iceServers = null;
41440
41440
  planLimits = null;
41441
+ compatBlocked = false;
41441
41442
  constructor(options) {
41442
41443
  this.options = options;
41443
41444
  }
@@ -41548,6 +41549,7 @@ var init_server_connection = __esm({
41548
41549
  const message = JSON.parse(text);
41549
41550
  if (message.type === "auth_ok") {
41550
41551
  this.reconnectAttempts = 0;
41552
+ this.compatBlocked = false;
41551
41553
  const payload = message.payload;
41552
41554
  this.userPlan = payload.plan || "free";
41553
41555
  this.iceServers = payload.iceServers || null;
@@ -41570,6 +41572,7 @@ var init_server_connection = __esm({
41570
41572
  LOG.info("Server", ` Run: adhdev daemon:upgrade
41571
41573
  `);
41572
41574
  } else if (message.type === "force_update_required") {
41575
+ this.compatBlocked = true;
41573
41576
  const p = message.payload;
41574
41577
  LOG.error("Server", `
41575
41578
  \u26D4 Daemon v${this.options.daemonVersion} is no longer compatible.`);
@@ -41616,6 +41619,11 @@ var init_server_connection = __esm({
41616
41619
  }
41617
41620
  return;
41618
41621
  }
41622
+ if (code === 4020 || this.compatBlocked) {
41623
+ LOG.info("Server", `[ServerConn] \u26A0 Version compatibility blocked. Waiting for daemon update.`);
41624
+ this.setState("disconnected");
41625
+ return;
41626
+ }
41619
41627
  if (code !== 1e3) {
41620
41628
  this.setState("disconnected");
41621
41629
  this.scheduleReconnect();
@@ -50067,13 +50075,13 @@ var init_adhdev_daemon = __esm({
50067
50075
  import_ws3 = require("ws");
50068
50076
  import_chalk2 = __toESM(require("chalk"));
50069
50077
  init_version();
50070
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.40" });
50078
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.42" });
50071
50079
  ACTIVE_CHAT_POLL_STATUSES = /* @__PURE__ */ new Set([
50072
50080
  "generating",
50073
50081
  "waiting_approval",
50074
50082
  "starting"
50075
50083
  ]);
50076
- AdhdevDaemon = class {
50084
+ AdhdevDaemon = class _AdhdevDaemon {
50077
50085
  localHttpServer = null;
50078
50086
  localWss = null;
50079
50087
  localClients = /* @__PURE__ */ new Set();
@@ -50092,6 +50100,15 @@ var init_adhdev_daemon = __esm({
50092
50100
  running = false;
50093
50101
  localPort;
50094
50102
  ideType = "unknown";
50103
+ pendingMandatoryUpdate = null;
50104
+ mandatoryUpgradeInFlight = false;
50105
+ static MANDATORY_UPDATE_BLOCKED_COMMANDS = /* @__PURE__ */ new Set([
50106
+ "launch_ide",
50107
+ "launch_cli",
50108
+ "restart_ide",
50109
+ "restart_session",
50110
+ "session_host_restart_session"
50111
+ ]);
50095
50112
  constructor() {
50096
50113
  this.localPort = 19222;
50097
50114
  }
@@ -50109,6 +50126,61 @@ var init_adhdev_daemon = __esm({
50109
50126
  const mode = this.getCliPresentationMode(sessionId);
50110
50127
  return mode === "chat" || mode === "terminal";
50111
50128
  }
50129
+ getUpgradePackageName() {
50130
+ return process.argv[1]?.includes("daemon-standalone") ? "@adhdev/daemon-standalone" : "adhdev";
50131
+ }
50132
+ hasBlockingSessionsForMandatoryUpdate() {
50133
+ if (!this.components) return false;
50134
+ const blocking = /* @__PURE__ */ new Set(["generating", "waiting_approval", "starting"]);
50135
+ const states = this.components.instanceManager.collectAllStates();
50136
+ for (const state of states) {
50137
+ if (blocking.has(String(state.status || ""))) return true;
50138
+ const childStates = "extensions" in state && Array.isArray(state.extensions) ? state.extensions : [];
50139
+ if (childStates.length > 0) {
50140
+ for (const child of childStates) {
50141
+ if (blocking.has(String(child.status || ""))) return true;
50142
+ }
50143
+ }
50144
+ }
50145
+ return false;
50146
+ }
50147
+ async maybeApplyMandatoryUpdate(trigger) {
50148
+ const pending = this.pendingMandatoryUpdate;
50149
+ if (!pending || this.mandatoryUpgradeInFlight) return;
50150
+ if (this.hasBlockingSessionsForMandatoryUpdate()) {
50151
+ LOG.warn("Upgrade", `Mandatory update deferred (${trigger}) \u2014 active work in progress`);
50152
+ return;
50153
+ }
50154
+ const pkgName = this.getUpgradePackageName();
50155
+ this.mandatoryUpgradeInFlight = true;
50156
+ try {
50157
+ const { execSync: execSync8 } = await import("child_process");
50158
+ const published = execSync8(`npm view ${pkgName}@${pending.targetVersion} version`, {
50159
+ encoding: "utf-8",
50160
+ timeout: 1e4,
50161
+ stdio: ["pipe", "pipe", "pipe"]
50162
+ }).trim();
50163
+ if (published !== pending.targetVersion) {
50164
+ throw new Error(`Published version mismatch: expected ${pending.targetVersion}, got ${published || "unknown"}`);
50165
+ }
50166
+ LOG.warn("Upgrade", `Applying mandatory daemon update (${pending.reason}) \u2192 v${pending.targetVersion}`);
50167
+ spawnDetachedDaemonUpgradeHelper({
50168
+ packageName: pkgName,
50169
+ targetVersion: pending.targetVersion,
50170
+ parentPid: process.pid,
50171
+ restartArgv: process.argv.slice(1),
50172
+ cwd: process.cwd(),
50173
+ sessionHostAppName: process.env.ADHDEV_SESSION_HOST_NAME || "adhdev"
50174
+ });
50175
+ setTimeout(() => {
50176
+ LOG.warn("Upgrade", "Exiting daemon so mandatory detached upgrader can continue...");
50177
+ process.exit(0);
50178
+ }, 1500);
50179
+ } catch (error48) {
50180
+ this.mandatoryUpgradeInFlight = false;
50181
+ LOG.error("Upgrade", `Mandatory auto-update failed: ${error48?.message || String(error48)}`);
50182
+ }
50183
+ }
50112
50184
  async buildChatTailUpdateForSubscription(subscription) {
50113
50185
  const result = await this.components.router.execute("read_chat", {
50114
50186
  targetSessionId: subscription.params.targetSessionId,
@@ -50549,6 +50621,8 @@ ${err?.stack || ""}`);
50549
50621
  }
50550
50622
  this.registerServerHandlers();
50551
50623
  this.serverConn.on("auth_ok", (msg) => {
50624
+ this.pendingMandatoryUpdate = null;
50625
+ this.mandatoryUpgradeInFlight = false;
50552
50626
  const serverNickname = msg.payload?.machineNickname;
50553
50627
  if (serverNickname === void 0) return;
50554
50628
  const nextNickname = typeof serverNickname === "string" && serverNickname.trim() ? serverNickname.trim() : null;
@@ -50559,6 +50633,16 @@ ${err?.stack || ""}`);
50559
50633
  LOG.info("Server", `[ServerConn] Synced machine nickname from server: ${nextNickname || "(cleared)"}`);
50560
50634
  this.statusReporter?.throttledReport();
50561
50635
  });
50636
+ this.serverConn.on("force_update_required", (msg) => {
50637
+ const payload = msg.payload;
50638
+ this.pendingMandatoryUpdate = {
50639
+ targetVersion: typeof payload.latest === "string" && payload.latest.trim() ? payload.latest.trim() : pkgVersion,
50640
+ reason: typeof payload.reason === "string" && payload.reason.trim() ? payload.reason.trim() : "major_minor_mismatch",
50641
+ minVersion: typeof payload.minVersion === "string" && payload.minVersion.trim() ? payload.minVersion.trim() : void 0
50642
+ };
50643
+ LOG.warn("Upgrade", `Mandatory daemon update required (${this.pendingMandatoryUpdate.reason})`);
50644
+ void this.maybeApplyMandatoryUpdate("server-force-update");
50645
+ });
50562
50646
  this.serverConn.onStateChange((state) => {
50563
50647
  if (state === "connected") {
50564
50648
  console.log(import_chalk2.default.green(" \u{1F4E1} Connected to ADHDev server"));
@@ -50582,6 +50666,7 @@ ${err?.stack || ""}`);
50582
50666
  this.statusReporter.startReporting();
50583
50667
  this.components.instanceManager.onEvent((event) => {
50584
50668
  this.statusReporter?.emitStatusEvent(event);
50669
+ void this.maybeApplyMandatoryUpdate(`instance-event:${event.event}`);
50585
50670
  });
50586
50671
  this.running = true;
50587
50672
  process.on("SIGINT", () => this.stop());
@@ -50650,6 +50735,16 @@ ${err?.stack || ""}`);
50650
50735
  const cmdStart = Date.now();
50651
50736
  const source = msg.ipcWs ? "ext" : typeof msg.source === "string" && msg.source.trim() ? msg.source : "ws";
50652
50737
  try {
50738
+ if (this.pendingMandatoryUpdate && _AdhdevDaemon.MANDATORY_UPDATE_BLOCKED_COMMANDS.has(cmd)) {
50739
+ this.sendResult(msg, false, {
50740
+ error: "A mandatory daemon update is pending. Finish current work and let the daemon update before starting a new session.",
50741
+ code: "DAEMON_UPDATE_REQUIRED",
50742
+ required: true,
50743
+ latest: this.pendingMandatoryUpdate.targetVersion,
50744
+ reason: this.pendingMandatoryUpdate.reason
50745
+ });
50746
+ return;
50747
+ }
50653
50748
  if (source === "api" && !loadConfig().allowServerApiProxy) {
50654
50749
  this.sendResult(msg, false, {
50655
50750
  error: "Server API relay is disabled on this daemon. Enable it explicitly with `adhdev daemon:api enable`.",