Add shared session watch APIs - #2415
Conversation
Expose passive shared-session watch handles for Node and Rust, with generated RPC types, ordered event routing, lifecycle cleanup, and tests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Adds passive shared-session watch APIs for Node.js and Rust, including event replay, lifecycle handling, cleanup, documentation, and generated RPC types.
Changes:
- Adds read-only shared-session watch handles and
sessions.watchintegration. - Propagates
session.disconnectedlifecycle events and cleans up routing. - Updates generated schemas, tests, documentation, and line-ending rules.
Show a summary per file
| File | Description |
|---|---|
.gitattributes |
Standardizes Node.js and Rust line endings. |
nodejs/README.md |
Documents shared-session watching. |
nodejs/src/client.ts |
Implements watch creation and cleanup. |
nodejs/src/generated/rpc.ts |
Adds generated watch RPC types. |
nodejs/src/generated/session-events.ts |
Refreshes generated event types. |
nodejs/src/index.ts |
Exports watch and lifecycle APIs. |
nodejs/src/session.ts |
Adds the passive watch handle. |
nodejs/src/types.ts |
Adds disconnected lifecycle typing. |
nodejs/test/client.test.ts |
Tests watch behavior and payloads. |
rust/README.md |
Documents Rust watch usage. |
rust/src/generated/api_types.rs |
Refreshes generated RPC payload types. |
rust/src/generated/rpc.rs |
Adds the generated watch RPC method. |
rust/src/generated/session_events.rs |
Refreshes generated event types. |
rust/src/handler.rs |
Updates permission-context example. |
rust/src/lib.rs |
Tracks watches and lifecycle cleanup. |
rust/src/router.rs |
Makes the session router cloneable. |
rust/src/session.rs |
Updates permission-context fixtures. |
rust/src/types.rs |
Adds disconnected lifecycle support. |
rust/src/watch.rs |
Implements Rust shared-session watches. |
rust/tests/api_types_test.rs |
Tests credential-free payload shapes. |
rust/tests/session_test.rs |
Tests replay, disconnect, and close behavior. |
Review details
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 16/21 changed files
- Comments generated: 3
- Review effort level: Balanced
Guard the hand-authored Node and Rust lifecycle unions against silent drift from the Runtime notification contract. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Regenerate the watch RPC from the accepted contract while preserving the SDK's published CLI schema surface and removing unrelated newer Runtime event/type drift. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: be0a255d-04f8-4830-888a-59f54ad1e607
This comment has been minimized.
This comment has been minimized.
Keep the generated watch API additive against the SDK's pinned CLI schema and leave repository-wide line-ending policy unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: be0a255d-04f8-4830-888a-59f54ad1e607
This comment has been minimized.
This comment has been minimized.
Route disconnect cleanup in the ordered session notification task and store watch classification with router entries so shutdown always uses sessions.close without racing terminal cleanup. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: be0a255d-04f8-4830-888a-59f54ad1e607
Resolve conflicts preserving both the shared session watch API surface and main's GitHub token provider work: - nodejs/src/client.ts: keep both sharedSessionWatches.clear() and githubTokenProviders.clear() in stop() and forceStop(). - rust/src/lib.rs: keep register/unregister_watch_session alongside main's register/retire_github_token_provider, and pass main's new required github_token_registry argument to router.ensure_started(). - rust/src/lib.rs: keep main's github_token_registry.clear() in force_stop(). - rust/src/types.rs: union both test import lists (SessionLifecycleEventType + PermissionResponseCapability). - rust/tests/session_test.rs: keep both new test sets. Also address PR review feedback: - nodejs/test/client.test.ts: replace the unreachable if (false) block (CodeQL) with a reachable compile-time PassiveWatch type assertion that still fails to compile if send/abort appear on SharedSessionWatch. - nodejs/src/session.ts: wrap replay dispatch in the same try/catch used for live delivery so a throwing handler cannot drop remaining replay events or prevent on() from returning its unsubscribe function. - rust/tests/session_test.rs: bound the final watch.events().recv() with timeout(TIMEOUT, ...) so a cleanup regression fails instead of hanging. - nodejs/src/client.ts: wrap an over-length if condition to satisfy prettier. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
| } | ||
| } | ||
| Ok(_) => {} | ||
| Err(e) => { |
Cross-SDK Consistency ReviewThis PR adds the
New API surface introduced
Suggestions for follow-upThe following equivalent APIs would be the natural parallel additions:
Since the PR description explicitly notes that execution is blocked on a future No blocking issues — this is informational to help plan the cross-SDK rollout.
|
Summary
sessions.watch({ sessionId })RPC surface from Runtime schema commit7c34f30aa270d2a6214d1aa0274fc1afd4c9790d(SHA-256dec3e7be93b7a3ca023eff9f6e90e9858bb6305d15f547d0e599283828a9b310)SharedSessionWatchhandles with immutable read-only metadata, ordered replay/livesession.eventdelivery, idempotentsessions.close, and no interactive or lane-credential surface{ type: "session.disconnected", sessionId }terminal lifecycle signal and atomically clean up watch routing after preceding eventssession.destroyValidation
Runtime and publication dependency
The generated API is pinned to the main-based schema-only Runtime commit above. Execution and normal package-backed regeneration remain blocked until a new
@github/copilotpublication carries Runtime PR github/copilot-agent-runtime#17282 (0179092d8c319b60b4b8cb7df0b0829c095adb4f) together withsessions.watchand the hand-writtensession.disconnectedlifecycle union. The lifecycle variant is intentionally absent fromgenerated/api.schema.json.