@backburner/cli 0.1.0
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/LICENSE +21 -0
- package/README.md +329 -0
- package/dist/src/agents/antigravity-launch.js +162 -0
- package/dist/src/agents/antigravity.js +251 -0
- package/dist/src/agents/claude-launch.js +117 -0
- package/dist/src/agents/claude.js +271 -0
- package/dist/src/agents/codex-launch.js +82 -0
- package/dist/src/agents/codex.js +261 -0
- package/dist/src/agents/composite-runner.js +13 -0
- package/dist/src/agents/extraction.js +442 -0
- package/dist/src/agents/failure-feedback.js +132 -0
- package/dist/src/agents/gemini-launch.js +96 -0
- package/dist/src/agents/gemini.js +392 -0
- package/dist/src/agents/job-agent-assignments.js +180 -0
- package/dist/src/agents/lifecycle-feedback.js +147 -0
- package/dist/src/agents/limit-detector.js +83 -0
- package/dist/src/agents/opencode-launch.js +138 -0
- package/dist/src/agents/opencode.js +156 -0
- package/dist/src/agents/plan-breakdown-feedback.js +97 -0
- package/dist/src/agents/pool.js +168 -0
- package/dist/src/agents/prompt.js +462 -0
- package/dist/src/agents/provider-sessions.js +105 -0
- package/dist/src/agents/review-feedback.js +255 -0
- package/dist/src/agents/selection.js +113 -0
- package/dist/src/agents/service.js +1087 -0
- package/dist/src/agents/types.js +1 -0
- package/dist/src/agents/wave-assessment-feedback.js +69 -0
- package/dist/src/attention/derive.js +337 -0
- package/dist/src/capabilities/index.js +2 -0
- package/dist/src/capabilities/projection.js +183 -0
- package/dist/src/capabilities/types.js +1 -0
- package/dist/src/capabilities/validator.js +87 -0
- package/dist/src/cli/commands/broker-smoke.js +96 -0
- package/dist/src/cli/commands/broker.js +56 -0
- package/dist/src/cli/commands/init.js +4 -0
- package/dist/src/cli/commands/journal.js +43 -0
- package/dist/src/cli/commands/run-loop.js +56 -0
- package/dist/src/cli/commands/run.js +1241 -0
- package/dist/src/cli/commands/tui.js +187 -0
- package/dist/src/cli/dispatcher.js +51 -0
- package/dist/src/cli/errors.js +2 -0
- package/dist/src/cli/init.js +92 -0
- package/dist/src/cli/options.js +86 -0
- package/dist/src/cli/output.js +231 -0
- package/dist/src/cli/run-journal.js +342 -0
- package/dist/src/cli/run-types.js +1 -0
- package/dist/src/cli/run.js +32 -0
- package/dist/src/cli/runtime/dispatch-lifecycle.js +772 -0
- package/dist/src/cli/runtime/provider-runtime-types.js +1 -0
- package/dist/src/cli/runtime/provider-runtime.js +152 -0
- package/dist/src/cli/runtime/provider-tools.js +73 -0
- package/dist/src/cli/runtime/providers/antigravity.js +26 -0
- package/dist/src/cli/runtime/providers/claude.js +20 -0
- package/dist/src/cli/runtime/providers/codex.js +20 -0
- package/dist/src/cli/runtime/providers/gemini.js +20 -0
- package/dist/src/cli/runtime/providers/opencode.js +20 -0
- package/dist/src/cli/runtime/run-context.js +131 -0
- package/dist/src/cli/tui/index.js +3 -0
- package/dist/src/cli/tui/screen.js +388 -0
- package/dist/src/cli/tui/tracker.js +558 -0
- package/dist/src/cli/tui/types.js +1 -0
- package/dist/src/cli/tui/views.js +1006 -0
- package/dist/src/config/loader.js +136 -0
- package/dist/src/config/schemas.js +403 -0
- package/dist/src/config/types.js +1 -0
- package/dist/src/context/types.js +331 -0
- package/dist/src/domain/entities.js +1 -0
- package/dist/src/git/backburner-git-tool-service.js +680 -0
- package/dist/src/git/gitops-lifecycle.js +56 -0
- package/dist/src/git/merge-prep-workspace.js +357 -0
- package/dist/src/git/types.js +484 -0
- package/dist/src/github/broker-model-content.js +215 -0
- package/dist/src/github/broker-server.js +237 -0
- package/dist/src/github/broker.js +638 -0
- package/dist/src/github/composed.js +53 -0
- package/dist/src/github/gateway.js +478 -0
- package/dist/src/github/normalize.js +222 -0
- package/dist/src/github/pr-classification.js +73 -0
- package/dist/src/github/scoped-broker.js +35 -0
- package/dist/src/github/security.js +126 -0
- package/dist/src/github/service.js +332 -0
- package/dist/src/github/types.js +1 -0
- package/dist/src/github/utils.js +16 -0
- package/dist/src/journal/index.js +4 -0
- package/dist/src/journal/reader.js +62 -0
- package/dist/src/journal/renderer.js +50 -0
- package/dist/src/journal/service.js +72 -0
- package/dist/src/journal/types.js +1 -0
- package/dist/src/journal/writer.js +19 -0
- package/dist/src/mcps/bridge.js +166 -0
- package/dist/src/mcps/index.js +5 -0
- package/dist/src/mcps/reconcile.js +113 -0
- package/dist/src/mcps/smithery-client.js +186 -0
- package/dist/src/mcps/smithery.js +164 -0
- package/dist/src/mcps/types.js +1 -0
- package/dist/src/memory/json-store.js +71 -0
- package/dist/src/memory/prompt.js +16 -0
- package/dist/src/memory/scope.js +31 -0
- package/dist/src/memory/store.js +1 -0
- package/dist/src/memory/tool-service.js +142 -0
- package/dist/src/memory/types.js +12 -0
- package/dist/src/onboarding/config-writer.js +96 -0
- package/dist/src/onboarding/engine.js +86 -0
- package/dist/src/onboarding/prompt.js +102 -0
- package/dist/src/onboarding/services/provider-discovery.js +58 -0
- package/dist/src/onboarding/services/repo-discovery.js +246 -0
- package/dist/src/onboarding/steps/check-github-auth.js +32 -0
- package/dist/src/onboarding/steps/check-requirements.js +34 -0
- package/dist/src/onboarding/steps/configure-models.js +105 -0
- package/dist/src/onboarding/steps/configure-paths.js +33 -0
- package/dist/src/onboarding/steps/discover-providers.js +38 -0
- package/dist/src/onboarding/steps/discover-repos.js +39 -0
- package/dist/src/onboarding/steps/generate-config.js +106 -0
- package/dist/src/onboarding/steps/readiness-validation.js +158 -0
- package/dist/src/onboarding/steps/select-repos.js +76 -0
- package/dist/src/onboarding/steps/show-summary.js +97 -0
- package/dist/src/onboarding/steps/welcome.js +27 -0
- package/dist/src/onboarding/types.js +1 -0
- package/dist/src/onboarding/validators/git-access.js +63 -0
- package/dist/src/onboarding/validators/github-auth.js +85 -0
- package/dist/src/onboarding/validators/tool-checker.js +153 -0
- package/dist/src/onboarding/validators/workspace.js +83 -0
- package/dist/src/prompts/resolver.js +106 -0
- package/dist/src/retrospectives/candidates.js +224 -0
- package/dist/src/retrospectives/derive.js +169 -0
- package/dist/src/retrospectives/ingest.js +321 -0
- package/dist/src/retrospectives/management-prs.js +380 -0
- package/dist/src/retrospectives/proposals.js +199 -0
- package/dist/src/retrospectives/scopes.js +272 -0
- package/dist/src/retrospectives/scoring.js +171 -0
- package/dist/src/retrospectives/types.js +1 -0
- package/dist/src/state/loader.js +473 -0
- package/dist/src/state/types.js +15 -0
- package/dist/src/tasks/derivation/builders.js +70 -0
- package/dist/src/tasks/derivation/handlers/comment-response.js +169 -0
- package/dist/src/tasks/derivation/handlers/implement-plan.js +103 -0
- package/dist/src/tasks/derivation/handlers/index.js +54 -0
- package/dist/src/tasks/derivation/handlers/packet-pr-control.js +92 -0
- package/dist/src/tasks/derivation/handlers/packet-worktree.js +29 -0
- package/dist/src/tasks/derivation/handlers/plan-breakdown.js +45 -0
- package/dist/src/tasks/derivation/handlers/prepare-for-merge.js +91 -0
- package/dist/src/tasks/derivation/handlers/product-discovery.js +36 -0
- package/dist/src/tasks/derivation/handlers/retry-failed-task.js +125 -0
- package/dist/src/tasks/derivation/handlers/review-pr.js +28 -0
- package/dist/src/tasks/derivation/handlers/shared.js +24 -0
- package/dist/src/tasks/derivation/handlers/sync-parent-branch.js +100 -0
- package/dist/src/tasks/derivation/handlers/wave-assessment.js +223 -0
- package/dist/src/tasks/derivation/handlers/write-plan.js +101 -0
- package/dist/src/tasks/derivation/handlers/write-product-spec.js +49 -0
- package/dist/src/tasks/derivation/runner.js +18 -0
- package/dist/src/tasks/derivation/types.js +1 -0
- package/dist/src/tasks/derive.js +810 -0
- package/dist/src/tasks/mcp-skip.js +10 -0
- package/dist/src/tasks/retry.js +10 -0
- package/dist/src/tasks/task.js +184 -0
- package/dist/src/tasks/types.js +1 -0
- package/dist/src/utils/command-runner.js +192 -0
- package/dist/src/utils/json.js +38 -0
- package/dist/src/utils/logger.js +43 -0
- package/dist/src/utils/paths.js +38 -0
- package/dist/src/utils/slug.js +10 -0
- package/dist/src/workflows/registry.js +174 -0
- package/dist/src/workflows/triage.js +90 -0
- package/dist/src/workflows/workstream-machine/derive-events.js +121 -0
- package/dist/src/workflows/workstream-machine/evaluate.js +24 -0
- package/dist/src/workflows/workstream-machine/events.js +1 -0
- package/dist/src/workflows/workstream-machine/machine.js +355 -0
- package/dist/src/workflows/workstream-machine/selectors.js +19 -0
- package/dist/src/workflows/workstream-machine/types.js +1 -0
- package/dist/src/workstreams/branch-sync.js +87 -0
- package/dist/src/workstreams/derive.js +629 -0
- package/dist/src/workstreams/mcp-blockers.js +420 -0
- package/dist/src/workstreams/packet-candidates.js +42 -0
- package/dist/src/workstreams/packet-lifecycle-feedback.js +60 -0
- package/dist/src/workstreams/packet-lifecycle-report.js +199 -0
- package/dist/src/workstreams/packet-plan.js +597 -0
- package/dist/src/workstreams/packet-projections.js +190 -0
- package/dist/src/workstreams/parent-branch-sync-action.js +312 -0
- package/dist/src/workstreams/parent-branch-sync.js +148 -0
- package/dist/src/workstreams/phases.js +4 -0
- package/dist/src/workstreams/plan-breakdown-generator/export.js +19 -0
- package/dist/src/workstreams/plan-breakdown-generator/index.js +6 -0
- package/dist/src/workstreams/plan-breakdown-generator/inspect.js +50 -0
- package/dist/src/workstreams/plan-breakdown-generator/patch.js +139 -0
- package/dist/src/workstreams/plan-breakdown-generator/session.js +19 -0
- package/dist/src/workstreams/plan-breakdown-generator/store.js +27 -0
- package/dist/src/workstreams/plan-breakdown-generator/tools.js +407 -0
- package/dist/src/workstreams/plan-breakdown-generator/types.js +6 -0
- package/dist/src/workstreams/plan-breakdown-generator/validate.js +212 -0
- package/dist/src/workstreams/plan-breakdown-schema.js +175 -0
- package/dist/src/workstreams/utils.js +15 -0
- package/dist/src/workstreams/wave-assessment/checkpoint.js +172 -0
- package/dist/src/workstreams/wave-assessment/index.js +3 -0
- package/dist/src/workstreams/wave-assessment/session.js +84 -0
- package/dist/src/workstreams/wave-assessment/store.js +51 -0
- package/dist/src/workstreams/wave-assessment/tools.js +419 -0
- package/dist/src/workstreams/wave-assessment/types.js +1 -0
- package/dist/src/workstreams/wave-assessment/validate.js +78 -0
- package/dist/src/worktrees/service.js +839 -0
- package/dist/src/worktrees/workspace-ownership.js +34 -0
- package/dist/src/worktrees/workspace-recovery.js +177 -0
- package/package.json +61 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { recommendBranchSyncAction } from "./branch-sync.js";
|
|
2
|
+
function getNextExpectedAction(waves, currentWaveIndex, isBranchSyncReady) {
|
|
3
|
+
if (currentWaveIndex === undefined) {
|
|
4
|
+
return "complete or verify final parent PR state";
|
|
5
|
+
}
|
|
6
|
+
const currentWave = waves.find((w) => w.index === currentWaveIndex);
|
|
7
|
+
if (!currentWave) {
|
|
8
|
+
return "complete or verify final parent PR state";
|
|
9
|
+
}
|
|
10
|
+
const hasPlannedWithoutPr = currentWave.packets.some((p) => p.status === "planned" && !p.prNumber);
|
|
11
|
+
if (hasPlannedWithoutPr) {
|
|
12
|
+
return "run orchestrator again to create current-wave packet PRs";
|
|
13
|
+
}
|
|
14
|
+
const allComplete = currentWave.packets.every((p) => p.status === "merged_to_parent");
|
|
15
|
+
if (!allComplete) {
|
|
16
|
+
return "review/merge current-wave packet PRs";
|
|
17
|
+
}
|
|
18
|
+
const isFinalWave = currentWaveIndex === waves.length - 1;
|
|
19
|
+
if (isFinalWave) {
|
|
20
|
+
return "complete or verify final parent PR state";
|
|
21
|
+
}
|
|
22
|
+
if (!isBranchSyncReady) {
|
|
23
|
+
return "follow branch sync recommendation";
|
|
24
|
+
}
|
|
25
|
+
return "Review/merge current-wave packet PRs. After all current-wave packets are merged to parent and parent branch sync is ready, the next run will advance.";
|
|
26
|
+
}
|
|
27
|
+
export function buildPacketLifecycleWorkstreamReport(input) {
|
|
28
|
+
const { workstream, packetPrsCreatedThisRun, waveAdvancementsThisRun, blockedThisRun, parentBranchSyncPreflights, agentSyncParentBranchLabel } = input;
|
|
29
|
+
const { packetPlan, id: workstreamId, repoKey } = workstream;
|
|
30
|
+
if (!packetPlan) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const parentPrNumber = workstream.integration?.prNumber;
|
|
34
|
+
const waves = packetPlan.waves.map((packetIds, index) => {
|
|
35
|
+
let state = "waiting";
|
|
36
|
+
if (packetPlan.currentWaveIndex === undefined) {
|
|
37
|
+
state = "complete";
|
|
38
|
+
}
|
|
39
|
+
else if (index < packetPlan.currentWaveIndex) {
|
|
40
|
+
const allMerged = packetIds.every((id) => packetPlan.packets[id]?.status === "merged_to_parent");
|
|
41
|
+
state = allMerged ? "complete" : "waiting";
|
|
42
|
+
}
|
|
43
|
+
else if (index === packetPlan.currentWaveIndex) {
|
|
44
|
+
state = "current";
|
|
45
|
+
}
|
|
46
|
+
else if (index > packetPlan.currentWaveIndex) {
|
|
47
|
+
state = "future";
|
|
48
|
+
}
|
|
49
|
+
const packets = packetIds.map((id) => {
|
|
50
|
+
const p = packetPlan.packets[id];
|
|
51
|
+
return {
|
|
52
|
+
id,
|
|
53
|
+
status: p?.status ?? "planned",
|
|
54
|
+
branchName: p?.branchName,
|
|
55
|
+
prNumber: p?.prNumber
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
return { index, state, packets };
|
|
59
|
+
});
|
|
60
|
+
const matchingPreflight = parentBranchSyncPreflights?.find(p => p.preflight.workstreamId === workstreamId);
|
|
61
|
+
const isBranchSyncReady = matchingPreflight
|
|
62
|
+
? recommendBranchSyncAction(matchingPreflight.branchSyncComparison, matchingPreflight.branchSyncComparisonSkippedReason) === "ready_to_advance"
|
|
63
|
+
: false;
|
|
64
|
+
const workstreamPrsCreated = packetPrsCreatedThisRun.filter(e => e.workstreamId === workstreamId);
|
|
65
|
+
const workstreamAdvancements = waveAdvancementsThisRun.filter(e => e.workstreamId === workstreamId);
|
|
66
|
+
const workstreamBlocked = blockedThisRun.filter(e => e.workstreamId === workstreamId);
|
|
67
|
+
return {
|
|
68
|
+
workstreamId,
|
|
69
|
+
repoKey,
|
|
70
|
+
parentPrNumber,
|
|
71
|
+
currentWaveIndex: packetPlan.currentWaveIndex,
|
|
72
|
+
waveCount: packetPlan.waves.length,
|
|
73
|
+
waves,
|
|
74
|
+
packetPrsCreatedThisRun: workstreamPrsCreated,
|
|
75
|
+
waveAdvancementsThisRun: workstreamAdvancements,
|
|
76
|
+
blockedThisRun: workstreamBlocked,
|
|
77
|
+
nextExpectedAction: getNextExpectedAction(waves, packetPlan.currentWaveIndex, isBranchSyncReady),
|
|
78
|
+
parentBranchSyncPreflight: matchingPreflight,
|
|
79
|
+
agentSyncParentBranchLabel
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function formatPacketLifecycleReport(report) {
|
|
83
|
+
const parts = [];
|
|
84
|
+
parts.push("## Multi-wave packet status\n");
|
|
85
|
+
parts.push(`Workstream: ${report.workstreamId}`);
|
|
86
|
+
if (report.parentPrNumber) {
|
|
87
|
+
parts.push(`Parent PR: #${report.parentPrNumber}`);
|
|
88
|
+
}
|
|
89
|
+
if (report.currentWaveIndex !== undefined) {
|
|
90
|
+
parts.push(`Current wave: ${report.currentWaveIndex} / ${report.waveCount}\n`);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
parts.push(`Current wave: complete\n`);
|
|
94
|
+
}
|
|
95
|
+
for (const wave of report.waves) {
|
|
96
|
+
parts.push(`Wave ${wave.index} - ${wave.state}`);
|
|
97
|
+
for (const packet of wave.packets) {
|
|
98
|
+
const prText = packet.prNumber ? `PR #${packet.prNumber}` : "no PR yet";
|
|
99
|
+
parts.push(`- ${packet.id} - ${packet.status} - ${prText}`);
|
|
100
|
+
}
|
|
101
|
+
parts.push("");
|
|
102
|
+
}
|
|
103
|
+
const branchSyncSection = formatParentBranchSyncSection(report.parentBranchSyncPreflight, report.agentSyncParentBranchLabel);
|
|
104
|
+
if (branchSyncSection) {
|
|
105
|
+
parts.push(branchSyncSection);
|
|
106
|
+
}
|
|
107
|
+
if (report.waveAdvancementsThisRun.length > 0 || report.packetPrsCreatedThisRun.length > 0 || report.blockedThisRun.length > 0) {
|
|
108
|
+
parts.push("This run:");
|
|
109
|
+
for (const adv of report.waveAdvancementsThisRun) {
|
|
110
|
+
parts.push(`- Advanced from wave ${adv.fromWaveIndex} to wave ${adv.toWaveIndex}.`);
|
|
111
|
+
if (adv.newlyCurrentPacketIds.length > 0) {
|
|
112
|
+
const newPrs = report.packetPrsCreatedThisRun.filter(p => adv.newlyCurrentPacketIds.includes(p.packetId));
|
|
113
|
+
if (newPrs.length < adv.newlyCurrentPacketIds.length) {
|
|
114
|
+
const deferredIds = adv.newlyCurrentPacketIds.filter(id => !newPrs.some(pr => pr.packetId === id));
|
|
115
|
+
parts.push(`- Deferred packet PR creation for newly advanced packets until the next run: ${deferredIds.join(", ")}.`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
for (const pr of report.packetPrsCreatedThisRun) {
|
|
120
|
+
parts.push(`- Created packet PR #${pr.prNumber} for ${pr.packetId}.`);
|
|
121
|
+
}
|
|
122
|
+
parts.push("");
|
|
123
|
+
}
|
|
124
|
+
if (report.blockedThisRun.length > 0) {
|
|
125
|
+
parts.push("Blocked / waiting:");
|
|
126
|
+
for (const blocked of report.blockedThisRun) {
|
|
127
|
+
parts.push(`- ${blocked.reason}`);
|
|
128
|
+
}
|
|
129
|
+
parts.push("");
|
|
130
|
+
}
|
|
131
|
+
parts.push("Next expected action:");
|
|
132
|
+
parts.push(`- ${report.nextExpectedAction}`);
|
|
133
|
+
return parts.join("\n");
|
|
134
|
+
}
|
|
135
|
+
function formatParentBranchSyncSection(item, syncLabel) {
|
|
136
|
+
if (!item) {
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
const { preflight, branchSyncComparison, branchSyncComparisonSkippedReason } = item;
|
|
140
|
+
const parts = ["Parent branch sync:"];
|
|
141
|
+
parts.push(`- Parent branch: \`${preflight.parentIntegrationBranch}\``);
|
|
142
|
+
parts.push(`- Default branch: \`${preflight.defaultBranch}\``);
|
|
143
|
+
const statusLine = formatBranchSyncStatus(branchSyncComparison, branchSyncComparisonSkippedReason);
|
|
144
|
+
parts.push(`- Status: ${statusLine}`);
|
|
145
|
+
const action = recommendBranchSyncAction(branchSyncComparison, branchSyncComparisonSkippedReason);
|
|
146
|
+
const recommendation = formatBranchSyncRecommendation(action, syncLabel ?? "agent-sync-parent-branch");
|
|
147
|
+
parts.push(`- Recommendation: ${recommendation}`);
|
|
148
|
+
const showLabel = action === "sync_parent_from_default" || action === "manual_conflict_aware_sync_required";
|
|
149
|
+
if (syncLabel && showLabel) {
|
|
150
|
+
parts.push(`- Action label: \`${syncLabel}\``);
|
|
151
|
+
}
|
|
152
|
+
parts.push("");
|
|
153
|
+
return parts.join("\n");
|
|
154
|
+
}
|
|
155
|
+
function formatBranchSyncStatus(comparison, skippedReason) {
|
|
156
|
+
if (skippedReason === "missing_local_path") {
|
|
157
|
+
return "unavailable (missing local repository path)";
|
|
158
|
+
}
|
|
159
|
+
if (!comparison) {
|
|
160
|
+
return "unknown";
|
|
161
|
+
}
|
|
162
|
+
let text = `\`${comparison.status}\``;
|
|
163
|
+
if (comparison.parentAheadCount !== undefined && comparison.parentBehindCount !== undefined) {
|
|
164
|
+
text += ` (behind ${comparison.parentBehindCount}, ahead ${comparison.parentAheadCount})`;
|
|
165
|
+
}
|
|
166
|
+
return text;
|
|
167
|
+
}
|
|
168
|
+
function formatBranchSyncRecommendation(action, syncLabel) {
|
|
169
|
+
switch (action) {
|
|
170
|
+
case "ready_to_advance":
|
|
171
|
+
return "the parent branch is up to date with default and the next packet wave may advance on the next orchestration evaluation.";
|
|
172
|
+
case "sync_parent_from_default":
|
|
173
|
+
return `add \`${syncLabel}\` to the parent PR to authorize merging default into the parent branch. The orchestrator will perform the local git operation and push.`;
|
|
174
|
+
case "manual_conflict_aware_sync_required":
|
|
175
|
+
return `the parent and default branches have diverged. Adding \`${syncLabel}\` authorizes one conflict-aware merge attempt. If conflicts occur, they will be reported as blocked and manual resolution will be required.`;
|
|
176
|
+
case "blocked_missing_ref":
|
|
177
|
+
return "sync is blocked because required branch refs are missing. These must be diagnosed before sync can proceed.";
|
|
178
|
+
case "blocked_unknown":
|
|
179
|
+
default:
|
|
180
|
+
return "parent branch sync status is unavailable or unknown and must be diagnosed before sync can proceed.";
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
export function formatPacketLifecycleReportsForRunSummary(reports) {
|
|
184
|
+
if (reports.length === 0) {
|
|
185
|
+
return "";
|
|
186
|
+
}
|
|
187
|
+
// Sort reports by repoKey, then workstreamId
|
|
188
|
+
const sortedReports = [...reports].sort((a, b) => {
|
|
189
|
+
if (a.repoKey !== b.repoKey)
|
|
190
|
+
return a.repoKey.localeCompare(b.repoKey);
|
|
191
|
+
return a.workstreamId.localeCompare(b.workstreamId);
|
|
192
|
+
});
|
|
193
|
+
const parts = ["Multi-wave packet lifecycle:"];
|
|
194
|
+
for (const report of sortedReports) {
|
|
195
|
+
parts.push(formatPacketLifecycleReport(report));
|
|
196
|
+
parts.push("");
|
|
197
|
+
}
|
|
198
|
+
return parts.join("\n").trimEnd();
|
|
199
|
+
}
|