@adhdev/daemon-standalone 0.9.82-rc.59 → 0.9.82-rc.60

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 CHANGED
@@ -48226,6 +48226,10 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
48226
48226
  inlineMeshCache = /* @__PURE__ */ new Map();
48227
48227
  /** Coordinator-owned whole-mesh aggregate status snapshots. Browser callers read this by default. */
48228
48228
  aggregateMeshStatusCache = /* @__PURE__ */ new Map();
48229
+ /** In-memory async Refinery jobs keyed by meshId:nodeId to reject/return duplicate in-flight requests. */
48230
+ runningRefineJobs = /* @__PURE__ */ new Map();
48231
+ /** Terminal async Refinery jobs preserve a clear answer after the worktree node has been removed. */
48232
+ terminalRefineJobs = /* @__PURE__ */ new Map();
48229
48233
  constructor(deps) {
48230
48234
  this.deps = deps;
48231
48235
  }
@@ -48855,6 +48859,340 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
48855
48859
  throw e;
48856
48860
  }
48857
48861
  }
48862
+ buildRefineJobKey(meshId, nodeId) {
48863
+ return `${meshId}:${nodeId}`;
48864
+ }
48865
+ buildRefineJobHandle(args) {
48866
+ return {
48867
+ success: true,
48868
+ async: true,
48869
+ status: args.status || "accepted",
48870
+ jobId: args.jobId || `refine_${createInteractionId()}`,
48871
+ interactionId: args.interactionId || createInteractionId(),
48872
+ meshId: args.meshId,
48873
+ nodeId: args.nodeId,
48874
+ targetNodeId: args.nodeId,
48875
+ targetDaemonId: readStringValue(args.node?.daemonId),
48876
+ workspace: readStringValue(args.node?.workspace),
48877
+ startedAt: args.startedAt || (/* @__PURE__ */ new Date()).toISOString(),
48878
+ ...args.completedAt ? { completedAt: args.completedAt } : {},
48879
+ eventDelivery: { pendingEvents: true, ledger: true },
48880
+ evidence: {
48881
+ pendingEventsCommand: "get_pending_mesh_events",
48882
+ ledgerCommand: "get_mesh_ledger_slice",
48883
+ taskHistoryKind: args.status === "completed" ? "task_completed" : args.status === "failed" ? "task_failed" : "task_dispatched"
48884
+ }
48885
+ };
48886
+ }
48887
+ queueRefineJobEvent(event, handle, result) {
48888
+ queuePendingMeshCoordinatorEvent({
48889
+ event,
48890
+ meshId: handle.meshId,
48891
+ nodeLabel: handle.targetNodeId,
48892
+ nodeId: handle.targetNodeId,
48893
+ workspace: handle.workspace,
48894
+ metadataEvent: {
48895
+ source: "refine_mesh_node_async_job",
48896
+ jobId: handle.jobId,
48897
+ interactionId: handle.interactionId,
48898
+ meshId: handle.meshId,
48899
+ nodeId: handle.targetNodeId,
48900
+ targetDaemonId: handle.targetDaemonId,
48901
+ workspace: handle.workspace,
48902
+ status: handle.status,
48903
+ startedAt: handle.startedAt,
48904
+ completedAt: handle.completedAt,
48905
+ ...result ? { result } : {}
48906
+ },
48907
+ queuedAt: Date.now()
48908
+ });
48909
+ }
48910
+ async appendRefineJobLedger(kind, handle, result) {
48911
+ try {
48912
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
48913
+ appendLedgerEntry2(handle.meshId, {
48914
+ kind,
48915
+ nodeId: handle.targetNodeId,
48916
+ payload: {
48917
+ source: "refine_mesh_node_async_job",
48918
+ refineJob: {
48919
+ jobId: handle.jobId,
48920
+ interactionId: handle.interactionId,
48921
+ status: handle.status,
48922
+ meshId: handle.meshId,
48923
+ nodeId: handle.targetNodeId,
48924
+ targetDaemonId: handle.targetDaemonId,
48925
+ workspace: handle.workspace,
48926
+ startedAt: handle.startedAt,
48927
+ completedAt: handle.completedAt
48928
+ },
48929
+ async: true,
48930
+ ...result ? {
48931
+ success: result.success === true,
48932
+ result,
48933
+ finalBranchConvergenceState: result.finalBranchConvergenceState
48934
+ } : {}
48935
+ }
48936
+ });
48937
+ } catch (e) {
48938
+ LOG2.warn("Mesh", `[Refinery] Failed to append async refine ledger entry: ${e?.message || e}`);
48939
+ }
48940
+ }
48941
+ async executeMeshRefineNodeSynchronously(meshId, nodeId, args) {
48942
+ const refineStages = [];
48943
+ try {
48944
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
48945
+ const mesh = meshRecord?.mesh;
48946
+ const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
48947
+ if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh`, refineStages };
48948
+ if (!node.isLocalWorktree || !node.workspace) {
48949
+ return { success: false, error: `Refinery requires a local worktree node`, refineStages };
48950
+ }
48951
+ const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
48952
+ const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
48953
+ if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
48954
+ const { execFile: execFile3 } = await import("child_process");
48955
+ const { promisify: promisify3 } = await import("util");
48956
+ const execFileAsync3 = promisify3(execFile3);
48957
+ const resolveStarted = Date.now();
48958
+ const { stdout: branchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
48959
+ const branch = branchStdout.trim();
48960
+ if (!branch) return { success: false, error: "Could not determine branch of the worktree node", refineStages };
48961
+ const { stdout: baseBranchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
48962
+ const baseBranch = baseBranchStdout.trim();
48963
+ const { stdout: baseHeadStdout } = await execFileAsync3("git", ["rev-parse", "HEAD"], { cwd: repoRoot, encoding: "utf8" });
48964
+ const { stdout: branchHeadStdout } = await execFileAsync3("git", ["rev-parse", branch], { cwd: node.workspace, encoding: "utf8" });
48965
+ const baseHead = baseHeadStdout.trim();
48966
+ const branchHead = branchHeadStdout.trim();
48967
+ recordMeshRefineStage(refineStages, "resolve_refs", "passed", resolveStarted, { branch, baseBranch, baseHead, branchHead });
48968
+ const validationStarted = Date.now();
48969
+ const validationSummary = await runMeshRefineValidationGate(mesh, node.workspace);
48970
+ recordMeshRefineStage(
48971
+ refineStages,
48972
+ "validation",
48973
+ validationSummary.status === "passed" ? "passed" : validationSummary.status === "failed" ? "failed" : "skipped",
48974
+ validationStarted,
48975
+ { validationStatus: validationSummary.status, commandsRun: validationSummary.commandsRun.length }
48976
+ );
48977
+ if (validationSummary.status === "failed") {
48978
+ return {
48979
+ success: false,
48980
+ code: "validation_failed",
48981
+ convergenceStatus: "blocked_review",
48982
+ error: "Refinery validation gate failed; merge/refine was not attempted.",
48983
+ branch,
48984
+ into: baseBranch,
48985
+ validationSummary,
48986
+ refineStages,
48987
+ finalBranchConvergenceState: {
48988
+ branch,
48989
+ baseBranch,
48990
+ merged: false,
48991
+ removed: false,
48992
+ validation: "failed",
48993
+ status: "blocked_review"
48994
+ }
48995
+ };
48996
+ }
48997
+ if (validationSummary.status === "skipped") {
48998
+ return {
48999
+ success: false,
49000
+ code: "validation_unavailable",
49001
+ convergenceStatus: "blocked_review",
49002
+ error: "Refinery validation gate is required but no allowlisted validation command was available; merge/refine was not attempted.",
49003
+ branch,
49004
+ into: baseBranch,
49005
+ validationSummary,
49006
+ refineStages,
49007
+ finalBranchConvergenceState: {
49008
+ branch,
49009
+ baseBranch,
49010
+ merged: false,
49011
+ removed: false,
49012
+ validation: "unavailable",
49013
+ status: "blocked_review"
49014
+ }
49015
+ };
49016
+ }
49017
+ const patchEquivalenceStarted = Date.now();
49018
+ const patchEquivalence = await runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead);
49019
+ recordMeshRefineStage(refineStages, "patch_equivalence", patchEquivalence.status, patchEquivalenceStarted, {
49020
+ equivalent: patchEquivalence.equivalent,
49021
+ expectedPatchId: patchEquivalence.expectedPatchId,
49022
+ actualPatchId: patchEquivalence.actualPatchId,
49023
+ error: patchEquivalence.error
49024
+ });
49025
+ if (!patchEquivalence.equivalent) {
49026
+ return {
49027
+ success: false,
49028
+ code: "patch_equivalence_failed",
49029
+ convergenceStatus: "blocked_review",
49030
+ error: "Refinery patch-equivalence preflight failed; merge/refine was not attempted.",
49031
+ branch,
49032
+ into: baseBranch,
49033
+ validationSummary,
49034
+ patchEquivalence,
49035
+ refineStages,
49036
+ finalBranchConvergenceState: {
49037
+ branch,
49038
+ baseBranch,
49039
+ merged: false,
49040
+ removed: false,
49041
+ validation: "passed",
49042
+ patchEquivalence: "failed",
49043
+ status: "blocked_review"
49044
+ }
49045
+ };
49046
+ }
49047
+ let mergeResult;
49048
+ const mergeStarted = Date.now();
49049
+ try {
49050
+ const result = await execFileAsync3("git", ["merge", "--no-ff", branch, "-m", `Auto-merge branch '${branch}' via Refinery`], { cwd: repoRoot, encoding: "utf8" });
49051
+ mergeResult = {
49052
+ stdout: truncateValidationOutput(result.stdout),
49053
+ stderr: truncateValidationOutput(result.stderr),
49054
+ durationMs: Date.now() - mergeStarted
49055
+ };
49056
+ recordMeshRefineStage(refineStages, "merge", "passed", mergeStarted, mergeResult);
49057
+ } catch (e) {
49058
+ recordMeshRefineStage(refineStages, "merge", "failed", mergeStarted, {
49059
+ error: e?.message || String(e),
49060
+ stdout: truncateValidationOutput(e?.stdout),
49061
+ stderr: truncateValidationOutput(e?.stderr)
49062
+ });
49063
+ return {
49064
+ success: false,
49065
+ error: `Merge failed (conflicts?): ${e.message}`,
49066
+ validationSummary,
49067
+ patchEquivalence,
49068
+ refineStages,
49069
+ finalBranchConvergenceState: {
49070
+ branch,
49071
+ baseBranch,
49072
+ merged: false,
49073
+ removed: false,
49074
+ validation: "passed",
49075
+ patchEquivalence: "passed",
49076
+ status: "not_mergeable"
49077
+ }
49078
+ };
49079
+ }
49080
+ const cleanupStarted = Date.now();
49081
+ const removeResult = await this.execute("remove_mesh_node", {
49082
+ meshId,
49083
+ nodeId,
49084
+ sessionCleanupMode: "preserve",
49085
+ inlineMesh: args?.inlineMesh
49086
+ });
49087
+ recordMeshRefineStage(refineStages, "cleanup", removeResult?.success === false ? "failed" : "passed", cleanupStarted, {
49088
+ removed: removeResult?.removed,
49089
+ code: removeResult?.code,
49090
+ error: removeResult?.error
49091
+ });
49092
+ let ledgerError;
49093
+ const ledgerStarted = Date.now();
49094
+ try {
49095
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
49096
+ appendLedgerEntry2(meshId, {
49097
+ kind: "node_removed",
49098
+ nodeId,
49099
+ payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary, patchEquivalence }
49100
+ });
49101
+ recordMeshRefineStage(refineStages, "ledger", "passed", ledgerStarted);
49102
+ } catch (e) {
49103
+ ledgerError = e?.message || String(e);
49104
+ recordMeshRefineStage(refineStages, "ledger", "failed", ledgerStarted, { error: ledgerError });
49105
+ }
49106
+ const finalBranchConvergenceState = {
49107
+ branch: baseBranch,
49108
+ mergedBranch: branch,
49109
+ baseBranch,
49110
+ merged: true,
49111
+ removed: removeResult?.success !== false,
49112
+ validation: "passed",
49113
+ patchEquivalence: "passed",
49114
+ status: removeResult?.success === false ? "merged_cleanup_failed" : "merged"
49115
+ };
49116
+ if (removeResult?.success === false) {
49117
+ return {
49118
+ success: false,
49119
+ code: "cleanup_failed",
49120
+ error: "Refinery merge completed but worktree cleanup failed; manual cleanup/retry is required.",
49121
+ merged: true,
49122
+ branch,
49123
+ into: baseBranch,
49124
+ removeResult,
49125
+ validationSummary,
49126
+ patchEquivalence,
49127
+ mergeResult,
49128
+ refineStages,
49129
+ ...ledgerError ? { ledgerError } : {},
49130
+ finalBranchConvergenceState
49131
+ };
49132
+ }
49133
+ return {
49134
+ success: true,
49135
+ merged: true,
49136
+ branch,
49137
+ into: baseBranch,
49138
+ removeResult,
49139
+ validationSummary,
49140
+ patchEquivalence,
49141
+ mergeResult,
49142
+ refineStages,
49143
+ ...ledgerError ? { ledgerError } : {},
49144
+ finalBranchConvergenceState
49145
+ };
49146
+ } catch (e) {
49147
+ return { success: false, error: e.message, refineStages };
49148
+ }
49149
+ }
49150
+ async finishMeshRefineJob(handle, args) {
49151
+ const key = this.buildRefineJobKey(handle.meshId, handle.targetNodeId);
49152
+ let result;
49153
+ try {
49154
+ result = await this.executeMeshRefineNodeSynchronously(handle.meshId, handle.targetNodeId, args);
49155
+ } catch (e) {
49156
+ result = { success: false, error: e?.message || String(e) };
49157
+ }
49158
+ const completedAt = (/* @__PURE__ */ new Date()).toISOString();
49159
+ const terminalHandle = this.buildRefineJobHandle({
49160
+ meshId: handle.meshId,
49161
+ nodeId: handle.targetNodeId,
49162
+ status: result.success === true ? "completed" : "failed",
49163
+ startedAt: handle.startedAt,
49164
+ completedAt,
49165
+ jobId: handle.jobId,
49166
+ interactionId: handle.interactionId,
49167
+ node: { daemonId: handle.targetDaemonId, workspace: handle.workspace }
49168
+ });
49169
+ const terminal = { ...terminalHandle, result };
49170
+ this.terminalRefineJobs.set(key, terminal);
49171
+ this.runningRefineJobs.delete(key);
49172
+ this.invalidateAggregateMeshStatus(handle.meshId);
49173
+ await this.appendRefineJobLedger(result.success === true ? "task_completed" : "task_failed", terminalHandle, result);
49174
+ this.queueRefineJobEvent(result.success === true ? "refine:completed" : "refine:failed", terminalHandle, result);
49175
+ }
49176
+ async startMeshRefineJob(meshId, nodeId, args) {
49177
+ const key = this.buildRefineJobKey(meshId, nodeId);
49178
+ const running = this.runningRefineJobs.get(key);
49179
+ if (running) return { ...running, duplicate: true };
49180
+ const terminal = this.terminalRefineJobs.get(key);
49181
+ if (terminal) return { ...terminal, duplicate: true };
49182
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
49183
+ const mesh = meshRecord?.mesh;
49184
+ const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
49185
+ if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
49186
+ if (!node.isLocalWorktree || !node.workspace) return { success: false, error: `Refinery requires a local worktree node` };
49187
+ const handle = this.buildRefineJobHandle({ meshId, nodeId, node });
49188
+ this.runningRefineJobs.set(key, handle);
49189
+ await this.appendRefineJobLedger("task_dispatched", handle);
49190
+ this.queueRefineJobEvent("refine:accepted", handle);
49191
+ setImmediate(() => {
49192
+ void this.finishMeshRefineJob(handle, args);
49193
+ });
49194
+ return handle;
49195
+ }
48858
49196
  // ─── Daemon-level command core ───────────────────
48859
49197
  /**
48860
49198
  * Daemon-level command execution (IDE start/stop/restart, CLI, detect, logs).
@@ -49940,213 +50278,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
49940
50278
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
49941
50279
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
49942
50280
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
49943
- const refineStages = [];
49944
- try {
49945
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
49946
- const mesh = meshRecord?.mesh;
49947
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
49948
- if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh`, refineStages };
49949
- if (!node.isLocalWorktree || !node.workspace) {
49950
- return { success: false, error: `Refinery requires a local worktree node`, refineStages };
49951
- }
49952
- const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
49953
- const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
49954
- if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
49955
- const { execFile: execFile3 } = await import("child_process");
49956
- const { promisify: promisify3 } = await import("util");
49957
- const execFileAsync3 = promisify3(execFile3);
49958
- const resolveStarted = Date.now();
49959
- const { stdout: branchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
49960
- const branch = branchStdout.trim();
49961
- if (!branch) return { success: false, error: "Could not determine branch of the worktree node", refineStages };
49962
- const { stdout: baseBranchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
49963
- const baseBranch = baseBranchStdout.trim();
49964
- const { stdout: baseHeadStdout } = await execFileAsync3("git", ["rev-parse", "HEAD"], { cwd: repoRoot, encoding: "utf8" });
49965
- const { stdout: branchHeadStdout } = await execFileAsync3("git", ["rev-parse", branch], { cwd: node.workspace, encoding: "utf8" });
49966
- const baseHead = baseHeadStdout.trim();
49967
- const branchHead = branchHeadStdout.trim();
49968
- recordMeshRefineStage(refineStages, "resolve_refs", "passed", resolveStarted, { branch, baseBranch, baseHead, branchHead });
49969
- const validationStarted = Date.now();
49970
- const validationSummary = await runMeshRefineValidationGate(mesh, node.workspace);
49971
- recordMeshRefineStage(
49972
- refineStages,
49973
- "validation",
49974
- validationSummary.status === "passed" ? "passed" : validationSummary.status === "failed" ? "failed" : "skipped",
49975
- validationStarted,
49976
- { validationStatus: validationSummary.status, commandsRun: validationSummary.commandsRun.length }
49977
- );
49978
- if (validationSummary.status === "failed") {
49979
- return {
49980
- success: false,
49981
- code: "validation_failed",
49982
- convergenceStatus: "blocked_review",
49983
- error: "Refinery validation gate failed; merge/refine was not attempted.",
49984
- branch,
49985
- into: baseBranch,
49986
- validationSummary,
49987
- refineStages,
49988
- finalBranchConvergenceState: {
49989
- branch,
49990
- baseBranch,
49991
- merged: false,
49992
- removed: false,
49993
- validation: "failed",
49994
- status: "blocked_review"
49995
- }
49996
- };
49997
- }
49998
- if (validationSummary.status === "skipped") {
49999
- return {
50000
- success: false,
50001
- code: "validation_unavailable",
50002
- convergenceStatus: "blocked_review",
50003
- error: "Refinery validation gate is required but no allowlisted validation command was available; merge/refine was not attempted.",
50004
- branch,
50005
- into: baseBranch,
50006
- validationSummary,
50007
- refineStages,
50008
- finalBranchConvergenceState: {
50009
- branch,
50010
- baseBranch,
50011
- merged: false,
50012
- removed: false,
50013
- validation: "unavailable",
50014
- status: "blocked_review"
50015
- }
50016
- };
50017
- }
50018
- const patchEquivalenceStarted = Date.now();
50019
- const patchEquivalence = await runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead);
50020
- recordMeshRefineStage(refineStages, "patch_equivalence", patchEquivalence.status, patchEquivalenceStarted, {
50021
- equivalent: patchEquivalence.equivalent,
50022
- expectedPatchId: patchEquivalence.expectedPatchId,
50023
- actualPatchId: patchEquivalence.actualPatchId,
50024
- error: patchEquivalence.error
50025
- });
50026
- if (!patchEquivalence.equivalent) {
50027
- return {
50028
- success: false,
50029
- code: "patch_equivalence_failed",
50030
- convergenceStatus: "blocked_review",
50031
- error: "Refinery patch-equivalence preflight failed; merge/refine was not attempted.",
50032
- branch,
50033
- into: baseBranch,
50034
- validationSummary,
50035
- patchEquivalence,
50036
- refineStages,
50037
- finalBranchConvergenceState: {
50038
- branch,
50039
- baseBranch,
50040
- merged: false,
50041
- removed: false,
50042
- validation: "passed",
50043
- patchEquivalence: "failed",
50044
- status: "blocked_review"
50045
- }
50046
- };
50047
- }
50048
- let mergeResult;
50049
- const mergeStarted = Date.now();
50050
- try {
50051
- const result = await execFileAsync3("git", ["merge", "--no-ff", branch, "-m", `Auto-merge branch '${branch}' via Refinery`], { cwd: repoRoot, encoding: "utf8" });
50052
- mergeResult = {
50053
- stdout: truncateValidationOutput(result.stdout),
50054
- stderr: truncateValidationOutput(result.stderr),
50055
- durationMs: Date.now() - mergeStarted
50056
- };
50057
- recordMeshRefineStage(refineStages, "merge", "passed", mergeStarted, mergeResult);
50058
- } catch (e) {
50059
- recordMeshRefineStage(refineStages, "merge", "failed", mergeStarted, {
50060
- error: e?.message || String(e),
50061
- stdout: truncateValidationOutput(e?.stdout),
50062
- stderr: truncateValidationOutput(e?.stderr)
50063
- });
50064
- return {
50065
- success: false,
50066
- error: `Merge failed (conflicts?): ${e.message}`,
50067
- validationSummary,
50068
- patchEquivalence,
50069
- refineStages,
50070
- finalBranchConvergenceState: {
50071
- branch,
50072
- baseBranch,
50073
- merged: false,
50074
- removed: false,
50075
- validation: "passed",
50076
- patchEquivalence: "passed",
50077
- status: "not_mergeable"
50078
- }
50079
- };
50080
- }
50081
- const cleanupStarted = Date.now();
50082
- const removeResult = await this.execute("remove_mesh_node", {
50083
- meshId,
50084
- nodeId,
50085
- sessionCleanupMode: "preserve",
50086
- inlineMesh: args?.inlineMesh
50087
- });
50088
- recordMeshRefineStage(refineStages, "cleanup", removeResult?.success === false ? "failed" : "passed", cleanupStarted, {
50089
- removed: removeResult?.removed,
50090
- code: removeResult?.code,
50091
- error: removeResult?.error
50092
- });
50093
- let ledgerError;
50094
- const ledgerStarted = Date.now();
50095
- try {
50096
- const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
50097
- appendLedgerEntry2(meshId, {
50098
- kind: "node_removed",
50099
- nodeId,
50100
- payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary, patchEquivalence }
50101
- });
50102
- recordMeshRefineStage(refineStages, "ledger", "passed", ledgerStarted);
50103
- } catch (e) {
50104
- ledgerError = e?.message || String(e);
50105
- recordMeshRefineStage(refineStages, "ledger", "failed", ledgerStarted, { error: ledgerError });
50106
- }
50107
- const finalBranchConvergenceState = {
50108
- branch: baseBranch,
50109
- mergedBranch: branch,
50110
- baseBranch,
50111
- merged: true,
50112
- removed: removeResult?.success !== false,
50113
- validation: "passed",
50114
- patchEquivalence: "passed",
50115
- status: removeResult?.success === false ? "merged_cleanup_failed" : "merged"
50116
- };
50117
- if (removeResult?.success === false) {
50118
- return {
50119
- success: false,
50120
- code: "cleanup_failed",
50121
- error: "Refinery merge completed but worktree cleanup failed; manual cleanup/retry is required.",
50122
- merged: true,
50123
- branch,
50124
- into: baseBranch,
50125
- removeResult,
50126
- validationSummary,
50127
- patchEquivalence,
50128
- mergeResult,
50129
- refineStages,
50130
- ...ledgerError ? { ledgerError } : {},
50131
- finalBranchConvergenceState
50132
- };
50133
- }
50134
- return {
50135
- success: true,
50136
- merged: true,
50137
- branch,
50138
- into: baseBranch,
50139
- removeResult,
50140
- validationSummary,
50141
- patchEquivalence,
50142
- mergeResult,
50143
- refineStages,
50144
- ...ledgerError ? { ledgerError } : {},
50145
- finalBranchConvergenceState
50146
- };
50147
- } catch (e) {
50148
- return { success: false, error: e.message, refineStages };
50149
- }
50281
+ return this.startMeshRefineJob(meshId, nodeId, args);
50150
50282
  }
50151
50283
  case "remove_mesh_node": {
50152
50284
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";