feat(session): raw-PTY terminal attach (connect --raw, start --connect)#35
Merged
Conversation
The pixel-perfect `agent session connect` from the interactive-sessions
handoff: bridge the sandbox's ttyd terminal to the local terminal so the
agent's live Claude Code TUI runs in your shell.
Pure /v1 client: opens WS /v1/sessions/{id}/terminal with the ordinary Bearer
login token; the API authenticates, mints the Modal token server-side, and
relays ttyd byte-for-byte (backend PR ellipsis-dev/ellipsis#5775). The CLI
never sees a sandbox URL, a Modal token, or a cookie.
- lib/terminal.ts: ttyd wire-protocol framing (init/input/resize + server-frame
parse), close-code guidance, and the raw stdin<->ws<->stdout bridge (SIGWINCH
resize, Ctrl-C passes through, Ctrl-] detaches, TTY restored on exit).
- session connect --raw: the raw attach, beside the existing message-based
connect (which stays the default: single-writer-safe, works headless / in a
sandbox). --raw needs a real TTY.
- session start --connect: wait for the sandbox to come live, then attach; not
combinable with --json/--watch.
14 new pure-helper tests (test/terminal.test.ts); typecheck + full suite (187)
+ build + compile smoke all green. Live end-to-end verification against a warm
interactive session still to do (needs a running sandbox).
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.
What
The pixel-perfect terminal attach from the interactive-sessions handoff. Bridges the sandbox's ttyd terminal (over the agent's live tmux) to your local terminal, so the agent's Claude Code TUI runs in your shell — the SSH-like
connectexperience.Backend companion: ellipsis-dev/ellipsis#5775 (
WS /v1/sessions/{id}/terminal). Merge that first.Security shape (pure /v1 Bearer client)
The CLI opens
wss://api.ellipsis.dev/v1/sessions/{id}/terminalwith its ordinary login token on the handshake — the same credential the REST API uses. The API authenticates it, mints the Modal connect token server-side, and relays ttyd byte-for-byte. The CLI never parses a code out of a URL, calls/__auth, holds a cookie, or sees a Modal token or sandbox origin. (This replaces the handoff doc's original browser-impersonation sketch, which was both factually wrong about the terminal endpoint and below the bar for a public repo — see #5775.)Verb shape — please confirm
I kept the existing message-based
connectas the default (single-writer-safe, works headless and from inside a sandbox) and added the raw PTY as a mode flag:agent session connect --raw [sessionId]— raw attach (needs a real TTY).agent session start --connect— start, wait for the sandbox to come live, then raw-attach. Not combinable with--json/--watch.The handoff noted you leaned toward "connect = the pixel-perfect attach". I went with
--raw(lowest-regret: no regression to the in-sandbox/headless message mode, fits the flags-not-sub-verbs grammar) and it's a one-line flip to make raw the default if you'd rather. Your call before merge.Other decisions to confirm:
send-keysuntil the write-baton ships — accepted pre-GA per INTERACTIVE_SESSIONS.md §6.Changes
lib/terminal.ts: ttyd wire-protocol framing (init/input/resize + server-frame parse), close-code → guidance, and the rawstdin<->ws<->stdoutbridge (SIGWINCH resize, Ctrl-C passthrough, Ctrl-] detach, TTY restored on every exit path).commands/connect.ts:--rawflag + sharedrunConnectRaw.commands/session.tsx:start --connect(wait-until-live then attach).wsonly) and nopackage.jsonchange.Gates
typecheck(strict tsc), fullvitestsuite (187 passed, incl. 14 new pure-helper tests intest/terminal.test.ts),tsupbuild, and the--compilebinary smoke — all green.