Skip to content

v0.9.0Back to the changelog

Workspace tabs and dock editor

Released on .

Workspace tabs, and a real editor in the dock

Paneflow 0.9.0 rebuilds the surface hierarchy. A workspace now owns a list of tabs instead of a single layout tree, and a pane holds exactly one surface instead of its own tab strip, so the product goes from two nested tab levels to one, as Zellij, kitty, Ghostty and WezTerm already do. The diff dock gains a File tab hosting a real editor, so a file can be read and corrected next to the agent that wrote it. The third top-level mode, Agents, is removed: its sidebar, bottom panel and project store are gone, and the mode switch drops to CLI and Review.

Sessions written by 0.8.x are migrated on load, not rejected. No manual step is required to upgrade.

Workspace tabs

  • A workspace row in the CLI sidebar is now a collapsible folder, and each tab is a child row with inline rename, hover actions, and reordering and reattachment by id rather than by index.
  • Per-tab zoom and navigation keep their 0.8 mechanics, one level down.
  • The activity badge drops from the workspace to the tab, computed by filtering the workspace's sessions on the tab's terminal ids. A collapsed folder re-aggregates its children, so nothing hides.
  • New default bindings: secondary-] for next_tab and secondary-[ for previous_tab. secondary-alt-t (new_tab) and secondary-w (close_tab) keep their meaning at the new level, and secondary-tab still cycles workspaces, not tabs. secondary is Ctrl on Linux and Windows, Cmd on macOS.
  • A pane header replaces the in-pane tab strip: surface name, agent pill, and the pane actions. Cross-pane tab drag gestures are removed along with the stale positional index they addressed; splitting already covers the gesture.
  • "New pane" opens a preset picker over the three catalogs that already exist: the default shell, the visible agents, and the workspace custom buttons. No new key in paneflow.json.
  • Workspace tabs are capped at 32 (MAX_SESSION_TABS). A session file above the cap is truncated on load with a logged warning rather than rejected.

Editable file tabs in the diff dock

  • The dock's tab strip gains a File variant hosting a real editor. The document is a ropey::Rope loaded off-thread behind a generation guard, with guard rails on file size, giant lines, and non-textual bytes.
  • Highlighting is incremental and reuses the diff's own tree-sitter grammars, so a file gets the same colors in the editor and in the diff.
  • Editing covers native input and IME, undo and redo, clipboard, indentation, save with a modified marker, and a conflict path for the case where an agent rewrites the file underneath the cursor.
  • Rendering virtualizes to the visible rows, with a line-number gutter, vertical and horizontal scrolling, and no soft wrap.
  • File tabs cap at 8 (MAX_DIFF_FILE_TABS), evicting the oldest tab that is neither modified nor active. A modified tab asks for a second press before it closes.
  • New default bindings: secondary-g opens a file tab and secondary-j opens a terminal tab. Both are scoped off shells, text surfaces and the editor itself, where bare Ctrl+G means BEL and Ctrl+J means LF.
  • The dock is now reachable from a CLI pane. A git-pull-request button in the pane header toggles the dock on the pane's workspace root: pressing it again on the same folder closes the dock, a different folder retargets it. Previously the dock was reachable only from the Agents environment toolbar, which scoped it to a thread's working directory.

Files sidebar

  • Any row now opens a File tab. Previously only markdown opened and every other row was inert.
  • Rows the editor would refuse, because of a binary extension or a size above code::load::MAX_FILE_BYTES, stay dimmed but remain clickable, so the refusal is stated inside the tab instead of the click doing nothing.
  • Typing in the sidebar filters it, scored by the same matcher the agents sidebar used.

Theme presets

  • Themes become four presets, Paneflow, Vercel, Claude and Cursor, each in a light and a dark variant, so the identity and the light/dark axis are orthogonal. theme in paneflow.json stores the resolved variant, for example "Paneflow Dark" or "Vercel Light".
  • Pre-preset names keep working. One Dark, PaneFlow Light, Vercel, Claude and Cursor resolve through an alias table to the same pixels. An unknown name falls back to Paneflow Dark and logs a warning on the next parse.
  • The Themes settings page leads with three full-bleed window mockups for Light, Dark and System, followed by a live terminal sample painted from the active theme: prompt, build output, the ANSI swatch row, a selection run and the cursor. Switching a mode or a preset repaints the sample in place.
  • The shell neutrals are hue-free.
  • Notifications and the AI permissions cards fold into General, and the settings nav rail's first row becomes "Back to the app".

Added

  • reduce_motion in paneflow.json (also in Settings, Themes, Preferences). When enabled, hover transitions settle instantly and the primary sidebar toggles without the slide. Default false.
  • unfocused_pane_opacity in paneflow.json. Panes that do not hold focus fade to 70% opacity when a workspace holds more than one pane. Accepts 0.15 to 1.0, where 1.0 disables the dim. The tab bar, attention glow, broadcast stripe and Composer stay at full contrast.
  • CLI panes float as continuous-corner cards, with matching row skins and delayed tooltips across the app chrome.
  • A Linux-only application icon, plus a monochrome Codex mark and a leaner terminal glyph.
  • surface.* IPC methods export a stable workspace_id on every surface and accept an optional workspace_id parameter. A surface that does not belong to the requested workspace is rejected with an invalid_params error naming both ids. Omitting the parameter keeps the previous instance-wide behavior, and the positional index stays in the payload for older clients.
  • list_panes over the MCP bridge names the holding tab.
  • An agent session is reaped when its shell returns to the prompt.

Removed

  • The Agents view. The third top-level mode is gone, along with the agents sidebar, the agents bottom panel, the agents view actions, and the project store behind them. The mode switch drops to CLI and Review, and the secondary-shift-a binding for open_agents_view is removed. A session.json written by an older build restores in CLI mode with its workspaces intact. The CLI mode tab is now named "Agents".
  • The in-pane tab strip, replaced by the pane header described above.
  • The agent identity pill in the pane header, and the Files sidebar button in the pane header.
  • Rename from the workspace context menu.
  • Word-level intra-line highlighting in the diff.
  • The paneflow-acp crate and the Zed markdown global-theme bootstrap.

Changed

  • Session schema v2. A workspace session carries a list of TabSession rather than a single layout tree. v1 files are migrated on load: the legacy layout: null (one default pane) is materialized explicitly so it stops colliding with v2's layout: null (an empty tab). No action is needed on upgrade. Downgrading to 0.8.x after running 0.9.0 is not supported for session files.
  • BoundedOutput no longer returns partial data with a truncation flag. A run that exceeds the stdout or stderr capture limit fails with ProcError::OutputLimitExceeded, so a caller can never mistake a clipped payload for a complete one.
  • Editors and file managers launched from Paneflow are spawned detached, backed on Windows by a job object, so they are no longer torn down with the app.
  • Find-in-buffer in the terminal is chunked, cancellable and budgeted.
  • The agent identity is declared at launch instead of being discovered by scanning.
  • GPUI is pinned back to upstream zed-industries/zed and the Paneflow fork is retired. The fork carried a single additive Markdown::append patch whose only consumer was the deleted in-app chat. Only gpui and gpui_platform remain declared. The lockfile drops from 1129 to 851 packages. This affects builds from source only; shipped binaries are unaffected.

Security

  • Telemetry capture is gated behind a closed event schema. Call sites previously built PostHog payloads as free-form json!({...}), so nothing stopped a new event from carrying a path, a hostname, or a reserved PostHog processing key. TelemetryEvent is now the only way to name an event or attach properties, and the client owns the reserved keys outright, which turns the no-PII rule into a type-system invariant rather than a review convention. The client also gains a queue bounded on both event count and serialized bytes, and a shutdown flush with an explicit deadline.
  • The agent-config lease ownership bit is stored outside the locked file.

Fixed

  • Windows: the title bar minimum height is aligned with the Win11 caption strip.
  • Codex 0.149.1 user turns are read correctly, and subagent rollouts are dropped from the session list.
  • Synthetic Claude records no longer leak into sidebar titles, and a project slug with trailing separators is normalized.
  • Bound Claude sessions are resumed instead of re-minted.
  • The launching agent session's environment markers are stripped from child PTYs.
  • Every conflict-watcher wake in the code editor stays on the view's thread.
  • The branches popover in the diff stays anchored while its list scrolls.
  • The delete and clear icons paint instead of leaving blank space.
  • The tab-cycling chord assertion is platform-aware.

Upgrade notes

No action is required. Install over 0.8.x and launch.

  • Your session.json is migrated from v1 to v2 in place on first launch. Workspaces, layouts and working directories are preserved. If you were in Agents mode, you land in CLI mode.
  • Your paneflow.json needs no edit. A pre-preset theme value keeps resolving to the same colors; write the explicit variant name only if you want to pin one.
  • Scripts driving surface.* over IPC keep working unchanged. Pass the new workspace_id parameter only if you want a call scoped to one workspace.
  • The terminal backend selection and the packaging contract are unchanged: libghostty on Linux and Windows x64 MSVC, Alacritty on macOS and as the explicit rollback through terminal.backend.

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 33006523043.

Legs that passed:

  • Build: x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, aarch64-apple-darwin, x86_64-pc-windows-msvc
  • Release test gate on Linux x86_64: cargo fmt --check, cargo clippy --workspace --locked -- -D warnings, 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: v0.8.2...v0.9.0