@adhdev/daemon-core 0.9.82-rc.132 → 0.9.82-rc.134
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 +76 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +76 -17
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-active-work.d.ts +15 -4
- package/dist/mesh/mesh-events.d.ts +17 -0
- package/package.json +1 -1
- package/src/mesh/coordinator-prompt.ts +1 -1
- package/src/mesh/mesh-active-work.ts +45 -6
- package/src/mesh/mesh-events.ts +67 -16
- package/src/providers/cli-provider-instance.ts +30 -3
package/dist/index.js
CHANGED
|
@@ -1203,7 +1203,7 @@ function buildRulesSection(coordinatorCliType) {
|
|
|
1203
1203
|
|
|
1204
1204
|
- **Minimize coordinator context.** The coordinator's job is routing, not implementing. Do not read source files, run commands, or analyze code directly \u2014 delegate all of that to node agents. Your context should stay lean.
|
|
1205
1205
|
- **Delegate analysis too.** If you need to understand a bug or explore the codebase, send that investigation as a task to the queue or a node. Do not do it yourself.
|
|
1206
|
-
- **Respect explicit provider requests.** If the user names an agent/provider, pass the matching provider type to \`mesh_launch_session\`: Hermes \u2192 \`hermes-cli\`, Claude Code/Claude \u2192 \`claude-cli\`, Codex \u2192 \`codex-cli\`, Gemini \u2192 \`gemini-cli\`. Never substitute \`claude-cli\` just because the coordinator itself is Claude Code.
|
|
1206
|
+
- **Respect explicit provider requests.** If the user names an agent/provider, pass the matching provider type to \`mesh_launch_session\`: Hermes \u2192 \`hermes-cli\`, Claude Code/Claude \u2192 \`claude-cli\`, Codex \u2192 \`codex-cli\`, Gemini \u2192 \`gemini-cli\`, Antigravity \u2192 \`antigravity-cli\`. Never substitute \`claude-cli\` just because the coordinator itself is Claude Code.
|
|
1207
1207
|
- **Front-load new task messages.** When calling \`mesh_enqueue_task\` or \`mesh_send_task\` for a new task, include everything the agent needs: what files to touch, what the problem is, what the fix should look like. The agent won't ask follow-up questions.
|
|
1208
1208
|
- **Avoid context-wasting restarts.** For follow-up, retry, commit/push, preview, or cleanup work on the same issue, prefer the existing idle session and send only the delta from its last verified state. Start a fresh chat/session only for genuinely independent work, explicit provider/user request, unsafe transcript contamination, or required branch/worktree isolation.
|
|
1209
1209
|
- **Don't inspect code.** Treat delegated agent summaries as self-reports, not verification. Verify side effects via \`mesh_git_status\` (including related repo freshness when configured), not by reading source files.
|
|
@@ -2819,14 +2819,26 @@ function findRecentTerminalLedgerEvidence(args) {
|
|
|
2819
2819
|
const entry = entries[i];
|
|
2820
2820
|
if (entry.kind !== "task_completed" && entry.kind !== "task_failed" && entry.kind !== "task_stalled") continue;
|
|
2821
2821
|
if (args.sessionId && entry.sessionId === args.sessionId) {
|
|
2822
|
-
return { kind: entry.kind, payload: entry.payload || {}, timestamp: entry.timestamp };
|
|
2822
|
+
return { id: entry.id, kind: entry.kind, payload: entry.payload || {}, timestamp: entry.timestamp };
|
|
2823
2823
|
}
|
|
2824
2824
|
if (!args.sessionId && args.nodeId && entry.nodeId === args.nodeId) {
|
|
2825
|
-
return { kind: entry.kind, payload: entry.payload || {}, timestamp: entry.timestamp };
|
|
2825
|
+
return { id: entry.id, kind: entry.kind, payload: entry.payload || {}, timestamp: entry.timestamp };
|
|
2826
2826
|
}
|
|
2827
2827
|
}
|
|
2828
2828
|
return null;
|
|
2829
2829
|
}
|
|
2830
|
+
function hasDispatchAfterTerminal(meshId, sessionId, terminalId) {
|
|
2831
|
+
const entries = readLedgerEntries(meshId);
|
|
2832
|
+
let pastTerminal = false;
|
|
2833
|
+
for (const entry of entries) {
|
|
2834
|
+
if (!pastTerminal) {
|
|
2835
|
+
if (entry.id === terminalId) pastTerminal = true;
|
|
2836
|
+
continue;
|
|
2837
|
+
}
|
|
2838
|
+
if (entry.kind === "task_dispatched" && entry.sessionId === sessionId) return true;
|
|
2839
|
+
}
|
|
2840
|
+
return false;
|
|
2841
|
+
}
|
|
2830
2842
|
function buildLongGeneratingCompletionReconciliation(args) {
|
|
2831
2843
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2832
2844
|
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
@@ -3331,13 +3343,16 @@ function injectMeshSystemMessage(components, args) {
|
|
|
3331
3343
|
nodeId: eventNodeId || void 0
|
|
3332
3344
|
});
|
|
3333
3345
|
if (terminal?.kind === "task_completed" && !sessionHasActiveAssignment(args.meshId, eventSessionId)) {
|
|
3334
|
-
const
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3346
|
+
const newDispatchAfterTerminal = hasDispatchAfterTerminal(args.meshId, eventSessionId, terminal.id);
|
|
3347
|
+
if (!newDispatchAfterTerminal) {
|
|
3348
|
+
const terminalProviderSessionId = readNonEmptyString2(terminal.payload.providerSessionId);
|
|
3349
|
+
const terminalFinalSummary = readNonEmptyString2(terminal.payload.finalSummary);
|
|
3350
|
+
const eventProviderSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
|
|
3351
|
+
const eventFinalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
|
|
3352
|
+
if (terminalProviderSessionId && terminalProviderSessionId === eventProviderSessionId || terminalFinalSummary && terminalFinalSummary === eventFinalSummary || args.metadataEvent.source === "long_generating_reconciliation") {
|
|
3353
|
+
LOG.info("MeshEvents", `Suppressed duplicate completion with existing terminal ledger evidence for mesh ${args.meshId} session ${eventSessionId}`);
|
|
3354
|
+
return { success: true, forwarded: 0, suppressed: true, duplicateCompletion: true, terminalLedgerEvidence: true };
|
|
3355
|
+
}
|
|
3341
3356
|
}
|
|
3342
3357
|
}
|
|
3343
3358
|
const duplicateCompletion = isDuplicateMeshCompletionEvent({
|
|
@@ -3564,7 +3579,13 @@ function injectMeshSystemMessage(components, args) {
|
|
|
3564
3579
|
}
|
|
3565
3580
|
return { success: true, forwarded: 0 };
|
|
3566
3581
|
}
|
|
3567
|
-
|
|
3582
|
+
const allCoordinatorsGenerating = isRefineTerminalEvent && coordinatorInstances.every((inst) => {
|
|
3583
|
+
const s = inst.getState();
|
|
3584
|
+
const status = readNonEmptyString2(s.status).toLowerCase();
|
|
3585
|
+
const activeChatStatus = readNonEmptyString2(s.activeChat?.status).toLowerCase();
|
|
3586
|
+
return status === "generating" || status === "streaming" || status === "long_generating" || activeChatStatus === "generating" || activeChatStatus === "streaming";
|
|
3587
|
+
});
|
|
3588
|
+
if (!isRefineTerminalEvent || allCoordinatorsGenerating) {
|
|
3568
3589
|
if (queuePendingMeshCoordinatorEvent({
|
|
3569
3590
|
event: args.event,
|
|
3570
3591
|
meshId: args.meshId,
|
|
@@ -3578,9 +3599,16 @@ function injectMeshSystemMessage(components, args) {
|
|
|
3578
3599
|
coordinatorMessage: messageText,
|
|
3579
3600
|
queuedAt: Date.now()
|
|
3580
3601
|
})) {
|
|
3581
|
-
|
|
3602
|
+
if (allCoordinatorsGenerating) {
|
|
3603
|
+
LOG.info("MeshEvents", `Queued ${args.event} for generating CLI coordinator (mesh ${args.meshId}) \u2014 will be delivered via get_pending_mesh_events when coordinator returns to idle`);
|
|
3604
|
+
} else {
|
|
3605
|
+
LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
|
|
3606
|
+
}
|
|
3582
3607
|
}
|
|
3583
3608
|
}
|
|
3609
|
+
if (allCoordinatorsGenerating) {
|
|
3610
|
+
return { success: true, forwarded: 0, bufferedForGeneratingCoordinator: true };
|
|
3611
|
+
}
|
|
3584
3612
|
for (const coord of coordinatorInstances) {
|
|
3585
3613
|
const coordState = coord.getState();
|
|
3586
3614
|
LOG.info("MeshEvents", `Forwarding mesh event to coordinator ${coordState.instanceId}`);
|
|
@@ -10208,6 +10236,7 @@ function buildMeshActiveWorkSummary(activeWork) {
|
|
|
10208
10236
|
statusCounts[item.status] += 1;
|
|
10209
10237
|
}
|
|
10210
10238
|
const staleDirectCount = activeWork.filter((item) => item.source === "direct" && item.staleReason).length;
|
|
10239
|
+
const staleDirectUnacknowledgedCount = activeWork.filter((item) => item.source === "direct" && item.staleDispatchUnacknowledged).length;
|
|
10211
10240
|
return {
|
|
10212
10241
|
totalActiveCount: activeWork.length,
|
|
10213
10242
|
queueActiveCount: sourceCounts.queue,
|
|
@@ -10219,6 +10248,7 @@ function buildMeshActiveWorkSummary(activeWork) {
|
|
|
10219
10248
|
sourceCounts,
|
|
10220
10249
|
statusCounts,
|
|
10221
10250
|
staleDirectCount,
|
|
10251
|
+
...staleDirectUnacknowledgedCount > 0 ? { staleDirectUnacknowledgedCount } : {},
|
|
10222
10252
|
...staleDirectCount > 0 ? { staleDirectNote: "Stale direct records are orphaned ledger entries whose node/session no longer exists. They are historical recovery evidence only \u2014 not active or unresolved work. The queue (source: queue) is authoritative for pending/assigned tasks." } : {}
|
|
10223
10253
|
};
|
|
10224
10254
|
}
|
|
@@ -10255,9 +10285,13 @@ function buildMeshActiveWork(opts) {
|
|
|
10255
10285
|
const live = sessionStatusFromNodes(opts.nodes, dispatch.nodeId, dispatch.sessionId);
|
|
10256
10286
|
const status = terminalStatus || live.status || "assigned";
|
|
10257
10287
|
const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
|
|
10258
|
-
const
|
|
10288
|
+
const dispatchedToIdleSession = dispatch.payload?.dispatchedToIdleSession === true;
|
|
10289
|
+
const isNoTransition = !terminalStatus && !live.status;
|
|
10290
|
+
const isIdleUnacknowledged = status === "idle";
|
|
10291
|
+
const ledgerOnlyStaleReason = !terminalRow && (isIdleUnacknowledged || isNoTransition || dispatchedToIdleSession && isIdleUnacknowledged) ? "direct task dispatch has no provider acknowledgement, transcript append, or active runtime transition" : void 0;
|
|
10259
10292
|
const message = readString2(dispatch.payload?.message) || readString2(dispatch.payload?.summary) || "";
|
|
10260
10293
|
const { title, summary: summary2 } = summarizeMessage(message);
|
|
10294
|
+
const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !live.staleReason);
|
|
10261
10295
|
const record = {
|
|
10262
10296
|
taskId,
|
|
10263
10297
|
source: "direct",
|
|
@@ -10276,7 +10310,8 @@ function buildMeshActiveWork(opts) {
|
|
|
10276
10310
|
terminal: terminalRow,
|
|
10277
10311
|
terminalKind: terminal?.kind,
|
|
10278
10312
|
terminalAt: terminal?.timestamp,
|
|
10279
|
-
staleReason: live.staleReason || ledgerOnlyStaleReason
|
|
10313
|
+
staleReason: live.staleReason || ledgerOnlyStaleReason,
|
|
10314
|
+
...isFreshUnacknowledged ? { staleDispatchUnacknowledged: true } : {}
|
|
10280
10315
|
};
|
|
10281
10316
|
if (terminalRow) {
|
|
10282
10317
|
terminalDirectWork.push(record);
|
|
@@ -10293,7 +10328,11 @@ function buildMeshActiveWork(opts) {
|
|
|
10293
10328
|
terminalDirectWork.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
10294
10329
|
const summary = buildMeshActiveWorkSummary(records);
|
|
10295
10330
|
summary.staleDirectCount = staleDirectWork.length;
|
|
10296
|
-
const
|
|
10331
|
+
const unacknowledgedCount = staleDirectWork.filter((r) => r.staleDispatchUnacknowledged).length;
|
|
10332
|
+
if (unacknowledgedCount > 0) {
|
|
10333
|
+
summary.staleDirectUnacknowledgedCount = unacknowledgedCount;
|
|
10334
|
+
}
|
|
10335
|
+
const staleDirectWorkNote = staleDirectWork.length > 0 ? unacknowledgedCount > 0 && unacknowledgedCount === staleDirectWork.length ? `${unacknowledgedCount} direct dispatch(es) were not acknowledged by the target session \u2014 the session received the agent_command but never transitioned to generating. This is a fresh dispatch failure, not historical noise. Recovery: launch a fresh session on the same node and retry the task, or use mesh_enqueue_task for queue-based assignment.` : unacknowledgedCount > 0 ? `${unacknowledgedCount} of ${staleDirectWork.length} stale direct record(s) are fresh unacknowledged dispatch failures (session still live but never transitioned to generating); the rest are orphaned historical entries whose node/session no longer exists. Fresh unacknowledged dispatches need recovery: launch a fresh session and retry. Orphaned entries are historical evidence only \u2014 not active or unresolved work.` : "These are orphaned ledger entries whose original node or session no longer exists in the live mesh. They are historical/recovery evidence only \u2014 not active or unresolved work. Do not treat staleDirectCount as a status mismatch; use the queue (source: queue) as authoritative for pending/assigned tasks." : void 0;
|
|
10297
10336
|
if (staleDirectWorkNote) {
|
|
10298
10337
|
summary.staleDirectNote = staleDirectWorkNote;
|
|
10299
10338
|
}
|
|
@@ -21328,7 +21367,10 @@ var CliProviderInstance = class {
|
|
|
21328
21367
|
if (!isCliGeneratingLikeStatus(parsedRawStatus)) return false;
|
|
21329
21368
|
if (adapterRawStatus !== "idle") return false;
|
|
21330
21369
|
if (hasNonEmptyCliModalButtons(parsedStatus?.activeModal ?? parsedStatus?.modal)) return false;
|
|
21331
|
-
|
|
21370
|
+
if (this.hasAdapterPendingResponse()) return false;
|
|
21371
|
+
const adapterAny = this.adapter;
|
|
21372
|
+
if (typeof adapterAny?.responseBuffer === "string" && adapterAny.responseBuffer.trim()) return false;
|
|
21373
|
+
return true;
|
|
21332
21374
|
}
|
|
21333
21375
|
getCompletedFinalizationBlock(latestVisibleStatus) {
|
|
21334
21376
|
if (latestVisibleStatus !== "idle") return { reason: `status:${latestVisibleStatus}`, terminal: true };
|
|
@@ -21526,13 +21568,30 @@ var CliProviderInstance = class {
|
|
|
21526
21568
|
} else if (newStatus === "idle" && (this.lastStatus === "generating" || this.lastStatus === "waiting_approval")) {
|
|
21527
21569
|
const duration = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : 0;
|
|
21528
21570
|
if (this.generatingDebouncePending) {
|
|
21529
|
-
|
|
21571
|
+
const shortDurationMs = this.generatingStartedAt ? now - this.generatingStartedAt : 0;
|
|
21572
|
+
LOG.info("CLI", `[${this.type}] suppressed short generating (${shortDurationMs}ms)`);
|
|
21530
21573
|
if (this.generatingDebounceTimer) {
|
|
21531
21574
|
clearTimeout(this.generatingDebounceTimer);
|
|
21532
21575
|
this.generatingDebounceTimer = null;
|
|
21533
21576
|
}
|
|
21534
21577
|
this.generatingDebouncePending = null;
|
|
21535
21578
|
this.generatingStartedAt = 0;
|
|
21579
|
+
let shortFinalSummary;
|
|
21580
|
+
try {
|
|
21581
|
+
shortFinalSummary = extractFinalSummaryFromMessages(this.adapter?.getScriptParsedStatus()?.messages);
|
|
21582
|
+
} catch {
|
|
21583
|
+
}
|
|
21584
|
+
this.pushEvent({
|
|
21585
|
+
event: "agent:generating_completed",
|
|
21586
|
+
chatTitle,
|
|
21587
|
+
duration: 0,
|
|
21588
|
+
timestamp: now,
|
|
21589
|
+
finalSummary: shortFinalSummary,
|
|
21590
|
+
completionDiagnostic: {
|
|
21591
|
+
reason: "short_generating_suppressed",
|
|
21592
|
+
shortDurationMs
|
|
21593
|
+
}
|
|
21594
|
+
});
|
|
21536
21595
|
} else {
|
|
21537
21596
|
this.completedDebouncePending = { chatTitle, duration, timestamp: now, firstObservedAt: now };
|
|
21538
21597
|
this.scheduleCompletedDebounceFlush(3e3);
|