@arvorco/relentless 0.1.18 → 0.1.19

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arvorco/relentless",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "Universal AI agent orchestrator - works with Claude Code, Amp, OpenCode, Codex, Droid, and Gemini",
5
5
  "type": "module",
6
6
  "publishConfig": {
package/src/tui/App.tsx CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import React from "react";
8
- import { Box, Text } from "ink";
8
+ import { Box, Text, useStdout } from "ink";
9
9
  import { Header } from "./components/Header.js";
10
10
  import { ProgressBar } from "./components/ProgressBar.js";
11
11
  import { CurrentStory } from "./components/CurrentStory.js";
@@ -20,8 +20,23 @@ interface AppProps {
20
20
  }
21
21
 
22
22
  export function App({ state }: AppProps): React.ReactElement {
23
+ const { stdout } = useStdout();
24
+ const terminalRows = stdout.rows ?? 24;
25
+
23
26
  const completedCount = state.stories.filter((s) => s.passes).length;
24
27
  const totalCount = state.stories.length;
28
+
29
+ // Calculate available rows for stories based on terminal height
30
+ // Chrome: Header(2) + Feature/Progress(2) + CurrentStory(2) + AgentOutputHeader(1) + AgentStatusFooter(2) + Padding(2) = ~11 lines
31
+ // AgentOutput: 6 lines
32
+ // Remaining space for stories
33
+ const chromeHeight = 11;
34
+ const agentOutputLines = 6;
35
+ const availableForStories = Math.max(8, terminalRows - chromeHeight - agentOutputLines);
36
+
37
+ // Calculate story rows needed for 2-column layout
38
+ const storyRows = Math.ceil(totalCount / 2);
39
+ const maxStoryRows = Math.min(storyRows, availableForStories);
25
40
 
26
41
  return (
27
42
  <Box flexDirection="column" width="100%">
@@ -50,13 +65,13 @@ export function App({ state }: AppProps): React.ReactElement {
50
65
  </Box>
51
66
 
52
67
  {/* Agent output */}
53
- <AgentOutput lines={state.outputLines} maxLines={8} />
68
+ <AgentOutput lines={state.outputLines} maxLines={agentOutputLines} />
54
69
 
55
70
  {/* Story grid */}
56
71
  <StoryGrid
57
72
  stories={state.stories}
58
73
  currentStoryId={state.currentStory?.id}
59
- maxRows={8}
74
+ maxRows={maxStoryRows}
60
75
  />
61
76
 
62
77
  {/* Agent status footer */}
@@ -37,14 +37,43 @@ export function StoryGrid({
37
37
  rows.push(row);
38
38
  }
39
39
 
40
- // Constrain to maxRows
41
- const visibleRows = maxRows ? rows.slice(0, maxRows) : rows;
40
+ // Window around current story to show context
41
+ let visibleRows = rows;
42
+ let startRow = 0;
43
+ let endRow = rows.length;
44
+
45
+ if (maxRows && rows.length > maxRows) {
46
+ // Find the row containing the current story
47
+ const currentRowIdx = currentStoryId
48
+ ? rows.findIndex((row) => row.some((story) => story.id === currentStoryId))
49
+ : -1;
50
+
51
+ if (currentRowIdx >= 0) {
52
+ // Center the window around the current story
53
+ const half = Math.floor(maxRows / 2);
54
+ startRow = Math.max(0, currentRowIdx - half);
55
+
56
+ // Adjust if window goes past the end
57
+ if (startRow + maxRows > rows.length) {
58
+ startRow = Math.max(0, rows.length - maxRows);
59
+ }
60
+
61
+ endRow = Math.min(rows.length, startRow + maxRows);
62
+ visibleRows = rows.slice(startRow, endRow);
63
+ } else {
64
+ // No current story, just show first N rows
65
+ visibleRows = rows.slice(0, maxRows);
66
+ endRow = Math.min(rows.length, maxRows);
67
+ }
68
+ }
42
69
 
43
70
  return (
44
71
  <Box flexDirection="column" paddingY={1}>
45
72
  <Box paddingX={1}>
46
73
  <Text color={colors.dim} bold>
47
- ── Stories ({stories.length}) ──
74
+ {visibleRows.length < rows.length
75
+ ? `── Stories (rows ${startRow + 1}-${endRow} of ${rows.length}, ${stories.length} total) ──`
76
+ : `── Stories (${stories.length}) ──`}
48
77
  </Text>
49
78
  </Box>
50
79
  <Box flexDirection="column" paddingX={1}>