Techniques
Extension Development Host
The EDH window: how oxp dev spawns it, its chrome, commands, output channel, error boundary, and lifecycle.
The Extension Development Host (EDH) is the IDE window in which your in-development extension runs. It is a real, full-fidelity instance of your IDE — VS Code, Cursor, Windsurf, VSCodium, or any IntelliJ-family product — with the OXP host adapter loaded and your extension auto-attached to the running dev session.
You never spawn the EDH manually. oxp dev does it for you.
Why a Separate Window?
Running your extension in the same window where you edit its source has historically been the standard "F5" experience — but it has real costs:
- State pollution — your dev environment (open files, debug sessions) collides with your extension's runtime state.
- Crash blast radius — a bug in your extension can take down your editor.
- Indistinguishable bundles — it's hard to tell what version of your extension is running.
The OXP EDH puts your extension in its own pristine window, with its own activity-bar icon, its own permissions, and a loud header indicating it's a dev session. Your source window stays untouched.
Automatic Spawn
When you run oxp dev:
- The CLI packs your extension.
- It writes an autostart marker to
$OXP_HOME/edh/autostart.json(default~/.oxp/edh/autostart.json). The marker contains: dev-server URL, project path, IDE family, host PID, and an expiry timestamp. - It launches the IDE with a clean workspace (no folder, no SCM context). Example:
code --new-window /tmp/oxp-edh-<sessionId>. - The OXP host extension activates in the new window, reads the marker (only if its expiry is fresh and PID is alive), and connects to the dev server immediately. No command palette step. No prompt.
- Your extension renders in the sidebar.
If the marker is missing or expired, the new window starts as a normal editor — no auto-attach. Run oxp dev clean to clear stale markers.
Anatomy of an EDH Window
┌──────────────────────────────────────────────────────────────────┐
│ File Edit … OXP Dev (v0.1.2) │ ← title bar tag
├───┬──────────────────────────────────────────────────────────────┤
│ ⓘ │ Your extension's sidebar view │
│ 🔍│ ───────────────────────────── │
│ 📦│ DEV: signature bypass │ ← header chip
│ ▶ │ │
│ 🅾 │ ◄── OXP activity-bar icon (clicked, sidebar visible) │
│ │ │
├───┴──────────────────────────────────────────────────────────────┤
│ $(plug) OXP Dev · v0.1.2 · session 4f3a …other status items… │ ← status bar
└──────────────────────────────────────────────────────────────────┘Key elements:
- Activity-bar / tool-window icon — labelled
OXP. The host adds it the moment a dev session attaches. - Sidebar view — renders
oxp-ui-v1orhybrid-v1UI natively. Forwebview-v1, an isolated webview iframe is mounted here. - DEV chip — always visible in dev mode; the production install path never shows this.
- Status bar / status widget — connection state, session id, packed version (see Development Workflow for the icon legend).
- Title-bar suffix —
OXP Dev (vX.Y.Z)so you can tell EDH windows apart at a glance.
Command Palette
The EDH exposes a small set of commands under the OXP: prefix:
| Command | What it does |
|---|---|
| OXP: Restart Dev Session | Disposes the extension, reconnects to the dev server, re-loads the latest bundle |
| OXP: Reload Bundle | Asks the dev server for the current bundle and re-instantiates without reconnecting |
| OXP: Open Output (Dev Host) | Focuses the OXP Dev Host output channel |
| OXP: Show Manifest | Opens the active bundle's oxp.json read-only |
| OXP: Show Bundle Info | Pops a modal with digest, size, signedBy (or unsigned (dev)), packed-at timestamp |
| OXP: Detach Dev Session | Disconnects but leaves the window open; useful for inspecting the last-known state |
In JetBrains hosts, the same commands are reachable via Help → Find Action (Ctrl/Cmd+Shift+A).
Output Channel
The OXP Dev Host channel logs everything: file events, pack results, reload pushes, RPC call traces (at info level), and unhandled errors.
In VS Code family: View → Output → OXP Dev Host. In JetBrains: OXP Dev Host tool window (bottom dock).
Set OXP_LOG=debug before oxp dev to include per-RPC tracing.
Error Boundary
Every host call (storage/*, http/*, editor/*, …) is wrapped in an error boundary on the host side. When your extension throws:
- The boundary catches the error and serializes it (message, stack, RPC method, args).
- The sidebar view switches to an error panel showing the structured failure.
- The status bar turns red:
$(error) OXP Dev. - The error is appended to the output channel.
- A Restart button re-instantiates the extension without restarting the IDE.
The host extension itself never crashes. The blast radius of a misbehaving extension is exactly one sidebar view.
Hot Reload
When the dev server pushes a new bundle:
- The host receives the WebSocket
reloadmessage. - The current extension instance's
dispose()is awaited (up to 2 s). - The new bundle is verified (digest match, manifest schema, policy).
- A new instance is constructed;
activate()is invoked. - The sidebar is re-rendered in place.
Total time, typical: 100–250 ms from save to visible update.
State across reload: UI form values and scroll positions are preserved for views with stable ids. In-memory JS variables are not — persist them through storage/* if you need durability.
Ending the Session
Press Ctrl+C in the terminal where oxp dev is running. The CLI:
- Sends a
shutdownframe to every connected host. - The EDH window dismisses its sidebar, removes the activity-bar icon, and closes itself.
- The dev server stops listening.
- The autostart marker is deleted.
You can also use OXP: Detach Dev Session in the EDH if you want the window to stay open after the server stops — the extension stays loaded as a frozen snapshot of the last bundle (useful for screenshots).
VS Code Family vs JetBrains
| Aspect | VS Code / Cursor / Windsurf / VSCodium | JetBrains (any IntelliJ-Platform IDE) |
|---|---|---|
| Window launch | code --new-window (or cursor, windsurf, codium) | idea / pycharm / webstorm / … via runtime-bin/ launcher |
| Sidebar | Activity bar, OXP icon | Right tool window, OXP stripe button |
| Detach gesture | Close window or OXP: Detach Dev Session | Close window or Tools → OXP → Detach |
| Output | Output panel, OXP Dev Host channel | Tool window, OXP Dev Host |
| Restart shortcut | Command palette → OXP: Restart Dev Session | Find Action → OXP: Restart Dev Session |
The contract is identical. Bundle, manifest, signature, WIT pin, RPC calls — all bit-equivalent across families.
Troubleshooting
- Window opened but extension didn't appear — check the OXP Dev Host output channel. Most often a pack/validation error.
- EDH won't attach — run
oxp dev cleanand start again. A stale autostart marker can block re-attach. - Wrong IDE launched — pass
--host vscodeor--host jetbrainsexplicitly. - Port in use —
oxp dev --port 8080(or setOXP_DEV_PORT). - Auto-detected wrong launcher (e.g.
codeinstead ofcursor) — setOXP_IDE_LAUNCHER=cursorin your shell environment.
Next Steps
- Development Workflow — the surrounding loop.
- Publishing — graduate from EDH to the real registry.