@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.js CHANGED
@@ -383,10 +383,10 @@ function readInjected(value) {
383
383
  }
384
384
  function getDaemonBuildInfo() {
385
385
  if (cached) return cached;
386
- const commit = readInjected(true ? "18afac213951f79c502feb6b25b7399fe4d709b3" : void 0) ?? "unknown";
387
- const commitShort = readInjected(true ? "18afac21" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
388
- const version = readInjected(true ? "0.9.82-rc.381" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
389
- const builtAt = readInjected(true ? "2026-06-25T11:44:40.598Z" : void 0);
386
+ const commit = readInjected(true ? "70741c4fe19c6f71bcef702e7e149d963d6fd916" : void 0) ?? "unknown";
387
+ const commitShort = readInjected(true ? "70741c4f" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
388
+ const version = readInjected(true ? "0.9.82-rc.382" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
389
+ const builtAt = readInjected(true ? "2026-06-25T13:31:28.133Z" : void 0);
390
390
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
391
391
  return cached;
392
392
  }
@@ -8581,6 +8581,109 @@ var init_mesh_active_work = __esm({
8581
8581
  }
8582
8582
  });
8583
8583
 
8584
+ // src/mesh/mesh-scheduling-runtime.ts
8585
+ var mesh_scheduling_runtime_exports = {};
8586
+ __export(mesh_scheduling_runtime_exports, {
8587
+ buildMeshSchedulingRuntime: () => buildMeshSchedulingRuntime
8588
+ });
8589
+ function isReadonly(task) {
8590
+ return task.taskMode === "live_debug_readonly";
8591
+ }
8592
+ function isAssigned(task) {
8593
+ return task.status === "assigned";
8594
+ }
8595
+ function buildMeshSchedulingRuntime(mesh, queue) {
8596
+ const strategy = normalizeMeshSchedulingStrategy(mesh?.policy?.schedulingStrategy);
8597
+ const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
8598
+ const maxReadonlyParallelTasks = Math.max(2, maxParallelTasks * 2);
8599
+ const assignedTasks = (Array.isArray(queue) ? queue : []).filter(isAssigned);
8600
+ const activeWriteAssigned = assignedTasks.filter((t) => !isReadonly(t)).length;
8601
+ const activeReadonlyAssigned = assignedTasks.filter(isReadonly).length;
8602
+ const globalWriteCapReached = activeWriteAssigned >= maxParallelTasks;
8603
+ const globalReadonlyCapReached = activeReadonlyAssigned >= maxReadonlyParallelTasks;
8604
+ const writeAssignedByNode = /* @__PURE__ */ new Map();
8605
+ const assignedByNode = /* @__PURE__ */ new Map();
8606
+ const providerCountByNode = /* @__PURE__ */ new Map();
8607
+ for (const task of assignedTasks) {
8608
+ const nodeId = typeof task.assignedNodeId === "string" ? task.assignedNodeId.trim() : "";
8609
+ if (!nodeId) continue;
8610
+ assignedByNode.set(nodeId, (assignedByNode.get(nodeId) ?? 0) + 1);
8611
+ if (!isReadonly(task)) {
8612
+ writeAssignedByNode.set(nodeId, (writeAssignedByNode.get(nodeId) ?? 0) + 1);
8613
+ }
8614
+ const provider = typeof task.assignedProviderType === "string" ? task.assignedProviderType : "";
8615
+ if (provider) {
8616
+ let byProvider = providerCountByNode.get(nodeId);
8617
+ if (!byProvider) {
8618
+ byProvider = /* @__PURE__ */ new Map();
8619
+ providerCountByNode.set(nodeId, byProvider);
8620
+ }
8621
+ byProvider.set(provider, (byProvider.get(provider) ?? 0) + 1);
8622
+ }
8623
+ }
8624
+ const nodes = [];
8625
+ for (const rawNode of Array.isArray(mesh?.nodes) ? mesh.nodes : []) {
8626
+ const nodeId = normalizeMeshNodeId(rawNode);
8627
+ if (!nodeId) continue;
8628
+ const policy = rawNode?.policy || void 0;
8629
+ const load4 = assignedByNode.get(nodeId) ?? 0;
8630
+ const schedulingPriority = resolveNodeSchedulingPriority(policy);
8631
+ const capReasons = [];
8632
+ if (globalWriteCapReached) capReasons.push("global_max_parallel_tasks_reached");
8633
+ if ((writeAssignedByNode.get(nodeId) ?? 0) > 0) capReasons.push("node_has_active_assignment");
8634
+ let providerRoles;
8635
+ const declaredRoles = Array.isArray(policy?.providerRoles) ? policy.providerRoles : [];
8636
+ if (declaredRoles.length) {
8637
+ const byProvider = providerCountByNode.get(nodeId);
8638
+ providerRoles = [];
8639
+ for (const role of declaredRoles) {
8640
+ if (!role || typeof role !== "object") continue;
8641
+ const providerType = typeof role.providerType === "string" ? role.providerType.trim() : "";
8642
+ if (!providerType) continue;
8643
+ const maxParallel = resolveProviderMaxParallel(policy, providerType);
8644
+ const activeAssigned = byProvider?.get(providerType) ?? 0;
8645
+ const capReached = maxParallel !== void 0 && activeAssigned >= maxParallel;
8646
+ providerRoles.push({
8647
+ providerType,
8648
+ ...maxParallel !== void 0 ? { maxParallel } : {},
8649
+ activeAssigned,
8650
+ capReached
8651
+ });
8652
+ if (capReached) capReasons.push(`max_provider_parallel_reached:${providerType}`);
8653
+ }
8654
+ if (!providerRoles.length) providerRoles = void 0;
8655
+ }
8656
+ const maxConcurrentSessions = Number(policy?.maxConcurrentSessions);
8657
+ const hasSessionCap = Number.isFinite(maxConcurrentSessions) && maxConcurrentSessions >= 0;
8658
+ nodes.push({
8659
+ nodeId,
8660
+ load: load4,
8661
+ schedulingPriority,
8662
+ ...hasSessionCap ? { maxConcurrentSessions: Math.floor(maxConcurrentSessions) } : {},
8663
+ ...providerRoles ? { providerRoles } : {},
8664
+ capReached: capReasons.length > 0,
8665
+ capReasons
8666
+ });
8667
+ }
8668
+ return {
8669
+ strategy,
8670
+ maxParallelTasks,
8671
+ maxReadonlyParallelTasks,
8672
+ activeWriteAssigned,
8673
+ activeReadonlyAssigned,
8674
+ globalWriteCapReached,
8675
+ globalReadonlyCapReached,
8676
+ nodes
8677
+ };
8678
+ }
8679
+ var init_mesh_scheduling_runtime = __esm({
8680
+ "src/mesh/mesh-scheduling-runtime.ts"() {
8681
+ "use strict";
8682
+ init_repo_mesh_types();
8683
+ init_dist();
8684
+ }
8685
+ });
8686
+
8584
8687
  // src/mesh/mesh-events-utils.ts
8585
8688
  function readNonEmptyString2(value) {
8586
8689
  return typeof value === "string" && value.trim() ? value.trim() : "";
@@ -13810,6 +13913,20 @@ function recoverMeshIdByNodeId(nodeId) {
13810
13913
  }
13811
13914
  return "";
13812
13915
  }
13916
+ function recoverMeshIdByCoordinatorAndNode(coordinatorDaemonId, nodeId) {
13917
+ if (!coordinatorDaemonId) return "";
13918
+ const hosted = listMeshes().filter((mesh) => {
13919
+ const host = resolveMeshHostStatus(mesh);
13920
+ return host.role === "host" && (!host.hostDaemonId || daemonIdsEquivalent(host.hostDaemonId, coordinatorDaemonId));
13921
+ });
13922
+ if (hosted.length === 0) return "";
13923
+ if (nodeId) {
13924
+ const byNode = hosted.find((mesh) => Array.isArray(mesh.nodes) && mesh.nodes.some((n) => meshNodeIdMatches(n, nodeId)));
13925
+ if (byNode) return readNonEmptyString2(byNode.id);
13926
+ return "";
13927
+ }
13928
+ return hosted.length === 1 ? readNonEmptyString2(hosted[0].id) : "";
13929
+ }
13813
13930
  function resolveForwardEventMeshId(components, payload) {
13814
13931
  const direct = readNonEmptyString2(payload.meshId);
13815
13932
  if (direct) return direct;
@@ -14556,7 +14673,10 @@ function handleMeshForwardEvent(components, payload) {
14556
14673
  }
14557
14674
  const nodeId = readNonEmptyString2(payload.nodeId);
14558
14675
  const workspace = readNonEmptyString2(payload.workspace);
14559
- const meshId = readNonEmptyString2(payload.meshId) || (workspace ? readNonEmptyString2(getCachedMeshByWorkspace(workspace)?.id) : "") || recoverMeshIdByNodeId(nodeId);
14676
+ const meshId = readNonEmptyString2(payload.meshId) || (workspace ? readNonEmptyString2(getCachedMeshByWorkspace(workspace)?.id) : "") || recoverMeshIdByNodeId(nodeId) || recoverMeshIdByCoordinatorAndNode(
14677
+ readNonEmptyString2(payload.meshCoordinatorDaemonId) || readNonEmptyString2(payload.coordinatorDaemonId),
14678
+ nodeId
14679
+ );
14560
14680
  if (!meshId) {
14561
14681
  traceMeshEventDrop("meshId_required", {
14562
14682
  taskId: payload.taskId,
@@ -14611,7 +14731,12 @@ function forwardUnresolvedDelegateEvent(components, routing, event) {
14611
14731
  ...event,
14612
14732
  event: eventName,
14613
14733
  nodeId: readNonEmptyString2(routing.nodeId) || readNonEmptyString2(event.meshNodeId) || void 0,
14614
- workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0
14734
+ workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0,
14735
+ // Fix B: carry the resolved coordinator anchor so the coordinator's receive-side
14736
+ // recovery (recoverMeshIdByCoordinatorAndNode) can match this forward to one of the
14737
+ // meshes it hosts when workspace + nodeId both miss. routing.coordinatorDaemonId is
14738
+ // the same anchor this forward is addressed to (coordinatorDaemonId below).
14739
+ meshCoordinatorDaemonId: coordinatorDaemonId
14615
14740
  };
14616
14741
  const resolvedMeshId = resolveForwardEventMeshId(components, payload);
14617
14742
  if (resolvedMeshId) payload.meshId = resolvedMeshId;
@@ -14740,6 +14865,7 @@ var init_mesh_event_forwarding = __esm({
14740
14865
  init_mesh_runtime_store();
14741
14866
  init_mesh_events_pending();
14742
14867
  init_mesh_routing();
14868
+ init_mesh_host_ownership();
14743
14869
  init_mesh_unresolved_forward_outbox();
14744
14870
  init_mesh_event_trace();
14745
14871
  init_snapshot();
@@ -23355,102 +23481,7 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
23355
23481
  init_mesh_work_queue();
23356
23482
  init_mesh_active_work();
23357
23483
  init_mesh_refine_status();
23358
-
23359
- // src/mesh/mesh-scheduling-runtime.ts
23360
- init_repo_mesh_types();
23361
- init_dist();
23362
- function isReadonly(task) {
23363
- return task.taskMode === "live_debug_readonly";
23364
- }
23365
- function isAssigned(task) {
23366
- return task.status === "assigned";
23367
- }
23368
- function buildMeshSchedulingRuntime(mesh, queue) {
23369
- const strategy = normalizeMeshSchedulingStrategy(mesh?.policy?.schedulingStrategy);
23370
- const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
23371
- const maxReadonlyParallelTasks = Math.max(2, maxParallelTasks * 2);
23372
- const assignedTasks = (Array.isArray(queue) ? queue : []).filter(isAssigned);
23373
- const activeWriteAssigned = assignedTasks.filter((t) => !isReadonly(t)).length;
23374
- const activeReadonlyAssigned = assignedTasks.filter(isReadonly).length;
23375
- const globalWriteCapReached = activeWriteAssigned >= maxParallelTasks;
23376
- const globalReadonlyCapReached = activeReadonlyAssigned >= maxReadonlyParallelTasks;
23377
- const writeAssignedByNode = /* @__PURE__ */ new Map();
23378
- const assignedByNode = /* @__PURE__ */ new Map();
23379
- const providerCountByNode = /* @__PURE__ */ new Map();
23380
- for (const task of assignedTasks) {
23381
- const nodeId = typeof task.assignedNodeId === "string" ? task.assignedNodeId.trim() : "";
23382
- if (!nodeId) continue;
23383
- assignedByNode.set(nodeId, (assignedByNode.get(nodeId) ?? 0) + 1);
23384
- if (!isReadonly(task)) {
23385
- writeAssignedByNode.set(nodeId, (writeAssignedByNode.get(nodeId) ?? 0) + 1);
23386
- }
23387
- const provider = typeof task.assignedProviderType === "string" ? task.assignedProviderType : "";
23388
- if (provider) {
23389
- let byProvider = providerCountByNode.get(nodeId);
23390
- if (!byProvider) {
23391
- byProvider = /* @__PURE__ */ new Map();
23392
- providerCountByNode.set(nodeId, byProvider);
23393
- }
23394
- byProvider.set(provider, (byProvider.get(provider) ?? 0) + 1);
23395
- }
23396
- }
23397
- const nodes = [];
23398
- for (const rawNode of Array.isArray(mesh?.nodes) ? mesh.nodes : []) {
23399
- const nodeId = normalizeMeshNodeId(rawNode);
23400
- if (!nodeId) continue;
23401
- const policy = rawNode?.policy || void 0;
23402
- const load4 = assignedByNode.get(nodeId) ?? 0;
23403
- const schedulingPriority = resolveNodeSchedulingPriority(policy);
23404
- const capReasons = [];
23405
- if (globalWriteCapReached) capReasons.push("global_max_parallel_tasks_reached");
23406
- if ((writeAssignedByNode.get(nodeId) ?? 0) > 0) capReasons.push("node_has_active_assignment");
23407
- let providerRoles;
23408
- const declaredRoles = Array.isArray(policy?.providerRoles) ? policy.providerRoles : [];
23409
- if (declaredRoles.length) {
23410
- const byProvider = providerCountByNode.get(nodeId);
23411
- providerRoles = [];
23412
- for (const role of declaredRoles) {
23413
- if (!role || typeof role !== "object") continue;
23414
- const providerType = typeof role.providerType === "string" ? role.providerType.trim() : "";
23415
- if (!providerType) continue;
23416
- const maxParallel = resolveProviderMaxParallel(policy, providerType);
23417
- const activeAssigned = byProvider?.get(providerType) ?? 0;
23418
- const capReached = maxParallel !== void 0 && activeAssigned >= maxParallel;
23419
- providerRoles.push({
23420
- providerType,
23421
- ...maxParallel !== void 0 ? { maxParallel } : {},
23422
- activeAssigned,
23423
- capReached
23424
- });
23425
- if (capReached) capReasons.push(`max_provider_parallel_reached:${providerType}`);
23426
- }
23427
- if (!providerRoles.length) providerRoles = void 0;
23428
- }
23429
- const maxConcurrentSessions = Number(policy?.maxConcurrentSessions);
23430
- const hasSessionCap = Number.isFinite(maxConcurrentSessions) && maxConcurrentSessions >= 0;
23431
- nodes.push({
23432
- nodeId,
23433
- load: load4,
23434
- schedulingPriority,
23435
- ...hasSessionCap ? { maxConcurrentSessions: Math.floor(maxConcurrentSessions) } : {},
23436
- ...providerRoles ? { providerRoles } : {},
23437
- capReached: capReasons.length > 0,
23438
- capReasons
23439
- });
23440
- }
23441
- return {
23442
- strategy,
23443
- maxParallelTasks,
23444
- maxReadonlyParallelTasks,
23445
- activeWriteAssigned,
23446
- activeReadonlyAssigned,
23447
- globalWriteCapReached,
23448
- globalReadonlyCapReached,
23449
- nodes
23450
- };
23451
- }
23452
-
23453
- // src/index.ts
23484
+ init_mesh_scheduling_runtime();
23454
23485
  init_mesh_host_ownership();
23455
23486
  init_mesh_events();
23456
23487
  init_mesh_events_utils();
@@ -39233,9 +39264,35 @@ var CliProviderInstance = class _CliProviderInstance {
39233
39264
  * terminal state. Leaving meshNodeFor pinned would route this session's
39234
39265
  * subsequent unrelated turns (e.g. ad-hoc dashboard chats) to the
39235
39266
  * coordinator as if they were task completions.
39267
+ *
39268
+ * MESHID-DROP-ON-DETACH (Fix C): a coordinator-LAUNCHED worker session
39269
+ * (launchedByCoordinator) holds its mesh membership (meshNodeFor / meshNodeId /
39270
+ * meshCoordinatorDaemonId) at the SESSION level — set once at launch
39271
+ * (mesh_launch_session / queue auto-launch), independent of any single task.
39272
+ * The original detach wiped meshNodeFor + meshNodeId together with the
39273
+ * task-level meshActiveTaskId, so the FIRST task completion stripped the
39274
+ * membership and EVERY subsequent completion forwarded with meshId absent —
39275
+ * resolveWorkerDelegateRouting fell to mesh_unresolved and the coordinator
39276
+ * rejected the forward "meshId required". For a launched member we therefore
39277
+ * clear ONLY the task-level marker (meshActiveTaskId) and preserve the
39278
+ * session-level membership so its next task's completion still resolves.
39279
+ * A task-less ad-hoc turn on a preserved-membership session is NOT misrouted:
39280
+ * its completion carries no taskId and the session holds no active assignment,
39281
+ * so the forwarder's WARMUPGAP guard skips the dispatch-row flip (it only
39282
+ * injects a benign task-less notification). A NON-launched session (a plain CLI
39283
+ * session adopted by mesh_send_task --direct, launchedByCoordinator falsy)
39284
+ * keeps the original full clear so an ad-hoc session is never left pinned.
39236
39285
  */
39237
39286
  detachMeshAssignment() {
39238
39287
  if (!this.settings.meshNodeFor && !this.settings.meshActiveTaskId && !this.settings.meshNodeId) return;
39288
+ if (this.settings.launchedByCoordinator === true) {
39289
+ if (!this.settings.meshActiveTaskId) return;
39290
+ const { meshActiveTaskId: meshActiveTaskId2, ...rest2 } = this.settings;
39291
+ void meshActiveTaskId2;
39292
+ this.settings = rest2;
39293
+ this.adapter.updateRuntimeSettings?.(this.settings);
39294
+ return;
39295
+ }
39239
39296
  const { meshNodeFor, meshNodeId, meshActiveTaskId, ...rest } = this.settings;
39240
39297
  void meshNodeFor;
39241
39298
  void meshActiveTaskId;
@@ -49104,6 +49161,9 @@ var meshStatusHandlers = {
49104
49161
  const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
49105
49162
  const queue = getQueue2(meshId);
49106
49163
  const queueSummary = getMeshQueueStats2(meshId);
49164
+ const { buildMeshSchedulingRuntime: buildMeshSchedulingRuntime2 } = await Promise.resolve().then(() => (init_mesh_scheduling_runtime(), mesh_scheduling_runtime_exports));
49165
+ const schedulingRuntime = buildMeshSchedulingRuntime2(mesh, queue);
49166
+ const schedulingByNode = new Map(schedulingRuntime.nodes.map((n) => [n.nodeId, n]));
49107
49167
  const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
49108
49168
  const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
49109
49169
  const asyncRefineLedgerEntries = readLedgerEntries2(meshId, { tail: 100 });
@@ -49218,6 +49278,11 @@ var meshStatusHandlers = {
49218
49278
  activeSessionDetails: [],
49219
49279
  launchReady: false
49220
49280
  };
49281
+ const nodeScheduling = schedulingByNode.get(nodeId);
49282
+ if (nodeScheduling) {
49283
+ const { nodeId: _omitNodeId, ...nodeSchedulingRest } = nodeScheduling;
49284
+ status.scheduling = nodeSchedulingRest;
49285
+ }
49221
49286
  if (isSelfNode) {
49222
49287
  status.connection = {
49223
49288
  perspective: "selected_coordinator",
@@ -49418,6 +49483,19 @@ var meshStatusHandlers = {
49418
49483
  branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
49419
49484
  ...previewFreshness ? { previewFreshness, deployFreshness: previewFreshness } : {},
49420
49485
  nodes: nodeStatuses,
49486
+ // Mesh-level scheduling rollup (strategy + global cap consumption). Mirrors
49487
+ // the MCP `mesh_status` tool's `scheduling` block field-for-field so both
49488
+ // surfaces read the same runtime; per-node detail lives on each
49489
+ // nodes[].scheduling above.
49490
+ scheduling: {
49491
+ strategy: schedulingRuntime.strategy,
49492
+ maxParallelTasks: schedulingRuntime.maxParallelTasks,
49493
+ maxReadonlyParallelTasks: schedulingRuntime.maxReadonlyParallelTasks,
49494
+ activeWriteAssigned: schedulingRuntime.activeWriteAssigned,
49495
+ activeReadonlyAssigned: schedulingRuntime.activeReadonlyAssigned,
49496
+ globalWriteCapReached: schedulingRuntime.globalWriteCapReached,
49497
+ globalReadonlyCapReached: schedulingRuntime.globalReadonlyCapReached
49498
+ },
49421
49499
  queue: { tasks: queue, summary: queueSummary },
49422
49500
  ledger: { entries: ledgerEntries, summary: ledgerSummary },
49423
49501
  ...missions.length > 0 ? { missions } : {},