@adhdev/daemon-standalone 0.9.82-rc.52 → 0.9.82-rc.54
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 +390 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22482,9 +22482,9 @@ ${error48.message || ""}`;
|
|
|
22482
22482
|
function parseWorktreeListOutput(output) {
|
|
22483
22483
|
const entries = [];
|
|
22484
22484
|
const blocks = output.trim().split(/\n\n+/);
|
|
22485
|
-
for (const
|
|
22486
|
-
if (!
|
|
22487
|
-
const lines =
|
|
22485
|
+
for (const block2 of blocks) {
|
|
22486
|
+
if (!block2.trim()) continue;
|
|
22487
|
+
const lines = block2.trim().split("\n");
|
|
22488
22488
|
const entry = { path: "", head: "", branch: null, bare: false };
|
|
22489
22489
|
for (const line of lines) {
|
|
22490
22490
|
if (line.startsWith("worktree ")) {
|
|
@@ -23311,7 +23311,8 @@ ${rules.join("\n")}`;
|
|
|
23311
23311
|
- **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
|
|
23312
23312
|
- **Never fabricate tool results.** Always call the actual tool; never pretend you did.
|
|
23313
23313
|
- **Clean up worktree nodes.** After a worktree task completes and its changes are merged or checkpointed, call \`mesh_remove_node\` to free resources.
|
|
23314
|
-
- **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, or explicitly report one of \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\` with the next action.
|
|
23314
|
+
- **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
|
+
- **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.
|
|
23315
23316
|
- **Name worktree branches meaningfully.** Use descriptive names like \`feat/auth-refactor\` or \`fix/build-123\`.${coordinatorNote}`;
|
|
23316
23317
|
}
|
|
23317
23318
|
var TOOLS_SECTION;
|
|
@@ -23337,6 +23338,7 @@ ${rules.join("\n")}`;
|
|
|
23337
23338
|
| \`mesh_read_debug\` | Collect a daemon-side chat/parser debug bundle for a session |
|
|
23338
23339
|
| \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
|
|
23339
23340
|
| \`mesh_git_status\` | Check git status on a specific node |
|
|
23341
|
+
| \`mesh_fast_forward_node\` | Safely dry-run or explicitly execute an obvious clean fast-forward without launching an agent session |
|
|
23340
23342
|
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
23341
23343
|
| \`mesh_approve\` | Approve/reject a pending agent action |
|
|
23342
23344
|
| \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
|
|
@@ -23359,7 +23361,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
23359
23361
|
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\`.
|
|
23360
23362
|
5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
|
|
23361
23363
|
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
23362
|
-
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 and \`mesh_refine_node\` for clean worktree branches when safe. 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.
|
|
23364
|
+
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. 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.
|
|
23363
23365
|
8. **Clean up** \u2014 Remove worktree nodes via \`mesh_remove_node\` after their work is merged or no longer needed.
|
|
23364
23366
|
9. **Report** \u2014 Summarize what was done, what changed, any issues, and the branch convergence state.
|
|
23365
23367
|
|
|
@@ -28363,6 +28365,7 @@ ${lastSnapshot}`;
|
|
|
28363
28365
|
enqueueTask: () => enqueueTask,
|
|
28364
28366
|
ensureSessionHostReady: () => ensureSessionHostReady2,
|
|
28365
28367
|
execNpmCommandSync: () => execNpmCommandSync,
|
|
28368
|
+
fastForwardMeshNode: () => fastForwardMeshNode,
|
|
28366
28369
|
filterActivityChatMessages: () => filterActivityChatMessages,
|
|
28367
28370
|
filterChatMessagesByVisibility: () => filterChatMessagesByVisibility,
|
|
28368
28371
|
filterInternalChatMessages: () => filterInternalChatMessages,
|
|
@@ -30480,6 +30483,354 @@ ${lastSnapshot}`;
|
|
|
30480
30483
|
return result;
|
|
30481
30484
|
}
|
|
30482
30485
|
init_mesh_ledger();
|
|
30486
|
+
init_git_executor();
|
|
30487
|
+
var STATUS_OPTIONS = { refreshUpstream: true, includeSubmodules: true, timeoutMs: 15e3 };
|
|
30488
|
+
async function fastForwardMeshNode(args) {
|
|
30489
|
+
const workspace = typeof args.workspace === "string" ? args.workspace.trim() : "";
|
|
30490
|
+
const nodeId = normalizeOptionalString(args.nodeId);
|
|
30491
|
+
const meshId = normalizeOptionalString(args.meshId);
|
|
30492
|
+
const requestedBranch = normalizeOptionalString(args.branch);
|
|
30493
|
+
const updateSubmodules = args.updateSubmodules === true;
|
|
30494
|
+
const dryRun = args.dryRun === true || args.execute !== true;
|
|
30495
|
+
const plannedSteps = buildPlannedSteps(updateSubmodules);
|
|
30496
|
+
const base = {
|
|
30497
|
+
...nodeId ? { nodeId } : {},
|
|
30498
|
+
...meshId ? { meshId } : {},
|
|
30499
|
+
workspace,
|
|
30500
|
+
dryRun,
|
|
30501
|
+
updateSubmodules,
|
|
30502
|
+
plannedSteps
|
|
30503
|
+
};
|
|
30504
|
+
if (!workspace) {
|
|
30505
|
+
return block(base, "invalid_workspace", ["workspace_required"]);
|
|
30506
|
+
}
|
|
30507
|
+
const current = await getGitRepoStatus(workspace, {
|
|
30508
|
+
...STATUS_OPTIONS,
|
|
30509
|
+
submoduleIgnorePaths: args.submoduleIgnorePaths,
|
|
30510
|
+
timeoutMs: args.timeoutMs ?? STATUS_OPTIONS.timeoutMs
|
|
30511
|
+
});
|
|
30512
|
+
const earlyBlockers = collectPreflightBlockers(current, requestedBranch);
|
|
30513
|
+
if (earlyBlockers.length > 0) {
|
|
30514
|
+
return {
|
|
30515
|
+
...block(base, chooseBlockCode(current, earlyBlockers), earlyBlockers),
|
|
30516
|
+
current,
|
|
30517
|
+
finalBranchConvergenceState: buildConvergenceState(current, codeToConvergenceStatus(chooseBlockCode(current, earlyBlockers)))
|
|
30518
|
+
};
|
|
30519
|
+
}
|
|
30520
|
+
if (current.behind === 0) {
|
|
30521
|
+
const result2 = {
|
|
30522
|
+
...base,
|
|
30523
|
+
success: true,
|
|
30524
|
+
code: "already_up_to_date",
|
|
30525
|
+
allowed: true,
|
|
30526
|
+
willRun: false,
|
|
30527
|
+
executed: false,
|
|
30528
|
+
blockingReasons: [],
|
|
30529
|
+
current,
|
|
30530
|
+
preStatus: current,
|
|
30531
|
+
postStatus: current,
|
|
30532
|
+
finalBranchConvergenceState: buildConvergenceState(current, "up_to_date")
|
|
30533
|
+
};
|
|
30534
|
+
await appendFastForwardLedger(result2, "noop");
|
|
30535
|
+
return result2;
|
|
30536
|
+
}
|
|
30537
|
+
const ancestorCheck = await verifyHeadIsAncestorOfUpstream(workspace, current.upstream || "", args.timeoutMs);
|
|
30538
|
+
if (!ancestorCheck.ok) {
|
|
30539
|
+
const result2 = {
|
|
30540
|
+
...block(base, "non_fast_forward", ["head_is_not_ancestor_of_upstream"]),
|
|
30541
|
+
current,
|
|
30542
|
+
preStatus: current,
|
|
30543
|
+
operationError: ancestorCheck.error,
|
|
30544
|
+
finalBranchConvergenceState: buildConvergenceState(current, "not_mergeable")
|
|
30545
|
+
};
|
|
30546
|
+
await appendFastForwardLedger(result2, "blocked");
|
|
30547
|
+
return result2;
|
|
30548
|
+
}
|
|
30549
|
+
if (dryRun) {
|
|
30550
|
+
const result2 = {
|
|
30551
|
+
...base,
|
|
30552
|
+
success: true,
|
|
30553
|
+
code: "fast_forward_available",
|
|
30554
|
+
allowed: true,
|
|
30555
|
+
willRun: false,
|
|
30556
|
+
executed: false,
|
|
30557
|
+
blockingReasons: [],
|
|
30558
|
+
current,
|
|
30559
|
+
preStatus: current,
|
|
30560
|
+
finalBranchConvergenceState: buildConvergenceState(current, "fast_forward_available")
|
|
30561
|
+
};
|
|
30562
|
+
return result2;
|
|
30563
|
+
}
|
|
30564
|
+
try {
|
|
30565
|
+
await runGit(workspace, ["merge", "--ff-only", current.upstream || ""], { timeoutMs: args.timeoutMs ?? 3e4 });
|
|
30566
|
+
} catch (error48) {
|
|
30567
|
+
const result2 = {
|
|
30568
|
+
...block(base, "merge_ff_only_failed", ["merge_ff_only_failed"]),
|
|
30569
|
+
current,
|
|
30570
|
+
preStatus: current,
|
|
30571
|
+
operationError: formatGitError2(error48),
|
|
30572
|
+
finalBranchConvergenceState: buildConvergenceState(current, "not_mergeable")
|
|
30573
|
+
};
|
|
30574
|
+
await appendFastForwardLedger(result2, "failed");
|
|
30575
|
+
return result2;
|
|
30576
|
+
}
|
|
30577
|
+
let postStatus = await getGitRepoStatus(workspace, {
|
|
30578
|
+
...STATUS_OPTIONS,
|
|
30579
|
+
submoduleIgnorePaths: args.submoduleIgnorePaths,
|
|
30580
|
+
timeoutMs: args.timeoutMs ?? STATUS_OPTIONS.timeoutMs
|
|
30581
|
+
});
|
|
30582
|
+
const submoduleIssues = collectSubmoduleBlockers(postStatus, "post");
|
|
30583
|
+
let submoduleFollowUpRequired = false;
|
|
30584
|
+
let operationError;
|
|
30585
|
+
if (submoduleIssues.length > 0) {
|
|
30586
|
+
if (updateSubmodules) {
|
|
30587
|
+
try {
|
|
30588
|
+
await runGit(workspace, ["submodule", "update", "--init", "--recursive"], { timeoutMs: args.timeoutMs ?? 6e4 });
|
|
30589
|
+
postStatus = await getGitRepoStatus(workspace, {
|
|
30590
|
+
...STATUS_OPTIONS,
|
|
30591
|
+
submoduleIgnorePaths: args.submoduleIgnorePaths,
|
|
30592
|
+
timeoutMs: args.timeoutMs ?? STATUS_OPTIONS.timeoutMs
|
|
30593
|
+
});
|
|
30594
|
+
} catch (error48) {
|
|
30595
|
+
operationError = formatGitError2(error48);
|
|
30596
|
+
}
|
|
30597
|
+
} else {
|
|
30598
|
+
submoduleFollowUpRequired = true;
|
|
30599
|
+
}
|
|
30600
|
+
}
|
|
30601
|
+
const postBlockers = collectPostExecutionBlockers(postStatus);
|
|
30602
|
+
if (operationError) postBlockers.push("submodule_update_failed");
|
|
30603
|
+
if (submoduleFollowUpRequired) postBlockers.push("submodule_update_required");
|
|
30604
|
+
const success2 = postBlockers.length === 0 || submoduleFollowUpRequired;
|
|
30605
|
+
const code = postBlockers.length === 0 ? "fast_forward_applied" : submoduleFollowUpRequired ? "fast_forward_applied_submodule_update_required" : "post_verify_failed";
|
|
30606
|
+
const result = {
|
|
30607
|
+
...base,
|
|
30608
|
+
success: success2,
|
|
30609
|
+
code,
|
|
30610
|
+
allowed: true,
|
|
30611
|
+
willRun: true,
|
|
30612
|
+
executed: true,
|
|
30613
|
+
blockingReasons: postBlockers,
|
|
30614
|
+
current,
|
|
30615
|
+
preStatus: current,
|
|
30616
|
+
postStatus,
|
|
30617
|
+
...operationError ? { operationError } : {},
|
|
30618
|
+
finalBranchConvergenceState: buildConvergenceState(
|
|
30619
|
+
postStatus,
|
|
30620
|
+
postBlockers.length === 0 ? "fast_forwarded" : submoduleFollowUpRequired ? "follow_up_required" : "post_verify_failed"
|
|
30621
|
+
)
|
|
30622
|
+
};
|
|
30623
|
+
await appendFastForwardLedger(result, success2 ? "executed" : "failed");
|
|
30624
|
+
return result;
|
|
30625
|
+
}
|
|
30626
|
+
function buildPlannedSteps(updateSubmodules) {
|
|
30627
|
+
const steps = [
|
|
30628
|
+
{
|
|
30629
|
+
operation: "refresh_upstream",
|
|
30630
|
+
description: "Refresh the tracked upstream remote ref before trusting ahead/behind state.",
|
|
30631
|
+
safe: true,
|
|
30632
|
+
willMutateWorktree: false
|
|
30633
|
+
},
|
|
30634
|
+
{
|
|
30635
|
+
operation: "verify_clean_worktree",
|
|
30636
|
+
description: "Require clean staged/modified/untracked/deleted/renamed/conflict/stash/submodule state.",
|
|
30637
|
+
safe: true,
|
|
30638
|
+
willMutateWorktree: false
|
|
30639
|
+
},
|
|
30640
|
+
{
|
|
30641
|
+
operation: "verify_fast_forward",
|
|
30642
|
+
description: "Require ahead=0, behind>0, and HEAD to be an ancestor of the upstream ref.",
|
|
30643
|
+
safe: true,
|
|
30644
|
+
willMutateWorktree: false
|
|
30645
|
+
},
|
|
30646
|
+
{
|
|
30647
|
+
operation: "merge_ff_only",
|
|
30648
|
+
description: "Apply git merge --ff-only against the tracked upstream; no force, reset, rebase, push, or deploy.",
|
|
30649
|
+
safe: true,
|
|
30650
|
+
willMutateWorktree: true
|
|
30651
|
+
}
|
|
30652
|
+
];
|
|
30653
|
+
if (updateSubmodules) {
|
|
30654
|
+
steps.push({
|
|
30655
|
+
operation: "submodule_update",
|
|
30656
|
+
description: "If the fast-forward changes gitlinks, run git submodule update --init --recursive and re-verify submodules.",
|
|
30657
|
+
safe: true,
|
|
30658
|
+
willMutateWorktree: true
|
|
30659
|
+
});
|
|
30660
|
+
}
|
|
30661
|
+
steps.push({
|
|
30662
|
+
operation: "verify_post_status",
|
|
30663
|
+
description: "Re-read daemon-owned git status and report final branch convergence state.",
|
|
30664
|
+
safe: true,
|
|
30665
|
+
willMutateWorktree: false
|
|
30666
|
+
});
|
|
30667
|
+
return steps;
|
|
30668
|
+
}
|
|
30669
|
+
function collectPreflightBlockers(status, requestedBranch) {
|
|
30670
|
+
const blockers = [];
|
|
30671
|
+
if (!status.isGitRepo) blockers.push("not_git_repo");
|
|
30672
|
+
if (!status.branch) blockers.push("detached_head_or_unknown_branch");
|
|
30673
|
+
if (requestedBranch && status.branch !== requestedBranch) blockers.push("branch_mismatch");
|
|
30674
|
+
if (!status.upstream) blockers.push("upstream_missing");
|
|
30675
|
+
if (status.upstreamStatus !== "fresh") blockers.push("upstream_not_fresh");
|
|
30676
|
+
if (status.hasConflicts) blockers.push("conflicts_present");
|
|
30677
|
+
if (status.staged > 0) blockers.push("staged_changes_present");
|
|
30678
|
+
if (status.modified > 0) blockers.push("modified_changes_present");
|
|
30679
|
+
if (status.untracked > 0) blockers.push("untracked_changes_present");
|
|
30680
|
+
if (status.deleted > 0) blockers.push("deleted_changes_present");
|
|
30681
|
+
if (status.renamed > 0) blockers.push("renamed_changes_present");
|
|
30682
|
+
if (status.stashCount > 0) blockers.push("stash_entries_present");
|
|
30683
|
+
blockers.push(...collectSubmoduleBlockers(status, "pre"));
|
|
30684
|
+
if (status.ahead > 0 && status.behind > 0) {
|
|
30685
|
+
blockers.push("branch_diverged_from_upstream");
|
|
30686
|
+
blockers.push("branch_has_local_commits");
|
|
30687
|
+
} else if (status.ahead > 0) blockers.push("branch_has_local_commits");
|
|
30688
|
+
return blockers;
|
|
30689
|
+
}
|
|
30690
|
+
function collectPostExecutionBlockers(status) {
|
|
30691
|
+
const blockers = [];
|
|
30692
|
+
if (!status.isGitRepo) blockers.push("post_not_git_repo");
|
|
30693
|
+
if (status.hasConflicts) blockers.push("post_conflicts_present");
|
|
30694
|
+
if (status.ahead !== 0) blockers.push("post_branch_ahead");
|
|
30695
|
+
if (status.behind !== 0) blockers.push("post_branch_still_behind");
|
|
30696
|
+
if (status.staged > 0 || status.modified > 0 || status.untracked > 0 || status.deleted > 0 || status.renamed > 0) {
|
|
30697
|
+
blockers.push("post_working_tree_not_clean");
|
|
30698
|
+
}
|
|
30699
|
+
if (status.stashCount > 0) blockers.push("post_stash_entries_present");
|
|
30700
|
+
blockers.push(...collectSubmoduleBlockers(status, "post"));
|
|
30701
|
+
return blockers;
|
|
30702
|
+
}
|
|
30703
|
+
function collectSubmoduleBlockers(status, phase) {
|
|
30704
|
+
const submodules = Array.isArray(status.submodules) ? status.submodules : [];
|
|
30705
|
+
const blockers = [];
|
|
30706
|
+
for (const submodule of submodules) {
|
|
30707
|
+
if (submodule.error) blockers.push(`${phase}_submodule_status_error:${submodule.path}`);
|
|
30708
|
+
if (submodule.dirty) blockers.push(`${phase}_submodule_dirty:${submodule.path}`);
|
|
30709
|
+
if (submodule.outOfSync) blockers.push(`${phase}_submodule_out_of_sync:${submodule.path}`);
|
|
30710
|
+
}
|
|
30711
|
+
return blockers;
|
|
30712
|
+
}
|
|
30713
|
+
function chooseBlockCode(status, blockers) {
|
|
30714
|
+
if (blockers.includes("not_git_repo")) return "not_git_repo";
|
|
30715
|
+
if (blockers.includes("branch_mismatch")) return "branch_mismatch";
|
|
30716
|
+
if (blockers.includes("upstream_missing")) return "upstream_missing";
|
|
30717
|
+
if (blockers.includes("upstream_not_fresh")) return "upstream_not_fresh";
|
|
30718
|
+
if (blockers.some((reason) => reason.includes("submodule"))) return "submodule_not_clean";
|
|
30719
|
+
if (blockers.includes("branch_diverged_from_upstream")) return "branch_diverged";
|
|
30720
|
+
if (blockers.includes("branch_has_local_commits") || status.ahead > 0) return "branch_ahead";
|
|
30721
|
+
if (blockers.some((reason) => reason.includes("changes") || reason.includes("conflicts") || reason.includes("stash"))) return "dirty_worktree";
|
|
30722
|
+
return "preflight_blocked";
|
|
30723
|
+
}
|
|
30724
|
+
function codeToConvergenceStatus(code) {
|
|
30725
|
+
if (code === "branch_diverged" || code === "branch_ahead" || code === "non_fast_forward") return "not_mergeable";
|
|
30726
|
+
if (code === "dirty_worktree" || code === "submodule_not_clean") return "blocked_review";
|
|
30727
|
+
return "blocked";
|
|
30728
|
+
}
|
|
30729
|
+
async function verifyHeadIsAncestorOfUpstream(workspace, upstream, timeoutMs) {
|
|
30730
|
+
if (!upstream) return { ok: false, error: "missing upstream" };
|
|
30731
|
+
try {
|
|
30732
|
+
await runGit(workspace, ["merge-base", "--is-ancestor", "HEAD", upstream], { timeoutMs: timeoutMs ?? 15e3 });
|
|
30733
|
+
return { ok: true };
|
|
30734
|
+
} catch (error48) {
|
|
30735
|
+
return { ok: false, error: formatGitError2(error48) };
|
|
30736
|
+
}
|
|
30737
|
+
}
|
|
30738
|
+
function block(base, code, blockingReasons) {
|
|
30739
|
+
const normalizedReasons = normalizeBlockingReasons(blockingReasons);
|
|
30740
|
+
return {
|
|
30741
|
+
...base,
|
|
30742
|
+
success: false,
|
|
30743
|
+
code,
|
|
30744
|
+
allowed: false,
|
|
30745
|
+
willRun: false,
|
|
30746
|
+
executed: false,
|
|
30747
|
+
blockingReasons: normalizedReasons
|
|
30748
|
+
};
|
|
30749
|
+
}
|
|
30750
|
+
function normalizeBlockingReasons(reasons) {
|
|
30751
|
+
const normalized = /* @__PURE__ */ new Set();
|
|
30752
|
+
for (const reason of reasons) {
|
|
30753
|
+
normalized.add(reason);
|
|
30754
|
+
}
|
|
30755
|
+
if ([
|
|
30756
|
+
"conflicts_present",
|
|
30757
|
+
"staged_changes_present",
|
|
30758
|
+
"modified_changes_present",
|
|
30759
|
+
"untracked_changes_present",
|
|
30760
|
+
"deleted_changes_present",
|
|
30761
|
+
"renamed_changes_present"
|
|
30762
|
+
].some((reason) => normalized.has(reason))) {
|
|
30763
|
+
normalized.add("working_tree_not_clean");
|
|
30764
|
+
}
|
|
30765
|
+
return Array.from(normalized);
|
|
30766
|
+
}
|
|
30767
|
+
function buildConvergenceState(status, convergenceStatus) {
|
|
30768
|
+
return {
|
|
30769
|
+
status: convergenceStatus,
|
|
30770
|
+
branch: status.branch,
|
|
30771
|
+
headCommit: status.headCommit,
|
|
30772
|
+
upstream: status.upstream,
|
|
30773
|
+
ahead: status.ahead,
|
|
30774
|
+
behind: status.behind,
|
|
30775
|
+
dirty: status.staged + status.modified + status.untracked + status.deleted + status.renamed > 0 || status.hasConflicts,
|
|
30776
|
+
stashCount: status.stashCount,
|
|
30777
|
+
submodules: summarizeSubmodules(status.submodules)
|
|
30778
|
+
};
|
|
30779
|
+
}
|
|
30780
|
+
function summarizeSubmodules(submodules) {
|
|
30781
|
+
return (submodules || []).map((submodule) => ({
|
|
30782
|
+
path: submodule.path,
|
|
30783
|
+
commit: submodule.commit,
|
|
30784
|
+
dirty: submodule.dirty,
|
|
30785
|
+
outOfSync: submodule.outOfSync,
|
|
30786
|
+
...submodule.error ? { error: submodule.error } : {}
|
|
30787
|
+
}));
|
|
30788
|
+
}
|
|
30789
|
+
function normalizeOptionalString(value) {
|
|
30790
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
30791
|
+
}
|
|
30792
|
+
function formatGitError2(error48) {
|
|
30793
|
+
if (error48 instanceof GitCommandError) {
|
|
30794
|
+
return error48.stderr || error48.stdout || error48.message;
|
|
30795
|
+
}
|
|
30796
|
+
if (error48 instanceof Error) return error48.message;
|
|
30797
|
+
return String(error48);
|
|
30798
|
+
}
|
|
30799
|
+
async function appendFastForwardLedger(result, outcome) {
|
|
30800
|
+
if (!result.meshId) return;
|
|
30801
|
+
try {
|
|
30802
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
30803
|
+
appendLedgerEntry2(result.meshId, {
|
|
30804
|
+
kind: "direct_fast_forward",
|
|
30805
|
+
...result.nodeId ? { nodeId: result.nodeId } : {},
|
|
30806
|
+
payload: {
|
|
30807
|
+
operation: "mesh_fast_forward_node",
|
|
30808
|
+
outcome,
|
|
30809
|
+
code: result.code,
|
|
30810
|
+
workspace: result.workspace,
|
|
30811
|
+
allowed: result.allowed,
|
|
30812
|
+
dryRun: result.dryRun,
|
|
30813
|
+
willRun: result.willRun,
|
|
30814
|
+
executed: result.executed,
|
|
30815
|
+
branch: result.postStatus?.branch ?? result.current?.branch,
|
|
30816
|
+
upstream: result.postStatus?.upstream ?? result.current?.upstream,
|
|
30817
|
+
before: result.current ? {
|
|
30818
|
+
headCommit: result.current.headCommit,
|
|
30819
|
+
ahead: result.current.ahead,
|
|
30820
|
+
behind: result.current.behind
|
|
30821
|
+
} : void 0,
|
|
30822
|
+
after: result.postStatus ? {
|
|
30823
|
+
headCommit: result.postStatus.headCommit,
|
|
30824
|
+
ahead: result.postStatus.ahead,
|
|
30825
|
+
behind: result.postStatus.behind
|
|
30826
|
+
} : void 0,
|
|
30827
|
+
blockingReasons: result.blockingReasons
|
|
30828
|
+
}
|
|
30829
|
+
});
|
|
30830
|
+
} catch (error48) {
|
|
30831
|
+
result.ledgerError = error48 instanceof Error ? error48.message : String(error48);
|
|
30832
|
+
}
|
|
30833
|
+
}
|
|
30483
30834
|
function lastTimestamp(slice) {
|
|
30484
30835
|
const entries = Array.isArray(slice?.entries) ? slice.entries : [];
|
|
30485
30836
|
return entries.length ? entries[entries.length - 1].timestamp : null;
|
|
@@ -45959,10 +46310,10 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
45959
46310
|
function stringifyPreviewContent(content) {
|
|
45960
46311
|
if (typeof content === "string") return content;
|
|
45961
46312
|
if (Array.isArray(content)) {
|
|
45962
|
-
return content.map((
|
|
45963
|
-
if (typeof
|
|
45964
|
-
if (
|
|
45965
|
-
return String(
|
|
46313
|
+
return content.map((block2) => {
|
|
46314
|
+
if (typeof block2 === "string") return block2;
|
|
46315
|
+
if (block2 && typeof block2 === "object" && "text" in block2) {
|
|
46316
|
+
return String(block2.text || "");
|
|
45966
46317
|
}
|
|
45967
46318
|
return "";
|
|
45968
46319
|
}).join(" ");
|
|
@@ -49203,6 +49554,32 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
49203
49554
|
cleanupWillRun: false
|
|
49204
49555
|
};
|
|
49205
49556
|
}
|
|
49557
|
+
case "fast_forward_mesh_node": {
|
|
49558
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
49559
|
+
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
49560
|
+
let workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
|
|
49561
|
+
let submoduleIgnorePaths = Array.isArray(args?.submoduleIgnorePaths) ? args.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0;
|
|
49562
|
+
if (!workspace && meshId && nodeId) {
|
|
49563
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
49564
|
+
const mesh = meshRecord?.mesh;
|
|
49565
|
+
const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
|
|
49566
|
+
workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
|
|
49567
|
+
if (!submoduleIgnorePaths && Array.isArray(node?.policy?.submoduleIgnorePaths)) {
|
|
49568
|
+
submoduleIgnorePaths = node.policy.submoduleIgnorePaths.filter((value) => typeof value === "string");
|
|
49569
|
+
}
|
|
49570
|
+
}
|
|
49571
|
+
const result = await fastForwardMeshNode({
|
|
49572
|
+
meshId: meshId || void 0,
|
|
49573
|
+
nodeId: nodeId || void 0,
|
|
49574
|
+
workspace,
|
|
49575
|
+
branch: typeof args?.branch === "string" ? args.branch : void 0,
|
|
49576
|
+
execute: args?.execute === true,
|
|
49577
|
+
dryRun: args?.dryRun === true,
|
|
49578
|
+
updateSubmodules: args?.updateSubmodules === true,
|
|
49579
|
+
submoduleIgnorePaths
|
|
49580
|
+
});
|
|
49581
|
+
return result;
|
|
49582
|
+
}
|
|
49206
49583
|
case "refine_mesh_node": {
|
|
49207
49584
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
49208
49585
|
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
@@ -49713,20 +50090,20 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
49713
50090
|
const geminiMdPath = `${workspace}/GEMINI.md`;
|
|
49714
50091
|
const marker = "<!-- adhdev-mesh-coordinator-prompt -->";
|
|
49715
50092
|
const markerEnd = "<!-- /adhdev-mesh-coordinator-prompt -->";
|
|
49716
|
-
const
|
|
50093
|
+
const block2 = `${marker}
|
|
49717
50094
|
${cliCmdSystemPrompt}
|
|
49718
50095
|
${markerEnd}`;
|
|
49719
50096
|
if (efs(geminiMdPath)) {
|
|
49720
50097
|
const existing = rfs(geminiMdPath, "utf-8");
|
|
49721
50098
|
const replaced = existing.replace(
|
|
49722
50099
|
new RegExp(`${marker}[\\s\\S]*?${markerEnd}`, "g"),
|
|
49723
|
-
|
|
50100
|
+
block2
|
|
49724
50101
|
);
|
|
49725
50102
|
wfs(geminiMdPath, replaced.includes(marker) ? replaced : `${existing}
|
|
49726
50103
|
|
|
49727
|
-
${
|
|
50104
|
+
${block2}`);
|
|
49728
50105
|
} else {
|
|
49729
|
-
wfs(geminiMdPath,
|
|
50106
|
+
wfs(geminiMdPath, block2);
|
|
49730
50107
|
}
|
|
49731
50108
|
LOG2.info("MeshCoordinator", `Wrote coordinator prompt to ${workspace}/GEMINI.md`);
|
|
49732
50109
|
} catch (e) {
|