@adhdev/daemon-core 0.9.82-rc.380 → 0.9.82-rc.382
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +4 -2
- package/dist/index.js +302 -61
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +295 -61
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-event-forwarding.d.ts +1 -0
- package/dist/mesh/mesh-runtime-store.d.ts +12 -0
- package/dist/mesh/mesh-scheduling-runtime.d.ts +78 -0
- package/dist/providers/cli-provider-instance.d.ts +18 -0
- package/dist/repo-mesh-types.d.ts +81 -0
- package/package.json +2 -2
- package/src/commands/high-family/mesh-status.ts +36 -0
- package/src/config/mesh-config.ts +6 -58
- package/src/index.ts +13 -0
- package/src/mesh/coordinator-prompt.ts +3 -3
- package/src/mesh/mesh-event-forwarding.ts +63 -2
- package/src/mesh/mesh-runtime-store.ts +23 -0
- package/src/mesh/mesh-scheduling-runtime.ts +199 -0
- package/src/providers/cli-provider-instance.ts +27 -0
- package/src/repo-mesh-types.ts +164 -0
package/dist/index.mjs
CHANGED
|
@@ -38,6 +38,56 @@ function resolveNodeSchedulingPriority(nodePolicy) {
|
|
|
38
38
|
function resolveAutoConvergeCodeChange(policy) {
|
|
39
39
|
return policy?.autoConvergeCodeChange === true;
|
|
40
40
|
}
|
|
41
|
+
function resolveMaxParallelTasks(value) {
|
|
42
|
+
const n = Number(value);
|
|
43
|
+
if (!Number.isFinite(n)) return DEFAULT_MESH_POLICY.maxParallelTasks;
|
|
44
|
+
return Math.max(MESH_MAX_PARALLEL_TASKS_MIN, Math.min(MESH_MAX_PARALLEL_TASKS_MAX, Math.floor(n)));
|
|
45
|
+
}
|
|
46
|
+
function normalizeAutoFastForwardPolicy(value) {
|
|
47
|
+
const record = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
48
|
+
const maxBehind = Number(record.maxBehind);
|
|
49
|
+
return {
|
|
50
|
+
enabled: record.enabled !== false,
|
|
51
|
+
...Number.isFinite(maxBehind) && maxBehind >= 0 ? { maxBehind: Math.floor(maxBehind) } : {},
|
|
52
|
+
requireCleanSubmodules: record.requireCleanSubmodules !== false
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function mergeAndNormalizePolicy(base, patch) {
|
|
56
|
+
const autoFastForward = normalizeAutoFastForwardPolicy({
|
|
57
|
+
...DEFAULT_MESH_POLICY.autoFastForward,
|
|
58
|
+
...base?.autoFastForward && typeof base.autoFastForward === "object" ? base.autoFastForward : {},
|
|
59
|
+
...patch?.autoFastForward && typeof patch.autoFastForward === "object" ? patch.autoFastForward : {}
|
|
60
|
+
});
|
|
61
|
+
const policy = {
|
|
62
|
+
...DEFAULT_MESH_POLICY,
|
|
63
|
+
...base || {},
|
|
64
|
+
...patch || {},
|
|
65
|
+
autoFastForward
|
|
66
|
+
};
|
|
67
|
+
if (!DIRTY_WORKSPACE_BEHAVIORS.has(policy.dirtyWorkspaceBehavior)) {
|
|
68
|
+
policy.dirtyWorkspaceBehavior = "warn";
|
|
69
|
+
}
|
|
70
|
+
policy.maxParallelTasks = resolveMaxParallelTasks(policy.maxParallelTasks);
|
|
71
|
+
policy.allowAutoPublishSubmoduleMainCommits = policy.allowAutoPublishSubmoduleMainCommits === true;
|
|
72
|
+
if (!SESSION_CLEANUP_MODES.has(policy.sessionCleanupOnNodeRemove)) {
|
|
73
|
+
policy.sessionCleanupOnNodeRemove = "preserve";
|
|
74
|
+
}
|
|
75
|
+
if (!SPAWNED_SESSION_VISIBILITY_MODES.has(policy.spawnedSessionVisibility)) {
|
|
76
|
+
policy.spawnedSessionVisibility = DEFAULT_MESH_POLICY.spawnedSessionVisibility;
|
|
77
|
+
}
|
|
78
|
+
const normalizedStrategy = normalizeMeshSchedulingStrategy(policy.schedulingStrategy);
|
|
79
|
+
if (normalizedStrategy === "first_eligible") {
|
|
80
|
+
delete policy.schedulingStrategy;
|
|
81
|
+
} else {
|
|
82
|
+
policy.schedulingStrategy = normalizedStrategy;
|
|
83
|
+
}
|
|
84
|
+
if (policy.autoConvergeCodeChange === true) {
|
|
85
|
+
policy.autoConvergeCodeChange = true;
|
|
86
|
+
} else {
|
|
87
|
+
delete policy.autoConvergeCodeChange;
|
|
88
|
+
}
|
|
89
|
+
return policy;
|
|
90
|
+
}
|
|
41
91
|
function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy) {
|
|
42
92
|
if (typeof nodePolicy?.delegatedWorkerAutoApprove === "boolean") {
|
|
43
93
|
return nodePolicy.delegatedWorkerAutoApprove;
|
|
@@ -62,7 +112,7 @@ function resolveProviderMaxParallel(nodePolicy, providerType) {
|
|
|
62
112
|
}
|
|
63
113
|
return void 0;
|
|
64
114
|
}
|
|
65
|
-
var MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, DEFAULT_MESH_POLICY;
|
|
115
|
+
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;
|
|
66
116
|
var init_repo_mesh_types = __esm({
|
|
67
117
|
"src/repo-mesh-types.ts"() {
|
|
68
118
|
"use strict";
|
|
@@ -92,6 +142,23 @@ var init_repo_mesh_types = __esm({
|
|
|
92
142
|
autoFastForward: { enabled: true },
|
|
93
143
|
maxTaskRetries: 1
|
|
94
144
|
};
|
|
145
|
+
SESSION_CLEANUP_MODES = /* @__PURE__ */ new Set([
|
|
146
|
+
"preserve",
|
|
147
|
+
"stop",
|
|
148
|
+
"delete_stopped",
|
|
149
|
+
"stop_and_delete"
|
|
150
|
+
]);
|
|
151
|
+
SPAWNED_SESSION_VISIBILITY_MODES = /* @__PURE__ */ new Set([
|
|
152
|
+
"visible",
|
|
153
|
+
"hidden"
|
|
154
|
+
]);
|
|
155
|
+
DIRTY_WORKSPACE_BEHAVIORS = /* @__PURE__ */ new Set([
|
|
156
|
+
"block",
|
|
157
|
+
"warn",
|
|
158
|
+
"checkpoint_then_continue"
|
|
159
|
+
]);
|
|
160
|
+
MESH_MAX_PARALLEL_TASKS_MIN = 1;
|
|
161
|
+
MESH_MAX_PARALLEL_TASKS_MAX = 8;
|
|
95
162
|
}
|
|
96
163
|
});
|
|
97
164
|
|
|
@@ -311,10 +378,10 @@ function readInjected(value) {
|
|
|
311
378
|
}
|
|
312
379
|
function getDaemonBuildInfo() {
|
|
313
380
|
if (cached) return cached;
|
|
314
|
-
const commit = readInjected(true ? "
|
|
315
|
-
const commitShort = readInjected(true ? "
|
|
316
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
317
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
381
|
+
const commit = readInjected(true ? "70741c4fe19c6f71bcef702e7e149d963d6fd916" : void 0) ?? "unknown";
|
|
382
|
+
const commitShort = readInjected(true ? "70741c4f" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
383
|
+
const version = readInjected(true ? "0.9.82-rc.382" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
384
|
+
const builtAt = readInjected(true ? "2026-06-25T13:31:28.133Z" : void 0);
|
|
318
385
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
319
386
|
return cached;
|
|
320
387
|
}
|
|
@@ -2366,52 +2433,6 @@ function normalizeRepoIdentity(remoteUrl) {
|
|
|
2366
2433
|
if (sshMatch) return `${sshMatch[1]}/${sshMatch[2]}`;
|
|
2367
2434
|
return identity;
|
|
2368
2435
|
}
|
|
2369
|
-
function mergeMeshPolicy(base, patch) {
|
|
2370
|
-
const autoFastForward = normalizeAutoFastForwardPolicy({
|
|
2371
|
-
...DEFAULT_MESH_POLICY.autoFastForward,
|
|
2372
|
-
...base?.autoFastForward && typeof base.autoFastForward === "object" ? base.autoFastForward : {},
|
|
2373
|
-
...patch?.autoFastForward && typeof patch.autoFastForward === "object" ? patch.autoFastForward : {}
|
|
2374
|
-
});
|
|
2375
|
-
const policy = {
|
|
2376
|
-
...DEFAULT_MESH_POLICY,
|
|
2377
|
-
...base || {},
|
|
2378
|
-
...patch || {},
|
|
2379
|
-
autoFastForward
|
|
2380
|
-
};
|
|
2381
|
-
if (!["block", "warn", "checkpoint_then_continue"].includes(policy.dirtyWorkspaceBehavior)) {
|
|
2382
|
-
policy.dirtyWorkspaceBehavior = "warn";
|
|
2383
|
-
}
|
|
2384
|
-
const maxParallelTasks = Number(policy.maxParallelTasks);
|
|
2385
|
-
policy.maxParallelTasks = Number.isFinite(maxParallelTasks) ? Math.max(1, Math.min(8, Math.floor(maxParallelTasks))) : 2;
|
|
2386
|
-
policy.allowAutoPublishSubmoduleMainCommits = policy.allowAutoPublishSubmoduleMainCommits === true;
|
|
2387
|
-
if (!SESSION_CLEANUP_MODES.has(String(policy.sessionCleanupOnNodeRemove))) {
|
|
2388
|
-
policy.sessionCleanupOnNodeRemove = "preserve";
|
|
2389
|
-
}
|
|
2390
|
-
if (!SPAWNED_SESSION_VISIBILITY_MODES.has(String(policy.spawnedSessionVisibility))) {
|
|
2391
|
-
policy.spawnedSessionVisibility = DEFAULT_MESH_POLICY.spawnedSessionVisibility;
|
|
2392
|
-
}
|
|
2393
|
-
const normalizedStrategy = normalizeMeshSchedulingStrategy(policy.schedulingStrategy);
|
|
2394
|
-
if (normalizedStrategy === "first_eligible") {
|
|
2395
|
-
delete policy.schedulingStrategy;
|
|
2396
|
-
} else {
|
|
2397
|
-
policy.schedulingStrategy = normalizedStrategy;
|
|
2398
|
-
}
|
|
2399
|
-
if (policy.autoConvergeCodeChange === true) {
|
|
2400
|
-
policy.autoConvergeCodeChange = true;
|
|
2401
|
-
} else {
|
|
2402
|
-
delete policy.autoConvergeCodeChange;
|
|
2403
|
-
}
|
|
2404
|
-
return policy;
|
|
2405
|
-
}
|
|
2406
|
-
function normalizeAutoFastForwardPolicy(value) {
|
|
2407
|
-
const record = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2408
|
-
const maxBehind = Number(record.maxBehind);
|
|
2409
|
-
return {
|
|
2410
|
-
enabled: record.enabled !== false,
|
|
2411
|
-
...Number.isFinite(maxBehind) && maxBehind >= 0 ? { maxBehind: Math.floor(maxBehind) } : {},
|
|
2412
|
-
requireCleanSubmodules: record.requireCleanSubmodules !== false
|
|
2413
|
-
};
|
|
2414
|
-
}
|
|
2415
2436
|
function listMeshes() {
|
|
2416
2437
|
return loadMeshConfig().meshes;
|
|
2417
2438
|
}
|
|
@@ -2710,7 +2731,7 @@ function updateNode(meshId, nodeId, opts) {
|
|
|
2710
2731
|
saveMeshConfig(config);
|
|
2711
2732
|
return node;
|
|
2712
2733
|
}
|
|
2713
|
-
var
|
|
2734
|
+
var mergeMeshPolicy;
|
|
2714
2735
|
var init_mesh_config = __esm({
|
|
2715
2736
|
"src/config/mesh-config.ts"() {
|
|
2716
2737
|
"use strict";
|
|
@@ -2718,8 +2739,7 @@ var init_mesh_config = __esm({
|
|
|
2718
2739
|
init_config();
|
|
2719
2740
|
init_repo_mesh_types();
|
|
2720
2741
|
init_mesh_host_ownership();
|
|
2721
|
-
|
|
2722
|
-
SPAWNED_SESSION_VISIBILITY_MODES = /* @__PURE__ */ new Set(["visible", "hidden"]);
|
|
2742
|
+
mergeMeshPolicy = mergeAndNormalizePolicy;
|
|
2723
2743
|
}
|
|
2724
2744
|
});
|
|
2725
2745
|
|
|
@@ -3043,7 +3063,7 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
|
|
|
3043
3063
|
if (recentActivity) sections.push(recentActivity);
|
|
3044
3064
|
const operatingNotes = buildOperatingNotesSection(ctx.operatingNotes);
|
|
3045
3065
|
if (operatingNotes) sections.push(operatingNotes);
|
|
3046
|
-
sections.push(buildPolicySection(
|
|
3066
|
+
sections.push(buildPolicySection(mergeAndNormalizePolicy(void 0, mesh.policy)));
|
|
3047
3067
|
sections.push(TOOLS_SECTION);
|
|
3048
3068
|
sections.push(TOOL_EXPOSURE_PREFLIGHT_SECTION);
|
|
3049
3069
|
sections.push(WORKFLOW_SECTION);
|
|
@@ -3076,7 +3096,7 @@ function expandPromptPlaceholders(template, ctx) {
|
|
|
3076
3096
|
mission: ctx.missionSection?.trim() || "",
|
|
3077
3097
|
recentActivity: buildRecentActivitySection(ctx.recentActivity) || "",
|
|
3078
3098
|
operatingNotes: buildOperatingNotesSection(ctx.operatingNotes) || "",
|
|
3079
|
-
policy: buildPolicySection(
|
|
3099
|
+
policy: buildPolicySection(mergeAndNormalizePolicy(void 0, mesh.policy)),
|
|
3080
3100
|
tools: TOOLS_SECTION,
|
|
3081
3101
|
workflow: WORKFLOW_SECTION,
|
|
3082
3102
|
rules: buildRulesSection(coordinatorCliType),
|
|
@@ -5741,6 +5761,28 @@ var init_mesh_runtime_store = __esm({
|
|
|
5741
5761
|
AND status NOT IN ('completed', 'failed')
|
|
5742
5762
|
`).run({ status, meshId, sessionId, updatedAt: now });
|
|
5743
5763
|
}
|
|
5764
|
+
/**
|
|
5765
|
+
* MESH-DISPATCH-MISROUTE (fix 3, consumer residual): resolve the task_id of the SINGLE
|
|
5766
|
+
* non-terminal direct dispatch a session owns. Returns the task_id only when the session
|
|
5767
|
+
* holds exactly ONE active ('dispatched'/'acked') row — the case where a taskId-less
|
|
5768
|
+
* lifecycle event (a legacy/relayed worker whose producer never stamped meshActiveTaskId)
|
|
5769
|
+
* unambiguously belongs to that one dispatch. With zero rows there is nothing to ack; with
|
|
5770
|
+
* two or more (a re-dispatch/nudge sibling) the firing event's owner is ambiguous, so we
|
|
5771
|
+
* return null and the caller MUST NOT fall back to the session_id sweep that would flip a
|
|
5772
|
+
* sibling row ("may flip a sibling dispatch row"). This narrows the legacy fallback to the
|
|
5773
|
+
* only safe case instead of removing the producer-side TASKIDLESS stamp's safety net.
|
|
5774
|
+
*/
|
|
5775
|
+
getSoleActiveDirectDispatchTaskId(meshId, sessionId) {
|
|
5776
|
+
if (!sessionId) return null;
|
|
5777
|
+
const rows = this.db.prepare(`
|
|
5778
|
+
SELECT task_id FROM mesh_direct_dispatches
|
|
5779
|
+
WHERE mesh_id = ? AND session_id = ?
|
|
5780
|
+
AND status NOT IN ('completed', 'failed', 'stale')
|
|
5781
|
+
`).all(meshId, sessionId);
|
|
5782
|
+
if (rows.length !== 1) return null;
|
|
5783
|
+
const taskId = typeof rows[0]?.task_id === "string" ? rows[0].task_id.trim() : "";
|
|
5784
|
+
return taskId || null;
|
|
5785
|
+
}
|
|
5744
5786
|
cleanupTerminalDirectDispatches(olderThanMs) {
|
|
5745
5787
|
const cutoff = new Date(Date.now() - olderThanMs).toISOString();
|
|
5746
5788
|
this.db.prepare(`
|
|
@@ -8532,6 +8574,109 @@ var init_mesh_active_work = __esm({
|
|
|
8532
8574
|
}
|
|
8533
8575
|
});
|
|
8534
8576
|
|
|
8577
|
+
// src/mesh/mesh-scheduling-runtime.ts
|
|
8578
|
+
var mesh_scheduling_runtime_exports = {};
|
|
8579
|
+
__export(mesh_scheduling_runtime_exports, {
|
|
8580
|
+
buildMeshSchedulingRuntime: () => buildMeshSchedulingRuntime
|
|
8581
|
+
});
|
|
8582
|
+
function isReadonly(task) {
|
|
8583
|
+
return task.taskMode === "live_debug_readonly";
|
|
8584
|
+
}
|
|
8585
|
+
function isAssigned(task) {
|
|
8586
|
+
return task.status === "assigned";
|
|
8587
|
+
}
|
|
8588
|
+
function buildMeshSchedulingRuntime(mesh, queue) {
|
|
8589
|
+
const strategy = normalizeMeshSchedulingStrategy(mesh?.policy?.schedulingStrategy);
|
|
8590
|
+
const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
|
|
8591
|
+
const maxReadonlyParallelTasks = Math.max(2, maxParallelTasks * 2);
|
|
8592
|
+
const assignedTasks = (Array.isArray(queue) ? queue : []).filter(isAssigned);
|
|
8593
|
+
const activeWriteAssigned = assignedTasks.filter((t) => !isReadonly(t)).length;
|
|
8594
|
+
const activeReadonlyAssigned = assignedTasks.filter(isReadonly).length;
|
|
8595
|
+
const globalWriteCapReached = activeWriteAssigned >= maxParallelTasks;
|
|
8596
|
+
const globalReadonlyCapReached = activeReadonlyAssigned >= maxReadonlyParallelTasks;
|
|
8597
|
+
const writeAssignedByNode = /* @__PURE__ */ new Map();
|
|
8598
|
+
const assignedByNode = /* @__PURE__ */ new Map();
|
|
8599
|
+
const providerCountByNode = /* @__PURE__ */ new Map();
|
|
8600
|
+
for (const task of assignedTasks) {
|
|
8601
|
+
const nodeId = typeof task.assignedNodeId === "string" ? task.assignedNodeId.trim() : "";
|
|
8602
|
+
if (!nodeId) continue;
|
|
8603
|
+
assignedByNode.set(nodeId, (assignedByNode.get(nodeId) ?? 0) + 1);
|
|
8604
|
+
if (!isReadonly(task)) {
|
|
8605
|
+
writeAssignedByNode.set(nodeId, (writeAssignedByNode.get(nodeId) ?? 0) + 1);
|
|
8606
|
+
}
|
|
8607
|
+
const provider = typeof task.assignedProviderType === "string" ? task.assignedProviderType : "";
|
|
8608
|
+
if (provider) {
|
|
8609
|
+
let byProvider = providerCountByNode.get(nodeId);
|
|
8610
|
+
if (!byProvider) {
|
|
8611
|
+
byProvider = /* @__PURE__ */ new Map();
|
|
8612
|
+
providerCountByNode.set(nodeId, byProvider);
|
|
8613
|
+
}
|
|
8614
|
+
byProvider.set(provider, (byProvider.get(provider) ?? 0) + 1);
|
|
8615
|
+
}
|
|
8616
|
+
}
|
|
8617
|
+
const nodes = [];
|
|
8618
|
+
for (const rawNode of Array.isArray(mesh?.nodes) ? mesh.nodes : []) {
|
|
8619
|
+
const nodeId = normalizeMeshNodeId(rawNode);
|
|
8620
|
+
if (!nodeId) continue;
|
|
8621
|
+
const policy = rawNode?.policy || void 0;
|
|
8622
|
+
const load4 = assignedByNode.get(nodeId) ?? 0;
|
|
8623
|
+
const schedulingPriority = resolveNodeSchedulingPriority(policy);
|
|
8624
|
+
const capReasons = [];
|
|
8625
|
+
if (globalWriteCapReached) capReasons.push("global_max_parallel_tasks_reached");
|
|
8626
|
+
if ((writeAssignedByNode.get(nodeId) ?? 0) > 0) capReasons.push("node_has_active_assignment");
|
|
8627
|
+
let providerRoles;
|
|
8628
|
+
const declaredRoles = Array.isArray(policy?.providerRoles) ? policy.providerRoles : [];
|
|
8629
|
+
if (declaredRoles.length) {
|
|
8630
|
+
const byProvider = providerCountByNode.get(nodeId);
|
|
8631
|
+
providerRoles = [];
|
|
8632
|
+
for (const role of declaredRoles) {
|
|
8633
|
+
if (!role || typeof role !== "object") continue;
|
|
8634
|
+
const providerType = typeof role.providerType === "string" ? role.providerType.trim() : "";
|
|
8635
|
+
if (!providerType) continue;
|
|
8636
|
+
const maxParallel = resolveProviderMaxParallel(policy, providerType);
|
|
8637
|
+
const activeAssigned = byProvider?.get(providerType) ?? 0;
|
|
8638
|
+
const capReached = maxParallel !== void 0 && activeAssigned >= maxParallel;
|
|
8639
|
+
providerRoles.push({
|
|
8640
|
+
providerType,
|
|
8641
|
+
...maxParallel !== void 0 ? { maxParallel } : {},
|
|
8642
|
+
activeAssigned,
|
|
8643
|
+
capReached
|
|
8644
|
+
});
|
|
8645
|
+
if (capReached) capReasons.push(`max_provider_parallel_reached:${providerType}`);
|
|
8646
|
+
}
|
|
8647
|
+
if (!providerRoles.length) providerRoles = void 0;
|
|
8648
|
+
}
|
|
8649
|
+
const maxConcurrentSessions = Number(policy?.maxConcurrentSessions);
|
|
8650
|
+
const hasSessionCap = Number.isFinite(maxConcurrentSessions) && maxConcurrentSessions >= 0;
|
|
8651
|
+
nodes.push({
|
|
8652
|
+
nodeId,
|
|
8653
|
+
load: load4,
|
|
8654
|
+
schedulingPriority,
|
|
8655
|
+
...hasSessionCap ? { maxConcurrentSessions: Math.floor(maxConcurrentSessions) } : {},
|
|
8656
|
+
...providerRoles ? { providerRoles } : {},
|
|
8657
|
+
capReached: capReasons.length > 0,
|
|
8658
|
+
capReasons
|
|
8659
|
+
});
|
|
8660
|
+
}
|
|
8661
|
+
return {
|
|
8662
|
+
strategy,
|
|
8663
|
+
maxParallelTasks,
|
|
8664
|
+
maxReadonlyParallelTasks,
|
|
8665
|
+
activeWriteAssigned,
|
|
8666
|
+
activeReadonlyAssigned,
|
|
8667
|
+
globalWriteCapReached,
|
|
8668
|
+
globalReadonlyCapReached,
|
|
8669
|
+
nodes
|
|
8670
|
+
};
|
|
8671
|
+
}
|
|
8672
|
+
var init_mesh_scheduling_runtime = __esm({
|
|
8673
|
+
"src/mesh/mesh-scheduling-runtime.ts"() {
|
|
8674
|
+
"use strict";
|
|
8675
|
+
init_repo_mesh_types();
|
|
8676
|
+
init_dist();
|
|
8677
|
+
}
|
|
8678
|
+
});
|
|
8679
|
+
|
|
8535
8680
|
// src/mesh/mesh-events-utils.ts
|
|
8536
8681
|
function readNonEmptyString2(value) {
|
|
8537
8682
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
@@ -10815,8 +10960,8 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
10815
10960
|
const maxParallelTasks = Math.max(1, Math.floor(Number(mesh?.policy?.maxParallelTasks) || 2));
|
|
10816
10961
|
const maxReadonlyParallelTasks = Math.max(2, maxParallelTasks * 2);
|
|
10817
10962
|
for (const task of pending) {
|
|
10818
|
-
const
|
|
10819
|
-
if (
|
|
10963
|
+
const isReadonly2 = task.taskMode === "live_debug_readonly";
|
|
10964
|
+
if (isReadonly2) {
|
|
10820
10965
|
if (activeReadonlyAssignedCount(meshId) >= maxReadonlyParallelTasks) {
|
|
10821
10966
|
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "max_readonly_parallel_tasks_reached" });
|
|
10822
10967
|
continue;
|
|
@@ -13763,6 +13908,20 @@ function recoverMeshIdByNodeId(nodeId) {
|
|
|
13763
13908
|
}
|
|
13764
13909
|
return "";
|
|
13765
13910
|
}
|
|
13911
|
+
function recoverMeshIdByCoordinatorAndNode(coordinatorDaemonId, nodeId) {
|
|
13912
|
+
if (!coordinatorDaemonId) return "";
|
|
13913
|
+
const hosted = listMeshes().filter((mesh) => {
|
|
13914
|
+
const host = resolveMeshHostStatus(mesh);
|
|
13915
|
+
return host.role === "host" && (!host.hostDaemonId || daemonIdsEquivalent(host.hostDaemonId, coordinatorDaemonId));
|
|
13916
|
+
});
|
|
13917
|
+
if (hosted.length === 0) return "";
|
|
13918
|
+
if (nodeId) {
|
|
13919
|
+
const byNode = hosted.find((mesh) => Array.isArray(mesh.nodes) && mesh.nodes.some((n) => meshNodeIdMatches(n, nodeId)));
|
|
13920
|
+
if (byNode) return readNonEmptyString2(byNode.id);
|
|
13921
|
+
return "";
|
|
13922
|
+
}
|
|
13923
|
+
return hosted.length === 1 ? readNonEmptyString2(hosted[0].id) : "";
|
|
13924
|
+
}
|
|
13766
13925
|
function resolveForwardEventMeshId(components, payload) {
|
|
13767
13926
|
const direct = readNonEmptyString2(payload.meshId);
|
|
13768
13927
|
if (direct) return direct;
|
|
@@ -14244,8 +14403,19 @@ function injectMeshSystemMessage(components, args) {
|
|
|
14244
14403
|
}
|
|
14245
14404
|
if (sessionId) {
|
|
14246
14405
|
const startedTaskId = readNonEmptyString2(args.metadataEvent.taskId) || void 0;
|
|
14247
|
-
if (startedTaskId
|
|
14406
|
+
if (startedTaskId) {
|
|
14248
14407
|
updateDirectDispatchStatus(args.meshId, sessionId, "acked", startedTaskId);
|
|
14408
|
+
} else if (sessionHasActiveAssignment(args.meshId, sessionId)) {
|
|
14409
|
+
const soleTaskId = (() => {
|
|
14410
|
+
try {
|
|
14411
|
+
return MeshRuntimeStore.getInstance().getSoleActiveDirectDispatchTaskId(args.meshId, sessionId);
|
|
14412
|
+
} catch {
|
|
14413
|
+
return null;
|
|
14414
|
+
}
|
|
14415
|
+
})();
|
|
14416
|
+
if (soleTaskId) {
|
|
14417
|
+
updateDirectDispatchStatus(args.meshId, sessionId, "acked", soleTaskId);
|
|
14418
|
+
}
|
|
14249
14419
|
}
|
|
14250
14420
|
const activeDeliveries = (() => {
|
|
14251
14421
|
try {
|
|
@@ -14498,7 +14668,10 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
14498
14668
|
}
|
|
14499
14669
|
const nodeId = readNonEmptyString2(payload.nodeId);
|
|
14500
14670
|
const workspace = readNonEmptyString2(payload.workspace);
|
|
14501
|
-
const meshId = readNonEmptyString2(payload.meshId) || (workspace ? readNonEmptyString2(getCachedMeshByWorkspace(workspace)?.id) : "") || recoverMeshIdByNodeId(nodeId)
|
|
14671
|
+
const meshId = readNonEmptyString2(payload.meshId) || (workspace ? readNonEmptyString2(getCachedMeshByWorkspace(workspace)?.id) : "") || recoverMeshIdByNodeId(nodeId) || recoverMeshIdByCoordinatorAndNode(
|
|
14672
|
+
readNonEmptyString2(payload.meshCoordinatorDaemonId) || readNonEmptyString2(payload.coordinatorDaemonId),
|
|
14673
|
+
nodeId
|
|
14674
|
+
);
|
|
14502
14675
|
if (!meshId) {
|
|
14503
14676
|
traceMeshEventDrop("meshId_required", {
|
|
14504
14677
|
taskId: payload.taskId,
|
|
@@ -14553,7 +14726,12 @@ function forwardUnresolvedDelegateEvent(components, routing, event) {
|
|
|
14553
14726
|
...event,
|
|
14554
14727
|
event: eventName,
|
|
14555
14728
|
nodeId: readNonEmptyString2(routing.nodeId) || readNonEmptyString2(event.meshNodeId) || void 0,
|
|
14556
|
-
workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0
|
|
14729
|
+
workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0,
|
|
14730
|
+
// Fix B: carry the resolved coordinator anchor so the coordinator's receive-side
|
|
14731
|
+
// recovery (recoverMeshIdByCoordinatorAndNode) can match this forward to one of the
|
|
14732
|
+
// meshes it hosts when workspace + nodeId both miss. routing.coordinatorDaemonId is
|
|
14733
|
+
// the same anchor this forward is addressed to (coordinatorDaemonId below).
|
|
14734
|
+
meshCoordinatorDaemonId: coordinatorDaemonId
|
|
14557
14735
|
};
|
|
14558
14736
|
const resolvedMeshId = resolveForwardEventMeshId(components, payload);
|
|
14559
14737
|
if (resolvedMeshId) payload.meshId = resolvedMeshId;
|
|
@@ -14682,6 +14860,7 @@ var init_mesh_event_forwarding = __esm({
|
|
|
14682
14860
|
init_mesh_runtime_store();
|
|
14683
14861
|
init_mesh_events_pending();
|
|
14684
14862
|
init_mesh_routing();
|
|
14863
|
+
init_mesh_host_ownership();
|
|
14685
14864
|
init_mesh_unresolved_forward_outbox();
|
|
14686
14865
|
init_mesh_event_trace();
|
|
14687
14866
|
init_snapshot();
|
|
@@ -22921,6 +23100,7 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
|
|
|
22921
23100
|
init_mesh_work_queue();
|
|
22922
23101
|
init_mesh_active_work();
|
|
22923
23102
|
init_mesh_refine_status();
|
|
23103
|
+
init_mesh_scheduling_runtime();
|
|
22924
23104
|
init_mesh_host_ownership();
|
|
22925
23105
|
init_mesh_events();
|
|
22926
23106
|
init_mesh_events_utils();
|
|
@@ -38703,9 +38883,35 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
38703
38883
|
* terminal state. Leaving meshNodeFor pinned would route this session's
|
|
38704
38884
|
* subsequent unrelated turns (e.g. ad-hoc dashboard chats) to the
|
|
38705
38885
|
* coordinator as if they were task completions.
|
|
38886
|
+
*
|
|
38887
|
+
* MESHID-DROP-ON-DETACH (Fix C): a coordinator-LAUNCHED worker session
|
|
38888
|
+
* (launchedByCoordinator) holds its mesh membership (meshNodeFor / meshNodeId /
|
|
38889
|
+
* meshCoordinatorDaemonId) at the SESSION level — set once at launch
|
|
38890
|
+
* (mesh_launch_session / queue auto-launch), independent of any single task.
|
|
38891
|
+
* The original detach wiped meshNodeFor + meshNodeId together with the
|
|
38892
|
+
* task-level meshActiveTaskId, so the FIRST task completion stripped the
|
|
38893
|
+
* membership and EVERY subsequent completion forwarded with meshId absent —
|
|
38894
|
+
* resolveWorkerDelegateRouting fell to mesh_unresolved and the coordinator
|
|
38895
|
+
* rejected the forward "meshId required". For a launched member we therefore
|
|
38896
|
+
* clear ONLY the task-level marker (meshActiveTaskId) and preserve the
|
|
38897
|
+
* session-level membership so its next task's completion still resolves.
|
|
38898
|
+
* A task-less ad-hoc turn on a preserved-membership session is NOT misrouted:
|
|
38899
|
+
* its completion carries no taskId and the session holds no active assignment,
|
|
38900
|
+
* so the forwarder's WARMUPGAP guard skips the dispatch-row flip (it only
|
|
38901
|
+
* injects a benign task-less notification). A NON-launched session (a plain CLI
|
|
38902
|
+
* session adopted by mesh_send_task --direct, launchedByCoordinator falsy)
|
|
38903
|
+
* keeps the original full clear so an ad-hoc session is never left pinned.
|
|
38706
38904
|
*/
|
|
38707
38905
|
detachMeshAssignment() {
|
|
38708
38906
|
if (!this.settings.meshNodeFor && !this.settings.meshActiveTaskId && !this.settings.meshNodeId) return;
|
|
38907
|
+
if (this.settings.launchedByCoordinator === true) {
|
|
38908
|
+
if (!this.settings.meshActiveTaskId) return;
|
|
38909
|
+
const { meshActiveTaskId: meshActiveTaskId2, ...rest2 } = this.settings;
|
|
38910
|
+
void meshActiveTaskId2;
|
|
38911
|
+
this.settings = rest2;
|
|
38912
|
+
this.adapter.updateRuntimeSettings?.(this.settings);
|
|
38913
|
+
return;
|
|
38914
|
+
}
|
|
38709
38915
|
const { meshNodeFor, meshNodeId, meshActiveTaskId, ...rest } = this.settings;
|
|
38710
38916
|
void meshNodeFor;
|
|
38711
38917
|
void meshActiveTaskId;
|
|
@@ -48579,6 +48785,9 @@ var meshStatusHandlers = {
|
|
|
48579
48785
|
const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
48580
48786
|
const queue = getQueue2(meshId);
|
|
48581
48787
|
const queueSummary = getMeshQueueStats2(meshId);
|
|
48788
|
+
const { buildMeshSchedulingRuntime: buildMeshSchedulingRuntime2 } = await Promise.resolve().then(() => (init_mesh_scheduling_runtime(), mesh_scheduling_runtime_exports));
|
|
48789
|
+
const schedulingRuntime = buildMeshSchedulingRuntime2(mesh, queue);
|
|
48790
|
+
const schedulingByNode = new Map(schedulingRuntime.nodes.map((n) => [n.nodeId, n]));
|
|
48582
48791
|
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
48583
48792
|
const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
|
|
48584
48793
|
const asyncRefineLedgerEntries = readLedgerEntries2(meshId, { tail: 100 });
|
|
@@ -48693,6 +48902,11 @@ var meshStatusHandlers = {
|
|
|
48693
48902
|
activeSessionDetails: [],
|
|
48694
48903
|
launchReady: false
|
|
48695
48904
|
};
|
|
48905
|
+
const nodeScheduling = schedulingByNode.get(nodeId);
|
|
48906
|
+
if (nodeScheduling) {
|
|
48907
|
+
const { nodeId: _omitNodeId, ...nodeSchedulingRest } = nodeScheduling;
|
|
48908
|
+
status.scheduling = nodeSchedulingRest;
|
|
48909
|
+
}
|
|
48696
48910
|
if (isSelfNode) {
|
|
48697
48911
|
status.connection = {
|
|
48698
48912
|
perspective: "selected_coordinator",
|
|
@@ -48893,6 +49107,19 @@ var meshStatusHandlers = {
|
|
|
48893
49107
|
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
|
|
48894
49108
|
...previewFreshness ? { previewFreshness, deployFreshness: previewFreshness } : {},
|
|
48895
49109
|
nodes: nodeStatuses,
|
|
49110
|
+
// Mesh-level scheduling rollup (strategy + global cap consumption). Mirrors
|
|
49111
|
+
// the MCP `mesh_status` tool's `scheduling` block field-for-field so both
|
|
49112
|
+
// surfaces read the same runtime; per-node detail lives on each
|
|
49113
|
+
// nodes[].scheduling above.
|
|
49114
|
+
scheduling: {
|
|
49115
|
+
strategy: schedulingRuntime.strategy,
|
|
49116
|
+
maxParallelTasks: schedulingRuntime.maxParallelTasks,
|
|
49117
|
+
maxReadonlyParallelTasks: schedulingRuntime.maxReadonlyParallelTasks,
|
|
49118
|
+
activeWriteAssigned: schedulingRuntime.activeWriteAssigned,
|
|
49119
|
+
activeReadonlyAssigned: schedulingRuntime.activeReadonlyAssigned,
|
|
49120
|
+
globalWriteCapReached: schedulingRuntime.globalWriteCapReached,
|
|
49121
|
+
globalReadonlyCapReached: schedulingRuntime.globalReadonlyCapReached
|
|
49122
|
+
},
|
|
48896
49123
|
queue: { tasks: queue, summary: queueSummary },
|
|
48897
49124
|
ledger: { entries: ledgerEntries, summary: ledgerSummary },
|
|
48898
49125
|
...missions.length > 0 ? { missions } : {},
|
|
@@ -62209,6 +62436,8 @@ export {
|
|
|
62209
62436
|
MAX_LEDGER_SLICE_LIMIT,
|
|
62210
62437
|
MESH_CONVERGE_FAST_FORWARD_TAG,
|
|
62211
62438
|
MESH_CONVERGE_REFINE_TAG,
|
|
62439
|
+
MESH_MAX_PARALLEL_TASKS_MAX,
|
|
62440
|
+
MESH_MAX_PARALLEL_TASKS_MIN,
|
|
62212
62441
|
MESH_MISSION_STATUSES,
|
|
62213
62442
|
MESH_NODE_LIVE_TRUTH_MARKER,
|
|
62214
62443
|
MESH_REFINE_CONFIG_LOCATIONS,
|
|
@@ -62259,6 +62488,7 @@ export {
|
|
|
62259
62488
|
buildMeshNodeCapabilityTags,
|
|
62260
62489
|
buildMeshNodeDataFreshness,
|
|
62261
62490
|
buildMeshNodeProbeFreshness,
|
|
62491
|
+
buildMeshSchedulingRuntime,
|
|
62262
62492
|
buildMissionPromptSection,
|
|
62263
62493
|
buildP2pRelayFailurePayload,
|
|
62264
62494
|
buildPinnedGlobalInstallCommand,
|
|
@@ -62407,11 +62637,13 @@ export {
|
|
|
62407
62637
|
markSetupComplete,
|
|
62408
62638
|
markStaleDirectDispatches,
|
|
62409
62639
|
maybeRunDaemonUpgradeHelperFromEnv,
|
|
62640
|
+
mergeAndNormalizePolicy,
|
|
62410
62641
|
meshNodeIdMatches,
|
|
62411
62642
|
namedKeyToAnsi,
|
|
62412
62643
|
namedKeysToAnsi,
|
|
62413
62644
|
nodeSatisfiesRequiredTags,
|
|
62414
62645
|
normalizeActiveChatData,
|
|
62646
|
+
normalizeAutoFastForwardPolicy,
|
|
62415
62647
|
normalizeChatMessage,
|
|
62416
62648
|
normalizeChatMessageKind,
|
|
62417
62649
|
normalizeChatMessages,
|
|
@@ -62473,11 +62705,13 @@ export {
|
|
|
62473
62705
|
resolveDelegatedWorkerAutoApprove,
|
|
62474
62706
|
resolveDeliveryDecision,
|
|
62475
62707
|
resolveGitRepository,
|
|
62708
|
+
resolveMaxParallelTasks,
|
|
62476
62709
|
resolveMeshHostStatus,
|
|
62477
62710
|
resolveMeshNodeAttribution,
|
|
62478
62711
|
resolveMeshRefineValidationPlan,
|
|
62479
62712
|
resolveMeshSurfacedSessionPreview,
|
|
62480
62713
|
resolveNodeSchedulingPriority,
|
|
62714
|
+
resolveProviderMaxParallel,
|
|
62481
62715
|
resolveSessionHostAppName,
|
|
62482
62716
|
resolveSessionHostAppNameResolution,
|
|
62483
62717
|
resolveWorktreePath,
|