@adhdev/daemon-core 0.9.82-rc.381 → 0.9.82-rc.382

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
@@ -378,10 +378,10 @@ function readInjected(value) {
378
378
  }
379
379
  function getDaemonBuildInfo() {
380
380
  if (cached) return cached;
381
- const commit = readInjected(true ? "18afac213951f79c502feb6b25b7399fe4d709b3" : void 0) ?? "unknown";
382
- const commitShort = readInjected(true ? "18afac21" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
383
- const version = readInjected(true ? "0.9.82-rc.381" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
384
- const builtAt = readInjected(true ? "2026-06-25T11:44:40.598Z" : void 0);
381
+ const commit = readInjected(true ? "70741c4fe19c6f71bcef702e7e149d963d6fd916" : void 0) ?? "unknown";
382
+ const commitShort = readInjected(true ? "70741c4f" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
383
+ const version = readInjected(true ? "0.9.82-rc.382" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
384
+ const builtAt = readInjected(true ? "2026-06-25T13:31:28.133Z" : void 0);
385
385
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
386
386
  return cached;
387
387
  }
@@ -8574,6 +8574,109 @@ var init_mesh_active_work = __esm({
8574
8574
  }
8575
8575
  });
8576
8576
 
8577
+ // src/mesh/mesh-scheduling-runtime.ts
8578
+ var mesh_scheduling_runtime_exports = {};
8579
+ __export(mesh_scheduling_runtime_exports, {
8580
+ buildMeshSchedulingRuntime: () => buildMeshSchedulingRuntime
8581
+ });
8582
+ function isReadonly(task) {
8583
+ return task.taskMode === "live_debug_readonly";
8584
+ }
8585
+ function isAssigned(task) {
8586
+ return task.status === "assigned";
8587
+ }
8588
+ function buildMeshSchedulingRuntime(mesh, queue) {
8589
+ const strategy = normalizeMeshSchedulingStrategy(mesh?.policy?.schedulingStrategy);
8590
+ const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
8591
+ const maxReadonlyParallelTasks = Math.max(2, maxParallelTasks * 2);
8592
+ const assignedTasks = (Array.isArray(queue) ? queue : []).filter(isAssigned);
8593
+ const activeWriteAssigned = assignedTasks.filter((t) => !isReadonly(t)).length;
8594
+ const activeReadonlyAssigned = assignedTasks.filter(isReadonly).length;
8595
+ const globalWriteCapReached = activeWriteAssigned >= maxParallelTasks;
8596
+ const globalReadonlyCapReached = activeReadonlyAssigned >= maxReadonlyParallelTasks;
8597
+ const writeAssignedByNode = /* @__PURE__ */ new Map();
8598
+ const assignedByNode = /* @__PURE__ */ new Map();
8599
+ const providerCountByNode = /* @__PURE__ */ new Map();
8600
+ for (const task of assignedTasks) {
8601
+ const nodeId = typeof task.assignedNodeId === "string" ? task.assignedNodeId.trim() : "";
8602
+ if (!nodeId) continue;
8603
+ assignedByNode.set(nodeId, (assignedByNode.get(nodeId) ?? 0) + 1);
8604
+ if (!isReadonly(task)) {
8605
+ writeAssignedByNode.set(nodeId, (writeAssignedByNode.get(nodeId) ?? 0) + 1);
8606
+ }
8607
+ const provider = typeof task.assignedProviderType === "string" ? task.assignedProviderType : "";
8608
+ if (provider) {
8609
+ let byProvider = providerCountByNode.get(nodeId);
8610
+ if (!byProvider) {
8611
+ byProvider = /* @__PURE__ */ new Map();
8612
+ providerCountByNode.set(nodeId, byProvider);
8613
+ }
8614
+ byProvider.set(provider, (byProvider.get(provider) ?? 0) + 1);
8615
+ }
8616
+ }
8617
+ const nodes = [];
8618
+ for (const rawNode of Array.isArray(mesh?.nodes) ? mesh.nodes : []) {
8619
+ const nodeId = normalizeMeshNodeId(rawNode);
8620
+ if (!nodeId) continue;
8621
+ const policy = rawNode?.policy || void 0;
8622
+ const load4 = assignedByNode.get(nodeId) ?? 0;
8623
+ const schedulingPriority = resolveNodeSchedulingPriority(policy);
8624
+ const capReasons = [];
8625
+ if (globalWriteCapReached) capReasons.push("global_max_parallel_tasks_reached");
8626
+ if ((writeAssignedByNode.get(nodeId) ?? 0) > 0) capReasons.push("node_has_active_assignment");
8627
+ let providerRoles;
8628
+ const declaredRoles = Array.isArray(policy?.providerRoles) ? policy.providerRoles : [];
8629
+ if (declaredRoles.length) {
8630
+ const byProvider = providerCountByNode.get(nodeId);
8631
+ providerRoles = [];
8632
+ for (const role of declaredRoles) {
8633
+ if (!role || typeof role !== "object") continue;
8634
+ const providerType = typeof role.providerType === "string" ? role.providerType.trim() : "";
8635
+ if (!providerType) continue;
8636
+ const maxParallel = resolveProviderMaxParallel(policy, providerType);
8637
+ const activeAssigned = byProvider?.get(providerType) ?? 0;
8638
+ const capReached = maxParallel !== void 0 && activeAssigned >= maxParallel;
8639
+ providerRoles.push({
8640
+ providerType,
8641
+ ...maxParallel !== void 0 ? { maxParallel } : {},
8642
+ activeAssigned,
8643
+ capReached
8644
+ });
8645
+ if (capReached) capReasons.push(`max_provider_parallel_reached:${providerType}`);
8646
+ }
8647
+ if (!providerRoles.length) providerRoles = void 0;
8648
+ }
8649
+ const maxConcurrentSessions = Number(policy?.maxConcurrentSessions);
8650
+ const hasSessionCap = Number.isFinite(maxConcurrentSessions) && maxConcurrentSessions >= 0;
8651
+ nodes.push({
8652
+ nodeId,
8653
+ load: load4,
8654
+ schedulingPriority,
8655
+ ...hasSessionCap ? { maxConcurrentSessions: Math.floor(maxConcurrentSessions) } : {},
8656
+ ...providerRoles ? { providerRoles } : {},
8657
+ capReached: capReasons.length > 0,
8658
+ capReasons
8659
+ });
8660
+ }
8661
+ return {
8662
+ strategy,
8663
+ maxParallelTasks,
8664
+ maxReadonlyParallelTasks,
8665
+ activeWriteAssigned,
8666
+ activeReadonlyAssigned,
8667
+ globalWriteCapReached,
8668
+ globalReadonlyCapReached,
8669
+ nodes
8670
+ };
8671
+ }
8672
+ var init_mesh_scheduling_runtime = __esm({
8673
+ "src/mesh/mesh-scheduling-runtime.ts"() {
8674
+ "use strict";
8675
+ init_repo_mesh_types();
8676
+ init_dist();
8677
+ }
8678
+ });
8679
+
8577
8680
  // src/mesh/mesh-events-utils.ts
8578
8681
  function readNonEmptyString2(value) {
8579
8682
  return typeof value === "string" && value.trim() ? value.trim() : "";
@@ -13805,6 +13908,20 @@ function recoverMeshIdByNodeId(nodeId) {
13805
13908
  }
13806
13909
  return "";
13807
13910
  }
13911
+ function recoverMeshIdByCoordinatorAndNode(coordinatorDaemonId, nodeId) {
13912
+ if (!coordinatorDaemonId) return "";
13913
+ const hosted = listMeshes().filter((mesh) => {
13914
+ const host = resolveMeshHostStatus(mesh);
13915
+ return host.role === "host" && (!host.hostDaemonId || daemonIdsEquivalent(host.hostDaemonId, coordinatorDaemonId));
13916
+ });
13917
+ if (hosted.length === 0) return "";
13918
+ if (nodeId) {
13919
+ const byNode = hosted.find((mesh) => Array.isArray(mesh.nodes) && mesh.nodes.some((n) => meshNodeIdMatches(n, nodeId)));
13920
+ if (byNode) return readNonEmptyString2(byNode.id);
13921
+ return "";
13922
+ }
13923
+ return hosted.length === 1 ? readNonEmptyString2(hosted[0].id) : "";
13924
+ }
13808
13925
  function resolveForwardEventMeshId(components, payload) {
13809
13926
  const direct = readNonEmptyString2(payload.meshId);
13810
13927
  if (direct) return direct;
@@ -14551,7 +14668,10 @@ function handleMeshForwardEvent(components, payload) {
14551
14668
  }
14552
14669
  const nodeId = readNonEmptyString2(payload.nodeId);
14553
14670
  const workspace = readNonEmptyString2(payload.workspace);
14554
- const meshId = readNonEmptyString2(payload.meshId) || (workspace ? readNonEmptyString2(getCachedMeshByWorkspace(workspace)?.id) : "") || recoverMeshIdByNodeId(nodeId);
14671
+ const meshId = readNonEmptyString2(payload.meshId) || (workspace ? readNonEmptyString2(getCachedMeshByWorkspace(workspace)?.id) : "") || recoverMeshIdByNodeId(nodeId) || recoverMeshIdByCoordinatorAndNode(
14672
+ readNonEmptyString2(payload.meshCoordinatorDaemonId) || readNonEmptyString2(payload.coordinatorDaemonId),
14673
+ nodeId
14674
+ );
14555
14675
  if (!meshId) {
14556
14676
  traceMeshEventDrop("meshId_required", {
14557
14677
  taskId: payload.taskId,
@@ -14606,7 +14726,12 @@ function forwardUnresolvedDelegateEvent(components, routing, event) {
14606
14726
  ...event,
14607
14727
  event: eventName,
14608
14728
  nodeId: readNonEmptyString2(routing.nodeId) || readNonEmptyString2(event.meshNodeId) || void 0,
14609
- workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0
14729
+ workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0,
14730
+ // Fix B: carry the resolved coordinator anchor so the coordinator's receive-side
14731
+ // recovery (recoverMeshIdByCoordinatorAndNode) can match this forward to one of the
14732
+ // meshes it hosts when workspace + nodeId both miss. routing.coordinatorDaemonId is
14733
+ // the same anchor this forward is addressed to (coordinatorDaemonId below).
14734
+ meshCoordinatorDaemonId: coordinatorDaemonId
14610
14735
  };
14611
14736
  const resolvedMeshId = resolveForwardEventMeshId(components, payload);
14612
14737
  if (resolvedMeshId) payload.meshId = resolvedMeshId;
@@ -14735,6 +14860,7 @@ var init_mesh_event_forwarding = __esm({
14735
14860
  init_mesh_runtime_store();
14736
14861
  init_mesh_events_pending();
14737
14862
  init_mesh_routing();
14863
+ init_mesh_host_ownership();
14738
14864
  init_mesh_unresolved_forward_outbox();
14739
14865
  init_mesh_event_trace();
14740
14866
  init_snapshot();
@@ -22974,102 +23100,7 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
22974
23100
  init_mesh_work_queue();
22975
23101
  init_mesh_active_work();
22976
23102
  init_mesh_refine_status();
22977
-
22978
- // src/mesh/mesh-scheduling-runtime.ts
22979
- init_repo_mesh_types();
22980
- init_dist();
22981
- function isReadonly(task) {
22982
- return task.taskMode === "live_debug_readonly";
22983
- }
22984
- function isAssigned(task) {
22985
- return task.status === "assigned";
22986
- }
22987
- function buildMeshSchedulingRuntime(mesh, queue) {
22988
- const strategy = normalizeMeshSchedulingStrategy(mesh?.policy?.schedulingStrategy);
22989
- const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
22990
- const maxReadonlyParallelTasks = Math.max(2, maxParallelTasks * 2);
22991
- const assignedTasks = (Array.isArray(queue) ? queue : []).filter(isAssigned);
22992
- const activeWriteAssigned = assignedTasks.filter((t) => !isReadonly(t)).length;
22993
- const activeReadonlyAssigned = assignedTasks.filter(isReadonly).length;
22994
- const globalWriteCapReached = activeWriteAssigned >= maxParallelTasks;
22995
- const globalReadonlyCapReached = activeReadonlyAssigned >= maxReadonlyParallelTasks;
22996
- const writeAssignedByNode = /* @__PURE__ */ new Map();
22997
- const assignedByNode = /* @__PURE__ */ new Map();
22998
- const providerCountByNode = /* @__PURE__ */ new Map();
22999
- for (const task of assignedTasks) {
23000
- const nodeId = typeof task.assignedNodeId === "string" ? task.assignedNodeId.trim() : "";
23001
- if (!nodeId) continue;
23002
- assignedByNode.set(nodeId, (assignedByNode.get(nodeId) ?? 0) + 1);
23003
- if (!isReadonly(task)) {
23004
- writeAssignedByNode.set(nodeId, (writeAssignedByNode.get(nodeId) ?? 0) + 1);
23005
- }
23006
- const provider = typeof task.assignedProviderType === "string" ? task.assignedProviderType : "";
23007
- if (provider) {
23008
- let byProvider = providerCountByNode.get(nodeId);
23009
- if (!byProvider) {
23010
- byProvider = /* @__PURE__ */ new Map();
23011
- providerCountByNode.set(nodeId, byProvider);
23012
- }
23013
- byProvider.set(provider, (byProvider.get(provider) ?? 0) + 1);
23014
- }
23015
- }
23016
- const nodes = [];
23017
- for (const rawNode of Array.isArray(mesh?.nodes) ? mesh.nodes : []) {
23018
- const nodeId = normalizeMeshNodeId(rawNode);
23019
- if (!nodeId) continue;
23020
- const policy = rawNode?.policy || void 0;
23021
- const load4 = assignedByNode.get(nodeId) ?? 0;
23022
- const schedulingPriority = resolveNodeSchedulingPriority(policy);
23023
- const capReasons = [];
23024
- if (globalWriteCapReached) capReasons.push("global_max_parallel_tasks_reached");
23025
- if ((writeAssignedByNode.get(nodeId) ?? 0) > 0) capReasons.push("node_has_active_assignment");
23026
- let providerRoles;
23027
- const declaredRoles = Array.isArray(policy?.providerRoles) ? policy.providerRoles : [];
23028
- if (declaredRoles.length) {
23029
- const byProvider = providerCountByNode.get(nodeId);
23030
- providerRoles = [];
23031
- for (const role of declaredRoles) {
23032
- if (!role || typeof role !== "object") continue;
23033
- const providerType = typeof role.providerType === "string" ? role.providerType.trim() : "";
23034
- if (!providerType) continue;
23035
- const maxParallel = resolveProviderMaxParallel(policy, providerType);
23036
- const activeAssigned = byProvider?.get(providerType) ?? 0;
23037
- const capReached = maxParallel !== void 0 && activeAssigned >= maxParallel;
23038
- providerRoles.push({
23039
- providerType,
23040
- ...maxParallel !== void 0 ? { maxParallel } : {},
23041
- activeAssigned,
23042
- capReached
23043
- });
23044
- if (capReached) capReasons.push(`max_provider_parallel_reached:${providerType}`);
23045
- }
23046
- if (!providerRoles.length) providerRoles = void 0;
23047
- }
23048
- const maxConcurrentSessions = Number(policy?.maxConcurrentSessions);
23049
- const hasSessionCap = Number.isFinite(maxConcurrentSessions) && maxConcurrentSessions >= 0;
23050
- nodes.push({
23051
- nodeId,
23052
- load: load4,
23053
- schedulingPriority,
23054
- ...hasSessionCap ? { maxConcurrentSessions: Math.floor(maxConcurrentSessions) } : {},
23055
- ...providerRoles ? { providerRoles } : {},
23056
- capReached: capReasons.length > 0,
23057
- capReasons
23058
- });
23059
- }
23060
- return {
23061
- strategy,
23062
- maxParallelTasks,
23063
- maxReadonlyParallelTasks,
23064
- activeWriteAssigned,
23065
- activeReadonlyAssigned,
23066
- globalWriteCapReached,
23067
- globalReadonlyCapReached,
23068
- nodes
23069
- };
23070
- }
23071
-
23072
- // src/index.ts
23103
+ init_mesh_scheduling_runtime();
23073
23104
  init_mesh_host_ownership();
23074
23105
  init_mesh_events();
23075
23106
  init_mesh_events_utils();
@@ -38852,9 +38883,35 @@ var CliProviderInstance = class _CliProviderInstance {
38852
38883
  * terminal state. Leaving meshNodeFor pinned would route this session's
38853
38884
  * subsequent unrelated turns (e.g. ad-hoc dashboard chats) to the
38854
38885
  * coordinator as if they were task completions.
38886
+ *
38887
+ * MESHID-DROP-ON-DETACH (Fix C): a coordinator-LAUNCHED worker session
38888
+ * (launchedByCoordinator) holds its mesh membership (meshNodeFor / meshNodeId /
38889
+ * meshCoordinatorDaemonId) at the SESSION level — set once at launch
38890
+ * (mesh_launch_session / queue auto-launch), independent of any single task.
38891
+ * The original detach wiped meshNodeFor + meshNodeId together with the
38892
+ * task-level meshActiveTaskId, so the FIRST task completion stripped the
38893
+ * membership and EVERY subsequent completion forwarded with meshId absent —
38894
+ * resolveWorkerDelegateRouting fell to mesh_unresolved and the coordinator
38895
+ * rejected the forward "meshId required". For a launched member we therefore
38896
+ * clear ONLY the task-level marker (meshActiveTaskId) and preserve the
38897
+ * session-level membership so its next task's completion still resolves.
38898
+ * A task-less ad-hoc turn on a preserved-membership session is NOT misrouted:
38899
+ * its completion carries no taskId and the session holds no active assignment,
38900
+ * so the forwarder's WARMUPGAP guard skips the dispatch-row flip (it only
38901
+ * injects a benign task-less notification). A NON-launched session (a plain CLI
38902
+ * session adopted by mesh_send_task --direct, launchedByCoordinator falsy)
38903
+ * keeps the original full clear so an ad-hoc session is never left pinned.
38855
38904
  */
38856
38905
  detachMeshAssignment() {
38857
38906
  if (!this.settings.meshNodeFor && !this.settings.meshActiveTaskId && !this.settings.meshNodeId) return;
38907
+ if (this.settings.launchedByCoordinator === true) {
38908
+ if (!this.settings.meshActiveTaskId) return;
38909
+ const { meshActiveTaskId: meshActiveTaskId2, ...rest2 } = this.settings;
38910
+ void meshActiveTaskId2;
38911
+ this.settings = rest2;
38912
+ this.adapter.updateRuntimeSettings?.(this.settings);
38913
+ return;
38914
+ }
38858
38915
  const { meshNodeFor, meshNodeId, meshActiveTaskId, ...rest } = this.settings;
38859
38916
  void meshNodeFor;
38860
38917
  void meshActiveTaskId;
@@ -48728,6 +48785,9 @@ var meshStatusHandlers = {
48728
48785
  const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
48729
48786
  const queue = getQueue2(meshId);
48730
48787
  const queueSummary = getMeshQueueStats2(meshId);
48788
+ const { buildMeshSchedulingRuntime: buildMeshSchedulingRuntime2 } = await Promise.resolve().then(() => (init_mesh_scheduling_runtime(), mesh_scheduling_runtime_exports));
48789
+ const schedulingRuntime = buildMeshSchedulingRuntime2(mesh, queue);
48790
+ const schedulingByNode = new Map(schedulingRuntime.nodes.map((n) => [n.nodeId, n]));
48731
48791
  const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
48732
48792
  const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
48733
48793
  const asyncRefineLedgerEntries = readLedgerEntries2(meshId, { tail: 100 });
@@ -48842,6 +48902,11 @@ var meshStatusHandlers = {
48842
48902
  activeSessionDetails: [],
48843
48903
  launchReady: false
48844
48904
  };
48905
+ const nodeScheduling = schedulingByNode.get(nodeId);
48906
+ if (nodeScheduling) {
48907
+ const { nodeId: _omitNodeId, ...nodeSchedulingRest } = nodeScheduling;
48908
+ status.scheduling = nodeSchedulingRest;
48909
+ }
48845
48910
  if (isSelfNode) {
48846
48911
  status.connection = {
48847
48912
  perspective: "selected_coordinator",
@@ -49042,6 +49107,19 @@ var meshStatusHandlers = {
49042
49107
  branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
49043
49108
  ...previewFreshness ? { previewFreshness, deployFreshness: previewFreshness } : {},
49044
49109
  nodes: nodeStatuses,
49110
+ // Mesh-level scheduling rollup (strategy + global cap consumption). Mirrors
49111
+ // the MCP `mesh_status` tool's `scheduling` block field-for-field so both
49112
+ // surfaces read the same runtime; per-node detail lives on each
49113
+ // nodes[].scheduling above.
49114
+ scheduling: {
49115
+ strategy: schedulingRuntime.strategy,
49116
+ maxParallelTasks: schedulingRuntime.maxParallelTasks,
49117
+ maxReadonlyParallelTasks: schedulingRuntime.maxReadonlyParallelTasks,
49118
+ activeWriteAssigned: schedulingRuntime.activeWriteAssigned,
49119
+ activeReadonlyAssigned: schedulingRuntime.activeReadonlyAssigned,
49120
+ globalWriteCapReached: schedulingRuntime.globalWriteCapReached,
49121
+ globalReadonlyCapReached: schedulingRuntime.globalReadonlyCapReached
49122
+ },
49045
49123
  queue: { tasks: queue, summary: queueSummary },
49046
49124
  ledger: { entries: ledgerEntries, summary: ledgerSummary },
49047
49125
  ...missions.length > 0 ? { missions } : {},