taskplane 0.5.4 → 0.5.6
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/dashboard/public/app.js
CHANGED
|
@@ -554,7 +554,7 @@ function renderMergeAgents(batch, tmuxSessions) {
|
|
|
554
554
|
// Repo filtering: if a repo is selected and this merge has repoResults,
|
|
555
555
|
// check if the selected repo is among them
|
|
556
556
|
const repoResults = mr.repoResults || [];
|
|
557
|
-
if (selectedRepo && showRepos && repoResults.length >=
|
|
557
|
+
if (selectedRepo && showRepos && repoResults.length >= 1) {
|
|
558
558
|
const hasSelectedRepo = repoResults.some(rr => rr.repoId === selectedRepo);
|
|
559
559
|
if (!hasSelectedRepo) continue;
|
|
560
560
|
}
|
|
@@ -582,8 +582,8 @@ function renderMergeAgents(batch, tmuxSessions) {
|
|
|
582
582
|
html += `<td style="font-size:0.8rem;color:var(--text-muted);">${mr.failureReason ? escapeHtml(mr.failureReason) : "—"}</td>`;
|
|
583
583
|
html += `</tr>`;
|
|
584
584
|
|
|
585
|
-
// Per-repo sub-rows:
|
|
586
|
-
if (showRepos && repoResults.length >=
|
|
585
|
+
// Per-repo sub-rows: show when workspace mode has repo results
|
|
586
|
+
if (showRepos && repoResults.length >= 1) {
|
|
587
587
|
const displayRepos = selectedRepo
|
|
588
588
|
? repoResults.filter(rr => rr.repoId === selectedRepo)
|
|
589
589
|
: repoResults;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Main batch execution engine
|
|
3
3
|
* @module orch/engine
|
|
4
4
|
*/
|
|
5
|
-
import { readFileSync, readdirSync, unlinkSync } from "fs";
|
|
6
|
-
import { join } from "path";
|
|
5
|
+
import { existsSync, readFileSync, readdirSync, unlinkSync } from "fs";
|
|
6
|
+
import { dirname, join, resolve } from "path";
|
|
7
7
|
|
|
8
8
|
import { formatDiscoveryResults, runDiscovery } from "./discovery.ts";
|
|
9
9
|
import { execLog, executeWave, tmuxKillSession } from "./execution.ts";
|
|
@@ -339,6 +339,16 @@ export async function executeOrchBatch(
|
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
+
// ── Workspace mode: commit task artifacts to task-area repos ─
|
|
343
|
+
// In workspace mode, workers write .DONE and STATUS.md to the
|
|
344
|
+
// canonical task folder (e.g., shared-libs/task-management/...) via
|
|
345
|
+
// absolute paths, not to the lane worktree. These changes land as
|
|
346
|
+
// uncommitted modifications in the task-area repo's working tree.
|
|
347
|
+
// Commit them before the merge step so they appear in the orch branch.
|
|
348
|
+
if (workspaceConfig && waveResult.succeededTaskIds.length > 0) {
|
|
349
|
+
commitWorkspaceTaskArtifacts(discoveryRef, workspaceRoot ?? repoRoot, waveIdx + 1, batchState.batchId);
|
|
350
|
+
}
|
|
351
|
+
|
|
342
352
|
// ── Wave Merge ───────────────────────────────────────────
|
|
343
353
|
// Only merge if there are succeeded tasks in this wave
|
|
344
354
|
let mergeResult: MergeWaveResult | null = null;
|
|
@@ -847,5 +857,78 @@ export async function executeOrchBatch(
|
|
|
847
857
|
}
|
|
848
858
|
|
|
849
859
|
|
|
860
|
+
// ── Workspace Task Artifact Commit ───────────────────────────────────
|
|
861
|
+
|
|
862
|
+
/**
|
|
863
|
+
* In workspace mode, commit task artifacts (.DONE, STATUS.md) that workers
|
|
864
|
+
* wrote to the canonical task folder in the task-area repo.
|
|
865
|
+
*
|
|
866
|
+
* Workers write to absolute paths (e.g., shared-libs/task-management/.../TP-002/.DONE)
|
|
867
|
+
* which land as uncommitted changes in the task-area repo's working tree.
|
|
868
|
+
* This function finds all task-area repos with dirty task files and commits them
|
|
869
|
+
* so they appear in the lane branches and merge correctly.
|
|
870
|
+
*
|
|
871
|
+
* Best-effort: failures are logged but don't block the batch.
|
|
872
|
+
*/
|
|
873
|
+
function commitWorkspaceTaskArtifacts(
|
|
874
|
+
discovery: DiscoveryResult | null,
|
|
875
|
+
workspaceRoot: string,
|
|
876
|
+
waveIndex: number,
|
|
877
|
+
batchId: string,
|
|
878
|
+
): void {
|
|
879
|
+
if (!discovery) return;
|
|
880
|
+
|
|
881
|
+
// Collect unique repo roots that contain task folders
|
|
882
|
+
const repoRootsWithTasks = new Set<string>();
|
|
883
|
+
for (const [, task] of discovery.pending) {
|
|
884
|
+
const taskFolder = resolve(task.taskFolder);
|
|
885
|
+
// Walk up to find the git repo root for this task folder
|
|
886
|
+
const gitResult = runGit(["rev-parse", "--show-toplevel"], dirname(taskFolder));
|
|
887
|
+
if (gitResult.ok) {
|
|
888
|
+
repoRootsWithTasks.add(gitResult.stdout.trim().replace(/\\/g, "/"));
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
for (const taskRepoRoot of repoRootsWithTasks) {
|
|
893
|
+
// Check for uncommitted changes
|
|
894
|
+
const statusResult = runGit(["status", "--porcelain", "--", "task-management/"], taskRepoRoot);
|
|
895
|
+
if (!statusResult.ok) {
|
|
896
|
+
// Try without path filter (task area might have different name)
|
|
897
|
+
const statusAll = runGit(["status", "--porcelain"], taskRepoRoot);
|
|
898
|
+
if (!statusAll.ok || !statusAll.stdout.trim()) continue;
|
|
899
|
+
}
|
|
900
|
+
if (statusResult.ok && !statusResult.stdout.trim()) continue;
|
|
901
|
+
|
|
902
|
+
// Stage task artifacts (only .DONE and STATUS.md files)
|
|
903
|
+
const lines = (statusResult.stdout || "").split("\n").filter(l => l.trim());
|
|
904
|
+
let hasTaskArtifacts = false;
|
|
905
|
+
for (const line of lines) {
|
|
906
|
+
const file = line.slice(3).trim();
|
|
907
|
+
if (file.endsWith(".DONE") || file.endsWith("STATUS.md")) {
|
|
908
|
+
const addResult = runGit(["add", file], taskRepoRoot);
|
|
909
|
+
if (addResult.ok) hasTaskArtifacts = true;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
if (!hasTaskArtifacts) continue;
|
|
914
|
+
|
|
915
|
+
// Commit
|
|
916
|
+
const commitResult = runGit(
|
|
917
|
+
["commit", "-m", `checkpoint: wave ${waveIndex} task artifacts (.DONE, STATUS.md)`],
|
|
918
|
+
taskRepoRoot,
|
|
919
|
+
);
|
|
920
|
+
if (commitResult.ok) {
|
|
921
|
+
execLog("batch", batchId, `committed workspace task artifacts`, {
|
|
922
|
+
repoRoot: taskRepoRoot,
|
|
923
|
+
wave: waveIndex,
|
|
924
|
+
});
|
|
925
|
+
} else if (!commitResult.stderr.includes("nothing to commit")) {
|
|
926
|
+
execLog("batch", batchId, `workspace task artifact commit failed (non-fatal): ${commitResult.stderr.slice(0, 200)}`, {
|
|
927
|
+
repoRoot: taskRepoRoot,
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
850
933
|
// ── Dashboard Widget (Step 6) ────────────────────────────────────────
|
|
851
934
|
|