Skip to content

ForkTTY 0.2.0-alpha.12

Pre-release
Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 12 Jun 23:18
· 106 commits to main since this release

[0.2.0-alpha.12] - 2026-06-13

Added

  • Terminal panes now show terse toasts for copy/paste failures and flash an accent border for visual bell events.
  • Terminal panes now show a minimal overlay scrollback indicator while viewing history.
  • Terminal content now has balanced 6px inner padding so text does not touch pane edges.
  • Split terminal panes now dim unfocused panes slightly so the focused pane is easier to pick out.
  • Ctrl+click opens links: OSC 8 hyperlinks and plain http(s):///file:// URLs in the output (also when wrapped across lines). Hovering with Ctrl held shows a pointer cursor and underlines the target.
  • Middle-click pastes the PRIMARY selection (select text, middle-click to paste — the standard Linux flow); Shift+middle-click pastes even inside mouse-tracking apps.
  • Shift+PageUp/PageDown page through the terminal scrollback, Shift+Home/End jump to its start/end; inside full-screen apps (vim, htop) the keys keep going to the app.
  • Typing or pasting in a scrolled-up terminal now snaps the viewport back to the bottom, like other terminals; output arriving while you read scrollback still leaves the viewport where it is.
  • Agent hook status updates now persist a per-surface agent session binding (agent + provider session_id) when metadata.set_status carries hook_session_id, plus the provider session cwd as resume_cwd when available, giving future resume work stable session state instead of a runtime-only hook cache.
  • Persisted agent session bindings now carry lifecycle state (running, idle, needs_input, ended, or unknown) derived from hook events, giving future hibernation/reclaim work an explicit ended-vs-idle signal.
  • Persisted agent session bindings now track hook-derived last_activity_ms, so automation can reason about idle age without scraping provider files.
  • agent.list, forktty agents, and the read-only MCP tool agent_list now expose persisted per-surface agent session ids, resume cwd, lifecycle, and last activity, so resume/HUD automation can discover Codex/Claude/Gemini/OpenCode/Antigravity sessions without scraping session-v2.json.
  • agent.health, forktty agent-health, and MCP agent_health now report whether persisted agent sessions have a supported argv-only resume command and provider executable on PATH before attempting a resume.
  • agent.reclaim.plan, forktty agent-reclaim-plan, and MCP agent_reclaim_plan now provide a read-only reclaim plan that classifies old idle, locally-resumable agent sessions as candidates and protects running/input-needed/ended/recent/not-ready sessions with explicit reasons.
  • agent.resume, forktty resume-agent, and MCP agent_resume now resume a persisted Codex, Claude Code, Gemini, OpenCode, or Antigravity session in a new ForkTTY tab using provider-specific argv-only commands.
  • Restored terminal surfaces with a persisted supported agent session now respawn through the provider's argv-only resume command instead of opening a plain shell after a ForkTTY restart; Codex sessions with a persisted hook cwd, or a cwd found in Codex's local session_meta JSONL, use codex resume -C <cwd> <id> to avoid Codex's resume-directory prompt when the pane cwd differs from the session cwd, and providers without a cwd flag such as Claude Code are spawned with the recorded cwd as their process directory.
  • status.summary, forktty statusline, and MCP status_summary now provide a compact read-only workspace summary with persisted agent sessions, status entries, and progress entries for agent statusline/HUD integrations.
  • The GTK app now has an Agent HUD in the titlebar and command palette, showing persisted agent sessions across workspaces with lifecycle, last activity, cwd/session context, needs-input highlighting, focus, and resume actions.
  • The Agent HUD updates live while open (one-second model re-snapshot that rebuilds rows only when they changed), shows each agent's last terminal output line refreshed in place (generation-gated so idle agents cost nothing), and its rows are keyboard-activatable — Enter or a click on a row focuses that agent's pane.
  • Agent HUD needs-input rows now show what the agent is actually waiting on (the hook prompt message, e.g. a permission request) instead of the raw terminal tail, and gain an inline reply entry that types the answer (plus Enter) straight into the agent's terminal without leaving the HUD; the list never rebuilds while a reply is being typed.
  • The MCP server now exposes a forktty://agent/operating-guide resource and a forktty_operating_guide prompt, plus matching initialize instructions, so agents can discover when ForkTTY tools are useful and when to keep working normally.
  • surface.read_text, surface.capture_tail, topology.tree, CLI forktty read-screen/capture-tail/tree, and MCP surface_read_text/surface_capture_tail/topology_tree now give agents read-only terminal inspection primitives before they focus or drive another pane.
  • forktty --json hooks doctor <agent> and forktty --json hooks test <agent> are now a stable machine-readable API (documented in SPEC.md): versioned report with an overall ok, per-method {method, ok, error?} results for hooks test (which keeps running after a failed method instead of aborting, so cleanup still happens and the report is complete), and exit code 0/1 reflecting overall health for CI gating. The Codex trust state stays a first-class field of the doctor report.
  • The worktree open-workspace boundary rejection now carries the structured error code precondition_failed (documented in SPEC.md), and MCP tool errors with a known recovery carry machine-readable remedy and suggested_tool fields in structuredContent — the boundary error points at workspace_create, so an agent can recover without parsing prose.

Changed

  • Touchpad scrolling in terminal panes now accumulates smooth deltas instead of forcing chunky wheel ticks.
  • The declared Rust MSRV is now 1.96, matching the current rusqlite/libsqlite3-sys dependency chain required by the workspace lockfile.
  • The competitive gap inventory now includes the non-browser cmux gaps plus the additional control-plane gaps found in oh-my-codex and oh-my-claudecode: workflow state/artifacts, team runtime, HUD/statusline export, and agent/skill catalogs.
  • Gemini CLI integrations are now legacy opt-in: default forktty hooks setup and forktty mcp setup skip Gemini and prefer Antigravity, while explicit Gemini setup/remove/doctor/test and persisted Gemini resume compatibility remain supported.
  • Claude Code session-start context now includes the same concise ForkTTY tool-use policy as the MCP operating guide: use ForkTTY for panes, agents, worktrees, status, or cross-surface text, but avoid tool calls for ordinary single-repo edits.

Fixed

  • Agent resume now preserves hook-reported bypassPermissions mode for Claude Code and Codex sessions: Claude resumes with --dangerously-skip-permissions, and Codex/yolo resumes with --dangerously-bypass-approvals-and-sandbox.
  • Copying a soft-wrapped line (a long command or paragraph the terminal wrapped to fit the width) no longer inserts a spurious newline at each wrap point: selection copy, the no-selection viewport copy, and select-all now rejoin soft-wrapped rows into their logical line, so pasting a wrapped command back into a shell runs it as one line instead of splitting it.
  • Selecting text by clicking an unfocused terminal pane no longer leaves the selection stuck following the pointer: the focus gesture claiming that first click used to cancel the selection drag without a release, stranding the selecting flag, so the highlight kept extending on every mouse move with no button held. The drag now finalizes on gesture cancel and whenever button 1 is no longer physically down.
  • Dragging a left-click selection in an agent pane (deferred local drag) no longer aborts the app with a RefCell already borrowed panic in the motion handler.
  • Terminal pane edge polish: double/triple-clicks and Ctrl+click/Ctrl+hover a few pixels into a pane's trailing gutter now select the last row/word and resolve last-row links instead of doing nothing; the pane being searched no longer dims while its search entry holds focus; middle-click or paste with an empty clipboard no longer shows a spurious "Paste failed" toast; and copying with an active selection still works when the terminal backend fails to render a frame.
  • Wayland touchpad scrolling in terminal panes no longer overscrolls roughly 30x: smooth-scroll deltas arrive in surface (logical pixel) units on Wayland and are now converted through the pane's cell height, while X11 smooth deltas and wheel ticks keep the 3-lines-per-tick mapping.
  • Scrolling inside mouse-tracking applications (vim, htop, tmux) now forwards one wheel press per three accumulated lines — matching physical-wheel speed — instead of one press per line, and hi-resolution wheels' fractional ticks accumulate into whole presses/lines instead of overscrolling on every fraction of a notch.
  • Mouse events in terminal padding now clamp to the nearest grid edge instead of reporting past the last cell to mouse-tracking applications.
  • Terminal copy failures no longer clear the existing clipboard contents, and the scrollback indicator no longer risks a panic during very small transient GTK allocations.
  • Terminal resize no longer aborts inside libghostty when GTK briefly reports a one-row allocation after wrapped output.
  • Terminal resize no longer aborts inside libghostty when maximizing a window with wrapped scrollback; the vendored Ghostty build now uses a temporary cursor-preservation pin and bounded wrap-count walks during column reflow.
  • Terminal mouse selection, Ctrl+click link detection, and mouse-tracking coordinates now account for the terminal widget's CSS padding, so highlighted/copied text lines up with the visible character grid.
  • Agent terminal panes now keep plain clicks working in mouse-tracking TUIs while treating a real left-button drag as local ForkTTY text selection, so Claude Code/OpenCode-style panes can select text without holding Shift.
  • Antigravity PreToolUse hooks now return an explicit {"decision":"approve"} response, and generated wrapper fallback scripts do the same, so ForkTTY status hooks no longer make agy deny every tool call when the hook response is parsed strictly.
  • Antigravity agent resume metadata now uses the hook payload's workspacePaths instead of the generated wrapper script cwd (~/.gemini/config), so agent-health reports the real project directory after agy publishes a new hook event.
  • Session restore path repair now uses the pane tree, not stale persisted surface metadata, to choose the owning workspace directory for browser/SSH surfaces whose saved cwd no longer exists.
  • Shell-trampoline detection for notification_command now catches env -u VAR sh -c ..., env --unset=VAR sh -c ..., and env -S "sh -c ..." wrappers instead of only plain env sh -c ....
  • Closed terminal panes no longer stay alive through GTK controller/search/context-menu reference cycles, so their PTY child and UI timers can be dropped.
  • Worktree merge failures now restore the checkout before returning an error, including failed fast-forward ref updates and failures after repo.merge(). If the merge commit was already created, a recovered finalization error no longer reports the merge as failed.
  • Large PTY writes now retry poll() interrupted by signals instead of treating EINTR as a fatal partial-paste error.
  • Config recovery no longer quarantines a valid config file on transient I/O errors such as permission/read failures.

The AppImage is the primary download for this alpha; the .deb remains available for Debian/Ubuntu users. Supported distros: see docs/QA.md.

Artifacts (AppImage, .deb, SHA256SUMS) are attached by CI after publish; verify with sha256sum -c SHA256SUMS.