Commit Graph
176 Commits
Author SHA1 Message Date
Can Celik babb09bd53 fix: send pane appearance changes only after the matching background
refs #4183
2026-10-23 18:22:55 +03:00
Eric YueandCan Celik be0e73f724 fix: reject oversized canonical input on macos (#4988)
refs #4950

Co-authored-by: Can Celik <ogulcancelik@gmail.com>
2026-10-11 23:39:48 +03:00
JJ Liebig fe935882f0 perf: reuse unchanged windows shell detection text (#5091) 2026-10-08 21:55:17 +02:00
cce57bc32c perf: reuse unchanged shell detection text (#5085)
* perf: reuse unchanged shell detection text

refs #5083

* perf: reuse unchanged shell detection text

refs #5083

---------

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
2026-10-08 20:26:14 +02:00
JJ Liebig 4f296c295b fix: preserve windows shell working directories (#5062)
refs #4472
2026-10-08 00:01:30 +02:00
akbash 376bafc8ab fix: honor the kitty graphics opt-out (#4979) 2026-10-07 23:18:49 +03:00
Can Celik 1b23719b3e fix: tell fish that herdr reflows its prompt on resize (#4977)
* fix: tell fish that herdr reflows its prompt on resize

refs #3672

* fix: match fish_handle_reflow casing exactly on windows

refs #3672

* test: keep temp path out of fish env spawn test command

refs #3672
2026-10-07 22:37:33 +03:00
Can Celik a124eed73c refactor: route all pane key encoding through libghostty (#5017)
* test: add input transparency conformance harness

* test: cover split host replies in input conformance harness

* fix: let libghostty encode every key sent to panes

* refactor: read live keyboard modes only from libghostty

* fix: wait for split input sequences instead of typing their fragments

* refactor: drop unused keyboard protocol argument from pane key encoding

* test: fix windows-only keyboard mode tests after libghostty mode refactor

* test: measure windows key record transparency against the keyboard layout

* fix: forward windows punctuation and altgr chords that produce no character

* test: expect libghostty kitty encoding in the windows conpty probe and cover release, alternate, text and modifyOtherKeys passthrough

* ci: lint windows-only test code in the cross-platform windows check

* refactor: delete herdr's own key encoder

* test: expect xterm modifyOtherKeys 2 encoding for shifted letters in the windows gauntlet

* refactor: read windows input through one native console reader

* refactor: parse sgr mouse reports once and map pixel reports without rewriting them

* refactor: decode framed input once instead of re-framing it in the client

* fix: keep macos alt, non-us kitty keys, text releases and reply-tail recovery correct after the libghostty switch

* fix: stop waiting for host replies the terminal never sends

* fix: deliver shifted punctuation releases after shift is let go

* fix: never type super, hyper or meta chords into panes that cannot read them

refs #4356

* test: replay reporter captures for fixed split-read and key-release issues

refs #4856
refs #4025
refs #4184

* fix: forward f1, f2 and f4 from kitty keyboard hosts

refs #4403

* fix: send pixel mouse reports to unfocused panes and only when the host supports them

refs #4750

* fix: treat 0x08 as backspace when the terminal's erase key is ctrl+h

refs #3244

* test: fix macos lint and keep the pixel mouse server test unix-only

* fix: deliver legacy alt+escape on macos instead of dropping it

* fix: address review findings on super+enter, held key releases and the pixel mouse probe

* test: expect super+enter to stay out of plain windows panes

* test: wait for the host pixel mouse mode instead of reading the channel once

* fix: send ctrl+shift+letter to plain shells as its control byte

* fix: encode each key under one keyboard mode snapshot

* fix: keep ime text intact and stop inventing key releases for committed text

* fix: release held key reports on focus loss and never drop held-key leases

* fix: send ctrl chords on non-latin layouts as their physical key

* fix: match non-latin ctrl chord releases after ctrl is let go

* fix: drop super chords before the windows conpty fallback in plain panes
2026-10-07 04:53:29 +03:00
Can Celik 950d012cf0 fix: keep agent sessions while the agent is suspended or backgrounded (#4964)
* fix: keep agent sessions while the agent is suspended or backgrounded

refs #1647
refs #1033

* fix: drop a suspended agent's session when a new one of its kind takes over

refs #1647
2026-10-05 22:33:44 +03:00
Can Celik 5da0a01e1e fix: hidden pane memory and new pane spawn size (#4873)
* fix: stop hidden panes keeping a full-size screen copy from creation

* fix: start new panes at their laid-out size

refs #4419
2026-10-03 02:21:24 +03:00
JJ Liebig 5d78d05d7f perf: avoid unused terminal reads in client snapshots (#4847) 2026-10-02 15:48:15 +02:00
Can Celik 25aaa0b7e3 fix: keep offscreen kitty images loaded instead of resending them on scroll (#4686) 2026-09-27 21:05:25 +03:00
Can Celik 2552d101af feat: let agents report their own resume command (#4687)
* feat: let agents report their own resume command

* fix: keep reported resume commands tied to accepted sessions and current owners
2026-09-27 20:57:00 +03:00
Can Celik fff6c820aa refactor: extract libghostty-vt binding into ghostty-vt workspace crate (#4661)
* refactor: extract libghostty-vt binding into ghostty-vt workspace crate

* fix: build libghostty-vt into each build's out dir
2026-09-27 00:06:29 +03:00
Can CelikandJJ Liebig c411883ec6 feat!: replace the custom graphics api with optimized native kitty rendering (#4561)
* feat!: replace the custom graphics api with optimized native kitty rendering

* fix: enable safe kitty optimizations automatically

---------

Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
2026-09-24 20:59:48 +03:00
JJ Liebig 9c96f7ddb3 fix: avoid inferring codex idle from terminal output (#4563)
refs #4507
2026-09-24 02:23:42 +02:00
JJ Liebig 440a8bdd1e fix: keep synchronized pane frames atomic (#4508)
refs #2968
2026-09-23 02:19:59 +02:00
Can Celik 90b0e40ab3 fix: preserve hook agent status across live handoff (#4493) 2026-09-22 18:31:37 +03:00
Can Celik 8ac9542757 fix: clear inherited terminal and agent session identity (#4461)
refs #4104
2026-09-22 02:20:47 +03:00
Can Celik 3602c757e0 fix: refresh forwarded ssh agents after reconnect (#4443)
refs #1931
2026-09-21 15:22:46 +03:00
Can CelikandJJ Liebig 0ff0f27e22 fix: preserve session layouts across shutdown and restore failures (#4400)
* fix: preserve session layouts across shutdown and restore failures

refs #4320

* test: update subscription fixture for pane restore errors

---------

Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
2026-09-21 00:29:45 +03:00
Can Celik cc7c696cd0 feat: add configurable pane screen and scrollback clearing (#4383) 2026-09-19 14:47:18 +03:00
JJ Liebig 101ccc20d3 fix(windows): prefer pwsh for the default pane shell (#4297)
* fix(windows): prefer pwsh for the default pane shell

Windows panes launched Windows PowerShell 5.1 (powershell.exe) whenever [terminal] default_shell was unset, ignoring PowerShell 7 even when pwsh.exe resolved on PATH. Resolve the unset default against PATH and prefer pwsh.exe, falling back to the inbox powershell.exe. An explicit default_shell still wins.

* fix(windows): validate pwsh before using it as the default shell

portable-pty resolves the configured shell with Path::exists and passes that path to CreateProcessW, which does not fall through to later PATH entries. Selecting an invalid pwsh.exe would therefore break new panes instead of falling back. Only prefer a pwsh.exe that starts with the PE MZ magic, and return its path so the validated binary is the one launched.

* fix(windows): validate the full PE header before preferring pwsh

Checking only the DOS MZ signature still accepted truncated images, DLLs, and foreign-architecture binaries. Because portable-pty passes the resolved path straight to CreateProcessW without trying later PATH entries, validate the PE signature, the COFF header (machine, executable-image bit, not a DLL, section count), and the optional header before preferring pwsh.exe.

* fix(windows): accept native ARM64 pwsh and validate the section table

Herdr ships an x64 Windows build that also runs on Windows ARM64 under x64 emulation, so cfg!(target_arch) cannot tell whether a native ARM64 pwsh.exe is launchable. Accept every executable machine type Windows supports instead of rejecting ARM64 on the x86_64 build. Also bound-check the section table (40 bytes per declared section) after the optional header so a truncated table falls back instead of being selected.

* fix(windows): detect the native host machine for pwsh compatibility

Machine compatibility was derived from cfg!(target_arch), which reports the emulated x64 process on Windows ARM64, and then briefly accepted ARM64 on every host. Read the native machine with IsWow64Process2 in the platform layer instead: ARM64 Windows accepts ARM64/x64/x86 images, x64 accepts x64/x86, and x86 accepts only x86.
2026-09-17 17:45:07 +02:00
JJ Liebig 9db1eed391 fix(windows): normalize pane launch cwd casing (#4199) 2026-09-15 17:17:47 +02:00
Can Celik f8e59221cb feat: add ctrl-hover highlighting and fix wrapped links (#4074)
refs #1282
2026-09-13 23:05:30 +03:00
JJ Liebig ff32bd450e fix(windows): keep powershell cwd reporting in login mode (#4065)
Windows login-mode PowerShell panes are now launched directly, but the PowerShell prompt-based cwd integration was still gated to non-login mode, leaving those panes without repository-owned cwd reporting after Set-Location. Enable the existing integration for login-mode PowerShell and build the integration args on the shared direct-shell path.

Follow-up to #4060.
2026-09-13 18:41:15 +02:00
JJ Liebig 38bc172fe8 fix(windows): honor default_shell in login shell mode (#4060)
* fix(windows): honor default_shell in login shell mode

Login-mode panes used portable-pty's default-program builder, which resolves to %ComSpec% (cmd.exe) on Windows and ignores the SHELL env override, so [terminal].default_shell was silently ignored. Build the launch command from the configured shell instead and append the shell's own login flag for POSIX-style shells that support one.

refs #1445

* fix(windows): add csh and tcsh to login shell flags

refs #1445
2026-09-13 18:24:51 +02:00
JJ Liebig a5d5f6f654 fix: ignore nested OMP session reports (#3994)
refs #2593
2026-09-12 13:52:18 +02:00
JJ Liebig c7a7cc454a fix: lint all targets on windows (#3963)
Native Windows lint and check only clippy-checked the herdr binary, while macOS and Linux run clippy across all targets. Enable --all-targets on Windows and gate the Unix-only test helpers that this exposed so Windows check matches the Unix one.
2026-09-11 18:12:49 +02:00
Can Celik 6e7d415bcf fix: keep terminal snapshots consistent while scrolling (#3928)
refs #3900
2026-09-11 02:08:31 +03:00
Can Celik 425c861797 chore: upgrade libghostty and preserve terminal behavior (#3906) 2026-09-10 21:51:57 +03:00
Can CelikandJonathan Liebig e7d8220788 fix: preserve sessions after interrupted pane exits (#3418)
* fix: preserve sessions when pane shells are signaled

refs #3415

* fix: preserve shutdown checkpoints across platforms

refs #3415

---------

Co-authored-by: Jonathan Liebig <jonathan.liebig@gmail.com>
2026-09-07 15:14:46 +02:00
Can Celik 9e9bc8a144 feat: manage multiple ssh machines from one client (#3670) 2026-09-06 02:27:06 +03:00
JJ Liebig 7916be1656 fix: make Windows Codex prompt delay size-aware (#3552)
refs #3187
2026-09-05 02:38:14 +02:00
JJ Liebig ec745235a9 fix(windows): preserve LF paste order (#3582)
refs #3172
2026-09-03 19:03:47 +02:00
Can Celik 9a2a7af540 perf: compress idle terminal scrollback (#3556) 2026-09-03 14:24:33 +03:00
JJ Liebig 8633a398e6 fix: reliably submit delayed agent prompts (#3506) 2026-09-02 13:34:03 +02:00
Can Celik 207be3c771 refactor: render the shell in the client (#3487)
* feat: add opt-in client-rendered shell

* feat: add client-owned shell mouse controls

* feat: complete client-owned shell chrome

* feat: add client-owned shell settings and notifications

* feat: run client shell custom commands

* feat: render popup terminals in client shell

* feat: add client-owned scrollback and copy mode

* fix: preserve client worktree trust defaults

* feat: render startup diagnostics in client shell

* feat: render onboarding in client shell

* feat: render product announcements in client shell

* feat: render release notes in client shell

* feat: render mobile switcher in client shell

* feat: render kitty graphics in client shell

* fix: preserve client shell lifecycle coherence

* refactor: route client shell commands through endpoint connections

* refactor: make the client-rendered shell the default

* refactor: remove monolithic launch mode

* refactor: complete client-rendered shell cutover

* perf: retain client pane surface updates

* perf: scale retained pane surface updates

* perf: remove remote pane input latency

* test: make client shell checks platform-independent

* fix: prevent client timer starvation

* test: fix client shell platform gates

* test: accept retained surfaces in cross-area checks

* test: make client mode assertions platform-neutral

* fix: badge only outdated integrations
2026-09-01 15:48:22 +03:00
caner-akca 3a3792622e fix: report the foreground group leader's cwd, not a descendant's (#3386)
refs #3270
2026-08-30 03:02:22 +03:00
Alex 82e6a80eb3 fix: keep OSC evidence through first agent acquisition (#3326) 2026-08-28 22:18:53 +03:00
JJ Liebig c714e4c20e fix: clear Windows Terminal identity in panes (#3127) 2026-08-22 23:34:38 +03:00
Can Celik a5c69beabf fix(perf): eliminate redundant terminal wake work (#2962)
* fix(perf): eliminate redundant terminal wake work

* fix(perf): harden release benchmark gate

* test(perf): strengthen performance guardrails
2026-08-19 04:43:28 +03:00
JJ Liebig 19022d03c9 fix: sync powershell process working directory (#2879) 2026-08-17 23:29:47 +03:00
Can Celik d76657f2c7 fix: speed up alternate-screen history reads (#2426)
refs #2387
2026-08-14 05:18:30 +03:00
952729ee03 fix: preserve logical lines in scrollback editor (#2735)
refs #2733

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
Co-authored-by: Can Celik <ogulcancelik@gmail.com>
2026-08-13 03:46:52 +03:00
Can CelikandJonathan Liebig 06ca0baa12 fix(windows): reduce idle agent detection CPU (#2651)
* fix(windows): reduce idle agent detection CPU

refs #2642

* fix(windows): gate agent process discovery

refs #2642

---------

Co-authored-by: Jonathan Liebig <jonathan.liebig@gmail.com>
2026-08-11 18:08:51 +03:00
JJ LiebigandCan Celik 7ae4b056a0 fix: wait for agent prompt readiness (#2537)
* fix: wait for agent prompt readiness

refs #2410

* fix: return pane updates after tab bar command

refs #2410

---------

Co-authored-by: Can Celik <ogulcancelik@gmail.com>
2026-08-11 03:24:02 +03:00
David Heinemeier HanssonandOgulcan Celik 350f001320 feat: keep the outer terminal window title in sync with the session (#2627)
* feat: keep the outer terminal window title in sync with the session

Herdr emulates the terminals in its panes, so an OSC 0/OSC 2 title
written inside a pane stops at Herdr and never reaches the terminal
Herdr itself runs in. That outer title is what window managers read for
title bars, tab bars, and group bars, so it kept showing whatever the
shell or ssh happened to leave behind.

Add `ui.window_title`, rendered from {hostname}, {workspace}, {tab},
{pane}, and {terminal_title}, and push it to the foreground client
whenever it changes. It renders on the server, so {hostname} names the
machine the panes actually run on rather than the machine a thin remote
client runs on, and it is gated on a pending render so an idle loop
never pays for it.

A title is only remembered as delivered once a foreground client takes
it, so the first client to attach is written to rather than skipped.
`client.window_title.set` still wins over the configured title, and
clearing it now hands the title back to `ui.window_title` instead of
only "herdr".

* fix: deliver the outer window title to a newly attached client

ClientConnected assigns the foreground client directly rather than going
through promote_client_to_foreground, so clearing the sent-title cache
there missed the case that matters most: attaching a second terminal to a
running session. The title was usually unchanged, so the sync returned
early and the new terminal kept whatever its shell or ssh had left.

Key the cache on the client that received the title instead of relying on
every foreground assignment to invalidate it.

* perf: keep hidden pane output off the window title path

Output from a hidden or background pane sets needs_render without setting
needs_full_render, and the retained render plan then skips presentation
for it entirely. Syncing the title on needs_render meant every coalesced
hidden-output tick still formatted, sanitized, and allocated a title that
could not have changed, against the hidden-source early exit AGENTS.md
requires.

Every input to the title is app state, which always requests a full
render, so gate on that instead. The one exception is the focused pane's
own terminal title, which arrives through PTY parsing, so ask for a full
render when that changes and the configured title uses it.

* fix: only cache a window title a client writer received

* fix: carry an api set window title across a live handoff

* fix: make outer window title updates event-driven

---------

Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>
2026-08-11 03:04:12 +03:00
Ogulcan Celik e2aa86a9e8 test: guard pane-scaled render performance
refs #2550
2026-08-09 20:36:11 +03:00
akbash e7c38ab37f perf(ui): avoid full pane mode reads for scrollbars (#2554) 2026-08-09 14:50:11 +03:00