@herbcaudill/ralph 0.5.1 → 0.6.1

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.
Files changed (45) hide show
  1. package/README.md +3 -14
  2. package/dist/cli.js +1 -1
  3. package/dist/components/App.d.ts.map +1 -1
  4. package/dist/components/App.js +2 -5
  5. package/dist/components/App.js.map +1 -1
  6. package/dist/components/EventDisplay.d.ts +2 -3
  7. package/dist/components/EventDisplay.d.ts.map +1 -1
  8. package/dist/components/EventDisplay.js +128 -63
  9. package/dist/components/EventDisplay.js.map +1 -1
  10. package/dist/components/EventDisplay.replay.test.js +49 -67
  11. package/dist/components/EventDisplay.replay.test.js.map +1 -1
  12. package/dist/components/EventDisplay.test.js +11 -11
  13. package/dist/components/EventDisplay.test.js.map +1 -1
  14. package/dist/components/FullScreenLayout.d.ts +14 -0
  15. package/dist/components/FullScreenLayout.d.ts.map +1 -0
  16. package/dist/components/FullScreenLayout.js +30 -0
  17. package/dist/components/FullScreenLayout.js.map +1 -0
  18. package/dist/components/Header.d.ts.map +1 -1
  19. package/dist/components/Header.js +1 -1
  20. package/dist/components/Header.js.map +1 -1
  21. package/dist/components/InitRalph.js +1 -1
  22. package/dist/components/InitRalph.js.map +1 -1
  23. package/dist/components/IterationRunner.d.ts.map +1 -1
  24. package/dist/components/IterationRunner.js +260 -93
  25. package/dist/components/IterationRunner.js.map +1 -1
  26. package/dist/components/IterationRunner.test.js +6 -6
  27. package/dist/components/IterationRunner.test.js.map +1 -1
  28. package/dist/components/ReplayLog.d.ts +1 -3
  29. package/dist/components/ReplayLog.d.ts.map +1 -1
  30. package/dist/components/ReplayLog.js +8 -9
  31. package/dist/components/ReplayLog.js.map +1 -1
  32. package/dist/lib/addTodo.d.ts.map +1 -1
  33. package/dist/lib/addTodo.js +3 -2
  34. package/dist/lib/addTodo.js.map +1 -1
  35. package/dist/lib/formatContentBlock.d.ts +10 -0
  36. package/dist/lib/formatContentBlock.d.ts.map +1 -0
  37. package/dist/lib/formatContentBlock.js +60 -0
  38. package/dist/lib/formatContentBlock.js.map +1 -0
  39. package/dist/lib/useTerminalSize.d.ts +5 -0
  40. package/dist/lib/useTerminalSize.d.ts.map +1 -0
  41. package/dist/lib/useTerminalSize.js +21 -0
  42. package/dist/lib/useTerminalSize.js.map +1 -0
  43. package/package.json +6 -3
  44. package/templates/prompt.md +0 -1
  45. package/templates/progress.md +0 -11
package/README.md CHANGED
@@ -9,9 +9,8 @@ Ralph spawns multiple Claude CLI sessions that:
9
9
  1. Check project health (build, tests)
10
10
  2. Select and work on the highest-priority task
11
11
  3. Validate changes with tests
12
- 4. Document progress
13
- 5. Commit changes
14
- 6. Repeat
12
+ 4. Commit changes
13
+ 5. Repeat
15
14
 
16
15
  ## Installation
17
16
 
@@ -37,8 +36,7 @@ This creates a `.ralph/` directory with template files:
37
36
 
38
37
  - `prompt.md` - Instructions for Claude during each iteration
39
38
  - `todo.md` - Your task list
40
- - `progress.md` - Progress log (auto-updated)
41
- - `events.log` - Event log (auto-generated)
39
+ - `events.log` - Event log (auto-generated during runs)
42
40
 
43
41
  2. **Customize the workflow:**
44
42
 
@@ -99,14 +97,6 @@ Your task list with priority and completion status. Tasks can be:
99
97
  - Detailed descriptions with acceptance criteria
100
98
  - Broken down into subtasks
101
99
 
102
- **`.ralph/progress.md`**
103
-
104
- Auto-updated log of completed work. Each entry includes:
105
-
106
- - What was changed
107
- - Why it was changed
108
- - Commit information
109
-
110
100
  **`.ralph/events.log`**
111
101
 
112
102
  Machine-readable log of all Claude interactions (JSON). Use for debugging or replay.
@@ -161,7 +151,6 @@ claude auth
161
151
  ## Tips
162
152
 
163
153
  - **Start with small iteration counts** (3-5) to verify the workflow before running longer sessions
164
- - **Review progress.md** between runs to understand what changed
165
154
  - **Customize prompt.md** for your project's specific needs (build commands, test frameworks, etc.)
166
155
  - **Break down complex tasks** into smaller subtasks in todo.md
167
156
  - **Let Claude prioritize** by not ordering tasks strictly - Claude will choose what makes sense
package/dist/cli.js CHANGED
@@ -11,7 +11,7 @@ export const program = new Command()
11
11
  .name("ralph")
12
12
  .description("Autonomous AI iteration engine for Claude CLI")
13
13
  .version(packageJson.version)
14
- .argument("[iterations]", "number of iterations to run", val => parseInt(val, 10), 10)
14
+ .argument("[iterations]", "number of iterations to run", val => parseInt(val, 10), 30)
15
15
  .option("--replay [file]", "replay events from log file")
16
16
  .action((iterations, options) => {
17
17
  const replayFile = options.replay !== undefined ?
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,eAAO,MAAM,GAAG,GAAI,yDAAyD,KAAK,sBAsBjF,CAAA;AAED,KAAK,KAAK,GAAG;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,eAAO,MAAM,GAAG,GAAI,yDAAyD,KAAK,sBAYjF,CAAA;AAED,KAAK,KAAK,GAAG;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA"}
@@ -1,13 +1,10 @@
1
1
  import React from "react";
2
- import { Box } from "ink";
3
2
  import { IterationRunner } from "./IterationRunner.js";
4
3
  import { ReplayLog } from "./ReplayLog.js";
5
4
  export const App = ({ iterations, replayFile, claudeVersion, ralphVersion }) => {
6
5
  if (replayFile) {
7
- return (React.createElement(Box, { flexDirection: "column", marginX: 1 },
8
- React.createElement(ReplayLog, { filePath: replayFile, claudeVersion: claudeVersion, ralphVersion: ralphVersion })));
6
+ return React.createElement(ReplayLog, { filePath: replayFile });
9
7
  }
10
- return (React.createElement(Box, { flexDirection: "column", marginX: 1 },
11
- React.createElement(IterationRunner, { totalIterations: iterations, claudeVersion: claudeVersion, ralphVersion: ralphVersion })));
8
+ return (React.createElement(IterationRunner, { totalIterations: iterations, claudeVersion: claudeVersion, ralphVersion: ralphVersion }));
12
9
  };
13
10
  //# sourceMappingURL=App.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAS,EAAE,EAAE;IACpF,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC;YACpC,oBAAC,SAAS,IACR,QAAQ,EAAE,UAAU,EACpB,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,GAC1B,CACE,CACP,CAAA;IACH,CAAC;IAED,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC;QACpC,oBAAC,eAAe,IACd,eAAe,EAAE,UAAU,EAC3B,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,GAC1B,CACE,CACP,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAS,EAAE,EAAE;IACpF,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,oBAAC,SAAS,IAAC,QAAQ,EAAE,UAAU,GAAI,CAAA;IAC5C,CAAC;IAED,OAAO,CACL,oBAAC,eAAe,IACd,eAAe,EAAE,UAAU,EAC3B,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,GAC1B,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -3,13 +3,12 @@ type IterationEvents = {
3
3
  iteration: number;
4
4
  events: Array<Record<string, unknown>>;
5
5
  };
6
- export declare const EventDisplay: ({ events, iteration, completedIterations, claudeVersion, ralphVersion, }: Props) => React.JSX.Element;
6
+ export declare const EventDisplay: ({ events, iteration, completedIterations, height }: Props) => React.JSX.Element;
7
7
  type Props = {
8
8
  events: Array<Record<string, unknown>>;
9
9
  iteration: number;
10
10
  completedIterations: IterationEvents[];
11
- claudeVersion: string;
12
- ralphVersion: string;
11
+ height?: number;
13
12
  };
14
13
  export {};
15
14
  //# sourceMappingURL=EventDisplay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EventDisplay.d.ts","sourceRoot":"","sources":["../../src/components/EventDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAA;AAOtC,KAAK,eAAe,GAAG;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACvC,CAAA;AAkED,eAAO,MAAM,YAAY,GAAI,0EAM1B,KAAK,sBAkGP,CAAA;AAED,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB,EAAE,eAAe,EAAE,CAAA;IACtC,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA"}
1
+ {"version":3,"file":"EventDisplay.d.ts","sourceRoot":"","sources":["../../src/components/EventDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAA;AAKnE,KAAK,eAAe,GAAG;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACvC,CAAA;AAuGD,eAAO,MAAM,YAAY,GAAI,oDAAoD,KAAK,sBAgGrF,CAAA;AAED,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB,EAAE,eAAe,EAAE,CAAA;IACtC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA"}
@@ -1,16 +1,16 @@
1
- import React, { useMemo } from "react";
2
- import { Box, Static, Text, useStdout } from "ink";
3
- import { StreamingText } from "./StreamingText.js";
4
- import { ToolUse } from "./ToolUse.js";
5
- import { Header } from "./Header.js";
1
+ import React, { useMemo, useState, useEffect, useRef } from "react";
2
+ import { Box, Text, useInput } from "ink";
6
3
  import { eventToBlocks } from "./eventToBlocks.js";
4
+ import { formatContentBlock, formatIterationHeader } from "../lib/formatContentBlock.js";
7
5
  // Process raw events into content blocks
6
+ // With includePartialMessages: true, we receive multiple snapshots of the same message
7
+ // as it builds up. Each snapshot may contain different parts of the message content,
8
+ // so we need to merge them and deduplicate.
8
9
  const processEvents = (events) => {
9
10
  // Filter to only show complete assistant messages, not streaming events
10
11
  // streaming events are incomplete and cause duplicate/disappearing content
11
12
  const assistantEvents = events.filter(event => event.type === "assistant");
12
- // Group by message ID and merge content from all versions
13
- // The Claude CLI sends multiple snapshots of the same message as it builds up
13
+ // Collect all content blocks from all snapshots of the same message
14
14
  const messageMap = new Map();
15
15
  for (const event of assistantEvents) {
16
16
  const message = event.message;
@@ -20,11 +20,10 @@ const processEvents = (events) => {
20
20
  if (!messageMap.has(messageId)) {
21
21
  messageMap.set(messageId, []);
22
22
  }
23
- // Collect all content blocks from all versions
24
23
  messageMap.get(messageId).push(...content);
25
24
  }
26
25
  }
27
- // Create merged events with all content
26
+ // Create merged events with deduplicated content
28
27
  const mergedEvents = Array.from(messageMap.entries()).map(([messageId, allContent]) => {
29
28
  // Deduplicate content blocks by their ID (for tool_use) or text (for text blocks)
30
29
  const seenBlocks = new Set();
@@ -33,10 +32,38 @@ const processEvents = (events) => {
33
32
  const blockType = block.type;
34
33
  let blockKey;
35
34
  if (blockType === "tool_use") {
36
- blockKey = block.id;
35
+ // Tool use blocks are unique by their ID
36
+ blockKey = `tool:${block.id}`;
37
37
  }
38
38
  else if (blockType === "text") {
39
- blockKey = `text:${block.text}`;
39
+ // For text blocks, check if this is a prefix of or prefixed by existing text
40
+ // This handles incremental text updates where each snapshot has more content
41
+ const text = block.text;
42
+ let isDuplicate = false;
43
+ for (const seenKey of seenBlocks) {
44
+ if (seenKey.startsWith("text:")) {
45
+ const seenText = seenKey.substring(5);
46
+ // If existing text starts with this text, or this text starts with existing,
47
+ // keep only the longer one
48
+ if (seenText.startsWith(text)) {
49
+ // Existing is longer, this is a duplicate
50
+ isDuplicate = true;
51
+ break;
52
+ }
53
+ else if (text.startsWith(seenText)) {
54
+ // This is longer, remove the old one and add this
55
+ seenBlocks.delete(seenKey);
56
+ // Also remove from uniqueContent
57
+ const idx = uniqueContent.findIndex(b => b.type === "text" && b.text === seenText);
58
+ if (idx >= 0)
59
+ uniqueContent.splice(idx, 1);
60
+ break;
61
+ }
62
+ }
63
+ }
64
+ if (isDuplicate)
65
+ continue;
66
+ blockKey = `text:${text}`;
40
67
  }
41
68
  else {
42
69
  blockKey = JSON.stringify(block);
@@ -56,62 +83,100 @@ const processEvents = (events) => {
56
83
  });
57
84
  return mergedEvents.flatMap(event => eventToBlocks(event));
58
85
  };
59
- export const EventDisplay = ({ events, iteration, completedIterations, claudeVersion, ralphVersion, }) => {
60
- const { stdout } = useStdout();
61
- // Account for the marginX={1} in App.tsx (2 chars total)
62
- const terminalWidth = (stdout?.columns ?? 80) - 2;
63
- // Build static items for completed iterations only
64
- // Current iteration is rendered separately to ensure proper ordering
65
- const staticItems = useMemo(() => {
66
- const items = [
67
- { type: "app-header", id: "app-header", claudeVersion, ralphVersion, width: terminalWidth },
68
- ];
69
- // Add completed iterations and their content
86
+ // Convert content blocks to lines of formatted text
87
+ const blocksToLines = (blocks) => {
88
+ const lines = [];
89
+ for (const block of blocks) {
90
+ const blockLines = formatContentBlock(block);
91
+ lines.push(...blockLines);
92
+ // Add blank line after each block
93
+ lines.push("");
94
+ }
95
+ return lines;
96
+ };
97
+ export const EventDisplay = ({ events, iteration, completedIterations, height }) => {
98
+ // Scroll offset from bottom (0 = at bottom, positive = scrolled up)
99
+ const [scrollOffset, setScrollOffset] = useState(0);
100
+ // Track if user has manually scrolled
101
+ const userScrolledRef = useRef(false);
102
+ // Track previous line count for auto-scroll
103
+ const prevLineCountRef = useRef(0);
104
+ // Convert all content to lines for virtual scrolling
105
+ const allLines = useMemo(() => {
106
+ const lines = [];
107
+ // Add completed iterations
70
108
  for (const completed of completedIterations) {
71
- items.push({
72
- type: "iteration-header",
73
- id: `iteration-${completed.iteration}`,
74
- iteration: completed.iteration,
75
- width: terminalWidth,
76
- });
109
+ lines.push("");
110
+ lines.push("");
111
+ lines.push(formatIterationHeader(completed.iteration));
112
+ lines.push("");
77
113
  const blocks = processEvents(completed.events);
78
- for (const block of blocks) {
79
- // Prefix block IDs with iteration number to ensure uniqueness
80
- items.push({
81
- ...block,
82
- id: `iter${completed.iteration}-${block.id}`,
83
- });
84
- }
114
+ lines.push(...blocksToLines(blocks));
85
115
  }
86
- return items;
87
- }, [completedIterations, claudeVersion, ralphVersion, terminalWidth]);
88
- // Process current iteration events
89
- const currentBlocks = useMemo(() => processEvents(events), [events]);
90
- // Use Static to render completed iterations permanently to the scrollback buffer.
91
- // Current iteration is rendered normally below to ensure headers appear correctly.
92
- // Note: We use a fragment to avoid wrapper Box indentation issues with Static.
93
- return (React.createElement(React.Fragment, null,
94
- React.createElement(Static, { items: staticItems }, (item, index) => {
95
- if (item.type === "app-header") {
96
- return (React.createElement(Header, { key: item.id, claudeVersion: item.claudeVersion, ralphVersion: item.ralphVersion, width: item.width }));
116
+ // Add current iteration
117
+ lines.push("");
118
+ lines.push("");
119
+ lines.push(formatIterationHeader(iteration));
120
+ lines.push("");
121
+ const currentBlocks = processEvents(events);
122
+ lines.push(...blocksToLines(currentBlocks));
123
+ return lines;
124
+ }, [events, iteration, completedIterations]);
125
+ // Auto-scroll to bottom when new content arrives (unless user scrolled up)
126
+ useEffect(() => {
127
+ if (allLines.length > prevLineCountRef.current && !userScrolledRef.current) {
128
+ setScrollOffset(0);
129
+ }
130
+ prevLineCountRef.current = allLines.length;
131
+ }, [allLines.length]);
132
+ // Handle keyboard input for scrolling
133
+ useInput((input, key) => {
134
+ if (!height)
135
+ return;
136
+ const maxOffset = Math.max(0, allLines.length - height);
137
+ const pageSize = Math.max(1, height - 2);
138
+ if (key.upArrow || input === "k") {
139
+ userScrolledRef.current = true;
140
+ setScrollOffset(prev => Math.min(maxOffset, prev + 1));
141
+ }
142
+ else if (key.downArrow || input === "j") {
143
+ const newOffset = Math.max(0, scrollOffset - 1);
144
+ setScrollOffset(newOffset);
145
+ if (newOffset === 0) {
146
+ userScrolledRef.current = false;
97
147
  }
98
- if (item.type === "iteration-header") {
99
- return (React.createElement(Box, { key: item.id, borderStyle: "round", borderColor: "cyan", paddingX: 1, marginBottom: 1, width: item.width },
100
- React.createElement(Text, { color: "cyan" },
101
- "Iteration ",
102
- item.iteration)));
148
+ }
149
+ else if (key.pageUp) {
150
+ userScrolledRef.current = true;
151
+ setScrollOffset(prev => Math.min(maxOffset, prev + pageSize));
152
+ }
153
+ else if (key.pageDown) {
154
+ const newOffset = Math.max(0, scrollOffset - pageSize);
155
+ setScrollOffset(newOffset);
156
+ if (newOffset === 0) {
157
+ userScrolledRef.current = false;
103
158
  }
104
- return (React.createElement(Box, { key: item.id, marginTop: index > 2 ? 1 : 0 }, item.type === "text" ?
105
- React.createElement(StreamingText, { content: item.content })
106
- : React.createElement(ToolUse, { name: item.name, arg: item.arg })));
107
- }),
108
- React.createElement(Box, { flexDirection: "column" },
109
- React.createElement(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1, marginBottom: 1, width: terminalWidth },
110
- React.createElement(Text, { color: "cyan" },
111
- "Iteration ",
112
- iteration)),
113
- currentBlocks.map((block, index) => (React.createElement(Box, { key: `iter${iteration}-${block.id}`, marginTop: index > 0 ? 1 : 0 }, block.type === "text" ?
114
- React.createElement(StreamingText, { content: block.content })
115
- : React.createElement(ToolUse, { name: block.name, arg: block.arg })))))));
159
+ }
160
+ else if (input === "g" && key.shift) {
161
+ // Shift+G = go to bottom
162
+ setScrollOffset(0);
163
+ userScrolledRef.current = false;
164
+ }
165
+ else if (input === "g") {
166
+ // g = go to top
167
+ userScrolledRef.current = true;
168
+ setScrollOffset(maxOffset);
169
+ }
170
+ });
171
+ // Calculate visible lines based on scroll position
172
+ const visibleLines = useMemo(() => {
173
+ if (!height || allLines.length <= height) {
174
+ return allLines;
175
+ }
176
+ const endIndex = allLines.length - scrollOffset;
177
+ const startIndex = Math.max(0, endIndex - height);
178
+ return allLines.slice(startIndex, endIndex);
179
+ }, [allLines, height, scrollOffset]);
180
+ return (React.createElement(Box, { flexDirection: "column" }, visibleLines.map((line, index) => (React.createElement(Text, { key: index, wrap: "wrap" }, line || " ")))));
116
181
  };
117
182
  //# sourceMappingURL=EventDisplay.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EventDisplay.js","sourceRoot":"","sources":["../../src/components/EventDisplay.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EventDisplay.js","sourceRoot":"","sources":["../../src/components/EventDisplay.tsx"],"names":[],"mappings":"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"}
@@ -26,7 +26,7 @@ async function replay(logFile) {
26
26
  }
27
27
  }
28
28
  // Render with all events
29
- const { lastFrame } = render(React.createElement(EventDisplay, { events: events, iteration: 1, completedIterations: [], claudeVersion: "1.0.0", ralphVersion: "0.1.0" }));
29
+ const { lastFrame } = render(React.createElement(EventDisplay, { events: events, iteration: 1, completedIterations: [] }));
30
30
  // Wait for rendering
31
31
  await vi.waitFor(() => {
32
32
  const output = lastFrame() ?? "";
@@ -37,63 +37,44 @@ async function replay(logFile) {
37
37
  describe("EventDisplay replay tests", () => {
38
38
  it("replays 1.txt", async () => {
39
39
  expect(await replay("1.txt")).toMatchInlineSnapshot(`
40
- "┌────────────────────────────────────────────────────────────────────────────────────────────────┐
41
- │ │
42
- │ │
43
- │ █▀█ ▄▀█ █ █▀█ █ █ │
44
- │ █▀▄ █▀█ █▄▄ █▀▀ █▀█ │
45
- │ │
46
- │ │
47
- │ @herbcaudill/ralph v0.1.0 • Claude Code v1.0.0 │
48
- └────────────────────────────────────────────────────────────────────────────────────────────────┘
49
-
50
- ╭────────────────────────────────────────────────────────────────────────────────────────────────╮
51
- │ Iteration 1 │
52
- ╰────────────────────────────────────────────────────────────────────────────────────────────────╯
40
+ "
41
+
42
+ ─── Iteration 1 ───
53
43
 
54
44
  I'll start by checking the types, unit tests, and end-to-end tests as instructed.
55
45
 
56
46
  TodoWrite
57
- [~] Run typecheck to verify types
58
- [ ] Run unit tests via pnpm test
59
- [ ] Run end-to-end tests via pnpm test:pw
47
+ [~] Run typecheck to verify types
48
+ [ ] Run unit tests via pnpm test
49
+ [ ] Run end-to-end tests via pnpm test:pw
60
50
 
61
51
  $ pnpm typecheck
62
52
 
63
53
  Good! Types check successfully. Now let me run the unit tests.
64
54
 
65
55
  TodoWrite
66
- [x] Run typecheck to verify types
67
- [~] Run unit tests via pnpm test
68
- [ ] Run end-to-end tests via pnpm test:pw
56
+ [x] Run typecheck to verify types
57
+ [~] Run unit tests via pnpm test
58
+ [ ] Run end-to-end tests via pnpm test:pw
69
59
 
70
60
  $ pnpm test
71
61
 
72
62
  Perfect! Unit tests pass. Now let me run the end-to-end tests.
73
63
 
74
64
  TodoWrite
75
- [x] Run typecheck to verify types
76
- [x] Run unit tests via pnpm test
77
- [~] Run end-to-end tests via pnpm test:pw
65
+ [x] Run typecheck to verify types
66
+ [x] Run unit tests via pnpm test
67
+ [~] Run end-to-end tests via pnpm test:pw
78
68
 
79
- $ pnpm test:pw"
69
+ $ pnpm test:pw
70
+ "
80
71
  `);
81
72
  });
82
73
  it("replays 2.txt", async () => {
83
74
  expect(await replay("2.txt")).toMatchInlineSnapshot(`
84
- "┌────────────────────────────────────────────────────────────────────────────────────────────────┐
85
- │ │
86
- │ │
87
- │ █▀█ ▄▀█ █ █▀█ █ █ │
88
- │ █▀▄ █▀█ █▄▄ █▀▀ █▀█ │
89
- │ │
90
- │ │
91
- │ @herbcaudill/ralph v0.1.0 • Claude Code v1.0.0 │
92
- └────────────────────────────────────────────────────────────────────────────────────────────────┘
93
-
94
- ╭────────────────────────────────────────────────────────────────────────────────────────────────╮
95
- │ Iteration 1 │
96
- ╰────────────────────────────────────────────────────────────────────────────────────────────────╯
75
+ "
76
+
77
+ ─── Iteration 1 ───
97
78
 
98
79
  I'll start by checking that the project builds successfully and running tests.
99
80
 
@@ -222,24 +203,24 @@ describe("EventDisplay replay tests", () => {
222
203
  Let me write a simpler test to see what's going on:
223
204
 
224
205
  $ cat > test-merge.ts << 'EOF'
225
- import { eventToBlocks } from "./src/components/eventToBlocks.js"
226
-
227
- const event = {
228
- type: "assistant",
229
- message: {
230
- id: "msg_123",
231
- content: [
232
- { type: "text", text: "Use the " },
233
- { type: "text", text: "\`console.log()\`" },
234
- { type: "text", text: " function to debug." },
235
- ],
236
- },
237
- }
238
-
239
- const result = eventToBlocks(event)
240
- console.log("Result:", JSON.stringify(result, null, 2))
241
- EOF
242
- tsx test-merge.ts
206
+ import { eventToBlocks } from "./src/components/eventToBlocks.js"
207
+
208
+ const event = {
209
+ type: "assistant",
210
+ message: {
211
+ id: "msg_123",
212
+ content: [
213
+ { type: "text", text: "Use the " },
214
+ { type: "text", text: "\`console.log()\`" },
215
+ { type: "text", text: " function to debug." },
216
+ ],
217
+ },
218
+ }
219
+
220
+ const result = eventToBlocks(event)
221
+ console.log("Result:", JSON.stringify(result, null, 2))
222
+ EOF
223
+ tsx test-merge.ts
243
224
 
244
225
  Let me check if my fix is actually working by looking at the eventToBlocks implementation more
245
226
  carefully. Actually, let me just trace through what should happen:
@@ -320,7 +301,7 @@ describe("EventDisplay replay tests", () => {
320
301
  Edit src/components/eventToBlocks.ts
321
302
 
322
303
  $ pnpm test EventDisplay.test.tsx 2>&1 | grep -A 50 "merges consecutive text blocks to prevent
323
- unwanted gaps"
304
+ unwanted gaps"
324
305
 
325
306
  EXCELLENT! The merging IS working correctly:
326
307
  - eventToBlocks returns: [{ "type": "text", "content": "Use the console.log() function to debug.",
@@ -408,23 +389,24 @@ describe("EventDisplay replay tests", () => {
408
389
  $ git add -A && git diff --cached --stat
409
390
 
410
391
  $ git commit -m "$(cat <<'EOF'
411
- Fix inline code blocks appearing in separate paragraphs
392
+ Fix inline code blocks appearing in separate paragraphs
412
393
 
413
- - Modified eventToBlocks.ts to merge consecutive text blocks using a textBuffer
414
- - Wrapped StreamingText content in Box component for proper inline rendering
415
- - Added test case to verify consecutive text blocks are merged
416
- - Updated existing tests to reflect new merging behavior
394
+ - Modified eventToBlocks.ts to merge consecutive text blocks using a textBuffer
395
+ - Wrapped StreamingText content in Box component for proper inline rendering
396
+ - Added test case to verify consecutive text blocks are merged
397
+ - Updated existing tests to reflect new merging behavior
417
398
 
418
- Fixes issue where inline code like \`console.log()\` was rendered on separate
419
- lines with gaps instead of flowing inline with surrounding text.
399
+ Fixes issue where inline code like \`console.log()\` was rendered on separate
400
+ lines with gaps instead of flowing inline with surrounding text.
420
401
 
421
- Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
422
- EOF
423
- )"
402
+ Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
403
+ EOF
404
+ )"
424
405
 
425
406
  Perfect! Let me verify git status:
426
407
 
427
- $ git status"
408
+ $ git status
409
+ "
428
410
  `);
429
411
  });
430
412
  });
@@ -1 +1 @@
1
- {"version":3,"file":"EventDisplay.replay.test.js","sourceRoot":"","sources":["../../src/components/EventDisplay.replay.test.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD;;GAEG;AACH,KAAK,UAAU,MAAM,CAAC,OAAe;IACnC,qBAAqB;IACrB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAA;IAC/D,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAEjD,uEAAuE;IACvE,MAAM,MAAM,GAAmC,EAAE,CAAA;IACjD,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC5C,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,SAAQ;QAC7B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,oBAAoB;QACtB,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAC1B,oBAAC,YAAY,IACX,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,CAAC,EACZ,mBAAmB,EAAE,EAAE,EACvB,aAAa,EAAC,OAAO,EACrB,YAAY,EAAC,OAAO,GACpB,CACH,CAAA;IAED,qBAAqB;IACrB,MAAM,EAAE,CAAC,OAAO,CACd,GAAG,EAAE;QACH,MAAM,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,CAAA;QAChC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;IAC1C,CAAC,EACD,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB,CAAA;IAED,OAAO,SAAS,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC;AAED,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;QAC7B,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAyCnD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;QAC7B,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAyVnD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"EventDisplay.replay.test.js","sourceRoot":"","sources":["../../src/components/EventDisplay.replay.test.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD;;GAEG;AACH,KAAK,UAAU,MAAM,CAAC,OAAe;IACnC,qBAAqB;IACrB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAA;IAC/D,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAEjD,uEAAuE;IACvE,MAAM,MAAM,GAAmC,EAAE,CAAA;IACjD,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC5C,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,SAAQ;QAC7B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,oBAAoB;QACtB,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAC1B,oBAAC,YAAY,IAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,mBAAmB,EAAE,EAAE,GAAI,CACxE,CAAA;IAED,qBAAqB;IACrB,MAAM,EAAE,CAAC,OAAO,CACd,GAAG,EAAE;QACH,MAAM,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,CAAA;QAChC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;IAC1C,CAAC,EACD,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB,CAAA;IAED,OAAO,SAAS,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC;AAED,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;QAC7B,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgCnD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;QAC7B,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgVnD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}