@adhdev/daemon-standalone 1.0.28 → 1.0.29-rc.2

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
@@ -33311,10 +33311,10 @@ var require_dist3 = __commonJS({
33311
33311
  }
33312
33312
  function getDaemonBuildInfo() {
33313
33313
  if (cached2) return cached2;
33314
- const commit = readInjected(true ? "65cb2fc5efccc67d1480cbb5472cfab944160211" : void 0) ?? "unknown";
33315
- const commitShort = readInjected(true ? "65cb2fc" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
33316
- const version2 = readInjected(true ? "1.0.28" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
33317
- const builtAt = readInjected(true ? "2026-07-31T07:59:06.980Z" : void 0);
33314
+ const commit = readInjected(true ? "970517bde86bb64ddf4944f4676a0b7aa3e0ecd6" : void 0) ?? "unknown";
33315
+ const commitShort = readInjected(true ? "970517bd" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
33316
+ const version2 = readInjected(true ? "1.0.29-rc.2" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
33317
+ const builtAt = readInjected(true ? "2026-08-01T12:48:29.542Z" : void 0);
33318
33318
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
33319
33319
  return cached2;
33320
33320
  }
@@ -36235,6 +36235,7 @@ ${error48.message || ""}`;
36235
36235
  normalizeRepoIdentity: () => normalizeRepoIdentity,
36236
36236
  removeMagiKindPanel: () => removeMagiKindPanel,
36237
36237
  removeNode: () => removeNode,
36238
+ resolveScopedMeshId: () => resolveScopedMeshId,
36238
36239
  setDifficultyBrains: () => setDifficultyBrains,
36239
36240
  setMagiKindPanel: () => setMagiKindPanel,
36240
36241
  tokenIdForManualPairing: () => tokenIdForManualPairing,
@@ -36265,15 +36266,41 @@ ${error48.message || ""}`;
36265
36266
  }
36266
36267
  function migrateLoadedMeshConfig(config2) {
36267
36268
  let changed = false;
36269
+ if (foldLegacyTopLevelMeshSetting(config2, "magiKindPanels", "mesh_magi_kind_panel_set({ meshId, task_kind, slots })")) changed = true;
36270
+ if (foldLegacyTopLevelMeshSetting(config2, "difficultyBrains", "difficulty_brains_set({ meshId, difficultyBrains })")) changed = true;
36268
36271
  for (const mesh of config2.meshes) {
36269
36272
  if (!mesh || !Array.isArray(mesh.nodes)) continue;
36273
+ const brains = normalizeDifficultyBrainMap(mesh.difficultyBrains);
36274
+ const ownerBrains = Object.keys(brains).length > 0 ? brains : { ...DEFAULT_DIFFICULTY_BRAINS };
36270
36275
  for (const node of mesh.nodes) {
36271
- if (migrateProviderRolesToSlots(node?.policy)) changed = true;
36276
+ if (migrateProviderRolesToSlots(node?.policy, ownerBrains)) changed = true;
36272
36277
  }
36273
36278
  }
36274
36279
  return changed;
36275
36280
  }
36276
- function migrateProviderRolesToSlots(policy) {
36281
+ function foldLegacyTopLevelMeshSetting(config2, key2, rebindHint) {
36282
+ const root = config2;
36283
+ const legacy = root[key2];
36284
+ if (!legacy || typeof legacy !== "object" || Array.isArray(legacy)) {
36285
+ if (key2 in root) {
36286
+ delete root[key2];
36287
+ return true;
36288
+ }
36289
+ return false;
36290
+ }
36291
+ delete root[key2];
36292
+ const entryKeys = Object.keys(legacy);
36293
+ if (config2.meshes.length === 1 && entryKeys.length > 0) {
36294
+ const mesh = config2.meshes[0];
36295
+ mesh[key2] = { ...legacy, ...mesh[key2] ?? {} };
36296
+ } else if (entryKeys.length > 0) {
36297
+ console.warn(
36298
+ `[mesh-config] Dropped legacy top-level ${key2} (keys: ${entryKeys.join(", ")}) \u2014 ${config2.meshes.length} meshes are configured, so the owning mesh cannot be determined. Re-apply it per mesh with ${rebindHint}.`
36299
+ );
36300
+ }
36301
+ return true;
36302
+ }
36303
+ function migrateProviderRolesToSlots(policy, ownerDifficultyBrains) {
36277
36304
  if (!policy || typeof policy !== "object" || Array.isArray(policy)) return false;
36278
36305
  const p = policy;
36279
36306
  const rawRoles = p.providerRoles;
@@ -36296,12 +36323,7 @@ ${error48.message || ""}`;
36296
36323
  }
36297
36324
  p.slots = explicitSlots;
36298
36325
  } else if (roleCap.size) {
36299
- let difficultyBrains;
36300
- try {
36301
- difficultyBrains = getDifficultyBrains();
36302
- } catch {
36303
- difficultyBrains = void 0;
36304
- }
36326
+ const difficultyBrains = ownerDifficultyBrains;
36305
36327
  const priority = Array.isArray(p.providerPriority) ? p.providerPriority.map((t) => typeof t === "string" ? t.trim() : "").filter(Boolean) : [];
36306
36328
  const derived = deriveSlotsFromLegacy({ providerPriority: priority, difficultyBrains });
36307
36329
  const slots = derived.length ? derived : [...roleCap.values()].map((r) => ({ provider: r.provider }));
@@ -36640,6 +36662,7 @@ ${error48.message || ""}`;
36640
36662
  const idx = mesh.nodes.findIndex((n) => n.id === nodeId);
36641
36663
  if (idx === -1) return false;
36642
36664
  mesh.nodes.splice(idx, 1);
36665
+ pruneMagiKindPanelsForRemovedNode(mesh, nodeId);
36643
36666
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
36644
36667
  saveMeshConfig(config2);
36645
36668
  return true;
@@ -36696,7 +36719,8 @@ ${error48.message || ""}`;
36696
36719
  }
36697
36720
  return s2;
36698
36721
  }
36699
- function normalizeMagiSlots(slots) {
36722
+ function normalizeMagiSlots(slots, knownNodeIds) {
36723
+ const allowed = knownNodeIds ? new Set(knownNodeIds) : void 0;
36700
36724
  if (!Array.isArray(slots) || slots.length === 0) {
36701
36725
  throw new Error("invalid_magi_kind_panel: slots must be a non-empty array");
36702
36726
  }
@@ -36713,6 +36737,11 @@ ${error48.message || ""}`;
36713
36737
  throw new Error(`invalid_magi_kind_panel: slot[${idx}].provider is required`);
36714
36738
  }
36715
36739
  const nodeId = typeof s2.nodeId === "string" && s2.nodeId.trim() ? s2.nodeId.trim() : void 0;
36740
+ if (nodeId && allowed && !allowed.has(nodeId)) {
36741
+ throw new Error(
36742
+ `invalid_magi_kind_panel: slot[${idx}].nodeId '${nodeId}' is not a node of this mesh (known: ${[...allowed].join(", ") || "(none)"}). Pin a node from this mesh, or omit nodeId to let the fan-out pick any node offering the provider.`
36743
+ );
36744
+ }
36716
36745
  const model = typeof s2.model === "string" && s2.model.trim() ? s2.model.trim() : void 0;
36717
36746
  const capabilityTags = normalizeCapabilityTags(s2.capabilityTags);
36718
36747
  const n = normalizeReplicaCount(s2.n);
@@ -36725,32 +36754,51 @@ ${error48.message || ""}`;
36725
36754
  };
36726
36755
  });
36727
36756
  }
36728
- function listMagiKindPanels() {
36729
- return loadMeshConfig().magiKindPanels ?? {};
36757
+ function resolveScopedMeshId(config2) {
36758
+ const meshes = (config2 ?? loadMeshConfig({ persistMigrations: false })).meshes;
36759
+ return meshes.length === 1 ? meshes[0].id : void 0;
36760
+ }
36761
+ function resolveScopedMesh(config2, meshId) {
36762
+ const id = meshId?.trim() || resolveScopedMeshId(config2);
36763
+ if (!id) return void 0;
36764
+ return config2.meshes.find((m) => m.id === id);
36730
36765
  }
36731
- function listMagiKindPanelsReadOnly() {
36732
- return loadMeshConfig({ persistMigrations: false }).magiKindPanels ?? {};
36766
+ function listMagiKindPanels(meshId) {
36767
+ const config2 = loadMeshConfig();
36768
+ return resolveScopedMesh(config2, meshId)?.magiKindPanels ?? {};
36769
+ }
36770
+ function listMagiKindPanelsReadOnly(meshId) {
36771
+ const config2 = loadMeshConfig({ persistMigrations: false });
36772
+ return resolveScopedMesh(config2, meshId)?.magiKindPanels ?? {};
36733
36773
  }
36734
- function getMagiKindPanel(kind) {
36774
+ function getMagiKindPanel(kind, meshId) {
36735
36775
  let key2;
36736
36776
  try {
36737
36777
  key2 = normalizeMagiTaskKindKey(kind);
36738
36778
  } catch {
36739
36779
  return void 0;
36740
36780
  }
36741
- return loadMeshConfig().magiKindPanels?.[key2];
36781
+ const config2 = loadMeshConfig();
36782
+ return resolveScopedMesh(config2, meshId)?.magiKindPanels?.[key2];
36742
36783
  }
36743
- function setMagiKindPanel(kind, slots) {
36784
+ function setMagiKindPanel(kind, slots, meshId) {
36744
36785
  const key2 = normalizeMagiTaskKindKey(kind);
36745
- const normalized = normalizeMagiSlots(slots);
36746
36786
  const stored = loadMeshConfig();
36747
- const map3 = stored.magiKindPanels ?? {};
36787
+ const mesh = resolveScopedMesh(stored, meshId);
36788
+ if (!mesh) {
36789
+ throw new Error(
36790
+ meshId?.trim() ? `invalid_magi_kind_panel: mesh '${meshId.trim()}' not found` : `magi_kind_panel_mesh_ambiguous: this machine hosts ${stored.meshes.length} meshes, so a MAGI kind-panel write must name its mesh explicitly (meshId). Panels are per mesh.`
36791
+ );
36792
+ }
36793
+ const normalized = normalizeMagiSlots(slots, mesh.nodes.map((n) => n.id));
36794
+ const map3 = mesh.magiKindPanels ?? {};
36748
36795
  map3[key2] = normalized;
36749
- stored.magiKindPanels = map3;
36796
+ mesh.magiKindPanels = map3;
36797
+ mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
36750
36798
  saveMeshConfig(stored);
36751
36799
  return normalized;
36752
36800
  }
36753
- function removeMagiKindPanel(kind) {
36801
+ function removeMagiKindPanel(kind, meshId) {
36754
36802
  let key2;
36755
36803
  try {
36756
36804
  key2 = normalizeMagiTaskKindKey(kind);
@@ -36758,21 +36806,47 @@ ${error48.message || ""}`;
36758
36806
  return false;
36759
36807
  }
36760
36808
  const stored = loadMeshConfig();
36761
- if (!stored.magiKindPanels || !stored.magiKindPanels[key2]) return false;
36762
- delete stored.magiKindPanels[key2];
36809
+ const mesh = resolveScopedMesh(stored, meshId);
36810
+ if (!mesh?.magiKindPanels?.[key2]) return false;
36811
+ delete mesh.magiKindPanels[key2];
36812
+ if (Object.keys(mesh.magiKindPanels).length === 0) delete mesh.magiKindPanels;
36813
+ mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
36763
36814
  saveMeshConfig(stored);
36764
36815
  return true;
36765
36816
  }
36766
- function getDifficultyBrains() {
36767
- const stored = loadMeshConfig().difficultyBrains;
36817
+ function pruneMagiKindPanelsForRemovedNode(mesh, nodeId) {
36818
+ const panels = mesh.magiKindPanels;
36819
+ if (!panels) return false;
36820
+ let changed = false;
36821
+ for (const [kind, slots] of Object.entries(panels)) {
36822
+ if (!Array.isArray(slots)) continue;
36823
+ const kept = slots.filter((slot) => slot.nodeId !== nodeId);
36824
+ if (kept.length === slots.length) continue;
36825
+ changed = true;
36826
+ if (kept.length === 0) delete panels[kind];
36827
+ else panels[kind] = kept;
36828
+ }
36829
+ if (changed && Object.keys(panels).length === 0) delete mesh.magiKindPanels;
36830
+ return changed;
36831
+ }
36832
+ function getDifficultyBrains(meshId) {
36833
+ const config2 = loadMeshConfig();
36834
+ const stored = resolveScopedMesh(config2, meshId)?.difficultyBrains;
36768
36835
  const normalized = normalizeDifficultyBrainMap(stored);
36769
36836
  return Object.keys(normalized).length > 0 ? normalized : { ...DEFAULT_DIFFICULTY_BRAINS };
36770
36837
  }
36771
- function setDifficultyBrains(map3) {
36838
+ function setDifficultyBrains(map3, meshId) {
36772
36839
  const normalized = normalizeDifficultyBrainMap(map3);
36773
36840
  const stored = loadMeshConfig();
36774
- if (Object.keys(normalized).length > 0) stored.difficultyBrains = normalized;
36775
- else delete stored.difficultyBrains;
36841
+ const mesh = resolveScopedMesh(stored, meshId);
36842
+ if (!mesh) {
36843
+ throw new Error(
36844
+ meshId?.trim() ? `invalid_difficulty_brains: mesh '${meshId.trim()}' not found` : `difficulty_brains_mesh_ambiguous: this machine hosts ${stored.meshes.length} meshes, so a difficulty-brain write must name its mesh explicitly (meshId). Presets are per mesh \u2014 they decide which model a task runs on, so writing to the wrong mesh changes what it costs.`
36845
+ );
36846
+ }
36847
+ if (Object.keys(normalized).length > 0) mesh.difficultyBrains = normalized;
36848
+ else delete mesh.difficultyBrains;
36849
+ mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
36776
36850
  saveMeshConfig(stored);
36777
36851
  return normalized;
36778
36852
  }
@@ -36808,12 +36882,12 @@ ${error48.message || ""}`;
36808
36882
  return true;
36809
36883
  });
36810
36884
  }
36811
- function resolveNodeCapabilitySlots(node) {
36885
+ function resolveNodeCapabilitySlots(node, meshId) {
36812
36886
  const explicit = normalizeNodeCapabilitySlots(node?.policy?.slots);
36813
36887
  if (explicit.length) return explicit;
36814
36888
  let difficultyBrains;
36815
36889
  try {
36816
- difficultyBrains = getDifficultyBrains();
36890
+ difficultyBrains = getDifficultyBrains(meshId);
36817
36891
  } catch {
36818
36892
  difficultyBrains = void 0;
36819
36893
  }
@@ -40828,7 +40902,7 @@ Next step: ${nextStep}`;
40828
40902
  const taskDifficulty = isMeshTaskDifficulty(opts?.difficulty) ? opts.difficulty : void 0;
40829
40903
  if (isMeshTaskDifficulty(opts?.difficulty)) {
40830
40904
  try {
40831
- const preset = getDifficultyBrains()[opts.difficulty];
40905
+ const preset = getDifficultyBrains(meshId)[opts.difficulty];
40832
40906
  if (preset) {
40833
40907
  if (!effectiveModel && preset.model) effectiveModel = preset.model;
40834
40908
  if (!effectiveThinkingLevel && preset.thinkingLevel) effectiveThinkingLevel = preset.thinkingLevel;
@@ -54047,6 +54121,77 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
54047
54121
  ]);
54048
54122
  }
54049
54123
  });
54124
+ function normalizeLiteral(model) {
54125
+ return model.toLowerCase().replace(/[_/\\().,]+/g, " ").replace(/-+/g, " ").replace(/\s+/g, " ").trim();
54126
+ }
54127
+ function canonicalizeModelName(model) {
54128
+ if (typeof model !== "string") return void 0;
54129
+ const literal2 = normalizeLiteral(model);
54130
+ if (!literal2) return void 0;
54131
+ const tokens = literal2.split(" ").filter((t) => t && !MODIFIER_WORDS.has(t));
54132
+ const family = CLAUDE_FAMILIES.find((f) => tokens.includes(f));
54133
+ let version2;
54134
+ if (family) {
54135
+ const after = tokens.slice(tokens.indexOf(family) + 1).filter((t) => /^\d+$/.test(t));
54136
+ if (after.length) version2 = after.join(".");
54137
+ else {
54138
+ const dotted = tokens.find((t) => /^\d+(\.\d+)+$/.test(t));
54139
+ if (dotted) version2 = dotted;
54140
+ }
54141
+ }
54142
+ return { family, version: version2, literal: literal2 };
54143
+ }
54144
+ function modelNamesEquivalent(a, b) {
54145
+ const ca = canonicalizeModelName(a);
54146
+ const cb = canonicalizeModelName(b);
54147
+ if (!ca || !cb) return false;
54148
+ if (ca.family && cb.family) {
54149
+ if (ca.family !== cb.family) return false;
54150
+ if (ca.version && cb.version) return ca.version === cb.version;
54151
+ return true;
54152
+ }
54153
+ if (ca.family || cb.family) return false;
54154
+ return ca.literal === cb.literal;
54155
+ }
54156
+ function isModelAllowedBySlot(model, slot) {
54157
+ if (!slot) return true;
54158
+ const declared = typeof slot.model === "string" ? slot.model.trim() : "";
54159
+ const requested = typeof model === "string" ? model.trim() : "";
54160
+ if (!declared) return !requested;
54161
+ if (!requested) return true;
54162
+ return modelNamesEquivalent(requested, declared);
54163
+ }
54164
+ function decideSlotForModel(input) {
54165
+ const { requestedModel, slots } = input;
54166
+ const declaring = slots.filter((s2) => isModelAllowedBySlot(requestedModel, s2.slot));
54167
+ if (!declaring.length) {
54168
+ const declaredModels = slots.map((s2) => typeof s2.slot.model === "string" && s2.slot.model.trim() ? s2.slot.model.trim() : "(provider default)").filter((v, i, a) => a.indexOf(v) === i);
54169
+ return { outcome: "notify", reason: SLOT_MODEL_ABSENT_SKIP_REASON, declaredModels };
54170
+ }
54171
+ const free = declaring.find((s2) => s2.available);
54172
+ if (free) {
54173
+ const declared = typeof free.slot.model === "string" && free.slot.model.trim() ? free.slot.model.trim() : void 0;
54174
+ return { outcome: "run", slot: free.slot, model: declared };
54175
+ }
54176
+ return {
54177
+ outcome: "wait",
54178
+ reason: SLOT_MODEL_BUSY_SKIP_REASON,
54179
+ busySlots: declaring.map((s2) => s2.slot)
54180
+ };
54181
+ }
54182
+ var CLAUDE_FAMILIES;
54183
+ var MODIFIER_WORDS;
54184
+ var SLOT_MODEL_BUSY_SKIP_REASON;
54185
+ var SLOT_MODEL_ABSENT_SKIP_REASON;
54186
+ var init_slot_model_enforcement = __esm2({
54187
+ "src/mesh/slot-model-enforcement.ts"() {
54188
+ "use strict";
54189
+ CLAUDE_FAMILIES = ["opus", "sonnet", "haiku"];
54190
+ MODIFIER_WORDS = /* @__PURE__ */ new Set(["thinking", "latest", "preview", "claude", "anthropic"]);
54191
+ SLOT_MODEL_BUSY_SKIP_REASON = "slot_for_model_busy";
54192
+ SLOT_MODEL_ABSENT_SKIP_REASON = "no_slot_declares_requested_model";
54193
+ }
54194
+ });
54050
54195
  function encodeDuplicateMeshDispatchCode(holderSessionId) {
54051
54196
  const holder = typeof holderSessionId === "string" ? holderSessionId.trim() : "";
54052
54197
  return holder ? `${DUPLICATE_MESH_DISPATCH_CODE}:${holder}` : DUPLICATE_MESH_DISPATCH_CODE;
@@ -54395,7 +54540,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
54395
54540
  return false;
54396
54541
  }
54397
54542
  const capabilityTags = buildMeshNodeCapabilityTags(node, providerType);
54398
- const providerMaxParallel = resolveProviderMaxParallel(resolveNodeCapabilitySlots(node), providerType);
54543
+ const providerMaxParallel = resolveProviderMaxParallel(resolveNodeCapabilitySlots(node, meshId), providerType);
54399
54544
  const nodeIsWorktree = node?.isLocalWorktree === true;
54400
54545
  const assignedTranscriptProfile = resolveClaimingSessionTranscriptProfile(components, sessionId);
54401
54546
  const task = claimNextTask(meshId, nodeId, sessionId, capabilityTags, {
@@ -54696,6 +54841,10 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
54696
54841
  summary: "the node's workspace is dirty, so auto-launch is blocked to avoid clobbering uncommitted changes",
54697
54842
  nextAction: "Clean or commit the node's working tree (or fast-forward it); the task will then auto-assign."
54698
54843
  };
54844
+ if (reason === SLOT_MODEL_ABSENT_SKIP_REASON) return {
54845
+ summary: "no capability slot on the node declares the model this task resolved to (its difficulty\u2192brain preset picked a model the node was never configured to run)",
54846
+ nextAction: "Re-enqueue with a difficulty/model the node's slots declare, target a node that declares this model, or add a slot for it. The task is NOT run on a substitute model \u2014 an undeclared model is never launched."
54847
+ };
54699
54848
  return {
54700
54849
  summary: `it cannot be dispatched (${reason})`,
54701
54850
  nextAction: "Inspect the node/mesh state with mesh_status and resolve the blocker, or re-enqueue the task."
@@ -54887,8 +55036,8 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
54887
55036
  }
54888
55037
  return score;
54889
55038
  }
54890
- function bestSlotForTask(node, task) {
54891
- const slots = resolveNodeCapabilitySlots(node);
55039
+ function bestSlotForTask(node, task, meshId) {
55040
+ const slots = resolveNodeCapabilitySlots(node, meshId);
54892
55041
  if (!slots.length) return null;
54893
55042
  let best = null;
54894
55043
  for (const slot of slots) {
@@ -54897,8 +55046,8 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
54897
55046
  }
54898
55047
  return best;
54899
55048
  }
54900
- function nodeFitnessForTask(node, task) {
54901
- return bestSlotForTask(node, task)?.score ?? 0;
55049
+ function nodeFitnessForTask(node, task, meshId) {
55050
+ return bestSlotForTask(node, task, meshId)?.score ?? 0;
54902
55051
  }
54903
55052
  function orderEligibleNodes(meshId, strategy, nodes, opts) {
54904
55053
  if (strategy === "first_eligible" || nodes.length <= 1) {
@@ -54907,7 +55056,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
54907
55056
  if (strategy === "fitness" && opts?.task) {
54908
55057
  const task = opts.task;
54909
55058
  return [...nodes].sort((a, b) => {
54910
- const fitDelta = nodeFitnessForTask(b.node, task) - nodeFitnessForTask(a.node, task);
55059
+ const fitDelta = nodeFitnessForTask(b.node, task, meshId) - nodeFitnessForTask(a.node, task, meshId);
54911
55060
  if (fitDelta !== 0) return fitDelta;
54912
55061
  const prioDelta = resolveNodeSchedulingPriority(b.node?.policy) - resolveNodeSchedulingPriority(a.node?.policy);
54913
55062
  if (prioDelta !== 0) return prioDelta;
@@ -54936,6 +55085,13 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
54936
55085
  function activeProviderAssignedCount(meshId, nodeId, providerType) {
54937
55086
  return getQueue(meshId, { status: ["assigned"] }).filter((task) => daemonIdsEquivalent(task.assignedNodeId, nodeId) && task.assignedProviderType === providerType).length;
54938
55087
  }
55088
+ function slotHasCapacity(meshId, nodeId, node, slot) {
55089
+ const providerType = typeof slot.provider === "string" ? slot.provider.trim() : "";
55090
+ if (!providerType) return false;
55091
+ const cap = resolveProviderMaxParallel(resolveNodeCapabilitySlots(node, meshId), providerType);
55092
+ if (cap === void 0) return true;
55093
+ return activeProviderAssignedCount(meshId, nodeId, providerType) < cap;
55094
+ }
54939
55095
  function sessionHasActiveAssignment(meshId, sessionId) {
54940
55096
  if (getQueue(meshId, { status: ["assigned"] }).some((task) => sessionIdsEquivalent(task.assignedSessionId, sessionId))) {
54941
55097
  return true;
@@ -55073,10 +55229,10 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
55073
55229
  retractActionableSkipIfPreviouslyNotified(meshId, taskId);
55074
55230
  }
55075
55231
  }
55076
- async function resolveUsableProvider(components, nodeId, node, requiredTags, task) {
55232
+ async function resolveUsableProvider(components, nodeId, node, meshId, requiredTags, task) {
55077
55233
  const providerLoader = components.providerLoader;
55078
55234
  if (!providerLoader) return { reason: "provider_loader_unavailable" };
55079
- const slots = resolveNodeCapabilitySlots(node);
55235
+ const slots = resolveNodeCapabilitySlots(node, meshId);
55080
55236
  if (!slots.length) return { reason: "missing_provider_priority" };
55081
55237
  const orderedSlots = task ? [...slots].sort((a, b) => scoreSlotForTask(b, task) - scoreSlotForTask(a, task)) : slots;
55082
55238
  const failed = [];
@@ -55110,7 +55266,12 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
55110
55266
  return {
55111
55267
  providerType: normalizedType,
55112
55268
  ...slot.model ? { model: slot.model } : {},
55113
- ...slot.thinkingLevel ? { thinkingLevel: slot.thinkingLevel } : {}
55269
+ ...slot.thinkingLevel ? { thinkingLevel: slot.thinkingLevel } : {},
55270
+ // The slot that won selection. Returned so the caller can enforce
55271
+ // "the launch model must be one this slot declares" — a preset
55272
+ // model must not widen what the operator configured. See
55273
+ // slot-model-enforcement.ts.
55274
+ slot
55114
55275
  };
55115
55276
  }
55116
55277
  failed.push(`${requestedType}: not detected`);
@@ -55247,7 +55408,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
55247
55408
  if (task.targetNodeId && !meshNodeIdMatches(node, task.targetNodeId)) return false;
55248
55409
  if (task.taskMode === "convergence" && node?.isLocalWorktree === true) return false;
55249
55410
  if (task.requiredTags?.length) {
55250
- const slotProviders = resolveNodeCapabilitySlots(node).map((s2) => s2.provider).filter(Boolean);
55411
+ const slotProviders = resolveNodeCapabilitySlots(node, meshId).map((s2) => s2.provider).filter(Boolean);
55251
55412
  const priorities = slotProviders.length ? slotProviders : normalizeProviderPriority2(node?.policy);
55252
55413
  const providerCandidates = priorities.length ? priorities : [void 0];
55253
55414
  return providerCandidates.some(
@@ -55336,18 +55497,36 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
55336
55497
  }
55337
55498
  autoLaunchInProgress.add(launchKey);
55338
55499
  try {
55339
- const resolved = await resolveUsableProvider(components, nodeId, node, task.requiredTags, { difficulty: task.difficulty, requiredTags: task.requiredTags });
55500
+ const resolved = await resolveUsableProvider(components, nodeId, node, meshId, task.requiredTags, { difficulty: task.difficulty, requiredTags: task.requiredTags });
55340
55501
  if (!resolved.providerType) {
55341
55502
  markSkip(nodeId, resolved.reason || "provider_unusable");
55342
55503
  continue;
55343
55504
  }
55344
- const rawEffectiveModel = typeof task.model === "string" && task.model.trim() ? task.model.trim() : resolved.model;
55505
+ const requestedModel = typeof task.model === "string" && task.model.trim() ? task.model.trim() : resolved.model;
55345
55506
  const effectiveThinkingLevel = typeof task.thinkingLevel === "string" && task.thinkingLevel.trim() ? task.thinkingLevel.trim() : resolved.thinkingLevel;
55507
+ const slotDecision = decideSlotForModel({
55508
+ requestedModel,
55509
+ slots: resolveNodeCapabilitySlots(node, meshId).map((slot) => ({
55510
+ slot,
55511
+ available: slotHasCapacity(meshId, nodeId, node, slot)
55512
+ }))
55513
+ });
55514
+ if (slotDecision.outcome === "wait") {
55515
+ LOG2.info("MeshQueue", `SLOT MODEL GUARD: model '${requestedModel}' is declared on node ${nodeId} but every matching slot is at its maxParallel cap (task ${task.id}); leaving the task queued until a slot goes idle`);
55516
+ markSkip(nodeId, slotDecision.reason, { providerType: resolved.providerType });
55517
+ continue;
55518
+ }
55519
+ if (slotDecision.outcome === "notify") {
55520
+ LOG2.warn("MeshQueue", `SLOT MODEL GUARD: no slot on node ${nodeId} declares model '${requestedModel}' (declared: ${slotDecision.declaredModels.join(", ") || "none"}) for task ${task.id}; not launching \u2014 surfacing to the coordinator to re-drive`);
55521
+ markSkip(nodeId, slotDecision.reason, { providerType: resolved.providerType });
55522
+ continue;
55523
+ }
55524
+ const rawEffectiveModel = slotDecision.model;
55346
55525
  const effectiveModel = isModelCompatibleWithProvider(rawEffectiveModel, resolved.providerType) ? rawEffectiveModel : void 0;
55347
55526
  if (rawEffectiveModel && effectiveModel === void 0) {
55348
55527
  LOG2.info("MeshQueue", `CODEX-400 GUARD: dropped incompatible launch model '${rawEffectiveModel}' for non-Anthropic provider '${resolved.providerType}' on node ${nodeId} (task ${task.id}); provider will use its own default model`);
55349
55528
  }
55350
- const providerCap = resolveProviderMaxParallel(resolveNodeCapabilitySlots(node), resolved.providerType);
55529
+ const providerCap = resolveProviderMaxParallel(resolveNodeCapabilitySlots(node, meshId), resolved.providerType);
55351
55530
  if (providerCap !== void 0 && activeProviderAssignedCount(meshId, nodeId, resolved.providerType) >= providerCap) {
55352
55531
  markSkip(nodeId, "max_provider_parallel_reached", { providerType: resolved.providerType });
55353
55532
  continue;
@@ -55441,7 +55620,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
55441
55620
  const requiredTags = Array.isArray(task.requiredTags) ? task.requiredTags.filter((t) => !!t) : [];
55442
55621
  const routingDecision = {
55443
55622
  source: "autoLaunch",
55444
- fitnessScore: nodeFitnessForTask(node, { difficulty: task.difficulty, requiredTags: task.requiredTags }),
55623
+ fitnessScore: nodeFitnessForTask(node, { difficulty: task.difficulty, requiredTags: task.requiredTags }, meshId),
55445
55624
  ...skippedCandidates.length ? { skippedCandidates } : {},
55446
55625
  requiredTagsResult: {
55447
55626
  required: requiredTags,
@@ -55885,6 +56064,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
55885
56064
  init_mesh_clone_grace();
55886
56065
  init_mesh_task_inflight();
55887
56066
  init_model_provider_compat();
56067
+ init_slot_model_enforcement();
55888
56068
  init_mesh_turn_ledger();
55889
56069
  init_mesh_duplicate_dispatch();
55890
56070
  IDLE_AUTO_FAST_FORWARD_THROTTLE_MS = 30 * 60 * 1e3;
@@ -55917,7 +56097,13 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
55917
56097
  "provider_loader_unavailable",
55918
56098
  "provider_priority_unusable",
55919
56099
  "provider_unusable",
55920
- "dirty_workspace"
56100
+ "dirty_workspace",
56101
+ // SLOT MODEL GUARD (absent): no slot on the node declares the task's model.
56102
+ // Permanent — no amount of waiting produces a slot, so the coordinator must
56103
+ // re-drive (adjust difficulty, target another node, ask the owner). Its
56104
+ // busy counterpart SLOT_MODEL_BUSY_SKIP_REASON is deliberately NOT listed:
56105
+ // that one clears on its own when the slot goes idle.
56106
+ SLOT_MODEL_ABSENT_SKIP_REASON
55921
56107
  ];
55922
56108
  TRANSIENT_TARGET_NODE_BOOTSTRAP_PENDING_REASON = "target_node_bootstrap_pending";
55923
56109
  lastActionableSkipNotified = /* @__PURE__ */ new Map();
@@ -71152,6 +71338,7 @@ ${lastSnapshot}`;
71152
71338
  buildChatMessageSignature: () => buildChatMessageSignature,
71153
71339
  buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
71154
71340
  buildClaudeInteractiveToolResult: () => buildClaudeInteractiveToolResult,
71341
+ buildCloudStatusReportPayload: () => buildCloudStatusReportPayload,
71155
71342
  buildCompactStaleDirectWorkSummary: () => buildCompactStaleDirectWorkSummary,
71156
71343
  buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt,
71157
71344
  buildIdleReminderMessage: () => buildIdleReminderMessage,
@@ -71451,6 +71638,7 @@ ${lastSnapshot}`;
71451
71638
  resolveNotBefore: () => resolveNotBefore,
71452
71639
  resolveProviderChannel: () => resolveProviderChannel,
71453
71640
  resolveProviderMaxParallel: () => resolveProviderMaxParallel,
71641
+ resolveScopedMeshId: () => resolveScopedMeshId,
71454
71642
  resolveSessionHostAppName: () => resolveSessionHostAppName,
71455
71643
  resolveSessionHostAppNameResolution: () => resolveSessionHostAppNameResolution2,
71456
71644
  resolveSessionTurnPresentation: () => resolveSessionTurnPresentation,
@@ -73026,7 +73214,7 @@ ${lastSnapshot}`;
73026
73214
  const bootstrapLoaded = loadMeshWorktreeBootstrapConfig(mesh, workspace);
73027
73215
  let magiKindPanels = {};
73028
73216
  try {
73029
- magiKindPanels = listMagiKindPanelsReadOnly();
73217
+ magiKindPanels = listMagiKindPanelsReadOnly(typeof mesh?.id === "string" ? mesh.id : void 0);
73030
73218
  } catch {
73031
73219
  magiKindPanels = {};
73032
73220
  }
@@ -87981,6 +88169,48 @@ ${body}
87981
88169
  }
87982
88170
  return screenText;
87983
88171
  }
88172
+ /**
88173
+ * Is `reread` a re-render of the SAME picker page as `landed`?
88174
+ *
88175
+ * Guards the return-pass screenText swap in captureClaudeTuiPrompt, which
88176
+ * replaces a page's entire raw screen and therefore must never be handed a
88177
+ * frame belonging to a different question.
88178
+ *
88179
+ * WHAT WE COMPARE — the question line, via the same parser the capture
88180
+ * itself uses (readFocusedClaudeTuiQuestion). Rationale:
88181
+ * - The question text is the one field that is per-page, always rendered
88182
+ * (it is the parse anchor — a page without it yields no question at all),
88183
+ * and stable across the redraw we are waiting on. The redraw races the
88184
+ * option-row GLYPH COLUMN, not the question line.
88185
+ * - The header is NOT usable on its own: on the headered variant every page
88186
+ * renders the identical nav line, and `page.header` is assigned by index
88187
+ * from that shared line rather than read from the page body — so it is
88188
+ * equal across pages by construction and would accept any frame.
88189
+ * - The option-label set is rejected as the primary key: it is drawn in the
88190
+ * very region that is mid-redraw, and rows can be clipped or scrolled out
88191
+ * of the captured frame (the same truncation that forced the headerless
88192
+ * parser to stop requiring the freeform escape hatch). Comparing it would
88193
+ * reject legitimate repairs — exactly the frames this pass exists to fix.
88194
+ *
88195
+ * STRICTNESS — deliberately asymmetric, because the two error directions are
88196
+ * not equally costly. Wrongly ALLOWING a swap corrupts a question into a
88197
+ * duplicate of another (the reported user-visible defect). Wrongly BLOCKING
88198
+ * one merely leaves the forward-pass capture in place — at worst a
88199
+ * multi-select page stays flagged single-select, which the live status-tick
88200
+ * upgrade (maybeUpgradeClaudeTuiMultiSelect) then repairs anyway. So this
88201
+ * blocks only on POSITIVE EVIDENCE of a different page: if either side fails
88202
+ * to parse we return true and defer to the pre-existing glyph gate, keeping
88203
+ * behaviour identical to before for every frame whose identity we cannot
88204
+ * read. Comparison is whitespace-normalised so a reflow or trailing-pad
88205
+ * difference does not read as a different question.
88206
+ */
88207
+ claudeTuiPagesLookLikeSameQuestion(landed, reread) {
88208
+ const landedQuestion = readFocusedClaudeTuiQuestion(landed.screenText);
88209
+ const rereadQuestion = readFocusedClaudeTuiQuestion(reread);
88210
+ if (!landedQuestion || !rereadQuestion) return true;
88211
+ const normalize4 = (text) => text.replace(/\s+/g, " ").trim();
88212
+ return normalize4(landedQuestion.question) === normalize4(rereadQuestion.question);
88213
+ }
87984
88214
  async captureClaudeTuiPrompt(firstScreen, headers) {
87985
88215
  const pages = [{ screenText: firstScreen, header: headers[0] }];
87986
88216
  for (let index = 1; index < headers.length; index += 1) {
@@ -87993,7 +88223,7 @@ ${body}
87993
88223
  await new Promise((resolve29) => setTimeout(resolve29, _SpecCliAdapter.CLAUDE_TUI_PAGE_POLL_INTERVAL_MS));
87994
88224
  const reread = await this.snapshotSettledClaudeTuiPage();
87995
88225
  const landed = pages[index - 1];
87996
- if (landed && !detectClaudeTuiMultiSelect(landed.screenText) && detectClaudeTuiMultiSelect(reread)) {
88226
+ if (landed && !detectClaudeTuiMultiSelect(landed.screenText) && detectClaudeTuiMultiSelect(reread) && this.claudeTuiPagesLookLikeSameQuestion(landed, reread)) {
87997
88227
  landed.screenText = reread;
87998
88228
  }
87999
88229
  }
@@ -101184,19 +101414,37 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
101184
101414
  }
101185
101415
  },
101186
101416
  // ─── MAGI kind → panel bindings (MAGI-KIND-PANEL, machine-local config) ───
101187
- // Per-task_kind slot lists in ~/.adhdev/meshes.json `magiKindPanels` — the SOLE
101188
- // MAGI panel-resolution surface (the former named-panel magi_panel_* handlers were
101189
- // removed). Owner-only gating: intentionally NOT listed in
101417
+ // Per-task_kind slot lists stored PER MESH in ~/.adhdev/meshes.json
101418
+ // (`meshes[].magiKindPanels`) — the SOLE MAGI panel-resolution surface (the former
101419
+ // named-panel magi_panel_* handlers were removed). `meshId` is optional on all three
101420
+ // so existing callers keep working: it resolves to the sole mesh on a single-mesh
101421
+ // machine, and is REQUIRED (loud error, never a silent pick) when several meshes
101422
+ // exist. Owner-only gating: intentionally NOT listed in
101190
101423
  // canPeerUsePrivilegedShareCommand (daemon-cloud data-channel-router), so a peer
101191
101424
  // holding ANY share permission hits its `default → false` branch — identical
101192
101425
  // owner-only gating to create_mesh / update_mesh / list_meshes. A trusted peer (no
101193
101426
  // permission = the owner) passes the top `!permission → true` guard. set/remove are
101194
101427
  // WRITE commands; list is read-only. normalizeMagiSlots (inside setMagiKindPanel)
101195
- // surfaces invalid_magi_kind_panel: … messages verbatim for the editor.
101196
- magi_kind_panel_list: async (_ctx, _args) => {
101428
+ // surfaces invalid_magi_kind_panel: … messages verbatim for the editor, including
101429
+ // a nodeId that is not a member of the target mesh.
101430
+ magi_kind_panel_list: async (_ctx, args) => {
101431
+ const requestedMeshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
101197
101432
  try {
101198
- const { listMagiKindPanels: listMagiKindPanels2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101199
- return { success: true, kindPanels: listMagiKindPanels2() };
101433
+ const { listMagiKindPanels: listMagiKindPanels2, resolveScopedMeshId: resolveScopedMeshId2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101434
+ const meshId = requestedMeshId || resolveScopedMeshId2();
101435
+ return {
101436
+ success: true,
101437
+ kindPanels: listMagiKindPanels2(requestedMeshId || void 0),
101438
+ scope: {
101439
+ kind: "mesh",
101440
+ storage: "machine_local",
101441
+ meshId: meshId ?? null,
101442
+ resolvedFrom: requestedMeshId ? "explicit" : meshId ? "sole_mesh" : "ambiguous",
101443
+ ...requestedMeshId || meshId ? {} : {
101444
+ note: "Several meshes are configured and no meshId was given, so no panels could be read. Pass meshId."
101445
+ }
101446
+ }
101447
+ };
101200
101448
  } catch (e) {
101201
101449
  return { success: false, error: e.message };
101202
101450
  }
@@ -101204,10 +101452,12 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
101204
101452
  magi_kind_panel_set: async (_ctx, args) => {
101205
101453
  const kind = typeof args?.kind === "string" ? args.kind.trim() : "";
101206
101454
  if (!kind) return { success: false, error: "invalid_magi_kind_panel: task_kind is required" };
101455
+ const requestedMeshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
101207
101456
  try {
101208
- const { setMagiKindPanel: setMagiKindPanel2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101209
- const slots = setMagiKindPanel2(kind, args?.slots);
101210
- return { success: true, kind, slots };
101457
+ const { setMagiKindPanel: setMagiKindPanel2, resolveScopedMeshId: resolveScopedMeshId2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101458
+ const slots = setMagiKindPanel2(kind, args?.slots, requestedMeshId || void 0);
101459
+ const meshId = requestedMeshId || resolveScopedMeshId2();
101460
+ return { success: true, kind, slots, meshId: meshId ?? null };
101211
101461
  } catch (e) {
101212
101462
  return { success: false, error: e.message };
101213
101463
  }
@@ -101215,30 +101465,52 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
101215
101465
  magi_kind_panel_remove: async (_ctx, args) => {
101216
101466
  const kind = typeof args?.kind === "string" ? args.kind.trim() : "";
101217
101467
  if (!kind) return { success: false, error: "invalid_magi_kind_panel: task_kind is required" };
101468
+ const requestedMeshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
101218
101469
  try {
101219
- const { removeMagiKindPanel: removeMagiKindPanel2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101220
- const removed = removeMagiKindPanel2(kind);
101221
- return { success: true, removed };
101470
+ const { removeMagiKindPanel: removeMagiKindPanel2, resolveScopedMeshId: resolveScopedMeshId2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101471
+ const removed = removeMagiKindPanel2(kind, requestedMeshId || void 0);
101472
+ const meshId = requestedMeshId || resolveScopedMeshId2();
101473
+ return { success: true, removed, meshId: meshId ?? null };
101222
101474
  } catch (e) {
101223
101475
  return { success: false, error: e.message };
101224
101476
  }
101225
101477
  },
101226
- // ─── Brain routing: per-difficulty brain presets (machine-local) ───
101227
- // getDifficultyBrains returns the seeded defaults when nothing is configured,
101228
- // so the editor always shows a usable mapping. set replaces the whole map.
101229
- difficulty_brains_get: async (_ctx, _args) => {
101478
+ // ─── Brain routing: per-difficulty brain presets (PER MESH, machine-local) ───
101479
+ // getDifficultyBrains returns the seeded defaults when the mesh has nothing
101480
+ // configured, so the editor always shows a usable mapping. set replaces the whole
101481
+ // map for ONE mesh. `meshId` is optional and resolves to the sole mesh, so
101482
+ // existing callers keep working; with several meshes a write must name its mesh
101483
+ // (these presets choose the model a task runs on — writing to the wrong mesh
101484
+ // changes what that mesh costs).
101485
+ difficulty_brains_get: async (_ctx, args) => {
101486
+ const requestedMeshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
101230
101487
  try {
101231
- const { getDifficultyBrains: getDifficultyBrains2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101232
- return { success: true, difficultyBrains: getDifficultyBrains2() };
101488
+ const { getDifficultyBrains: getDifficultyBrains2, resolveScopedMeshId: resolveScopedMeshId2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101489
+ const meshId = requestedMeshId || resolveScopedMeshId2();
101490
+ return {
101491
+ success: true,
101492
+ difficultyBrains: getDifficultyBrains2(requestedMeshId || void 0),
101493
+ scope: {
101494
+ kind: "mesh",
101495
+ storage: "machine_local",
101496
+ meshId: meshId ?? null,
101497
+ resolvedFrom: requestedMeshId ? "explicit" : meshId ? "sole_mesh" : "ambiguous",
101498
+ ...requestedMeshId || meshId ? {} : {
101499
+ note: "Several meshes are configured and no meshId was given, so these are the shipped defaults, not any mesh's saved presets. Pass meshId."
101500
+ }
101501
+ }
101502
+ };
101233
101503
  } catch (e) {
101234
101504
  return { success: false, error: e.message };
101235
101505
  }
101236
101506
  },
101237
101507
  difficulty_brains_set: async (_ctx, args) => {
101508
+ const requestedMeshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
101238
101509
  try {
101239
- const { setDifficultyBrains: setDifficultyBrains2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101240
- const difficultyBrains = setDifficultyBrains2(args?.difficultyBrains);
101241
- return { success: true, difficultyBrains };
101510
+ const { setDifficultyBrains: setDifficultyBrains2, resolveScopedMeshId: resolveScopedMeshId2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101511
+ const difficultyBrains = setDifficultyBrains2(args?.difficultyBrains, requestedMeshId || void 0);
101512
+ const meshId = requestedMeshId || resolveScopedMeshId2();
101513
+ return { success: true, difficultyBrains, meshId: meshId ?? null };
101242
101514
  } catch (e) {
101243
101515
  return { success: false, error: e.message };
101244
101516
  }
@@ -102889,10 +103161,10 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
102889
103161
  return void 0;
102890
103162
  }
102891
103163
  };
102892
- const loadMagiKindPanelsBestEffort = async () => {
103164
+ const loadMagiKindPanelsBestEffort = async (forMeshId) => {
102893
103165
  try {
102894
103166
  const { listMagiKindPanels: listMagiKindPanels2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
102895
- return listMagiKindPanels2();
103167
+ return listMagiKindPanels2(forMeshId);
102896
103168
  } catch {
102897
103169
  return void 0;
102898
103170
  }
@@ -102994,7 +103266,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
102994
103266
  if (coordinatorSetup.kind === "cli_command") {
102995
103267
  let cliCmdSystemPrompt = "";
102996
103268
  try {
102997
- cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh: effectiveMesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id), recentActivity: await buildRecentActivityBestEffort(mesh.id), operatingNotes: await buildEffectiveOperatingNotes(mesh.id), magiKindPanels: await loadMagiKindPanelsBestEffort() });
103269
+ cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh: effectiveMesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id), recentActivity: await buildRecentActivityBestEffort(mesh.id), operatingNotes: await buildEffectiveOperatingNotes(mesh.id), magiKindPanels: await loadMagiKindPanelsBestEffort(meshId) });
102998
103270
  } catch (error48) {
102999
103271
  const message = error48?.message || String(error48);
103000
103272
  LOG2.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
@@ -103191,7 +103463,7 @@ ${ptyResult.output.slice(-2e3)}`);
103191
103463
  }
103192
103464
  let systemPrompt = "";
103193
103465
  try {
103194
- systemPrompt = buildCoordinatorSystemPrompt2({ mesh: effectiveMesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id), recentActivity: await buildRecentActivityBestEffort(mesh.id), operatingNotes: await buildEffectiveOperatingNotes(mesh.id), magiKindPanels: await loadMagiKindPanelsBestEffort() });
103466
+ systemPrompt = buildCoordinatorSystemPrompt2({ mesh: effectiveMesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id), recentActivity: await buildRecentActivityBestEffort(mesh.id), operatingNotes: await buildEffectiveOperatingNotes(mesh.id), magiKindPanels: await loadMagiKindPanelsBestEffort(meshId) });
103195
103467
  } catch (error48) {
103196
103468
  const message = error48?.message || String(error48);
103197
103469
  LOG2.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
@@ -109175,6 +109447,32 @@ ${e?.stderr || ""}`;
109175
109447
  init_logger();
109176
109448
  init_runtime_defaults();
109177
109449
  init_snapshot();
109450
+ function buildCloudStatusReportPayload(sessions, p2p, timestamp2) {
109451
+ const list = Array.isArray(sessions) ? sessions : [];
109452
+ return {
109453
+ sessions: list.map((raw) => {
109454
+ const session = raw || {};
109455
+ return {
109456
+ id: session.id,
109457
+ parentId: session.parentId ?? null,
109458
+ providerType: session.providerType,
109459
+ providerName: session.providerName || session.providerType,
109460
+ kind: session.kind,
109461
+ transport: session.transport,
109462
+ status: session.status,
109463
+ workspace: session.workspace ?? null,
109464
+ cdpConnected: session.cdpConnected,
109465
+ // Forward surfaceHidden/muted so the server can gate push notifications
109466
+ // for coordinator-hidden and user-muted sessions (the WS path is the
109467
+ // only one the server sees). Both are plain booleans, not content.
109468
+ surfaceHidden: session.surfaceHidden,
109469
+ muted: session.muted
109470
+ };
109471
+ }),
109472
+ p2p,
109473
+ timestamp: timestamp2
109474
+ };
109475
+ }
109178
109476
  var DaemonStatusReporter = class {
109179
109477
  deps;
109180
109478
  log;
@@ -109388,28 +109686,7 @@ ${e?.stderr || ""}`;
109388
109686
  }
109389
109687
  if (opts?.p2pOnly) return;
109390
109688
  if (!serverConnected || !serverConn) return;
109391
- const payloadSessions = Array.isArray(payload.sessions) ? payload.sessions : [];
109392
- const wsPayload = {
109393
- sessions: payloadSessions.map((session) => ({
109394
- id: session.id,
109395
- parentId: session.parentId,
109396
- providerType: session.providerType,
109397
- providerName: session.providerName || session.providerType,
109398
- kind: session.kind,
109399
- transport: session.transport,
109400
- status: session.status,
109401
- workspace: session.workspace ?? null,
109402
- title: session.title,
109403
- cdpConnected: session.cdpConnected,
109404
- summaryMetadata: session.summaryMetadata,
109405
- settings: session.settings,
109406
- // Forward surfaceHidden so the server can gate push notifications for
109407
- // coordinator-hidden sessions (the WS path is the only one the server sees).
109408
- surfaceHidden: session.surfaceHidden
109409
- })),
109410
- p2p: payload.p2p,
109411
- timestamp: now
109412
- };
109689
+ const wsPayload = buildCloudStatusReportPayload(payload.sessions, payload.p2p, now);
109413
109690
  const wsHash = this.simpleHash(JSON.stringify({
109414
109691
  ...wsPayload,
109415
109692
  timestamp: void 0