adhdev 0.8.39 → 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/cli/index.js CHANGED
@@ -2856,7 +2856,7 @@ var init_chat_history = __esm({
2856
2856
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
2857
2857
  fs3.appendFileSync(filePath, lines, "utf-8");
2858
2858
  const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
2859
- if (messages.length < prevCount * 0.5 && prevCount > 3) {
2859
+ if (!historySessionId && messages.length < prevCount * 0.5 && prevCount > 3) {
2860
2860
  seenHashes.clear();
2861
2861
  this.lastSeenSignatures.delete(dedupKey);
2862
2862
  this.lastSeenTurnSignatures.delete(dedupKey);
@@ -5389,16 +5389,7 @@ async function handleSendChat(h, args) {
5389
5389
  const provider = h.getProvider(args?.agentType);
5390
5390
  const transport = getTargetTransport(h, provider);
5391
5391
  const dedupeKey = buildRecentSendKey(h, args, provider, text);
5392
- const historySessionId = getHistorySessionId(h, args);
5393
5392
  const _logSendSuccess = (method, targetAgent) => {
5394
- h.historyWriter.appendNewMessages(
5395
- targetAgent || provider?.type || getCurrentProviderType(h, "unknown_agent"),
5396
- [{ role: "user", content: text, receivedAt: Date.now() }],
5397
- void 0,
5398
- // title
5399
- args?.targetSessionId,
5400
- historySessionId
5401
- );
5402
5393
  return { success: true, sent: true, method, targetAgent };
5403
5394
  };
5404
5395
  if (isRecentDuplicateSend(dedupeKey)) {
@@ -41447,6 +41438,7 @@ var init_server_connection = __esm({
41447
41438
  userPlan = "free";
41448
41439
  iceServers = null;
41449
41440
  planLimits = null;
41441
+ compatBlocked = false;
41450
41442
  constructor(options) {
41451
41443
  this.options = options;
41452
41444
  }
@@ -41557,6 +41549,7 @@ var init_server_connection = __esm({
41557
41549
  const message = JSON.parse(text);
41558
41550
  if (message.type === "auth_ok") {
41559
41551
  this.reconnectAttempts = 0;
41552
+ this.compatBlocked = false;
41560
41553
  const payload = message.payload;
41561
41554
  this.userPlan = payload.plan || "free";
41562
41555
  this.iceServers = payload.iceServers || null;
@@ -41579,6 +41572,7 @@ var init_server_connection = __esm({
41579
41572
  LOG.info("Server", ` Run: adhdev daemon:upgrade
41580
41573
  `);
41581
41574
  } else if (message.type === "force_update_required") {
41575
+ this.compatBlocked = true;
41582
41576
  const p = message.payload;
41583
41577
  LOG.error("Server", `
41584
41578
  \u26D4 Daemon v${this.options.daemonVersion} is no longer compatible.`);
@@ -41625,6 +41619,11 @@ var init_server_connection = __esm({
41625
41619
  }
41626
41620
  return;
41627
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
+ }
41628
41627
  if (code !== 1e3) {
41629
41628
  this.setState("disconnected");
41630
41629
  this.scheduleReconnect();
@@ -50076,13 +50075,13 @@ var init_adhdev_daemon = __esm({
50076
50075
  import_ws3 = require("ws");
50077
50076
  import_chalk2 = __toESM(require("chalk"));
50078
50077
  init_version();
50079
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.39" });
50078
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.41" });
50080
50079
  ACTIVE_CHAT_POLL_STATUSES = /* @__PURE__ */ new Set([
50081
50080
  "generating",
50082
50081
  "waiting_approval",
50083
50082
  "starting"
50084
50083
  ]);
50085
- AdhdevDaemon = class {
50084
+ AdhdevDaemon = class _AdhdevDaemon {
50086
50085
  localHttpServer = null;
50087
50086
  localWss = null;
50088
50087
  localClients = /* @__PURE__ */ new Set();
@@ -50101,6 +50100,15 @@ var init_adhdev_daemon = __esm({
50101
50100
  running = false;
50102
50101
  localPort;
50103
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
+ ]);
50104
50112
  constructor() {
50105
50113
  this.localPort = 19222;
50106
50114
  }
@@ -50118,6 +50126,61 @@ var init_adhdev_daemon = __esm({
50118
50126
  const mode = this.getCliPresentationMode(sessionId);
50119
50127
  return mode === "chat" || mode === "terminal";
50120
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
+ }
50121
50184
  async buildChatTailUpdateForSubscription(subscription) {
50122
50185
  const result = await this.components.router.execute("read_chat", {
50123
50186
  targetSessionId: subscription.params.targetSessionId,
@@ -50558,6 +50621,8 @@ ${err?.stack || ""}`);
50558
50621
  }
50559
50622
  this.registerServerHandlers();
50560
50623
  this.serverConn.on("auth_ok", (msg) => {
50624
+ this.pendingMandatoryUpdate = null;
50625
+ this.mandatoryUpgradeInFlight = false;
50561
50626
  const serverNickname = msg.payload?.machineNickname;
50562
50627
  if (serverNickname === void 0) return;
50563
50628
  const nextNickname = typeof serverNickname === "string" && serverNickname.trim() ? serverNickname.trim() : null;
@@ -50568,6 +50633,16 @@ ${err?.stack || ""}`);
50568
50633
  LOG.info("Server", `[ServerConn] Synced machine nickname from server: ${nextNickname || "(cleared)"}`);
50569
50634
  this.statusReporter?.throttledReport();
50570
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
+ });
50571
50646
  this.serverConn.onStateChange((state) => {
50572
50647
  if (state === "connected") {
50573
50648
  console.log(import_chalk2.default.green(" \u{1F4E1} Connected to ADHDev server"));
@@ -50591,6 +50666,7 @@ ${err?.stack || ""}`);
50591
50666
  this.statusReporter.startReporting();
50592
50667
  this.components.instanceManager.onEvent((event) => {
50593
50668
  this.statusReporter?.emitStatusEvent(event);
50669
+ void this.maybeApplyMandatoryUpdate(`instance-event:${event.event}`);
50594
50670
  });
50595
50671
  this.running = true;
50596
50672
  process.on("SIGINT", () => this.stop());
@@ -50659,6 +50735,16 @@ ${err?.stack || ""}`);
50659
50735
  const cmdStart = Date.now();
50660
50736
  const source = msg.ipcWs ? "ext" : typeof msg.source === "string" && msg.source.trim() ? msg.source : "ws";
50661
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
+ }
50662
50748
  if (source === "api" && !loadConfig().allowServerApiProxy) {
50663
50749
  this.sendResult(msg, false, {
50664
50750
  error: "Server API relay is disabled on this daemon. Enable it explicitly with `adhdev daemon:api enable`.",