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-]fornext_tabandsecondary-[forprevious_tab.secondary-alt-t(new_tab) andsecondary-w(close_tab) keep their meaning at the new level, andsecondary-tabstill cycles workspaces, not tabs.secondaryis 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
Filevariant hosting a real editor. The document is aropey::Ropeloaded 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-gopens a file tab andsecondary-jopens 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-requestbutton 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
Filetab. 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.
themeinpaneflow.jsonstores the resolved variant, for example"Paneflow Dark"or"Vercel Light". - Pre-preset names keep working.
One Dark,PaneFlow Light,Vercel,ClaudeandCursorresolve through an alias table to the same pixels. An unknown name falls back toPaneflow Darkand 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_motioninpaneflow.json(also in Settings, Themes, Preferences). When enabled, hover transitions settle instantly and the primary sidebar toggles without the slide. Defaultfalse.unfocused_pane_opacityinpaneflow.json. Panes that do not hold focus fade to 70% opacity when a workspace holds more than one pane. Accepts0.15to1.0, where1.0disables 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 stableworkspace_idon every surface and accept an optionalworkspace_idparameter. A surface that does not belong to the requested workspace is rejected with aninvalid_paramserror naming both ids. Omitting the parameter keeps the previous instance-wide behavior, and the positional index stays in the payload for older clients.list_panesover 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-abinding foropen_agents_viewis removed. Asession.jsonwritten 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-acpcrate and the Zed markdown global-theme bootstrap.
Changed
- Session schema v2. A workspace session carries a list of
TabSessionrather than a single layout tree. v1 files are migrated on load: the legacylayout: null(one default pane) is materialized explicitly so it stops colliding with v2'slayout: 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. BoundedOutputno longer returns partial data with a truncation flag. A run that exceeds the stdout or stderr capture limit fails withProcError::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/zedand the Paneflow fork is retired. The fork carried a single additiveMarkdown::appendpatch whose only consumer was the deleted in-app chat. Onlygpuiandgpui_platformremain 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.TelemetryEventis 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.jsonis 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.jsonneeds no edit. A pre-presetthemevalue 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 newworkspace_idparameter 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 (
.debpostinst), Fedora 40 and openSUSE Tumbleweed (.rpmpostinst), Arch Linux (tar.gzbinary), Windows MSI install and relay - Auto-update end to end on Linux x86_64
Full Changelog: v0.8.2...v0.9.0