@herbcaudill/ralph 0.5.1 → 0.6.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/README.md +3 -14
- package/dist/cli.js +1 -1
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +2 -5
- package/dist/components/App.js.map +1 -1
- package/dist/components/EventDisplay.d.ts +2 -3
- package/dist/components/EventDisplay.d.ts.map +1 -1
- package/dist/components/EventDisplay.js +128 -63
- package/dist/components/EventDisplay.js.map +1 -1
- package/dist/components/EventDisplay.replay.test.js +49 -67
- package/dist/components/EventDisplay.replay.test.js.map +1 -1
- package/dist/components/EventDisplay.test.js +11 -11
- package/dist/components/EventDisplay.test.js.map +1 -1
- package/dist/components/FullScreenLayout.d.ts +14 -0
- package/dist/components/FullScreenLayout.d.ts.map +1 -0
- package/dist/components/FullScreenLayout.js +30 -0
- package/dist/components/FullScreenLayout.js.map +1 -0
- package/dist/components/Header.d.ts.map +1 -1
- package/dist/components/Header.js +1 -1
- package/dist/components/Header.js.map +1 -1
- package/dist/components/InitRalph.js +1 -1
- package/dist/components/InitRalph.js.map +1 -1
- package/dist/components/IterationRunner.d.ts.map +1 -1
- package/dist/components/IterationRunner.js +260 -93
- package/dist/components/IterationRunner.js.map +1 -1
- package/dist/components/IterationRunner.test.js +6 -6
- package/dist/components/IterationRunner.test.js.map +1 -1
- package/dist/components/ReplayLog.d.ts +1 -3
- package/dist/components/ReplayLog.d.ts.map +1 -1
- package/dist/components/ReplayLog.js +8 -9
- package/dist/components/ReplayLog.js.map +1 -1
- package/dist/lib/formatContentBlock.d.ts +10 -0
- package/dist/lib/formatContentBlock.d.ts.map +1 -0
- package/dist/lib/formatContentBlock.js +60 -0
- package/dist/lib/formatContentBlock.js.map +1 -0
- package/dist/lib/useTerminalSize.d.ts +5 -0
- package/dist/lib/useTerminalSize.d.ts.map +1 -0
- package/dist/lib/useTerminalSize.js +21 -0
- package/dist/lib/useTerminalSize.js.map +1 -0
- package/package.json +6 -3
- package/templates/prompt.md +0 -1
- 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.
|
|
13
|
-
5.
|
|
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
|
-
- `
|
|
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),
|
|
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;
|
|
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"}
|
package/dist/components/App.js
CHANGED
|
@@ -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
|
|
8
|
-
React.createElement(ReplayLog, { filePath: replayFile, claudeVersion: claudeVersion, ralphVersion: ralphVersion })));
|
|
6
|
+
return React.createElement(ReplayLog, { filePath: replayFile });
|
|
9
7
|
}
|
|
10
|
-
return (React.createElement(
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
-
//
|
|
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
|
|
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
|
-
|
|
35
|
+
// Tool use blocks are unique by their ID
|
|
36
|
+
blockKey = `tool:${block.id}`;
|
|
37
37
|
}
|
|
38
38
|
else if (blockType === "text") {
|
|
39
|
-
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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":"AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;
|
|
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: []
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
|
|
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
|
-
|
|
392
|
+
Fix inline code blocks appearing in separate paragraphs
|
|
412
393
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
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
|
-
|
|
419
|
-
|
|
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
|
-
|
|
422
|
-
|
|
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,
|
|
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"}
|