Skip to content

refactor(playground): remove session token - #3965

Merged
rossirpaulo merged 5 commits into
canaryfrom
paulo/remove-playground-token
Jul 10, 2026
Merged

rossirpaulo merged 5 commits into
canaryfrom
paulo/remove-playground-token

Conversation

@rossirpaulo

@rossirpaulo rossirpaulo commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Remove the per-session playground token minting and API authorization checks.
  • Restore bare HTTP, WebSocket, and source-file URLs with no ?token= propagation.
  • Delete the token helper, package export, Vite alias, UUID dependency, and token-specific connection-status banner.
  • Remove token documentation and update the playground describe snapshot.
  • Preserve the SSH tunnel support from feat(playground): make baml playground usable over SSH tunnels #3949, including loopback-origin handling, the 4265 default port, explicit port selection, headless behavior, and filtered environment-variable delivery.

Why

#3949 introduced the session token alongside the SSH playground changes. We have decided not to use token-based authorization for the local playground, so this removes the feature and all supporting structures rather than leaving compatibility plumbing or dead code behind.

Impact

baml playground now prints and opens a bare local URL. Playground API and WebSocket requests no longer require a query parameter. The origin guard remains in place: remapped loopback origins used by SSH tunnels are accepted, while hostile remote origins are rejected.

Validation

  • cargo fmt --all -- --check
  • cargo test -p baml_lsp_server --lib — 24 passed
  • cargo test -p baml_cli describe_command_tests — 89 passed
  • pnpm --filter @b/pkg-playground typecheck
  • pnpm --filter @b/pkg-proto generate && pnpm --filter app-vscode-webview build
  • Live smoke test with an explicit port: bare URL printed, tokenless remapped-loopback request returned 200, and a hostile origin returned 403

Summary by CodeRabbit

  • New Features

    • Simplified playground access by removing session-token requirements across browser, editor, API, and WebSocket connections.
    • Playground links now open using plain base URLs, and WebSocket endpoints are derived from the current page (no token query parameters).
  • Bug Fixes

    • Removed token-dependent banner/retry behavior and adjusted banner output to match the token-free flow.
  • Refactor

    • Removed public WebSocket connection status reporting and related UI hooks.
  • Documentation

    • Updated playground keyword documentation to reflect the shortened, token-free URL behavior.

@vercel

vercel Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview, Comment Jul 10, 2026 10:13pm
promptfiddle Ready Ready Preview, Comment Jul 10, 2026 10:13pm
promptfiddle2 Ready Ready Preview, Comment Jul 10, 2026 10:13pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6fe82c27-704f-4ce7-9719-57ac5ffdef87

📥 Commits

Reviewing files that changed from the base of the PR and between fd92a8f and 52cfd77.

📒 Files selected for processing (3)
  • baml_language/crates/baml_lsp_server/src/lib.rs
  • baml_language/crates/baml_lsp_server/src/playground_sender.rs
  • baml_language/crates/baml_lsp_server/src/playground_server.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • baml_language/crates/baml_lsp_server/src/playground_sender.rs
  • baml_language/crates/baml_lsp_server/src/lib.rs

📝 Walkthrough

Walkthrough

The playground no longer uses per-session URL tokens or token-based API authorization. Rust startup and server paths, frontend URL construction, token exports, and WebSocket connection-status handling were simplified accordingly.

Changes

Playground access and client integration

Layer / File(s) Summary
Remove server-side session-token access flow
baml_language/crates/baml_builtins2/..., baml_language/crates/baml_lsp_server/...
Playground startup, browser links, sender notifications, middleware, tests, dependency wiring, and documentation no longer generate, pass, validate, or describe session tokens.
Remove client token URL wiring
typescript2/app-vscode-webview/src/RemoteEditorView.tsx, typescript2/pkg-editor/..., typescript2/app-vscode-webview/vite.config.ts
Frontend API and WebSocket URLs are constructed directly, and token helpers, exports, package mappings, and aliases are removed.
Remove WebSocket connection status API
typescript2/pkg-playground/..., typescript2/app-vscode-webview/src/App.tsx
WebSocketRuntimePort no longer tracks or publishes connection status, and the consuming retry state and banner are removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Poem

A bunny hops where tokens flew,
No query strings to chase anew.
The playground opens bright and plain,
WebSockets hop without status strain.
Rust and TypeScript share the cheer—
“A simpler path is burrowed here!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the PR’s main change: removing the playground session token flow.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch paulo/remove-playground-token

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

⏭️ Performance benchmarks were skipped

Perf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to canary/main.

To run them on this PR, do any of the following, then push a commit (or re-run CI):

  • Add RUN_CODSPEED=1 to the PR description, or
  • Include run-perf or /perf in the PR title or any commit message.

@vercel
vercel Bot temporarily deployed to Preview – beps July 10, 2026 19:02 Inactive
@rossirpaulo
rossirpaulo marked this pull request as ready for review July 10, 2026 19:05
@rossirpaulo
rossirpaulo enabled auto-merge July 10, 2026 19:07
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 10, 2026 19:09 Inactive
@github-actions

github-actions Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

Binary size checks passed

✅ 7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
✅ baml-cli Linux 🔒 22.0 MB 9.4 MB file 21.5 MB +462.7 KB (+2.1%) OK
✅ packed-program Linux 🔒 15.9 MB 6.7 MB file 15.6 MB +296.3 KB (+1.9%) OK
✅ baml-cli macOS 🔒 16.9 MB 8.2 MB file 16.6 MB +364.9 KB (+2.2%) OK
✅ packed-program macOS 🔒 12.3 MB 5.9 MB file 12.1 MB +232.0 KB (+1.9%) OK
✅ baml-cli Windows 🔒 18.5 MB 8.4 MB file 18.1 MB +382.0 KB (+2.1%) OK
✅ packed-program Windows 🔒 13.2 MB 5.9 MB file 13.0 MB +242.1 KB (+1.9%) OK
✅ bridge_wasm WASM 14.7 MB 🔒 4.2 MB gzip 4.1 MB +120.4 KB (+3.0%) OK

🔒 = the size this artifact is GATED on (ceiling + delta). Binaries gate on file size (installed binary); WASM gates on gzip (download size). The other size is shown for information only.


Generated by cargo size-gate · workflow run

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
typescript2/app-vscode-webview/src/App.tsx (1)

109-110: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

WS fallback hardcodes ws://; derive scheme from window.location.protocol.

remoteUrlsFromLocation in remote-backend.ts picks wss for https: origins, but this fallback always uses ws://. If the standalone/iframe page is ever served over HTTPS, the browser will block the insecure ws:// connection as mixed content. Align the two paths.

♻️ Proposed fix to match protocol-aware scheme selection
-    const wsUrl =
-      window.__PLAYGROUND_WS_URL ?? `ws://${window.location.host}/api/ws`;
+    const scheme = window.location.protocol === 'https:' ? 'wss' : 'ws';
+    const wsUrl =
+      window.__PLAYGROUND_WS_URL ?? `${scheme}://${window.location.host}/api/ws`;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/app-vscode-webview/src/App.tsx` around lines 109 - 110, Update
the `wsUrl` fallback in `App` to derive the WebSocket scheme from
`window.location.protocol`, using `wss` for HTTPS and `ws` otherwise, while
preserving the existing host and `/api/ws` path. Keep the explicit
`window.__PLAYGROUND_WS_URL` override unchanged and align the logic with
`remoteUrlsFromLocation`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@typescript2/app-vscode-webview/src/App.tsx`:
- Around line 109-110: Update the `wsUrl` fallback in `App` to derive the
WebSocket scheme from `window.location.protocol`, using `wss` for HTTPS and `ws`
otherwise, while preserving the existing host and `/api/ws` path. Keep the
explicit `window.__PLAYGROUND_WS_URL` override unchanged and align the logic
with `remoteUrlsFromLocation`.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 819738a0-286e-40ca-bcb3-d13625b3129e

📥 Commits

Reviewing files that changed from the base of the PR and between 4fa203d and 68a5f77.

⛔ Files ignored due to path filters (2)
  • baml_language/Cargo.lock is excluded by !**/*.lock
  • baml_language/crates/baml_cli/src/snapshots/baml_cli__describe_command_tests__render_keyword_playground.snap is excluded by !**/*.snap
📒 Files selected for processing (14)
  • baml_language/crates/baml_builtins2/keyword_docs/baml_keywords.yaml
  • baml_language/crates/baml_lsp_server/Cargo.toml
  • baml_language/crates/baml_lsp_server/src/lib.rs
  • baml_language/crates/baml_lsp_server/src/playground_sender.rs
  • baml_language/crates/baml_lsp_server/src/playground_server.rs
  • typescript2/app-vscode-webview/src/App.tsx
  • typescript2/app-vscode-webview/src/RemoteEditorView.tsx
  • typescript2/app-vscode-webview/vite.config.ts
  • typescript2/pkg-editor/package.json
  • typescript2/pkg-editor/src/index.ts
  • typescript2/pkg-editor/src/playground-token.ts
  • typescript2/pkg-editor/src/remote-backend.ts
  • typescript2/pkg-playground/src/index.ts
  • typescript2/pkg-playground/src/ports/WebSocketRuntimePort.ts
💤 Files with no reviewable changes (8)
  • typescript2/pkg-editor/src/playground-token.ts
  • baml_language/crates/baml_lsp_server/Cargo.toml
  • typescript2/pkg-playground/src/index.ts
  • typescript2/pkg-editor/src/index.ts
  • typescript2/app-vscode-webview/vite.config.ts
  • baml_language/crates/baml_builtins2/keyword_docs/baml_keywords.yaml
  • typescript2/pkg-editor/package.json
  • typescript2/pkg-playground/src/ports/WebSocketRuntimePort.ts

@vercel
vercel Bot temporarily deployed to Preview – beps July 10, 2026 19:16 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 10, 2026 19:23 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 10, 2026 19:36 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 10, 2026 19:58 Inactive
@vercel
vercel Bot temporarily deployed to Preview – beps July 10, 2026 19:59 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 10, 2026 20:05 Inactive
@rossirpaulo
rossirpaulo added this pull request to the merge queue Jul 10, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Jul 10, 2026
@vercel
vercel Bot temporarily deployed to Preview – beps July 10, 2026 20:30 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 10, 2026 20:37 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 10, 2026 20:51 Inactive
# Conflicts:
#	baml_language/crates/baml_lsp_server/src/lib.rs
#	baml_language/crates/baml_lsp_server/src/playground_sender.rs
#	baml_language/crates/baml_lsp_server/src/playground_server.rs
@vercel
vercel Bot temporarily deployed to Preview – beps July 10, 2026 21:52 Inactive
@rossirpaulo
rossirpaulo enabled auto-merge July 10, 2026 21:53
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 10, 2026 22:00 Inactive
@rossirpaulo
rossirpaulo added this pull request to the merge queue Jul 10, 2026
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 10, 2026 22:13 Inactive
Merged via the queue into canary with commit 507745a Jul 10, 2026
55 checks passed
@rossirpaulo
rossirpaulo deleted the paulo/remove-playground-token branch July 10, 2026 22:29
tsenart pushed a commit to perfloop-oss/baml that referenced this pull request Jul 13, 2026
…ment + Phase 1 bounded ingress (BoundaryML#4000)

Combines BoundaryML#3969 (Phase 0) and BoundaryML#3976 (Phase 1) into one PR against canary,
with latest canary merged in (including the BoundaryML#3965 session-token removal
and BoundaryML#3973 test-metadata work, both semantically reconciled). Supersedes
both stacked PRs. Implements `docs/design/lsp-latency-and-mutex-fix.md`
(committed in this PR) through Phase 1; Phase 2 (salsa snapshot reads)
remains behind the doc's spike gate.

## Root cause
The 0.14.0 debounced engine rebuild holds the project DB mutex across
compiles while `try_lock_db` maps any contention to `-32001`; stale
build candidates could install over newer edits, busy diagnostic reads
looked empty, and playground/browser routing could leak stale session
output.

## Phase 0 — correctness containment (from BoundaryML#3969)
- Monotonic `SourceRevision`; owned compilation/diagnostic/engine
candidates; **revision-conditional engine commit** through the same gate
as source mutations — stale installs impossible by construction
(rendezvous-tested at the exact commit boundary).
- `DiagnosticsFence` judging staleness against the **authoritative
revision**: a superseded rebuild's late diagnostics or a candidate
racing `mark_dirty` can never regress newer markers.
- Bounded request-lane waits (1s) mapping to typed errors —
`ContentModified`/`RequestFailed`; **`-32001` is never emitted**. Busy
is never conflated with empty; poison is terminal.
- Salsa-memoized `file_annotations`/`semantic_tokens`; 150/300 ms
debounced tails; single-flight rebuilds; UTF-8/UTF-16 `PositionCodec`
(C1).

## Phase 1 — bounded ingress, cancellation, client gating (from BoundaryML#3976)
- **IngressScheduler + LspRuntime** in `baml_lsp_server`: stdio and
browser LSP sessions through one bounded scheduler (per-class byte/item
budgets, lifecycle barriers, response ownership); `$/cancelRequest`
handled on the transport thread — queued requests answer **`-32800`**,
running cancellable requests observe a dispatch-scoped token (entry +
post-source-guard safe points; never salsa unwinding); browser takeover
tombstones the old session's sink and replays overlays.
- Hardened framing/output: 16 KiB header cap; oversized
messages/responses degrade **per-message** (`-32803`) instead of killing
the session/process; serialize-once shared outbound frames with accurate
budget accounting; connection-scoped sessions (per-connection encoding
negotiation).
- **Playground run-gating (D6)**: during rebuild windows
(`is_bex_current == false` or a `projectNotReady` rejection)
Run/test/preview disable with "Preparing current build…" and re-enable
on the next current update — no protocol version bump. Closes the
fail-closed D7 UX window Phase 0 introduces.
- **Reconnect correctness**: fail-closed hello; bounded first-connect
queue; session-scoped commands never replay into a new session
(synthesized rejections); the desired-runtime lease survives reconnects.
- **Track A**: canonical multi-root ownership (`projectRoots.ts`) +
routing; closing the last `.baml` document no longer stops the owner
server; aggregate status preserves startup failures.

## Measured (same harness/machine, 400 generated functions)
| Metric | 0.14.1 (regressed) | this PR |
|---|---:|---:|
| Typing inlayHint p50 / p95 | 313.6 / 379.4 ms | **~2 / ~52 ms** |
| Post-pause `-32001` failures | 46–57 per feature/window | **0** |
| Unanswered requests | 144–160 | **0** |
| Rebuild-window inlay/hover/completion | mass failures | 218/218 each |
| Explicit `$/cancelRequest` | rejected/ignored | **`-32800`** |
| Refresh storms per 10-edit burst | — | 0 |

## Deliberately not included
- **Phase 2 salsa snapshots** (removes the residual post-pause hitch on
very large projects): gated by the design doc's own spike-and-signoff
decision — `panic=abort` release profile vs salsa's unwinding
cancellation must be resolved first.
- **D5 demand-gating server side**: client seam ships dormant (typed +
tested, nothing sends it).
- The alternate implementation's five-lock core rewrite (redundant with
Phase 0's invariants), playground protocol-v3 lockstep (compat hazard;
equivalent wire-compatible fixes included), and stdlib `testing.*` API
additions (unauthorized surface).

## Validation
- `bex_project` 45/45 (+1 pre-existing ignored) incl. commit-boundary
rendezvous, fence, bounded-wait classification; `baml_lsp_server` 64/64
(22 scheduler, 9 runtime, framing/budget); workspace `cargo check --lib`
clean; clippy `-D warnings` clean; wasm check clean.
- TS: playground 125/125, extension 13/13, webview 19/19 (incl. gating),
all typechecks.
- Latency harness re-run on this exact merged head (numbers above).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01VEMxti5WQ8bCgJUuX9AQvo

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Improved LSP responsiveness and stability with bounded messaging,
cancellation handling, session recovery, and safer browser takeover
behavior.
* Added negotiated UTF-8/UTF-16 position handling for more accurate
diagnostics, ranges, formatting, and semantic highlighting.
* Added project-aware VS Code routing for nested projects, symlinks, and
changing project markers.
  * Added runtime leasing support for playground connections.

* **Bug Fixes**
* Prevented runs and tests from starting while a project build is stale
or unavailable, with clearer preparation feedback.
* Improved cancellation, error reporting, diagnostics updates, and run
generation consistency.

* **Documentation**
* Expanded contributor and Rust workspace setup, testing, formatting,
and debugging guidance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Fable 5 <[email protected]>

This branch was previously deployed

3 inactive deployments
Preview – promptfiddle — 52cfd77a Deployed Jul 10, 2026 by vercel[bot]
Preview – promptfiddle2 — 52cfd77a Deployed Jul 10, 2026 by vercel[bot]
Preview – beps — 52cfd77a Deployed Jul 10, 2026 by vercel[bot]
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