@herbcaudill/ralph 0.2.0 → 0.3.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/bin/ralph.js +1 -1
- package/dist/cli.d.ts +2 -19
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +30 -65
- package/dist/cli.js.map +1 -1
- package/dist/components/App.d.ts +10 -0
- package/dist/components/App.d.ts.map +1 -0
- package/dist/components/App.js +16 -0
- package/dist/components/App.js.map +1 -0
- package/dist/components/EventDisplay.d.ts +7 -0
- package/dist/components/EventDisplay.d.ts.map +1 -0
- package/dist/components/EventDisplay.js +64 -0
- package/dist/components/EventDisplay.js.map +1 -0
- package/dist/components/EventDisplay.replay.test.d.ts +2 -0
- package/dist/components/EventDisplay.replay.test.d.ts.map +1 -0
- package/dist/components/EventDisplay.replay.test.js +403 -0
- package/dist/components/EventDisplay.replay.test.js.map +1 -0
- package/dist/components/EventDisplay.test.d.ts +2 -0
- package/dist/components/EventDisplay.test.d.ts.map +1 -0
- package/dist/components/EventDisplay.test.js +223 -0
- package/dist/components/EventDisplay.test.js.map +1 -0
- package/dist/components/Header.d.ts +8 -0
- package/dist/components/Header.d.ts.map +1 -0
- package/dist/components/Header.js +15 -0
- package/dist/components/Header.js.map +1 -0
- package/dist/components/Header.test.d.ts +2 -0
- package/dist/components/Header.test.d.ts.map +1 -0
- package/dist/components/Header.test.js +27 -0
- package/dist/components/Header.test.js.map +1 -0
- package/dist/components/InitRalph.d.ts +3 -0
- package/dist/components/InitRalph.d.ts.map +1 -0
- package/dist/components/InitRalph.js +100 -0
- package/dist/components/InitRalph.js.map +1 -0
- package/dist/components/IterationRunner.d.ts +7 -0
- package/dist/components/IterationRunner.d.ts.map +1 -0
- package/dist/components/IterationRunner.js +285 -0
- package/dist/components/IterationRunner.js.map +1 -0
- package/dist/components/IterationRunner.test.d.ts +2 -0
- package/dist/components/IterationRunner.test.d.ts.map +1 -0
- package/dist/components/IterationRunner.test.js +109 -0
- package/dist/components/IterationRunner.test.js.map +1 -0
- package/dist/components/ReplayLog.d.ts +7 -0
- package/dist/components/ReplayLog.d.ts.map +1 -0
- package/dist/components/ReplayLog.js +51 -0
- package/dist/components/ReplayLog.js.map +1 -0
- package/dist/components/StreamingText.d.ts +7 -0
- package/dist/components/StreamingText.d.ts.map +1 -0
- package/dist/components/StreamingText.js +36 -0
- package/dist/components/StreamingText.js.map +1 -0
- package/dist/components/StreamingText.test.d.ts +2 -0
- package/dist/components/StreamingText.test.d.ts.map +1 -0
- package/dist/components/StreamingText.test.js +86 -0
- package/dist/components/StreamingText.test.js.map +1 -0
- package/dist/components/ToolUse.d.ts +8 -0
- package/dist/components/ToolUse.d.ts.map +1 -0
- package/dist/components/ToolUse.js +10 -0
- package/dist/components/ToolUse.js.map +1 -0
- package/dist/components/ToolUse.test.d.ts +2 -0
- package/dist/components/ToolUse.test.d.ts.map +1 -0
- package/dist/components/ToolUse.test.js +43 -0
- package/dist/components/ToolUse.test.js.map +1 -0
- package/dist/components/eventToBlocks.d.ts +12 -0
- package/dist/components/eventToBlocks.d.ts.map +1 -0
- package/dist/components/eventToBlocks.js +142 -0
- package/dist/components/eventToBlocks.js.map +1 -0
- package/dist/components/eventToBlocks.test.d.ts +2 -0
- package/dist/components/eventToBlocks.test.d.ts.map +1 -0
- package/dist/components/eventToBlocks.test.js +412 -0
- package/dist/components/eventToBlocks.test.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -21
- package/dist/index.js.map +1 -1
- package/dist/lib/cleanupAllWorktrees.d.ts +5 -0
- package/dist/lib/cleanupAllWorktrees.d.ts.map +1 -0
- package/dist/lib/cleanupAllWorktrees.js +25 -0
- package/dist/lib/cleanupAllWorktrees.js.map +1 -0
- package/dist/lib/cleanupWorktree.d.ts +6 -0
- package/dist/lib/cleanupWorktree.d.ts.map +1 -0
- package/dist/lib/cleanupWorktree.js +33 -0
- package/dist/lib/cleanupWorktree.js.map +1 -0
- package/dist/lib/copyRalphFilesFromWorktree.d.ts +5 -0
- package/dist/lib/copyRalphFilesFromWorktree.d.ts.map +1 -0
- package/dist/lib/copyRalphFilesFromWorktree.js +19 -0
- package/dist/lib/copyRalphFilesFromWorktree.js.map +1 -0
- package/dist/lib/copyRalphFilesToWorktree.d.ts +5 -0
- package/dist/lib/copyRalphFilesToWorktree.d.ts.map +1 -0
- package/dist/lib/copyRalphFilesToWorktree.js +21 -0
- package/dist/lib/copyRalphFilesToWorktree.js.map +1 -0
- package/dist/lib/createWorktree.d.ts +6 -0
- package/dist/lib/createWorktree.d.ts.map +1 -0
- package/dist/lib/createWorktree.js +34 -0
- package/dist/lib/createWorktree.js.map +1 -0
- package/dist/lib/getClaudeVersion.d.ts +2 -0
- package/dist/lib/getClaudeVersion.d.ts.map +1 -0
- package/dist/lib/getClaudeVersion.js +17 -0
- package/dist/lib/getClaudeVersion.js.map +1 -0
- package/dist/lib/getClaudeVersion.test.d.ts +2 -0
- package/dist/lib/getClaudeVersion.test.d.ts.map +1 -0
- package/dist/lib/getClaudeVersion.test.js +39 -0
- package/dist/lib/getClaudeVersion.test.js.map +1 -0
- package/dist/lib/getGitRoot.d.ts +5 -0
- package/dist/lib/getGitRoot.d.ts.map +1 -0
- package/dist/lib/getGitRoot.js +18 -0
- package/dist/lib/getGitRoot.js.map +1 -0
- package/dist/lib/installDependencies.d.ts +5 -0
- package/dist/lib/installDependencies.d.ts.map +1 -0
- package/dist/lib/installDependencies.js +23 -0
- package/dist/lib/installDependencies.js.map +1 -0
- package/dist/lib/installDependencies.test.d.ts +2 -0
- package/dist/lib/installDependencies.test.d.ts.map +1 -0
- package/dist/lib/installDependencies.test.js +37 -0
- package/dist/lib/installDependencies.test.js.map +1 -0
- package/dist/lib/mergeWorktreeToMain.d.ts +6 -0
- package/dist/lib/mergeWorktreeToMain.d.ts.map +1 -0
- package/dist/lib/mergeWorktreeToMain.js +44 -0
- package/dist/lib/mergeWorktreeToMain.js.map +1 -0
- package/dist/lib/popStash.d.ts +5 -0
- package/dist/lib/popStash.d.ts.map +1 -0
- package/dist/lib/popStash.js +17 -0
- package/dist/lib/popStash.js.map +1 -0
- package/dist/lib/rel.test.d.ts +2 -0
- package/dist/lib/rel.test.d.ts.map +1 -0
- package/dist/lib/rel.test.js +36 -0
- package/dist/lib/rel.test.js.map +1 -0
- package/dist/lib/replayLog.d.ts.map +1 -1
- package/dist/lib/replayLog.js +20 -6
- package/dist/lib/replayLog.js.map +1 -1
- package/dist/lib/runIteration.d.ts.map +1 -1
- package/dist/lib/runIteration.js +18 -8
- package/dist/lib/runIteration.js.map +1 -1
- package/dist/lib/shortenTempPaths.test.d.ts +2 -0
- package/dist/lib/shortenTempPaths.test.d.ts.map +1 -0
- package/dist/lib/shortenTempPaths.test.js +46 -0
- package/dist/lib/shortenTempPaths.test.js.map +1 -0
- package/dist/lib/signalHandler.d.ts +3 -0
- package/dist/lib/signalHandler.d.ts.map +1 -0
- package/dist/lib/signalHandler.js +19 -0
- package/dist/lib/signalHandler.js.map +1 -0
- package/dist/lib/stashChanges.d.ts +6 -0
- package/dist/lib/stashChanges.d.ts.map +1 -0
- package/dist/lib/stashChanges.js +27 -0
- package/dist/lib/stashChanges.js.map +1 -0
- package/dist/lib/types.d.ts +8 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +5 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/worktree.d.ts +43 -0
- package/dist/lib/worktree.d.ts.map +1 -0
- package/dist/lib/worktree.js +210 -0
- package/dist/lib/worktree.js.map +1 -0
- package/dist/ui/EventProcessor.d.ts +11 -0
- package/dist/ui/EventProcessor.d.ts.map +1 -0
- package/dist/ui/EventProcessor.js +95 -0
- package/dist/ui/EventProcessor.js.map +1 -0
- package/dist/ui/IterationApp.d.ts +10 -0
- package/dist/ui/IterationApp.d.ts.map +1 -0
- package/dist/ui/IterationApp.js +21 -0
- package/dist/ui/IterationApp.js.map +1 -0
- package/dist/ui/IterationUI.d.ts +13 -0
- package/dist/ui/IterationUI.d.ts.map +1 -0
- package/dist/ui/IterationUI.js +19 -0
- package/dist/ui/IterationUI.js.map +1 -0
- package/dist/ui/TextDisplay.d.ts +7 -0
- package/dist/ui/TextDisplay.d.ts.map +1 -0
- package/dist/ui/TextDisplay.js +41 -0
- package/dist/ui/TextDisplay.js.map +1 -0
- package/dist/ui/ToolUseDisplay.d.ts +10 -0
- package/dist/ui/ToolUseDisplay.d.ts.map +1 -0
- package/dist/ui/ToolUseDisplay.js +10 -0
- package/dist/ui/ToolUseDisplay.js.map +1 -0
- package/package.json +23 -4
- package/templates/progress.md +1 -1
- package/templates/prompt.md +11 -1
- package/templates/todo.md +0 -1
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "ink-testing-library";
|
|
3
|
+
import { describe, it, expect, vi } from "vitest";
|
|
4
|
+
import { readFileSync } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { EventDisplay } from "./EventDisplay.js";
|
|
7
|
+
/**
|
|
8
|
+
* Helper function to replay an event log file and return the rendered output
|
|
9
|
+
*/
|
|
10
|
+
async function replay(logFile) {
|
|
11
|
+
// Read the event log
|
|
12
|
+
const logPath = join(process.cwd(), "test/event-logs", logFile);
|
|
13
|
+
const logContent = readFileSync(logPath, "utf-8");
|
|
14
|
+
// Parse JSON events (multi-line JSON objects separated by blank lines)
|
|
15
|
+
const events = [];
|
|
16
|
+
const jsonObjects = logContent.split("\n\n");
|
|
17
|
+
for (const jsonStr of jsonObjects) {
|
|
18
|
+
if (!jsonStr.trim())
|
|
19
|
+
continue;
|
|
20
|
+
try {
|
|
21
|
+
const event = JSON.parse(jsonStr);
|
|
22
|
+
events.push(event);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// Skip invalid JSON
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Render with all events
|
|
29
|
+
const { lastFrame } = render(React.createElement(EventDisplay, { events: events }));
|
|
30
|
+
// Wait for rendering
|
|
31
|
+
await vi.waitFor(() => {
|
|
32
|
+
const output = lastFrame() ?? "";
|
|
33
|
+
expect(output.length).toBeGreaterThan(0);
|
|
34
|
+
}, { timeout: 1000 });
|
|
35
|
+
return lastFrame() ?? "";
|
|
36
|
+
}
|
|
37
|
+
describe("EventDisplay replay tests", () => {
|
|
38
|
+
it("replays 1.txt", async () => {
|
|
39
|
+
expect(await replay("1.txt")).toMatchInlineSnapshot(`
|
|
40
|
+
"I'll start by checking the types, unit tests, and end-to-end tests as instructed.
|
|
41
|
+
|
|
42
|
+
TodoWrite
|
|
43
|
+
[~] Run typecheck to verify types
|
|
44
|
+
[ ] Run unit tests via pnpm test
|
|
45
|
+
[ ] Run end-to-end tests via pnpm test:pw
|
|
46
|
+
|
|
47
|
+
$ pnpm typecheck
|
|
48
|
+
|
|
49
|
+
Good! Types check successfully. Now let me run the unit tests.
|
|
50
|
+
|
|
51
|
+
TodoWrite
|
|
52
|
+
[x] Run typecheck to verify types
|
|
53
|
+
[~] Run unit tests via pnpm test
|
|
54
|
+
[ ] Run end-to-end tests via pnpm test:pw
|
|
55
|
+
|
|
56
|
+
$ pnpm test
|
|
57
|
+
|
|
58
|
+
Perfect! Unit tests pass. Now let me run the end-to-end tests.
|
|
59
|
+
|
|
60
|
+
TodoWrite
|
|
61
|
+
[x] Run typecheck to verify types
|
|
62
|
+
[x] Run unit tests via pnpm test
|
|
63
|
+
[~] Run end-to-end tests via pnpm test:pw
|
|
64
|
+
|
|
65
|
+
$ pnpm test:pw"
|
|
66
|
+
`);
|
|
67
|
+
});
|
|
68
|
+
it("replays 2.txt", async () => {
|
|
69
|
+
expect(await replay("2.txt")).toMatchInlineSnapshot(`
|
|
70
|
+
"I'll start by checking that the project builds successfully and running tests.
|
|
71
|
+
|
|
72
|
+
$ pnpm build
|
|
73
|
+
|
|
74
|
+
$ pnpm test
|
|
75
|
+
|
|
76
|
+
Good! The build is successful and all tests pass. Now let me check the todo list to find the
|
|
77
|
+
highest-priority task.
|
|
78
|
+
|
|
79
|
+
Read .ralph/todo.md
|
|
80
|
+
|
|
81
|
+
Looking at the todo list, I'll prioritize the "Inline code blocks are being put in separate
|
|
82
|
+
paragraphs" issue. This is a functional bug affecting the display quality, whereas the others are
|
|
83
|
+
enhancements. Let me investigate this issue first.
|
|
84
|
+
|
|
85
|
+
Read src/components/StreamingText.tsx
|
|
86
|
+
|
|
87
|
+
Let me check the tests to understand the expected behavior and see if there's a failing test case:
|
|
88
|
+
|
|
89
|
+
Read src/components/StreamingText.test.tsx
|
|
90
|
+
|
|
91
|
+
I need to understand where StreamingText is being used and what the actual problem is. Let me check
|
|
92
|
+
where it's called from and look at some example output:
|
|
93
|
+
|
|
94
|
+
Grep StreamingText
|
|
95
|
+
|
|
96
|
+
Read src/components/EventDisplay.tsx
|
|
97
|
+
|
|
98
|
+
I see the issue now! In EventDisplay.tsx:70, there's a <Box flexDirection="column" gap={1}> which
|
|
99
|
+
wraps each StreamingText component. Each StreamingText (which represents text blocks) is being
|
|
100
|
+
placed in its own box with a gap, causing inline code to appear in separate paragraphs.
|
|
101
|
+
|
|
102
|
+
The problem is that each text block from Claude's message content is being rendered as a separate
|
|
103
|
+
StreamingText component with gaps between them. This works fine for separate paragraphs, but inline
|
|
104
|
+
code within a sentence gets split incorrectly.
|
|
105
|
+
|
|
106
|
+
Let me look at how the events are being split into blocks:
|
|
107
|
+
|
|
108
|
+
Read src/components/eventToBlocks.ts
|
|
109
|
+
|
|
110
|
+
Now I understand the issue. Claude's message content can have multiple text blocks (e.g., "Here's
|
|
111
|
+
the code: ", then a tool_use block, then " and that's it"). Each text block becomes a separate
|
|
112
|
+
ContentBlock with type "text", and EventDisplay renders each one as a separate <StreamingText>
|
|
113
|
+
component in a Box with gap={1}, causing unwanted spacing.
|
|
114
|
+
|
|
115
|
+
The fix should be to merge consecutive text blocks together. Let me write a test first to
|
|
116
|
+
demonstrate the problem:
|
|
117
|
+
|
|
118
|
+
Read src/components/EventDisplay.test.tsx
|
|
119
|
+
|
|
120
|
+
Now let me add a test that demonstrates the inline code block problem and then fix it:
|
|
121
|
+
|
|
122
|
+
Edit src/components/EventDisplay.test.tsx
|
|
123
|
+
|
|
124
|
+
Now let me run the test to confirm it fails (demonstrating the problem):
|
|
125
|
+
|
|
126
|
+
$ pnpm test EventDisplay.test.tsx
|
|
127
|
+
|
|
128
|
+
Perfect! The test fails as expected, confirming the bug. Now I need to fix it by modifying
|
|
129
|
+
eventToBlocks to merge consecutive text blocks:
|
|
130
|
+
|
|
131
|
+
Edit src/components/eventToBlocks.ts
|
|
132
|
+
|
|
133
|
+
Now I need to also flush the text buffer at the end of the loop:
|
|
134
|
+
|
|
135
|
+
Edit src/components/eventToBlocks.ts
|
|
136
|
+
|
|
137
|
+
Now let me run the tests again to verify the fix works:
|
|
138
|
+
|
|
139
|
+
$ pnpm test EventDisplay.test.tsx
|
|
140
|
+
|
|
141
|
+
The test still fails. This suggests the problem might also be in EventDisplay, not just
|
|
142
|
+
eventToBlocks. Let me debug by adding a simpler test to see what's happening in eventToBlocks:
|
|
143
|
+
|
|
144
|
+
Read src/components/eventToBlocks.test.ts
|
|
145
|
+
|
|
146
|
+
I see! The existing test "extracts multiple text blocks" expects them NOT to be merged. I need to
|
|
147
|
+
update this test and add a new one specifically for consecutive text blocks:
|
|
148
|
+
|
|
149
|
+
Edit src/components/eventToBlocks.test.ts
|
|
150
|
+
|
|
151
|
+
Now let me add a test for text blocks separated by tool calls:
|
|
152
|
+
|
|
153
|
+
Read src/components/eventToBlocks.test.ts
|
|
154
|
+
|
|
155
|
+
Let me add a test that specifically checks text blocks separated by tool calls:
|
|
156
|
+
|
|
157
|
+
Edit src/components/eventToBlocks.test.ts
|
|
158
|
+
|
|
159
|
+
Now let me run all tests to verify my changes to eventToBlocks work:
|
|
160
|
+
|
|
161
|
+
$ pnpm test eventToBlocks.test.ts
|
|
162
|
+
|
|
163
|
+
I need to look at this failing test:
|
|
164
|
+
|
|
165
|
+
Read src/components/eventToBlocks.test.ts
|
|
166
|
+
|
|
167
|
+
This test expects 3 separate IDs for 3 text blocks, but my code now merges them into 1. I need to
|
|
168
|
+
update this test to reflect the new behavior:
|
|
169
|
+
|
|
170
|
+
Edit src/components/eventToBlocks.test.ts
|
|
171
|
+
|
|
172
|
+
Now let me run the eventToBlocks tests again:
|
|
173
|
+
|
|
174
|
+
$ pnpm test eventToBlocks.test.ts
|
|
175
|
+
|
|
176
|
+
Great! Now let me run the EventDisplay test again:
|
|
177
|
+
|
|
178
|
+
$ pnpm test EventDisplay.test.tsx
|
|
179
|
+
|
|
180
|
+
The problem is still happening at the EventDisplay level. Let me check what's actually being
|
|
181
|
+
rendered. The issue must be in how EventDisplay merges the events. Let me look more carefully at the
|
|
182
|
+
EventDisplay logic:
|
|
183
|
+
|
|
184
|
+
Read src/components/EventDisplay.tsx
|
|
185
|
+
|
|
186
|
+
I see! The EventDisplay is doing its own deduplication, but it's NOT merging consecutive text
|
|
187
|
+
blocks. The text blocks in the test data remain separate even after eventToBlocks merges them,
|
|
188
|
+
because my test is creating a single event with 3 separate text blocks in content.
|
|
189
|
+
|
|
190
|
+
Wait, let me re-check the flow. EventDisplay calls eventToBlocks on each merged event. So if
|
|
191
|
+
eventToBlocks correctly merges text blocks, then EventDisplay should get a single merged text block.
|
|
192
|
+
Let me debug by adding a console log or looking at what's actually happening.
|
|
193
|
+
|
|
194
|
+
Let me write a simpler test to see what's going on:
|
|
195
|
+
|
|
196
|
+
$ cat > test-merge.ts << 'EOF'
|
|
197
|
+
import { eventToBlocks } from "./src/components/eventToBlocks.js"
|
|
198
|
+
|
|
199
|
+
const event = {
|
|
200
|
+
type: "assistant",
|
|
201
|
+
message: {
|
|
202
|
+
id: "msg_123",
|
|
203
|
+
content: [
|
|
204
|
+
{ type: "text", text: "Use the " },
|
|
205
|
+
{ type: "text", text: "\`console.log()\`" },
|
|
206
|
+
{ type: "text", text: " function to debug." },
|
|
207
|
+
],
|
|
208
|
+
},
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const result = eventToBlocks(event)
|
|
212
|
+
console.log("Result:", JSON.stringify(result, null, 2))
|
|
213
|
+
EOF
|
|
214
|
+
tsx test-merge.ts
|
|
215
|
+
|
|
216
|
+
Let me check if my fix is actually working by looking at the eventToBlocks implementation more
|
|
217
|
+
carefully. Actually, let me just trace through what should happen:
|
|
218
|
+
|
|
219
|
+
1. eventToBlocks receives an event with 3 text blocks
|
|
220
|
+
2. It loops through content
|
|
221
|
+
3. First text block: adds "Use the " to textBuffer
|
|
222
|
+
4. Second text block: adds "console.log()" to textBuffer (now "Use the console.log()")
|
|
223
|
+
5. Third text block: adds " function to debug." to textBuffer (now "Use the console.log() function
|
|
224
|
+
to debug.")
|
|
225
|
+
6. After the loop, it flushes the textBuffer as one merged text block
|
|
226
|
+
|
|
227
|
+
That should work! Let me check if there's an issue with my implementation. Let me re-read the code:
|
|
228
|
+
|
|
229
|
+
Read src/components/eventToBlocks.ts
|
|
230
|
+
|
|
231
|
+
The code looks correct. Let me check if the EventDisplay is receiving the correct merged content. I
|
|
232
|
+
think the issue might be in how EventDisplay deduplicates and merges content before calling
|
|
233
|
+
eventToBlocks. Let me look at that logic again:
|
|
234
|
+
|
|
235
|
+
Read src/components/EventDisplay.tsx
|
|
236
|
+
|
|
237
|
+
Ah! I see the problem now. In the test, we're providing a single event with one message containing 3
|
|
238
|
+
text blocks. EventDisplay keeps the text blocks separate in uniqueContent (lines 36-54), so they
|
|
239
|
+
stay as 3 separate blocks before being passed to eventToBlocks. Then eventToBlocks merges them. But
|
|
240
|
+
there's still the Box with gap={1} that creates spacing.
|
|
241
|
+
|
|
242
|
+
Wait, actually looking at the logic again - eventToBlocks should merge them, and return a single
|
|
243
|
+
ContentBlock. Then that single block gets rendered as a single <StreamingText> component. So there
|
|
244
|
+
should be no gaps.
|
|
245
|
+
|
|
246
|
+
Let me add some logging to see what's actually happening. But actually, I think the problem is that
|
|
247
|
+
the test is checking for newlines in the output. Ink's Box with flexDirection="column" adds newlines
|
|
248
|
+
between elements. So even if I have 1 StreamingText, the Box might still add newlines around it.
|
|
249
|
+
|
|
250
|
+
Actually wait - if eventToBlocks returns 1 block, then there's only 1 child in the Box, so there
|
|
251
|
+
should be no gaps. Let me trace through more carefully what the test is doing:
|
|
252
|
+
|
|
253
|
+
In the test, we render <EventDisplay events={[...]} />. The EventDisplay:
|
|
254
|
+
1. Filters to assistant messages
|
|
255
|
+
2. Merges by message ID (only 1 message)
|
|
256
|
+
3. Deduplicates (all 3 text blocks are unique)
|
|
257
|
+
4. Calls eventToBlocks on the merged event
|
|
258
|
+
5. eventToBlocks should merge the 3 text blocks into 1
|
|
259
|
+
6. Renders the blocks
|
|
260
|
+
|
|
261
|
+
Let me print what lastFrame() actually returns by modifying the test temporarily:
|
|
262
|
+
|
|
263
|
+
Edit src/components/EventDisplay.test.tsx
|
|
264
|
+
|
|
265
|
+
$ pnpm test EventDisplay.test.tsx 2>&1 | grep -A 20 "merges consecutive"
|
|
266
|
+
|
|
267
|
+
Aha! The output is "Use the\\n\\nconsole.log()\\n\\n function to debug." - there are TWO newlines
|
|
268
|
+
between each part! This tells me that the 3 text blocks are NOT being merged by eventToBlocks.
|
|
269
|
+
They're still coming through as 3 separate parts.
|
|
270
|
+
|
|
271
|
+
This means the EventDisplay deduplication logic is keeping them separate, OR there's a bug in my
|
|
272
|
+
eventToBlocks implementation. Let me add logging to eventToBlocks to see:
|
|
273
|
+
|
|
274
|
+
Edit src/components/eventToBlocks.ts
|
|
275
|
+
|
|
276
|
+
$ pnpm test EventDisplay.test.tsx 2>&1 | grep -A 30 "eventToBlocks content"
|
|
277
|
+
|
|
278
|
+
Perfect! So eventToBlocks IS receiving the 3 separate text blocks:
|
|
279
|
+
json
|
|
280
|
+
[
|
|
281
|
+
{ "type": "text", "text": "Use the " },
|
|
282
|
+
{ "type": "text", "text": "console.log()" },
|
|
283
|
+
{ "type": "text", "text": " function to debug." }
|
|
284
|
+
]
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
But the output still shows them on 3 separate lines. This means my merging logic isn't working. Let
|
|
288
|
+
me add more logging to see what's happening in the loop:
|
|
289
|
+
|
|
290
|
+
Edit src/components/eventToBlocks.ts
|
|
291
|
+
|
|
292
|
+
Edit src/components/eventToBlocks.ts
|
|
293
|
+
|
|
294
|
+
$ pnpm test EventDisplay.test.tsx 2>&1 | grep -A 50 "merges consecutive text blocks to prevent
|
|
295
|
+
unwanted gaps"
|
|
296
|
+
|
|
297
|
+
EXCELLENT! The merging IS working correctly:
|
|
298
|
+
- eventToBlocks returns: [{ "type": "text", "content": "Use the console.log() function to debug.",
|
|
299
|
+
"id": "msg_123-0" }]
|
|
300
|
+
|
|
301
|
+
But the output is still: "Use the\\n\\nconsole.log()\\n\\n function to debug."
|
|
302
|
+
|
|
303
|
+
This means the problem is in how StreamingText is rendering! The backticks in the merged text are
|
|
304
|
+
being split up by StreamingText's markdown processing. Let me check the StreamingText component
|
|
305
|
+
logic again - it must be detecting the backticks and rendering them as separate Text components, and
|
|
306
|
+
those are getting newlines between them!
|
|
307
|
+
|
|
308
|
+
Oh wait, I see it now! Look at EventDisplay:69-76:
|
|
309
|
+
|
|
310
|
+
tsx
|
|
311
|
+
<Box flexDirection="column" gap={1}>
|
|
312
|
+
{contentBlocks.map(block =>
|
|
313
|
+
block.type === "text" ?
|
|
314
|
+
<StreamingText key={block.id} content={block.content} />
|
|
315
|
+
: <ToolUse key={block.id} name={block.name} arg={block.arg} />,
|
|
316
|
+
)}
|
|
317
|
+
</Box>
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
The Box has gap={1}, which adds gaps between CHILDREN. StreamingText renders multiple <Text>
|
|
321
|
+
components (one for each formatted segment), and those become CHILDREN of the parent, not siblings.
|
|
322
|
+
Wait, no - StreamingText returns a fragment <>...</> containing multiple Text components.
|
|
323
|
+
|
|
324
|
+
Actually, I think the issue is that Ink is rendering the separate Text components with gaps. Let me
|
|
325
|
+
check StreamingText more carefully - it returns a fragment with separate Text components. Those Text
|
|
326
|
+
components might be getting wrapped or treated differently by Ink.
|
|
327
|
+
|
|
328
|
+
Actually, I think the real fix is to render StreamingText as inline, not in a column layout. But
|
|
329
|
+
wait, the Box flexDirection="column" affects the layout of contentBlocks (Text vs ToolUse), not the
|
|
330
|
+
internal layout of StreamingText.
|
|
331
|
+
|
|
332
|
+
Let me check if the problem is in how StreamingText uses fragments. When you return a fragment with
|
|
333
|
+
multiple <Text> components in Ink, they might be rendered on separate lines. Let me check:
|
|
334
|
+
|
|
335
|
+
Read src/components/StreamingText.tsx
|
|
336
|
+
|
|
337
|
+
The issue is that StreamingText returns a fragment with multiple <Text> components. In Ink, these
|
|
338
|
+
might be rendered as separate blocks. The fix is to wrap them in a single <Text> component or use
|
|
339
|
+
the <Text wrap="wrap"> with inline rendering.
|
|
340
|
+
|
|
341
|
+
Let me look at how Ink handles multiple Text components. Actually, the fix is simple - wrap all the
|
|
342
|
+
text parts in a single Box or Text component with inline rendering:
|
|
343
|
+
|
|
344
|
+
Edit src/components/StreamingText.tsx
|
|
345
|
+
|
|
346
|
+
Edit src/components/StreamingText.tsx
|
|
347
|
+
|
|
348
|
+
Now let me remove the console.log statements and test:
|
|
349
|
+
|
|
350
|
+
Edit src/components/eventToBlocks.ts
|
|
351
|
+
|
|
352
|
+
Edit src/components/eventToBlocks.ts
|
|
353
|
+
|
|
354
|
+
Edit src/components/EventDisplay.test.tsx
|
|
355
|
+
|
|
356
|
+
Now let me run all tests:
|
|
357
|
+
|
|
358
|
+
$ pnpm test
|
|
359
|
+
|
|
360
|
+
Perfect! All tests pass now. Let me verify the build still works:
|
|
361
|
+
|
|
362
|
+
$ pnpm build
|
|
363
|
+
|
|
364
|
+
Excellent! Now let me update the todo list and progress file, then commit:
|
|
365
|
+
|
|
366
|
+
Read .ralph/todo.md
|
|
367
|
+
|
|
368
|
+
Edit .ralph/todo.md
|
|
369
|
+
|
|
370
|
+
Read .ralph/progress.md
|
|
371
|
+
|
|
372
|
+
Edit .ralph/progress.md
|
|
373
|
+
|
|
374
|
+
Now let me format the code with Prettier:
|
|
375
|
+
|
|
376
|
+
$ pnpm format
|
|
377
|
+
|
|
378
|
+
Good! Now let me commit all these changes:
|
|
379
|
+
|
|
380
|
+
$ git add -A && git diff --cached --stat
|
|
381
|
+
|
|
382
|
+
$ git commit -m "$(cat <<'EOF'
|
|
383
|
+
Fix inline code blocks appearing in separate paragraphs
|
|
384
|
+
|
|
385
|
+
- Modified eventToBlocks.ts to merge consecutive text blocks using a textBuffer
|
|
386
|
+
- Wrapped StreamingText content in Box component for proper inline rendering
|
|
387
|
+
- Added test case to verify consecutive text blocks are merged
|
|
388
|
+
- Updated existing tests to reflect new merging behavior
|
|
389
|
+
|
|
390
|
+
Fixes issue where inline code like \`console.log()\` was rendered on separate
|
|
391
|
+
lines with gaps instead of flowing inline with surrounding text.
|
|
392
|
+
|
|
393
|
+
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
394
|
+
EOF
|
|
395
|
+
)"
|
|
396
|
+
|
|
397
|
+
Perfect! Let me verify git status:
|
|
398
|
+
|
|
399
|
+
$ git status"
|
|
400
|
+
`);
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
//# sourceMappingURL=EventDisplay.replay.test.js.map
|
|
@@ -0,0 +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,CAAC,oBAAC,YAAY,IAAC,MAAM,EAAE,MAAM,GAAI,CAAC,CAAA;IAE9D,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;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BnD,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2UnD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventDisplay.test.d.ts","sourceRoot":"","sources":["../../src/components/EventDisplay.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "ink-testing-library";
|
|
3
|
+
import { describe, it, expect, vi } from "vitest";
|
|
4
|
+
import { EventDisplay } from "./EventDisplay.js";
|
|
5
|
+
describe("EventDisplay", () => {
|
|
6
|
+
it("filters out stream_event types and only shows assistant messages", async () => {
|
|
7
|
+
const events = [
|
|
8
|
+
{
|
|
9
|
+
type: "stream_event",
|
|
10
|
+
event: {
|
|
11
|
+
type: "content_block_delta",
|
|
12
|
+
delta: { type: "text_delta", text: "Streaming..." },
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
type: "assistant",
|
|
17
|
+
message: {
|
|
18
|
+
id: "msg_123",
|
|
19
|
+
content: [{ type: "text", text: "Complete message" }],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
const { lastFrame } = render(React.createElement(EventDisplay, { events: events }));
|
|
24
|
+
await vi.waitFor(() => {
|
|
25
|
+
const output = lastFrame() ?? "";
|
|
26
|
+
expect(output).toContain("Complete message");
|
|
27
|
+
// Should not show streaming events
|
|
28
|
+
expect(output).not.toContain("Streaming...");
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
it("deduplicates events with the same message ID", async () => {
|
|
32
|
+
const events = [
|
|
33
|
+
{
|
|
34
|
+
type: "assistant",
|
|
35
|
+
message: {
|
|
36
|
+
id: "msg_123",
|
|
37
|
+
content: [{ type: "text", text: "First version" }],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: "assistant",
|
|
42
|
+
message: {
|
|
43
|
+
id: "msg_123",
|
|
44
|
+
content: [
|
|
45
|
+
{ type: "text", text: "First version" },
|
|
46
|
+
{ type: "text", text: "Updated version" },
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
const { lastFrame } = render(React.createElement(EventDisplay, { events: events }));
|
|
52
|
+
// Wait for useEffect to complete
|
|
53
|
+
await vi.waitFor(() => {
|
|
54
|
+
const output = lastFrame() ?? "";
|
|
55
|
+
expect(output).toContain("Updated version");
|
|
56
|
+
});
|
|
57
|
+
const output = lastFrame() ?? "";
|
|
58
|
+
// Should not duplicate the first text
|
|
59
|
+
expect(output.match(/First version/g)?.length).toBe(1);
|
|
60
|
+
});
|
|
61
|
+
it("handles multiple different messages", async () => {
|
|
62
|
+
const events = [
|
|
63
|
+
{
|
|
64
|
+
type: "assistant",
|
|
65
|
+
message: {
|
|
66
|
+
id: "msg_123",
|
|
67
|
+
content: [{ type: "text", text: "Message 1" }],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: "assistant",
|
|
72
|
+
message: {
|
|
73
|
+
id: "msg_456",
|
|
74
|
+
content: [{ type: "text", text: "Message 2" }],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
const { lastFrame } = render(React.createElement(EventDisplay, { events: events }));
|
|
79
|
+
await vi.waitFor(() => {
|
|
80
|
+
const output = lastFrame() ?? "";
|
|
81
|
+
expect(output).toContain("Message 1");
|
|
82
|
+
expect(output).toContain("Message 2");
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
it("handles tool use events", async () => {
|
|
86
|
+
const events = [
|
|
87
|
+
{
|
|
88
|
+
type: "assistant",
|
|
89
|
+
message: {
|
|
90
|
+
id: "msg_123",
|
|
91
|
+
content: [
|
|
92
|
+
{
|
|
93
|
+
type: "tool_use",
|
|
94
|
+
name: "Read",
|
|
95
|
+
input: { file_path: "/absolute/path/file.ts" },
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
const { lastFrame } = render(React.createElement(EventDisplay, { events: events }));
|
|
102
|
+
await vi.waitFor(() => {
|
|
103
|
+
const output = lastFrame() ?? "";
|
|
104
|
+
expect(output).toContain("Read");
|
|
105
|
+
expect(output).toContain("file.ts");
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
it("updates display when new events arrive", async () => {
|
|
109
|
+
const events1 = [
|
|
110
|
+
{
|
|
111
|
+
type: "assistant",
|
|
112
|
+
message: {
|
|
113
|
+
id: "msg_123",
|
|
114
|
+
content: [{ type: "text", text: "Initial" }],
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
const { lastFrame, rerender } = render(React.createElement(EventDisplay, { events: events1 }));
|
|
119
|
+
await vi.waitFor(() => {
|
|
120
|
+
expect(lastFrame()).toContain("Initial");
|
|
121
|
+
});
|
|
122
|
+
const events2 = [
|
|
123
|
+
...events1,
|
|
124
|
+
{
|
|
125
|
+
type: "assistant",
|
|
126
|
+
message: {
|
|
127
|
+
id: "msg_456",
|
|
128
|
+
content: [{ type: "text", text: "New message" }],
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
rerender(React.createElement(EventDisplay, { events: events2 }));
|
|
133
|
+
await vi.waitFor(() => {
|
|
134
|
+
const output = lastFrame() ?? "";
|
|
135
|
+
expect(output).toContain("Initial");
|
|
136
|
+
expect(output).toContain("New message");
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
it("handles partial message updates without duplicating keys", async () => {
|
|
140
|
+
// Simulate streaming where the same message gets updated multiple times
|
|
141
|
+
const events = [
|
|
142
|
+
{
|
|
143
|
+
type: "assistant",
|
|
144
|
+
message: {
|
|
145
|
+
id: "msg_123",
|
|
146
|
+
content: [{ type: "text", text: "Thinking..." }],
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: "assistant",
|
|
151
|
+
message: {
|
|
152
|
+
id: "msg_123",
|
|
153
|
+
content: [
|
|
154
|
+
{ type: "text", text: "Thinking..." },
|
|
155
|
+
{
|
|
156
|
+
type: "tool_use",
|
|
157
|
+
id: "toolu_read1",
|
|
158
|
+
name: "Read",
|
|
159
|
+
input: { file_path: "/path/file.ts" },
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: "assistant",
|
|
166
|
+
message: {
|
|
167
|
+
id: "msg_123",
|
|
168
|
+
content: [
|
|
169
|
+
{ type: "text", text: "Thinking..." },
|
|
170
|
+
{
|
|
171
|
+
type: "tool_use",
|
|
172
|
+
id: "toolu_read1",
|
|
173
|
+
name: "Read",
|
|
174
|
+
input: { file_path: "/path/file.ts" },
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
type: "tool_use",
|
|
178
|
+
id: "toolu_edit1",
|
|
179
|
+
name: "Edit",
|
|
180
|
+
input: { file_path: "/path/file.ts" },
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
];
|
|
186
|
+
const { lastFrame } = render(React.createElement(EventDisplay, { events: events }));
|
|
187
|
+
await vi.waitFor(() => {
|
|
188
|
+
const output = lastFrame() ?? "";
|
|
189
|
+
// Should only see one instance of each tool
|
|
190
|
+
expect(output.match(/Read/g)?.length).toBe(1);
|
|
191
|
+
expect(output.match(/Edit/g)?.length).toBe(1);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
it("merges consecutive text blocks to prevent unwanted gaps", async () => {
|
|
195
|
+
// When Claude outputs text in multiple blocks (e.g., before and after inline code),
|
|
196
|
+
// we should merge them into one StreamingText component to avoid gaps
|
|
197
|
+
const events = [
|
|
198
|
+
{
|
|
199
|
+
type: "assistant",
|
|
200
|
+
message: {
|
|
201
|
+
id: "msg_123",
|
|
202
|
+
content: [
|
|
203
|
+
{ type: "text", text: "Use the " },
|
|
204
|
+
{ type: "text", text: "`console.log()`" },
|
|
205
|
+
{ type: "text", text: " function to debug." },
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
];
|
|
210
|
+
const { lastFrame } = render(React.createElement(EventDisplay, { events: events }));
|
|
211
|
+
await vi.waitFor(() => {
|
|
212
|
+
const output = lastFrame() ?? "";
|
|
213
|
+
expect(output).toContain("Use the");
|
|
214
|
+
expect(output).toContain("console.log()");
|
|
215
|
+
expect(output).toContain("function to debug");
|
|
216
|
+
});
|
|
217
|
+
// The output should be on one line without extra spacing
|
|
218
|
+
const output = lastFrame() ?? "";
|
|
219
|
+
const lines = output.split("\n").filter(l => l.trim());
|
|
220
|
+
expect(lines.length).toBe(1);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
//# sourceMappingURL=EventDisplay.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventDisplay.test.js","sourceRoot":"","sources":["../../src/components/EventDisplay.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../src/components/Header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,eAAO,MAAM,MAAM,GAAI,iCAAiC,KAAK,sBAiB5D,CAAA;AAED,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA"}
|