@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 +376 -99
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/public/assets/{index-Dm68eVOH.js → index-B83k8HUW.js} +42 -42
- package/public/assets/{terminal-BZj_X5zy.js → terminal-DiXj2eIR.js} +1 -1
- package/public/assets/{vendor-cL4V2vaO.js → vendor-DyCWA2YZ.js} +57 -49
- package/public/index.html +2 -2
- package/vendor/mcp-server/index.js +54 -18
- package/vendor/mcp-server/index.js.map +1 -1
- package/vendor/session-host-daemon/index.js +0 -0
- package/vendor/session-host-daemon/index.mjs +0 -0
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 ? "
|
|
33315
|
-
const commitShort = readInjected(true ? "
|
|
33316
|
-
const version2 = readInjected(true ? "1.0.
|
|
33317
|
-
const builtAt = readInjected(true ? "2026-
|
|
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
|
|
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
|
-
|
|
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
|
|
36729
|
-
|
|
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
|
|
36732
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
36762
|
-
|
|
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
|
|
36767
|
-
const
|
|
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
|
-
|
|
36775
|
-
|
|
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
|
|
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
|
|
101188
|
-
// MAGI panel-resolution surface (the former
|
|
101189
|
-
// removed).
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
101228
|
-
// so the editor always shows a usable mapping. set replaces the whole
|
|
101229
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|