@dreb/coding-agent 2.34.1 → 2.34.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/docs/tui.md +7 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -42,6 +42,8 @@
|
|
|
42
42
|
|
|
43
43
|
### Fixed
|
|
44
44
|
|
|
45
|
+
- Fixed serial duplicate rows during streamed assistant/thinking markdown lists by normalizing TUI markdown render entries and rejecting raw line breaks before terminal row state can drift. ([#301](https://github.com/aebrer/dreb/issues/301))
|
|
46
|
+
|
|
45
47
|
- Fixed the TUI yanking the viewport to the top and wiping scrollback when a live-region-only change occurred while the user was scrolled up — at turn end (the working spinner disappearing) or on resize. A one-line live-region change was escalating to `recommitAll()`, which clears scrollback and repaints the whole session from the top, destroying the user's scroll position and native scrollback. The working indicator now lives on the always-present editor input line (constant live-region height, so turn boundaries no longer shrink the live region), live-region-only viewport shifts route through a new `restoreLiveViewport()` that bottom-anchors without replaying committed content, and `recommitAll()` re-establishes input modes via a RIS reset before any transcript bytes. A structural guard now makes it a loud error (with terminal teardown) for any live-only render path to reach `recommitAll()`, so the committed-replay class of bug cannot silently return. ([#292](https://github.com/aebrer/dreb/issues/292))
|
|
46
48
|
|
|
47
49
|
- Fixed ESC doing nothing during `stream_retry` / `length_retry` backoff. The old handlers stopped the working spinner (`loadingAnimation`) and swapped in a dedicated retry spinner that had no ESC wiring, so the default ESC handler's `if (this.loadingAnimation)` guard fell through to a no-op. The fix removes the retry spinner entirely, keeps the working spinner running throughout the retry, and surfaces retry feedback as a persistent warning in the chat scrollback instead. ESC now aborts via the pre-existing spinner-abort path — identical to cancelling normal generation. ([#262](https://github.com/aebrer/dreb/issues/262))
|
package/docs/tui.md
CHANGED
|
@@ -21,12 +21,12 @@ interface Component {
|
|
|
21
21
|
|
|
22
22
|
| Method | Description |
|
|
23
23
|
|--------|-------------|
|
|
24
|
-
| `render(width)` | Return array of strings
|
|
24
|
+
| `render(width)` | Return array of strings, one logical line per entry. Entries **must not contain raw `\n` or `\r`**; split multi-line content into separate entries. Each unmarked line **must not exceed `width`**. |
|
|
25
25
|
| `handleInput?(data)` | Receive keyboard input when component has focus. |
|
|
26
26
|
| `wantsKeyRelease?` | If true, component receives key release events (Kitty protocol). Default: false. |
|
|
27
27
|
| `invalidate()` | Clear cached render state. Called on theme changes. |
|
|
28
28
|
|
|
29
|
-
The TUI appends a full SGR reset and OSC 8 reset at the end of each rendered line. Styles do not carry across lines. If you emit multi-line text with styling, reapply styles per line or use `wrapTextWithAnsi()` so styles are preserved for each wrapped line.
|
|
29
|
+
The TUI appends a full SGR reset and OSC 8 reset at the end of each rendered line. Styles do not carry across lines. If you emit multi-line text with styling, split it into separate render entries and reapply styles per line, or use `wrapTextWithAnsi()` so styles are preserved for each wrapped line.
|
|
30
30
|
|
|
31
31
|
## Focusable Interface (IME Support)
|
|
32
32
|
|
|
@@ -287,21 +287,21 @@ handleInput(data: string) {
|
|
|
287
287
|
|
|
288
288
|
## Line Width
|
|
289
289
|
|
|
290
|
-
**Critical:** Each
|
|
290
|
+
**Critical:** Each entry from `render()` must represent one logical line and must not contain raw `\n` or `\r`. Split multi-line content before returning it. Unmarked lines must not exceed the `width` parameter.
|
|
291
291
|
|
|
292
292
|
```typescript
|
|
293
|
-
import { visibleWidth, truncateToWidth } from "@dreb/tui";
|
|
293
|
+
import { visibleWidth, truncateToWidth, wrapTextWithAnsi } from "@dreb/tui";
|
|
294
294
|
|
|
295
295
|
render(width: number): string[] {
|
|
296
|
-
//
|
|
297
|
-
return
|
|
296
|
+
// Split styled multi-line content into separate render entries.
|
|
297
|
+
return wrapTextWithAnsi(this.text.replace(/\r\n?/g, "\n"), width);
|
|
298
298
|
}
|
|
299
299
|
```
|
|
300
300
|
|
|
301
301
|
Utilities:
|
|
302
302
|
- `visibleWidth(str)` - Get display width (ignores ANSI codes)
|
|
303
303
|
- `truncateToWidth(str, width, ellipsis?)` - Truncate with optional ellipsis
|
|
304
|
-
- `wrapTextWithAnsi(str, width)` - Word wrap preserving ANSI codes
|
|
304
|
+
- `wrapTextWithAnsi(str, width)` - Word wrap preserving ANSI codes and splitting on raw line breaks
|
|
305
305
|
|
|
306
306
|
## Creating Custom Components
|
|
307
307
|
|