tongs 1.1.0
Released 2026-10-12. This is a feature release. The All Open tab loads one
page per repository and fills in CI for the rows you can see, in every inbox
tab of both apps. Diffs can show the unchanged lines around a change or the
whole file, and a file too large for the forge can be diffed on your machine.
The terminal diff keeps indentation and colours, and the desktop diff is
faster on large reviews, highlights syntax and lets you mark files as viewed.
The [ui] and [editor] settings now work in the terminal app, config.toml
is checked when tongs starts, and the desktop app gets a System, Light and Dark
colour scheme. tongs-mcp runs on the same services as the two apps, which
changes approve_mr. A few changes need your attention; they are listed under
Before you upgrade.
Install
Section titled “Install”pipx install tongs==1.1.0pip install tongs==1.1.0 and uv tool install tongs==1.1.0 work the same
way. To upgrade an existing installation, run pipx upgrade tongs, or
uv tool upgrade tongs, or pip install --upgrade tongs. If you use the
per-user desktop app, upgrade the core first and then install the matching
desktop release, because the desktop app and the core exchange new fields in
this release:
tongs desktop updateBefore you upgrade
Section titled “Before you upgrade”[ui] themenow takes effect. If yourconfig.tomlsaystheme = "monokai", the terminal app now uses Textual’s Monokai theme. Remove the line to keep the look you had. See Settings.- A mistake in
config.tomlstops tongs at startup, with a message that names the file, section and key. Unknown keys only log a warning. See Settings. tongs-mcpclients must passhead_shatoapprove_mr. See tongs-mcp.- Upgrade every tongs that shares your drafts at the same time. Running a
tongs older than 1.1.0 and 1.1.0 against the same
drafts.dbwhile a review submission is in flight is not supported. See Review drafts.
The inbox
Section titled “The inbox”- All Open shows rows sooner and loads more on demand. It reads the newest 100 open reviews of each repository and shows them as each repository arrives. Press m, or move to the last row, to load the next 100 of each repository that has more; the status line says how many were added. Pages you load stay when you switch tabs. Loading more in All Open has the details. (#396, #419)
- Reviews and My MRs show CI status, and CI fills in as you scroll. On
All Open, Reviews and My MRs, each row starts with a loading marker (
…, or..withascii_mode) and gets its CI status when it comes into view. Rows you never scroll to cost no requests, and on GitHub the rows looked up together are batched into GraphQL requests. The desktop inbox fills in CI per card the same way on every tab, and shows N/A when a lookup failed. (#385, #419) - GitHub CI now counts commit statuses as well as check runs, so pull requests that report only through statuses, as Jenkins and Prow do, show their state. (#419)
- When GitHub’s rate limit is reached, the status line names the reset time and tongs stops looking up CI on that host until then, instead of retrying. (#419)
Diffs in the terminal app
Section titled “Diffs in the terminal app”- Word diffs keep indentation, spacing and syntax colours. Changed words, including changed indentation, are bold and underlined, and a re-indent from tabs to spaces shows as a change. (#308, #427)
- Added, removed and cursor rows keep their background tint behind highlighted code, in both Unified and Split. (#308)
- Each file is highlighted once, so saving a draft comment, toggling a thread or going back to a recent file no longer highlights it again. The old and new side of each hunk are highlighted separately, so an unclosed string or comment on one side no longer colours the other side or a later hunk. (#308)
Diffs in the desktop app (beta)
Section titled “Diffs in the desktop app (beta)”- Large reviews are faster. Clicking or dragging over lines no longer redraws the whole app or the changed-file list. (#306, #428)
- Diffs are syntax highlighted in Unified and Split for common languages, including Python, Go, Rust, C and C++, Java, JavaScript, TypeScript, shell, YAML, JSON and Markdown. Added, removed and selected backgrounds stay visible. Files over 2,000 diff lines or 256 Ki characters stay plain. (#384, #428)
- Mark files as viewed. Each file header has a Viewed checkbox, which Space toggles, that collapses the file and marks it in the changed-file list. The review header shows “N of M files viewed”. The marks last while the app is open and reset when the review gets a new head commit. (#195, #428)
- Switching between Unified and Split reuses the diff already read, with no forge request. A diff draws from its first page while the rest loads, and if a later page fails, the pages already drawn stay on screen with the reason. (#305, #427)
Diffs in both apps
Section titled “Diffs in both apps”- Show the unchanged lines around a change, or the whole file. Gap rows above, between and below hunks say how many lines they hide. In the terminal, e expands or collapses a gap and ShiftF shows the whole file. In the desktop app, click a gap row or focus it and press Enter, and use Full file in the toolbar. Expanded lines are read-only. Opening a diff costs the same requests as before; a file is read only when you expand it. Expanding context and Show unchanged lines have the details. (#381, #383, #433)
- Generate a diff the forge would not send. For a file whose diff GitHub
or GitLab left out as too large, press e in the terminal or
Generate diff locally in the desktop app. tongs downloads the file’s two
versions and builds the diff on your machine, with progress and a way to
cancel. The result is labelled Generated locally, and comments are not
available on it. The diff is built with Python’s
difflib, which can align a large rewrite differently from the forge’s own diff. (#382, #383, #433) - File contents are cached. A new setting,
[cache] file_content_ttl, sets how long a file read to expand context stays in the cache:1dby default, from1hto365d. (#433) - Fewer forge reads. Submitting a review reads the diff once per revision instead of twice for every inline comment, and a revision check reads only the review itself, not its checks, reviews or approvals. (#305, #427)
- GitLab diffs come from the paginated
/diffsAPI. On GitLab older than 15.7, which does not have it, tongs falls back to the older/changesAPI. (#397, #427) - File mode changes show in the file header, such as
mode 100644 -> 100755, for GitLab and for parsed git diffs. GitHub does not report file modes. Files whose only change is their mode, copied files, and file names that git writes quoted, such as non-ASCII names, now show correctly. (#397)
Settings
Section titled “Settings”config.tomlis checked when tongs starts. A syntax error names the file, line and column. A wrong type or bad value names the file, section and key, without repeating the value. The terminal app prints the message and exits, the desktop app shows it in a dialog, andtongs-mcpreturns it from each tool call. An unknown section or key, such as a misspelled one, only logs a warning. How tongs checks the file has the details. (#310, #436)[ui] themeworks, and its default istextual-dark. Before 1.1.0 the terminal app ignoredtheme. A config that saystheme = "monokai"now gets Textual’s Monokai theme; remove the line to keep the old look. (#145, #436)- New and working terminal settings in
[ui]:syntax_themesets the Pygments style for code in diffs and comments (defaultmonokai),diff_stylesets the layout a diff opens in, andshow_draft_mrs = falsehides draft reviews in Reviews, My MRs and All Open. An unknown name logs a warning and the default applies. (#145) [editor] commandandexternal_editor_enabledapply to the terminal app for F2 and F3, as they already did in the desktop app. (#145)ascii_modecovers every screen, dialog and panel of the terminal app: borders, the file tree, CI statuses, key names, loading text and tables. (#322, #436)- The desktop app has a System, Light and Dark colour scheme. A toggle in
the application bar switches it, and the window and native dialogs follow.
Light or Dark is saved in the desktop app’s own settings, never in
config.toml; System clears it. The new[ui] color_schemekey (system,lightordark) sets the default. Colour scheme has the details. (#226, #436)
Repositories
Section titled “Repositories”- Symlinked checkouts and git worktrees are found. The scan follows
symlinked directories, including ones that point outside
scan_root, and each link counts as one level ofscan_depth. A repository reached by two paths is found once, and link loops and broken links are skipped. A git worktree is found like any other checkout. Hidden folders such as.worktrees/are still skipped. (#156, #441) - The terminal repo list shows one row per project and opens the main checkout rather than a worktree. (#156)
tongs-mcp
Section titled “tongs-mcp”tongs-mcp now runs on the same application services as the terminal and
desktop apps, so it gets the same safety checks.
(#301,
#425)
- Approvals are pinned to the reviewed revision. The forge receives the head SHA, so an approval never lands on commits pushed after the review was read. Approving has the exact messages.
list_mrsis bounded. It reads one page, acceptsstateopen,closedormergedand rejects anything else, and looks up CI only for the open reviews it returns. Closed and merged reviews report CI asunknown.get_mr_difflists every changed file. A file without a patch gets a marker such as[binary],[renamed]or[truncated], and the output is capped at 256 KiB with a note naming how many files were left out.get_mralso returnsbase_sha. Errors are the same short messages the two apps show, returned as MCP tool errors. Review lists and CI can come from the tongs response cache formr_list_ttl.- A GitHub workflow run without a branch now has
"ref": ""inlist_pipelinesinstead ofnull. (#443, #448)
Review drafts
Section titled “Review drafts”- Submitted drafts are cleaned up. A submitted draft disappears from both
apps at once and is deleted from local storage after 24 hours. The new
[drafts] submitted_retentionsetting changes that window, from1hto365d. Drafts that are still being edited or submitted are never deleted. (#317, #406) - Both apps apply the same draft limits: 200 comments, 65,536 bytes for the summary and each comment, and no control characters other than tab and newline. A save over a limit is refused with an error, and in the terminal your text stays in the editor. Drafts already stored over a limit still load, and the desktop draft list skips one damaged draft instead of failing. (#316, #406)
- Rare review submission failures now report what happened and how to recover, instead of a misleading message such as the draft being active in another tongs. (#391, #406)
- Review submission lock files are deleted when the submission ends, and
ones left behind by a crash are removed the next time a draft store opens.
This follows the design @tayfuryldz proposed in the issue. Thank you!
Running a tongs older than 1.1.0 and 1.1.0 against the same
drafts.dbwhile a submission is in flight is not supported, because older versions do not check for a deleted lock file. (#251, #448)
The desktop app (beta)
Section titled “The desktop app (beta)”- The desktop service restarts on its own after a crash, up to three times within a minute, after which the status line says it has stopped. Retry after a crash now works. (#224, #408)
- The desktop service’s diagnostic output goes to the app log, with control and bidirectional characters replaced. (#336, #408)
- Job logs of any size open. The desktop app streams a log and keeps at most its last 8 MiB, so a long log shows its end, with a first line naming the full size, instead of an error. “Showing the end of this job log” is now a notice, not an error. (#314, #448, #450)
- A search typed into the job log search box right after the log appears is no longer cleared. (#449)
- Open in editor is safer. F2 works for any job name, including names
with
/. Editors that hand the file to a running instance, such ascode,subl,kate,gedit,gvimandemacsclient, are made to wait. A log over 4 MiB opens as its last part, after a note line such as[tongs] This job log is 12.0 MiB. Showing the last 4.0 MiB; earlier output is left out.(#314, #408, #447, #450) - Editor exports move to a private folder:
$XDG_RUNTIME_DIR/tongs/editor-exports, ortongs-editor-exports-<uid>in the temp folder when the runtime folder is not private. A folder that others can open is refused with a message naming it. The old sharedtongs-editor-exportsfolder in the temp folder is not removed for you; delete it once you have upgraded. Read and search a log has the details. (#314, #408) - Long sessions keep working. When the app’s table of open lists is full, the least recently used ones are released instead of every new list failing. A session that has sent very many write actions says “Too many write actions in this session. Restart tongs to continue.” in both apps. (#313, #408)
- Empty optional forge fields no longer break a view. A pipeline, job, commit or review with a missing optional field, such as a GitHub workflow run without a branch, loads and leaves the missing value out. (#184, #443, #445, #448)
- Cancelled requests, such as reads abandoned while you scroll, are no longer logged as errors, and generated diffs that are no longer on screen release their memory. (#430, #431, #432, #445)
Exiting cleanly
Section titled “Exiting cleanly”- The terminal app no longer hangs at exit after a failed shutdown. When cleaning up a review submission failed, open storage could keep the process alive, and you had to kill it. tongs now closes every store on the way out and reports the error after it exits. With a stuck submission, quitting can take a little longer, within a fixed bound. (#198, #445)
- The desktop service and
tongs-mcpclose their stores the same way, and the desktop app gives its service up to 15 seconds to exit before stopping it. (#442, #448)
Plugins
Section titled “Plugins”- A failing palette command no longer stops the terminal app. The error is logged with the plugin name and shown as a notice. (#312, #405)
- Start MCP Server is now MCP Server Setup. It shows the command that
registers
tongs-mcpwith an MCP client, instead of starting a server in the background that the MCP client could not use. (#405) - Desktop providers start together within one 6-second budget, so a slow provider no longer delays the app’s start, and the default provider call timeout is 25 seconds instead of 30. On shutdown every provider is asked to stop. Each plugin read has its own cancellation, so a failed read never cancels its caller’s other work. (#312, #405, #448)
Dependencies
Section titled “Dependencies”- Textual is bounded below 9 (
textual>=4.0,<9). (#427) - The desktop app moves to React 19.3 and adds
highlight.jsandlowlightfor syntax highlighting. (#423, #428, #452)
Release and packaging
Section titled “Release and packaging”- RPM payloads are compressed with multithreaded zstd at level 19, the same level as before on all cores, and the RPM files rebuild byte for byte from the same commit. Nothing changes for installs. (#161, #455)
- The RPMs are built on a pinned Fedora 44 builder image that is published to GitHub Container Registry with an attestation, which the build checks before it uses the image. A weekly pull request moves the pin to a newer image. (#161, #434, #435, #437, #439)
- For contributors: Dependabot proposes monthly dependency updates, Ruff is
pinned through a new
lintextra (pip install -e ".[dev,lint]"), and the desktop sources have Prettier and ESLint checks with a check for control characters in tracked files. (#162, #204, #404, #420, #450) - Test coverage grew for desktop plugin resource limits and lifecycle, the desktop installer, protocol and renderer, CI evidence and RPM packaging. Thanks to @Tiyatrotist for the desktop plugin resource limit and lifecycle tests, and for the first pass at the example plugin’s error-path tests. (#360, #401, #403, #407, #448, #453)
Release assets
Section titled “Release assets”The GitHub Release
carries the same set of assets as 1.0.5, for version 1.1.0: the per-user
archive with its release manifest and Sigstore attestation, the unsigned Fedora
44 RPMs with their source-built companion packages, the archive SBOM with its
attestation, and SHA256SUMS. Install the RPMs together with
dnf install ./*.rpm.
Known issues
Section titled “Known issues”Known issues lists the defects known in 1.1.0, with the issue for each fix.