Skip to content

Releases: Lucenx9/forktty

ForkTTY 0.2.0-alpha.18

Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 06 Jul 12:53

[0.2.0-alpha.18] - 2026-07-06

Added

  • Team workers can now persist a bounded final report through
    team.worker.upsert, CLI, and MCP; the report is returned by team.get,
    counted in team.summary, and surfaced in team.worker.health.
  • task.strategy.plan and task.strategy.apply responses now include
    planner_version so agents can record which ForkTTY planner produced or
    applied a routing decision.
  • Task strategy apply now bootstraps an initial planned workflow loop record
    for plans with layers.loop_metadata: true and context snapshots warn with
    loop_never_recorded when such workflows are finished without loop
    adoption evidence. The bootstrap now includes pending verifier-contract gates
    so loops start with explicit review/implementation/verification checks.
  • Task strategy apply now appends an advisory next-best-harness hint to
    assignment launchability and worker launch failures, naming the highest
    scored other ready harness for the same role so callers can retry without
    re-planning; apply never retries or substitutes harnesses on its own.
  • Task strategy harness_signals now accept an optional cooldown_kind
    (quota, auth, crash, or timeout) so the soft cooldown penalty scales
    with the cause instead of weighing every reason the same; unknown kinds and
    kinds without cooldown: true are rejected.
  • Task strategy planning now infers an advisory soft cooldown for a harness
    from ForkTTY's own workflow history (at least two recent failed
    task-strategy workflows naming that harness, cleared by a newer success),
    named in plan reasons and score factors; explicit harness_signals still
    replace inference for the harnesses they name.
  • Added dry-run-first orchestration.cleanup over socket, MCP
    orchestration_cleanup, and forktty cleanup orchestration so stale
    team/workflow records can be inspected and conservatively closed without
    touching live worker surfaces.
  • Added ergonomic workflow-loop CLI wrappers: workflow-loop-gate to merge one
    gate update, workflow-loop-step-done to mark a stage complete, and
    workflow-loop-publish to record a published commit stop reason without
    hand-writing the full gates array.
  • Added workflow-loop-iteration-start and workflow-loop-iteration-done
    wrappers so agents can advance bounded loop passes and record the pass result
    without hand-writing workflow.loop.set payloads.
  • Added read-only forktty worktree-doctor diagnostics that report repository
    and linked-worktree health without creating, pruning, merging, or removing
    any worktree state.
  • Added a short GETTING_STARTED.md walkthrough and docs/socket-api.md
    stability map so users and agents can distinguish stable-for-alpha socket
    calls from public alpha orchestration surfaces.
  • Added METRICS.md with manual attention-first UI quality targets for the
    Router rail and workflow feed.
  • Added an Attention-first UI smoke checklist to release QA so those metrics
    are exercised before alpha releases instead of remaining advisory only.
  • Extended METRICS.md and release QA with general anti-slop UI quality checks
    tied to the existing GTK visual rules.

Changed

  • Softened the orange status dots so they read as quiet ambient cues: warn
    .rail-dots (sidebar nav, worker/health, feed, pane footers) and the
    .pane-attention-dot now render at reduced opacity instead of full-strength
    orange.
  • Quietened neutral status indicators so only meaningful state carries colour:
    the workflow-feed "live" marker is now a small green dot plus a muted label
    instead of a filled green pill, and the Router status chip's idle/neutral
    state is plain muted text (transparent background/border) rather than a filled
    grey box — active ok/warn/err states keep their subtle tinted pill.
  • Consolidated the orchestration status-signal palette (rail dots, rail-strip
    badges, status chips, list rows, feed status) onto the shared semantic colour
    tokens: warn and error indicators now render the same warm-orange
    (@ft_warning) and danger red (@ft_danger) used elsewhere instead of two
    divergent gold/red hues, and the status blue is now the named @ft_info
    token — one hue per meaning across the whole app.
  • Agent-status badges in the sidebar (.workspace-status-badge) and pane
    headers (.pane-agent-badge) are now compact squared pills (5px radius,
    tighter padding, hairline border) instead of fully rounded chips: live/running
    reads sober green, needs-input/attention warm orange, idle/exited neutral
    grey.
  • Normalized corner radii to a tight 3-step scale (4px small controls, 6px
    buttons/badges, 8px cards/rows/dialogs, plus full-round pills), collapsing the
    previous ad-hoc mix of 4/5/6/7/8px so nested surfaces read as one system.
  • Aligned the workflow-feed / router status chips (live / idle / warn) to the
    token system: 6px radius, neutral surface + hairline tokens, and the warm
    accent for the warning state.
  • Refined the header count badges (notification/agent) to a compact squared
    chip on the sober warm accent, replacing the red/orange full-round dots.
  • Unified surface borders onto a single hairline color and evened out
    horizontal-padding drift, so cards, rows, and dialogs share one border weight
    and spacing rhythm instead of three near-identical grays.
  • Unified the "needs attention / needs input" accent across the app onto the
    warm-orange ForkTTY accent (#e88745/#eaa06a), replacing the inconsistent
    gold and peach tints previously used by the header attention button, sidebar
    needs-attention rail, needs-attention pane border/dot, inline warning status,
    and agent/notification prompt states. The distinct "current" row marker and
    keyboard focus rings are unchanged.
  • The GTK workbench now follows the agent-workspace layout end to end: the
    titlebar carries a Router cluster (breadcrumb, workspace selector, Plan and
    Review Plan shortcuts into the read-only Router planner) plus live team
    chips; the sidebar gains TEAM, RESOURCES, and Settings/About sections; the
    right-side rail shows an attention-first summary plus structured
    strategy/loop/approval/worker/report/notification rows with working
    Review/Deny on pending Feed approvals and a notifications Clear-all; the
    workflow feed gets wall-clock timestamps, per-kind status colors, filter
    tabs, and a Clear button; split panes gain a slim footer with the shell name
    and agent lifecycle; and the status bar summarizes the active Router strategy
    and loop.
  • The workflow feed now includes an ATTENTION tab that isolates approvals,
    errors, warnings, stale/conflict signals, and needs-input rows from routine
    workflow/log churn.
  • The sidebar Resources section now exposes only the implemented Worktrees
    shortcut instead of placeholder Knowledge Base, Snippets, Environments, and
    Secrets rows.
  • The Router rail and bottom workflow feed can now be collapsed from their
    headers for temporary workspace space recovery while the Settings toggles
    remain the persistent show/hide controls.
  • Reworked both collapsed states: the collapsed Router rail is a slim strip
    with an expand chevron plus pending-approval and unread-notification badges
    (and now stays collapsed even after the divider has been dragged), the rail
    header no longer scrolls away with the rail body, the workflow feed
    collapses with a slide animation and re-expands when a feed tab is clicked,
    collapse controls use chevron icons instead of ASCII arrows, and the rail
    status and feed "live" pills were restyled (status pill now colored by
    state instead of always green).
  • Settings follows the same agent-workspace pass: Interface gains live "Show
    orchestration rail" and "Show workflow feed" toggles (new
    appearance.show_orchestration_rail / appearance.show_workflow_feed
    config keys, default on), Worktrees links the worktree manager, Agents can
    re-scan provider readiness on demand, Notifications can clear the in-app
    history, and Privacy states the local-first guarantees and stored data
    locations next to the telemetry toggle.
  • team.finish now accepts compact/--compact to finalize teams without
    echoing the full team record and mailbox bodies in the response.
  • Team worker health now distinguishes workers that have no heartbeat plumbing
    from stale workers and uses persisted agent-session lifecycle evidence to
    report idle, needs_input, or done when hooks already recorded it.
  • The agent skill and operating guide now make verify-loop state recording
    part of the strategy contract: when an applied task-strategy plan sets
    layers.loop_metadata: true, apply seeds the initial planned loop record,
    and agents must update stage/iteration/gates each pass and record the stop
    reason at the end so loop_summaries can restore loop position after
    context compaction.
  • Reduced the always-sent ForkTTY MCP initialize instructions and task-strategy
    tool descriptions so agents get the routing essentials without duplicating
    the full operating guide; the complete guide remains available through the
    MCP resource and prompt.
  • forktty skills setup and forktty skills remove now retain only the three
    newest ForkTTY-managed skill backups per target and report pruned backups,
    while leaving unmanaged .bak-* directories untouched.
  • Task strategy planning now accepts normalized task_kind / task_class_hint
    aliases such as bugfix, feature, review, and research, so agents can
    pass clear user intent across languages without relying on ForkTTY keyword
    guessing or exact internal enum names.
  • Task strategy planning now treats explicit iterative goals such as repeat
    verification, iterative audits, and "keep checking until clean" as
    verify-loop work, and preserves review_only strategy for explicit review
    hints while still setting layers.loop_metadata: true; no hidden scheduler
    is started.
  • The Router rail loop row now shows ...
Read more

ForkTTY 0.2.0-alpha.17

Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 03 Jul 14:50

ForkTTY 0.2.0-alpha.17

Added

  • Added app actions exposed in the Command Palette for moving the active
    workspace up or down, with toast feedback when the workspace moves or is
    already at an edge.
  • Added a read-only task strategy planner for agents and CLI users so ForkTTY
    can recommend when to use solo work, workflow loops, reviewers, teams,
    worktrees, MCP, and hooks before launching visible agent work.
  • Added staged task strategy apply over socket, CLI, and MCP so an approved
    plan can create visible workflow/team/task/message coordination state without
    launching hidden workers or sending terminal input.
  • Added approved task.strategy.apply submit support for supported team plans
    so ForkTTY can launch visible worker panes and dispatch role prompts through
    the team mailbox, including worktree-layer plans when worktree_name names an
    already-open ForkTTY worktree workspace.
  • Added Feed-backed task strategy approval requests so task.strategy.apply
    can publish a pending start-run approval, stay blocked without workflow/team
    mutation, and later consume the approved request-bound approval_id.
  • Added task strategy safeguards so provider selection respects configured
    team provider order, reviewer strategies always include a reviewer role, and
    apply recomputes structural worktree and multi-worker submit approvals instead
    of trusting a client-provided plan approval list.
  • Added task strategy context inference so task.strategy.plan can derive
    dirty git state from the selected surface/workspace cwd when callers omit an
    explicit repo_dirty hint, and can infer likely user-visible edit intent
    from goal wording when callers omit an explicit user-visible hint.
  • Added an explicit task strategy planning cwd override for socket, CLI, and
    MCP callers whose real repository cwd differs from the selected ForkTTY pane.
  • Added ranked candidate strategy scores to task.strategy.plan responses so
    agents can see why ForkTTY selected a mode and which alternatives were
    considered before applying a plan.
  • Added role-aware harness assignment scores to task.strategy.plan responses
    so ForkTTY can prefer plan-mode reviewers and worktree-cwd-capable
    implementers while keeping configured provider order as a tie-break.
  • Added task router profiles (balanced, fast, conservative, parallel,
    and review_heavy) so task.strategy.plan, MCP task_strategy_plan, and
    forktty task-plan --profile can reweight the same explainable scorer
    without making users manually choose team, loop, worktree, or harness modes.
  • Added per-harness task routing signals so scripts and MCP agents can pass
    observed cooldowns as soft assignment penalties while hard task/mode lockouts
    exclude a harness from the selected plan.
  • Added advisory last-known-good task routing so task.strategy.plan, MCP,
    and forktty task-plan can infer prior successful strategy/harness evidence
    from completed task-strategy workflows or accept explicit caller evidence,
    then apply only a small explainable score bias without overriding readiness,
    cooldown, lockout, task fit, or approval rules.
  • Added Grok Build (grok) as a visible team/router harness with Settings,
    system.capabilities, team.worker.launch, and task-strategy routing
    support.

Changed

  • Reordered the main menu so the standard app items stay grouped, and the
    sidebar toggle now reports its shown/hidden state with a toast.
  • Improved dark UI shortcut contrast in custom menus and the Command Palette,
    and disabled workspace move commands when the active workspace is already at
    an edge.
  • Improved forktty task-plan --help, forktty task-apply --help, and
    forktty feed respond --help so task-router approval flows document their
    positional goals, plan JSON, cwd, and approval decisions directly.

Fixed

  • Fixed cargo audit failures by updating the Windows notification backend
    dependency so the lockfile no longer includes vulnerable quick-xml versions.
  • Fixed CLI boolean parsing so commands such as
    forktty task-plan --repo-dirty false --parallel false treat the following
    true/false token as the option value instead of silently leaving it in the
    positional task goal.
  • Fixed team.summary and compact context snapshots so workers whose terminal
    surfaces disappeared are no longer counted as active and now raise a
    consistency warning.
  • Fixed task strategy worker prompts so launched workers are told that the
    leader already applied the plan and must not call task.strategy.apply,
    launch nested workers, or create nested worktrees unless separately directed.
  • Fixed command argv validation so GNU env wrappers cannot hide shell
    trampolines behind -- NAME=VALUE assignments, -a/--argv0 arguments,
    -S/--split-string values that begin with --, or attached/clustered
    -Sstring and -vSstring split-string forms.
  • Fixed Feed persistence so corrupt feed.json files are quarantined instead
    of disabling the Feed on every launch, Feed saves are fsync-backed like the
    other stores, and approved approval rows are retained through notification
    churn so later task.strategy.apply retries can still consume them; prompt
    notification approval decisions are now preserved only for the same persisted
    prompt payload so a same-millisecond id collision after restart cannot inherit
    an old decision. Feed writes and recovery now also reject duplicate entry ids
    or inconsistent approval state instead of saving or loading ambiguous approval
    rows.
  • Fixed team store validation/recovery and ack idempotency so legacy duplicate
    persisted message ids are repaired on load by retaining the first message
    while preserving delivered/superseded terminal state, strict saves reject
    invalid state, and repeated message acknowledgements do not emit duplicate
    team.message.acked events.
  • Fixed team/workflow store mutation ordering so event sequence failures cannot
    leave in-memory plan, task, worker, or message updates partially applied
    before the store update is rejected.
  • Fixed team/workflow store caps so creating a new record can evict the oldest
    terminal done/closed/cancelled/finished record instead of leaving the
    store permanently full until manual JSON editing.
  • Fixed team.finish --close-workers so a worker surface close failure leaves
    team and worker store state unchanged instead of persisting partial shutdown
    requests or missing-surface worker cleanup before the error.
  • Fixed team.finish --close-workers so closing multiple worker panes restores
    any already-closed runtime surface if a later worker surface close fails,
    avoiding a half-closed visible team after an error.
  • Fixed team.finish --close-workers so closing a launch-owned worker pane that
    became the only pane in an inactive workspace still spawns the normal
    replacement terminal surface, and leaves the worker running if that
    replacement cannot be spawned.
  • Fixed team.worker.shutdown --close-surface so a worker surface close
    failure leaves the worker store state unchanged instead of persisting a
    partial shutdown request.
  • Fixed small GTK polish issues: failed worktree merge/remove notifications now
    appear as errors, multi-tab close confirmations say tab instead of pane,
    sidebar pane counts ignore extra tabs, context menu shortcut/copy icon hints
    are consistent, notification clear copy matches the action, and workspace
    popover buttons expose accessible names.
  • Fixed task strategy routing so parallel research/experiment plans respect
    each harness's declared parallel session capacity instead of assigning
    multiple concurrent roles to a single-session harness.
  • Fixed task strategy routing so a single launchable harness can provide
    multiple parallel research lanes when its declared session capacity permits
    it, instead of degrading to a non-parallel strategy.
  • Fixed task strategy routing so parallel research/experiment plans do not
    launch an eager synthesizer worker before researcher workers can produce
    output.
  • Fixed task strategy routing so review-requested implementer/reviewer plans
    no longer require worktree isolation in clean repositories unless dirty-repo
    edit isolation actually applies.
  • Fixed provider capability reporting so plan-mode support is exposed through
    system.capabilities and used by task-strategy reviewer scoring.
  • Fixed task strategy approval retries so an approved Feed request covering a
    superset of required approvals can still satisfy the remaining approvals when
    the caller also supplies explicit attestations for part of the same request.
  • Fixed task strategy submit retries so an existing live worker is reused only
    when its harness, role, task, worktree, and active worker status match the
    current deterministic assignment; blocked, idle, or needs-input workers now
    return conflict before any prompt dispatch.
  • Fixed task strategy apply so conflicting surface_id and leader_surface_id
    aliases are rejected before dirty-repo checks or workflow/team mutation.
  • Fixed task strategy planning so explicit cwd context is limited to Git
    repositories already represented by an open ForkTTY workspace, surface, or
    effective project cwd.
  • Fixed task strategy apply so explicit cwd launch targets must also be
    inside a Git repository already represented by an open ForkTTY workspace,
    surface, or effective project cwd before any workflow/team mutation.
  • Fixed task strategy apply so explicit cwd launch targets are canonicalized
    before worker launch, prompt generation, and submit-retry compatibility
    checks, keeping retries idempotent when callers switch between symlinked and
    real paths for the same open repository.
  • Fixed task strategy apply so camelCase workspace selector aliases such as
    workspaceId and worktreeName target the same workspace for dirty-repo
    inference and workflow/team mutation instead of ...
Read more

ForkTTY 0.2.0-alpha.16

Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 27 Jun 17:59

ForkTTY 0.2.0-alpha.16 is an alpha release focused on socket/team/workspace reliability, AppImage hook/MCP setup, clean GTK shutdown, and disabled PTY-persistence cleanup.

Highlights

Fixed

  • Fixed GTK window close so the embedded Unix-socket server receives a shutdown signal instead of keeping the ForkTTY GUI/AppImage process alive after the last window is closed.
  • Fixed hook and MCP setup from AppImage launches so generated ForkTTY CLI commands set APPIMAGE_EXTRACT_AND_RUN=1, preventing short hook calls and persistent MCP servers from leaving FUSE AppImage runtime mounts behind.
  • Fixed AppImage terminal launches with opt-in PTY process persistence so detached dtach brokers do not inherit AppImage runtime file descriptors and keep the FUSE mount alive after the GTK window closes.
  • Fixed opt-in PTY process persistence cleanup so disabling the setting, starting with it disabled, explicitly closing/restarting a pane, or closing the GTK window after disabling persistence terminates stale ForkTTY-managed dtach brokers and their child process trees instead of leaving detached terminals behind.
  • Fixed generated OpenCode hook plugins so they contain valid JavaScript constants instead of Rust visibility prefixes.
  • Fixed official CLI/MCP socket clients timing out before slower server-side operations complete or rejecting valid bounded responses larger than 1 MiB.
  • Fixed team.message.dispatch so concurrent or post-send/failed-ack retries of the same queued message do not write the prompt to a terminal twice.
  • Fixed duplicate team.worker.launch calls for the same live launch-owned worker so the second call fails before leaving an orphaned worker pane.
  • Fixed workspace.close and worktree.remove rollback and surface-set races so failed or concurrent close operations cannot leave orphan terminal runtimes behind.
  • Fixed team and workflow store updates to coordinate through per-store lock files, preventing lost updates when multiple ForkTTY processes share a state directory, and moved socket store I/O onto Tokio's blocking pool so slow filesystems do not stall unrelated socket requests.
  • Fixed events.subscribe validation for non-boolean replay values and capped event subscribers separately from the general socket request budget.
  • Fixed MCP tool metadata and SPEC.md drift for workflow loop state and non-idempotent team heartbeat/ack operations.
  • Fixed Antigravity hook setup so the generated PreInvocation entry uses Antigravity's flat lifecycle-hook handler shape instead of the nested tool-hook matcher shape, allowing ForkTTY's before-model wrapper to load.

Security

  • Restricted opt-in PTY process persistence to explicitly plain interactive terminal shell spawns so project actions and team-worker provider commands cannot be wrapped in dtach and outlive their visible pane unexpectedly.

Artifacts

  • forktty-0.2.0-alpha.16-x86_64.AppImage
  • forktty-0.2.0-alpha.16-x86_64.AppImage.zsync
  • forktty_0.2.0.alpha.16_amd64.deb
  • SHA256SUMS

SHA256

  • 0bc6a755b5860b849deefe32aa15ffead6909224c73c2c8605a2eb3a23366daf forktty-0.2.0-alpha.16-x86_64.AppImage
  • 98900d471e9738cf6de4263060d11facc97d78f516caca24ff52eeae72bc7b37 forktty-0.2.0-alpha.16-x86_64.AppImage.zsync
  • ddea003b25501b49886f90b0fcc8af15a52cd797b2027f87b9e87283143f9992 forktty_0.2.0.alpha.16_amd64.deb

ForkTTY 0.2.0-alpha.15

Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 23 Jun 13:42

Added

  • Opt-in real PTY/process persistence for generic terminal panes via a new
    general.persist_terminal_processes config flag (default off). When enabled
    and a detach/reattach broker (dtach) is on PATH, plain interactive
    terminals run under the broker so their process tree (shell, dev servers,
    REPLs, editors, long-running commands) survives a GTK UI restart; a relaunch
    re-attaches the same surface to its still-running processes, keyed by the
    persisted surface id. Agent panes (provider resume), SSH, and browser surfaces
    are unaffected, and behavior is unchanged when the flag is off or no broker is
    installed. The broker socket lives under the owner-only per-user runtime dir
    and ForkTTY never wraps a sh -c command. system.capabilities and
    forktty capabilities report whether the flag is configured and whether a
    broker is currently available. Explicit ForkTTY pane close/restart removes
    the per-surface broker socket so a later reused surface id starts fresh
    instead of re-attaching to a stale detached session. Settings > Worktrees now
    exposes a "Persist terminal processes" toggle and shows whether dtach is
    available from the running ForkTTY environment.
  • CLI automation now includes high-level forktty team ask/watch/finish/review
    wrappers, forktty status explain/watch, a context-snapshot alias, grouped
    help/examples, and generated bash/zsh/fish completions.
  • forktty skills setup now installs a ForkTTY agent orchestration skill for
    Agent Skills-compatible tools (~/.agents/skills) and Claude Code
    (~/.claude/skills) so agents have an explicit policy for proactively using
    ForkTTY MCP, hooks, context snapshots, and team workers.
  • Socket context.snapshot and MCP context_snapshot now provide a compact
    read-only workspace snapshot with pane/surface state, status, agent health,
    compact workflow/team/feed/remote summaries, and bounded untrusted terminal
    tails. Full workflow and team records are opt-in.
  • system.capabilities now advertises a provider capability matrix for the
    supported team/resume providers (codex, claude, pi, opencode, and
    antigravity) so socket and MCP clients do not need to infer provider support
    by trial and error.
  • Agent rows returned by agent.list, agent.health, status.summary, and
    context.snapshot now include lifecycle_evidence, a compact diagnostic
    block that correlates the persisted lifecycle, freshness timestamps, current
    workspace/provider status row, permission mode, and resume-readiness reason
    where available.
  • Socket/MCP/CLI automation now includes system.identify/identify for a
    compact canonical workspace/surface/effective-project-cwd read, and CLI
    automation adds forktty wait agent-status for bounded read-only polling of
    persisted agent lifecycle state through short context.snapshot reads.
  • Pi is now a supported team/resume provider: team launch accepts --agent pi,
    agent resume uses pi --session <id>, forktty skills setup pi aliases the
    interoperable Agent Skills target, and Pi review workers default to read-only
    --tools read,grep,find,ls unless explicit Pi tool args are supplied.
  • Team message dispatch now supports an explicit submit mode through socket
    team.message.dispatch (submit: true), MCP team_message_dispatch, and
    CLI forktty team-message-dispatch --submit, appending a carriage-return
    Enter to the dispatched terminal input when the message does not already end
    in carriage return.
  • Socket/MCP/CLI automation now includes team.finish / team_finish /
    forktty team finish to verify team state, optionally close current-runtime
    launch-owned disposable worker panes, normalize missing worker surfaces, and
    mark the team done in one finalization step.
  • Workflow automation now includes bounded closed-loop state through socket
    workflow.loop.set, MCP workflow_loop_set, and CLI
    forktty workflow-loop-set: agents can record a loop recipe, stage,
    iteration budget, stop reason, and verification gate counts without granting
    ForkTTY any background scheduler or automatic command execution.
  • Team worker launch now supports configurable provider auto-selection:
    Settings > Agents exposes the default provider, fallback, provider order,
    disabled providers, PATH detection, and direct command overrides for
    non-default harness install locations; socket/MCP/CLI launches can omit
    agent or pass auto, and successful launches report the selected provider
    and considered candidates.

Changed

  • ForkTTY config no longer emits the obsolete general.theme_source key;
    existing files that still contain it continue to load, and terminal theme
    preferences remain owned by Ghostty config.
  • Command Palette, GTK context menus, Keyboard Shortcuts, About ForkTTY, and
    Settings have been polished for clearer shortcut labeling, standard menu
    access (F10 outside terminal focus), richer About links, and correct
    initial focus when opening directly to the Agents settings page.
  • AGENTS.md now reflects the current MCP/team/workflow/skill/AppImage
    maintenance flow, including final-binary skill checksum verification.
  • Agent HUD rows now show a compact workflow loop chip when a visible agent
    surface is bound to closed-loop workflow state, with gate failures and
    human-attention stops highlighted without adding a separate loop panel.
  • Pane drag-and-drop now exposes a visible header grip and tooltip clarifying
    that dragging a pane header swaps panes.
  • Tab drag-and-drop now starts from the tab grip instead of the whole tab,
    reducing accidental drags while selecting or closing tabs.
  • Notification panel and Agent HUD polish now make attention states easier to
    scan: notifications group prompt/current-workspace history, avoid a duplicate
    global open action, and use quieter tonal cards/chips/action areas; agent
    rows show the current pane, group lifecycles, surface risky permission modes,
    compact ended sessions, calmer status chips, compact risky permission labels,
    and inline terminal previews.
  • Agent-oriented workspace chrome now uses more human scan labels and targets:
    running agent rows/badges read as Working, ended rows read as Done, sidebar
    metadata suppresses standing permission-mode noise, workspace paths prefer a
    tracked agent resume_cwd when it differs from the launch directory,
    notification jump prioritizes unread prompts, and high-level team CLI output
    reports the worker, task, surface, provider, and submit state.
  • GTK chrome micro-polish now aligns workspace badges, pane action hover/focus
    states, sidebar actions, status shortcuts, and pane hairlines with the quieter
    Agent HUD and notification panel treatment.

Fixed

  • AppImages now prefer the host GTK/libadwaita stack when it is available and
    keep the bundled GTK copy as a fallback/override
    (FORKTTY_APPIMAGE_GTK_RUNTIME=bundled|host|auto), preventing the Ubuntu
    release bundle's GTK 4.14 runtime from failing embedded Ghostty OpenGL context
    creation on newer desktop stacks.
  • Notification cleanup now stays coherent across surfaces: clearing through the
    socket or notification panel closes matching desktop notifications, sends OSC
    99 close reports when the terminal requested them, and marks pending prompt
    approval feed rows as dismissed; stale prompt approvals whose target
    workspace/surface disappeared now report approval_state: "stale" and no
    longer raise pending_approval risk flags.
  • Workspace/surface-targeted desktop notifications now expose a best-effort
    default Open action that focuses the relevant ForkTTY surface or workspace,
    while terminal notification action buttons carry accessible labels and
    app-authored notification chips use the clearer App label.
  • Team message dispatch and worker shutdown submit mode now use
    provider-aware input: Claude receives staged text, a short settle, and a
    separate Enter, while other providers keep text plus carriage-return Enter in
    one terminal input.
  • Context snapshots now include compact loop_summaries rows for workflow
    loops, including stale surface-binding detection and risk flags for failed
    gates, blocked/needs-human stages, exhausted loop budgets, and stale
    workflow surface bindings; the rows omit full workflow goals and detailed
    gate notes so default snapshots stay compact.
  • Workflow loop iteration updates now clear prior gate results and stop reasons
    unless the same request supplies replacements, preventing stale failed gates
    from carrying into a new verification pass.
  • Workflow consistency warnings now treat completed plan steps as terminal,
    matching existing workflow records and avoiding false done_with_open_plan_steps
    risk flags in compact context snapshots.
  • CLI routing now recognizes forktty workflow-loop-set and its socket-style
    aliases, so the documented wrapper reaches workflow.loop.set instead of
    being rejected as an unknown argument.
  • Worktree socket/CLI/MCP operations now ignore hook-reported agent resume_cwd
    metadata for repository authorization and only trust visible workspace roots
    plus the recorded cwd of open surfaces, preventing spoofed hook metadata from
    authorizing hidden worktree operations in unopened repositories.
  • Team worker launch no longer copies a leader's hook-reported resume_cwd into
    the new worker surface cwd, preventing spoofed agent metadata from being
    promoted into the worktree authorization boundary through a visible worker
    tab.
  • CLI routing now accepts socket-style worktree.* and project.action.*
    aliases in addition to the documented dash/colon forms, keeping low-level
    worktree and project-action wrappers consistent with other socket methods.
  • team.summary now flags active teams that have no active workers, open tasks,
    or pending messages as active_without_open_work, so stale orchestration
    records are visible before an agent mistakes...
Read more

ForkTTY 0.2.0-alpha.14

Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 19 Jun 21:17

[0.2.0-alpha.14] - 2026-06-19

Fixed

  • Embedded Ghostty terminal panes no longer force GTK's cairo software
    renderer, which leaked multi-GiB of live, malloc_trim-immune heap while
    compositing the embedded Ghostty GtkGLArea every frame (most visible during
    long full-screen agent TUI sessions such as Codex; idle and standalone
    Ghostty were unaffected). ForkTTY now defaults GSK_RENDERER to the GL
    renderer (ngl), which composites the GLArea natively with no such growth.
    An explicit GSK_RENDERER override is still honored for QA/debugging.
  • Embedded Ghostty panes no longer cap their redraw tick at ~10fps during
    continuous output. That 100ms floor was a throttle against the old cairo
    software-renderer leak; with the GL renderer default it only added latency,
    so the tick now follows the 16ms wakeup-check cadence and GTK's frame clock.
  • AppImage packaging now bundles and verifies the runtime dependencies of the
    embedded Ghostty GTK library itself, not only the main ForkTTY binary, so
    GitHub-built AppImages do not ship smaller artifacts whose terminal panes
    fail to start on distributions missing those libraries system-wide.
  • Embedded Ghostty panes now follow Ghostty's scrollback-limit config, falling
    back to Ghostty's bounded default budget (10 MB per surface) instead of
    disabling retained history, so mouse-wheel scrollback works in freshly opened
    terminal panes.
  • Embedded Ghostty panes now pack the raw Ghostty surface inside a GTK scrolled
    window and honor Ghostty's scrollbar = system|never config, so retained
    scrollback has the same visible vertical scrollbar behavior as standalone
    Ghostty.
  • Agent health, explicit resume, and restore-time auto-resume now preserve
    hook-reported bypassPermissions sessions for Codex and Claude Code by
    rebuilding argv with the providers' documented dangerous-mode flags
    (codex --dangerously-bypass-approvals-and-sandbox resume ... and
    claude --dangerously-skip-permissions --resume ...) instead of silently
    resuming those panes back in prompted mode.

Security

  • Rejected control characters in restored session identifiers and embedded
    Ghostty command-spawn values so tampered session state cannot influence
    terminal child argv or environment setup.
  • Hardened embedded Ghostty GTK library loading by canonicalizing candidate
    paths and rejecting relative paths, non-regular files, untrusted ownership,
    or group/other-writable files and parent directories before dlopen, while
    allowing packaged AppImage libraries below sticky /tmp mounts.
  • Limited OSC99 terminal notification icon dimensions before decoding or
    forwarding image data to desktop notification servers.
  • Kitty image snapshots now copy and downsample only the rendered pixel
    footprint for each placement and use fallible render-buffer allocation,
    preventing malicious terminal output from forcing full-source-image
    per-placement copies on every redraw.

Changed

  • Settings and newly saved configs no longer expose Ghostty-owned terminal
    appearance/runtime controls (font_family, font_size, scrollback_lines,
    terminal_audible_bell, terminal_renderer, terminal_theme). Those TOML
    keys still load for compatibility, but ForkTTY now leaves font, theme, bell,
    and terminal rendering behavior to Ghostty's config and keeps only
    ForkTTY-owned settings in the visible UI.
  • ForkTTY documentation, package metadata, first-run privacy link, and the
    anonymous telemetry endpoint now use the canonical https://forktty.dev
    domain.
  • Documented the .deb runtime baseline as Debian 13/Trixie+ and Ubuntu
    24.04 LTS+, and added a repeatable piuparts install/purge release check.
  • Clarified privacy/security documentation around the anonymous daily ping,
    update checks, and packaged source/license availability.
  • App dialogs now use tighter shared spacing, shorter copy, and calmer inline
    actions across the command palette, shortcuts, worktree, and notification
    panels.
  • The Agent HUD now uses a calmer dense-card layout with compact actions,
    subtler status pills, and terminal-like output snippets.
  • The About dialog now uses a more compact identity layout, calmer metadata
    rows, and lighter action buttons.
  • App chrome now uses quieter top/status bars, subtler split-pane focus,
    softer per-pane tabs, and less intrusive pane/browser toolbars.
  • Sidebar navigation, popovers, badges, and terminal empty/error states now use
    calmer density, shorter copy, and less dominant status styling.
  • Settings now use a clamped, denser layout with calmer inline actions, and the
    Agents page presents one recommended integration action plus advanced
    per-component actions.
  • The welcome dialog's agent setup action now opens Settings directly on the
    Agents page, so first-time setup shows installed/update state before writing
    provider configuration files.
  • Settings no longer exposes a shell editor; advanced users can still set
    general.shell manually in config.toml, while the dialog focuses on
    ForkTTY-owned behavior and appearance.

Fixed

  • Embedded Ghostty panes now disable cursor blinking in the embedded runtime
    and drain Ghostty's app mailbox from a wakeup callback instead of polling
    ghostty_gtk_context_tick() while idle, preventing background memory growth
    even when no terminal output is being rendered.
  • Embedded Ghostty panes now coalesce continuous wakeups before ticking
    Ghostty's GTK app mailbox, avoiding redundant GTK runtime work during bursty
    terminal output.
  • AppImages now prefer the bundled usr/lib/ghostty-gtk-embed.so before any
    development checkout under vendor/ghostty, so package smoke tests and user
    runs exercise the same embedded Ghostty library unless explicitly overridden
    with FORKTTY_GHOSTTY_GTK_LIB.
  • First-launch onboarding now describes the default workspace as the user's
    home directory instead of the process current directory, matching the actual
    startup behavior.
  • AppImages now bundle libgtk4-layer-shell.so beside the embedded Ghostty
    GTK library, and Debian packages now declare libgtk4-layer-shell0, so
    terminal panes can start on systems such as Fedora that do not have
    gtk4-layer-shell installed globally.
  • AppRun now always uses the bundled GTK/libadwaita userspace stack, while
    still leaving glibc, fontconfig/text shaping, display-server libraries, and
    GPU drivers host-side, so AppImages no longer depend on host GTK packages.
  • Debian and AppImage packaging now include ForkTTY copyright/license text and
    third-party notices for the vendored Ghostty runtime artifacts.
  • Embedded Ghostty terminals launched from the AppImage no longer leak the
    AppImage runtime environment (LD_LIBRARY_PATH, APPDIR/APPIMAGE/OWD,
    and GTK/GObject module search paths) into spawned children, so a child
    process such as git, an editor, or an agent links against the host's
    libraries instead of the AppImage's bundled copies. XDG_DATA_DIRS is left
    intact because Ghostty's own shell integration depends on it.
  • AppImage and Debian packages now include Ghostty's bundled themes, so
    embedded Ghostty panes can resolve user configs such as
    theme = Catppuccin Mocha instead of falling back to the default colors.
  • Embedded Ghostty panes now keep the cursor blink timer disabled while the
    rendered terminal state uses a steady cursor, preventing idle OpenGL redraws
    from steadily growing RSS for Ghostty configs such as
    cursor-style-blink = false.
  • The embedded Ghostty GTK library probe now builds Ghostty with the stable
    ReleaseSafe optimization profile and a linker-compatible Blueprint helper,
    avoiding local Zig/GCC .sframe linker failures and ReleaseFast
    startup crashes when running ForkTTY from cargo.
  • Refined the per-pane tab close button styling so hover changes only the X
    color instead of drawing a filled control around it.
  • Embedded Ghostty panes now focus the terminal's internal focusable widget
    after new workspace, tab, split, or pane-header selection, so typing reaches
    the newly focused pane without an extra click inside the terminal.
  • Dialogs now handle Escape in capture phase, so command palette and other
    dialogs close even when a search field or text entry has focus.
  • Embedded Ghostty panes now use a native command-spawn ABI when the bundled
    library supports it, so per-surface FORKTTY_* environment setup no longer
    appears as a typed exec /usr/bin/env ... command in every new workspace.
    Older embedding libraries now start Ghostty's default shell without the
    ForkTTY environment instead of typing a bootstrap command into the terminal.
  • Embedded Ghostty socket text reads now use a bounded GTK ABI when the
    embedding library supports it, so read_text/capture_tail requests do not
    ask Ghostty to materialize unbounded scrollback in ForkTTY before response
    truncation.
  • Embedded Ghostty scrollback tail capture (tail_text) now returns an empty
    string for a zero-column terminal instead of erroring on an out-of-bounds grid
    reference, matching the existing guard in visible_screen_rows.
  • Failed agent.hibernate close attempts now restore the previous unread bit
    and status entry instead of leaving the running surface shown as suspended.
  • Pending embedded Ghostty spawns now lose their orphan-reaper protection
    after one reconciliation if their backend surface never appears in the
    model, preventing hidden PTY/widget processes from surviving a
    spawn/model-removal race.
  • Bounded the forktty remote-helper pty stdin relay queue so
    non-draining PTY children apply backpressure instead of allowing unbounded
    memory growth.
  • Feed approval rows now use durable notification feed IDs and avoid carrying
    approval decisions across newer entries with reused transient notification
    IDs.
  • The socket CLI now writes all success output through the broken-pipe-aware
    writer, so piping a command into a consumer ...
Read more

ForkTTY 0.2.0-alpha.13

Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 16 Jun 12:59

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

Security

  • Stop hooks now preserve agent permission-mode warnings when the provider has a later session-end cleanup, while providers without session-end hooks still clear the warning on final stop.
  • Terminal smooth-scroll handling now rejects non-finite deltas and caps per-event line replay, preventing oversized synthetic scroll events from monopolizing the UI thread while mouse tracking is active.
  • Browser automation now injects and evaluates its driver in an isolated WebKit script world, preventing visited pages from detecting or tampering with window.__forktty.
  • Chromium cookie import now verifies the version-24+ encrypted host digest before accepting decrypted values, rejecting malformed or cross-host cookie rows.
  • Agent resume PTY spawns now resolve bare provider commands using only absolute PATH entries before applying the recorded session cwd, preventing relative/empty PATH entries from executing project-local binaries during restore or resume.
  • Socket hook correlation now rejects hook_session_id values larger than the metadata text limit before caching them, preventing a local client from retaining many near-request-size session IDs in memory.
  • Socket-triggered notification dispatch and custom notification command reaping now use bounded queues instead of spawning unbounded OS threads per notification.create, preventing a local client from exhausting threads by flooding notifications.

Added

  • forktty doctor now accepts --hooks, --socket, and --packaging scopes for running only the relevant local diagnostics.
  • First launch now shows a one-time welcome dialog: an informed (default-on) telemetry toggle linking to the privacy notice, and a one-click "Set up agent integration" button that runs hooks setup and mcp setup. The first anonymous ping is deferred until this dialog is dismissed, so the toggle is always seen before any data leaves the machine; the welcome is recorded in $XDG_STATE_HOME/forktty/welcome-seen.json and the update check is skipped on that first launch.
  • The GTK app now sends at most one anonymous daily usage ping when telemetry.anonymous_ping = true (the default). The payload contains only schema/kind/app/version/date, can be disabled in Settings or config, and crash uploads remain unimplemented.
  • The GTK app now checks GitHub Releases at most once per day when updates.auto_check = true, shows update availability in-app, opens the release page for non-AppImage installs, and can self-update writable AppImages after explicit confirmation by downloading the AppImage plus SHA256SUMS, verifying SHA256, and atomically replacing the current file.
  • Release AppImages can now embed AppImage update information and ship a matching .zsync asset when APPIMAGE_UPDATE_INFO=1 is used during packaging; release CI enables this and includes .zsync in SHA256SUMS.
  • Agent HUD rows now include a Forget action with Undo, so stale tracked sessions can be removed from the HUD without closing the terminal or deleting provider data.
  • Agent HUD rows now show an accent unread dot when an agent has produced output you have not viewed since last focusing it, and float those rows up within their lifecycle group — so a finished (idle) agent whose result is still unseen stands out instead of sinking to the bottom of the list.

Fixed

  • The terminal pane header now keeps the Close Pane button on the far right of split-pane headers instead of clustering it beside the split and new-tab actions.
  • Worktree list/status reporting now treats registered worktree paths replaced by files, symlinks, or invalid directories as unknown instead of clean/dirty.
  • Command palette and Settings selection states now use neutral row highlights instead of heavy accent rails.
  • Settings toggles are now smaller and use a subtler checked state.
  • Settings sidebar navigation is now more compact, with item descriptions kept in tooltips and accessibility labels instead of visible subtitles.
  • Settings pages now use shorter page and section copy, hiding redundant section descriptions.
  • Settings, Agent HUD, and Notifications now expose a maximize/restore titlebar control and enforce minimum window sizes, while Command Palette windows stay fixed-size.
  • Settings now labels the privacy and reset page as Privacy instead of Advanced.
  • Agent HUD now relies on its titlebar close button and Esc instead of showing a duplicate Close footer button.
  • Agent HUD now opens shorter when sessions are present, keeps its empty state unclipped, uses flatter rows, and gives row actions clearer visual hierarchy.
  • Worktree merge selected by worktree name now merges that worktree's branch even when an unrelated local branch shares the worktree's derived name (e.g. worktree feat-a for branch feat/a alongside a separate feat-a branch), matching the worktree the cleanliness check already validates instead of silently merging the wrong branch.
  • Config loading now normalizes a notification_command that tokenizes to zero words (for example an inline shell comment like "# disabled") to an empty command instead of rejecting it and quarantining the entire config, so a benign command value no longer resets every other setting to defaults.
  • Nested worktree creation now appends .worktrees/ to .git/info/exclude even when the existing exclude file contains non-UTF-8 bytes, instead of failing before creating the worktree.
  • Agent session-end hooks now mark the persisted agent binding as ended when clearing its live status, so agents whose providers emit a session-end event no longer remain shown as running in the Agent HUD.
  • Chromium bookmark import, browser bookmark loading, and browser profile metadata loading now reject or skip non-regular files before reading, preventing local FIFO/device paths from blocking the import or profile workflows.
  • Socket metadata calls now reject stale explicit surface_id values even when workspace_id is valid, oversized request lines return the documented payload_too_large code, and invalid parameter errors use the documented invalid_param code.
  • Config recovery now quarantines config paths that resolve to FIFOs without blocking application startup.
  • Worktree create now propagates branch lookup errors other than NotFound instead of treating every libgit2 failure as a missing branch.
  • Creating or attaching a worktree whose registration survived an external deletion of its working directory now prunes the stale registration and recreates the worktree in place, instead of failing with an unresolved-path error; create adopts the existing branch in this case and never deletes a pre-existing branch during cleanup.
  • ProfileStore::save now creates the browser_profiles directory with owner-only (0700) permissions instead of inheriting the umask, so profile metadata is not world-readable on multi-user systems when the directory is first created via the socket API.
  • ProfileStore::save now hardens an existing browser_profiles directory owned by the current uid/gid by removing group/other permission bits before writing profile metadata.
  • Browser import spooling now uses anonymous (unlinked) temp files instead of named temp files, so spooled pre-read data is reclaimed automatically if the process is killed mid-import.
  • Browser imports now spool pre-read source data to temporary files instead of retaining every selected profile in memory, preventing large all-source imports from exhausting memory while preserving all-or-nothing read validation before writes begin.
  • Update checks now honor HTTP-date Retry-After headers from GitHub rate-limit responses instead of retrying before the requested deadline.
  • Restarting an agent pane now resumes the agent session (provider resume argv and recorded cwd) instead of relaunching a plain shell, matching the session-restore and worktree spawn paths.
  • Session restore now quarantines a session file containing invalid UTF-8 instead of returning an error that crashed startup on every launch.
  • The first-run welcome dialog now stays open when persisting a telemetry opt-out fails (e.g. a read-only config directory), so it cannot silently fall back to the default-enabled ping without giving the user a chance to fix permissions or re-enable telemetry.
  • Saving browser bookmarks now creates the profile directory with owner-only (0700) permissions instead of inheriting the umask, matching the history database directory, so bookmark URLs are not exposed when a profile's first write is a bookmark.
  • Bookmark entries now bound the stored URL and title to the same size caps as history visits, preventing an oversized imported bookmark from growing bookmarks.json until it becomes unreadable.
  • Shell trampoline detection now keeps scanning after shell options that take a value, so bash -o vi -c ... and bash --rcfile file -c ... notification commands are rejected instead of bypassing the -c guard.
  • Shell trampoline detection now recognizes PowerShell's command grammar, so pwsh -Command ..., pwsh -EncodedCommand ..., and pwsh -CommandWithArgs ... notification commands (and their -c/-e/-ec/-cwa aliases) are rejected instead of bypassing the shell-command guard.
  • PtySession::read_until now reports UnexpectedEof when a child exits before the requested bytes arrive, instead of returning partial output as success.
  • forktty hooks test now sanitizes socket error text before rendering human-readable failures, preventing local socket responses from injecting terminal control sequences.
  • Browser import is now limited to the in-app Settings workflow and is no longer advertised or accepted over the socket/CLI automation boundary, preventing local socket clients from using ForkTTY to read external browser profile data.
  • Notification command validation now rejects rbash -c shell trampolines instead of allowing restricted Bash aliases to bypass the shell-command guard.
  • Session ...
Read more

ForkTTY 0.2.0-alpha.12

Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 12 Jun 23:18

[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 cli...
Read more

ForkTTY 0.2.0-alpha.9

ForkTTY 0.2.0-alpha.9 Pre-release
Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 11 Jun 00:22

Changed

  • The Settings dialog was reorganized and rebuilt with standard GNOME preference rows: the terminal palette now lives on the Terminal page next to font and scrollback, the Alerts page is named Notifications, enum options (palette, window mode, sidebar position, worktree layout, font family) use combo rows with explicit value mapping instead of free-form combo boxes, font size and scrollback use spin rows with the validated bounds, the font picker is searchable, and an invalid shell or notification command now marks the row in red in addition to the error toast.
  • Dropped the vendored libghostty-vt-sys copy: upstream libghostty-rs now makes the zig optimize mode follow the Cargo profile (Uzaaft/libghostty-rs#55), so both libghostty crates are pinned to upstream master via [patch.crates-io], with LIBGHOSTTY_VT_SYS_OPTIMIZE=ReleaseSafe pinned in .cargo/config.toml so debug and test builds keep the optimized VT parser. The lines-to-bytes scrollback conversion stays on our side (upstream C API issue, Uzaaft/libghostty-rs#56).

Added

  • Double-click selects the word under the pointer (ghostty's default word boundaries, so paths like /tmp/a.txt select whole) and triple-click selects the visual row; both publish to the PRIMARY selection like a finished drag and work with Shift inside mouse-tracking apps.
  • Dragging a selection past the top or bottom edge of a pane now autoscrolls the viewport (faster the further the pointer goes) and keeps extending the selection; the selection is re-anchored under the scroll instead of being dropped.
  • Panics now also append message, location, and backtrace to $XDG_STATE_HOME/forktty/panic.log before the process dies, so field crashes (which abort inside GTK signal trampolines) no longer require coredump symbolization to diagnose.
  • The session state is now guarded by a lock file: a second running instance (e.g. a deb-installed and an AppImage forktty that DBus could not deduplicate) refuses to start instead of silently fighting the first one's session autosave.

Fixed

  • An empty or malformed OSC 99 sequence no longer leaves a debug-formatted "Terminal metadata" status entry in the sidebar; it is ignored.
  • Terminal pixel-size reports now keep the measured cell dimensions after pane-only cell resizes instead of reverting to the 10x20 startup fallback.
  • Terminal OSC 110/111/104 color resets now restore ForkTTY's configured theme defaults instead of falling back to libghostty's built-in black/background palette.
  • Dead-key and compose-key input now has the GTK input-method handoff documented at the terminal key fallback, clarifying why committed text is not duplicated by fallback key encoding.
  • The search bar's match counter no longer shows a stale "current/total" after new terminal output removes the match highlight; it resets to 0/0 until the next step.
  • Two processes quarantining the same corrupt profile/bookmark store at the same time can no longer overwrite each other's backup file.
  • The sidebar toggle and the periodic PR lookup no longer read the config file on the GTK main thread, and the 2s session autosave no longer builds a debug dump of the whole session to detect changes.
  • An events.subscribe client that stops reading is now disconnected after 10s instead of holding one of the 64 socket connection slots forever; enough stuck subscribers used to silently deny the socket to agent hooks.
  • The event stream now reports a surface whose owning workspace changes (session-restore repair) by re-asserting it as removed + added; subscribers' per-workspace surface lists used to go silently stale.
  • forktty events flushes every event line, so piped consumers (| jq, | while read) see events as they happen instead of in 8KB bursts; when the server drops events because the consumer lags, a warning now also lands on stderr.

CI

  • CI now verifies on every push that the binary carries the RUNPATH it needs to find the bundled libghostty, and the release smoke test runs the packaged binaries exactly the way the alpha.7 field failures did: the deb tree and the extracted AppImage's inner binary without any LD_LIBRARY_PATH, plus the FORKTTY_APPIMAGE exports in AppRun.

Downloads: the AppImage is the primary download for this alpha; the .deb remains available for Debian/Ubuntu. Supported distros: see docs/QA.md. SHA256SUMS is attached — verify with sha256sum -c SHA256SUMS.

Upgrading from v0.2.0-alpha.7 or older AppImages: re-run forktty hooks setup so agent hooks point at the stable launcher path.

ForkTTY 0.2.0-alpha.11

Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 11 Jun 19:33

Added

  • MCP tools now declare spec tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) so clients can surface risk before invoking: list/status tools are read-only, worktree_remove is flagged destructive, status_set/surface_focus are idempotent, and every tool is closed-world (local instance only).
  • New MCP tool workspace_create (working_dir + optional name): agents can open a workspace on a repository themselves, which is the precondition the worktree tools enforce — precondition error, workspace_create, retry, without leaving MCP.

Changed

  • Every socket CLI subcommand now answers --help with its accepted options (generated from the same allow-list validation uses), and create-workspace accepts --cwd as an alias for --working-dir, matching the worktree commands' spelling.
  • The worktree open-workspace boundary rejection now names the open workspace roots and the forktty create-workspace --working-dir <repo> remedy instead of a bare "cwd must be inside the git repository of an open workspace"; the MCP worktree tool descriptions state the precondition up front and SPEC.md documents the boundary as deliberate.

Fixed

  • Worktree socket operations no longer run their git work on the socket server's async runtime: worktree.create/remove execute the repo's setup/teardown hook (up to 30s) and every worktree method walks the repository on disk, which pinned tokio workers and could starve other socket connections (agent hook status updates timing out) while worktrees were being created or removed in parallel. The git2 work, the hooks, the open-workspace boundary validation, and the config read now run on the blocking pool.
  • Creating a notification through the socket (notification.create from the CLI, MCP server, or agent hooks) no longer kills the connection without a response when desktop notifications are enabled: the desktop notifier blocks on its own async runtime, which panics inside the socket server's runtime ("Cannot start a runtime from within a runtime"); dispatch now runs on a dedicated thread.
  • MCP list tools (workspace_list, surface_list, worktree_list) no longer fail with strict MCP clients (including Claude Code): the socket returns bare JSON arrays for list methods and the server passed them straight through as structuredContent, which the MCP spec requires to be an object. Non-object results are now wrapped as {"result": ...}.

Downloads: the AppImage is the primary download for this alpha; the .deb remains available for Debian/Ubuntu. Supported distros: see docs/QA.md. SHA256SUMS is attached — verify with sha256sum -c SHA256SUMS.

This release hardens the socket/MCP/hooks integration shipped in alpha.10: every bug found during the post-release MCP and hooks verification is fixed here. If you use the MCP server with Claude Code, the list tools now work; notification.create no longer drops the connection.

ForkTTY 0.2.0-alpha.10

Pre-release

Choose a tag to compare

@Lucenx9 Lucenx9 released this 11 Jun 18:20

Fixed

  • The pty master and slave are now opened with O_CLOEXEC atomically (posix_openpt) instead of setting the flag after openpty(): a process forked on another thread in that window (worktree hooks, notification commands) inherited the descriptors and kept the pty alive past its session. Slave duplicates for the child's stdio use F_DUPFD_CLOEXEC for the same reason.
  • Release binaries no longer inherit the CPU feature set of the CI build machine: libghostty's zig build now targets the generic x86-64 baseline (-Dcpu=baseline, via a vendored one-line patch in vendor/libghostty-rs). The first alpha.10 cut was built on an AVX-512 runner and its statically linked memset crashed every non-AVX-512 machine with SIGILL at startup; the same lottery silently applied to every release since alpha.7.

Added

  • forktty mcp now runs a local stdio MCP server exposing ForkTTY workspaces, surfaces, worktrees, notifications, and status metadata as typed tools; forktty mcp setup/remove registers the server for Codex, Claude Code, Gemini CLI, and Antigravity while preserving foreign MCP servers (Codex config.toml is edited in place, keeping comments and formatting). Claude Code session-start hooks now include ForkTTY workspace/branch context and a short MCP/CLI capability cheat sheet.
  • Agent hooks for Antigravity CLI (agy, Google's Gemini CLI successor): forktty hooks setup antigravity installs a ForkTTY-owned "forktty" group in ~/.gemini/config/hooks.json for the verified PreInvocation/PreToolUse/PostToolUse events, plus generated wrapper scripts (Antigravity executes a hook command as one bare executable path, without arguments or a shell). Sessions are correlated via conversationId, hook responses use the strict-protojson-safe {}, and hooks doctor antigravity reports the launcher state from the generated scripts. Gemini CLI hooks remain supported.
  • forktty hooks doctor codex now reports trustCheck: Codex requires per-hook trust approval (recorded under [hooks.state] in its config.toml) before running installed hooks, so the doctor lists events with no approval record yet and points at /hooks inside Codex.

Changed

  • forktty hooks setup claude now installs lifecycle hooks by default and omits the blocking per-tool PreToolUse/PostToolUse/PostToolUseFailure/PostToolBatch hooks; use forktty hooks setup --full claude to restore the previous full profile. Existing installs keep working, and re-running setup migrates Claude hooks to the lifecycle default unless --full is passed.
  • Chromium bookmark import now deserializes only the bookmark fields ForkTTY uses, avoiding large extra allocations for ignored browser metadata.

Security

  • Pasted text is now encoded with libghostty's paste encoder, which neutralizes control bytes in the payload: clipboard content containing \x1b[201~ can no longer terminate the bracketed-paste wrapper early and inject the remainder as typed input (including command execution in a shell).
  • A socket client that sends a request and then stops reading the response is now disconnected after a write timeout instead of holding one of the 64 connection slots forever; enough stuck clients used to deny the socket to agent hooks.

Fixed

  • Agent hook status updates that lose FORKTTY_WORKSPACE_ID/FORKTTY_SURFACE_ID after session start (for example through tmux, ssh, or containers) can now be attributed back to the originating pane by hook_session_id when the socket server has seen that session with explicit targets.
  • "Merge Worktree" now works when invoked from inside a linked worktree (it used to always fail with "Cannot resolve admin directory"), and fast-forward merges update the main checkout's files instead of only moving the branch ref.
  • Large pastes (bigger than the kernel pty buffer, ~12KB) are no longer silently truncated; the terminal now waits for the child to drain its input, with a 10s safety timeout. Automatic VT query replies sent over the same path can no longer be cut off mid-sequence either.
  • Splitting panes beyond the persistable depth (6 nested splits) is refused instead of silently breaking every subsequent session autosave and losing the layout on restart.
  • Ctrl with non-letter keys (Space, [, \, ], ^, _, ?) now sends the standard C0 control codes instead of nothing.
  • In maximize mode, focus changes that don't alter the pane tree (command palette "Focus Next Pane", socket surface.focus) now switch the visible pane instead of leaving a stale one on screen.
  • The Close Pane confirmation now closes the pane it was opened for, even if a socket client switched the active workspace while the dialog was open.
  • Piped CLI output (forktty list --json | head -1 and similar) no longer panics with exit 101 and a panic.log entry when the consumer closes the pipe early.
  • "Reset Terminal" no longer reverts the pane to libghostty's default colors; the configured theme is re-applied and stale paste/focus mode state is cleared.
  • A configured shell or notification command that is temporarily missing from disk no longer quarantines the whole config and resets every setting to defaults; the value is normalized (default shell / cleared command) on load instead.
  • The socket server keeps serving through transient accept() failures such as file-descriptor exhaustion (EMFILE/ENFILE) instead of shutting down for the rest of the app's lifetime.
  • Two concurrent closes of the last workspace (or a close racing a worktree removal) no longer leave a duplicate replacement workspace.
  • Replacing a pane or workspace context menu no longer risks a re-entrant RefCell crash from the popover's synchronous closed signal.
  • Saving a setting from the Settings dialog no longer reverts config changes made outside the dialog while it was open (e.g. the F9 sidebar toggle); each change is rebased onto the config on disk.
  • forktty doctor --socket/--verbose/--debug now explains that doctor runs locally and that the socket doctor takes global flags first (forktty --json doctor); the CLI help documents the reachable spelling.
  • Hook event ordering now uses CLOCK_BOOTTIME instead of the wall clock, so hook status updates are no longer silently dropped after the system clock steps backwards; orders from different clock sources are no longer compared against each other.
  • forktty hooks with a missing or typoed subcommand now exits with a helpful error instead of printing hook continue-JSON and exiting 0.
  • worktree-status rejects combining a positional path with --path/--cwd instead of silently ignoring the positional, matching its sibling commands.
  • forktty --json doctor and forktty hooks setup no longer hang forever when an inspected config path is a FIFO.
  • Socket connections from the CLI and agent hooks are bounded by a connect timeout instead of hanging when the app's accept backlog is full.
  • A poisoned model lock no longer makes the socket event stream broadcast false removal events for every workspace and surface.
  • Workspace cwd validation no longer runs git repository discovery while holding the model lock shared with the UI thread, and the startup socket probe now has an overall deadline instead of only per-read timeouts.
  • Shell-trampoline detection for the notification command now catches clustered flags (bash -lc), separated flags (bash -x -c), and env-wrapped shells (env bash -c).
  • A child process flooding its terminal can no longer hold the UI in a single unbounded read; terminal reads are capped at 1MiB per pump tick.

Downloads: the AppImage is the primary download for this alpha; the .deb remains available for Debian/Ubuntu. Supported distros: see docs/QA.md. SHA256SUMS is attached — verify with sha256sum -c SHA256SUMS.

Agent integration: forktty mcp setup registers the new stdio MCP server for Codex, Claude Code, Gemini CLI, and Antigravity. forktty hooks setup claude now installs the lifecycle hook profile by default — pass --full to keep the previous per-tool profile.