Skip to content

Releases

tether-e3a345b

Choose a tag to compare

@github-actions github-actions released this 01 Oct 18:58
fix: resync decoder on fresh ESC mid-sequence, keep build version cur…

tether-b5ac2ea

Choose a tag to compare

@github-actions github-actions released this 01 Oct 15:34
fix: close audit low findings L1-L13, keep L4/L14 as documented risks

tether-f42cec0

Choose a tag to compare

@github-actions github-actions released this 30 Sep 11:04
ci: publish per-push release tagged by commit hash (artifacts flaky)

tether-efea8fe

Choose a tag to compare

@github-actions github-actions released this 30 Sep 11:40
ci: install upx so release binaries are packed

tether-af1d8ff

Choose a tag to compare

@github-actions github-actions released this 30 Sep 19:51
fix: keep the release probe off non-interactive starts, and cover the…

tether-a521ba3

Choose a tag to compare

@github-actions github-actions released this 30 Sep 15:24
fix: contain new files lexically, without letting surplus ".." escape

realpath(3) fails on missing paths, so within_workspace answered
"outside" for every new file (bogus approval menu) and atomic_write's
sibling temp file then died with "cannot open temp file" (bogus failure
after approval). Resolve the nearest existing ancestor and reattach the
missing tail lexically, and create the parent directories before writing.

The lexical tail cancels name/.. pairs, but a ".." with nothing left to
cancel climbs above the existing ancestor — swallowing it read as
"inside" for ws/newdir/../../<outside>/file, and the new mkdirp then
created newdir, at which point the kernel resolved that very string
outside the workspace. Such a path now has no lexical answer and goes
through the outside-workspace confirmation. T-missing-paths' realpath
stub gains -e: bare coreutils realpath tolerates a missing last
component, realpath(3) (src/host/main.c:437) does not, and the stub
claimed to be faithful.

tether-707e9b2

Choose a tag to compare

@github-actions github-actions released this 30 Sep 18:06
feat: self-update — startup release probe, banner row, `tether update`

An install is a throwaway tarball run from ~/.local/bin, so updating it meant
rebuilding or re-downloading by hand. Releases are already published per push to
main under tag tether-<sha>, so the newest build is one small text file away.

Identity is a git short sha, which has no ordering, so any cached sha other than
the running build reads as "update available" — a locally-built newer commit
therefore suggests a downgrade, the ceiling marked ponytail: in update.lua. The
probe never runs in front of the user: startup reads ~/.tether/update.json,
decides from disk inside the 24h TTL, and otherwise hands the VERSION fetch to
tether.fetch_bg with an update.json.pending marker, reusing metadata.lua's
detached-probe discipline (empty marker younger than 120s = child still running,
older = dead, drop and reschedule; FETCH_FAILED cools down by stamping
checked_at). The banner is one role="system" row seeded after the splash in
ui._startup_rows, so /clear and /new stay splash-only and it shows at most once
per session. The copy lives in update.lua because copy.lua's TCOPY guard rejects
the literal release-name token it would have to quote. update_check=false in the
config skips probe and banner; --print skips both too.

CI now publishes two more assets next to the tarball: the bare binary and a
VERSION file. A tar.gz would need a gzip+tar decoder on the Lua side, and both
URLs use the releases/latest/download web host rather than the REST API, which is
capped at 60 unauthenticated requests per hour per IP.

`tether update` is trimmed before the flag parser, like the extension verbs:
http_get VERSION, http_get the bare binary, reject an empty body, a body without
the ELF magic or one under the size floor, then write a temp file in the running
executable's own directory, fchmod 0755, os.rename over the target. Rename is
required, not tidiness — this process IS the file being replaced, so an in-place
write would fail with ETXTBSY while a rename only re-links the dirent and leaves
the live inode alone. Refusals (no exepath, dev build, unwritable directory,
failed rename) exit non-zero with the path and the sudo / make install
PREFIX=$HOME/.local way forward.

T293–T312 in tests/update_tests.lua (config coercion and bootstrap, strict
version parse, cache round-trip and truncated file, probe lifecycle against a
stubbed tether table, notice rules, seed/width/mono, verb dispatch before flag
parsing, full swap on a fake exe tree plus rejected blobs), and a pty run of the
built binary against a local stub release server: banner renders once under the
wordmark, empty-cache start returns in 0.12s and the marker folds into
update.json for the next launch, disabled and unreachable-source starts stay
silent and fast.

tether-534cfa9

Choose a tag to compare

@github-actions github-actions released this 30 Sep 11:33
build: install to ~/.local/bin, UPX-pack make tether