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/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)) {
@@ -40950,6 +40941,7 @@ var init_server_connection = __esm({
40950
40941
  userPlan = "free";
40951
40942
  iceServers = null;
40952
40943
  planLimits = null;
40944
+ compatBlocked = false;
40953
40945
  constructor(options) {
40954
40946
  this.options = options;
40955
40947
  }
@@ -41060,6 +41052,7 @@ var init_server_connection = __esm({
41060
41052
  const message = JSON.parse(text);
41061
41053
  if (message.type === "auth_ok") {
41062
41054
  this.reconnectAttempts = 0;
41055
+ this.compatBlocked = false;
41063
41056
  const payload = message.payload;
41064
41057
  this.userPlan = payload.plan || "free";
41065
41058
  this.iceServers = payload.iceServers || null;
@@ -41082,6 +41075,7 @@ var init_server_connection = __esm({
41082
41075
  LOG.info("Server", ` Run: adhdev daemon:upgrade
41083
41076
  `);
41084
41077
  } else if (message.type === "force_update_required") {
41078
+ this.compatBlocked = true;
41085
41079
  const p = message.payload;
41086
41080
  LOG.error("Server", `
41087
41081
  \u26D4 Daemon v${this.options.daemonVersion} is no longer compatible.`);
@@ -41128,6 +41122,11 @@ var init_server_connection = __esm({
41128
41122
  }
41129
41123
  return;
41130
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
+ }
41131
41130
  if (code !== 1e3) {
41132
41131
  this.setState("disconnected");
41133
41132
  this.scheduleReconnect();
@@ -49527,13 +49526,13 @@ var init_adhdev_daemon = __esm({
49527
49526
  import_ws3 = require("ws");
49528
49527
  import_chalk2 = __toESM(require("chalk"));
49529
49528
  init_version();
49530
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.39" });
49529
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.41" });
49531
49530
  ACTIVE_CHAT_POLL_STATUSES = /* @__PURE__ */ new Set([
49532
49531
  "generating",
49533
49532
  "waiting_approval",
49534
49533
  "starting"
49535
49534
  ]);
49536
- AdhdevDaemon = class {
49535
+ AdhdevDaemon = class _AdhdevDaemon {
49537
49536
  localHttpServer = null;
49538
49537
  localWss = null;
49539
49538
  localClients = /* @__PURE__ */ new Set();
@@ -49552,6 +49551,15 @@ var init_adhdev_daemon = __esm({
49552
49551
  running = false;
49553
49552
  localPort;
49554
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
+ ]);
49555
49563
  constructor() {
49556
49564
  this.localPort = 19222;
49557
49565
  }
@@ -49569,6 +49577,61 @@ var init_adhdev_daemon = __esm({
49569
49577
  const mode = this.getCliPresentationMode(sessionId);
49570
49578
  return mode === "chat" || mode === "terminal";
49571
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
+ }
49572
49635
  async buildChatTailUpdateForSubscription(subscription) {
49573
49636
  const result = await this.components.router.execute("read_chat", {
49574
49637
  targetSessionId: subscription.params.targetSessionId,
@@ -50009,6 +50072,8 @@ ${err?.stack || ""}`);
50009
50072
  }
50010
50073
  this.registerServerHandlers();
50011
50074
  this.serverConn.on("auth_ok", (msg) => {
50075
+ this.pendingMandatoryUpdate = null;
50076
+ this.mandatoryUpgradeInFlight = false;
50012
50077
  const serverNickname = msg.payload?.machineNickname;
50013
50078
  if (serverNickname === void 0) return;
50014
50079
  const nextNickname = typeof serverNickname === "string" && serverNickname.trim() ? serverNickname.trim() : null;
@@ -50019,6 +50084,16 @@ ${err?.stack || ""}`);
50019
50084
  LOG.info("Server", `[ServerConn] Synced machine nickname from server: ${nextNickname || "(cleared)"}`);
50020
50085
  this.statusReporter?.throttledReport();
50021
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
+ });
50022
50097
  this.serverConn.onStateChange((state) => {
50023
50098
  if (state === "connected") {
50024
50099
  console.log(import_chalk2.default.green(" \u{1F4E1} Connected to ADHDev server"));
@@ -50042,6 +50117,7 @@ ${err?.stack || ""}`);
50042
50117
  this.statusReporter.startReporting();
50043
50118
  this.components.instanceManager.onEvent((event) => {
50044
50119
  this.statusReporter?.emitStatusEvent(event);
50120
+ void this.maybeApplyMandatoryUpdate(`instance-event:${event.event}`);
50045
50121
  });
50046
50122
  this.running = true;
50047
50123
  process.on("SIGINT", () => this.stop());
@@ -50110,6 +50186,16 @@ ${err?.stack || ""}`);
50110
50186
  const cmdStart = Date.now();
50111
50187
  const source = msg.ipcWs ? "ext" : typeof msg.source === "string" && msg.source.trim() ? msg.source : "ws";
50112
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
+ }
50113
50199
  if (source === "api" && !loadConfig().allowServerApiProxy) {
50114
50200
  this.sendResult(msg, false, {
50115
50201
  error: "Server API relay is disabled on this daemon. Enable it explicitly with `adhdev daemon:api enable`.",