Techniques
Development Workflow
Master oxp dev: automatic Extension Development Host, hot-reload, and the full development loop.
oxp dev is your primary development tool. You run one command — the CLI packs your extension, spawns a fresh Extension Development Host (EDH) window of your IDE, attaches it to the dev session, and starts watching files. Save anything → re-pack → live reload. No "attach" command. No WebSocket URL to remember. No configuration.
Starting a Dev Session
oxp dev # default: open the IDE you ran it from
oxp dev --host vscode # force a specific host family
oxp dev --host jetbrains # spawn an IntelliJ-family EDH
oxp dev ./my-ext # explicit project directory
oxp dev --port 8080 # custom dev-server port (default 7373)The CLI auto-detects your IDE family from $TERM_PROGRAM, $VSCODE_PID, or by walking up the process tree. Pass --host to override.
What Happens, In Order
- Initial build — the project is packed once. Schema validation and policy checks run; failures abort before any window opens.
- Dev server up — an HTTP + WebSocket server binds on
localhost:7373(or--port). - EDH spawn — the CLI writes an autostart marker (
$OXP_HOME/edh/autostart.json) and launches a new IDE window with the marker workspace. The host extension reads the marker on activation and attaches automatically. - Native render — your extension appears in the OXP activity-bar icon → sidebar view. UI panels, commands, status-bar items, and registered MCP servers are all live.
- Watch + reload — chokidar watches the project (ignoring
.git,node_modules,dist/*.oxp,.next,target). On any change, debounced 100 ms, the bundle is re-packed and pushed to the EDH over WebSocket. The host disposes the previous instance and re-instantiates the new one in place — no window reload needed. - End session — press
Ctrl+Cin the terminal. The dev server shuts down, the EDH window closes itself, and the autostart marker is cleared.
The Status Bar
Every connected host shows a session indicator in the status bar:
| Indicator | Meaning |
|---|---|
$(plug) OXP Dev | Connected, idle |
$(sync~spin) OXP Dev | Re-pack in progress |
$(check) OXP Dev · v0.1.2 | Last reload succeeded, shows packed version |
$(error) OXP Dev | Last pack failed — click to open the output channel |
Click the status item to focus the OXP Dev Host output channel.
The Output Channel
A dedicated output channel — OXP Dev Host in VS Code, OXP Dev Host tool window in JetBrains — streams every event:
[12:04:01.022] pack ok · 184 KB · sha256:a1b2c3…
[12:04:01.041] reload → 1 client(s) connected
[12:04:18.503] file changed · src/panel.tsx
[12:04:18.612] pack failed · TS2304: Cannot find name 'Foo'This is the first place to look when something behaves unexpectedly.
The Error Boundary
Runtime errors inside your extension are caught by the host's error boundary and surfaced in the sidebar as a structured panel:
- Error message and stack
- Manifest version and bundle digest
- A Restart button that re-instantiates the extension without losing your dev session
If a pack fails, the previous good bundle remains loaded — you keep working with the last-known-good version until your next save succeeds.
Hot Reload Semantics
Hot reload re-instantiates your extension — it does not preserve in-memory state. If you want stateful reloads, write your state to disk via the storage/* capability and re-hydrate on activation.
UI panels keep their scroll position and form values across reloads when their id is stable.
Endpoints (for tooling)
The dev server exposes a small HTTP/WS API. You generally don't touch these directly — the host adapter does — but they're useful for custom tooling:
| Endpoint | Method | Response |
|---|---|---|
ws://localhost:7373/dev | WebSocket | JSON reload messages |
http://localhost:7373/info | GET | Manifest, digest, bundle size |
http://localhost:7373/manifest | GET | Raw oxp.json |
http://localhost:7373/bundle | GET | Raw .oxp bytes |
Signature Bypass in Dev
VS Code Family vs JetBrains
| Behavior | VS Code / Cursor / Windsurf / VSCodium | JetBrains (IDEA / PyCharm / WebStorm / …) |
|---|---|---|
| EDH spawn mechanism | code --new-window <marker-workspace> | idea --line 1 <marker-workspace> via runtime-bin launcher |
| Sidebar location | Activity bar, OXP icon | Right tool window, OXP stripe button |
| Output channel name | OXP Dev Host (Output panel) | OXP Dev Host (Run tool window) |
| Hot-reload mechanism | WebSocket → Extension.dispose() + re-instantiate | WebSocket → coroutine cancel + re-instantiate |
The wire protocol is identical. The same .oxp bundle, the same WIT contract, the same host calls.
Common Patterns
- Multiple IDEs at once — start
oxp devin one terminal, then runoxp dev attach --host jetbrainsin another. Both EDHs reload from the same dev server. - Network dev server — use
--bind 0.0.0.0and--port 7373to attach a remote host (e.g. a JetBrains EDH on another machine). - Pack-only mode — run
oxp dev --no-spawnif you want the server but want to attach the EDH yourself withoxp dev attach. - Recovering a stuck session —
oxp dev cleanremoves$OXP_HOME/edh/autostart.jsonif a window was force-closed and refuses to re-attach.
Next Steps
- Extension Development Host — full reference for the EDH window: chrome, commands, output channel.
- Publishing — when you're ready to ship.