An agent-agnostic GUI for coding agents — a chat panel inside VS Code, or a browser UI served by a small NestJS host. It works with Pi and OpenCode, and stays engine-neutral: one session list, one transcript, one set of shortcuts, regardless of which agent is driving.
Whether you search for a Pi GUI, an OpenCode GUI, a VS Code Pi extension, a VS Code OpenCode client, a web UI for Pi/OpenCode, a comfortable UI for Pi, or a comfortable UI for OpenCode, Morse is the same comfortable interface.
It is built agent-agnostic on purpose: Pi and OpenCode are the engines today, and the same session list, transcript and UI are ready to host more (Grok Bot, Hermes, and other agents) as integrations land — no fork of the interface.
Pi normally lives in your terminal as a TUI; OpenCode can run as a TUI or a server. Morse gives either agent — its models, tools and sessions — a real interface without reimplementing any of it. This project doesn't embed an agent; it talks to each one through its own RPC/API, which is why you install the agent you want to use yourself.
VS Code extension:
Browser host:
Both clips run the same agent, transcript and protocol; only the host differs.
Morse started as a vibe-coded prototype, but not anymore. I fell in love with this app and got serious about making it genuinely useful and productivity-boosting. Now I've started carefully refactoring the codebase and engineering it heavily instead of just vibing.
- Two engines, one session list — pi and OpenCode drive the same sidebar, transcript and tabs. A session's
id belongs to Morse and records which engine holds its conversation, so reopening it returns to that engine.
pi is the default;
MORSE_ENGINE=opencode/morse.enginestarts new sessions on OpenCode when it is installed or a server is configured. - Pick the engine and the mode — an empty session offers every installed engine, and switching re-reads the
chosen engine's model/mode catalogs before the first prompt. An OpenCode session offers its primary agents
(
build,plan, and any you define) and can switch between them while it runs; the default follows your OpenCode configuration, not a Morse constant. - Multiple sessions across multiple projects — one gateway per session, kept warm (LRU), alive while you switch projects or reload the page. An In progress section lifts the sessions working right now, and a refresh reattaches and replays the transcript.
- A real transcript — markdown with highlighted, copyable code blocks; tool calls as a compact tree by default (one summary line per turn, steps and their files nested under it — the always-open timeline is one toggle away); thinking that streams as it arrives; paged history for long sessions.
- Steer while it works —
steer, follow-up and abort. A prompt sent mid-run is queued as a follow-up above the composer (Queued messages: edit, send now, remove) rather than refused, and runs when the current turn settles. Context compaction is a click away, with a confirmation. - Model & thinking that follow pi — pick any model pi is configured with; the thinking picker mirrors the
levels the current model supports in pi's own TUI and re-reads them on every switch, and a model added to
models.jsonappears when you open the picker — no reload, no restart. - Edit or fork what was sent — edit-and-resend forks before a past prompt and sends the rewrite; fork branches there and hands the prompt back to the composer. The old branch stays resumable.
- Attach context the way each host can — editor selection and live selection chips in VS Code; drag, drop
and pasted images everywhere; browser uploads land next to the session and ride as
@mentions. @mentionanything — a gitignore-aware picker for files and directories (@docs/drills in), opened with+or by typing@, with markdown formatting in your own prompts too.- Native interactions in VS Code — single-value interaction requests become QuickPick/InputBox there, and are rendered inline in the browser. A multi-field form is always rendered in the panel, because no native dialog can express it.
- Git, files and a terminal where there is no editor — on the browser host, a git panel (commit list, branch graph, uncommitted changes), an Explorer and a terminal, with read-only previews, diff views, and line ranges you drag to pin into your next message. VS Code keeps its own Explorer, editor, Source Control and terminal.
- Manage MCP servers — an indicator in the chat toolbar opens a manager for the servers pi sees for the
session's directory: their state, tools and errors, plus add, remove, enable and disable. In project scope,
disabling a user-level server writes a project override — the same file pi's own
/mcpwrites. - Prompt templates with a form — a
/<template>opens a generated form with a live preview, and a template file added or edited shows up without restarting pi. - Keyboard first —
Ctrl+Alt+…(⌘⌥…on macOS) starts a session, narrows the sidebar to a project, changes the model or the thinking level, toggles the git panel (browser host), and opens the compaction question;/jumps to the session search and?prints the whole list.
- Node.js 20+ (developed on 24) and npm 10+.
- The
piCLI installed and authenticated (pi --version), or a path to it viamorse.pi.path/MORSE_PI_PATH. - Optional: OpenCode for the second engine — its binary on
PATH, or a runningopencode serveplus its password (MORSE_OPENCODE_URL/morse.opencode.url). A machine with neither simply stays pi-only. - VS Code 1.138+ for the extension host.
- Morse reuses each engine's own configuration: pi's models, credentials, tools and sessions under
~/.pi; OpenCode's providers, agents and sessions in its server.
npm install -g @supanadit/morse-web
morse start ▲ Morse started
│
◆ port 4399 (PID: 20880)
│
● visit: http://127.0.0.1:4399/
● logs: morse logs
│
└ daemon running — the terminal can be closed
morse start --port 3020, morse status, morse logs --follow, morse stop, morse restart. Add --lan
to bind 0.0.0.0 (the UI has no auth — trusted networks only, or put an authenticating proxy in front), and
-f to stay in the foreground for systemd or Docker.
morse update installs the latest release and restarts. The same thing is a button: start the host with
MORSE_SELF_UPDATE=1 and the sidebar's "Update available" row installs and reloads for you. It is off by
default, and only answers the machine the host runs on.
Install it from the VS Code Marketplace or from Open VSX — the registry VSCodium, Cursor, Windsurf, code-server and Theia install from — or build the VSIX yourself:
npm install
npm run package
code --install-extension dist/morse.vsixThen open the Morse view in the activity bar. The full step-by-step for both hosts — Marketplace, local
tarballs, npm link, settings and troubleshooting — is in docs/INSTALL.md.
| Document | Contents |
|---|---|
docs/INSTALL.md |
Installing both hosts: marketplaces (VS Code + Open VSX), VSIX, npm/tarball, npm link, troubleshooting |
docs/CONFIGURATION.md |
VS Code settings and the browser host's environment variables |
docs/DEVELOPMENT.md |
Build/dev commands, F5, ?mock=1, and the pipeline checks |
docs/ARCHITECTURE.md |
The two hosts, packages, ports and the layering rules |
docs/FRONTENDS.md |
The frontend contract and how to add a React/Svelte/Vue one |
docs/PACKAGING.md |
How the browser host becomes one npm package, and how to publish it |
docs/RELEASING.md |
Cutting a semver release: bump, tag, CI publish of the VSIX and npm package |
docs/STATUS.md |
What is implemented, and what is not built yet |
MIT © 2026 Supan Adit Pratama

