adhdev 0.8.40 → 0.8.41

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
@@ -40941,6 +40941,7 @@ var init_server_connection = __esm({
40941
40941
  userPlan = "free";
40942
40942
  iceServers = null;
40943
40943
  planLimits = null;
40944
+ compatBlocked = false;
40944
40945
  constructor(options) {
40945
40946
  this.options = options;
40946
40947
  }
@@ -41051,6 +41052,7 @@ var init_server_connection = __esm({
41051
41052
  const message = JSON.parse(text);
41052
41053
  if (message.type === "auth_ok") {
41053
41054
  this.reconnectAttempts = 0;
41055
+ this.compatBlocked = false;
41054
41056
  const payload = message.payload;
41055
41057
  this.userPlan = payload.plan || "free";
41056
41058
  this.iceServers = payload.iceServers || null;
@@ -41073,6 +41075,7 @@ var init_server_connection = __esm({
41073
41075
  LOG.info("Server", ` Run: adhdev daemon:upgrade
41074
41076
  `);
41075
41077
  } else if (message.type === "force_update_required") {
41078
+ this.compatBlocked = true;
41076
41079
  const p = message.payload;
41077
41080
  LOG.error("Server", `
41078
41081
  \u26D4 Daemon v${this.options.daemonVersion} is no longer compatible.`);
@@ -41119,6 +41122,11 @@ var init_server_connection = __esm({
41119
41122
  }
41120
41123
  return;
41121
41124
  }
41125
+ if (code === 4020 || this.compatBlocked) {
41126
+ LOG.info("Server", `[ServerConn] \u26A0 Version compatibility blocked. Waiting for daemon update.`);
41127
+ this.setState("disconnected");
41128
+ return;
41129
+ }
41122
41130
  if (code !== 1e3) {
41123
41131
  this.setState("disconnected");
41124
41132
  this.scheduleReconnect();
@@ -49518,13 +49526,13 @@ var init_adhdev_daemon = __esm({
49518
49526
  import_ws3 = require("ws");
49519
49527
  import_chalk2 = __toESM(require("chalk"));
49520
49528
  init_version();
49521
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.40" });
49529
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.41" });
49522
49530
  ACTIVE_CHAT_POLL_STATUSES = /* @__PURE__ */ new Set([
49523
49531
  "generating",
49524
49532
  "waiting_approval",
49525
49533
  "starting"
49526
49534
  ]);
49527
- AdhdevDaemon = class {
49535
+ AdhdevDaemon = class _AdhdevDaemon {
49528
49536
  localHttpServer = null;
49529
49537
  localWss = null;
49530
49538
  localClients = /* @__PURE__ */ new Set();
@@ -49543,6 +49551,15 @@ var init_adhdev_daemon = __esm({
49543
49551
  running = false;
49544
49552
  localPort;
49545
49553
  ideType = "unknown";
49554
+ pendingMandatoryUpdate = null;
49555
+ mandatoryUpgradeInFlight = false;
49556
+ static MANDATORY_UPDATE_BLOCKED_COMMANDS = /* @__PURE__ */ new Set([
49557
+ "launch_ide",
49558
+ "launch_cli",
49559
+ "restart_ide",
49560
+ "restart_session",
49561
+ "session_host_restart_session"
49562
+ ]);
49546
49563
  constructor() {
49547
49564
  this.localPort = 19222;
49548
49565
  }
@@ -49560,6 +49577,61 @@ var init_adhdev_daemon = __esm({
49560
49577
  const mode = this.getCliPresentationMode(sessionId);
49561
49578
  return mode === "chat" || mode === "terminal";
49562
49579
  }
49580
+ getUpgradePackageName() {
49581
+ return process.argv[1]?.includes("daemon-standalone") ? "@adhdev/daemon-standalone" : "adhdev";
49582
+ }
49583
+ hasBlockingSessionsForMandatoryUpdate() {
49584
+ if (!this.components) return false;
49585
+ const blocking = /* @__PURE__ */ new Set(["generating", "waiting_approval", "starting"]);
49586
+ const states = this.components.instanceManager.collectAllStates();
49587
+ for (const state of states) {
49588
+ if (blocking.has(String(state.status || ""))) return true;
49589
+ const childStates = "extensions" in state && Array.isArray(state.extensions) ? state.extensions : [];
49590
+ if (childStates.length > 0) {
49591
+ for (const child of childStates) {
49592
+ if (blocking.has(String(child.status || ""))) return true;
49593
+ }
49594
+ }
49595
+ }
49596
+ return false;
49597
+ }
49598
+ async maybeApplyMandatoryUpdate(trigger) {
49599
+ const pending = this.pendingMandatoryUpdate;
49600
+ if (!pending || this.mandatoryUpgradeInFlight) return;
49601
+ if (this.hasBlockingSessionsForMandatoryUpdate()) {
49602
+ LOG.warn("Upgrade", `Mandatory update deferred (${trigger}) \u2014 active work in progress`);
49603
+ return;
49604
+ }
49605
+ const pkgName = this.getUpgradePackageName();
49606
+ this.mandatoryUpgradeInFlight = true;
49607
+ try {
49608
+ const { execSync: execSync7 } = await import("child_process");
49609
+ const published = execSync7(`npm view ${pkgName}@${pending.targetVersion} version`, {
49610
+ encoding: "utf-8",
49611
+ timeout: 1e4,
49612
+ stdio: ["pipe", "pipe", "pipe"]
49613
+ }).trim();
49614
+ if (published !== pending.targetVersion) {
49615
+ throw new Error(`Published version mismatch: expected ${pending.targetVersion}, got ${published || "unknown"}`);
49616
+ }
49617
+ LOG.warn("Upgrade", `Applying mandatory daemon update (${pending.reason}) \u2192 v${pending.targetVersion}`);
49618
+ spawnDetachedDaemonUpgradeHelper({
49619
+ packageName: pkgName,
49620
+ targetVersion: pending.targetVersion,
49621
+ parentPid: process.pid,
49622
+ restartArgv: process.argv.slice(1),
49623
+ cwd: process.cwd(),
49624
+ sessionHostAppName: process.env.ADHDEV_SESSION_HOST_NAME || "adhdev"
49625
+ });
49626
+ setTimeout(() => {
49627
+ LOG.warn("Upgrade", "Exiting daemon so mandatory detached upgrader can continue...");
49628
+ process.exit(0);
49629
+ }, 1500);
49630
+ } catch (error48) {
49631
+ this.mandatoryUpgradeInFlight = false;
49632
+ LOG.error("Upgrade", `Mandatory auto-update failed: ${error48?.message || String(error48)}`);
49633
+ }
49634
+ }
49563
49635
  async buildChatTailUpdateForSubscription(subscription) {
49564
49636
  const result = await this.components.router.execute("read_chat", {
49565
49637
  targetSessionId: subscription.params.targetSessionId,
@@ -50000,6 +50072,8 @@ ${err?.stack || ""}`);
50000
50072
  }
50001
50073
  this.registerServerHandlers();
50002
50074
  this.serverConn.on("auth_ok", (msg) => {
50075
+ this.pendingMandatoryUpdate = null;
50076
+ this.mandatoryUpgradeInFlight = false;
50003
50077
  const serverNickname = msg.payload?.machineNickname;
50004
50078
  if (serverNickname === void 0) return;
50005
50079
  const nextNickname = typeof serverNickname === "string" && serverNickname.trim() ? serverNickname.trim() : null;
@@ -50010,6 +50084,16 @@ ${err?.stack || ""}`);
50010
50084
  LOG.info("Server", `[ServerConn] Synced machine nickname from server: ${nextNickname || "(cleared)"}`);
50011
50085
  this.statusReporter?.throttledReport();
50012
50086
  });
50087
+ this.serverConn.on("force_update_required", (msg) => {
50088
+ const payload = msg.payload;
50089
+ this.pendingMandatoryUpdate = {
50090
+ targetVersion: typeof payload.latest === "string" && payload.latest.trim() ? payload.latest.trim() : pkgVersion,
50091
+ reason: typeof payload.reason === "string" && payload.reason.trim() ? payload.reason.trim() : "major_minor_mismatch",
50092
+ minVersion: typeof payload.minVersion === "string" && payload.minVersion.trim() ? payload.minVersion.trim() : void 0
50093
+ };
50094
+ LOG.warn("Upgrade", `Mandatory daemon update required (${this.pendingMandatoryUpdate.reason})`);
50095
+ void this.maybeApplyMandatoryUpdate("server-force-update");
50096
+ });
50013
50097
  this.serverConn.onStateChange((state) => {
50014
50098
  if (state === "connected") {
50015
50099
  console.log(import_chalk2.default.green(" \u{1F4E1} Connected to ADHDev server"));
@@ -50033,6 +50117,7 @@ ${err?.stack || ""}`);
50033
50117
  this.statusReporter.startReporting();
50034
50118
  this.components.instanceManager.onEvent((event) => {
50035
50119
  this.statusReporter?.emitStatusEvent(event);
50120
+ void this.maybeApplyMandatoryUpdate(`instance-event:${event.event}`);
50036
50121
  });
50037
50122
  this.running = true;
50038
50123
  process.on("SIGINT", () => this.stop());
@@ -50101,6 +50186,16 @@ ${err?.stack || ""}`);
50101
50186
  const cmdStart = Date.now();
50102
50187
  const source = msg.ipcWs ? "ext" : typeof msg.source === "string" && msg.source.trim() ? msg.source : "ws";
50103
50188
  try {
50189
+ if (this.pendingMandatoryUpdate && _AdhdevDaemon.MANDATORY_UPDATE_BLOCKED_COMMANDS.has(cmd)) {
50190
+ this.sendResult(msg, false, {
50191
+ error: "A mandatory daemon update is pending. Finish current work and let the daemon update before starting a new session.",
50192
+ code: "DAEMON_UPDATE_REQUIRED",
50193
+ required: true,
50194
+ latest: this.pendingMandatoryUpdate.targetVersion,
50195
+ reason: this.pendingMandatoryUpdate.reason
50196
+ });
50197
+ return;
50198
+ }
50104
50199
  if (source === "api" && !loadConfig().allowServerApiProxy) {
50105
50200
  this.sendResult(msg, false, {
50106
50201
  error: "Server API relay is disabled on this daemon. Enable it explicitly with `adhdev daemon:api enable`.",