bullswarm 0.18.2 → 0.18.3
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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/workflow/dashboard.js +21 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# bullswarm changelog
|
|
2
2
|
|
|
3
|
+
## 0.18.3 — mobile timeline polish
|
|
4
|
+
|
|
5
|
+
- Auto-follow now begins at a timestamped milestone instead of exposing an
|
|
6
|
+
orphaned detail line when a long timeline is clipped on a small terminal.
|
|
7
|
+
- Qualified terminal runs state the number of concerns and direct the user to
|
|
8
|
+
review them in the result envelope.
|
|
9
|
+
|
|
3
10
|
## 0.18.2 — truthful recovery timeline and verifier cleanup
|
|
4
11
|
|
|
5
12
|
- Dependency-blocked plan branches now appear as a single skipped phase in the
|
package/package.json
CHANGED
|
@@ -559,13 +559,18 @@ function renderWorkflowOverviewPanel(model, width, height, spinnerFrame, timelin
|
|
|
559
559
|
const timelineRows = Math.max(1, contentRows - liveRows - nextRows);
|
|
560
560
|
const maxTimelineScroll = Math.max(0, timeline.lines.length - timelineRows);
|
|
561
561
|
const scroll = clamp(timelineScroll, 0, maxTimelineScroll);
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
visibleTimeline[0] = dimText(`↑ ${start + 1} earlier timeline rows`, inner);
|
|
562
|
+
let start = Math.max(0, timeline.lines.length - timelineRows - scroll);
|
|
563
|
+
if (start > 0) {
|
|
564
|
+
while (start < timeline.lines.length && !/^\d{2}:\d{2}\s/.test(timeline.lines[start])) start += 1;
|
|
566
565
|
}
|
|
567
|
-
|
|
568
|
-
|
|
566
|
+
const historyRows = start > 0 ? Math.max(0, timelineRows - 1) : timelineRows;
|
|
567
|
+
let visibleTimeline = timeline.lines.slice(start, start + historyRows);
|
|
568
|
+
if (start > 0) {
|
|
569
|
+
visibleTimeline.unshift(dimText(`↑ ${start} earlier timeline rows`, inner));
|
|
570
|
+
}
|
|
571
|
+
const end = start + historyRows;
|
|
572
|
+
if (end < timeline.lines.length && visibleTimeline.length) {
|
|
573
|
+
visibleTimeline[visibleTimeline.length - 1] = dimText(`↓ ${timeline.lines.length - end} newer timeline rows`, inner);
|
|
569
574
|
}
|
|
570
575
|
const visibleLive = live.lines.slice(0, liveRows);
|
|
571
576
|
const visibleNext = next.slice(0, nextRows);
|
|
@@ -784,14 +789,16 @@ function workflowLiveLines(model, width, spinnerFrame) {
|
|
|
784
789
|
lines.push('');
|
|
785
790
|
}
|
|
786
791
|
if (!lines.length) lines.push(state.finishedAt
|
|
787
|
-
? `${statusIcon(state.status)} No agents running · ${terminalWorkflowLabel(state.status)}`
|
|
792
|
+
? `${statusIcon(state.status)} No agents running · ${terminalWorkflowLabel(state.status, state.outcome?.concerns?.length)}`
|
|
788
793
|
: '⧖ Waiting for the next dispatch');
|
|
789
794
|
return { lines, running, waiting };
|
|
790
795
|
}
|
|
791
796
|
|
|
792
|
-
function terminalWorkflowLabel(status) {
|
|
797
|
+
function terminalWorkflowLabel(status, concernCount = 0) {
|
|
793
798
|
if (status === 'completed') return 'workflow finished';
|
|
794
|
-
if (status === 'completed_with_concerns') return
|
|
799
|
+
if (status === 'completed_with_concerns') return concernCount
|
|
800
|
+
? `workflow finished with ${concernCount} concern${concernCount === 1 ? '' : 's'}`
|
|
801
|
+
: 'workflow finished with concerns';
|
|
795
802
|
if (status === 'blocked') return 'workflow stopped with blockers';
|
|
796
803
|
if (status === 'failed') return 'workflow failed';
|
|
797
804
|
if (status === 'cancelled') return 'workflow cancelled';
|
|
@@ -802,14 +809,17 @@ function terminalWorkflowLabel(status) {
|
|
|
802
809
|
function workflowNextLines(model, width) {
|
|
803
810
|
const { state, orchestrator } = model;
|
|
804
811
|
if (state.finishedAt) {
|
|
805
|
-
const
|
|
812
|
+
const concernCount = state.outcome?.concerns?.length ?? 0;
|
|
813
|
+
const next = state.status === 'completed'
|
|
806
814
|
? 'result ready'
|
|
815
|
+
: state.status === 'completed_with_concerns'
|
|
816
|
+
? concernCount ? `review ${concernCount} concern${concernCount === 1 ? '' : 's'} in result` : 'review concerns in result'
|
|
807
817
|
: state.status === 'blocked' ? 'review blockers and partial work'
|
|
808
818
|
: state.status === 'failed' ? 'inspect the failure before using partial work'
|
|
809
819
|
: state.status === 'cancelled' ? 'review any partial work'
|
|
810
820
|
: state.status === 'interrupted' ? 'resume the workflow or inspect partial work'
|
|
811
821
|
: 'inspect the workflow result';
|
|
812
|
-
const label = terminalWorkflowLabel(state.status);
|
|
822
|
+
const label = terminalWorkflowLabel(state.status, concernCount);
|
|
813
823
|
return [truncate(`${statusIcon(state.status)} ${label[0].toUpperCase()}${label.slice(1)} · ${next}`, width)];
|
|
814
824
|
}
|
|
815
825
|
const ledger = state.actionLedger ?? [];
|