Skip to content
PaneflowPaneflow

v0.17.7Latest

Status from OSC 7501

View on GitHub

Agent status comes from OSC 7501

Paneflow 0.17.7 makes OSC 7501 the only source of agent turn status. Any program, agent or not, can report working, blocked, done, or error with one escape sequence: the pane header shows it, a blocked or failed program enters the Attention queue and sends a notification that names the pane, and a declared done or error stays until you type in the pane. Paneflow no longer reads agent status off the screen or from hooks, so an agent that does not emit OSC 7501 shows no turn status. The release also moves the terminal engine to Ghostty b699ea79: trackpad scrolling follows the gesture by the pixel, the mouse pointer takes the shape a program asks for, and each character is drawn on its own cell. Six built-in agents are removed.

Upgrade notes

  • Agent turn status now needs OSC 7501. In 0.17.6, Claude Code, Codex, Gemini, OpenCode, Pi, Hermes Agent, and fx got a turn status from hooks or screen rules. From 0.17.7, an agent that does not report its state with OSC 7501 shows no turn status: no working or waiting state in the sidebar, no Attention queue entry, and no notification. Claude Code and Codex hooks stay installed and still resume conversations, name tabs, and report the last result. For such an agent, paneflow send --submit reports no_signal and paneflow wait --idle waits for the output to go quiet instead of returning at the end of the turn. Paneflow offers no replacement: the status comes back once the agent itself emits OSC 7501.
  • Script-visible fields changed. activity_source is now declared or none (it was hooks, screen, or none) in paneflow sessions, Controller events, paneflow status --json, and fleet.list. attention_reason and menu_prompt_active are gone. hooked is true only after a hook event from a runtime that has a hook installer (Claude Code and Codex), where fleet.list rows always said true. An outcome is now completed or failed, optionally failed:<reason>; expired and cancelled are no longer produced. A script that waited for activity_source to be hooks or screen should test for declared instead, and one that read attention_reason or menu_prompt_active should read status instead.
  • Sessions that outlive the update end as Incompatible. The session host embeds the terminal engine, and a host started by the previous version cannot serve a desktop built on the new engine. Updating from inside Paneflow stops the host before restarting, so this only happens after an update made outside the app (a system package, Homebrew, or an MSI installed by hand) or when you choose Keep sessions running before updating. Each such session ends with Retry and Stop host and restart; choose Stop host and restart to start the new host, or let the sessions finish first.

Added

  • The mouse pointer takes the shape a program requests with OSC 22, such as a hand over a link or a resize arrow over a splitter. The scrollbar and a Ctrl-hovered link keep their own pointer, and a shape Paneflow cannot draw shows the default arrow.
  • Trackpad scrolling through the scrollback follows the gesture by the pixel instead of jumping a line at a time. Mouse wheels keep line-by-line scrolling, and so does reduce_motion, which also drops an offset already on screen at the next frame. A program that reads the mouse, or an alternate screen that scrolls alternately, always gets whole lines and an unshifted grid.
  • Any program can report its own status with OSC 7501, agent or not, and the pane header shows it. For example, a script that runs printf '\033]7501;state=blocked:kind=permission:app=deploy:msg=QXBwbHk/\033\\' shows blocked: permission · Apply? in the pane header (msg is base64), and the Attention queue and the notification name it deploy. A program without an agent that reports blocked or error enters the Attention queue and sends a desktop notification that names the pane, such as deploy needs input in build or cargo failed in build, at most once every 10 seconds per pane, when agent_panel.notify_when_agent_waiting allows it. An error entry leaves the queue once you have looked at the pane, while the pane header keeps error until you type in it.
  • A declared done or error stays until you type in the pane, while working, blocked, and idle clear when the shell prompt returns or the program exits, as the OSC 7501 spec requires. Text sent by paneflow send or write_pane does not count as typing.
  • A manual reset clears the declared status, the progress bar, and the title, like ESC c (RIS) does.
  • A burst of thousands of status reports in one write loses no transition; past a 256 KiB budget, Paneflow clears every declared status instead of keeping a partial one, and logs a warning.
  • Conformance suites such as vttest and esctest can get DECRQCRA checksum replies by setting terminal.xt_checksum_report to true, with the calculation tuned by terminal.xt_checksum_extension (0 to 31). Checksums stay off by default, because a program could otherwise read back the whole screen one cell at a time. An xt_checksum_extension outside 0 to 31 falls back to 0 with a warning naming the key, and the rest of paneflow.json still applies.
  • host.status reports how much memory each session's terminal holds, under resources.sessions[].memory: resident_bytes, virtual_bytes, compressed_bytes, image_bytes, and compression_supported. Every session is listed: one that has not started, has exited, or does not answer reports memory: null with not_started, exited, or timeout in memory_unavailable, never 0. All sessions are queried at once under one 500 ms deadline, so a reply with 64 stalled sessions still arrives in under 600 ms. See the work counters section of bench/README.md.

Changed

  • Agent status now comes only from OSC 7501. An agent's sidebar state, Attention queue entry, and notifications follow what it declares: working shows as working, blocked as waiting, idle and done as idle, and error as errored. Entering blocked or error sends a needs-input notification, and done after a turn sends a finished notification; idle sends none. An agent that declares nothing shows no turn status. paneflow send --submit and paneflow wait --idle follow the declared state.
  • A needs-input notification names the pane and its workspace, such as Claude Code needs input in build (backend), or only the one that has a name.
  • Reattaching to a session with a long scrollback stores the restored history compressed, so the desktop no longer holds a second uncompressed copy of the host's scrollback. In a 50,000-line test, the restored terminal's resident memory drops from about 35 MB to 1.3 MB. Scrolling into the history or searching it shows the same content as before, and after 2 seconds without activity the history is compressed again in small steps off the UI thread.
  • The pinned libghostty-vt archive moves from Ghostty 0c2a290d to b699ea79. Character widths follow Unicode 18.0.0 (uucode 9d555245), up from Unicode 17.0.0.

Fixed

  • On Windows, enlarging a pane no longer pulls lines back out of the scrollback, so the next output from ConPTY lands on the row it was meant for instead of being shifted.
  • Each character is drawn on its own cell. A narrow no-break space drawn from a fallback font, such as the thousands separator in a French dir listing, no longer pulls the following digits onto it, and text after an emoji or a CJK character no longer overlaps it.
  • A full-screen program that redraws with synchronized output (DEC mode 2026) shows exactly the frame it finished, never a half-drawn one, even when it ends one redraw and starts the next in the same write. A program that never ends its redraw still releases the screen after 150 ms. Scrolling or selecting during a redraw shows live content without replacing the finished frame, which comes back until the redraw ends.
  • Narrowing a pane whose last column holds the left half of an emoji or a CJK character no longer leaves that half behind, which could write past the row and crash the terminal.
  • After a resize, the cursor and the cursor a program saved keep their position and their pending line wrap, so the next character lands where the program expects, even after several widenings in a row.
  • Moving the cursor left with reverse wrap no longer jumps it to another row when the scroll region starts below the cursor.
  • Double-clicking either half of a wide character selects the whole word, a word selection no longer runs past a hard line break, and a triple-click on blank cells between two prompt marks no longer pulls in the neighboring prompt.
  • A character above U+00FF prints as itself in the DEC Special Graphics and British character sets, and a single shift (SS2, SS3) maps exactly one printed character.
  • CAN and SUB cancel an OSC in progress, so ESC ] 2 ; title followed by CAN no longer changes the title, and OSC indexes such as OSC 4 ; 1_0 are rejected instead of being read as 10.
  • ESC c (RIS) restores your theme's 256-color palette after a program changed it with OSC 4.
  • The ANSI form of DECRQM (CSI 4 $ p) is answered, and a query for a mode above 32767 is answered for that mode instead of aliasing a lower one.
  • Erasing a whole line clears the kitty graphics placeholder mark of that row.
  • A follower of paneflow sessions --follow or the Controller API receives each session's title with its events, so reconnecting after a worker restart no longer replays a row whose only change was its title.
  • On Windows, an agent started in a pane is recognized even when it prints nothing right after it starts; Paneflow looks at the pane again once its process list covers the launch.

Removed

  • Paneflow no longer reads agent status off the screen. The built-in screen.toml rules, local overrides in ~/.paneflow/runtimes/, the signed screen rule catalog and its download from GitHub Releases, paneflow agent capture, and paneflow agent explain are removed. The menu_attention_detection and agents.remote_screen_catalog settings are ignored, and ~/.paneflow/cache/screen-catalog/ can be deleted.
  • The terminal bell no longer puts an agent in the Attention queue, and attention_reason is gone from status --json. Pressing Escape in an agent pane no longer settles its turn on Paneflow's side.
  • Six built-in agents are gone: Antigravity, CodeBuddy, Cursor Agent, DeepSeek Harness, Kiro, and Qoder. Their launcher buttons, their PATH shims (agy, codebuddy, cursor-agent, dsh, kiro-cli, qodercli), their rows in Settings, and the Kiro conversations in the session sidebar are removed. A leftover *_button_visible key for one of them is ignored, and an agent_profiles entry based on one of them is skipped with a warning.

Install and validation

Download the signed artifacts from this release or use the installation instructions.

Every primary artifact carries a .sha256 sidecar and a minisign .minisig; each AppImage also ships an .AppImage.zsync for delta updates. 35 assets in total.

Pipeline: run 38094573398.

Legs that passed:

  • Build: x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, aarch64-apple-darwin, x86_64-pc-windows-msvc, each gated by cargo fmt --check and cargo clippy --workspace --locked --target <target> -- -D warnings
  • Release test gate on Linux x86_64: cargo test --workspace --locked
  • Package smoke tests: Debian 12 and Ubuntu 22.04 (.deb postinst), Fedora 40 and openSUSE Tumbleweed (.rpm postinst), Arch Linux (tar.gz binary), Windows MSI install and relay
  • Auto-update end to end on Linux x86_64

Full Changelog: https://github.com/arthjean/paneflow/compare/v0.17.6...v0.17.7

Contributors