Give the mouse back, retire the follow controls, update Claude per session #54

Merged
jknapp merged 3 commits from feat/mouse-release-retire-follow-update into main 2026-09-08 23:43:35 +00:00
3 Commits
Author SHA1 Message Date
shadowdaoandClaude Opus 5 5d16b5713d Give BuildKit the host's network, so it can reach the runner's cache
Secret Scan / scan (push) Successful in 4s
Build App (Preview) / compute-version (pull_request) Successful in 6s
Secret Scan / scan (pull_request) Successful in 6s
Build App (Preview) / create-release (pull_request) Successful in 2s
Build App (Preview) / build-macos (pull_request) Successful in 2m45s
Build App (Preview) / build-windows (pull_request) Successful in 4m45s
Build App (Preview) / build-linux (pull_request) Successful in 7m38s
Build App (Preview) / prune-previews (pull_request) Successful in 4s
Build Container / build-container (pull_request) Successful in 14m48s
The multi-arch build needs the `docker-container` driver — the plain `docker`
driver cannot do linux/amd64+linux/arm64 — and that driver runs BuildKit in
its own container on Docker's default bridge. act_runner advertises
ACTIONS_CACHE_URL as an address the *job* container can reach, and nothing
teaches the BuildKit container about it. So the job could reach
192.168.1.126:40649 while the container actually making the cache request
could not.

That is also why no other workflow here hit this: it is the only one using
buildx. The rest make their cache calls from the job container act_runner set
up.

`no route to host` is EHOSTUNREACH — a firewall rejecting, not a missing route
— which is what a default firewalld zone does to traffic from the docker
bridge, and the runner registers under the stock RHEL/Fedora hostname.
Sharing the host's namespace sidesteps it: the cache address becomes local to
BuildKit. No effect on runners where this already worked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145mQi9NZiCDrznBUEEDE4n
2026-09-08 15:30:27 -07:00
shadowdaoandClaude Opus 5 c02c02cbfc Never fail a container build because the cache was unreachable
Secret Scan / scan (push) Successful in 4s
Build App (Preview) / compute-version (pull_request) Successful in 3s
Secret Scan / scan (pull_request) Successful in 4s
Build App (Preview) / create-release (pull_request) Successful in 1s
Build App (Preview) / build-macos (pull_request) Successful in 2m41s
Build App (Preview) / build-windows (pull_request) Successful in 4m52s
Build App (Preview) / build-linux (pull_request) Successful in 8m0s
Build App (Preview) / prune-previews (pull_request) Successful in 2s
Build Container / build-container (pull_request) Successful in 10m21s
Every layer of both architectures built. The job then died exporting to
act_runner's emulated GitHub Actions cache service, which it could not route
to: `GetCacheEntryDownloadURL ... dial tcp 192.168.1.126:40649: no route to
host`.

On a pull_request `push:` is false, so this job pushes nothing and the cache
is its only output — which means a network problem between the buildx
`docker-container` builder and the runner host threw away a complete,
successful validation of the Dockerfile on linux/amd64 and linux/arm64. A
cache is an optimisation; it must degrade to "slow", never to "red".

Only the exporter needs the flag. The import is already non-fatal — the build
ran all 37 layers after warning it could not read the cache.

This does not fix the routing itself, so builds stay uncached until that is
sorted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145mQi9NZiCDrznBUEEDE4n
2026-09-08 12:48:41 -07:00
shadowdaoandClaude Opus 5 c0e4c87cec Give the mouse back, retire the follow controls, update Claude per session
Secret Scan / scan (push) Successful in 4s
Build App (Preview) / compute-version (pull_request) Successful in 3s
Secret Scan / scan (pull_request) Successful in 4s
Build App (Preview) / create-release (pull_request) Successful in 1s
Build App (Preview) / build-macos (pull_request) Successful in 2m44s
Build App (Preview) / build-linux (pull_request) Successful in 5m8s
Build App (Preview) / build-windows (pull_request) Successful in 6m28s
Build App (Preview) / prune-previews (pull_request) Successful in 2s
Build Container / build-container (pull_request) Failing after 14m49s
Three things the terminal was getting wrong.

**A program that grabs the mouse and dies used to freeze the tab.** A TUI sets
DECSET ?1000/?1002/?1003; if it exits without resetting them, xterm keeps
routing clicks, drags and — under ?1003 — every pointer *move* to the PTY.
Text selection dies and escape bytes flood the prompt. The only exit was
closing the tab. `TerminalView` now reconciles a flag against
`term.modes.mouseTrackingMode` in the `term.write()` callback — the mode only
changes because the container printed a sequence, so one check per write
catches every transition with no polling — and `Ctrl+Shift+X` or a status-bar
button writes the resets back through `term.write`, never `sendInput`: the
reset belongs to xterm's parser, and a still-live TUI told about it would just
re-grab on its next repaint.

The control is in the status bar deliberately. Mouse tracking is the *normal*
state of htop, vim, lazygit and Claude Code, so a badge over the terminal
would be on screen for the whole life of those programs and would swallow
clicks aimed at their own top-right corner. `macOptionClickForcesSelection` is
also on now: xterm's force-select is Shift everywhere except macOS, where it
is Option and is gated behind that option, which defaults to false — so until
now Mac users had no way to select text while a program held the mouse.

**"Following" and "Jump to Current" are gone.** Claude Code draws on the
alternate screen, which has no scrollback, so `viewportY` always equalled
`baseY` and neither control could do anything. They did still work in bash
tabs; xterm's native follow covers that, and the per-write `scrollToBottom()`
went with them because it fought exactly that. What remains, on activate and
after a refit, now samples `viewportY >= baseY` *before* the fit, so opening
the Notes dock no longer yanks a reader to the tail.

**`claude update` runs before every Claude session, not just at container
start.** Containers here stop/start and often just keep running, so a
long-lived one never re-checked. Both copies take the same flock: the
entrypoint prints "container ready" only after its own update finishes, so
opening a tab immediately would otherwise run two updaters against the same
~/.claude/bin, with `|| echo` hiding a half-written install one line before
`exec claude` ran it.

This turns the non-Bedrock path from a bare argv into a `bash -c` wrapper, so
flags and session names are shell-interpolated now and must go through
`shell_quote_arg`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145mQi9NZiCDrznBUEEDE4n
2026-09-08 11:02:33 -07:00