feat: session-scoped client integration channel (publish + events)#30
Merged
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ange Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- POST /s/:id/publish — streams JSON lines to subscribers; 409 if PTY not running - ws /ws/:id/events — WebSocket subscribe; 4002 if PTY not running - ws /ws/:id/pty — PTY renamed from /ws/:id for consistency - session.subscribers set independent from session.clients (PTY) - channel lifecycle tied to PTY: closes with shell exit / server stop - 100% coverage on tracked files (223 tests) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a session-scoped “client integration channel” alongside the existing PTY WebSocket, enabling external publishers (CLI/tools) to stream newline-delimited JSON events into a session while browser subscribers receive one JSON frame per event.
Changes:
- Added
POST /s/:id/publishto stream/submit JSON lines and broadcast valid lines to session event subscribers. - Added
ws /ws/:id/eventssubscribe endpoint and introducedsession.subscribersto manage subscriber lifecycle tied to the PTY. - Renamed PTY WebSocket endpoint from
/ws/:idto/ws/:id/ptyand updated client/tests/docs accordingly.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/server/websocket.ts | Adds /events WebSocket routing, subscriber tracking, and subscriber cleanup on shutdown/exit. |
| src/server/websocket.test.ts | Updates PTY WS route and adds tests for the new events subscription behavior. |
| src/server/session.ts | Extends Session with subscribers: Set<WS> and initializes it. |
| src/server/routes.ts | Implements POST /s/:id/publish streaming JSON-line ingestion and broadcasting. |
| src/server/routes.test.ts | Adds route-level tests for /s/:id/publish error cases. |
| src/client/index.ts | Updates browser client to connect to /ws/:id/pty. |
| src/cli/http.test.ts | Adds CLI tests around executor selection and spawn error handling. |
| docs/specs/webtty.md | Documents the client integration feature in the feature table. |
| docs/specs/client-integration.md | Adds the client integration spec document. |
| docs/adrs/025.server.channel.md | Adds the ADR describing the integration channel API and lifecycle. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ix ADR subscribe error code Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
Summary
POST /s/:id/publish— accepts one-shot or streaming newline-delimited JSON; broadcasts each line to subscribers as a discrete WS frame as it arrives;204after publisher closes;409if PTY not runningws /ws/:id/events— WebSocket subscribe endpoint; receives one JSON object per frame; WS close4002if PTY not running/ws/:id→/ws/:id/ptyfor consistency (server and client ship together, not a breaking change)session.subscribersis a separateSet<WebSocket>fromsession.clients(PTY); the two are fully independentSpec / ADR
Test plan
POST /s/:id/publish— 404 unknown session, 400 wrong content-type, 409 no PTY/ws/:id/events— 4001 unknown session, 4002 no PTY, receives published events, multi-line delivers one frame per line, invalid JSON lines skipped, closed with 4001 on shell exit🤖 Generated with Claude Code