Commit Graph
157 Commits
Author SHA1 Message Date
Ogulcan Celik 4e78166de4 fix(perf): eliminate redundant terminal wake work 2026-08-19 03:25:25 +03:00
akbashandakbash-bot 2d24950ad9 fix: isolate hidden pane render cadence (#2892)
refs #2890

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
2026-08-18 04:37:11 +03:00
akbashandakbash-bot 76211757ec fix: reap ctrl-click url openers (#2906)
* fix: reap ctrl-click url openers

refs #2903

* fix: scope linux opener test import

refs #2903

* test: isolate url opener regression

refs #2903

---------

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
2026-08-18 00:11:20 +03:00
Can Celik 15539d3dec feat: make headless terminal size configurable (#2829)
refs #2828
2026-08-15 15:09:53 +03:00
Can Celik d76657f2c7 fix: speed up alternate-screen history reads (#2426)
refs #2387
2026-08-14 05:18:30 +03:00
Can Celik b7dca4bb2a fix(graphics): support high-dpi direct file frames (#2680) 2026-08-13 17:21:26 +03:00
akbashandakbash-bot 3607453087 fix(render): compact large terminal redraws (#2675)
refs #2670

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
2026-08-11 22:55:49 +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
Can Celik 7e4ab7b034 fix(server): prioritize shutdown requests (#2624)
refs #2612
2026-08-10 21:01:45 +03:00
Can CelikandDavid Heinemeier Hansson e48d83067a feat: add configurable tab bar status (#2586)
* feat: show a zoom indicator in the desktop tab bar

Reserve the right edge of the tab row for a ZOOM pill while the
focused pane is zoomed, matching the accent style of the mode bars.
The per-tab Z suffix stays; the pill makes the zoomed state visible
at a glance like tmux's status-right flag.

* feat: optionally show the hostname in the desktop tab bar

Add ui.tab_bar_hostname to display the machine's hostname at the right
edge of the tab row, like tmux's #h in status-right. The value resolves
where the server renders, so remote sessions show the remote host. Off
by default.

* fix: strip control characters from the tab bar hostname

* fix: hide the hostname when it would squeeze out the tab strip

* feat: add configurable tab bar status

* fix: harden tab bar status updates

* fix: terminate tab bar status process trees

* fix: disable status commands on unsupported platforms

* fix: skip unchanged status command renders

* fix: keep tab bar status opt-in by default

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
2026-08-10 01:20:09 +03:00
Ogulcan Celik e2aa86a9e8 test: guard pane-scaled render performance
refs #2550
2026-08-09 20:36:11 +03:00
Can Celik 1777e9bba3 feat(graphics): add direct pane frame streaming (#2523)
* feat(graphics): add direct pane frame streaming

* feat(graphics): expose pane visibility

* test(graphics): preserve legacy terminal image output

* fix(graphics): harden streaming lifecycle

* fix(input): preserve mouse releases outside panes
2026-08-09 02:04:39 +03:00
akbashandakbash-bot 6f311498ae fix: forward pane terminal bells (#2498)
refs #2453

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
2026-08-08 02:15:56 +03:00
be1891ec52 fix(terminal): render halfwidth katakana voiced marks (#2257)
Co-authored-by: oyoguhito <oyoguhito@kamatanoMacBook-Pro.local>
Co-authored-by: Can Celik <ogulcancelik@gmail.com>
2026-08-05 00:48:15 +03:00
Kataoka Katsukiandkataokatsuki 1997b88b3f fix(input): keep pending url clicks across host focus loss (#2291)
Opening a URL raises the browser, which takes focus away from the host
terminal before the mouse release arrives. release_input_source(_headless)
cleared pending_url_click_sources on that focus loss, so the release was
forwarded to the pane and the agent opened the same URL again.

Clear the set in clear_input_source instead, whose only production caller
is remove_client.

refs #2290

Co-authored-by: kataokatsuki <kataokatsuki@users.noreply.github.com>
2026-08-04 17:46:43 +03:00
akbashandakbash-bot e6fa5289f2 fix(ui): preserve sidebar scroll across clients (#2280)
refs #2255

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
2026-08-04 15:37:33 +03:00
Michael HacknerandCan Celik eacea2daf0 fix: page keys scroll pane scrollback at zsh and REPL prompts (#2191)
* fix: page keys scroll pane scrollback at zsh and REPL prompts

PageUp/PageDown were forwarded to the pane whenever DECCKM (application
cursor) was on, assuming only primary-screen pagers enable it, but zsh's
line editor also enables DECCKM, as do REPLs such as python3. The result
was PageUp scrolling shell history instead of Herdr scrollback.

Bracketed paste discriminates the two: it means the app accepts typed or
pasted text at a prompt, so line editors enable it and pagers do not.

* test: update page key state fixture

---------

Co-authored-by: Can Celik <ogulcancelik@gmail.com>
2026-08-03 04:08:47 +03:00
Can Celik 10eb0bc744 fix: propagate host color scheme to pane apps (#2214)
refs #714
2026-08-03 02:05:27 +03:00
serhat dolmaci 885c9a6b5b fix(socket_paths): remove dead if-branch in derive_client_socket_from_api_socket (#2157) 2026-08-01 19:38:43 +03:00
Can CelikandJonathan Liebig b76adc155d fix(input): preserve native key lifecycle across routing (#2142)
refs #2077

Co-authored-by: Jonathan Liebig <jonathan.liebig@gmail.com>
2026-08-01 04:27:50 +03:00
Ogulcan Celik bc1c052d15 fix: read alternate-screen agent history 2026-07-31 16:22:04 +03:00
Can Celik 0732039eaf fix: preserve windows sessions after ssh logout (#2098)
* fix: preserve windows sessions after ssh logout

refs #2008

* chore: document windows wmi safety

refs #2008
2026-07-30 23:39:03 +03:00
Can Celik ac47b9e679 fix: resume agents after headless restore (#2088)
refs #2064
2026-07-30 19:15:00 +03:00
Ogulcan Celik e27a4ea427 perf: skip rendering hidden pty updates 2026-07-28 23:29:11 +03:00
Ogulcan Celik 81f355fada perf: replace agent spinners with static status marks 2026-07-28 14:56:53 +03:00
Can Celik e536bd8bd9 fix: support non-us shifted keybindings (#1876)
* fix: support non-us shifted keybindings

refs #1870

* docs: require current pull request base
2026-07-26 04:22:05 +03:00
Can Celik 547aba8e0a fix: avoid renders for passive mouse motion (#1872)
refs #1865
2026-07-26 00:28:11 +03:00
Can Celik b01fc37e66 perf: avoid full pane renders for spinner animation (#1868) 2026-07-25 23:20:08 +03:00
Can Celik d4e0dd3d90 perf: eliminate repeated workspace git discovery (#1842)
* perf: eliminate repeated workspace git discovery

refs #1838

* fix: keep workspace labels current without extra redraws

refs #1838

* fix: retain discovered workspace git metadata

refs #1838
2026-07-25 04:26:55 +03:00
Ogulcan Celik e608a75159 fix: make known-agent exit process-owned
refs #1792
refs #1648
2026-07-24 02:50:58 +03:00
Ogulcan Celik 36de78dd4f fix: preserve kitty graphics during host repaints
refs #1628
2026-07-24 01:31:06 +03:00
akbashandOgulcan Celik 503613c8ec fix: inherit host palette in pane queries (#1759)
refs #1752

Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>
2026-07-24 01:28:35 +03:00
Ogulcan Celik e7fc85bfdb fix: preserve kitty printable key releases
refs #1746
2026-07-23 03:47:44 +03:00
akbashandakbash-bot 6382bd433a fix: reject oversized text pastes safely (#1676)
refs #1665

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
2026-07-21 17:33:07 +03:00
Ogulcan Celik d30ab1b54f feat: add plugin-driven agent views and startup hooks 2026-07-20 00:55:36 +03:00
Ogulcan Celik 8dcb75a5c0 refactor: extract active tab surface rendering 2026-07-16 22:47:10 +03:00
Ogulcan Celik 2c7c8beb07 feat: add floating popup panes
refs #1125
2026-07-15 04:02:14 +03:00
Ogulcan Celik 88370e1516 feat: add isolated pane graphics streaming 2026-07-15 02:32:52 +03:00
Ogulcan Celik b88aa1301e fix: flush live handoff responses before exit 2026-07-14 22:07:06 +03:00
2e5da968ea fix: forward outer focus events to panes (#1388)
* fix: forward outer focus events to panes

refs #1337

* fix: preserve ordered focus forwarding

refs #1337

---------

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>
2026-07-14 01:06:11 +03:00
akbashandakbash-bot 75ed6abc62 fix: reap detached custom command children (#1384)
* fix: reap detached custom command children

refs #1360

* test: harden child cleanup and sidebar metrics

refs #1360

---------

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
2026-07-13 17:25:52 +03:00
Ogulcan Celik 5cfe5e5e73 feat: add configurable sidebar metadata tokens 2026-07-13 03:30:13 +03:00
Ogulcan Celik 9c45342766 fix: preserve explicit session sockets during live handoff
refs #1180

reported-by: dvic

based-on: https://github.com/dvic/herdr/pull/3
2026-07-09 16:32:26 +03:00
Ogulcan Celik d6285aaa59 fix: avoid render-time plain url scans 2026-07-08 00:44:49 +03:00
Ogulcan Celik b425260f9d perf: move session autosaves off main loop 2026-07-07 15:35:20 +03:00
4f22e9a73b fix: preserve wrapped pane links (#1099)
refs #1098

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
Co-authored-by: Can Celik <ogulcancelik@gmail.com>
2026-07-06 23:59:59 +03:00
ppggffandOgulcan Celik 2bc1724c2d fix: switch prefix ASCII input source on the foreground client (#1016)
* fix: switch prefix ASCII input source on the foreground client

The macOS prefix ASCII-switch ran in the headless server, whose
TISCopyCurrentKeyboardInputSource read is a stale per-process cache
(refreshed only via a main-run-loop notification the server never pumps),
so prefix could leave the terminal on the wrong input source.

Forward it to the foreground client, like clipboard: sync_prefix_input_source
emits AppEvent::PrefixInputSource as an intent; the server forwards it to the
foreground client and the monolithic app applies it in-process via
RealPrefixInputSource, which pumps its main run loop before the stale TIS read.
Key it on Mode::wants_ascii_input so multi-level prefix commands keep ASCII
until returning to the terminal, and restore the IME for rename text entry.

Adds ServerMessage::PrefixInputSource to the already-unreleased protocol 15.

refs #774

* fix: keep prefix input-source switch out of the headless server process

An App-internal drain (the exhaustive drain at the top of
handle_api_request, reachable from prefix-key runtime mutations) can
consume a queued PrefixInputSource intent before the server's
forwarding drain sees it, applying the TIS switch in the headless
server process and stranding the restore state. Gate the in-process
switch on App.local_input_source_switch, disabled by the headless
server alongside the other local side effects, so a swallowed intent
degrades to a skipped switch. Widen the forwarding-bypass maintenance
test to the handle_internal_event_with_prefix_sync wrapper.

refs #774

* docs: clarify prefix input-source comments and flag docs

refs #774

* fix: bump protocol for prefix input source

refs #774

---------

Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>
2026-07-05 03:25:47 +03:00
Ogulcan Celik 04682e57e6 refactor: route headless deferred creates through runtime helpers 2026-07-04 16:51:10 +03:00
Ogulcan Celik 15cab964f3 feat: emit layout update events for runtime layout changes 2026-07-04 16:51:10 +03:00