mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-21 16:02:20 +00:00
chore(release): v26.8.2
This commit is contained in:
+668
-35
@@ -5,20 +5,56 @@ All notable changes to tty7 are documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
## [26.8.2] - 2026-08-09
|
||||
|
||||
### Added
|
||||
|
||||
- **Update tty7 without leaving the app** — the launch check and
|
||||
**Settings → About → Check Now** now offer **Update and Relaunch** for
|
||||
packaged macOS installs instead of sending the user to GitHub Releases. A
|
||||
dedicated `tty7-updater` helper verifies the release checksum, bundle
|
||||
version, and code-signing requirement before replacing the app, and restores
|
||||
the previous bundle if relaunch fails. The new GUI reuses a running local
|
||||
server when its wire protocol is compatible, preserving shells; an
|
||||
incompatible server keeps its shells too and raises the existing explicit
|
||||
keep-or-restart prompt. Other platforms and unsupported layouts retain the
|
||||
release-page fallback, and Nightly remains unchanged for the first version.
|
||||
**Settings → About → Check Now** now offer **Update and Relaunch** instead of
|
||||
sending the user to GitHub Releases. A dedicated `tty7-updater` helper
|
||||
verifies the release checksum, the bundle version, and — on macOS — the
|
||||
code-signing requirement before replacing the installation, and restores the
|
||||
previous copy if the relaunch fails. The update is fetched and verified while
|
||||
the prompt is up, so installing it is a restart; declining defers it rather
|
||||
than retiring it.
|
||||
|
||||
On macOS the new GUI reuses a running local server when its wire protocol is
|
||||
compatible, preserving shells; an incompatible server keeps its shells too and
|
||||
raises the existing explicit keep-or-restart prompt. Windows cannot replace a
|
||||
running daemon's image, so its install path stops the service and the dialog
|
||||
says so. Layouts that cannot be updated in place — notably an all-users
|
||||
`C:\Program Files` install, where running Setup as the signed-in user would
|
||||
either install a second copy beside the real one or put a bare UAC prompt in
|
||||
front of a user whose GUI just vanished — keep the release-page fallback.
|
||||
(by @ayamir in #309, by @ArnoChenFx in #330)
|
||||
|
||||
- **Stable and Nightly are separate update channels** — the channel is a
|
||||
property of the installation rather than something inferred from how version
|
||||
numbers sort, so a Nightly build follows Nightly instead of being walked back
|
||||
onto Stable by an update it never asked for. Stable reads `/releases/latest`,
|
||||
which excludes prereleases; Nightly reads `/releases/tags/nightly`. Neither
|
||||
feed can hand the other an update, so an installation only changes channel
|
||||
when the user changes it in Settings.
|
||||
|
||||
The nightly release cannot state its version in its tag — `nightly` is
|
||||
force-moved every night, so `tag_name` is the literal string — so it now
|
||||
publishes `nightly.json` beside the packages, falling back to parsing asset
|
||||
filenames for builds that predate the manifest. Prereleases are ordered by
|
||||
every numeric identifier in the stamp, and the stamp goes to the minute so two
|
||||
builds in one day are distinguishable; a stable release still outranks every
|
||||
dated build of its core version, which is how switching back to Stable
|
||||
graduates rather than downgrades. Switching channel invalidates what the old
|
||||
feed produced: the staged package, the deferred prompt, and any transfer still
|
||||
in flight. Skipping a version is retired along with its state and its Settings
|
||||
row. (#386)
|
||||
|
||||
- **A proxy for tty7's own network traffic** — update checks, release downloads
|
||||
and remote-server installs now resolve an HTTP/SOCKS proxy from, in order, a
|
||||
new `http_proxy` config field, the platform system proxy (Windows registry,
|
||||
macOS `SCDynamicStore`), and `HTTP_PROXY` / `HTTPS_PROXY` / `ALL_PROXY`.
|
||||
Programs running in a pane are deliberately unaffected — they inherit their
|
||||
proxy from their own environment, as in any other terminal.
|
||||
(by @shihuaidexianyu in #367, reported in #365)
|
||||
|
||||
- **`tty7 wait` — the primitive an agent team was missing** — block until a
|
||||
pane's agent needs input, finishes its turn, or dies:
|
||||
@@ -47,7 +83,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
stateless question composes into scripts (`tty7 wait %3 && tty7 capture %3
|
||||
--plain`), survives a server restart mid-wait, and needs no cursor. The
|
||||
cost is one aggregate request per tick — the same one `tty7 agents` makes
|
||||
once. (#248)
|
||||
once. (by @yetone in #248)
|
||||
|
||||
- **An orchestration skill for Claude Code** — a switch under
|
||||
**Settings → Agents** installs `~/.claude/skills/tty7-orchestration`, a
|
||||
@@ -112,7 +148,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
arriving mid-scroll shifts the grid without dragging the animation somewhere
|
||||
else. Everything that moves the view on its own — jumping to a prompt,
|
||||
dragging a selection past the edge, clearing the scrollback, the keyboard and
|
||||
mouse-reporting paths — cancels what is in flight first.
|
||||
mouse-reporting paths — cancels what is in flight first. (#382)
|
||||
|
||||
- **The GUI speaks English, Simplified Chinese and Japanese** — every string in
|
||||
the interface now goes through a locale table, selected by **Settings →
|
||||
General → Language**. The menu bar, command palette, switcher, settings,
|
||||
SFTP panel, file tree, diff overlay, toasts, SSH prompts and confirmations are
|
||||
all translated, with plural- and select-aware helpers where a count or a
|
||||
gender-free choice is involved. The `zh` and `ja` key tables are exhaustive,
|
||||
so adding an `L10nKey` fails the build until it is translated rather than
|
||||
silently rendering English.
|
||||
|
||||
Two things stay in English on purpose. A theme's name is data, not chrome —
|
||||
it is written into the theme YAML and matched back by suffix, so translating
|
||||
it forked "Nord" into a Chinese name that then stacked a second suffix on the
|
||||
next fork and stayed Chinese after switching the GUI back. And the words
|
||||
Chinese developers read and speak in English anyway — hook, agent, worktree,
|
||||
diff, fork, shell, pane, server — are left alone; translating them lost more
|
||||
than it gained. Language names in the picker stay endonyms (English /
|
||||
简体中文 / 日本語) in every locale.
|
||||
(by @shihuaidexianyu in #303, by @cwatanab in #372)
|
||||
|
||||
- **Oh My Pi (`omp`) is a first-class agent** — the eighteenth CLI tty7
|
||||
recognizes in a pane, with the full set: brand avatar, status dot, session
|
||||
@@ -127,6 +182,120 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
bridge is the Pi extension the fork inherited (same default-exported
|
||||
factory, same four lifecycle events), so one template now serves both,
|
||||
landing at `~/.omp/agent/extensions/tty7/index.ts`.
|
||||
(#405, reported by @Hanser0521 in #376)
|
||||
|
||||
- **The switcher is two columns, and Ctrl+Tab raises it** — it listed
|
||||
workspaces only, so reaching a tab inside one meant opening the workspace
|
||||
first. Now workspaces sit on the left and the tabs of whichever one the cursor
|
||||
is on sit to the right, and Ctrl+Tab raises the panel as a most-recently-used
|
||||
tab switcher that commits when the modifier comes up, the way IDEA does it.
|
||||
|
||||
Picking a workspace or a tab switches this window in place; a second window is
|
||||
something you ask for, with the platform modifier or **Open in New Window**,
|
||||
rather than what happens by default. New workspaces also get a codename
|
||||
("amber-yak") instead of inheriting whatever directory their first shell
|
||||
started in. (#380)
|
||||
|
||||
- **Every shell tty7 can find is in the new-terminal menu, plus one you name** —
|
||||
the menu lists the shells detected on this machine (Nushell included, on every
|
||||
platform) and a configurable custom entry with its own arguments, which
|
||||
survive across shell-inventory rescans. (by @ArnoChenFx in #311)
|
||||
|
||||
- **Windows Explorer context menus** — an optional **Open in tty7** verb for a
|
||||
directory background and for a folder, registered from the installer rather
|
||||
than from Settings: writing shell verbs is an install-time decision, which is
|
||||
where VS Code and Git for Windows put theirs. A task checkbox drives new
|
||||
`--register-explorer-menu` / `--unregister-explorer-menu` flags, so the key
|
||||
layout stays in `core::explorer_context_menu` instead of being copied into the
|
||||
`.iss`. The uninstaller unregisters unconditionally, so an install that
|
||||
registered once and was later upgraded without the box ticked does not leave
|
||||
keys pointing at a deleted exe. (by @ArnoChenFx in #310, #350)
|
||||
|
||||
- **`tty7` opens directories in new tabs** — the CLI accepts one or more
|
||||
directories and opens a tab per directory in the running GUI, restoring a
|
||||
window if none is open. Paths that do not round-trip through UTF-8 are
|
||||
rejected rather than opened somewhere else. (by @ArnoChenFx in #308)
|
||||
|
||||
- **A bell that both flashes and rings** — `BellMode` gained a `Both` variant
|
||||
alongside `None`, `Visual` and `Audible`, exposed as a fourth option under
|
||||
**Settings → Terminal → Bell**. Existing `none` / `visual` / `audible` config
|
||||
values are unchanged. (by @shihuaidexianyu in #357)
|
||||
|
||||
- **Desktop notifications you can click** — a notification now carries the pane
|
||||
it came from, and clicking it reveals that pane's window, tab and split.
|
||||
Windows shows a WinRT toast with an `Activated` handler, macOS uses
|
||||
mac-notification-sys' click response, and both route through the existing tray
|
||||
dispatch channel; Linux keeps the plain notify-rust path. Titles gained
|
||||
context — an agent name or the machine, then the workspace — and bodies name
|
||||
the command or agent alongside the duration, all of it translated. Notification
|
||||
text is sanitized on every path: it comes off the terminal, and a stray
|
||||
control byte used to make the Windows toast XML fail to parse and lose the
|
||||
notification outright. (by @shihuaidexianyu in #373)
|
||||
|
||||
- **The bright half of the ANSI palette is rescued when a theme makes it
|
||||
illegible** — bright colors that fall under the contrast floor on the theme
|
||||
background are lifted to it, behind a setting so a theme that means it can opt
|
||||
out. (by @ArnoChenFx in #413)
|
||||
|
||||
### Changed
|
||||
|
||||
- **The About page is about the app again** — it had grown three sections that
|
||||
change system state and that nobody looks for under "About": a PATH install, a
|
||||
registry write, and a daemon restart. The `tty7` CLI toggle moves to
|
||||
**Agents**, which already describes tty7 ↔ agent integration in the other
|
||||
direction (hooks reporting session status). The Windows Explorer context menu
|
||||
moves to the installer. Server restart stays — it is about the app itself.
|
||||
|
||||
What is left is trimmed to what it is for: the marketing paragraph goes, the
|
||||
update and server explanations drop from multi-sentence accounts of internals
|
||||
to one line each, the tech credits move to the bottom, and the update toggle
|
||||
renders with `settings_row` like every other switch. Eight strings the page
|
||||
had skipped are now localized. (#350, #358)
|
||||
|
||||
- **The close-confirmation setting is gone** — closing a window with live panes
|
||||
always confirms. (#383)
|
||||
|
||||
- **The Outline right panel is gone** — with all of its wiring: the tab, the
|
||||
action, the palette command, the keymap arm and four i18n keys. An existing
|
||||
config value of `outline` falls back to the default Info tab, and a user
|
||||
keybinding naming `ShowRightPanelOutline` degrades to a logged warning rather
|
||||
than breaking the keymap. (#375, requested by @shihuaidexianyu in #374)
|
||||
|
||||
- **Chinese terminology, corrected throughout** — the worst one collided two
|
||||
concepts: a git worktree was translated as 工作区, the same word tty7 uses for
|
||||
a workspace, so "Remove Worktree" read as "delete this workspace" inside a
|
||||
destructive confirmation. Worktree is 工作树 now and workspace keeps 工作区 to
|
||||
itself. Also: Forget password means "clear the stored password", not password
|
||||
recovery; the SSH auth mode **Agent** was 代理, the same word as the proxy
|
||||
fields beside it; an SSH profile is a saved host (主机配置), not a file on
|
||||
disk; scrollback was 回滚, which means rollback — the opposite direction; and
|
||||
tty7's own server is now written `server`, the way `shell`, `pane` and `agent`
|
||||
already were, while 服务器 stays where it means the SSH host being connected
|
||||
to. (#334, #350, #417)
|
||||
|
||||
- **Kitty graphics frames cost one copy less** — a re-transmitting sender like
|
||||
terminal-browser sends a fresh full-window frame per rendered frame, ~26 MiB
|
||||
of RGBA at Retina resolution, and the client copied that buffer twice on the
|
||||
way to the atlas. The decode now consumes the frame `Vec` the reader already
|
||||
owns off the socket and drains the header off the front, and the uncompressed
|
||||
fast path moves the pixel buffer out so the R↔B swap happens in place. On a
|
||||
3216×2160 frame the decode-and-normalize step drops from ~1.78 ms to ~0.89 ms
|
||||
— about 53 ms/s at 60fps. (by @ayamir in #388)
|
||||
|
||||
- **Powerline separators are drawn with more curve segments**, so the
|
||||
half-circle caps read as circles at large font sizes.
|
||||
(by @cwatanab in #335, by @ArnoChenFx in #341)
|
||||
|
||||
- **macOS declares its privacy intents** — tty7 shipped no
|
||||
`NS*UsageDescription` keys, so macOS denied a pane's child process access to a
|
||||
protected folder (Containers, Mail, Messages, Calendar) with a repeated prompt
|
||||
instead of a single clear grant. The bundle now declares the folder, volume
|
||||
and device usage strings its peers declare, kitty-style, and the Full Disk
|
||||
Access manual grant is documented in the feature notes. No entitlement is
|
||||
added: the hardened-runtime automation check runs against the process actually
|
||||
sending an Apple event, which is the pane's child carrying its own signature,
|
||||
so granting one would only have widened what injected code could reach.
|
||||
(by @Gabyran in #323)
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -137,7 +306,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
the test suite, and CI all stayed green while the previous nightly
|
||||
shipped with the semantics half of the fix disabled and the maximize
|
||||
garbling intact. The flag is back, and a regression test now pins the
|
||||
wiring itself so the flag can't silently drop again.
|
||||
wiring itself so the flag can't silently drop again. (#419)
|
||||
|
||||
- **Maximizing a Windows pane no longer shreds it** — two separate resize
|
||||
disagreements stacked up here, and the visible one was the second.
|
||||
@@ -174,28 +343,144 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
probe), and on remote routes, where only the local daemon's features are
|
||||
known — a current remote daemon's echo lands there as a harmless
|
||||
same-size no-op, and probing per connection is the follow-up that
|
||||
extends deferral to remote panes.
|
||||
extends deferral to remote panes. (#415)
|
||||
|
||||
- **Pasting a screenshot into a remote pane works on macOS too** — the
|
||||
clipboard-image paste that stages a file and hands the agent its path was
|
||||
built off macOS only, because a local macOS agent reads the system
|
||||
clipboard itself when it sees Ctrl+V and that carries the image at full
|
||||
fidelity. The reasoning stops at the pane boundary: an agent in an SSH
|
||||
pane or a remote workspace reads the clipboard of the host *it* runs on,
|
||||
which never holds this machine's screenshot, so SYN was a no-op and the
|
||||
paste did nothing at all. Remote panes now stage and upload on every
|
||||
platform, while a local macOS pane keeps SYN untouched. macOS screenshots
|
||||
arrive as TIFF, which agent vision rejects the same way it rejects a
|
||||
Windows BMP, so those transcode to PNG on the way out. (#338)
|
||||
- **The whole window no longer hangs after a remote workspace reconnects** — on
|
||||
Windows, `shutdown()` does not wake a thread parked in a blocking `read()` on
|
||||
the same socket the way it does on unix, and pane teardown shut the writer
|
||||
down and then *joined* the reader, counting on that wake-up. When the peer
|
||||
stayed silent — a routed pane whose SSH leg went zombie: nothing arrives, no
|
||||
FIN ever comes — the join blocked its caller, which was the UI thread. That is
|
||||
the "not responding" freeze right after a reconnect.
|
||||
|
||||
- **A WSL pane is handed a path it can actually open** — the same paste
|
||||
staged its file on the Windows side and pasted the Windows name for it, so
|
||||
an agent in WSL got `C:\Users\…\paste-1.png` and found nothing there. A
|
||||
WSL pane shares this machine's disk but not its path syntax, so there is
|
||||
nothing to upload and only a name to rewrite: the paste now carries the
|
||||
automount view, `/mnt/c/Users/…`. A path with no mapping — a UNC temp
|
||||
directory — keeps the Windows name, which at least says where the file
|
||||
went. (#338)
|
||||
Teardown now sets a per-reader quit flag and abandons the thread instead of
|
||||
joining it. The reader's read always times out within 500 ms so a parked
|
||||
reader notices the flag promptly, and it checks the flag once per frame, so a
|
||||
retired reader processes nothing at all — without that, a buffered `Exited`
|
||||
arriving down an abandoned link could close the pane that had just adopted its
|
||||
replacement. The reader teardown had no Windows test coverage at all before
|
||||
this; the new tests block for over three seconds against the old code. (#407)
|
||||
|
||||
- **A Windows update that reported success and left the old build** — the
|
||||
updater stopped the daemon and started the Inno installer the moment the
|
||||
daemon's endpoint disappeared, but the endpoint going away is not the same
|
||||
event as the images being released. The ConPTY hosts (`OpenConsole.exe`) are
|
||||
the daemon's children, not the shells', so the per-pane kill never reached
|
||||
them, and the daemon's `exit(0)` skipped every destructor that would have
|
||||
closed them: they kept the installed `OpenConsole.exe` open for seconds after
|
||||
`--stop-daemon` returned. Silent Setup then hit the lock, took the suppressed
|
||||
dialog's default (Abort), and the recovery relaunched the old build. A daemon
|
||||
that died without cleaning up made it permanent — its orphaned hosts survive
|
||||
indefinitely, which is the `DeleteFile` code 5 users hit even after "closing
|
||||
everything".
|
||||
|
||||
Both shapes were reproduced in isolation first: with a pane open,
|
||||
`--stop-daemon` returned about a second in while `OpenConsole.exe` stayed
|
||||
locked for another 1.4 s; after killing the daemon outright, the orphaned host
|
||||
held the lock forever. The shutdown now finishes what it starts at every layer
|
||||
that can be the last one standing — the daemon reaps its descendants and waits
|
||||
for them while the endpoint is still up, `stop()` waits for the recorded pid to
|
||||
actually exit rather than merely stop listening, and
|
||||
`--stop-daemon --update-install-dir` also terminates anything still running
|
||||
from the installation directory and only returns once the `.exe`/`.dll` images
|
||||
there open for writing, naming the holdouts if they never do. The updater runs
|
||||
that clearing itself before invoking Setup, so a directory that cannot be
|
||||
cleared fails with a cause in `update.log` instead of Inno's bare
|
||||
"DeleteFile failed; code 5".
|
||||
|
||||
Three smaller holes closed with it: the macOS updater waits for its parent by
|
||||
watching `getppid()` reparent to launchd rather than polling `kill(pid, 0)`,
|
||||
which a recycled pid could satisfy forever; a Windows update guard makes
|
||||
`ensure_running` refuse to spawn a daemon mid-install, so a `tty7` CLI call
|
||||
cannot relock the images Setup is replacing; and a Windows portable backup
|
||||
carries an incomplete marker from the first file move until the replacement
|
||||
lands, so an interrupted update is reported at the next launch instead of
|
||||
leaving a silently mixed installation. (#403)
|
||||
|
||||
- **A newly installed command works in the next pane** — Windows hands every
|
||||
process a private copy of the environment block at `CreateProcess` time and
|
||||
never updates it, so a daemon that had been up since before an installer
|
||||
edited `HKCU\Environment` gave a brand-new pane its startup `PATH` and the
|
||||
freshly installed command was unresolvable until tty7 restarted. Windows
|
||||
Terminal launched from Explorer found it, because Explorer rebuilds its own
|
||||
block when it sees `WM_SETTINGCHANGE`.
|
||||
|
||||
Rather than chase broadcast messages, the daemon re-reads the two hives
|
||||
Windows itself composes an environment from — machine
|
||||
`Session Manager\Environment` and `HKCU\Environment` — at the moment a pane is
|
||||
spawned. The merge is a pure function over (machine, user, process, configured
|
||||
overrides), so the semantics are unit-testable without a registry: names are
|
||||
keyed case-insensitively so `Path` and `PATH` collapse into one variable;
|
||||
`PATH` and `PSModulePath` are *combined*, machine first, which is what Windows
|
||||
does and what keeps a per-user install from shadowing the system half;
|
||||
`REG_EXPAND_SZ` values are expanded against the merged map with a depth bound;
|
||||
the machine hive's `USERNAME=SYSTEM` is dropped as Windows drops it; and
|
||||
directories the daemon's own `PATH` held that neither hive lists stay
|
||||
reachable, appended behind the registry entries — freshening `PATH` should
|
||||
only ever add resolvable commands. (#349, reported by @yhzhu99 in #333)
|
||||
|
||||
- **Windows panes can answer a background-color query** — the in-box conhost
|
||||
swallows a pane process's OSC 11 query, so it never reached tty7's emulator
|
||||
and no reply was written back: applications that pick a light or dark UI from
|
||||
the terminal background rendered a dark UI under a light theme. tty7 already
|
||||
answers OSC 10/11/12 from the live theme, so nothing was missing but a
|
||||
pseudoconsole that forwards the question. Microsoft ships one as a
|
||||
redistributable and `portable-pty` already prefers a sideloaded `conpty.dll`
|
||||
over kernel32's, so this is packaging rather than code: the pair goes beside
|
||||
`tty7-app.exe`.
|
||||
|
||||
Measured on Windows 11 26200, same binary, only the pair added beside it: with
|
||||
the in-box host the client times out with no reply; with the bundled ConPTY a
|
||||
real pane reads back `rgb:efef/f1f1/f5f5` under `catppuccin_latte`, which is
|
||||
that preset's exact background. The two files are one supported unit, so the
|
||||
release verifier fails a package carrying only one, a mismatched pair, or a
|
||||
DLL without its MIT notice, and `build.rs` stages them beside cargo's output
|
||||
so a development build does not quietly run on the in-box host.
|
||||
(#360, reported by @yhzhu99 in #345)
|
||||
|
||||
- **A second cursor no longer blinks in the wrong place on Windows** —
|
||||
conhost's VT renderer brackets every frame it paints with `?25l` … `?25h` so
|
||||
the cursor does not flicker across the repaint, and it moves the cursor
|
||||
explicitly just before the show only on the frames where it painted the
|
||||
cursor. On the others the show commits wherever the last erase or write left
|
||||
it, and the cursor blinks there until conhost's next frame moves it back. tty7
|
||||
repaints when a batch of pty output lands, so it draws that cursor for a frame
|
||||
— and a TUI that repaints on a spinner produces one every tick.
|
||||
|
||||
Measured on Windows 11 26200 from a raw ConPTY capture of a Codex session at
|
||||
110×30: 295 ms of cursor-visible dwell across 42 frames parked at the end of
|
||||
the status line, each stray corrected 7–15 ms later by the following frame.
|
||||
A scanner now pairs each hide with its show and marks the show as *parked*
|
||||
when the run in between moved the cursor around to paint but did not end on a
|
||||
move — nothing chose the cell it is about to appear on — and restores the cell
|
||||
the cursor stood on when it went invisible, which is where the correcting
|
||||
frame would have put it anyway. A hide and a show more than 100 ms apart are
|
||||
an application keeping the cursor off for the length of some work, not a
|
||||
renderer bracketing one frame, and are left alone. This is inert where the
|
||||
bundled ConPTY redistributable is in play; it earns its keep on hosts without
|
||||
it, notably a remote Windows server. (#362)
|
||||
|
||||
- **Windows toasts are tty7's, not PowerShell's** — notifications showed the
|
||||
PowerShell icon and name because tty7 had no AUMID of its own registered. It
|
||||
now brands the process and refreshes the single per-user `tty7.lnk` Inno's
|
||||
default install owns — but only when that shortcut is not already ours, never
|
||||
from a cargo build directory, and never as a second per-user copy beside an
|
||||
all-users install, all three of which the first cut got wrong on a real
|
||||
machine. The shell indexes a new `.lnk` asynchronously and `Toast::show()`
|
||||
reports success while dropping the toast for an AUMID it has not seen yet, so
|
||||
toasts keep the PowerShell identity for half a minute after tty7 writes one:
|
||||
ugly beats invisible. (by @shihuaidexianyu in #340, reported in #339)
|
||||
|
||||
- **Windows panes are told whether the window is light or dark** — the daemon
|
||||
needs to know when it spawns a pane, because ConPTY drops the child's OSC 11
|
||||
query before tty7's emulator can answer it. It was reading that from a dead
|
||||
`Config::theme` field, which meant the GUI had to rewrite the user's
|
||||
`config.json` every time the effective preset changed sides. The hint moves to
|
||||
its own `appearance.json` in the data dir: derived state, written by the
|
||||
process that paints the window and read by the one that has to describe it.
|
||||
Absent, unreadable and unparsable all read as light — what the default preset
|
||||
is — so a daemon that starts before the GUI has ever applied a theme describes
|
||||
the default window instead of guessing. (by @yhzhu99 in #332)
|
||||
|
||||
- **Scoop shims work again when tty7 is launched from a hardened Windows
|
||||
shell broker** — some brokers enforce `ProcessRedirectionTrustPolicy` on
|
||||
@@ -213,7 +498,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
mitigation policy. Everything else about the spawn is unchanged, and the
|
||||
ordinary path still runs whenever the policy is absent — or whenever the
|
||||
desktop shell cannot be borrowed, in which case tty7 logs a warning and
|
||||
starts degraded rather than not starting at all. (#292)
|
||||
starts degraded rather than not starting at all. Note the daemon's token on
|
||||
the clean-parent path derives from Explorer, so an elevated tty7 starts a
|
||||
medium-integrity daemon. (by @ArnoChenFx in #292)
|
||||
|
||||
- **A pane's last line of output no longer loses the race with its exit on
|
||||
Windows** — the process-exit monitor could observe a short-lived shell
|
||||
@@ -223,7 +510,353 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
only after it has forwarded everything up to EOF, announce the death. A
|
||||
bounded window behind it still covers the case where EOF never arrives —
|
||||
a grandchild holding the ConPTY output pipe open keeps the shell's own
|
||||
exit from ever closing it. (#292)
|
||||
exit from ever closing it. (by @ArnoChenFx in #292)
|
||||
|
||||
- **A resumed agent keeps the flags it was launched with, on Windows** — on
|
||||
macOS and Linux the daemon reads the foreground process's real argv, so
|
||||
`resume_command` can replay a launch flag like
|
||||
`--dangerously-skip-permissions`. The Windows path detects the agent from the
|
||||
OSC 133;C command capture but threw the command line away, stamping an empty
|
||||
argv, so every resumed agent came back bare. The captured command is now
|
||||
tokenized (case preserved, quotes trimmed, the PowerShell call operator
|
||||
dropped) and stamped as the pane's launch argv; fork commands share that
|
||||
source and are fixed by the same change. (#406)
|
||||
|
||||
- **Codex hook commands work under PowerShell on Windows** — the installed hook
|
||||
command is written as a PATH-resolvable bare name rather than a path
|
||||
PowerShell would not run. (by @shihuaidexianyu in #298)
|
||||
|
||||
- **Switching workspaces no longer destroys live sessions** — it rebuilt every
|
||||
pane it was asked to restore, and a window that rebuilt nothing then deleted
|
||||
the workspace outright, tree and store both. Three separate guesses, each one
|
||||
authorizing an irreversible act.
|
||||
|
||||
`session_from_tree` erased a pane's id when the tree said `live: false`. That
|
||||
flag is a cached observation from another process, reloaded as false on every
|
||||
server start, so a quiet pane read as dead while its shell was running: the
|
||||
restore had nothing to attach to and spawned a fresh shell over it. Two
|
||||
servers could also start against one config dir — `run_with` decided another
|
||||
server was dead by failing to connect once, then unlinked its socket and bound
|
||||
its own, and the loser kept `control.sock` with an empty pane registry, so
|
||||
`MachineGet` reported every pane dead and nothing logged an error. And
|
||||
`finish_hydration` marked a window informed before the rebuild and without
|
||||
looking at the result, while `tabs_from_session` drops any tab whose panes all
|
||||
fail to start — which is every tab when the pane socket is unreachable —
|
||||
leaving a window that was empty and authoritative at once, so the next switch
|
||||
deleted a workspace with ten live tabs.
|
||||
|
||||
Each is now settled by whoever holds the truth: attaching decides whether a
|
||||
pane is there, an advisory lock decides which process is the server, and a
|
||||
deletion needs the machine's own mirror to agree that the workspace is empty.
|
||||
A corrupt `views.json` is quarantined the way `machine.json` already was,
|
||||
rather than logged and overwritten by the next save. (#410)
|
||||
|
||||
- **Tab in a WSL pane completes paths again** — the pane's filesystem is
|
||||
foreign, so the completion engine had no cwd to list and handed every Tab back
|
||||
to bash. A WSL pane's POSIX cwd (OSC 7) is now translated to the distro's
|
||||
`\\wsl$` share, which this process can read like any directory, while
|
||||
everything that would consult *this* machine stays switched off: no `PATH`
|
||||
binaries in the command position, no generator scripts, and `~` is left to the
|
||||
shell, since it names the distro's home. Absolute words stay inside the share,
|
||||
so `ls /etc<Tab>` lists the distro's `/etc` and not `C:\etc`. A `wsl.exe` pane
|
||||
spawned without `--distribution` resolves the default distro from the registry
|
||||
rather than carrying an empty placeholder.
|
||||
|
||||
The follow-up fixed the gate that had made this unreachable for the case it
|
||||
was written for: a pane in a WSL *workspace* is served by the daemon inside
|
||||
the distro, so its host id is never `LOCAL`, and an early locality check threw
|
||||
those panes away. The check belongs only to the `wsl.exe`-in-a-local-workspace
|
||||
branch — a remote host's WSL pane must not read a same-named share here —
|
||||
while a WSL workspace is this computer's distro by construction. (#408, #418)
|
||||
|
||||
- **A WSL machine can restart and replace its server** — the machine menu
|
||||
offered "restart server" only when the target was SSH, so a distro's row had
|
||||
just "new workspace" and "disconnect", and the router refused the action for
|
||||
anything else even though `restart_wsl_daemon` had been sitting unused since it
|
||||
was written. A distro's server is installed and launched from this computer
|
||||
exactly like an SSH one; only the transport differs. Both actions now have WSL
|
||||
arms, so the mismatch dialog's **Update Server** is no longer a dead end
|
||||
there. A `--stdio` workspace still has nothing to restart: it is whatever
|
||||
program the user named. (#417)
|
||||
|
||||
- **The mismatch dialog replaces the server binary instead of just restarting
|
||||
it** — the old **Restart Server** button restarted the same incompatible
|
||||
daemon, leaving the user on the same mismatch afterwards. It now replaces the
|
||||
binary and then restarts, and says so: **Update Server**.
|
||||
(by @shihuaidexianyu in #352, reported in #351)
|
||||
|
||||
- **A version-mismatched remote server is described as old, not as
|
||||
not-tty7** — a handshake refused on the control dialect was shown with the
|
||||
protocol layer's own wording: "java answered, but not as a tty7 server:
|
||||
control peer (build …) speaks control v4, this build speaks v5". The far end
|
||||
*is* tty7; it is a build on the other side of a dialect bump, and the reader
|
||||
cannot act on the dialect numbers either way. The message now states which
|
||||
side is behind, and the button names the action. The failure that followed was
|
||||
also invisible: the switcher paints a failed `connect` in preference to stored
|
||||
host errors, and restarting or replacing a server cleared only the latter, so
|
||||
whatever went wrong during the install was covered by the complaint that
|
||||
started it. (#384)
|
||||
|
||||
- **Remote server errors appear under the machine they came from** — restart and
|
||||
replace failures were reported through a global modal, which mixed errors from
|
||||
different machines together and blocked the UI. They are now stored per host
|
||||
and surfaced in that host's switcher group, which expands to show them, with a
|
||||
Dismiss button scoped to its own host and a clear on the next connect so a
|
||||
later success does not leave a stale failure on screen. A failure raised where
|
||||
there is no switcher to put it in — the window menu's restart command, or a
|
||||
mismatch hit mid-connect — still falls back to the modal.
|
||||
(by @shihuaidexianyu in #354)
|
||||
|
||||
- **An SSH remote install uses the bundled server before reaching for the
|
||||
network** — it only ever checked the release download path and ignored the
|
||||
server binary already shipped beside the Windows executable, which WSL was
|
||||
using. The bundled binary is now auto-discovered and the GitHub release
|
||||
download is the fallback for when no matching local asset exists. The explicit
|
||||
path keeps its strict no-fallback behavior, and WSL remains bundled-only.
|
||||
(by @shihuaidexianyu in #344)
|
||||
|
||||
- **A server that is only a control dialect behind is noticed at launch** — the
|
||||
pane protocol and the control dialect are versioned apart and the launch check
|
||||
only compared the first, so a server from before the v4-to-v5 control bump
|
||||
answered the pane handshake with this build's own number and was waved through
|
||||
as ours while every machine-tree call was refused: the window opened with no
|
||||
tabs and the only trace was a log line the default config does not write
|
||||
anywhere. The control socket is asked too now, and the restart prompt says
|
||||
which version disagrees and picks its wording by which side is ahead, rather
|
||||
than calling a newer server old. A window that still opens empty says why —
|
||||
once per window, latched, since a failed pull is retried from every
|
||||
fifteen-second sync. (#387)
|
||||
|
||||
- **"Keep Shells" is no longer offered beside a mismatched server** — both
|
||||
handshakes compare their version for equality and hang up on anything else, so
|
||||
a server whose number disagrees cannot be talked round, and that button
|
||||
offered a state that does not work: panes still spawn while every machine-tree
|
||||
call is refused, which is how a window opens with no tabs and saves none of
|
||||
the ones you make. The choice is now restart or quit. Quit goes first, because
|
||||
it destroys nothing — the server and every shell under it keep running — and
|
||||
because this prompt arrives unasked at launch, the moment a stray Return is
|
||||
likeliest. A prompt dismissed without an answer re-arms instead of falling
|
||||
through. (#389)
|
||||
|
||||
- **Pasting a screenshot into a remote pane works** — the clipboard-image paste
|
||||
that stages a file and hands the agent its path was built off macOS only,
|
||||
because a local macOS agent reads the system clipboard itself when it sees
|
||||
Ctrl+V and that carries the image at full fidelity. The reasoning stops at the
|
||||
pane boundary: an agent in an SSH pane or a remote workspace reads the
|
||||
clipboard of the host *it* runs on, which never holds this machine's
|
||||
screenshot, so the paste did nothing at all. Remote panes now stage and upload
|
||||
on every platform, while a local macOS pane keeps its direct path untouched.
|
||||
macOS screenshots arrive as TIFF, which agent vision rejects the same way it
|
||||
rejects a Windows BMP, so those transcode to PNG on the way out.
|
||||
|
||||
Staging is hardened on the remote side. `/tmp/tty7-clipboard-<user>` is a
|
||||
predictable name in a world-writable directory: any local account on the
|
||||
remote host could pre-create it, and the `Mkdir` result was discarded, so tty7
|
||||
would have uploaded into a directory someone else owned — readable by them,
|
||||
and swappable for another image before the pane's agent opened the path.
|
||||
Images now stage in `$HOME/.cache/tty7/clipboard` resolved from the session's
|
||||
own `realpath .`, and the directory is verified before anything goes into it:
|
||||
a symlink is refused outright, a `chmod 0700` the daemon watched succeed is
|
||||
the ownership proof, and a following `stat` must report exactly `0700`. Any
|
||||
doubt is a hard failure that falls back to pasting the local path. The whole
|
||||
path also moves off the UI thread, which is what lets a failed upload notify
|
||||
once, naming the host and the reason, instead of leaving a dangling remote
|
||||
path in the line and saying nothing.
|
||||
(by @shihuaidexianyu in #338, reported in #337; #399)
|
||||
|
||||
- **A WSL pane is handed a path it can actually open** — the same paste staged
|
||||
its file on the Windows side and pasted the Windows name for it, so an agent in
|
||||
WSL got `C:\Users\…\paste-1.png` and found nothing there. A WSL pane shares
|
||||
this machine's disk but not its path syntax, so there is nothing to upload and
|
||||
only a name to rewrite: the paste now carries the automount view,
|
||||
`/mnt/c/Users/…`. A path with no mapping — a UNC temp directory — keeps the
|
||||
Windows name, which at least says where the file went. (#399)
|
||||
|
||||
- **Arrow keys reach ncurses applications in the form they asked for** — Arrow,
|
||||
Home and End were always sent as their CSI form, no matter what the foreground
|
||||
program had requested. Programs that turn on DECCKM via `smkx` — which is
|
||||
every ncurses full-screen app — expect the SS3 form, because that is what
|
||||
`xterm-256color` spells `kcuu1` and friends as, and ncurses matches terminfo
|
||||
byte for byte. htop was the report: ncurses failed to match `\E[A`, handed the
|
||||
bytes to htop one at a time, and htop binds `[` to "lower priority", so every
|
||||
Up or Down bumped the selected process's nice value instead of moving the
|
||||
selection. The same breakage hit ncdu, mc, dialog, menuconfig and nmtui;
|
||||
shells were unaffected because readline and zle bind both forms.
|
||||
|
||||
Named keys now also carry their modifiers the way terminfo declares them
|
||||
(`kLFT=\E[1;2D`, `kUP5=\E[1;5A`, `kDC3=\E[3;3~`) instead of dropping
|
||||
Shift/Ctrl entirely and prefixing Alt with a bare ESC. Cmd stays out of the
|
||||
modifier parameter — xterm has no encoding for it.
|
||||
(#366, reported by @hak0 in #361)
|
||||
|
||||
- **A right-click goes to the application when mouse reporting is on** — a TUI
|
||||
that turns mouse reporting on (vim with `set mouse=a`, lazygit, tmux) draws its
|
||||
own right-button menus, and tty7 was delivering one right-click to both
|
||||
consumers: the press was forwarded to the application *and* tty7's own context
|
||||
menu popped over the top of it. One pure predicate now decides, called from
|
||||
both sides, so one click can only ever feed one consumer; Shift stays the
|
||||
escape hatch that reaches tty7, the same override it already provides for
|
||||
selection and for the wheel. (#347)
|
||||
|
||||
- **`$SHELL` names the shell the pane actually runs** — a pane configured to run
|
||||
fish still advertised the login shell, because the pane environment injected
|
||||
`TERM`, the `TTY7_*` markers and `TERM_PROGRAM` but never touched `SHELL`, so
|
||||
the pane inherited the GUI session's login-time snapshot. Everything that
|
||||
spawns "the user's shell" read that: tmux's `default-shell` started zsh inside
|
||||
a fish pane, and so did `sudo -s`, an editor's shell escape, and any coding
|
||||
agent picking a quoting dialect from `$SHELL`. The failure is silent — fish
|
||||
rejects the bash line, the agent's sentinel file never appears, and the
|
||||
rejected text stays in the line editor to concatenate onto the next send.
|
||||
|
||||
`SHELL` is now injected alongside the other markers, set to the absolute path
|
||||
of the program the pane is about to exec, read off argv rather than off the
|
||||
shell tty7 resolved — an argv-replacing integration injection and the
|
||||
parent-shell override both rewrite argv. Only an absolute path is ever
|
||||
written: a configured command may be bare so `PATH` decides which install
|
||||
wins, so a bare name is resolved against the `PATH` the pane will inherit and
|
||||
skipped when that finds nothing. An explicit `SHELL` in the user's env block
|
||||
still wins. Windows is deliberately left out — neither cmd nor PowerShell reads
|
||||
`SHELL`, and the POSIX emulations that do want a POSIX path.
|
||||
(#348, reported by @nohzafk in #342)
|
||||
|
||||
- **The login shell is read from passwd, not from a stale `$SHELL`** — `$SHELL`
|
||||
is a snapshot the session inherits at login, so `chsh` never moves it: a GUI
|
||||
launch kept reporting the shell that was current when the user logged in, and
|
||||
the window's shell menu marked the wrong entry "default" for that whole
|
||||
stretch. The passwd entry is read instead, via the reentrant `getpwuid_r`,
|
||||
with `$SHELL` as the fallback. The same change fixes who wins a name in the
|
||||
menu: `$PATH` is probed before `/etc/shells`, so on a machine with a Homebrew
|
||||
bash the menu's "bash" is the binary typing `bash` would reach rather than
|
||||
macOS's 3.2 from 2007. (#278)
|
||||
|
||||
- **A forwarding `.bash_profile` no longer sources `.bashrc` twice** — the
|
||||
rcfile tty7 hands bash replays the login-shell startup chain, but then sourced
|
||||
`~/.bashrc` unconditionally afterwards. A login shell never does that on its
|
||||
own: `~/.bashrc` arrives only because the profile that won the chain forwarded
|
||||
to it, which is how nearly every `~/.bash_profile` is written. The result was
|
||||
the user's whole `~/.bashrc` running twice per pane — banners printed twice,
|
||||
completions sourced twice, appends to `PROMPT_COMMAND` stacking up.
|
||||
`~/.bashrc` joins the same first-match-wins chain, which keeps the fallback
|
||||
for a `$HOME` with no profile at all. (#279)
|
||||
|
||||
- **The macOS locale fallback sets `LANG`, not `LC_CTYPE`** — when a pane
|
||||
inherits no locale at all, the usual case for a GUI-launched process on macOS,
|
||||
tty7 derives an installed UTF-8 locale and injects it — but as `LC_CTYPE`,
|
||||
which backs only character handling. Collation, time and numbers stayed at C,
|
||||
and bash warned `setlocale: LC_COLLATE: cannot change locale ()` once per
|
||||
category on every launch; zsh and fish swallowed the failure and merely looked
|
||||
fine while being just as half-configured. `LANG` backs every category and
|
||||
still loses to any `LC_*` the user's own rc files set afterwards, which is
|
||||
what a fallback should do. (#280)
|
||||
|
||||
- **Three defects in the inline completion menu** — a candidate was inserted
|
||||
verbatim, so a directory named `My Documents` completed to `cd My Documents/`,
|
||||
which the shell resplits into two arguments; candidates are escaped now, with
|
||||
a leading `~/` left alone since that prefix is the user's own text and escaping
|
||||
it would stop the home expansion it was typed for. The same escape decides
|
||||
whether a common-prefix step is safe to write — the prefix shared by
|
||||
`My Documents` and `My Music` is `My `, and writing it raw both broke the line
|
||||
and closed the menu on the next keystroke — so a prefix that needs escaping
|
||||
steps through the candidates instead. A menu fed only by generators stayed
|
||||
armed forever when nothing matched, swallowing every later Tab instead of
|
||||
handing the line to the shell; sessions now count their generators and the
|
||||
last one to answer closes a menu that still has nothing in it. And command
|
||||
completion scanned *this* machine's `PATH` in a remote pane, so
|
||||
`system_prof<Tab>` over SSH to Linux offered macOS's `system_profiler` —
|
||||
builtins are true on any POSIX shell and still go out, the `PATH` scan is now
|
||||
local-only. (#276)
|
||||
|
||||
- **macOS editing shortcuts reach a foreground TUI** — Cmd+Backspace and the
|
||||
rest of the line-editing chord set are forwarded to the application instead of
|
||||
being swallowed. (by @loscoy in #304)
|
||||
|
||||
- **Ctrl-E accepts a ghost suggestion on the first try** — it accepts a visible
|
||||
inline history suggestion while keeping end-of-line behavior when none is
|
||||
shown. (by @vkingw in #329, reported in #315)
|
||||
|
||||
- **No stray `^U` after interrupting an agent** — typeahead captured across an
|
||||
alt-screen boundary was replayed into the line editor after the interrupt.
|
||||
(by @shihuaidexianyu in #312, reported by @fuchen in #305)
|
||||
|
||||
- **The editor is restored after an interrupted tab handoff.** (#290)
|
||||
|
||||
- **ANSI dim text and text decorations render** — underline, double underline,
|
||||
curly, dotted, dashed, overline and strikethrough, and SGR 2 dim.
|
||||
(#288, #289)
|
||||
|
||||
- **Powerline separators have no seam between them** — adjacent separators left
|
||||
a hairline of background between the two glyphs. A cover quad closes it, and
|
||||
is skipped when the glyph is dim: the cover and the anti-aliased path overlap
|
||||
on the closing edge's device pixel, which is a no-op for an opaque foreground
|
||||
but pushes a dim cell's alpha to 0.884 and tints the neighboring cell's
|
||||
background. (by @ArnoChenFx in #336)
|
||||
|
||||
- **Tokens that bypassed the contrast machinery now have a floor** — sidebar
|
||||
text, the caret and hairlines were flat blends with no floor, sitting one line
|
||||
away from tokens that are bisected to hit a target exactly, and semantic inks
|
||||
were floored against the window background but painted on popovers and sidebar
|
||||
rows, which sit a step toward the foreground. `sidebar_fg` is floored at 4.5:1
|
||||
on the sidebar fill it is actually painted on — four builtins landed at
|
||||
3.35–3.92:1 — the caret is conditioned to 3:1, where the default Light theme
|
||||
shipped an orange caret on pure white at 2.07:1, `border` keeps its blend but
|
||||
gains a 1.5:1 floor so a divider is worth the same in every theme, and
|
||||
semantic inks clear their floor on background, sidebar and popover alike.
|
||||
Themes that already cleared a floor are untouched. (#400)
|
||||
|
||||
- **Smooth scroll steps are aligned with presented frames**, and a queued scroll
|
||||
animation wakes the window. (by @ArnoChenFx in #414)
|
||||
|
||||
- **Kitty graphics frames cannot pile up faster than they decode** — the
|
||||
unbounded decode channel becomes a bounded latest-frame inbox, so a
|
||||
full-window sender cannot queue frames faster than they are consumed, and
|
||||
superseded frames are discarded before being decoded. Only images that reached
|
||||
the sprite atlas are retired, and remaining atlas entries are evicted when a
|
||||
pane closes, which keeps hidden terminal-browser tabs and repeated pane
|
||||
lifecycles from retaining one decoded frame per repaint.
|
||||
|
||||
- **The terminal's own context menu and search bar are translated** — the
|
||||
context menu was the last surface still speaking hardcoded English in a
|
||||
three-locale app, 14 literals of it, and the search bar had three more with
|
||||
its Previous / Next / Close buttons icon-only and untooltipped. It also spoke
|
||||
a fourth vocabulary for one action: "Maximize Pane" for what the menu bar, the
|
||||
palette and Keybindings all call "Zoom Pane", and "Close Pane" for what is
|
||||
"Close Pane / Tab" everywhere else — which is the accurate name, since the
|
||||
action closes the tab when the pane is the last one. (#401)
|
||||
|
||||
- **A new tab lands in its repo group on the first frame** instead of appearing
|
||||
ungrouped for one paint. (by @ArnoChenFx in #411)
|
||||
|
||||
- **Settings hover highlights respond immediately**, with a stable row identity
|
||||
so the highlight does not jump between rows. (by @ArnoChenFx in #313)
|
||||
|
||||
- **Overlay scrollbars are softer.** (#293)
|
||||
|
||||
- **`tty7 send` submits its Enter outside a paste burst**, so an agent does not
|
||||
read the newline as part of pasted text. (#322)
|
||||
|
||||
- **Closing a tab from the CLI terminates its panes.** (#319)
|
||||
|
||||
- **`tty7` diagnoses an unavailable agent hook** instead of failing silently.
|
||||
(#321)
|
||||
|
||||
- **tty7 no longer panics on launch under Wayland on a slow VM** — the
|
||||
xdg-desktop-portal event source notified windows of the initial color-scheme
|
||||
and button-layout replies while still holding `client.borrow_mut()`, and those
|
||||
callbacks re-enter GPUI and reach the same `RefCell`. Whether it fires depends
|
||||
on whether the portal reply beats window creation, so a VMware Ubuntu guest
|
||||
lost that race every time. Fixed in the gpui fork for both the Wayland and X11
|
||||
clients by collecting the window pointers and dropping the borrow before
|
||||
notifying.
|
||||
|
||||
- **The Windows package verifier can read the Inno payload again** — the bundle
|
||||
script deleted the staging directory as its last act, and the verifier reads
|
||||
that directory to check what lands in `{app}`, since a compiled `setup.exe`
|
||||
cannot be read back without innoextract. Every Windows build had failed the
|
||||
check since it arrived, taking nightly red for two nights, and a stable
|
||||
release would have failed the same way. Both workflows already expected the
|
||||
directory to survive — their upload steps name it among the intermediates the
|
||||
asset globs deliberately skip — so the removal goes rather than the check.
|
||||
(#368)
|
||||
|
||||
## [26.8.1] - 2026-08-01
|
||||
|
||||
|
||||
Generated
+4
-4
@@ -9663,7 +9663,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tty7"
|
||||
version = "26.8.1"
|
||||
version = "26.8.2"
|
||||
dependencies = [
|
||||
"alacritty_terminal",
|
||||
"anyhow",
|
||||
@@ -9706,7 +9706,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tty7-cli"
|
||||
version = "26.8.1"
|
||||
version = "26.8.2"
|
||||
dependencies = [
|
||||
"alacritty_terminal",
|
||||
"anyhow",
|
||||
@@ -9721,7 +9721,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tty7-core"
|
||||
version = "26.8.1"
|
||||
version = "26.8.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
@@ -9753,7 +9753,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tty7-server"
|
||||
version = "26.8.1"
|
||||
version = "26.8.2"
|
||||
dependencies = [
|
||||
"tempfile",
|
||||
"tty7-core",
|
||||
|
||||
+1
-1
@@ -251,7 +251,7 @@ edition = "2024"
|
||||
# they must never drift apart. This is the line a release bump edits (and the
|
||||
# one nightly's `awk '/^version = /'` stamps: it is the first such line in the
|
||||
# file, since the package entries above are all `version.workspace = true`).
|
||||
version = "26.8.1"
|
||||
version = "26.8.2"
|
||||
|
||||
[workspace.dependencies]
|
||||
# Our fork's `tty7` branch carries the local customizations tty7 relies on:
|
||||
|
||||
Reference in New Issue
Block a user