Repository navigation
Fix the top ten audit findings: clipboard and git safety, idle CPU, sidebar order - #436
Merged
Merged
Conversation
The built-in browser was removed on 2026-10-05, but [Unreleased] still advertised default-browser support and browser cookie methods. Record the removal instead, and label the README split shortcuts correctly.
It reuses the build-app artifact, so the unit-tests dependency only lengthened the main-push CI tail by about four minutes.
Darwin fails SO_RCVTIMEO with EINVAL once the peer has closed, so a server that answered and hung up quickly made the CLI and MCP bridge report "Failed to configure socket receive timeout" instead of the reply. Source of the MCPSocketBridgeTests shard-2 flake (run 38943517971).
…ected workspace Notifications no longer move their workspace to the top, so Cmd+1..9 keep pointing at the same workspaces. Selecting a workspace that is off screen now scrolls the sidebar to it by the minimum distance. Also removes sidebar row layouts left unreachable by the settings removed in #415, and the legacy tab-color migration keys.
…ppers `programa themes` now always lists themes instead of opening the interactive picker, so the app no longer ships a second copy of the ghostty command-line tool (about 6 MB) and builds skip its Zig compile. List, set and clear are unchanged; an unknown theme now suggests matches. The undocumented omo, omx and omc wrappers are removed; see docs/removed/omo-omx-omc-wrappers.md.
…ing repo filters Programs in a pane could replace the clipboard through OSC 52 without asking. Clipboard writes now ask by default, with a preview of the text and an "Always allow for this terminal" option so tmux and Neovim yanks stop prompting. A clipboard-write line in your own config still wins. The sidebar's background git checks no longer run filter commands defined in a repository's own .git/config, so opening a crafted folder can't run a command. Filters from global config, such as Git LFS, keep working. A terminal-reported directory must be an existing absolute path before it is probed.
Each terminal's scrollback log woke ten times a second and rewrote its status file with an fsync every five seconds, which was most of the app's idle CPU. It now wakes only when a terminal prints something, and the status file is written on real changes plus an hourly liveness update. With scrollback saving off, nothing wakes unless a session holder still needs the liveness update. Old terminal history is cleaned up again: settings files no longer stall the cleanup, and a saved session from another build that has not been touched in 14 days no longer keeps its history. The running build's own saved session always does. Removes upgrade code for builds older than 30 days: the first-generation session holder, the retry for holders from before 2026-08-10, and restoring hidden windows from old snapshots. Old window geometry keys are cleared once at launch instead of on every save.
…s off the main thread Only dev and bench snapshots stop pinning scrollback after 14 days, so a dev build can't sweep production's history after a long break. The OSC 7 directory existence check now runs on a serial queue so a stalled network mount can't freeze the app.
…lter config when a repo appears A program sending OSC 52 in a loop replaced the open sheet on every request, so the user could not click Deny. Requests that arrive while a prompt is open are now denied and the sheet stays. The filter-config cache could hand a non-repository directory's empty answer to a repository extracted into it within 10 s. Cached answers are now tied to the identity of every .git and config file discovery could read, so they are reused only while those are unchanged, and the "no filters" answer is cached again. Repository-local lfs.extension keys match regardless of case.
The filter fixture changed a.txt's size, so git status marked it modified from the index and never ran the clean filter; the edit now keeps the size. The sweep test stored its own snapshot outside the directory the sweep scans. The clipboard replacement test now uses a paste, which still replaces an open prompt, and a new test covers an OSC 52 request being denied while a prompt is open.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Fixes the top ten items from the October 19 audit. Programs running in a terminal can no longer write the clipboard without asking, and opening a folder can no longer make the app run commands that folder's git config defines. Idle terminals stop waking the CPU ten times a second. The sidebar no longer reshuffles itself on notifications. The app drops the bundled ghostty CLI helper and the omo/omx/omc wrappers.
Summary
Suggested review order: the security commits first (11521e0, b47674f, e2c3113, 0c5a094), then the scrollback log (cb35dde, 5345052, 929f5bb), then the rest.
Security:
clipboard-writesetting still wins.lfs.extension.*key also turns offfilter.lfs.statusanddiffpass--ignore-submodules=dirty, so git doesn't run status inside submodules..gitandconfigthat git's discovery could read are unchanged, so a repo extracted into an already-probed folder is read fresh.git statuson every prompt. The app works out whether the repo has changes with its own guarded probe.addrefuses and the cleanup leaves the branch alone.Scrollback log:
Other:
setsockoptfails with EINVAL after the server closed. This was the cause of the MCP test flake.ui-regressionsno longer waits for the unit-test shards.programa themesis Swift now, and the zig installs and signing steps for the helper are removed from CI.docs/removed/omo-omx-omc-wrappers.md.Accepted risks, per the 30-day decision:
include.pathor a linked worktree's common config dir. Using either needs write access to the repo.A security review covered every security commit up to 0c5a094 and approved them; it was static, with no tests run. A cross-model review covered the first eight commits, and its findings are fixed.
Test Plan
ConfigFixSweepRegressionTestsandTerminalAndGhosttyTestsandtests/test_cli_themes.py. These have only been compiled so far.printf '\e]52;c;aGk=\a'in a terminal and expect a prompt. Click Deny, run it again within 30 seconds, and expect no prompt and an unchanged clipboard.while :; do printf '\e]52;c;aGk=\a'; doneand expect one prompt that stays put. Clicking Deny should work.filter.x.clean = touch /tmp/markerand a.gitattributesthat uses it, open a terminal there and expect/tmp/markernever to appear.