feat(attach): deliver control requests and stop notices scrolling the screen - #51
Open
aksOps wants to merge 1 commit into
Open
feat(attach): deliver control requests and stop notices scrolling the screen#51aksOps wants to merge 1 commit into
aksOps wants to merge 1 commit into
Conversation
… screen The last two findings #48 verified but deferred, which turn out to be one change: both are about how UAM talks to a viewer whose screen belongs to the agent. `prefix r` reached nobody. The client wrote the frame and told the asker "control requested"; the host accepted it and returned. The controller — the only party who can act on it — was never told. The notice is now delivered as terminal output rather than a new control event, deliberately: the client rejects control events it does not recognise, so a viewer from an older build would drop its connection instead of ignoring one. Transfer stays controller-owned; the request is a notice, not a handoff. Notices scrolled the agent's screen. Every UAM notice was written as "\r\n[uam: ...]\r\n" at the cursor, which on the alternate screen pushed the agent's display up with nothing to repaint it. They are now painted on the terminal's bottom rows with the cursor saved and restored around them, so the agent's screen does not move and its next repaint of those rows clears the notice. A notice longer than the terminal — `prefix i` runs past 80 columns — wraps upward across as many bottom rows as it needs rather than being cut, since losing half the key list is worse than using two rows. Without a known geometry the plain form stays. Verified end to end: a standby's `prefix r` now appears on the controller's real terminal, and the info notice keeps its full text across the wrap. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01X3PrstXFvYdemQrz8Vb1b1
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.
The last two findings #48 verified but deferred. They turned out to be one change: both are about how UAM talks to a viewer whose screen belongs to the agent.
prefix rreached nobodyThe client wrote the frame and told the asker "control requested". The host accepted it and returned. The controller — the only party who can act on it — was never told, so the documented feature did nothing.
The notice is delivered as terminal output, not a new control event. That is deliberate:
observeRoleEventreturns an error for any event it does not recognise, and the host cannot add a capability to gate it either —validateClientHellorejects unknown capabilities, so a new client advertising one would fail to attach to a still-running older host. Terminal output is the one channel every protocol version already understands.Transfer stays controller-owned. The request is a notice, not a handoff.
Notices scrolled the agent's screen
Every notice was
"\r\n[uam: ...]\r\n"written at the cursor. On the alternate screen that pushes the agent's display up, and nothing repaints it — the emulator never saw those bytes, because they are the client's, not the agent's.Notices are now painted on the terminal's bottom rows, wrapped in
DECSC/DECRC, so the cursor and pen come back exactly where the agent left them and the screen does not move. The agent's next repaint of those rows clears the notice, which is the right lifetime for it.One thing I got wrong first time and caught in the e2e run: my initial version truncated a notice to one row.
prefix iis longer than 80 columns, so that silently ate most of the key list — worse than the scrolling it replaced. It now wraps upward across as many bottom rows as it needs.Verification
prefix rand the notice appears on a real controller's terminal.go test ./...— all green.make test-e2e— all green.go test -race ./internal/session/...— clean.go vet,gofmt,golangci-lint— clean.Also in this branch: the e2e harness now registers viewer cleanup on the subtest rather than the parent. The truncation bug above cascaded into two unrelated failures because the failing subtest left its client attached holding the controller role — the harness should not make one failure look like three.
🤖 Generated with Claude Code
https://claude.ai/code/session_01X3PrstXFvYdemQrz8Vb1b1