Skip to content

fix(tui): viewport sizing, remote SSH field plumbing, lint gap, exec-in-View, modal seams - #174

Merged
skzv merged 5 commits into
mainfrom
claude/fix-tui-batch4
Aug 3, 2026
Merged

fix(tui): viewport sizing, remote SSH field plumbing, lint gap, exec-in-View, modal seams#174
skzv merged 5 commits into
mainfrom
claude/fix-tui-batch4

Conversation

@skzv

@skzv skzv commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Batch 2 of the review-sweep fixes — the TUI set. All findings re-verified against current main; each ships a fail-before/pass-after test; goldens unchanged throughout.

  • Agents preview bottom is reachable againagentBrowser.View's value receiver silently discarded every viewport resize, pinning it at its constructed 80×20 (scroll clamped against the wrong height; Glamour wrapped at the wrong width). Proper SetSize plumbing now flows WindowSizeMsg → agents screen → all four sub-models, with the pane math extracted pure so View and SetSize measure identically.
  • Remote create-and-attach carries SSH addressinghostChoice dropped ssh_port always and the project flow dropped User/Mosh, so sessions were created remotely but the follow-up attach dialed port 22 as the local user over plain ssh. All three fields now flow through both n flows and the Projects Enter-on-remote-project path (same bug, found during implementation). One follow-up remains out of scope: threading the port into internal/remoteattach's actual ssh argv (noted in the deferred list).
  • Styles lint can't be evaded by line breaks anymore — the regex now catches .\n Padding(1, 3) chains; the four literal-padding call sites it had missed (tour, attach-loading, confirmation, ssh wizard) migrated to spacing tokens at identical values.
  • No more exec-in-Viewtmuxchrome.DetectedPrefix gets a 5s TTL cache (narrow-layout renders shelled out to tmux on every keystroke).
  • Conversations p overlay tail-clamps to the terminal height — newest turns + the close-hint footer stay visible instead of being cut off.
  • Rapid preview toggles no longer accumulate tick chains — ticks carry a generation; stale generations are dropped (the matrix screen's documented pattern).
  • Refactors: modalCapturingText now ORs per-model capturesInput() seams so the next modal can't be forgotten (18-state pin test); new-project form finally has a blinking cursor; five truncation helpers consolidated onto the ANSI-aware pair with edge contracts preserved.

Verification

Full go test ./... green; gofmt/vet clean; linux + windows cross-compile OK; goldens byte-identical.

🤖 Generated with Claude Code

skzv and others added 5 commits August 2, 2026 22:50
…elds, lint gaps, tick chains, overlay clamp

Six verified findings plus three small improvements, each with a
fail-before/pass-after test:

- agentbrowser: View's value receiver dropped the computed pane size
  every frame, so the persistent preview viewport kept its constructed
  80x20 — scrolling clamped against the stale height (last lines
  unreachable on short panes) and Glamour wrapped at the stale width.
  Geometry is now a shared pure helper; SetSize persists it Update-side
  via App WindowSizeMsg -> agentsModel.SetSize -> per-sub-tab setSize.

- remote create-and-attach: both `n` flows dropped SSH addressing —
  hostChoice had no SSHPort (Sessions flow always dialed 22) and the
  project flow dropped User/Mosh entirely. All three now ride through
  hostChoice, both submit messages, and remoteSessionStartedMsg
  (including the Projects Enter-on-remote-project path).

- styles lint: the spacing regex required `.` directly before
  Padding/Margin, so chained calls split across lines evaded it; four
  screen files carried literal padding. Regex is now line-break
  tolerant (with its own regression test) and the four call sites use
  s.Spacing tokens.

- tmuxchrome.DetectedPrefix: shelled out on every narrow-layout render
  (each keystroke + 2s tick). Now TTL-cached (5s) behind injectable
  exec/clock seams; the error fallback is cached too.

- conversations `p` overlay: up to 30 Glamour messages rendered with no
  height clamp, cutting off the newest turns and the close-hint footer.
  Body is now tail-clamped to the height budget (tailLines).

- sessions preview ticks: rapid `p` off->on within the 1s interval left
  the old tick chain alive, permanently stacking capture chains. Ticks
  now carry a generation; stale generations are dropped.

Improvements: modalCapturingText refactored onto per-model
capturesInput() seams (behavior pinned by a table test);
textInputBlink() stub now wires textinput.Blink so the new-project
form cursor blinks; truncation helpers consolidated onto the
ANSI-aware truncate with thin wrappers (width-safety property test;
goldens unchanged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@skzv
skzv merged commit 23cd02e into main Aug 3, 2026
6 checks passed
@skzv
skzv deleted the claude/fix-tui-batch4 branch August 3, 2026 06:07
skzv added a commit that referenced this pull request Aug 5, 2026
…ctor timeouts (#180)

Two follow-ups from the review sweep.

1. remoteattach dropped the SSH port. #174 threaded SSHPort through the
   TUI's create-session forms, but every argv builder here ignored it,
   so ccmux created a session on a custom-port host and then dialed 22
   to attach — stranding the user with a session they couldn't reach.
   The same drop hit the Network screen's shell action and both
   discovered-peer and configured-host attach paths.

   Port is now a required parameter on SSH/SSHInteractive/Mosh/RunArgv
   rather than a separate *Port variant. The old shape had exactly that
   split — SSHInteractivePort existed while callers reached for the
   port-blind SSHInteractive — which is how the bug survived. Making it
   required means a new call site has to decide. 0 and 22 produce argv
   byte-identical to before.

   mosh needs different syntax and that trap gets its own test: mosh's
   -p is the UDP port range for the mosh session, NOT the ssh port, so
   passing it the way ssh takes it would request a UDP bind on 2222
   while still connecting to SSH on 22. The port travels via --ssh.

2. doctor's timeout branch didn't name the port while refused/OK both
   did — so the one case where 'did we probe the wrong port?' is the
   live question was the case that stayed silent. Extracted the branch
   copy into probeResultLine so every message is testable without a
   live host, and pinned the rule.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant