Commit Graph

25 Commits

Author SHA1 Message Date
3492b2b1c5 Add passthrough-mode tests; stop wiping screen on exit
proxy.rs: expose set_passthrough_mode/vt_render_pending test hooks, and
on Drop only reset attribute state (fg/bg/hyperlink) instead of also
clearing the viewport — so the child's final output stays on screen like
a normal CLI once the palimpsest bug is fixed.

integration_tests.rs: tests asserting passthrough mode forwards child
PTY bytes verbatim (no termwiz re-encoding) and skips the deferred
render path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:38:11 +00:00
7e0accc032 fix: tmux passthrough + renderer state drift + exit cleanup
Investigating "weird redraw issues" surfaced by the wezterm-term swap
turned up four separate bugs in the proxy↔terminal byte path:

1. TerminfoRenderer caches CellAttributes across render_to calls.
   The trailing raw `\x1b[0m` and out-of-band CLEAR_SCREEN writes
   left its `current_attr` desynced from the real terminal — next
   frame's SGR transitions were computed against the wrong baseline,
   manifesting as bg-color smears and sticky links. Route the reset
   through `Change::AllAttributes(default)` so the renderer's pen
   stays in sync, and recreate the renderer whenever `force_full`
   fires (startup, lookback exit, alt exit, resize) so the cached
   state can't outlive an out-of-band write.

2. Proxy startup didn't clear the terminal, so the first VT diff
   landed on top of whatever the user's shell had on screen. Wipe
   on spawn alongside enabling bracketed paste.

3. `Drop` only disabled bracketed paste and restored termios, so an
   exit mid-render leaked active styles into the shell prompt and
   left Claude's last UI frame on screen. Add OSC-8 close → SGR 0 →
   CLEAR_SCREEN → CURSOR_HOME before the existing teardown.

4. Under tmux, steady-state diff renders produced a palimpsest of
   stacked frames because termwiz's `Surface::diff_lines` only walks
   the new frame's *visible* cells — cells that became blank don't
   generate clearing Changes. tmux is also tracking the grid and is
   sensitive to the partial repaint stream. Detect `$TMUX` at spawn
   and switch to passthrough: feed wezterm-term for state but
   forward raw child bytes to stdout. Lookback's one-shot full
   repaint still uses the renderer (screen is cleared first, so
   the diff_lines blank-cell behavior is fine).

Test infrastructure:
- New shared `test_support::pty_mock_binary()` honors CARGO_TARGET_DIR,
  tries debug/release, and panics with an actionable message instead
  of returning Option<String>. All 8 `let Some(...) else { return; }`
  silent-skip patterns replaced with direct destructure.
- Mirror is now advanced after `render_to` succeeds, not before.

New regression tests:
- `sgr_reemitted_on_second_frame_after_wire_reset`
- `hyperlink_reemitted_on_second_frame_after_wire_close`
- `forced_full_render_reemits_sgr_after_renderer_recreate`
- `test_lookback_exit_emits_clear_screen` asserts CLEAR/HOME precede
  the SYNC-wrapped repaint payload.

122 passing / 0 failing / 4 ignored (the two pre-existing
underline-style cases plus the claude-CLI-required integration).
2026-05-03 06:08:27 +00:00
8ca1e80603 feat: replace vt100 with wezterm-term for the screen emulator
Some checks failed
CI / Version Badge (pull_request) Has been cancelled
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / test-matrix (macos-latest) (pull_request) Has been cancelled
CI / test-matrix (ubuntu-latest) (pull_request) Has been cancelled
CI / Test (pull_request) Has been cancelled
CI / Integration Tests (macos-latest) (pull_request) Has been cancelled
CI / Integration Tests (ubuntu-latest) (pull_request) Has been cancelled
CI / Nix Build (macos-latest) (pull_request) Has been cancelled
CI / Nix Build (ubuntu-latest) (pull_request) Has been cancelled
Swap the rendering core. The previous backend (vt100 0.16) only stored
six attributes — fg/bg color, bold, dim, italic, underline, inverse —
and silently dropped everything else when re-emitting the screen. With
modern Claude Code that meant losing OSC 8 hyperlinks, strikethrough,
fancy underline styles, underline color, and so on.

New stack:
  * wezterm-term::Terminal handles the byte-driven VT emulation. Its
    cell model preserves the full modern attribute set including
    hyperlinks and underline color.
  * termwiz::surface::Surface is used as a "mirror of last emitted
    state." Each render diffs the terminal's current visible lines
    against this mirror to compute the minimum change set.
  * termwiz::render::TerminfoRenderer encodes those Changes as bytes
    using a TrueColor + hyperlink-capable capability profile.

A defensive OSC 8 close is appended to every render to handle the case
where the diff ends inside a hyperlinked region (the renderer only
emits the close on transition to a non-hyperlinked cell).

Both termwiz and wezterm-term are pulled from the wezterm git repo at
a pinned rev so the Line types unify across the dep graph.

Test results, against the color-preservation harness from the previous
commit (run via cargo test color_preservation -- --ignored on master):

  baseline (vt100):  0 / 5 passing
  after this commit: 3 / 5 passing  (osc8, strikethrough, double underline)

The two still-ignored tests (curly underline, underline color) are
upstream renderer limitations: termwiz's TerminfoRenderer only emits
Single/Double underline and never emits SGR 58. The cell model stores
both correctly; only the emit step drops them. Tests are kept #[ignore]
with comments calling out the upstream gap.

Total: 118 passed, 4 ignored, 0 failed.
2026-05-01 18:56:29 +00:00
1be6e4954e test: add failing color/SGR/hyperlink preservation tests
Pin the baseline: feed OSC 8 hyperlinks, strikethrough, curly underline,
underline color, and double underline through Proxy, force a render,
and capture what the proxy emits to its stdout side. Each test asserts
the styling survives the round-trip.

All five fail on the current vt100 0.16 backend because its cell model
only stores fg/bg color, bold, dim, italic, underline, inverse — every
other attribute is dropped at render time. Tests are #[ignore]-gated so
CI stays green; run with --ignored to see the baseline failures. Once
the emulator is swapped to termwiz, remove the gates.

A truecolor-foreground sanity test runs by default and confirms the
parts of the SGR space vt100 does support are still working.

Adds Proxy::force_render as a #[cfg(test)] wrapper around the private
render_vt_screen method.
2026-05-01 17:20:35 +00:00
3256167f48 test: add PTY integration test harness
Add a pty-mock workspace crate (echo/alt-screen/paste-echo/buffer-fill/
sync-blocks subcommands) plus an in-process integration test suite that
drives Proxy directly via a new_for_test constructor and #[cfg(test)]
state accessors. Sets up the regression net needed before swapping the
underlying VT emulator from vt100 to termwiz.

Pulled from upstream draft PR #35; the alt-screen feed-order semantic
change is intentionally deferred (its dedicated test is left #[ignore]).
2026-05-01 17:11:08 +00:00
TheKelvinPerez
66cc2ea0b8 Fix bracketed paste passthrough and PTY write deadlock (#34)
Some checks failed
CI / Version Badge (push) Has been cancelled
CI / Check (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / test-matrix (macos-latest) (push) Has been cancelled
CI / test-matrix (ubuntu-latest) (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Integration Tests (macos-latest) (push) Has been cancelled
CI / Integration Tests (ubuntu-latest) (push) Has been cancelled
CI / Nix Build (macos-latest) (push) Has been cancelled
CI / Nix Build (ubuntu-latest) (push) Has been cancelled
* fix: bracketed paste passthrough and pty write deadlock prevention

Enable bracketed paste on the real terminal at startup so tmux/Ghostty
wraps paste content in markers. Detect paste markers in process_input
and forward directly to the child pty, skipping byte-by-byte lookback
matching. Replace blocking write_all with write_to_pty_draining that
interleaves output reads to prevent the classic pty buffer deadlock
when forwarding large input.

* Fix clippy/fmt, buffer drained PTY output through VT parser, handle split paste end markers

- Fix clippy collapsible_if warning and cargo fmt issues
- Drained child output during PTY writes now buffers into pty_drain_buffer
  and is processed through process_output after process_input returns,
  keeping VT parser state, history, and alt-screen tracking in sync
- Add paste_remainder buffer to handle paste end markers split across
  read() boundaries, preventing permanent stuck-in-paste-mode state
- Add split_trailing_marker_prefix helper with tests

---------

Co-authored-by: Dave Beesley <david.beesley@pm.me>
2026-03-29 18:05:44 -06:00
Vova Ignatov
2595cf7f89 Add cargo install --git option to installation instructions (#31) 2026-02-07 15:17:16 -07:00
Cameron
896e431321 feat: add nix package (#29) 2026-02-06 19:10:55 -07:00
David Beesley
b821abdd2a Fix Ghostty terminal support (#26) 2026-01-25 23:46:22 -07:00
David Beesley
e2b20dce1c Fix: Filter Kitty keyboard and other terminal queries from history (#23) 2026-01-24 20:57:49 -07:00
David Beesley
420da759a7 Readme update: ctrl shift 6 on Mac 2026-01-22 20:36:41 -07:00
David Beesley
cfaa5a1afe Fix/kitty keyboard (#21)
* Add dynamic Kitty protocol tracking, unit tests, and version badge with CI check
2026-01-22 18:13:29 -07:00
David Beesley
0903d8c205 Fix auto-lookback trigger and add version tracking (#20)
* Fix auto-lookback trigger and add version tracking

- Trigger on stdin inactivity instead of render time
- Only dump when new output exists since last dump
- Default timeout 5s -> 15s
- Embed git hash in version output
- Document macOS config path
2026-01-22 15:58:47 -07:00
David Beesley
35ecc80e2f Fix: Remove terminal queries from history to prevent terminal responses on stdin (#10) 2026-01-20 12:54:43 +13:00
David Beesley
68c04b5d2c docs: update README for auto-lookback feature and add -a short flag (#8) 2026-01-20 05:46:33 +13:00
David Beesley
e0c04ae8dd feat: add auto lookback mode (#7)
* feat: add auto lookback mode

Automatically shows full terminal history after idle timeout,
returns to truncated view when new output arrives.

- Add auto_lookback_timeout_ms config option (default: 1000ms)
- Add --auto-lookback-timeout CLI flag
- Set to 0 to disable the feature

* intermediate

* auto lookback

---------

Co-authored-by: Ilya Sinkin <ilyasinkin2002@yandex.kz>
2026-01-19 18:33:24 +13:00
David Beesley
a824eaea77 Feature/vt (#6)
VT emulation instead of clipping sync blocks.
2026-01-19 17:40:09 +13:00
David Beesley
c7ab4aa06b Fix/exit display (#4)
* fix exit output
2026-01-18 10:41:57 +13:00
David Beesley
b800ec12b9 mac (#3)
* mac

* Add cross-platform integration tests

* Fix ioctl request type for macOS

* terminal-guard

* suppress bash deprecation warning

* test dumb mode

* workflow naming
2026-01-18 09:31:21 +13:00
David Beesley
91e0516fe9 Fix/key sequences (#2)
* Change default hotkey to Ctrl+6 and fix ctrl+punctuation handling
* Disable lookback mode when alternate screen is active
2026-01-18 06:17:14 +13:00
David Beesley
76b65add1d Add CI workflow (#1)
* Add CI workflow

* Fix formatting
2026-01-18 06:11:51 +13:00
Dave Beesley
e9f2b03684 commit 2026-01-16 23:14:05 -07:00
Dave Beesley
58f448e05e commit 2026-01-16 22:50:11 -07:00
Dave Beesley
961fc90313 Add CLI, config file support, and configurable lookback key
- Add clap-based CLI with comprehensive help
- Add TOML config support (~/.config/claude-chill.toml)
- Add key_parser for user-friendly key bindings ([ctrl][shift][j])
- Change default lookback key to Ctrl+Shift+J
- Remove unused modules (analyzer, output_processor, script_parser)
- Add MIT LICENSE file
- Add disclaimer to README

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 21:19:49 -07:00
Dave Beesley
9db120e05d commit 2026-01-16 20:19:52 -07:00