Repository navigation
Conversation
* 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 herdrdev#1445 * fix(windows): add csh and tcsh to login shell flags refs herdrdev#1445
) 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 herdrdev#4060.
…3574) A process-exit observation is not proof the agent is gone: the same observation can be wrong while the agent keeps running, and the name is the only handle its owner has on the pane. Detection uncertainty already preserves the name, so releasing it on the observation alone contradicts that contract and leaves a live agent unreachable by name with a rename as the only recovery. Free the name at the point the agent actually leaves the pane - a recorded exit with no agent detected any more - so a wrong observation costs nothing and a real exit still releases the name for reuse. refs herdrdev#3225 Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
* fix: auto-expire worktree action error banners refs herdrdev#1827 * fix: restart endpoint error timeout on repeated errors Route every transient client-side action error through a setter that installs a fresh deadline, so an identical repeated message cannot inherit an older, nearly-expired deadline. refs herdrdev#1827 * test: derive endpoint error expiry assertions from stored deadline refs herdrdev#1827
Codepoints 57364-57375 (F1-F12) were missing from the kitty-protocol codepoint table, so terminals that send function keys as full CSI-u sequences (e.g. Ghostty, which enables the kitty keyboard protocol by default) had those keys silently dropped. Confirmed live against a running herdr session: injecting the raw F3/F4 codepoint sequences did nothing before this fix and correctly triggered previous_tab/next_tab after. refs herdrdev#1809 Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
Terminals such as foot send F1-F4 as parameterized CSI-tilde sequences (for example F3 as `\x1b[13;1:1~`). `parse_xterm_modified_special_sequence` mapped codes 15-24 but not 11-14, so these presses were dropped before keybindings saw them. Map 11-14 to F1-F4, matching the unmodified `\x1b[11~`..`\x1b[14~` aliases already accepted. refs herdrdev#1809
* feat: install windows remote host packages refs herdrdev#3651 * docs: clarify windows saved reconnect package behavior refs herdrdev#3651 * fix: include windows installer in nix sources refs herdrdev#3651 * fix: preserve paths in windows scp transfers refs herdrdev#3651 * refactor: isolate windows remote package setup refs herdrdev#3651
refs herdrdev#3621 Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
* ci: migrate remaining pinned actions to node24 actions/cache@v4 and mlugg/setup-zig@v2.2.1 still target Node 20, which GitHub removes from runners on 2026-09-23. Bump actions/cache to v6.1.0 and replace mlugg/setup-zig with vercel-labs/setup-zig@v1.0.2. vercel-labs/setup-zig takes only `version`, so the use-cache/cache-size-limit tuning and Zig global-cache reuse are dropped. See the PR for alternatives. * ci: restore zig caching for vercel setup-zig vercel-labs/setup-zig has no cache controls, so redirect the Zig global cache into the workspace .zig-cache and run the Zig build cache step on Linux too. Drop this commit if we switch to a setup action that owns Zig caching, e.g. step-security/setup-zig or xyzzylabs/setup-zig.
* fix: scope agent views to the selected machine refs herdrdev#3732 * fix: preserve stable agent view ordering refs herdrdev#3732 --------- Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com> Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
…erdrdev#4079) Co-authored-by: dengos <dengoswei@gmail.com>
…#4082) * test(windows): deflake media player invalid media assertion The Windows sound test required MediaPlayer's MediaFailed event for invalid media. Some runners never raise it, so the script exits through its playback timer and the test saw "sound playback timed out" instead, panicking on the MediaFailed assertion. Accept either terminal error and keep the timer short under test via HERDR_SOUND_TIMEOUT_SECONDS so a missed MediaFailed no longer waits out the production 15 second bound. * test(windows): keep media player timeout override test-only Generate the short-timer player script only in tests instead of reading a process environment override. This keeps the production script's fixed 15 second bound unchanged, and the script-content test now proves the test variant rewrites the timer.
…drdev#4083) * fix: clean up idle ssh bridges and back off flapping connections * chore: keep ssh liveness smoke tooling local
refs herdrdev#3937 Root cause: Activating another endpoint applies a snapshot with a different endpoint-qualified graphics scope. This triggers reset_endpoint_projection, which clears agent_scroll together with endpoint-local state even though the agent list aggregates all machines. The selected agent receives focus, but the list jumps back to the top. Fix: Save the client-owned agent scroll offset and restore it only when activation changes endpoints. Keep same-endpoint reboot resets, workspace/tab scroll resets, input cleanup and existing list bounds clamping unchanged. This adds constant-time work on endpoint activation, with no protocol, persisted-state or pane-scaled rendering changes. Validation: The new regression fails on the original implementation with scroll 0 instead of 6. Tests cover repeated bidirectional agent clicks, stable visible rows, shrinking lists and same-machine reboots. All 242 client shell tests pass. Real SSH A/B testing against the same two disposable 0.9.0 servers reproduces the reset with both the stable and current-master clients. The patched client preserves the visible rows through six cross-machine switches and two same-machine control clicks. Native just ci passes: 3535 Rust tests, six default skips, plus lint, maintenance, architecture and integration-asset checks. All seven docs contract tests pass. Windows cross-lint was not run because its SDK is not installed; native macOS and Windows UI behavior was not tested.
…rdev#4099) * fix: detect codex activity with static titles and queued inputs refs herdrdev#4092 Codex 0.154.0 can omit the activity bullet when tui.animations is false and replace the literal Working label with a task-specific label. Its terminal title can also remain static during an active turn, so the OSC spinner rule is not sufficient to identify work. The screen fallback required a bullet followed by Working in the last three non-empty lines. It therefore missed both the animation-disabled status line and dynamic labels. Queued follow-ups add a heading, input text, and an edit hint below the activity line, moving that line outside the three-line region. The lower-priority non-empty OSC title rule then reported idle while Codex still showed an active timer and interrupt control. Recognize the elapsed-time and esc-to-interrupt controls in the detection snapshot before the current composer. Allow an optional bullet, a dynamic activity label, and queued follow-ups below that line. Require that no later response, completion, or interruption marker supersedes the live activity. This excludes composer text and stale output without letting an earlier interruption suppress a subsequent active turn. Keep OSC state precedence and transcript-viewer skip behavior unchanged. Update the bundled and distributed manifests together to 2026.09.14.1. Add regression coverage for optional bullets, dynamic labels, queued inputs, resumed work after interruption, and stale or quoted controls. Avoid discarding Regex search caches on every detection poll. The loader previously cloned the entire compiled rule vector, and each Regex clone created a fresh search cache pool despite sharing compiled read-only state. Share the immutable rules through Arc instead. Reload publishes a new array while in-flight readers retain a valid old generation, without holding the global cache lock during matching. Add a cheap contains gate for the required interrupt text before running the multiline expression. Add a deterministic regression for compiled-rule sharing, reload replacement, retained old readers, and concurrent detection. Measure the baseline and optimized detector kernels in three alternating rounds on CPU 24 with NUMA node 0 and CPU 25 with NUMA node 1. Real queued detection falls from about 116 to 22 microseconds, and two evaluations per pane over 15 panes fall from about 3.45 to 0.65 milliseconds on both sockets, about 81 percent less time. No benchmark match results change. The cache improvement requires the updated binary, not just a manifest reload. Validate on the official Herdr 0.9.0 release with Codex 0.154.0 by toggling the old and new manifests during the same active queued task. Confirm working for active turns and idle after completion or interruption. Pass 86 captured-screen and semantic checks through the optimized source binary, 69 manifest/cache tests, CPU-pinned render scaling, and the full native CI suite: 3535 Rust tests passed, with six default skips. Run CI serially with inherited Herdr session context removed; no tests were excluded or expectations relaxed to make CI pass. * fix: detect codex pending follow-ups as working refs herdrdev#4092 * fix: handle wrapped codex follow-up hints refs herdrdev#4092 --------- Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>
* refactor: share cli and api command contracts * fix: address cli contract review findings
…#5232) * fix: retry a reconnecting machine immediately when selected Assisted-by: Claude <noreply@anthropic.com> * fix: retry the active SSH machine when selected refs herdrdev#4721 --------- Co-authored-by: Bart Louwers <bart@emeel.net>
* fix: cancel and clean up endpoint connection attempts refs herdrdev#4721 * fix: keep probe teardown scoped to its bridge refs herdrdev#4721 * fix: preserve nonblocking bridge output and simplify cleanup refs herdrdev#4721
* fix: recover endpoint connections promptly after wake refs herdrdev#4721 * test: wait for asynchronous endpoint pipe closure refs herdrdev#4721
* fix: recover blocked shared ssh connections refs herdrdev#4721 * test: support shared ssh checks in client fixtures refs herdrdev#4721 * test: separate ssh cancellation from timeout scheduling refs herdrdev#4721
…ev#5269) portable-pty's Windows search_path accepted any existing candidate, so a directory on PATH whose name matched the program shadowed the real executable and CreateProcessW failed with os error 5. Require a regular file for both the exact name and the PATHEXT candidates. refs herdrdev#5267
Every bundled Windows PowerShell hook read its hook JSON with `[Console]::In.ReadToEnd()`, which decodes stdin using the process console input code page instead of UTF-8. On Korean Windows (CP949) that corrupts the payload, `ConvertFrom-Json` throws, and the hook silently exits without reporting the session. Read the raw stdin stream as UTF-8 (BOM-aware) in every PowerShell hook and bump the affected integration versions. refs herdrdev#5253
The client_mode::federated_client_starts_without_local_and_survives_its_restart integration test fails intermittently on the ubuntu (and macos) runners at two polling budgets: - "remote must be usable before Local exists" - "remote reconnect N must restore visible input and preserve the shell" Both budgets are shorter than the client's own connection and activation deadlines. Saved-SSH discovery probes are bounded by a 15s SSH command timeout, the remote handshake read timeout is 60s, and each endpoint activation phase has a 5s deadline that can retry. Under a loaded runner the client can still be legitimately connecting, or holding pane input closed through an activation retry, when the test gives up. Give the remote-readiness and remote-input waits budgets that exceed those deadlines. The waits still return as soon as the observed condition holds, so only the failure path gets slower. The intentionally tight waits that prove Local does not wait for a stalled remote stay at 3s.
…5282) PowerShell serializes progress records such as module auto-loading's "Preparing modules for first use." to the stderr CLIXML stream when stderr is redirected under `-EncodedCommand`, and Herdr forwards that stderr during interactive remote setup. Set `$ProgressPreference = 'SilentlyContinue'` in the shared Windows PowerShell preamble so `machine add` and `--remote` no longer print raw CLIXML records. refs herdrdev#4639
The macOS CI job intermittently fails server::client_transport::tests::observer_write_timeout_resets_when_sending_makes_progress with "assertion failed: write_framed_bytes(...)" followed by "observer disconnected while making progress". The test proves that every partial write resets the writer's deadline by draining a 1 MiB frame through an observer that sleeps 5 ms per 16 KiB read while the writer's send timeout is 100 ms. On a loaded runner, one scheduler stall longer than 100 ms makes write_client_stream time out and shut the socket down, so the write assertion fails and the observer then reads EOF. Give the writer a 1 s timeout and slow the observer to 25 ms per read. The transfer still takes about 1.6 s, longer than the timeout, so the deadline reset is still required, while the stall budget grows 10x and the drain cadence stays 40x below it. Also bound both kernel socket buffers well below the frame size. The reset path is only exercised while the writer is blocked, so the test should not depend on the platform default buffers happening to be smaller than 1 MiB.
Stage 1 of 3 toward upstream v0.9.5: upstream master 956f23f, the v0.9.1 metadata sync point. Resolution notes: - api: keep the fork's pane.mark.set beside upstream's pane.link.resolve in the method enum, method names, client-shell method list, and dispatcher. - agent marks: carry the Marked view field and marked-first ordering onto upstream's shared agent_view_eval (AgentViewEntry::marked); the sidebar draws the mark gutter through upstream's agent_row path. - clipboard: thread the fork's ClipboardWriter beside upstream's scheduled_activation; adapt forward_clipboard_uses_local_clipboard_path to the writer. - selection and copy mode: route upstream's word_selection_gesture row reads, completion, and focus-loss cancellation through the popup target helpers; keep paste into the popup copy-search prompt; share the occlusion-aware highlight and cursor helpers between panes and the popup. - popup text routing: upstream's rule that a copy-search prompt yields typed and pasted text to an open popup applies to copy mode left on a pane. Copy mode armed over the popup keeps the text in its prompt, and other shell sub-modes armed over the popup still drop it. - repeatable prefix: keep tick_prefix_repeat beside upstream's endpoint error timer; timer_delay covers both deadlines. - surface codecs: keep the fork's surface_v2 negotiation beside upstream's surface_reuse and surface_delta; frame dedup also requires unchanged popup metrics, and metrics stay paired with delta frames. - retained surface: apply pane dimming to upstream's dirty patch snapshot. - tab bar: port upstream's max_tab_scroll rewrite with the minimal style's gap. - docs/next/CHANGELOG.md: take upstream. The fork's two Unreleased lines (ui.sidebar_divider, ui.zoom_indicator) are covered by docs/fork/FORK_FEATURES.md. - docs/next/api/herdr-api.schema.json: regenerated.
Stage 2 of 3 toward upstream v0.9.5: upstream master f9a99bd, after the v0.9.2 and v0.9.3 releases. Resolution notes: - prefix keys: carry the fork's table binding form onto upstream's multiple prefixes; keys.prefix also accepts { key, repeat } and ignores repeat (a config diagnostic follows separately). The popup shell lets every configured prefix through via matches_prefix, and resolve_prefix_binding stays as a test-only wrapper. - popup metrics and frame order: frames that carry a native graphics upload now take the ordered lane. Add send_ordered_with_control so popup metrics are queued with such a frame under one lock, ahead of it, both or neither, as try_send_render_with_control already does for the render slot. The client already stages reports for two frames in flight. - server render: use upstream's early shell surface render and its synchronized-output deferral; the popup metrics ride the same RenderedPaneSurface. prepare_pane_surface_with_file takes the popup metrics after upstream's file-upload flag. The retained surface still bails out while a popup is open, so it passes no metrics. - panes: keep inactive pane dimming beside upstream's restore error message. - client shell: layer the prefix highlight and popup dim and background onto upstream's ComposedFrame; keep the sidebar divider beside the workspace highlight colors; reapply pending agent marks before reconciling the workspace highlight; tick_prefix_repeat runs beside tick_workspace_highlight. - clipboard: keep the async ClipboardWriter. Upstream's duplicate check runs on the worker in write_native_clipboard, which treats a skipped duplicate as handled so it does not fall back to OSC 52. Inline OSC 52 writes report failure. Drop forward_clipboard_uses_local_clipboard_path with upstream. - api: keep the fork's popup responses; take upstream's removal of pane.graphics.*. socket-api.mdx (en/ja/zh-cn) follows upstream's pane row plus pane.mark.set. - tests: new upstream initializers gain marked and surface_v2, fork popup tests gain surface_scroll, and the delta test decoder takes the scroll flag. - docs/next/api/herdr-api.schema.json: regenerated.
Stage 3 of 3 toward upstream v0.9.5: upstream master 2f3432c, the v0.9.5 metadata sync point. Besides the v0.9.4 and v0.9.5 releases it brings the master-only shared CLI/API contract refactor (herdrdev#5212), the connection fixes that followed it, and a test deflake. Resolution notes: - api (herdrdev#5212): API methods now come from the define_operations! table, which also derives request_changes_ui, api_method_name and the client-shell method list. Add rows for pane.mark.set and popup.scroll / selection.read / copy_motion / copy_search with the same classification the fork's hand-written list entries had, and drop those entries. PaneMarkSetParams becomes a cli_params! projection. - cli (herdrdev#5212): the pane and agent commands are now built from their bindings, and cli/runtime.rs is gone. `herdr pane mark` becomes a Leaf in cli/pane/bindings.rs and `herdr agent mark` an Operation in cli/agent/bindings.rs, keeping the old grammar: pane mark needs a selector and --on or --off; agent mark resolves the agent, then sends pane.mark.set and flips the current mark without a flag. Help now comes from the bindings, so the fork's line in print_agent_help goes with upstream's removal. spec.rs keeps the fork's registration test. Contract tests for both commands join tests/cli/contracts.rs, and pane_projection_all_leaf_request_values gains a mark row. - panes (herdrdev#4873): new panes start at their laid-out size. Take pane padding off before the scrollbar gutter in new_terminal_size and in the zoomed branches of resize_tab_panes and compute_pane_infos_for_tab, so a padded new pane does not start larger and then resize. Add a test that new panes start at their padded laid-out size. - git refresh (herdrdev#4958): the fork's early return for a cwd-only pane title refresh also clears git_refresh_spawn_retry_pending. Nothing needs git there, so a stale flag would keep headless git refresh scheduled. - pane.rs: keep the fork's foreground process name probe beside upstream's process probe changes. - server render: keep the fork's popup metrics framing beside upstream's interactive echo latency tracking (herdrdev#5149). - mouse: keep the fork's removal of the second popup guard, so overlay-less full-screen views still take clicks over a popup, ahead of upstream's mouse capture check for hyperlink clicks (herdrdev#5064). - tests: new upstream tests use the fork's EndpointServerWelcome::compatible_with_surface_codec, pass the ClipboardWriter to dispatch_client_shell_actions, and set surface_v2. - docs/next/api/herdr-api.schema.json: regenerated.
Since upstream's multiple prefix keys, keys.prefix takes the same binding config as actions, so the fork's table form lets it carry `repeat = true`. A prefix key has no action to repeat, and the keys deserializer flattened the table, so the option vanished without a word. Before the sync, a table prefix was a config error. Keep the option on keys.prefix when it is set and report it as a non-fatal diagnostic. The warning banner and `herdr config check` show it while the prefix keys and config reload still apply; rejecting it would fall back to ctrl+b.
Upstream needs Zig 0.16.0 since v0.9.1: it is the vendored libghostty-vt's minimum_zig_version. Pin `make build` to zig@0.16.0. Drop the ZIG wrapper. It gave zig 0.15.2 an xcrun shim that returned the macOS 15.4 SDK, which the Command Line Tools no longer ship. Zig 0.16 links against the installed SDK, so the build now uses the zig that `mise exec` puts on PATH; a ZIG from the environment still overrides it.
Log the staged merge to upstream 2f3432c in FORK_FEATURES, including where each fork feature was re-seated and what is deferred to the next sync (the CLAUDE.md removal and herdrdev#5583). Update FORK_WORKFLOW and CLAUDE.local.md for the new baseline: zig 0.16.0 replaces the xcrun-shim wrapper, staged merges use the master release sync points instead of tags, the known local test failures are remeasured, and the inherited preview and release workflows no longer run in the fork.
WalkthroughWarning Review details and warnings were omitted to fit the comment limit. |
Upstream herdrdev#3698 makes the copy-search prompt yield committed text and pastes to an open popup. The fork keeps them in the prompt only when copy mode targets the popup, so copy mode left on a pane now sends them to the popup instead of its prompt. Also state that the agent sort order is unchanged by the sync.
Upstream herdrdev#4803 added a Windows-only activation test that calls dispatch_client_shell_actions, which has taken the fork's clipboard writer since fork.10. Unix builds never compile that test, so only the Windows CI job caught the missing argument.
Running the Windows-target clippy with a no-op zig compiles every cfg(windows) item and test without the Microsoft SDK. Skipping it let a fork signature change break an upstream Windows-only test unnoticed until CI.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
upstream(
ogulcancelik/herdr)を、v0.9.5 のリリース同期点2f3432c6までmainに取り込む。前回の同期(2026-09-10、120c6820= v0.9.0+14)以降の約 300 コミット分。フォーク機能は一つも落とさずに載せ直した。ビルドは
0.9.5-fork.10を名乗る(sync では fork 番号を上げない)。upstream のリリースタグは master の祖先ではないので、master 上の
release: synchronize metadata for vXを区切りに 3 段でマージした。956f23ff)f9a99bd2、v0.9.2 を含む)2f3432c6、v0.9.4 と herdrdev#5212 ほかを含む)keys.prefixに書いたrepeatを警告するMakefile)dispatch_client_shell_actionsを古い引数で呼んでいた)主な載せ替え
pane.mark.setはsrc/api/schema.rsのdefine_operations!表の 1 行になった。CLI は upstream の表駆動化(refactor: share cli and api command contracts herdrdev/herdr#5212)に合わせてsrc/cli/pane/bindings.rsとsrc/cli/agent/bindings.rsへ移した(文法は不変)。並びは upstream の「切断中のエンドポイントは後ろ」を優先し、マークはその次のキー。word_selection_gesture)と、ペインと共用の遮蔽対応ハイライト・カーソルへ載せ替えた。send_ordered_with_controlでメトリクスを同じロックの中でフレームの直前に積む。timer_delayで待つ。keys.prefixのrepeat(2b42da5)v0.9.2 から
keys.prefixもテーブル形式を受け付けるので、prefix = { key = "ctrl+a", repeat = true }と書けてしまう。prefix キーには繰り返す動作が無いので、このrepeatは効かない。致命扱いにすると prefix が既定の
ctrl+bに戻るため、警告(画面上部の設定警告行とherdr config check)だけを出し、prefix キーとリロードはそのまま効かせる。検証(ローカル、macOS 26.6)
cargo fmt --check、cargo clippy --all-targets --locked -- -D warnings:緑。cargo nextest run --no-fail-fast:4133 件中 1 件失敗(config_replacement_preserves_macos_acl)。素の upstream2f3432c6でも毎回落ちる環境依存のテスト。素の upstream との失敗の照合結果は FORK_WORKFLOW §0 に記録した。tests/cli.rsの CLI 契約テストは macOS では無効なので、ゲートを一時的に外して回した(14/14、フォークのマーク 3 件を含む)。just maintenance-test/ui-hot-path-architecture-test/integration-assets-test/docs-contract-test:緑。cargo clippy --all-targets --locked -- -D warnings:緑。Microsoft の SDK は使わず、libghostty-vt の zig ビルドを空振りさせて回した(リンクしないので check と clippy まで)。Windows でのテストの実行は CI に任せる。prefix+m)、popup のタイトル・余白・背景・減光・copy mode・マウスドラッグでの OSC 52 コピー。いずれも期待どおり。make buildの成果物がherdr 0.9.5-fork.10を名乗ることを確認。次回の同期に持ち越すもの
CLAUDE.mdを削除した(b796ca60)。次回、CLAUDE.local.mdの冒頭に@AGENTS.mdを足して補う。既知の制約
preview.yml/release.ymlはpreview-*/v*タグの push でだけ起動し、全ジョブがherdrdev/herdr限定になった。フォークの Release は以前の手順(main:masterの反映と手動 dispatch)では作れない(FORK_WORKFLOW §6 A に記載)。validate(distribution.yml)は、フォークにリリースタグが無いため構造的に赤。🤖 Generated with Claude Code