@adhdev/daemon-core 0.9.82-rc.394 → 0.9.82-rc.395
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 +9 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/mesh/mesh-queue-assignment.ts +31 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "0.9.82-rc.
|
|
3
|
+
"version": "0.9.82-rc.395",
|
|
4
4
|
"description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"author": "vilmire",
|
|
47
47
|
"license": "AGPL-3.0-or-later",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@adhdev/mesh-shared": "0.9.82-rc.
|
|
49
|
+
"@adhdev/mesh-shared": "0.9.82-rc.395",
|
|
50
50
|
"@adhdev/session-host-core": "*",
|
|
51
51
|
"@agentclientprotocol/sdk": "^0.16.1",
|
|
52
52
|
"ajv": "^8.20.0",
|
|
@@ -269,6 +269,37 @@ export function tryAssignQueueTask(
|
|
|
269
269
|
const mesh = getMeshWithCache(components, meshId);
|
|
270
270
|
const node = mesh?.nodes.find((n: any) => readMeshNodeId(n) === nodeId);
|
|
271
271
|
|
|
272
|
+
// WORKTREE-CLAIM-GATE-BYPASS: the SINGLE claim-time gate for the worktree-bootstrap defer.
|
|
273
|
+
// tryAssignQueueTask is the one funnel every claim path flows through — the event-driven
|
|
274
|
+
// agent:ready drain, the triggerMeshQueue idle-session drain (local + remote), the
|
|
275
|
+
// auto-launch claim, and the PHASE 3 reconcile re-drain all call it. The agent:ready handler
|
|
276
|
+
// (mesh-event-forwarding) deferred its OWN claim while a worktree node's bootstrap was still
|
|
277
|
+
// 'running', but it ALSO called setRemoteIdleSession first — registering the session as a
|
|
278
|
+
// claim candidate. A concurrent triggerMeshQueue drain then pulled that candidate and claimed
|
|
279
|
+
// through tryAssignQueueTask within ~0.16s, BYPASSING the event-handler-local defer: the task
|
|
280
|
+
// dispatched into a half-built worktree (native addons not yet installed → child daemon dies
|
|
281
|
+
// → empty session, totalMessages=0). The transport ack returns ok:true, so neither the
|
|
282
|
+
// assigned-stranded watchdog nor the pending-only PHASE 3 reconcile ever re-fires it → the
|
|
283
|
+
// session is stranded empty forever.
|
|
284
|
+
//
|
|
285
|
+
// Lowering the gate HERE makes the defer a property of the claim itself, not of one caller:
|
|
286
|
+
// a worktree node whose bootstrap is still 'running' can never be claimed from any path. The
|
|
287
|
+
// task stays pending (we return false WITHOUT touching its status — no fail/cancel), so the
|
|
288
|
+
// bootstrap_complete refire (triggerMeshQueue re-fired on worktree_bootstrap_complete) re-runs
|
|
289
|
+
// this claim and passes once status is no longer 'running'. The registered remote-idle session
|
|
290
|
+
// persists for REMOTE_IDLE_SESSION_TTL_MS (5min > observed ~2m8s bootstrap), so the refire
|
|
291
|
+
// still finds a live candidate to re-claim. Identity uses meshNodeIdMatches (the same shared
|
|
292
|
+
// 3-form normalizer the defer guard uses), never a raw === — canon-identity regression guard.
|
|
293
|
+
// Conservative: any non-'running' status (idle/complete/failed/absent/unknown) does NOT gate,
|
|
294
|
+
// so a base node and a fully-bootstrapped worktree keep prior behavior exactly.
|
|
295
|
+
const gateNode = mesh?.nodes?.find((n: any) => meshNodeIdMatches(n, nodeId)) as
|
|
296
|
+
| { worktreeBootstrap?: { status?: string } }
|
|
297
|
+
| undefined;
|
|
298
|
+
if (gateNode?.worktreeBootstrap?.status === 'running') {
|
|
299
|
+
LOG.info('MeshQueue', `Gating queue claim for worktree node ${nodeId} (${sessionId}): worktree bootstrap still running — task left pending; claim re-fires once bootstrap reaches a terminal state (guards against dispatching into a half-built worktree → empty session)`);
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
|
|
272
303
|
// WTCLAIM (fix-B extended to the enqueue→claim path): a base-targeted task must never be
|
|
273
304
|
// claimed by — and dispatched into — a co-located worktree-clone session, nor vice versa.
|
|
274
305
|
// The drain candidate's nodeId is derived from settings.meshNodeId || settings.nodeId
|