v1.2.1
Browser IDE, Atomic Terminal Rendering, Strict Gateway Egress + Governed Mode, Session-Scoped Pi Review Orchestration, Unified SDD Contracts, Inference Mesh Landing, Bucket-Stable Vault, Dependency + Image Slimming
The Browser IDE is the headline. A full VS Code editor now runs inside every advanced session's container over
~/workspace, one click from the header — session-isolated by design, reusing the existing auth chain end to end, with no new Worker, Durable Object, binding, or auth system. Alongside it, this release closes the longest-running visible defect in the product: terminal rendering under agent output is now atomic — a three-stage rebuild of scroll ownership that ends with DEC 2026 synchronized frames delivered to xterm as the single writes their authors intended, eliminating the snap-to-top and scrollback-walk flashes for good. The enterprise stack gains a controller-mediated Strict Gateway Egress boundary with external-provider credential isolation and Governed Mode with a verified, chunked re-encrypt migration; Pi's PR-boundary review pipeline is rebuilt around visible session-scoped agents with a mutation-free triage barrier; the seven SDD enforcement skills collapse into one canonical cross-agent contract; the Vault becomes bucket-stable across sessions; and the container image drops from 3.55 GB to 3.26 GB while every open dependency bump lands consolidated.
Browser IDE
Per-session OpenVSCode Server
A full VS Code editor (OpenVSCode Server) runs inside each session's container, reached from the header through the existing Worker → Container → host proxy at /api/vscode/<sessionId>/. It is session-keyed only — the deliberate opposite of the bucket-stable Vault: distinct base-path, service-worker scope, ephemeral server data dir, and container per session, so two sessions get two isolated editors. OpenVSCode is base-path-native, so the path forwards unchanged — no strip, no HTML graft. It reuses the Vault's session-safe auth chain (origin → authenticate + CSRF → tier → ownership → health) and container-auth bearer injection. Lazy-started by an advanced-mode supervisor on first request; while it boots the host serves an auto-refreshing warming page, and non-advanced sessions are refused at the host. The WS proxy raises maxPayload to 32 MiB for VS Code protocol messages; workspace edits persist through the existing final sync. Watch the agent work at machine speed, take the wheel when you want to edit directly.
Terminal rendering — the endgame
The terminal snapping to the top or bottom of scrollback during agent output — the most-reported defect across desktop and mobile — is closed by a three-stage rebuild, each stage source-verified against the pinned xterm build and finished with an external adversarial audit.
Reader ownership: streamed output defers while you read
While a user owns the viewport in the normal buffer, streamed output is held, not written — the display freezes under the reader, so scrollback trimming can never drag them. The hold releases progressively on bottom return (re-deferring if the reader scrolls back up mid-release), and past its 2M-character cap it drops the oldest held output rather than ever writing through a reader. Scrollback grows 1,000 → 5,000 lines. Correlated user intent (touch, wheel, pointer drags, floating page controls) establishes ownership; keyboard-open mobile keeps its deliberate fit-plus-bottom-anchor behavior, and swipes with the keyboard open still send arrow keys.
Buffer authority on every scroll route
xterm 6.1's public scroll APIs resolve relative to a DOM scroll state that silently desyncs from the buffer during refits — the next tick then resolves the divergence as one giant jump to the top. Every scroll route now goes through the internal buffer service: a capture-phase wheel interceptor converts deltas to lines (alternate-buffer and zoom-modified wheel pass through), keystroke re-anchoring moves from xterm's scrollOnUserInput to an app-owned onData path covering hardware keys, the mobile compositor jail, swipe arrows, and voice, and every app-initiated bottom anchor moves by the buffer-derived delta and re-commands the DOM position absolutely — repairing desyncs on every tick instead of amplifying them.
Atomic synchronized frames
Pi authors every redraw as a DEC 2026 synchronized frame; a full replay (clear + home + scrollback wipe + the whole transcript, measured live at ~400 KB across ~100 WebSocket messages) fed to xterm incrementally could outlast xterm's 1,000 ms synchronized-output safety timeout — xterm then abandoned atomicity and painted the partially rebuilt transcript, visibly walking through scrollback. A per-terminal frame assembler now sits at the WebSocket ingest boundary: ordinary bytes keep the 33 ms batching, while each complete frame reaches xterm as ONE write — a single synchronous parse the timeout callback can never interleave. Malformed streams fail open within fixed stall/size bounds; the read-hold, ring-drop, and release budget compose at whole-frame granularity; a partially assembled frame dies at every WebSocket stream boundary (reconnect restores supersede queued output; final closes drain every complete unit); and the bottom anchor now clears the stale scroll lock a scrollback wipe leaves inside xterm (upstream xterm.js#6046) — reproduced and repaired in a pinned-version browser test. Claude Code and Codex frames gain the same atomicity for free; non-emitting applications see byte-identical passthrough.
Mobile keyboard and stability fixes
The xterm 6.1 bump had cost touch devices the on-screen keyboard — restored via a bubble-phase gesture shield, with the colorSchemeQuery VT flood disabled. Expired sessions now recover without a manual reload: explicit 401s, Access redirects, opaque redirects, HTML login responses, and Samsung-style status-zero failures all converge on one clean top-level sign-in. The decorative WebGL flare retires permanently on coarse-pointer backgrounding or context loss, leaving the stable dark CSS surface.
MultiView terminal workspaces
Advanced users can select several sessions from the dashboard and open them as a tiled terminal workspace. Each visible pane owns its WebSocket, focus, input, resize authority, and mobile keyboard handoff, so concurrent sessions cannot fight over a PTY. Closing a pane is distinct from losing its transport, and returning to the dashboard preserves the correct session state.
GitHub, OAuth & onboarding
GitHub integration and cloning
The GitHub panel is now a complete integration rather than a display shell: connect through GitHub App or OAuth, search repositories, clone into a new or running session, refresh or disconnect, and revoke provider tokens during disconnect or offboarding. The paired Storage browser opens files safely in a new tab with inert content types for untrusted HTML and SVG. Enterprise deployments inject GitHub credentials at the egress boundary; other modes retain the existing scoped GH_TOKEN path. Enterprise provider ids and encrypted secrets can be managed in Setup.
OAuth Connect and onboarding mode
Non-enterprise users can connect both GitHub and Cloudflare through OAuth. Cloudflare grants come from the tiered scope catalog and refresh at the interception boundary.
OAuth operator action: register the current Advanced scope superset on the Cloudflare OAuth client before users select Recommended or Advanced. Each connection can only narrow the client's registered scopes; a missing scope fails with
invalid_scope.
The new Onboarding deployment mode reuses the public landing design for /login, GitHub sign-in, access requests, confirmation email, and the Turnstile-protected contact relay. The landing also publishes canonical social metadata, sitemap, robots.txt, and llms.txt endpoints. Billing, admin, and routing surfaces now follow the explicit SaaS, Onboarding, and Enterprise mode split.
Browser Run parity
Claude and Pi now have the same deployed-browser capability. Claude uses the Browser Run MCP server for interactive and read access; Pi reaches the same interactive Chrome DevTools surface through pi-mcp-adapter. The Browser Rendering token can be stored once in enterprise Setup, encrypted and masked on prefill, instead of being entered per user.
Enterprise egress & governance
Strict Gateway Egress and provider credential isolation
A controller-mediated Cloudflare Gateway egress boundary is enterprise-gated and off by default. External GitHub transport swaps to the egress binding, fails closed without it, guards SSRF literal IPs, fail-closes raw TCP/UDP, and bridges WebSocket upgrades through a fresh pair. Cloudflare AI Gateway remains a platform-native direct path, independent of the egress binding. Own-account R2 requests are re-signed at the boundary so the container holds placeholder storage credentials. With Strict Gateway Egress and Governed Mode both active, the container's only real secret is the DO-issued CONTAINER_AUTH_TOKEN; external provider credentials stay outside it.
Governed Mode with a verified migration engine
A deployment-wide, default-OFF toggle disables R2 SSE-C so corporate-owned bucket data is scannable by the company's own tooling — with a lossless, in-place, chunked re-encrypt migration rebuilt as a verified state machine after the first field incident: a single state object as source of truth, REPLACE-directive copies with conditional-match guards, a slice-driven scanner that uses the full background budget, a backend gate that drains cleanly, and regime commits only after a full verify scan. Starting a migration drains running containers, aborts in-flight multipart uploads, and blocks new sessions plus every R2 writer until the bucket returns to ready; reads remain available through dual-regime fallback. Objects above R2's 5 GB single-copy limit are recorded and skipped. Key rotation or an unfixable verify failure halts migration for admin review. The dashboard mirrors live migration progress ("Migrating N%") without sticking, and toggling back off recovers stray objects.
Cloudflare OAuth credentials stay out of the container
The non-enterprise "Connect to Cloudflare" OAuth flow no longer dies when its short-lived access token expires: a non-secret placeholder ships in the container and api.cloudflare.com is intercepted at the egress boundary, stamping a freshly refreshed token per request — the same interception pattern the enterprise gateway uses, now protecting both deployment families. A 60-scope tier catalog governs advanced-mode OAuth grants. Session idle-timeout gains a 4-hour option with a fail-safe fallback raised to match.
Enterprise routing wizard: seven thinking levels
The enterprise routing wizard adopts Pi's seven thinking levels, so gateway dynamic routes can be tiered by reasoning effort rather than a binary switch.
Setup-managed routes and Access groups
Enterprise operator action:
AIG_LANGUAGE_MODELis removed. Configure at least one AI Gateway route in Setup; the first route becomes the default unless another default is selected.
Route catalogs, default reasoning, AI Gateway credentials, Access-group chips, per-group route availability, and per-group defaults now live in Setup without requiring a redeploy. Access groups can also grant live admin access, with fail-closed identity checks and revocation on the next request after group removal.
View-Only Storage and deployment targets
View-Only Storage can block downloads and non-viewable inline content at the server boundary while still allowing approved previews. Enterprise Setup also provisions a narrowly scoped Access bypass for the Vault's native service-worker path, allowing SilverBullet to register under host-wide Access without opening the rest of the Vault proxy. The deploy workflow adds a separate enterprise integration target for tenant-safe iteration, and the high resource tier increases from 8 GB to 12 GB of disk.
Multi-agent runtime (Pi)
Session-scoped, visible review orchestration
Pi's PR-boundary pipeline is rebuilt around visible session-scoped background agents instead of hidden durable state: one ordered launch plan starts every required report-only reviewer without inherited context, then one independent exact-head CI monitor. The root session is the only writer — it owns review-head acknowledgement, fixes, commits, pushes, and follow-up rounds. Reviewers receive exact diff worksets and return evidence rather than re-querying shared context. Delayed notifications, superseded heads, shell wrappers, nested repositories, worktrees, and reload boundaries all have explicit contracts; a dead or unmarked review monitor self-heals from ground-truth liveness, and CI monitoring fires exactly once per push.
Triage before fixes
Reviewer results now end in a mutation-free triage turn: enforcement requires the structural triage table after every reviewer notification before acknowledgement is written and a separate fix follow-up starts — so the next pushed head is reviewed only from an acknowledged checkpoint, and finding dispositions are auditable.
Compact startup context, capabilities on demand
Pi starts with compact canonical context: path rules become grouped skills, proactive skills keep trigger-preserving compact descriptions, one capability tool activates registered tools on demand, and independent managed-seed and runtime budgets bound startup context without losing a single trigger. context-mode ships default-off pending an upstream memory-safe adapter (/ctx on preserves the package) — and a global override that had silently disabled context-mode's bridge idle-reaper is removed, fixing a Pi subagent bridge-process leak. Reviewer lanes run with pinned per-lane reasoning effort, reversing a measured reviewer cost regression.
Transactional memory and extraction
Session-memory capture and Vault extraction advance their counters only after note and graph publication, so an interrupted extraction can never skip content. All knowledge-graph pipelines converge on one cumulative vault graph; memory and vault automation is inert inside subagent child sessions so monitor results can't be overwritten. The official Cloudflare platform skills are bundled into the advanced agent seed, and clone-time Graphify triage asks before touching a stale repo graph.
SDD & review governance
One canonical enforcement contract (AD106)
The seven SDD enforcement skills existed twice — full versions in the Claude preseed, hand-maintained condensed rewrites in the Pi preseed — and had drifted to the point of issuing different findings on the same repository. The Claude-tree files are now the single agent-neutral contract; Pi receives byte-equivalent policy through the existing seed transform, with every conflict resolved to the stricter side.
Honest verification at the acceptance-criterion level
REQ-level manual verification is replaced by per-AC @manual markers, and per-AC test evidence now supports multiple independently resolving anchors — so one behavior can be jointly proven by unit, store, and pinned-browser suites without weakening the orphan checks. A whole-tree deep-clean pass ran under the new contracts, and Claude's review pipeline gains the same finding-triage stage Pi has.
Landing & dashboard
Inference Mesh, second hero
The public landing presents Inference Mesh directly under the primary hero — turn idle machines you own into private inference capacity, keep sessions warm on it, keep sensitive work inside your boundary, treat a hosted model as a policy choice — with infrastructure operations elevated to a peer section beside Security, and a VS Code workbench band presenting the Browser IDE as the bridge between the traditional SDLC and agentic development.
Enter-the-Matrix CTA: the chrome grows, the header never moves
The header sign-in CTA's hover decode gets its final layout contract: the visible border and background ride an absolutely-positioned shell that shrink-wraps the churning glyphs — the button genuinely expands and contracts with each frame, symmetrically — while an in-flow ghost holds the anchor's resting layout box, so the five navigation links never move and no width is ever reserved. No-JS and reduced-motion visitors keep the plain static button.
Dashboard right column, rebuilt
The GitHub panel returns as the lead face of an adaptive GitHub/Storage split whose measurement is now a true fixed point (no feedback-loop flicker), with the split decision keyed to viewport width so tablets and non-maximized laptops keep both panels. The landing↔login navigation flash is eliminated via cross-document view transitions. The public README repositions to default-only deployment (two required secrets), with advanced deployment modes documented privately.
Vault
Bucket-stable persistence — indexed once, not per session
The vault's IndexedDB store is now keyed to the bucket, not the session, via a bucket-stable URL — ending the re-index-on-every-session pain. Prewarm becomes an explicit on-demand two-click flow; the button goes permanently green once ready and a ready (green) button opens directly, with the per-open re-verify that caused a ~10 s "re-index" on every click removed. The native service worker's proactive key flush is neutered in the graft, fixing cold-open 403s; second-start conflicts and the first-open auth race are resolved; machine-owned session-capture memory (Raw/Sessions/, ~95 % of vault bytes) is hidden from the SilverBullet client and shielded from client deletion, fixing long-session vault staleness; and the armed green survives sticky mobile hover.
Sessions, storage & housekeeping
Restored sessions behave: restored authentication fails back to a clean top-level sign-in, container WebSocket forwards time out into a retryable close instead of a dead socket, and the Storage Browser paginates by appending rows rather than replacing them.
Stop and Delete both run the final R2 drain. Delete now drains even when the platform reports a transient running:false state, and records the result in durable finalSyncAudit state. This closes a confirmed path that could lose edits made since the previous sync.
Breaking API removal: the session bookmark feature and the entire /api/presets CRUD surface are removed after usage review. Governed-session and terminal WS reconnect edge cases picked up dedicated regression coverage, and new fuzz suites cover the vault-migration and terminal-link-provider parsers.
CI, supply chain & image
- Per-extension dependency automation — the Pi dependency-bump job is rebuilt per-extension, and every open dependency bump landed consolidated: 22 Dependabot/shadow-pin updates in one wave plus a July follow-up wave, with the vitest major aligned across all nine packages. Notable tool upgrades include SilverBullet 2.8.1 → 2.9.0, zoxide 0.9.9 → 0.10.0, and lazygit 0.62.2 → 0.63.1.
- Image slimmed 3.55 GB → 3.26 GB — build-time prewarm for the non-default agents is deactivated (kept for the primary pair), trimming cold-start surface nobody paid for.
- Trivy gate policy — deployment scans now use
ignore-unfixed: true, so unfixed HIGH/CRITICAL findings do not fail a deployment. Fixable findings still fail unless they carry a reviewed.trivyignoreacceptance. - Security remediation — the dependency wave clears the reported happy-dom RCE and two HIGH findings, scopes deploy-token permissions, and updates the preseeded Hono copy that carried the credentialed CORS vulnerability.
- Vulnerability acceptances, each with a written justification — npm-vendored sigstore (publish-time only), adm-zip bundled inside a vendored SDK tarball (unreachable from any lockfile), and the vendored OpenVSCode Server set (single-tenant sandbox behind the full auth chain).
- xterm pin —
@xterm/xtermpinned at 6.1.0-beta.288 with upstream's synchronized-output viewport deferral verified in-tree; the remaining upstream gaps (the 1-second timeout and the stale scroll lock) are closed on our side of the boundary, so the pin can advance on its own schedule.
Full Changelog: v1.2.0...v1.2.1