@adhdev/daemon-standalone 0.9.82-rc.77 → 0.9.82-rc.79
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 +231 -83
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/vendor/mcp-server/index.js +9 -2
- package/vendor/mcp-server/index.js.map +1 -1
package/dist/index.js
CHANGED
|
@@ -23254,25 +23254,42 @@ ${userInstruction}`);
|
|
|
23254
23254
|
return sections.join("\n\n");
|
|
23255
23255
|
}
|
|
23256
23256
|
function buildNodeStatusSection(nodes) {
|
|
23257
|
-
const lines = [
|
|
23257
|
+
const lines = [
|
|
23258
|
+
"## Current Node Status",
|
|
23259
|
+
"",
|
|
23260
|
+
"Node labels are display context, not aliases. Use exact `nodeId` values in mesh tool calls; do not invent shorthand names such as M1/M2 unless they are explicitly configured labels.",
|
|
23261
|
+
""
|
|
23262
|
+
];
|
|
23258
23263
|
for (const n of nodes) {
|
|
23259
23264
|
const healthIcon = n.health === "online" ? "\u{1F7E2}" : n.health === "dirty" ? "\u{1F7E1}" : n.health === "offline" ? "\u26AB" : "\u{1F534}";
|
|
23260
23265
|
const sessions = n.activeSessions.length > 0 ? `sessions: ${n.activeSessions.join(", ")}` : "no active sessions";
|
|
23261
23266
|
const branch = n.git?.branch ? `branch: \`${n.git.branch}\`` : "";
|
|
23262
|
-
|
|
23263
|
-
|
|
23267
|
+
const context = [
|
|
23268
|
+
n.daemonId ? `daemon: \`${n.daemonId}\`` : "",
|
|
23269
|
+
n.providers?.length ? `providers: ${n.providers.join(", ")}` : ""
|
|
23270
|
+
].filter(Boolean).join(" | ");
|
|
23271
|
+
lines.push(`- ${healthIcon} **${n.machineLabel}** (nodeId: \`${n.nodeId}\`)`);
|
|
23272
|
+
lines.push(` workspace: \`${n.workspace}\`${context ? ` | ${context}` : ""} | ${branch} | ${sessions}`);
|
|
23264
23273
|
if (n.error) lines.push(` \u26A0\uFE0F ${n.error}`);
|
|
23265
23274
|
}
|
|
23266
23275
|
return lines.join("\n");
|
|
23267
23276
|
}
|
|
23268
23277
|
function buildNodeConfigSection(mesh) {
|
|
23269
|
-
const lines = [
|
|
23278
|
+
const lines = [
|
|
23279
|
+
"## Configured Nodes",
|
|
23280
|
+
"",
|
|
23281
|
+
"Node labels are display context, not aliases. Use exact `nodeId` values in mesh tool calls; do not invent shorthand names such as M1/M2 unless they are explicitly configured labels.",
|
|
23282
|
+
""
|
|
23283
|
+
];
|
|
23270
23284
|
for (const n of mesh.nodes) {
|
|
23271
23285
|
const labels = [];
|
|
23272
23286
|
if (n.isLocalWorktree) labels.push("worktree");
|
|
23273
23287
|
if (n.policy?.readOnly) labels.push("read-only");
|
|
23274
23288
|
const suffix = labels.length ? ` [${labels.join(", ")}]` : "";
|
|
23275
|
-
|
|
23289
|
+
const explicitMachineLabel = typeof n.machineLabel === "string" ? n.machineLabel : "";
|
|
23290
|
+
const explicitLabel = explicitMachineLabel ? ` label: **${explicitMachineLabel}** |` : "";
|
|
23291
|
+
const providerPriority = n.policy?.providerPriority?.length ? ` | providers: ${n.policy.providerPriority.join(", ")}` : "";
|
|
23292
|
+
lines.push(`- ${explicitLabel} nodeId: \`${n.id}\` | workspace: \`${n.workspace}\`${n.daemonId ? ` | daemon: \`${n.daemonId}\`` : ""}${providerPriority}${suffix}`);
|
|
23276
23293
|
}
|
|
23277
23294
|
lines.push("", "_Use `mesh_status` to probe live health before delegating work._");
|
|
23278
23295
|
return lines.join("\n");
|
|
@@ -23313,7 +23330,7 @@ ${rules.join("\n")}`;
|
|
|
23313
23330
|
- **Clean up worktree nodes.** After a worktree task completes and its changes are merged or checkpointed, call \`mesh_remove_node\` to free resources.
|
|
23314
23331
|
- **Do not strand completed branches.** A checkpointed or clean feature/worktree branch is not done by itself. Merge/refine it to the mesh default branch, fast-forward obvious clean behind-only branches with \`mesh_fast_forward_node\`, or explicitly report one of \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\` with the next action.
|
|
23315
23332
|
- **Keep Refinery validation project-configurable.** \`mesh_refine_node\` must execute validation from repo mesh/refine config (for example \`.adhdev/refine.{json,yaml,yml}\`, \`.adhdev/repo-mesh-refine.*\`, or \`repo-mesh.refine.*\`). Heuristics are suggestions/scaffolding only, not the execution path.
|
|
23316
|
-
- **Treat submodule reachability as publish-needed.** A \`submodule_reachability_failed\` refine result means the root gitlink points at a submodule commit that is not reachable from the configured submodule remote. Do not retry validation blindly or start code review first. Classify it as \`blocked_review\`, request user approval to push/publish the submodule commit, then rerun \`mesh_refine_node\`.
|
|
23333
|
+
- **Treat submodule main reachability as publish-needed.** A \`submodule_reachability_failed\` refine result means the root gitlink points at a submodule commit that is not reachable from the configured submodule remote main branch. Do not treat feature-branch reachability as complete, retry validation blindly, or start code review first. Classify it as \`blocked_review\`, request user approval to push/publish the submodule commit to submodule main, then rerun \`mesh_refine_node\`.
|
|
23317
23334
|
- **Name worktree branches meaningfully.** Use descriptive names like \`feat/auth-refactor\` or \`fix/build-123\`.${coordinatorNote}`;
|
|
23318
23335
|
}
|
|
23319
23336
|
var TOOLS_SECTION;
|
|
@@ -23362,7 +23379,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
23362
23379
|
4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Use \`mesh_view_queue\` to see the status of all pending, assigned, completed, and failed tasks. Do not call \`mesh_read_chat\` again within a few seconds for the same generating session. Use at most one compact \`mesh_read_chat\` check after a completion/approval signal. Handle approvals via \`mesh_approve\`.
|
|
23363
23380
|
5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
|
|
23364
23381
|
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
23365
|
-
7. **Converge branches** \u2014 Before marking any task complete, classify every touched node/branch into exactly one final state: \`merged_to_main\`, \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\`. Use \`mesh_status\` branchConvergenceSummary. For obvious clean branch catch-up (ahead 0, behind > 0, upstream fresh, no dirty/stash/submodule issues), use \`mesh_fast_forward_node\` dry-run first and execute only when explicitly safe/approved; this avoids consuming an agent session. Use \`mesh_refine_node\` for clean worktree branches when safe. Before/refine merging root commits that contain submodule gitlink changes, require each submodule commit to be reachable from
|
|
23382
|
+
7. **Converge branches** \u2014 Before marking any task complete, classify every touched node/branch into exactly one final state: \`merged_to_main\`, \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\`. Use \`mesh_status\` branchConvergenceSummary. For obvious clean branch catch-up (ahead 0, behind > 0, upstream fresh, no dirty/stash/submodule issues), use \`mesh_fast_forward_node\` dry-run first and execute only when explicitly safe/approved; this avoids consuming an agent session. Use \`mesh_refine_node\` for clean worktree branches when safe. Before/refine merging root commits that contain submodule gitlink changes, require each submodule commit to be reachable from the configured submodule remote main branch, not merely present on a feature ref or local checkout. If \`mesh_refine_node\` returns \`submodule_reachability_failed\` or publish-required evidence, keep the public convergence bucket as \`blocked_review\`, ask the user for explicit approval to push/publish the unreachable submodule commit(s) to submodule main, then rerun \`mesh_refine_node\`; do not merge the root branch until the submodule commit(s) are reachable from submodule origin/main. A task that remains on a non-main branch is not fully complete unless the final report names the follow-up state and next step.
|
|
23366
23383
|
8. **Clean up** \u2014 Remove worktree nodes via \`mesh_remove_node\` after their work is merged or no longer needed.
|
|
23367
23384
|
9. **Report** \u2014 Summarize what was done, what changed, any issues, and the branch convergence state.
|
|
23368
23385
|
|
|
@@ -25201,23 +25218,54 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
25201
25218
|
const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
|
|
25202
25219
|
const result = readRecord(args.metadataEvent.result);
|
|
25203
25220
|
const validationSummary = readRecord(result?.validationSummary);
|
|
25221
|
+
const patchEquivalence = readRecord(result?.patchEquivalence);
|
|
25222
|
+
const finalConvergence = readRecord(result?.finalBranchConvergenceState);
|
|
25204
25223
|
const validationStatus = readNonEmptyString2(validationSummary?.status);
|
|
25224
|
+
const patchStatus = readNonEmptyString2(patchEquivalence?.status) || (patchEquivalence?.equivalent === true ? "passed" : "");
|
|
25205
25225
|
const into = readNonEmptyString2(result?.into);
|
|
25206
25226
|
const branch = readNonEmptyString2(result?.branch);
|
|
25227
|
+
const mergeStatus = result?.merged === true ? "merged" : readNonEmptyString2(finalConvergence?.status);
|
|
25228
|
+
const convergenceStatus = readNonEmptyString2(finalConvergence?.status);
|
|
25229
|
+
const nextStep = readNonEmptyString2(result?.nextStep) || readNonEmptyString2(finalConvergence?.nextStep) || "Continue from the updated mesh state.";
|
|
25207
25230
|
const details = [
|
|
25208
25231
|
jobId ? `job_id=${jobId}` : "",
|
|
25209
25232
|
branch && into ? `${branch}\u2192${into}` : "",
|
|
25210
|
-
validationStatus ? `validation=${validationStatus}` : ""
|
|
25233
|
+
validationStatus ? `validation=${validationStatus}` : "",
|
|
25234
|
+
patchStatus ? `patch_equivalence=${patchStatus}` : "",
|
|
25235
|
+
mergeStatus ? `merge=${mergeStatus}` : "",
|
|
25236
|
+
convergenceStatus ? `final_convergence=${convergenceStatus}` : ""
|
|
25211
25237
|
].filter(Boolean).join("; ");
|
|
25212
|
-
return `[System] Refinery async job for ${args.nodeLabel} completed successfully${details ? ` (${details})` : ""}.
|
|
25238
|
+
return `[System] Refinery async job for ${args.nodeLabel} completed successfully${details ? ` (${details})` : ""}.
|
|
25239
|
+
Next step: ${nextStep}`;
|
|
25213
25240
|
}
|
|
25214
25241
|
if (args.event === "refine:failed") {
|
|
25215
25242
|
const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
|
|
25216
25243
|
const result = readRecord(args.metadataEvent.result);
|
|
25244
|
+
const validationSummary = readRecord(result?.validationSummary);
|
|
25245
|
+
const patchEquivalence = readRecord(result?.patchEquivalence);
|
|
25246
|
+
const finalConvergence = readRecord(result?.finalBranchConvergenceState);
|
|
25217
25247
|
const code = readNonEmptyString2(result?.code);
|
|
25218
25248
|
const error48 = readNonEmptyString2(result?.error);
|
|
25219
|
-
const
|
|
25220
|
-
|
|
25249
|
+
const validationStatus = readNonEmptyString2(validationSummary?.status);
|
|
25250
|
+
const patchStatus = readNonEmptyString2(patchEquivalence?.status) || (patchEquivalence?.equivalent === true ? "passed" : "");
|
|
25251
|
+
const mergeStatus = result?.merged === true ? "merged" : finalConvergence?.merged === false ? "not_merged" : "";
|
|
25252
|
+
const convergenceStatus = readNonEmptyString2(result?.convergenceStatus) || readNonEmptyString2(finalConvergence?.status);
|
|
25253
|
+
const blockedReason = readNonEmptyString2(result?.blockedReason);
|
|
25254
|
+
const nextStep = readNonEmptyString2(result?.nextStep) || readNonEmptyString2(finalConvergence?.nextStep);
|
|
25255
|
+
const details = [
|
|
25256
|
+
jobId ? `job_id=${jobId}` : "",
|
|
25257
|
+
code ? `code=${code}` : "",
|
|
25258
|
+
validationStatus ? `validation=${validationStatus}` : "",
|
|
25259
|
+
patchStatus ? `patch_equivalence=${patchStatus}` : "",
|
|
25260
|
+
mergeStatus ? `merge=${mergeStatus}` : "",
|
|
25261
|
+
convergenceStatus ? `convergence=${convergenceStatus}` : "",
|
|
25262
|
+
blockedReason ? `reason=${blockedReason}` : ""
|
|
25263
|
+
].filter(Boolean).join("; ");
|
|
25264
|
+
const parts = [
|
|
25265
|
+
`[System] Refinery async job for ${args.nodeLabel} failed${details ? ` (${details})` : ""}${error48 ? `: ${error48}` : "."}`,
|
|
25266
|
+
nextStep ? `Next step: ${nextStep}` : "Review the terminal refine event/ledger before retrying."
|
|
25267
|
+
];
|
|
25268
|
+
return parts.join("\n");
|
|
25221
25269
|
}
|
|
25222
25270
|
return "";
|
|
25223
25271
|
}
|
|
@@ -25339,7 +25387,8 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
25339
25387
|
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
25340
25388
|
}
|
|
25341
25389
|
if (sessionId) {
|
|
25342
|
-
updateSessionTaskStatus(args.meshId, sessionId, "failed");
|
|
25390
|
+
const failedTask = updateSessionTaskStatus(args.meshId, sessionId, "failed");
|
|
25391
|
+
completedTaskForLedger = failedTask ? { id: failedTask.id } : null;
|
|
25343
25392
|
}
|
|
25344
25393
|
}
|
|
25345
25394
|
const ledgerKind = EVENT_TO_LEDGER_KIND[args.event];
|
|
@@ -25434,6 +25483,13 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
25434
25483
|
LOG2.warn("MeshRecovery", `Failed to build recovery context: ${e?.message || e}`);
|
|
25435
25484
|
}
|
|
25436
25485
|
}
|
|
25486
|
+
const messageText = buildMeshSystemMessage({
|
|
25487
|
+
event: args.event,
|
|
25488
|
+
nodeLabel: args.nodeLabel,
|
|
25489
|
+
metadataEvent: args.metadataEvent,
|
|
25490
|
+
recoveryContext
|
|
25491
|
+
});
|
|
25492
|
+
if (!messageText) return { success: false, error: "unsupported mesh event" };
|
|
25437
25493
|
const coordinatorInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
25438
25494
|
const instState = inst.getState();
|
|
25439
25495
|
if (instState.settings?.meshCoordinatorFor !== args.meshId) return false;
|
|
@@ -25451,19 +25507,13 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
25451
25507
|
...args.metadataEvent,
|
|
25452
25508
|
...recoveryContext ? { recoveryContext } : {}
|
|
25453
25509
|
},
|
|
25510
|
+
coordinatorMessage: messageText,
|
|
25454
25511
|
queuedAt: Date.now()
|
|
25455
25512
|
})) {
|
|
25456
25513
|
LOG2.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
|
|
25457
25514
|
}
|
|
25458
25515
|
return { success: true, forwarded: 0 };
|
|
25459
25516
|
}
|
|
25460
|
-
const messageText = buildMeshSystemMessage({
|
|
25461
|
-
event: args.event,
|
|
25462
|
-
nodeLabel: args.nodeLabel,
|
|
25463
|
-
metadataEvent: args.metadataEvent,
|
|
25464
|
-
recoveryContext
|
|
25465
|
-
});
|
|
25466
|
-
if (!messageText) return { success: false, error: "unsupported mesh event" };
|
|
25467
25517
|
for (const coord of coordinatorInstances) {
|
|
25468
25518
|
const coordState = coord.getState();
|
|
25469
25519
|
LOG2.info("MeshEvents", `Forwarding mesh event to coordinator ${coordState.instanceId}`);
|
|
@@ -31389,9 +31439,11 @@ ${lastSnapshot}`;
|
|
|
31389
31439
|
return Number.isFinite(started) ? Math.max(0, now - started) : 0;
|
|
31390
31440
|
}
|
|
31391
31441
|
function sessionStatusFromNodes(nodes, nodeId, sessionId) {
|
|
31392
|
-
if (!
|
|
31442
|
+
if (!Array.isArray(nodes)) return {};
|
|
31443
|
+
if (!nodeId) return { staleReason: "direct task has no node id" };
|
|
31393
31444
|
const node = nodes.find((item) => readString2(item?.id) === nodeId || readString2(item?.nodeId) === nodeId || readString2(item?.node_id) === nodeId);
|
|
31394
|
-
if (!node) return
|
|
31445
|
+
if (!node) return { staleReason: "direct task node is no longer in the live mesh" };
|
|
31446
|
+
if (!sessionId) return {};
|
|
31395
31447
|
const candidates = [];
|
|
31396
31448
|
for (const value of [node.sessions, node.activeSessions, node.active_sessions, node.lastProbe?.sessions, node.last_probe?.sessions, node.lastProbe?.status?.sessions, node.last_probe?.status?.sessions]) {
|
|
31397
31449
|
if (Array.isArray(value)) candidates.push(...value);
|
|
@@ -31400,16 +31452,18 @@ ${lastSnapshot}`;
|
|
|
31400
31452
|
if (value && typeof value === "object") candidates.push(value);
|
|
31401
31453
|
}
|
|
31402
31454
|
const session = candidates.find((item) => {
|
|
31455
|
+
if (typeof item === "string") return item === sessionId;
|
|
31403
31456
|
const id = readString2(item?.id) || readString2(item?.sessionId) || readString2(item?.session_id) || readString2(item?.runtimeSessionId) || readString2(item?.instanceId);
|
|
31404
31457
|
return id === sessionId;
|
|
31405
31458
|
});
|
|
31406
|
-
if (!session) return
|
|
31459
|
+
if (!session) return { staleReason: "direct task session is not present in live session records" };
|
|
31460
|
+
if (typeof session === "string") return {};
|
|
31407
31461
|
const raw = `${readString2(session.status) || ""} ${readString2(session.lifecycle) || ""} ${readString2(session.state) || ""} ${readString2(session.activeChat?.status) || ""}`.toLowerCase();
|
|
31408
|
-
if (raw.includes("approval")) return "awaiting_approval";
|
|
31409
|
-
if (raw.includes("generating") || raw.includes("running") || raw.includes("busy")) return "generating";
|
|
31410
|
-
if (raw.includes("failed") || raw.includes("stopped") || raw.includes("terminated") || raw.includes("exited")) return "failed";
|
|
31411
|
-
if (raw.includes("idle") || raw.includes("waiting_input") || raw.includes("ready")) return "idle";
|
|
31412
|
-
return
|
|
31462
|
+
if (raw.includes("approval")) return { status: "awaiting_approval" };
|
|
31463
|
+
if (raw.includes("generating") || raw.includes("running") || raw.includes("busy")) return { status: "generating" };
|
|
31464
|
+
if (raw.includes("failed") || raw.includes("stopped") || raw.includes("terminated") || raw.includes("exited")) return { status: "failed" };
|
|
31465
|
+
if (raw.includes("idle") || raw.includes("waiting_input") || raw.includes("ready")) return { status: "idle" };
|
|
31466
|
+
return {};
|
|
31413
31467
|
}
|
|
31414
31468
|
function isDirectDispatch(entry) {
|
|
31415
31469
|
if (entry.kind !== "task_dispatched") return false;
|
|
@@ -31456,15 +31510,17 @@ ${lastSnapshot}`;
|
|
|
31456
31510
|
failedCount: statusCounts.failed,
|
|
31457
31511
|
idleCount: statusCounts.idle,
|
|
31458
31512
|
sourceCounts,
|
|
31459
|
-
statusCounts
|
|
31513
|
+
statusCounts,
|
|
31514
|
+
staleDirectCount: activeWork.filter((item) => item.source === "direct" && item.staleReason).length
|
|
31460
31515
|
};
|
|
31461
31516
|
}
|
|
31462
31517
|
function buildMeshActiveWork(opts) {
|
|
31463
31518
|
const now = opts.now ?? Date.now();
|
|
31464
31519
|
const records = [];
|
|
31520
|
+
const staleDirectWork = [];
|
|
31465
31521
|
for (const task of opts.queue || []) {
|
|
31466
31522
|
if (task.status !== "pending" && task.status !== "assigned") continue;
|
|
31467
|
-
const { title, summary } = summarizeMessage(task.message || "");
|
|
31523
|
+
const { title, summary: summary2 } = summarizeMessage(task.message || "");
|
|
31468
31524
|
records.push({
|
|
31469
31525
|
taskId: task.id,
|
|
31470
31526
|
source: "queue",
|
|
@@ -31472,7 +31528,7 @@ ${lastSnapshot}`;
|
|
|
31472
31528
|
nodeId: task.assignedNodeId || task.targetNodeId,
|
|
31473
31529
|
sessionId: task.assignedSessionId || task.targetSessionId,
|
|
31474
31530
|
taskTitle: title,
|
|
31475
|
-
taskSummary:
|
|
31531
|
+
taskSummary: summary2,
|
|
31476
31532
|
message: task.message,
|
|
31477
31533
|
taskMode: task.taskMode,
|
|
31478
31534
|
createdAt: task.createdAt,
|
|
@@ -31487,13 +31543,13 @@ ${lastSnapshot}`;
|
|
|
31487
31543
|
const taskId = directDispatchTaskId(dispatch);
|
|
31488
31544
|
const terminal = terminals.filter((entry) => new Date(entry.timestamp).getTime() >= new Date(dispatch.timestamp).getTime()).find((entry) => terminalMatchesDispatch(entry, dispatch, taskId));
|
|
31489
31545
|
const terminalStatus = terminal ? statusFromTerminal(terminal) : void 0;
|
|
31490
|
-
const
|
|
31491
|
-
const status = terminalStatus ||
|
|
31546
|
+
const live = sessionStatusFromNodes(opts.nodes, dispatch.nodeId, dispatch.sessionId);
|
|
31547
|
+
const status = terminalStatus || live.status || "assigned";
|
|
31492
31548
|
const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
|
|
31493
31549
|
if (terminalRow && opts.includeTerminalDirect !== true) continue;
|
|
31494
31550
|
const message = readString2(dispatch.payload?.message) || readString2(dispatch.payload?.summary) || "";
|
|
31495
|
-
const { title, summary } = summarizeMessage(message);
|
|
31496
|
-
|
|
31551
|
+
const { title, summary: summary2 } = summarizeMessage(message);
|
|
31552
|
+
const record2 = {
|
|
31497
31553
|
taskId,
|
|
31498
31554
|
source: "direct",
|
|
31499
31555
|
status,
|
|
@@ -31501,7 +31557,7 @@ ${lastSnapshot}`;
|
|
|
31501
31557
|
sessionId: dispatch.sessionId,
|
|
31502
31558
|
providerType: dispatch.providerType || readString2(dispatch.payload?.providerType),
|
|
31503
31559
|
taskTitle: readString2(dispatch.payload?.taskTitle) || title,
|
|
31504
|
-
taskSummary: readString2(dispatch.payload?.taskSummary) ||
|
|
31560
|
+
taskSummary: readString2(dispatch.payload?.taskSummary) || summary2,
|
|
31505
31561
|
message,
|
|
31506
31562
|
taskMode: readString2(dispatch.payload?.taskMode),
|
|
31507
31563
|
createdAt: dispatch.timestamp,
|
|
@@ -31510,11 +31566,20 @@ ${lastSnapshot}`;
|
|
|
31510
31566
|
elapsedMs: elapsedSince(dispatch.timestamp, now),
|
|
31511
31567
|
terminal: terminalRow,
|
|
31512
31568
|
terminalKind: terminal?.kind,
|
|
31513
|
-
terminalAt: terminal?.timestamp
|
|
31514
|
-
|
|
31569
|
+
terminalAt: terminal?.timestamp,
|
|
31570
|
+
staleReason: live.staleReason
|
|
31571
|
+
};
|
|
31572
|
+
if (live.staleReason && !terminalRow) {
|
|
31573
|
+
staleDirectWork.push(record2);
|
|
31574
|
+
continue;
|
|
31575
|
+
}
|
|
31576
|
+
records.push(record2);
|
|
31515
31577
|
}
|
|
31516
31578
|
records.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
31517
|
-
|
|
31579
|
+
staleDirectWork.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
31580
|
+
const summary = buildMeshActiveWorkSummary(records);
|
|
31581
|
+
summary.staleDirectCount = staleDirectWork.length;
|
|
31582
|
+
return { activeWork: records, staleDirectWork, summary };
|
|
31518
31583
|
}
|
|
31519
31584
|
init_mesh_host_ownership();
|
|
31520
31585
|
init_mesh_events();
|
|
@@ -41699,23 +41764,28 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41699
41764
|
if (hasNonEmptyCliModalButtons(parsedStatus?.activeModal ?? parsedStatus?.modal)) return false;
|
|
41700
41765
|
return !this.hasAdapterPendingResponse();
|
|
41701
41766
|
}
|
|
41702
|
-
|
|
41703
|
-
if (latestVisibleStatus !== "idle") return `status:${latestVisibleStatus}
|
|
41767
|
+
getCompletedFinalizationBlock(latestVisibleStatus) {
|
|
41768
|
+
if (latestVisibleStatus !== "idle") return { reason: `status:${latestVisibleStatus}`, terminal: true };
|
|
41704
41769
|
const adapterAny = this.adapter;
|
|
41705
|
-
if (adapterAny?.isWaitingForResponse === true) return "adapter_waiting_for_response";
|
|
41706
|
-
if (adapterAny?.currentTurnScope) return "adapter_turn_scope_active";
|
|
41770
|
+
if (adapterAny?.isWaitingForResponse === true) return { reason: "adapter_waiting_for_response", terminal: true };
|
|
41771
|
+
if (adapterAny?.currentTurnScope) return { reason: "adapter_turn_scope_active", terminal: true };
|
|
41772
|
+
if (this.hasAdapterPendingResponse()) return { reason: "adapter_pending_response", terminal: true };
|
|
41707
41773
|
const partial2 = typeof this.adapter.getPartialResponse === "function" ? this.adapter.getPartialResponse() : "";
|
|
41708
|
-
if (typeof partial2 === "string" && partial2.trim()) return "partial_response_pending";
|
|
41774
|
+
if (typeof partial2 === "string" && partial2.trim()) return { reason: "partial_response_pending", terminal: true };
|
|
41709
41775
|
let parsed;
|
|
41710
41776
|
try {
|
|
41711
41777
|
parsed = this.adapter.getScriptParsedStatus();
|
|
41712
41778
|
} catch (error48) {
|
|
41713
|
-
return `parse_error:${error48?.message || String(error48)}
|
|
41779
|
+
return { reason: `parse_error:${error48?.message || String(error48)}` };
|
|
41714
41780
|
}
|
|
41715
41781
|
const parsedStatus = typeof parsed?.status === "string" ? parsed.status : "unknown";
|
|
41716
|
-
if (parsedStatus !== "idle")
|
|
41717
|
-
|
|
41718
|
-
|
|
41782
|
+
if (parsedStatus !== "idle") {
|
|
41783
|
+
const adapterStatus = this.adapter.getStatus({ allowParse: false });
|
|
41784
|
+
if (this.shouldSuppressStaleParsedBusyStatus(parsed, adapterStatus)) return null;
|
|
41785
|
+
return { reason: `parsed_status:${parsedStatus}`, terminal: isCliGeneratingLikeStatus(parsedStatus) };
|
|
41786
|
+
}
|
|
41787
|
+
if (parsed?.activeModal || parsed?.modal) return { reason: "parsed_modal_active", terminal: true };
|
|
41788
|
+
if (!this.completionHasFinalAssistantMessage(parsed?.messages)) return { reason: "missing_final_assistant" };
|
|
41719
41789
|
return null;
|
|
41720
41790
|
}
|
|
41721
41791
|
scheduleCompletedDebounceFlush(delayMs) {
|
|
@@ -41737,10 +41807,11 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41737
41807
|
this.completedDebounceTimer = null;
|
|
41738
41808
|
return;
|
|
41739
41809
|
}
|
|
41740
|
-
const
|
|
41741
|
-
if (
|
|
41810
|
+
const block2 = this.getCompletedFinalizationBlock(latestVisibleStatus);
|
|
41811
|
+
if (block2) {
|
|
41812
|
+
const blockReason = block2.reason;
|
|
41742
41813
|
const waitedMs = Date.now() - pending.firstObservedAt;
|
|
41743
|
-
if (waitedMs < COMPLETED_FINALIZATION_MAX_WAIT_MS) {
|
|
41814
|
+
if (block2.terminal || waitedMs < COMPLETED_FINALIZATION_MAX_WAIT_MS) {
|
|
41744
41815
|
if (pending.loggedBlockReason !== blockReason) {
|
|
41745
41816
|
LOG2.info("CLI", `[${this.type}] waiting to emit completed until transcript finalizes (${blockReason})`);
|
|
41746
41817
|
pending.loggedBlockReason = blockReason;
|
|
@@ -43596,6 +43667,47 @@ ${rawInput}` : rawInput;
|
|
|
43596
43667
|
function normalizeAgentStatus(value) {
|
|
43597
43668
|
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
43598
43669
|
}
|
|
43670
|
+
function hasNonEmptyModalButtons2(activeModal) {
|
|
43671
|
+
const buttons = activeModal?.buttons;
|
|
43672
|
+
return Array.isArray(buttons) && buttons.some((button) => String(button || "").trim().length > 0);
|
|
43673
|
+
}
|
|
43674
|
+
function hasAdapterPendingResponse(adapter) {
|
|
43675
|
+
if (adapter?.isWaitingForResponse === true) return true;
|
|
43676
|
+
if (adapter?.currentTurnScope) return true;
|
|
43677
|
+
try {
|
|
43678
|
+
if (typeof adapter?.isProcessing === "function" && adapter.isProcessing()) return true;
|
|
43679
|
+
} catch {
|
|
43680
|
+
}
|
|
43681
|
+
try {
|
|
43682
|
+
const partial2 = typeof adapter?.getPartialResponse === "function" ? adapter.getPartialResponse() : "";
|
|
43683
|
+
if (typeof partial2 === "string" && partial2.trim()) return true;
|
|
43684
|
+
} catch {
|
|
43685
|
+
}
|
|
43686
|
+
return false;
|
|
43687
|
+
}
|
|
43688
|
+
function shouldSuppressStaleParsedBusyStatus(adapterStatus, parsedStatus, adapter) {
|
|
43689
|
+
const parsedRawStatus = normalizeAgentStatus(parsedStatus?.status);
|
|
43690
|
+
if (!BUSY_AGENT_STATUSES.has(parsedRawStatus)) return false;
|
|
43691
|
+
if (adapterStatus !== "idle") return false;
|
|
43692
|
+
if (hasNonEmptyModalButtons2(parsedStatus?.activeModal ?? parsedStatus?.modal)) return false;
|
|
43693
|
+
return !hasAdapterPendingResponse(adapter);
|
|
43694
|
+
}
|
|
43695
|
+
function getEffectiveAgentSendStatus(adapter) {
|
|
43696
|
+
const adapterStatus = normalizeAgentStatus(adapter?.getStatus?.({ allowParse: false })?.status ?? adapter?.getStatus?.()?.status);
|
|
43697
|
+
if (adapterStatus && adapterStatus !== "idle") return adapterStatus;
|
|
43698
|
+
if (adapterStatus !== "idle") return adapterStatus;
|
|
43699
|
+
if (typeof adapter?.getScriptParsedStatus !== "function") return adapterStatus;
|
|
43700
|
+
try {
|
|
43701
|
+
const parsedStatus = adapter.getScriptParsedStatus();
|
|
43702
|
+
const parsedRawStatus = normalizeAgentStatus(parsedStatus?.status);
|
|
43703
|
+
if (BUSY_AGENT_STATUSES.has(parsedRawStatus) && !shouldSuppressStaleParsedBusyStatus(adapterStatus, parsedStatus, adapter)) {
|
|
43704
|
+
return parsedRawStatus;
|
|
43705
|
+
}
|
|
43706
|
+
} catch {
|
|
43707
|
+
return adapterStatus;
|
|
43708
|
+
}
|
|
43709
|
+
return adapterStatus;
|
|
43710
|
+
}
|
|
43599
43711
|
var chalkModule = import_chalk.default;
|
|
43600
43712
|
var chalkApi = typeof chalkModule.yellow === "function" ? chalkModule : chalkModule.default || null;
|
|
43601
43713
|
function colorize(color, text) {
|
|
@@ -44370,7 +44482,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44370
44482
|
if (!found) throw new Error(`CLI agent not running: ${agentType}`);
|
|
44371
44483
|
const { adapter, key } = found;
|
|
44372
44484
|
if (action === "send_chat") {
|
|
44373
|
-
const currentStatus =
|
|
44485
|
+
const currentStatus = getEffectiveAgentSendStatus(adapter);
|
|
44374
44486
|
if (BUSY_AGENT_STATUSES.has(currentStatus)) {
|
|
44375
44487
|
return {
|
|
44376
44488
|
success: false,
|
|
@@ -47831,6 +47943,17 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
47831
47943
|
}).filter((entry) => entry !== null);
|
|
47832
47944
|
return submodules.length > 0 ? submodules : void 0;
|
|
47833
47945
|
}
|
|
47946
|
+
function buildMeshNodeDisplayLabel(node, nodeId, providerPriority) {
|
|
47947
|
+
const explicit = readStringValue(node.machineLabel, node.machine_label, node.machineNickname, node.machine_nickname, node.alias);
|
|
47948
|
+
if (explicit) return explicit;
|
|
47949
|
+
const workspace = readStringValue(node.workspace, node.repoRoot, node.repo_root);
|
|
47950
|
+
const workspaceName = workspace ? (0, import_path8.basename)(workspace) : void 0;
|
|
47951
|
+
const host = readStringValue(node.hostname, node.host, node.daemonId, node.daemon_id, node.machineId, node.machine_id);
|
|
47952
|
+
const provider = providerPriority[0] || (Array.isArray(node.providers) ? readStringValue(...node.providers) : void 0);
|
|
47953
|
+
const parts = [workspaceName, host, provider].filter(Boolean);
|
|
47954
|
+
if (parts.length > 0) return parts.join(" \xB7 ");
|
|
47955
|
+
return nodeId || "unidentified mesh node";
|
|
47956
|
+
}
|
|
47834
47957
|
function normalizeInlineMeshGitStatus(status, node, options) {
|
|
47835
47958
|
const isGitRepo = readBooleanValue(status.isGitRepo);
|
|
47836
47959
|
if (!Object.keys(status).length || isGitRepo === void 0) return void 0;
|
|
@@ -48501,7 +48624,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
48501
48624
|
}
|
|
48502
48625
|
function buildSubmodulePublishRequiredNextStep(entries) {
|
|
48503
48626
|
const refs = entries.map((entry) => `${entry.path}@${entry.commit}`).join(", ");
|
|
48504
|
-
return `Ask the user for explicit approval to push/publish the unreachable submodule commit(s) (${refs}) to
|
|
48627
|
+
return `Ask the user for explicit approval to push/publish the unreachable submodule commit(s) (${refs}) to the configured submodule remote main branch, then rerun mesh_refine_node. Do not merge the root branch until every submodule gitlink commit is reachable from submodule origin/main.`;
|
|
48505
48628
|
}
|
|
48506
48629
|
async function computeGitPatchId(cwd, fromRef, toRef) {
|
|
48507
48630
|
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
@@ -48588,15 +48711,9 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
48588
48711
|
});
|
|
48589
48712
|
return String(stdout || "");
|
|
48590
48713
|
};
|
|
48591
|
-
const
|
|
48592
|
-
|
|
48593
|
-
|
|
48594
|
-
await runGit2(probeDir, ["init", "-q"]);
|
|
48595
|
-
await runGit2(probeDir, ["-c", "protocol.file.allow=always", "fetch", "--depth=1", remoteUrl, commit]);
|
|
48596
|
-
await runGit2(probeDir, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
48597
|
-
} finally {
|
|
48598
|
-
fs11.rmSync(probeDir, { recursive: true, force: true });
|
|
48599
|
-
}
|
|
48714
|
+
const verifyRemoteMainContainsCommit = async (submodulePath, commit, branch = "main") => {
|
|
48715
|
+
await runGit2(submodulePath, ["-c", "protocol.file.allow=always", "fetch", "origin", `refs/heads/${branch}:refs/remotes/origin/${branch}`]);
|
|
48716
|
+
await runGit2(submodulePath, ["merge-base", "--is-ancestor", commit, `refs/remotes/origin/${branch}`]);
|
|
48600
48717
|
};
|
|
48601
48718
|
const treeOutput = await runGit2(repoRoot, ["ls-tree", "-r", "-z", mergedTree]);
|
|
48602
48719
|
const gitlinks = treeOutput.split("\0").filter(Boolean).map((record2) => {
|
|
@@ -48637,15 +48754,18 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
48637
48754
|
entries.push(entry);
|
|
48638
48755
|
continue;
|
|
48639
48756
|
}
|
|
48640
|
-
|
|
48757
|
+
entry.remoteMainBranch = "main";
|
|
48758
|
+
await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, "main");
|
|
48641
48759
|
entry.fetchedFromOrigin = true;
|
|
48642
48760
|
entry.remoteReachable = true;
|
|
48761
|
+
entry.remoteMainReachable = true;
|
|
48643
48762
|
entry.reachable = true;
|
|
48644
48763
|
} catch (e) {
|
|
48645
48764
|
entry.remoteReachable = false;
|
|
48765
|
+
entry.remoteMainReachable = false;
|
|
48646
48766
|
entry.publishRequired = true;
|
|
48647
48767
|
const details = truncateValidationOutput(e?.stderr || e?.message || String(e));
|
|
48648
|
-
entry.error = `Submodule remote reachability check failed for origin: ${details}`;
|
|
48768
|
+
entry.error = `Submodule remote main reachability check failed for origin/main: ${details}`;
|
|
48649
48769
|
}
|
|
48650
48770
|
} catch (e) {
|
|
48651
48771
|
entry.error = truncateValidationOutput(e?.message || String(e));
|
|
@@ -49620,28 +49740,51 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
49620
49740
|
};
|
|
49621
49741
|
}
|
|
49622
49742
|
queueRefineJobEvent(event, handle, result) {
|
|
49623
|
-
|
|
49743
|
+
const metadataEvent = {
|
|
49744
|
+
source: "refine_mesh_node_async_job",
|
|
49745
|
+
jobId: handle.jobId,
|
|
49746
|
+
interactionId: handle.interactionId,
|
|
49747
|
+
meshId: handle.meshId,
|
|
49748
|
+
nodeId: handle.targetNodeId,
|
|
49749
|
+
targetDaemonId: handle.targetDaemonId,
|
|
49750
|
+
workspace: handle.workspace,
|
|
49751
|
+
status: handle.status,
|
|
49752
|
+
startedAt: handle.startedAt,
|
|
49753
|
+
completedAt: handle.completedAt,
|
|
49754
|
+
retryOfJobId: handle.retryOfJobId,
|
|
49755
|
+
...result ? { result } : {}
|
|
49756
|
+
};
|
|
49757
|
+
const eventPayload = {
|
|
49624
49758
|
event,
|
|
49625
49759
|
meshId: handle.meshId,
|
|
49626
49760
|
nodeLabel: handle.targetNodeId,
|
|
49627
49761
|
nodeId: handle.targetNodeId,
|
|
49628
49762
|
workspace: handle.workspace,
|
|
49629
|
-
metadataEvent
|
|
49630
|
-
source: "refine_mesh_node_async_job",
|
|
49631
|
-
jobId: handle.jobId,
|
|
49632
|
-
interactionId: handle.interactionId,
|
|
49633
|
-
meshId: handle.meshId,
|
|
49634
|
-
nodeId: handle.targetNodeId,
|
|
49635
|
-
targetDaemonId: handle.targetDaemonId,
|
|
49636
|
-
workspace: handle.workspace,
|
|
49637
|
-
status: handle.status,
|
|
49638
|
-
startedAt: handle.startedAt,
|
|
49639
|
-
completedAt: handle.completedAt,
|
|
49640
|
-
retryOfJobId: handle.retryOfJobId,
|
|
49641
|
-
...result ? { result } : {}
|
|
49642
|
-
},
|
|
49763
|
+
metadataEvent,
|
|
49643
49764
|
queuedAt: Date.now()
|
|
49644
|
-
}
|
|
49765
|
+
};
|
|
49766
|
+
if (typeof this.deps.instanceManager?.getByCategory === "function") {
|
|
49767
|
+
const forwarded = handleMeshForwardEvent(
|
|
49768
|
+
{ instanceManager: this.deps.instanceManager },
|
|
49769
|
+
{
|
|
49770
|
+
event,
|
|
49771
|
+
meshId: handle.meshId,
|
|
49772
|
+
nodeId: handle.targetNodeId,
|
|
49773
|
+
workspace: handle.workspace,
|
|
49774
|
+
jobId: handle.jobId,
|
|
49775
|
+
interactionId: handle.interactionId,
|
|
49776
|
+
status: handle.status,
|
|
49777
|
+
targetDaemonId: handle.targetDaemonId,
|
|
49778
|
+
startedAt: handle.startedAt,
|
|
49779
|
+
completedAt: handle.completedAt,
|
|
49780
|
+
retryOfJobId: handle.retryOfJobId,
|
|
49781
|
+
...result ? { result } : {}
|
|
49782
|
+
}
|
|
49783
|
+
);
|
|
49784
|
+
if (forwarded?.success === true) return;
|
|
49785
|
+
LOG2.warn("Mesh", `[Refinery] Failed to forward async refine event ${event}: ${forwarded?.error || "unknown error"}`);
|
|
49786
|
+
}
|
|
49787
|
+
queuePendingMeshCoordinatorEvent(eventPayload);
|
|
49645
49788
|
}
|
|
49646
49789
|
async appendRefineJobLedger(kind, handle, result) {
|
|
49647
49790
|
try {
|
|
@@ -49793,6 +49936,8 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
49793
49936
|
remote: entry.remote,
|
|
49794
49937
|
remoteUrl: entry.remoteUrl,
|
|
49795
49938
|
remoteReachable: entry.remoteReachable,
|
|
49939
|
+
remoteMainBranch: entry.remoteMainBranch,
|
|
49940
|
+
remoteMainReachable: entry.remoteMainReachable,
|
|
49796
49941
|
error: entry.error
|
|
49797
49942
|
})),
|
|
49798
49943
|
error: submoduleReachability.error
|
|
@@ -49805,13 +49950,13 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
49805
49950
|
convergenceStatus: "blocked_review",
|
|
49806
49951
|
publishRequired: true,
|
|
49807
49952
|
blockedReason: "submodule_publish_required",
|
|
49808
|
-
error: "Refinery submodule reachability preflight failed because one or more submodule gitlink commits are not reachable from their configured remote; merge/refine cleanup was not attempted.",
|
|
49953
|
+
error: "Refinery submodule reachability preflight failed because one or more submodule gitlink commits are not reachable from their configured remote main branch; merge/refine cleanup was not attempted.",
|
|
49809
49954
|
nextStep,
|
|
49810
49955
|
nextSteps: [
|
|
49811
49956
|
"Ask the user for explicit approval before pushing or publishing any submodule commit.",
|
|
49812
|
-
"Push/publish each unreachable submodule commit to the configured submodule remote shown in the evidence.",
|
|
49957
|
+
"Push/publish each unreachable submodule commit to the configured submodule remote main branch shown in the evidence.",
|
|
49813
49958
|
"Rerun mesh_refine_node after remote reachability is confirmed.",
|
|
49814
|
-
"Do not merge the root branch until every submodule gitlink commit is reachable from
|
|
49959
|
+
"Do not merge the root branch until every submodule gitlink commit is reachable from submodule origin/main."
|
|
49815
49960
|
],
|
|
49816
49961
|
unreachableSubmoduleCommits: submoduleReachability.unreachable.map((entry) => ({
|
|
49817
49962
|
path: entry.path,
|
|
@@ -49819,6 +49964,8 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
49819
49964
|
remote: entry.remote,
|
|
49820
49965
|
remoteUrl: entry.remoteUrl,
|
|
49821
49966
|
remoteReachable: entry.remoteReachable,
|
|
49967
|
+
remoteMainBranch: entry.remoteMainBranch,
|
|
49968
|
+
remoteMainReachable: entry.remoteMainReachable,
|
|
49822
49969
|
error: entry.error
|
|
49823
49970
|
})),
|
|
49824
49971
|
branch,
|
|
@@ -51693,7 +51840,8 @@ ${block2}`);
|
|
|
51693
51840
|
) || Boolean(meshRecord?.inline && nodeIndex === 0);
|
|
51694
51841
|
const status = {
|
|
51695
51842
|
nodeId,
|
|
51696
|
-
machineLabel: node
|
|
51843
|
+
machineLabel: buildMeshNodeDisplayLabel(node, nodeId, providerPriority),
|
|
51844
|
+
labelSource: readStringValue(node.machineLabel, node.machine_label, node.machineNickname, node.machine_nickname, node.alias) ? "explicit_metadata" : "workspace_host_provider_context",
|
|
51697
51845
|
workspace: node.workspace,
|
|
51698
51846
|
repoRoot: node.repoRoot,
|
|
51699
51847
|
isLocalWorktree: node.isLocalWorktree,
|