taskplane 0.24.24 → 0.24.25
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.
|
@@ -2908,6 +2908,45 @@ export async function executeOrchBatch(
|
|
|
2908
2908
|
return hasSucceeded && hasHardFailure;
|
|
2909
2909
|
});
|
|
2910
2910
|
|
|
2911
|
+
// ── Safety net: auto-commit uncommitted artifacts before merge ──
|
|
2912
|
+
// Workers should commit at step boundaries, but may leave uncommitted
|
|
2913
|
+
// files (especially for level-0 / fast tasks). Check each merge-candidate
|
|
2914
|
+
// lane worktree and auto-commit any remaining changes so they're included
|
|
2915
|
+
// in the merge. Skips lanes with only failed/stalled tasks (no merge).
|
|
2916
|
+
for (const lane of waveResult.allocatedLanes) {
|
|
2917
|
+
if (!lane.worktreePath || !existsSync(lane.worktreePath)) continue;
|
|
2918
|
+
// Only check lanes that have at least one succeeded task (merge candidates)
|
|
2919
|
+
const laneOutcome = laneOutcomeByNumber.get(lane.laneNumber);
|
|
2920
|
+
if (!laneOutcome) continue;
|
|
2921
|
+
const hasSucceeded = laneOutcome.tasks.some(t => t.status === "succeeded");
|
|
2922
|
+
if (!hasSucceeded) continue;
|
|
2923
|
+
try {
|
|
2924
|
+
const addResult = runGit(["add", "-A"], lane.worktreePath);
|
|
2925
|
+
if (!addResult.ok) {
|
|
2926
|
+
execLog("merge", batchState.batchId, `safety-net: git add failed in ${lane.laneId}`, { stderr: addResult.stderr });
|
|
2927
|
+
continue;
|
|
2928
|
+
}
|
|
2929
|
+
const statusResult = runGit(["status", "--porcelain"], lane.worktreePath);
|
|
2930
|
+
if (!statusResult.ok || !statusResult.stdout?.trim()) continue;
|
|
2931
|
+
const taskIds = lane.tasks.map(t => t.taskId).join(", ");
|
|
2932
|
+
const commitResult = runGit(
|
|
2933
|
+
["commit", "-m", `safety-net: uncommitted artifacts for ${taskIds}`],
|
|
2934
|
+
lane.worktreePath,
|
|
2935
|
+
);
|
|
2936
|
+
if (commitResult.ok) {
|
|
2937
|
+
execLog("merge", batchState.batchId, `safety-net: auto-committed uncommitted files in ${lane.laneId}`, {
|
|
2938
|
+
worktree: lane.worktreePath,
|
|
2939
|
+
taskIds,
|
|
2940
|
+
files: statusResult.stdout.trim(),
|
|
2941
|
+
});
|
|
2942
|
+
} else {
|
|
2943
|
+
execLog("merge", batchState.batchId, `safety-net: commit failed in ${lane.laneId}`, { stderr: commitResult.stderr });
|
|
2944
|
+
}
|
|
2945
|
+
} catch (err: any) {
|
|
2946
|
+
execLog("merge", batchState.batchId, `safety-net: unexpected error in ${lane.laneId}`, { error: err?.message });
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2911
2950
|
if (succeededSegmentTaskIdsForMerge.length > 0) {
|
|
2912
2951
|
const mergeableLaneCount = waveResult.allocatedLanes.filter(lane => {
|
|
2913
2952
|
const outcome = laneOutcomeByNumber.get(lane.laneNumber);
|