@adhdev/daemon-core 0.9.82-rc.508 → 0.9.82-rc.509
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/config/mesh-config.d.ts +12 -0
- package/dist/index.js +246 -80
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +246 -80
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-node-slots.d.ts +22 -0
- package/dist/mesh/mesh-runtime-store.d.ts +2 -2
- package/dist/mesh/mesh-scheduling-runtime.d.ts +5 -1
- package/dist/mesh/mesh-work-queue.d.ts +3 -3
- package/dist/providers/cli-provider-instance-types.d.ts +1 -0
- package/dist/providers/cli-provider-instance.d.ts +54 -0
- package/dist/repo-mesh-types.d.ts +30 -29
- package/package.json +3 -3
- package/src/commands/med-family/mesh-crud.ts +24 -14
- package/src/config/mesh-config.ts +71 -24
- package/src/mesh/coordinator-prompt.ts +19 -14
- package/src/mesh/mesh-node-slots.ts +52 -0
- package/src/mesh/mesh-queue-assignment.ts +23 -23
- package/src/mesh/mesh-runtime-store.ts +3 -3
- package/src/mesh/mesh-scheduling-runtime.ts +24 -9
- package/src/mesh/mesh-work-queue.ts +3 -3
- package/src/providers/cli-provider-instance-types.ts +15 -0
- package/src/providers/cli-provider-instance.ts +174 -2
- package/src/repo-mesh-types.ts +39 -38
|
@@ -7,6 +7,18 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { LocalMeshEntry, LocalMeshNodeEntry, RepoMeshPolicy, RepoMeshNodePolicy, RepoMeshNodeCapabilities, RepoMeshCoordinatorConfig, RepoMeshHostMetadata, RepoMeshDaemonRole } from '../repo-mesh-types.js';
|
|
9
9
|
import type { MagiKindPanelMap, MagiSlot, DifficultyBrainMap } from '@adhdev/mesh-shared';
|
|
10
|
+
/**
|
|
11
|
+
* Migrate a node policy's legacy `providerRoles` cap onto `slots[].maxParallel`,
|
|
12
|
+
* in place, then delete the `providerRoles` field. Defensive against malformed
|
|
13
|
+
* entries. Returns true when the policy was mutated.
|
|
14
|
+
*
|
|
15
|
+
* Behavior-preserving: the resulting slots carry the same per-(node, provider)
|
|
16
|
+
* cap the queue previously enforced from providerRoles. When the node had no
|
|
17
|
+
* explicit slots, slots are derived from the legacy providerPriority (folding the
|
|
18
|
+
* caps in via deriveSlotsFromLegacy-equivalent logic); when it did, each cap is
|
|
19
|
+
* merged into the first matching-provider slot lacking a maxParallel.
|
|
20
|
+
*/
|
|
21
|
+
export declare function migrateProviderRolesToSlots(policy: unknown): boolean;
|
|
10
22
|
export declare function normalizeCapabilityTags(value: unknown): string[] | undefined;
|
|
11
23
|
/**
|
|
12
24
|
* Normalize a Git remote URL into a stable identity string.
|
package/dist/index.js
CHANGED
|
@@ -122,20 +122,20 @@ function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy) {
|
|
|
122
122
|
}
|
|
123
123
|
return true;
|
|
124
124
|
}
|
|
125
|
-
function resolveProviderMaxParallel(
|
|
125
|
+
function resolveProviderMaxParallel(slots, providerType) {
|
|
126
126
|
const wanted = typeof providerType === "string" ? providerType.trim().toLowerCase() : "";
|
|
127
127
|
if (!wanted) return void 0;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
for (const
|
|
131
|
-
if (!
|
|
132
|
-
const type = typeof
|
|
128
|
+
if (!Array.isArray(slots)) return void 0;
|
|
129
|
+
let total;
|
|
130
|
+
for (const slot of slots) {
|
|
131
|
+
if (!slot || typeof slot !== "object") continue;
|
|
132
|
+
const type = typeof slot.provider === "string" ? slot.provider.trim().toLowerCase() : "";
|
|
133
133
|
if (!type || type !== wanted) continue;
|
|
134
|
-
const raw = Number(
|
|
135
|
-
if (!Number.isFinite(raw) || raw < 0)
|
|
136
|
-
|
|
134
|
+
const raw = Number(slot.maxParallel);
|
|
135
|
+
if (!Number.isFinite(raw) || raw < 0) continue;
|
|
136
|
+
total = (total ?? 0) + Math.floor(raw);
|
|
137
137
|
}
|
|
138
|
-
return
|
|
138
|
+
return total;
|
|
139
139
|
}
|
|
140
140
|
var MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, DEFAULT_MESH_POLICY, SESSION_CLEANUP_MODES, SPAWNED_SESSION_VISIBILITY_MODES, DIRTY_WORKSPACE_BEHAVIORS, MESH_MAX_PARALLEL_TASKS_MIN, MESH_MAX_PARALLEL_TASKS_MAX, DEFAULT_MESH_READONLY_MULTIPLIER;
|
|
141
141
|
var init_repo_mesh_types = __esm({
|
|
@@ -417,10 +417,10 @@ function readInjected(value) {
|
|
|
417
417
|
}
|
|
418
418
|
function getDaemonBuildInfo() {
|
|
419
419
|
if (cached) return cached;
|
|
420
|
-
const commit = readInjected(true ? "
|
|
421
|
-
const commitShort = readInjected(true ? "
|
|
422
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
423
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
420
|
+
const commit = readInjected(true ? "8ebe4d4bcdc658e11253a51a28237d392aa4d978" : void 0) ?? "unknown";
|
|
421
|
+
const commitShort = readInjected(true ? "8ebe4d4b" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
422
|
+
const version = readInjected(true ? "0.9.82-rc.509" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
423
|
+
const builtAt = readInjected(true ? "2026-07-13T02:51:57.282Z" : void 0);
|
|
424
424
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
425
425
|
return cached;
|
|
426
426
|
}
|
|
@@ -2848,12 +2848,6 @@ function normalizeNodeCapabilitySlots(raw) {
|
|
|
2848
2848
|
function deriveSlotsFromLegacy(input) {
|
|
2849
2849
|
const priority = Array.isArray(input.providerPriority) ? input.providerPriority.filter((p) => typeof p === "string" && !!p.trim()).map((p) => p.trim()) : [];
|
|
2850
2850
|
if (priority.length === 0) return [];
|
|
2851
|
-
const roleCap = /* @__PURE__ */ new Map();
|
|
2852
|
-
for (const role of input.providerRoles || []) {
|
|
2853
|
-
if (role && typeof role.providerType === "string" && Number.isFinite(role.maxParallel)) {
|
|
2854
|
-
roleCap.set(role.providerType.trim(), Math.floor(Number(role.maxParallel)));
|
|
2855
|
-
}
|
|
2856
|
-
}
|
|
2857
2851
|
const brains = input.difficultyBrains || {};
|
|
2858
2852
|
const byProvider = /* @__PURE__ */ new Map();
|
|
2859
2853
|
const shared = [];
|
|
@@ -2875,13 +2869,11 @@ function deriveSlotsFromLegacy(input) {
|
|
|
2875
2869
|
const difficulty = applied.map((a) => a.difficulty);
|
|
2876
2870
|
const model = applied.find((a) => a.model)?.model;
|
|
2877
2871
|
const thinkingLevel = applied.find((a) => a.thinkingLevel)?.thinkingLevel;
|
|
2878
|
-
const maxParallel = roleCap.get(provider);
|
|
2879
2872
|
return {
|
|
2880
2873
|
provider,
|
|
2881
2874
|
...model ? { model } : {},
|
|
2882
2875
|
...thinkingLevel ? { thinkingLevel } : {},
|
|
2883
|
-
...difficulty.length ? { difficulty } : {}
|
|
2884
|
-
...maxParallel !== void 0 ? { maxParallel } : {}
|
|
2876
|
+
...difficulty.length ? { difficulty } : {}
|
|
2885
2877
|
};
|
|
2886
2878
|
});
|
|
2887
2879
|
}
|
|
@@ -3049,6 +3041,7 @@ __export(mesh_config_exports, {
|
|
|
3049
3041
|
listMagiKindPanels: () => listMagiKindPanels,
|
|
3050
3042
|
listMeshes: () => listMeshes,
|
|
3051
3043
|
markMeshHostPairingJoined: () => markMeshHostPairingJoined,
|
|
3044
|
+
migrateProviderRolesToSlots: () => migrateProviderRolesToSlots,
|
|
3052
3045
|
normalizeCapabilityTags: () => normalizeCapabilityTags,
|
|
3053
3046
|
normalizeMagiSlots: () => normalizeMagiSlots,
|
|
3054
3047
|
normalizeRepoIdentity: () => normalizeRepoIdentity,
|
|
@@ -3087,23 +3080,51 @@ function migrateLoadedMeshConfig(config) {
|
|
|
3087
3080
|
for (const mesh of config.meshes) {
|
|
3088
3081
|
if (!mesh || !Array.isArray(mesh.nodes)) continue;
|
|
3089
3082
|
for (const node of mesh.nodes) {
|
|
3090
|
-
if (
|
|
3083
|
+
if (migrateProviderRolesToSlots(node?.policy)) changed = true;
|
|
3091
3084
|
}
|
|
3092
3085
|
}
|
|
3093
3086
|
return changed;
|
|
3094
3087
|
}
|
|
3095
|
-
function
|
|
3096
|
-
if (!policy || typeof policy !== "object") return false;
|
|
3097
|
-
const
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3088
|
+
function migrateProviderRolesToSlots(policy) {
|
|
3089
|
+
if (!policy || typeof policy !== "object" || Array.isArray(policy)) return false;
|
|
3090
|
+
const p = policy;
|
|
3091
|
+
const rawRoles = p.providerRoles;
|
|
3092
|
+
if (!Array.isArray(rawRoles)) return false;
|
|
3093
|
+
const roleCap = /* @__PURE__ */ new Map();
|
|
3094
|
+
for (const entry of rawRoles) {
|
|
3095
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
3096
|
+
const rec = entry;
|
|
3097
|
+
const provider = typeof rec.providerType === "string" ? rec.providerType.trim() : "";
|
|
3098
|
+
if (!provider) continue;
|
|
3099
|
+
const cap = Number(rec.maxParallel);
|
|
3100
|
+
if (!Number.isFinite(cap) || cap < 0) continue;
|
|
3101
|
+
roleCap.set(provider.toLowerCase(), { provider, cap: Math.floor(cap) });
|
|
3102
|
+
}
|
|
3103
|
+
const explicitSlots = Array.isArray(p.slots) ? normalizeNodeCapabilitySlots(p.slots) : [];
|
|
3104
|
+
if (explicitSlots.length) {
|
|
3105
|
+
for (const { provider, cap } of roleCap.values()) {
|
|
3106
|
+
const target = explicitSlots.find((s2) => s2.provider.trim().toLowerCase() === provider.toLowerCase() && s2.maxParallel === void 0);
|
|
3107
|
+
if (target) target.maxParallel = cap;
|
|
3108
|
+
}
|
|
3109
|
+
p.slots = explicitSlots;
|
|
3110
|
+
} else if (roleCap.size) {
|
|
3111
|
+
let difficultyBrains;
|
|
3112
|
+
try {
|
|
3113
|
+
difficultyBrains = getDifficultyBrains();
|
|
3114
|
+
} catch {
|
|
3115
|
+
difficultyBrains = void 0;
|
|
3116
|
+
}
|
|
3117
|
+
const priority = Array.isArray(p.providerPriority) ? p.providerPriority.map((t) => typeof t === "string" ? t.trim() : "").filter(Boolean) : [];
|
|
3118
|
+
const derived = deriveSlotsFromLegacy({ providerPriority: priority, difficultyBrains });
|
|
3119
|
+
const slots = derived.length ? derived : [...roleCap.values()].map((r) => ({ provider: r.provider }));
|
|
3120
|
+
for (const slot of slots) {
|
|
3121
|
+
const match = roleCap.get(slot.provider.trim().toLowerCase());
|
|
3122
|
+
if (match && slot.maxParallel === void 0) slot.maxParallel = match.cap;
|
|
3104
3123
|
}
|
|
3124
|
+
p.slots = slots;
|
|
3105
3125
|
}
|
|
3106
|
-
|
|
3126
|
+
delete p.providerRoles;
|
|
3127
|
+
return true;
|
|
3107
3128
|
}
|
|
3108
3129
|
function normalizeCapabilityTags(value) {
|
|
3109
3130
|
if (!Array.isArray(value)) return void 0;
|
|
@@ -3561,6 +3582,39 @@ var init_mesh_config = __esm({
|
|
|
3561
3582
|
}
|
|
3562
3583
|
});
|
|
3563
3584
|
|
|
3585
|
+
// src/mesh/mesh-node-slots.ts
|
|
3586
|
+
function normalizeProviderPriority(policy) {
|
|
3587
|
+
const raw = policy && typeof policy === "object" && !Array.isArray(policy) ? policy.providerPriority : void 0;
|
|
3588
|
+
if (!Array.isArray(raw)) return [];
|
|
3589
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3590
|
+
return raw.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean).filter((type) => {
|
|
3591
|
+
if (seen.has(type)) return false;
|
|
3592
|
+
seen.add(type);
|
|
3593
|
+
return true;
|
|
3594
|
+
});
|
|
3595
|
+
}
|
|
3596
|
+
function resolveNodeCapabilitySlots(node) {
|
|
3597
|
+
const explicit = normalizeNodeCapabilitySlots(node?.policy?.slots);
|
|
3598
|
+
if (explicit.length) return explicit;
|
|
3599
|
+
let difficultyBrains;
|
|
3600
|
+
try {
|
|
3601
|
+
difficultyBrains = getDifficultyBrains();
|
|
3602
|
+
} catch {
|
|
3603
|
+
difficultyBrains = void 0;
|
|
3604
|
+
}
|
|
3605
|
+
return deriveSlotsFromLegacy({
|
|
3606
|
+
providerPriority: normalizeProviderPriority(node?.policy),
|
|
3607
|
+
difficultyBrains
|
|
3608
|
+
});
|
|
3609
|
+
}
|
|
3610
|
+
var init_mesh_node_slots = __esm({
|
|
3611
|
+
"src/mesh/mesh-node-slots.ts"() {
|
|
3612
|
+
"use strict";
|
|
3613
|
+
init_dist();
|
|
3614
|
+
init_mesh_config();
|
|
3615
|
+
}
|
|
3616
|
+
});
|
|
3617
|
+
|
|
3564
3618
|
// src/mesh/coordinator-prompt.ts
|
|
3565
3619
|
var coordinator_prompt_exports = {};
|
|
3566
3620
|
__export(coordinator_prompt_exports, {
|
|
@@ -3744,13 +3798,20 @@ function buildNodeConfigSection(mesh) {
|
|
|
3744
3798
|
const explicitMachineLabel = typeof n.machineLabel === "string" ? n.machineLabel : "";
|
|
3745
3799
|
const explicitLabel = explicitMachineLabel ? ` label: **${explicitMachineLabel}** |` : "";
|
|
3746
3800
|
const providerPriority = n.policy?.providerPriority?.length ? ` | providers: ${n.policy.providerPriority.join(", ")}` : "";
|
|
3747
|
-
const
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3801
|
+
const nodeSlots = resolveNodeCapabilitySlots(n);
|
|
3802
|
+
const seenCapProvider = /* @__PURE__ */ new Set();
|
|
3803
|
+
const providerCaps = [];
|
|
3804
|
+
for (const slot of nodeSlots) {
|
|
3805
|
+
const type = typeof slot?.provider === "string" ? slot.provider.trim() : "";
|
|
3806
|
+
if (!type) continue;
|
|
3807
|
+
const key2 = type.toLowerCase();
|
|
3808
|
+
if (seenCapProvider.has(key2)) continue;
|
|
3809
|
+
seenCapProvider.add(key2);
|
|
3810
|
+
const cap = resolveProviderMaxParallel(nodeSlots, type);
|
|
3811
|
+
if (cap === void 0) continue;
|
|
3812
|
+
providerCaps.push(`${type} (max ${cap})`);
|
|
3813
|
+
}
|
|
3814
|
+
const providerRolesSuffix = providerCaps.length ? ` | caps: ${providerCaps.join(", ")}` : "";
|
|
3754
3815
|
lines.push(`- ${explicitLabel} nodeId: \`${n.id}\` | workspace: \`${n.workspace}\`${n.daemonId ? ` | daemon: \`${n.daemonId}\`` : ""}${providerPriority}${providerRolesSuffix}${suffix}`);
|
|
3755
3816
|
const routingTags = [];
|
|
3756
3817
|
const custom = Array.isArray(n.capabilities) ? n.capabilities : [];
|
|
@@ -3962,6 +4023,7 @@ var init_coordinator_prompt = __esm({
|
|
|
3962
4023
|
path8 = __toESM(require("path"));
|
|
3963
4024
|
init_repo_mesh_types();
|
|
3964
4025
|
init_mesh_config();
|
|
4026
|
+
init_mesh_node_slots();
|
|
3965
4027
|
init_dist();
|
|
3966
4028
|
PROMPT_SOFT_CAP_BYTES = 60 * 1024;
|
|
3967
4029
|
OPERATING_NOTES_PROMPT_CAP = 20;
|
|
@@ -7163,8 +7225,8 @@ var init_mesh_runtime_store = __esm({
|
|
|
7163
7225
|
/**
|
|
7164
7226
|
* Count active (status='assigned') tasks on a (node, provider) combination,
|
|
7165
7227
|
* matched by the assignedProviderType stamped on the payload at claim time.
|
|
7166
|
-
* Drives the per-(node, provider) maxParallel cap (
|
|
7167
|
-
*
|
|
7228
|
+
* Drives the per-(node, provider) maxParallel cap (summed across a provider's
|
|
7229
|
+
* slots[].maxParallel). The active-assignment set for a single node is tiny, so
|
|
7168
7230
|
* parsing payloads here is cheap and avoids a schema migration. Pre-cap legacy
|
|
7169
7231
|
* rows (no provider stamp) and other providers on the same node do not consume
|
|
7170
7232
|
* this provider's budget, so the cap is fully backward compatible.
|
|
@@ -12914,15 +12976,22 @@ function buildMeshSchedulingRuntime(mesh, queue) {
|
|
|
12914
12976
|
if (globalWriteCapReached) capReasons.push("global_max_parallel_tasks_reached");
|
|
12915
12977
|
if ((writeAssignedByNode.get(nodeId) ?? 0) > 0) capReasons.push("node_has_active_assignment");
|
|
12916
12978
|
let providerRoles;
|
|
12917
|
-
const
|
|
12918
|
-
|
|
12979
|
+
const slots = resolveNodeCapabilitySlots(rawNode);
|
|
12980
|
+
const cappedProviders = [];
|
|
12981
|
+
const seenProvider = /* @__PURE__ */ new Set();
|
|
12982
|
+
for (const slot of slots) {
|
|
12983
|
+
const providerType = typeof slot?.provider === "string" ? slot.provider.trim() : "";
|
|
12984
|
+
if (!providerType) continue;
|
|
12985
|
+
const key2 = providerType.toLowerCase();
|
|
12986
|
+
if (seenProvider.has(key2)) continue;
|
|
12987
|
+
seenProvider.add(key2);
|
|
12988
|
+
if (resolveProviderMaxParallel(slots, providerType) !== void 0) cappedProviders.push(providerType);
|
|
12989
|
+
}
|
|
12990
|
+
if (cappedProviders.length) {
|
|
12919
12991
|
const byProvider = providerCountByNode.get(nodeId);
|
|
12920
12992
|
providerRoles = [];
|
|
12921
|
-
for (const
|
|
12922
|
-
|
|
12923
|
-
const providerType = typeof role.providerType === "string" ? role.providerType.trim() : "";
|
|
12924
|
-
if (!providerType) continue;
|
|
12925
|
-
const maxParallel = resolveProviderMaxParallel(policy, providerType);
|
|
12993
|
+
for (const providerType of cappedProviders) {
|
|
12994
|
+
const maxParallel = resolveProviderMaxParallel(slots, providerType);
|
|
12926
12995
|
const activeAssigned = byProvider?.get(providerType) ?? 0;
|
|
12927
12996
|
const capReached = maxParallel !== void 0 && activeAssigned >= maxParallel;
|
|
12928
12997
|
providerRoles.push({
|
|
@@ -12963,6 +13032,7 @@ var init_mesh_scheduling_runtime = __esm({
|
|
|
12963
13032
|
"use strict";
|
|
12964
13033
|
init_repo_mesh_types();
|
|
12965
13034
|
init_dist();
|
|
13035
|
+
init_mesh_node_slots();
|
|
12966
13036
|
init_mesh_work_queue();
|
|
12967
13037
|
}
|
|
12968
13038
|
});
|
|
@@ -15777,7 +15847,7 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
|
|
|
15777
15847
|
return false;
|
|
15778
15848
|
}
|
|
15779
15849
|
const capabilityTags = buildMeshNodeCapabilityTags(node, providerType);
|
|
15780
|
-
const providerMaxParallel = resolveProviderMaxParallel(node
|
|
15850
|
+
const providerMaxParallel = resolveProviderMaxParallel(resolveNodeCapabilitySlots(node), providerType);
|
|
15781
15851
|
const nodeIsWorktree = node?.isLocalWorktree === true;
|
|
15782
15852
|
const task = claimNextTask(meshId, nodeId, sessionId, capabilityTags, {
|
|
15783
15853
|
providerType,
|
|
@@ -16035,7 +16105,7 @@ function sweepExpiredCooldowns() {
|
|
|
16035
16105
|
if (now >= until) autoLaunchCooldownUntil.delete(key2);
|
|
16036
16106
|
}
|
|
16037
16107
|
}
|
|
16038
|
-
function
|
|
16108
|
+
function normalizeProviderPriority2(policy) {
|
|
16039
16109
|
const raw = policy && typeof policy === "object" && !Array.isArray(policy) ? policy.providerPriority : void 0;
|
|
16040
16110
|
if (!Array.isArray(raw)) return [];
|
|
16041
16111
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -16149,21 +16219,6 @@ function buildSchedulingPool(localCandidates, remoteCandidates) {
|
|
|
16149
16219
|
}));
|
|
16150
16220
|
return { pool, uniqueNodes };
|
|
16151
16221
|
}
|
|
16152
|
-
function resolveNodeCapabilitySlots(node) {
|
|
16153
|
-
const explicit = normalizeNodeCapabilitySlots(node?.policy?.slots);
|
|
16154
|
-
if (explicit.length) return explicit;
|
|
16155
|
-
let difficultyBrains;
|
|
16156
|
-
try {
|
|
16157
|
-
difficultyBrains = getDifficultyBrains();
|
|
16158
|
-
} catch {
|
|
16159
|
-
difficultyBrains = void 0;
|
|
16160
|
-
}
|
|
16161
|
-
return deriveSlotsFromLegacy({
|
|
16162
|
-
providerPriority: normalizeProviderPriority(node?.policy),
|
|
16163
|
-
providerRoles: Array.isArray(node?.policy?.providerRoles) ? node.policy.providerRoles : void 0,
|
|
16164
|
-
difficultyBrains
|
|
16165
|
-
});
|
|
16166
|
-
}
|
|
16167
16222
|
function scoreSlotForTask(slot, task) {
|
|
16168
16223
|
let score = 1;
|
|
16169
16224
|
const diff = isMeshTaskDifficulty(task.difficulty) ? task.difficulty : void 0;
|
|
@@ -16290,6 +16345,7 @@ function nodeHasLiveSessionPendingClaim(components, meshId, nodeId) {
|
|
|
16290
16345
|
const state = inst.getState();
|
|
16291
16346
|
const settings = state.settings || {};
|
|
16292
16347
|
if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
|
|
16348
|
+
if (readNonEmptyString2(settings.meshCoordinatorFor) === meshId) return false;
|
|
16293
16349
|
const instNodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
|
|
16294
16350
|
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
16295
16351
|
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
@@ -16494,7 +16550,7 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
16494
16550
|
if (task.targetNodeId && !meshNodeIdMatches(node, task.targetNodeId)) return false;
|
|
16495
16551
|
if (task.taskMode === "convergence" && node?.isLocalWorktree === true) return false;
|
|
16496
16552
|
if (task.requiredTags?.length) {
|
|
16497
|
-
const priorities =
|
|
16553
|
+
const priorities = normalizeProviderPriority2(node?.policy);
|
|
16498
16554
|
const providerCandidates = priorities.length ? priorities : [void 0];
|
|
16499
16555
|
return providerCandidates.some(
|
|
16500
16556
|
(p) => nodeSatisfiesRequiredTags(task.requiredTags, buildMeshNodeCapabilityTags(node, p))
|
|
@@ -16581,7 +16637,7 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
16581
16637
|
if (rawEffectiveModel && effectiveModel === void 0) {
|
|
16582
16638
|
LOG.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`);
|
|
16583
16639
|
}
|
|
16584
|
-
const providerCap = resolveProviderMaxParallel(node
|
|
16640
|
+
const providerCap = resolveProviderMaxParallel(resolveNodeCapabilitySlots(node), resolved.providerType);
|
|
16585
16641
|
if (providerCap !== void 0 && activeProviderAssignedCount(meshId, nodeId, resolved.providerType) >= providerCap) {
|
|
16586
16642
|
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "max_provider_parallel_reached", nodeId, providerType: resolved.providerType });
|
|
16587
16643
|
continue;
|
|
@@ -16905,6 +16961,7 @@ var init_mesh_queue_assignment = __esm({
|
|
|
16905
16961
|
init_mesh_warmup_deadline();
|
|
16906
16962
|
init_repo_mesh_types();
|
|
16907
16963
|
init_dist();
|
|
16964
|
+
init_mesh_node_slots();
|
|
16908
16965
|
init_mesh_events_stale();
|
|
16909
16966
|
init_mesh_events_utils();
|
|
16910
16967
|
init_mesh_node_identity();
|
|
@@ -45761,6 +45818,7 @@ var STATUS_HYDRATION_TAIL_LIMIT = 200;
|
|
|
45761
45818
|
var COMPLETED_FINALIZATION_RETRY_MS = 1e3;
|
|
45762
45819
|
var COMPLETED_FINALIZATION_MAX_WAIT_MS = 3e4;
|
|
45763
45820
|
var NATIVE_HISTORY_MESH_IDLE_SETTLE_MS = 4e3;
|
|
45821
|
+
var PTY_PARSED_FINAL_ASSISTANT_QUIET_DWELL_MS = 1200;
|
|
45764
45822
|
var BACKGROUND_TASK_HOLD_MAX_MS = 5 * 6e4;
|
|
45765
45823
|
var USER_INPUT_ACK_DEDUP_WINDOW_MS = 6e4;
|
|
45766
45824
|
var STARTUP_GRACE_IDLE_COLLAPSE_WINDOW_MS = 12e3;
|
|
@@ -46003,6 +46061,39 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
46003
46061
|
* the nudge was NOT deferred) and leaked to the coordinator.
|
|
46004
46062
|
*/
|
|
46005
46063
|
static AUTO_APPROVE_MASK_STALL_MS = 10500;
|
|
46064
|
+
/**
|
|
46065
|
+
* AUTOAPPROVE-FLAP-INBOX-MISSING: sticky-approval overlay window. Same time-tick
|
|
46066
|
+
* hold idea as the FALSE-IDLE completion gate — an approval signal that was
|
|
46067
|
+
* DOMINANT within this recent window is re-presented across a momentary busy blip
|
|
46068
|
+
* instead of collapsing.
|
|
46069
|
+
*
|
|
46070
|
+
* RCA (live 2026-07-13): a claude-cli worker sitting at a Bash approval modal
|
|
46071
|
+
* ("Do you want to proceed? ❯1.Yes") flaps waiting_approval↔busy on a ~2-3s period.
|
|
46072
|
+
* The spec `approval→busy` transition fires whenever the footer/modal approval
|
|
46073
|
+
* markers momentarily drop out of their parsed sections while the PRIOR command's
|
|
46074
|
+
* residual spinner text ("✳ Checking vendor drift…") still matches the busy regex.
|
|
46075
|
+
* On the busy frame the adapter reports status='generating', activeModal=null. That
|
|
46076
|
+
* corrupts THREE consumers at once: (1) mesh_active_work samples 'generating' →
|
|
46077
|
+
* collectPendingApprovals never sees 'awaiting_approval' → mesh_list_pending_approvals
|
|
46078
|
+
* count:0 (inbox miss); (2) the auto-approve settle gate is torn down each busy phase
|
|
46079
|
+
* so the 600ms settle never accrues → auto-approve never fires; (3) a mesh_approve
|
|
46080
|
+
* landing on a busy frame hits "Not in approval state". The existing FLAP machinery
|
|
46081
|
+
* (AUTO_APPROVE_FLAP_CONTINUITY_MS) only keeps the settle gate warm while status is
|
|
46082
|
+
* STILL waiting_approval (buttons scrolled out) — it does nothing once the FSM fully
|
|
46083
|
+
* commits to 'busy', and it never stabilises the status the inbox samples.
|
|
46084
|
+
*
|
|
46085
|
+
* Fix: when the raw adapter status flaps to generating/busy/idle but a
|
|
46086
|
+
* waiting_approval WITH a concrete modal was observed within this window, overlay
|
|
46087
|
+
* the cached modal and report status='waiting_approval'. This stabilized status
|
|
46088
|
+
* feeds getState (→ inbox), detectStatusTransition (→ event emission), and
|
|
46089
|
+
* maybeAutoApproveStatus (→ settle gate) uniformly, so the approval both registers
|
|
46090
|
+
* in the inbox and settles for auto-approve across the flap. Bounded (a genuine
|
|
46091
|
+
* resume that never returns to approval unmasks after this window) and scoped at the
|
|
46092
|
+
* call site to autonomous mesh sessions. 4000ms bridges the observed ~2-3s flap with
|
|
46093
|
+
* margin while staying well under AUTO_APPROVE_MASK_STALL_MS (a truly stalled/absent
|
|
46094
|
+
* approval still surfaces).
|
|
46095
|
+
*/
|
|
46096
|
+
static APPROVAL_STICKY_FLAP_MS = 4e3;
|
|
46006
46097
|
/**
|
|
46007
46098
|
* FALSE-IDLE (inter-approval quiet valley): grace window after an auto-approve
|
|
46008
46099
|
* (or mesh_approve) RESOLVES a modal during which a subsequent generating→idle
|
|
@@ -46106,6 +46197,14 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
46106
46197
|
// signature) while a genuinely closed modal — buttons empty continuously past
|
|
46107
46198
|
// the continuity window — is still recognised and resets the gate.
|
|
46108
46199
|
autoApproveLastModalSeenAt = 0;
|
|
46200
|
+
// AUTOAPPROVE-FLAP-INBOX-MISSING sticky-approval overlay (see APPROVAL_STICKY_FLAP_MS).
|
|
46201
|
+
// The wall-clock of the last frame where the RAW adapter reported waiting_approval with
|
|
46202
|
+
// a CONCRETE modal (buttons present), the cached modal to re-present across a busy blip,
|
|
46203
|
+
// and the approvalEntrySeq at that frame (so a stabilized frame carries the right seq to
|
|
46204
|
+
// the emission-dedup fingerprint). All zero/null when no recent concrete approval.
|
|
46205
|
+
approvalStickyLastConcreteAt = 0;
|
|
46206
|
+
approvalStickyModal = null;
|
|
46207
|
+
approvalStickyEntrySeq = 0;
|
|
46109
46208
|
// STATUS-MISMATCH: wall-clock when the CURRENT auto-approve episode (waiting_approval
|
|
46110
46209
|
// + shouldAutoApprove) first began wanting to mask. Unlike pendingAutoApprovalSince it
|
|
46111
46210
|
// is NOT reset when the modal signature changes (a still-streaming/flapping prompt) and
|
|
@@ -46247,7 +46346,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
46247
46346
|
}
|
|
46248
46347
|
}
|
|
46249
46348
|
getState() {
|
|
46250
|
-
const adapterStatus = this.adapter.getStatus();
|
|
46349
|
+
const adapterStatus = this.stabilizeFlappingApprovalStatus(this.adapter.getStatus());
|
|
46251
46350
|
if (Object.prototype.hasOwnProperty.call(adapterStatus, "activeInteractivePrompt")) {
|
|
46252
46351
|
this.activeInteractivePrompt = adapterStatus.activeInteractivePrompt ?? null;
|
|
46253
46352
|
}
|
|
@@ -47111,6 +47210,9 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
47111
47210
|
return null;
|
|
47112
47211
|
}
|
|
47113
47212
|
if (this.type === "antigravity-cli") {
|
|
47213
|
+
if (allowMissingAssistantTimeout) {
|
|
47214
|
+
return { reason: "missing_final_assistant", terminal: false, holdForTranscript: true };
|
|
47215
|
+
}
|
|
47114
47216
|
return null;
|
|
47115
47217
|
}
|
|
47116
47218
|
if (allowMissingAssistantTimeout && pending.previousStatus === "waiting_approval") {
|
|
@@ -47142,6 +47244,19 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
47142
47244
|
}
|
|
47143
47245
|
} catch {
|
|
47144
47246
|
}
|
|
47247
|
+
if (allowMissingAssistantTimeout && !adapterOwnsMessagesElsewhere && finalAssistantEvidence.source === "parsed") {
|
|
47248
|
+
try {
|
|
47249
|
+
const outStatus = this.adapter.getStatus({ allowParse: false });
|
|
47250
|
+
const lastOutputAt = typeof outStatus?.lastOutputAt === "number" && Number.isFinite(outStatus.lastOutputAt) ? outStatus.lastOutputAt : void 0;
|
|
47251
|
+
if (typeof lastOutputAt === "number") {
|
|
47252
|
+
const quietMs = Date.now() - lastOutputAt;
|
|
47253
|
+
if (quietMs < PTY_PARSED_FINAL_ASSISTANT_QUIET_DWELL_MS) {
|
|
47254
|
+
return { reason: "parsed_final_assistant_quiet_dwell", terminal: false };
|
|
47255
|
+
}
|
|
47256
|
+
}
|
|
47257
|
+
} catch {
|
|
47258
|
+
}
|
|
47259
|
+
}
|
|
47145
47260
|
return null;
|
|
47146
47261
|
}
|
|
47147
47262
|
// (FALSEIDLE-a) Positive, structural proof that the latest approval entry was resolved
|
|
@@ -47563,6 +47678,53 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
47563
47678
|
...opts.completionDiagnostic !== void 0 ? { completionDiagnostic: opts.completionDiagnostic } : {}
|
|
47564
47679
|
});
|
|
47565
47680
|
}
|
|
47681
|
+
/**
|
|
47682
|
+
* AUTOAPPROVE-FLAP-INBOX-MISSING sticky-approval overlay. Returns the adapterStatus a
|
|
47683
|
+
* flap-prone claude-cli approval SHOULD present this frame — either the raw status
|
|
47684
|
+
* unchanged, or, when the raw status has momentarily flapped OFF a recently-dominant
|
|
47685
|
+
* concrete approval, a synthetic `waiting_approval` re-presenting the cached modal.
|
|
47686
|
+
*
|
|
47687
|
+
* Records the concrete approval whenever the raw status is waiting_approval WITH
|
|
47688
|
+
* buttons. On a subsequent non-approval frame (the spec `approval→busy` flap), if that
|
|
47689
|
+
* concrete approval was seen within APPROVAL_STICKY_FLAP_MS AND the engine has NOT
|
|
47690
|
+
* resolved a modal since (lastApprovalResolvedAt not advanced past the sticky start),
|
|
47691
|
+
* overlay the cached modal + waiting_approval so the inbox / auto-approve / mesh_approve
|
|
47692
|
+
* all see the stable approval. A genuine resolution (auto-approve or mesh_approve fires
|
|
47693
|
+
* resolveModal → lastApprovalResolvedAt advances) clears the sticky immediately, so a
|
|
47694
|
+
* legitimate post-approval resume is NEVER masked as a lingering approval. Bounded by the
|
|
47695
|
+
* window, and scoped to autonomous mesh sessions (a foreground/attended or non-mesh
|
|
47696
|
+
* session, where a human answers the prompt, is returned untouched).
|
|
47697
|
+
*/
|
|
47698
|
+
stabilizeFlappingApprovalStatus(adapterStatus, now = Date.now()) {
|
|
47699
|
+
if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return adapterStatus;
|
|
47700
|
+
const rawStatus = adapterStatus?.status;
|
|
47701
|
+
const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
|
|
47702
|
+
if (rawStatus === "waiting_approval") {
|
|
47703
|
+
if (hasNonEmptyCliModalButtons(adapterStatus?.activeModal)) {
|
|
47704
|
+
this.approvalStickyLastConcreteAt = now;
|
|
47705
|
+
this.approvalStickyModal = adapterStatus.activeModal;
|
|
47706
|
+
this.approvalStickyEntrySeq = typeof adapterStatus?.approvalEntrySeq === "number" ? adapterStatus.approvalEntrySeq : this.approvalStickyEntrySeq;
|
|
47707
|
+
}
|
|
47708
|
+
return adapterStatus;
|
|
47709
|
+
}
|
|
47710
|
+
if (this.approvalStickyLastConcreteAt > 0 && this.approvalStickyModal) {
|
|
47711
|
+
const withinWindow = now - this.approvalStickyLastConcreteAt < _CliProviderInstance.APPROVAL_STICKY_FLAP_MS;
|
|
47712
|
+
const resolvedSinceAnchor = resolvedAt >= this.approvalStickyLastConcreteAt;
|
|
47713
|
+
if (withinWindow && !resolvedSinceAnchor) {
|
|
47714
|
+
return {
|
|
47715
|
+
...adapterStatus,
|
|
47716
|
+
status: "waiting_approval",
|
|
47717
|
+
activeModal: this.approvalStickyModal,
|
|
47718
|
+
...this.approvalStickyEntrySeq ? { approvalEntrySeq: this.approvalStickyEntrySeq } : {},
|
|
47719
|
+
approvalStickyOverlay: true
|
|
47720
|
+
};
|
|
47721
|
+
}
|
|
47722
|
+
this.approvalStickyLastConcreteAt = 0;
|
|
47723
|
+
this.approvalStickyModal = null;
|
|
47724
|
+
this.approvalStickyEntrySeq = 0;
|
|
47725
|
+
}
|
|
47726
|
+
return adapterStatus;
|
|
47727
|
+
}
|
|
47566
47728
|
maybeAutoApproveStatus(adapterStatus, now = Date.now()) {
|
|
47567
47729
|
if (adapterStatus?.status === "waiting_approval" && this.shouldAutoApprove() && this.manualAttendance.isAttended(now)) {
|
|
47568
47730
|
this.lastAutoApprovalSignature = "";
|
|
@@ -47792,7 +47954,7 @@ ${buttons.join("\n")}`;
|
|
|
47792
47954
|
}
|
|
47793
47955
|
detectStatusTransition() {
|
|
47794
47956
|
const now = Date.now();
|
|
47795
|
-
const adapterStatus = this.adapter.getStatus({ allowParse: false });
|
|
47957
|
+
const adapterStatus = this.stabilizeFlappingApprovalStatus(this.adapter.getStatus({ allowParse: false }), now);
|
|
47796
47958
|
const adapterProviderSessionId = normalizeProviderSessionId(
|
|
47797
47959
|
this.provider,
|
|
47798
47960
|
typeof adapterStatus?.providerSessionId === "string" ? adapterStatus.providerSessionId : ""
|
|
@@ -56081,7 +56243,7 @@ var meshCrudHandlers = {
|
|
|
56081
56243
|
const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node addition");
|
|
56082
56244
|
if (ownerFailure) return ownerFailure;
|
|
56083
56245
|
try {
|
|
56084
|
-
const { addNode: addNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
56246
|
+
const { addNode: addNode2, migrateProviderRolesToSlots: migrateProviderRolesToSlots2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
56085
56247
|
const providerPriority = Array.isArray(args?.providerPriority) ? args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean) : [];
|
|
56086
56248
|
const readOnly = args?.readOnly === true;
|
|
56087
56249
|
const providerRoles = normalizeProviderRoles(args?.providerRoles);
|
|
@@ -56090,6 +56252,7 @@ var meshCrudHandlers = {
|
|
|
56090
56252
|
...providerPriority.length ? { providerPriority } : {},
|
|
56091
56253
|
...providerRoles.length ? { providerRoles } : {}
|
|
56092
56254
|
};
|
|
56255
|
+
if (providerRoles.length) migrateProviderRolesToSlots2(policy);
|
|
56093
56256
|
const role = normalizeMeshDaemonRole(args?.role);
|
|
56094
56257
|
const daemonId = typeof args?.daemonId === "string" && args.daemonId.trim() ? args.daemonId.trim() : void 0;
|
|
56095
56258
|
const machineId = typeof args?.machineId === "string" && args.machineId.trim() ? args.machineId.trim() : void 0;
|
|
@@ -56118,7 +56281,7 @@ var meshCrudHandlers = {
|
|
|
56118
56281
|
const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node update");
|
|
56119
56282
|
if (ownerFailure) return ownerFailure;
|
|
56120
56283
|
try {
|
|
56121
|
-
const { updateNode: updateNode2, normalizeCapabilityTags: normalizeCapabilityTags2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
56284
|
+
const { updateNode: updateNode2, normalizeCapabilityTags: normalizeCapabilityTags2, migrateProviderRolesToSlots: migrateProviderRolesToSlots2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
56122
56285
|
const policy = args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy) ? { ...args.policy } : {};
|
|
56123
56286
|
if (Array.isArray(args?.providerPriority)) {
|
|
56124
56287
|
const providerPriority = args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean);
|
|
@@ -56131,12 +56294,10 @@ var meshCrudHandlers = {
|
|
|
56131
56294
|
}
|
|
56132
56295
|
if (Array.isArray(args?.providerRoles)) {
|
|
56133
56296
|
const providerRoles = normalizeProviderRoles(args.providerRoles);
|
|
56134
|
-
if (providerRoles.length)
|
|
56135
|
-
|
|
56136
|
-
} else {
|
|
56137
|
-
delete policy.providerRoles;
|
|
56138
|
-
}
|
|
56297
|
+
if (providerRoles.length) policy.providerRoles = providerRoles;
|
|
56298
|
+
else delete policy.providerRoles;
|
|
56139
56299
|
}
|
|
56300
|
+
migrateProviderRolesToSlots2(policy);
|
|
56140
56301
|
const patch = { policy };
|
|
56141
56302
|
if (typeof args?.systemPrompt === "string") {
|
|
56142
56303
|
const trimmed = args.systemPrompt.trim();
|
|
@@ -56408,8 +56569,11 @@ var meshCrudHandlers = {
|
|
|
56408
56569
|
console.log(`[mesh] clone_mesh_node base sync: ${result.baseSync.action} (startRef=${result.baseSync.startRef})`);
|
|
56409
56570
|
}
|
|
56410
56571
|
let node;
|
|
56572
|
+
const { migrateProviderRolesToSlots: migrateProviderRolesToSlots2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
56411
56573
|
if (meshRecord.inline) {
|
|
56412
56574
|
const { randomUUID: randomUUID15 } = await import("crypto");
|
|
56575
|
+
const clonedPolicy = { ...sourceNode.policy || {} };
|
|
56576
|
+
migrateProviderRolesToSlots2(clonedPolicy);
|
|
56413
56577
|
node = {
|
|
56414
56578
|
id: `node_${randomUUID15().replace(/-/g, "")}`,
|
|
56415
56579
|
workspace: result.worktreePath,
|
|
@@ -56417,7 +56581,7 @@ var meshCrudHandlers = {
|
|
|
56417
56581
|
daemonId: sourceNode.daemonId,
|
|
56418
56582
|
machineId: sourceNode.machineId ?? sourceNode.machine_id,
|
|
56419
56583
|
userOverrides: { ...sourceNode.userOverrides || {} },
|
|
56420
|
-
policy:
|
|
56584
|
+
policy: clonedPolicy,
|
|
56421
56585
|
isLocalWorktree: true,
|
|
56422
56586
|
worktreeBranch: result.branch,
|
|
56423
56587
|
clonedFromNodeId: sourceNodeId
|
|
@@ -56425,6 +56589,8 @@ var meshCrudHandlers = {
|
|
|
56425
56589
|
ctx.updateInlineMeshNode(meshId, mesh, node);
|
|
56426
56590
|
} else {
|
|
56427
56591
|
const { addNode: addNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
56592
|
+
const clonedPolicy = { ...sourceNode.policy || {} };
|
|
56593
|
+
migrateProviderRolesToSlots2(clonedPolicy);
|
|
56428
56594
|
node = addNode2(meshId, {
|
|
56429
56595
|
workspace: result.worktreePath,
|
|
56430
56596
|
repoRoot: result.worktreePath,
|
|
@@ -56434,7 +56600,7 @@ var meshCrudHandlers = {
|
|
|
56434
56600
|
isLocalWorktree: true,
|
|
56435
56601
|
worktreeBranch: result.branch,
|
|
56436
56602
|
clonedFromNodeId: sourceNodeId,
|
|
56437
|
-
policy:
|
|
56603
|
+
policy: clonedPolicy
|
|
56438
56604
|
});
|
|
56439
56605
|
if (!node) return { success: false, error: "Failed to register worktree node" };
|
|
56440
56606
|
const inlineForReconcile = ctx.getCachedInlineMesh(meshId);
|