@adhdev/daemon-core 0.9.82-rc.263 → 0.9.82-rc.265

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.mjs CHANGED
@@ -260,10 +260,10 @@ function readInjected(value) {
260
260
  }
261
261
  function getDaemonBuildInfo() {
262
262
  if (cached) return cached;
263
- const commit = readInjected(true ? "2cf602f99ce68b3d3f1af02b429f6fb7a7c8e686" : void 0) ?? "unknown";
264
- const commitShort = readInjected(true ? "2cf602f" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
265
- const version = readInjected(true ? "0.9.82-rc.263" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
266
- const builtAt = readInjected(true ? "2026-06-14T13:48:10.699Z" : void 0);
263
+ const commit = readInjected(true ? "b062e0b564f44876b742641cc25ad182a3e088b3" : void 0) ?? "unknown";
264
+ const commitShort = readInjected(true ? "b062e0b" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
265
+ const version = readInjected(true ? "0.9.82-rc.265" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
266
+ const builtAt = readInjected(true ? "2026-06-14T16:39:31.621Z" : void 0);
267
267
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
268
268
  return cached;
269
269
  }
@@ -334,6 +334,30 @@ async function getGitRepoStatus(workspace, options = {}) {
334
334
  );
335
335
  }
336
336
  }
337
+ async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
338
+ try {
339
+ const diff = await runGit(repoPath, ["diff", "--name-only", `${buildCommit}..HEAD`], options);
340
+ const files = diff.stdout.split("\n").map((line) => line.trim()).filter(Boolean);
341
+ if (files.length === 0) {
342
+ return { isDaemonAffecting: true, affectedPackages: [] };
343
+ }
344
+ const pkgs = /* @__PURE__ */ new Set();
345
+ let sawNonPackageOrUnknown = false;
346
+ for (const file of files) {
347
+ const match = file.match(/(?:^|\/)packages\/([^/]+)\//);
348
+ if (!match) {
349
+ sawNonPackageOrUnknown = true;
350
+ continue;
351
+ }
352
+ pkgs.add(match[1]);
353
+ }
354
+ const affectedPackages = [...pkgs].sort();
355
+ const allWebOnly = !sawNonPackageOrUnknown && affectedPackages.length > 0 && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
356
+ return { isDaemonAffecting: !allWebOnly, affectedPackages };
357
+ } catch {
358
+ return { isDaemonAffecting: true, affectedPackages: [] };
359
+ }
360
+ }
337
361
  async function detectDaemonBuildBehind(repo, submodules, options) {
338
362
  const build = options.daemonBuildInfo ?? getDaemonBuildInfo();
339
363
  if (!build.commit || build.commit === "unknown") return void 0;
@@ -350,12 +374,21 @@ async function detectDaemonBuildBehind(repo, submodules, options) {
350
374
  const head = headResult.stdout.trim();
351
375
  if (!head || head === build.commit) continue;
352
376
  await runGit(repoPath, ["merge-base", "--is-ancestor", build.commit, "HEAD"], options);
377
+ const { isDaemonAffecting, affectedPackages } = await classifyDaemonBuildChange(
378
+ repoPath,
379
+ build.commit,
380
+ options
381
+ );
382
+ const scopeLabel = scope === "root" ? "workspace" : scope;
383
+ const warning = isDaemonAffecting ? `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}. Merged code is NOT live until the daemon is rebuilt/redeployed and restarted \u2014 a local dist rebuild alone does not update a cloud daemon.` : `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}, but only web packages changed (${(affectedPackages || []).join(", ") || "web"}). Daemon restart NOT required \u2014 redeploy the web app to reflect the change.`;
353
384
  return {
354
385
  buildCommit: build.commit,
355
386
  buildCommitShort: build.commitShort,
356
387
  head,
357
388
  scope,
358
- warning: `Live daemon was built from ${build.commitShort} which is behind ${scope === "root" ? "workspace" : scope} HEAD ${head.slice(0, 7)}. Merged code is NOT live until the daemon is rebuilt/redeployed and restarted \u2014 a local dist rebuild alone does not update a cloud daemon.`
389
+ isDaemonAffecting,
390
+ ...affectedPackages && affectedPackages.length > 0 ? { affectedPackages } : {},
391
+ warning
359
392
  };
360
393
  } catch {
361
394
  continue;
@@ -575,11 +608,29 @@ function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
575
608
  }
576
609
  return submodules;
577
610
  }
611
+ var DAEMON_RUNTIME_PACKAGES, WEB_ONLY_PACKAGES;
578
612
  var init_git_status = __esm({
579
613
  "src/git/git-status.ts"() {
580
614
  "use strict";
581
615
  init_git_executor();
582
616
  init_build_info();
617
+ DAEMON_RUNTIME_PACKAGES = /* @__PURE__ */ new Set([
618
+ "daemon-core",
619
+ "daemon-standalone",
620
+ "session-host-core",
621
+ "session-host-daemon",
622
+ "terminal-mux-core",
623
+ "terminal-mux-control",
624
+ "terminal-mux-cli",
625
+ "ghostty-vt-node",
626
+ "mcp-server"
627
+ ]);
628
+ WEB_ONLY_PACKAGES = /* @__PURE__ */ new Set([
629
+ "web-core",
630
+ "web-standalone",
631
+ "web-devconsole",
632
+ "terminal-render-web"
633
+ ]);
583
634
  }
584
635
  });
585
636
 
@@ -43174,10 +43225,31 @@ ${hintLines.join("\n")}` : "",
43174
43225
  };
43175
43226
  }
43176
43227
  const cleanupStarted = Date.now();
43228
+ const refineSessionCleanupMode = this.normalizeMeshSessionCleanupMode(
43229
+ mesh?.policy?.sessionCleanupOnNodeRemove
43230
+ );
43231
+ let refineSessionIds;
43232
+ if (refineSessionCleanupMode !== "preserve" && this.deps.sessionHostControl) {
43233
+ try {
43234
+ const liveSessions = await this.deps.sessionHostControl.listSessions();
43235
+ const workspace = typeof node.workspace === "string" ? node.workspace : "";
43236
+ refineSessionIds = liveSessions.filter((record) => {
43237
+ const sid = typeof record?.sessionId === "string" ? record.sessionId : "";
43238
+ if (!sid) return false;
43239
+ if (readStringValue(record?.meta?.meshCoordinatorFor) === meshId) return false;
43240
+ const boundToNode = readStringValue(record?.meta?.meshNodeId) === nodeId;
43241
+ const matchedByWorkspace = !!workspace && record?.workspace === workspace;
43242
+ return boundToNode || matchedByWorkspace;
43243
+ }).map((record) => String(record.sessionId));
43244
+ } catch {
43245
+ refineSessionIds = void 0;
43246
+ }
43247
+ }
43177
43248
  const removeResult = await this.execute("remove_mesh_node", {
43178
43249
  meshId,
43179
43250
  nodeId,
43180
- sessionCleanupMode: "preserve",
43251
+ sessionCleanupMode: refineSessionCleanupMode,
43252
+ ...refineSessionIds && refineSessionIds.length > 0 ? { sessionIds: refineSessionIds } : {},
43181
43253
  inlineMesh: args?.inlineMesh
43182
43254
  });
43183
43255
  recordMeshRefineStage(refineStages, "cleanup", removeResult?.success === false ? "failed" : "passed", cleanupStarted, {
@@ -45247,6 +45319,23 @@ ${hintLines.join("\n")}` : "",
45247
45319
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
45248
45320
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
45249
45321
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
45322
+ const isDryRun = args?.dryRun !== false && args?.execute !== true;
45323
+ if (isDryRun) {
45324
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
45325
+ const mesh = meshRecord?.mesh;
45326
+ const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
45327
+ if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
45328
+ return {
45329
+ success: true,
45330
+ dryRun: true,
45331
+ nodeId,
45332
+ workspace: node.workspace,
45333
+ validationPlan: buildMeshRefineValidationPlan(mesh, node.workspace),
45334
+ mergeWillRun: false,
45335
+ cleanupWillRun: false,
45336
+ hint: "Dry-run only \u2014 no merge/push/cleanup performed. Re-invoke with execute:true to converge this node."
45337
+ };
45338
+ }
45250
45339
  return this.startMeshRefineJob(meshId, nodeId, args);
45251
45340
  }
45252
45341
  case "batch_refine_mesh_nodes": {
@@ -45268,9 +45357,17 @@ ${hintLines.join("\n")}` : "",
45268
45357
  const sessionCleanupMode = this.normalizeMeshSessionCleanupMode(
45269
45358
  args?.sessionCleanupMode ?? args?.session_cleanup_mode ?? mesh?.policy?.sessionCleanupOnNodeRemove
45270
45359
  );
45360
+ const explicitSessionIds = Array.isArray(args?.sessionIds) ? args.sessionIds.filter((v) => typeof v === "string" && v.trim().length > 0).map((v) => v.trim()) : void 0;
45271
45361
  let sessionCleanup;
45272
45362
  if (node && sessionCleanupMode !== "preserve") {
45273
- sessionCleanup = await this.cleanupMeshSessions({ meshId, nodeId, node, mode: sessionCleanupMode, source: "mesh_remove_node" });
45363
+ sessionCleanup = await this.cleanupMeshSessions({
45364
+ meshId,
45365
+ nodeId,
45366
+ node,
45367
+ mode: sessionCleanupMode,
45368
+ ...explicitSessionIds && explicitSessionIds.length > 0 ? { sessionIds: explicitSessionIds } : {},
45369
+ source: "mesh_remove_node"
45370
+ });
45274
45371
  if (sessionCleanup.success === false) return { success: false, removed: false, sessionCleanup };
45275
45372
  }
45276
45373
  let worktreeCleanup;