diff --git a/.pql/pql-plan.json b/.pql/pql-plan.json index 0a5760ca..097958f0 100644 --- a/.pql/pql-plan.json +++ b/.pql/pql-plan.json @@ -1,5 +1,5 @@ { - "exported_at": "2026-05-01T10:01:22Z", + "exported_at": "2026-05-01T10:08:01Z", "decisions": [ { "id": "D-1", diff --git a/lib/builtin/claude/src/claude_pane.dart b/lib/builtin/claude/src/claude_pane.dart index e92f5e02..0e74a766 100644 --- a/lib/builtin/claude/src/claude_pane.dart +++ b/lib/builtin/claude/src/claude_pane.dart @@ -186,11 +186,13 @@ class _ClaudePaneState extends State { final b64 = e.data['bytes_b64']; if (b64 is String) { _outputBuf.write(utf8.decode(base64Decode(b64), allowMalformed: true)); - // Throttle writes to ~60fps. Multiple PTY reads within a - // 16ms window are batched into one terminal.write() call, - // preventing split escape sequences from rendering as - // garbage between frames. - _flushTimer ??= Timer(const Duration(milliseconds: 16), _flushOutput); + // Batch all output from the current event loop turn into one + // terminal.write() call. scheduleMicrotask runs after all + // pending events but before the next frame, so split escape + // sequences within the same event batch are reunited. + if (_flushTimer == null) { + _flushTimer = Timer(Duration.zero, _flushOutput); + } } case 'pane.exit': if (widget.isPrimary) { diff --git a/lib/src/panes/registry.dart b/lib/src/panes/registry.dart index e031414e..7d1ea9c0 100644 --- a/lib/src/panes/registry.dart +++ b/lib/src/panes/registry.dart @@ -56,6 +56,7 @@ class PaneRegistry { 'COLORTERM': 'truecolor', 'LANG': 'en_US.UTF-8', 'LC_ALL': 'en_US.UTF-8', + 'TERMINFO': '/usr/share/terminfo', if (env != null) ...env, };