ompweb is a local, browser-based workspace for the
oh-my-pi (omp) coding agent. It lets a
user browse the same local sessions they use in the terminal, continue live
work, configure supported OMP settings, and inspect project files without
creating a second agent runtime or a second source of truth.
The project originated from agegr/pi-web (MIT), but it is maintained as an OMP-focused downstream. We preserve the license and attribution, and selectively learn from upstream improvements; we do not assume that Pi-specific implementation changes can be merged unchanged.
- OMP remains authoritative. Sessions, credentials, providers, and agent
behavior belong to the installed
ompCLI. ompweb must not invent a parallel data format or credential store. - Local-first by default. The server binds to
127.0.0.1; remote access is an explicit user choice and must be protected by a trusted network boundary and HTTPS. - Node-first installation. A normal user installs Node.js 22.19+ and OMP,
then runs
npx ompweb@latestor installsompwebglobally. ompweb does not require users to install Bun for its own runtime. - Native compatibility over imitation. Prefer OMP's CLI and documented on-disk formats to copied SDK internals. If a capability cannot be done safely through those boundaries, leave it out rather than emulating it speculatively.
- A calm, capable workspace. The UI should make active work, session history, configuration, and project context understandable without hiding the agent's state or expanding the app into a general remote-control plane.
- npm package and CLI command:
ompweb. - Default server address:
http://127.0.0.1:30177. - Existing
OMP_WEB_*environment variables remain the configuration prefix for compatibility:OMP_WEB_HOSTNAME,OMP_WEB_NO_OPEN,OMP_WEB_PASSWORD, andOMP_WEB_OMP_BIN. PI_CODING_AGENT_DIR, profiles, and OMP's own directory conventions are respected because they identify the user’s existing OMP state.- The web UI displays its own package version separately from the detected installed OMP version; those versions may legitimately differ.
Browser
│ HTTP / Server-Sent Events
▼
ompweb (Next.js on Node)
├─ reads native OMP session files and selected configuration
├─ serves allow-listed project files
└─ starts one `omp --mode rpc-ui` child per active session
│ NDJSON over stdio
▼
installed OMP CLI and its existing ~/.omp/agent state
OMP SDK packages are Bun-only TypeScript and import Bun APIs. Importing
@oh-my-pi/* or @earendil-works/* into a Node/Next server would make the
application unreliable or non-runnable. Therefore, production code must not
add those runtime dependencies.
Live work goes through the user’s installed omp --mode rpc-ui process. This
keeps the agent version, providers, extensions, and session behavior aligned
with the CLI the user already trusts. The RPC layer negotiates v2 when the CLI
advertises it, reassembles bounded chunked frames, and remains compatible with
v1-capable installations.
~/.omp/agent(or OMP's configured/profiled equivalent) is the source of truth for sessions, configuration, models, skills, plugins, and blobs.agent.dbcontains authentication data. ompweb never reads or writes it; authentication actions go through the OMP RPC process.- A live OMP process owns writes to its session file. ompweb routes supported live actions through RPC and never races a live file rewrite.
Session browsing is implemented in pure Node against OMP JSONL files. The reader tolerates the fixed title slot and older session shapes, resolves blob references when needed, and builds the active branch context from the entry tree.
Direct session mutation is deliberately narrow and explicit: rename/title, archive, deletion, and required branch-parent maintenance. These writes are atomic where possible; archive or deletion stops the associated live process first. ompweb does not provide a general editor for session JSONL or opaque OMP state.
Models and allow-listed OMP settings use surgical YAML updates that preserve
unrelated content. Plugin operations run the installed omp plugin CLI. MCP
configuration is project-local, validated before writing, and saved atomically.
- Bind loopback-only by default. A non-loopback hostname is an explicit opt-in.
OMP_WEB_PASSWORDprotects every route with a password-only sign-in screen. Successful sign-in creates an HTTP-only, signed cookie with a 30-day expiry; changing the configured password invalidates existing sessions. Exposed deployments require HTTPS through a trusted reverse proxy or VPN.- API requests are origin-checked. Do not add browser-to-host execution paths that bypass this boundary.
- OMP RPC host tools are intentionally not registered. A browser request must not become arbitrary host command execution through an extension callback.
- File APIs are not a general filesystem browser. They are restricted to selected workspaces, valid Git worktrees, session-referenced directories, and explicitly selected roots. Paths are canonicalized to reject traversal and symlink escapes.
- Secrets, raw API keys, and auth database contents never appear in API responses, logs, or the browser.
- The session sidebar is the durable navigation model: projects, sessions, branches, worktrees, and files must agree about the selected workspace.
- Streaming state is explicit. The UI reconciles Server-Sent Events with RPC state so a background tab cannot remain falsely “running”.
- Desktop and mobile share the same core workflow. Mobile controls keep usable touch targets and a visible loading state rather than a blank shell.
- Accessibility and motion preferences are first-class. Components use the shared design tokens and UI primitives rather than one-off colors or controls.
- Expensive rendering is deferred until needed; responsiveness and initial bundle size are part of the product contract.
agegr/pi-web is the historical source and a useful source of UI ideas,
bug fixes, and tests. Before adopting an upstream change, verify that it does
not depend on Pi runtime behavior or Bun-only APIs. Port the user-visible
behavior, not blindly the implementation.
Releases are independent:
- Run typecheck, lint, relevant tests, and a production build.
- Confirm
npm pack --dry-runcontains the built.nextoutput and exposes theompwebbinary. - Publish
ompweb@<version>only from an npm account authorized for that package. - Tag and release the repository that owns this downstream project.
- Reimplementing OMP, its provider registry, or its credential database.
- Embedding Bun-only OMP SDK packages in the Node server.
- Turning a local agent workspace into an internet-facing multi-user service.
- Unrestricted filesystem browsing or arbitrary browser-triggered host tools.
- Automatic bulk synchronization from
agegr/pi-web.
When a proposed feature conflicts with one of these boundaries, preserve the boundary unless the design is intentionally revised first.