Skip to content

UX sweep: usage/UX improvements#10

Merged
burakgon merged 12 commits into
mainfrom
feat/ux-sweep
Jul 2, 2026
Merged

UX sweep: usage/UX improvements#10
burakgon merged 12 commits into
mainfrom
feat/ux-sweep

Conversation

@burakgon

@burakgon burakgon commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Incremental UX fixes from the usage audit (paste/continuity/login done; more via agents). Verifying via CI; single OTA at the end.

burakgon added 2 commits July 2, 2026 10:56
…rrect off, show file captions

- Paste box now wraps text in bracketed-paste markers so a multi-line prompt is one paste (was submitting
  line-by-line on each embedded newline).
- Paste textarea gets autocapitalize/correct/complete/spellcheck off (commands no longer mangled).
- Files panel shows the caption claude attached (captured but never rendered).

Claude-Session: https://claude.ai/code/session_01VzSyCsEWfbKujbBiFcoUUV
…ocal-dev path + token hint

- activeSessionId is persisted (localStorage) and restored on load; a one-shot effect clears it if that
  session no longer exists, so a reload/relaunch/OTA-heal returns you to your session instead of the landing.
- LoginScreen: the tokenless 'local dev' button now shows ONLY on a loopback host (a confusing 401 otherwise);
  the lede explains where the token comes from + that a dead link may have rotated.

Claude-Session: https://claude.ai/code/session_01VzSyCsEWfbKujbBiFcoUUV
Copilot AI review requested due to automatic review settings July 2, 2026 08:05

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements several incremental UX improvements across the web client, focused on better continuity across reloads, more reliable multi-line pasting into the terminal, clearer login guidance, and richer file attachment display.

Changes:

  • Persist and restore the active session ID across reload/relaunch, with a validation pass after sessions load.
  • Send paste-box input as a bracketed paste sequence and disable text input auto-features for the paste modal.
  • Display attachment captions in the Files panel and improve login copy + hide tokenless dev login off-loopback.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/web/src/store/store.ts Adds localStorage-backed persistence for activeSessionId via loadActiveSession / saveActiveSession.
packages/web/src/chat/TerminalView.tsx Wraps paste-box sends in bracketed-paste sequences; disables autocorrect/capitalize/autocomplete/spellcheck in paste textarea.
packages/web/src/chat/TerminalFiles.tsx Renders file captions and adds styling for caption display.
packages/web/src/auth/LoginScreen.tsx Expands login guidance text and hides “tokenless local dev” login unless on loopback host.
packages/web/src/App.tsx Adds one-shot validation to clear restored activeSessionId if it no longer exists once sessions have loaded.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/web/src/App.tsx
Comment on lines +230 to +241
// Validate a RESTORED active session (persisted across reload/relaunch — see store) once the list has
// loaded: if it no longer exists (closed while away), clear it so we land on the picker instead of a
// dead "Session not found" screen. One-shot (ref) so it never fights a fresh selection or a deep link.
const activeValidatedRef = useRef(false);
useEffect(() => {
if (phase !== "ready" || activeValidatedRef.current) return;
activeValidatedRef.current = true;
const deepLink = sessionIdFromLocation(window.location.search);
if (activeSessionId && !deepLink && !sessions.some((s) => s.id === activeSessionId)) {
setActive(undefined);
}
}, [phase, sessions, activeSessionId, setActive]);
Comment on lines 398 to 404
// Inject the paste-box contents into the terminal (raw bytes → claude's input line), then close + refocus.
const sendPaste = () => {
const text = pasteRef.current?.value ?? "";
if (text) sockRef.current?.sendInput(text);
// Bracketed paste (\x1b[200~ … \x1b[201~) so claude treats a multi-line prompt as ONE paste instead of
// submitting on the first embedded newline — a raw send makes every \n an Enter, breaking long prompts.
if (text) sockRef.current?.sendInput(`\x1b[200~${text}\x1b[201~`);
setPasteOpen(false);
burakgon added 10 commits July 2, 2026 11:21
Wire up the server half of the away-from-desk loop:
- push-dispatch: fan Web Push (awaiting/finished/file/ask) over pushStore.list(),
  prune dead subs on 404/410; wired in start.ts with a VAPID subject from
  REMOTE_CODER_VAPID_SUBJECT (sane mailto default), boot-safe.
- terminal-manager: conservative output-idle awaiting heuristic (unref'd timers,
  never blocks/breaks the pty), exposed as awaiting in GET /sessions; onAwaiting
  (away-gated) + onFinished notifiers; bounded attachment buffer replayed on attach.
- transport: POST /sessions/:id/ask (long-poll, 5min graceful timeout) + ask control
  frame + ask replay on reconnect; POST /sessions/:id/ask/answer; file push on /attach.
- tests for the dispatcher, awaiting/replay heuristics, and the ask round-trip.

Claude-Session: https://claude.ai/code/session_01AHW15cYTpc8Qu9bLzGrQ39
# Conflicts:
#	packages/web/src/chat/TerminalFiles.tsx
…+ ask-cancel dismiss

Cross-agent glue after merging the 4 worktree branches: App threads the session-settings 'new session in
this folder with these settings' model/effort/permission/danger into NewSessionWizard's initial* props +
passes onNewSessionHere; TerminalView dismisses the ask overlay on the server's {t:'ask-cancel'} frame.
…to-latest wiring defensive

The terminal agent's 'jump to latest' chip calls term.onScroll + term.buffer.onBufferChange; the test's xterm
mock lacked them (agents don't run tests). Add them to the mock and optional-chain the registration/cleanup.
@burakgon burakgon merged commit 9aeefe3 into main Jul 2, 2026
1 check passed
@burakgon burakgon deleted the feat/ux-sweep branch July 2, 2026 08:45
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.

2 participants