Running Apps
Running Apps is a built-in sidebar virtual project that lists every dev server Omniscio is running for you: see each live app with its local address, open it inside Omniscio in an embedded browser view, and stop it — without hunting for ports or terminal tabs.
What it is
Omniscio ships a built-in Running Apps panel as a sidebar virtual project. Click Running Apps in the Omniscio sidebar group (emerald AppWindow icon) and the right pane swaps to a full-width list of the dev servers Omniscio is currently running for you — no sessions list, no chat composer, just the live apps.
It exists so that when a Claude session spins up a dev server (a Next.js app, a Vite frontend, an API), you have one place to see every one that's live, open it in-pane, and stop it — without hunting for ports or terminal tabs.
Where to find it
Enabling it
Running Apps is off by default. Turn it on at Settings → Features → Running Apps (or search settings for "running apps" / "portless" / "dev server"). Toggling it off hides the sidebar row and pauses the live-apps poll; toggling back on restores both.
How it behaves
What powers it: portless
Running Apps is a thin UI over portless, a small dev proxy. Instead of each dev server grabbing a random port you have to remember (localhost:3000, localhost:5173, …), Omniscio launches it behind the portless proxy, which gives it a stable, human-readable hostname:
https://my-feature.localhost
https://api.localhost
The <slug>.localhost name is derived from the session/app name. .localhost always resolves to your own machine (it's a reserved loopback name), so these URLs only ever reach local dev servers — nothing leaves your computer.
Requirements
Two hard prerequisites (Omniscio probes both before offering to use portless):
- portless installed and on your PATH —
npm i -g portless. You don't have to run this by hand: when portless is missing the panel's empty state shows a one-click Install portless button (see "The empty state is availability-aware" below). - System Node 24 or newer — portless declares
engines.node: ">=24". The relevant Node is the systemnodethat runs the globalportlessbinary, not Omniscio's bundled Electron runtime. When the system Node is below 24, the panel shows an "update Node first" message + a nodejs.org link and deliberately does not offer the install button (npm rejects the install below theengines.nodefloor).
The empty state is availability-aware
When no apps are running, the panel probes readiness once on mount (the read-only portless:availability IPC — gated on runningAppsEnabled like every other handler, so it never spawns a probe while the feature is off) and shows one of:
- portless installed → plain "No apps running" (dev servers launched through portless appear here).
- portless missing + Node ≥ 24 → an Install portless button. One click runs the install with a spinner; on success the panel flips to ready (no app restart). The install reuses Omniscio's existing toolchain installer — portless is a registered opt-in
npm-globaltool — so it also gets an Install button in Settings → Connected Tools and the Tools screen. - system Node < 24 → an "update Node first" message + a Get Node 24+ link, no install button.
- still probing → the plain empty state (it never flashes the Install button at someone who already has portless).
The post-install detection reads the fresh system PATH (and routes the Windows .cmd shim through cmd.exe), so a just-installed global portless is found without relaunching Omniscio.
What you see
A simple list, one row per live app:
- Slug — the app's short name (e.g.
my-feature), taken from its.localhosthostname. - Port pill — a green chip showing the dev server's local port (portless assigns one in the 4000-4999 range).
- URL — the browsable
https://<slug>.localhostlink. Click it to open the app inside Omniscio in an embedded browser view (a<webview>), so you stay in the app. A Back button returns you to the list. - Stop — stops that preview (terminates the portless route). The list refreshes immediately.
A toolbar Refresh button re-reads the list on demand, and the panel also live-updates on its own: a background poll watches portless's route table and pushes changes to the panel every few seconds, so apps appear and disappear without you clicking anything.
If nothing is running you get an availability-aware empty state — a plain "No apps running", a one-click Install portless button, or an "update Node first" message (see "The empty state is availability-aware" above).
HTTPS .localhost and certificates
portless serves previews over HTTPS using a local certificate authority. Chromium doesn't trust that CA by default, so Omniscio adds a narrow certificate-error exception scoped to .localhost hosts only — that lets the embedded preview load without a security warning. The exception is deliberately tight: it applies only to localhost / *.localhost names; any other site with a bad certificate is still rejected normally.
Privacy & scope
- The embedded preview uses a fresh, in-memory browser partition per panel open — it doesn't share cookies or storage with the rest of Omniscio or with the persistent Browser pane.
- The desktop
.localhostpreview is loopback-only (.localhostnever resolves off your machine) and the live-apps push is desktop-only. Viewing an app on your phone is a separate, opt-in path — the authenticated/app-preview/proxy over your Tailscale address (see "View a running app on your phone" above), reachable only by your logged-in, device-approved phone.
Controlling it from an agent (CLI control server)
A spawned agent or external script can interact with Running Apps over Omniscio's bearer-authed CLI control server (http://127.0.0.1:19519), not just the in-app panel:
GET /portless/apps— list the live previews (every running portless app, Omniscio- or agent-launched).POST /portless/launch— launch a preview for a dev server ({ sessionId, sessionName, workDir, devCommand[], proxyPort?, tls? }) → returns{ slug, url }.POST /portless/stop— stop a tracked preview ({ slug }).
Every route is gated on the same runningAppsEnabled flag — when the feature is off (the default) they all return 403, so the agent surface is dead until you enable Running Apps. launch validates that workDir is a real folder before spawning and runs the dev command shell-safe; routes are bearer-authed and rate-limited like every other CLI endpoint. (An agent can also just run portless directly in its own shell — it still appears in the panel, because Omniscio reads portless's route table.)
View a running app on your phone
When mobile access over Tailscale is on (Settings → the Smartphone button → enable Tailscale access; private to your own Tailscale devices by default, public only when you allow it), each running app also gets a phone-openable preview link. In the Running Apps panel a Smartphone icon appears on every row; click it to copy https://<your-machine>.ts.net/app-preview/<slug>/, then open that on your phone to see the live dev server — the mobile version of "build on the machine, preview in your hand".
How it works: Omniscio already carries its web app to your phone over Tailscale (private serve by default, public Funnel only when you turn that on), behind your phone login + device approval. The preview link rides that SAME secure path — an authenticated reverse-proxy forwards the phone's request to the running dev server's local port (looked up from portless's route table). It is not a public link: an unlogged-in or unapproved device is refused before any app bytes are returned, exactly like the rest of mobile access.
One setup requirement — the dev server's base path. For the live app to render correctly through the sub-path link, its dev server must serve under that base path. For Vite, start it with --base=/app-preview/<slug>/ (the slug is the app's short name shown in the panel); other frameworks have an equivalent base-path setting. The proxy forwards requests transparently — it does not rewrite your app — so without the matching base path the page's absolute-root asset URLs won't resolve. Live reload (HMR) works too once the base path is set (its websocket is proxied through the same link).
Security note (v1). The preview is served on the same web address (origin) as the Omniscio web app, so a previewed app's scripts share that origin. This is fine for previewing your own agents' dev servers (your own code, reachable only by your own approved phone) and is the accepted v1 scope; Omniscio does not yet isolate previews on a separate origin, so don't use it to host untrusted third-party apps. Turn the whole feature off any time with AMC_DISABLE_MOBILE_APP_PREVIEW=1, or by turning Running Apps off.
For agents
Where it lives in the code
- Sidebar entry + icon:
src/renderer/src/integrations/ui-registry.ts(id: 'running-apps', AppWindow icon,panelOwnsLayout: true). - Manifest + virtual project sentinel:
src/shared/integrations/running-apps.tsandRUNNING_APPS_PROJECT_ID = '__running_apps__'insrc/shared/virtual-project-ids.ts. - Panel UI:
src/renderer/src/features/running-apps/RunningAppsPanel.tsx. - IPC surface (list / launch / stop + the
portless:apps-changedlive push):src/shared/ipc-channels/portless.ts, handlers insrc/main/ipc/handlers-portless.ts. - CLI control-server routes (
/portless/apps|launch|stop):src/main/services/cli/cli-server-portless-routes.ts, registered insrc/main/app/startup/register-cli-routes.ts. - Backend manager + portless launch / route reader / availability probe + the live-apps poll:
src/main/services/portless/. - Availability-aware empty state: the read-only probe handler
PORTLESS_AVAILABILITYinsrc/main/ipc/handlers-portless.ts→ its system probesrc/main/services/portless/portless-availability-probe.ts(fresh PATH +.cmdshim) → pure UI decisionsrc/renderer/src/features/running-apps/portless-empty-state.ts. The Install portless button reusesTOOLCHAIN_INSTALL_TOOL; portless is registered as an opt-innpm-globaltool insrc/main/services/toolchain/toolchain-registry.ts(+toolchain-checks.ts/toolchain-install.ts/src/shared/tool-provenance.ts/ theToolIdunion). .localhostcertificate trust:src/main/localhost-cert-trust.ts(wired intohardenWebContentsinsrc/main/webcontents-hardening.ts— index.ts is intentionally untouched).- Mobile app-preview reverse proxy (view a running app on your phone):
src/main/services/web/web-access-preview-proxy.ts, wired intoweb-access-http-routes.ts(dispatchAuthedRoute, HTTP) +web-access-server.ts(handleUpgrade, WS); the panel's phone link reusesIPC.TUNNEL_STATUS. Thepreview-*invariants in.claude/memory/contracts/running-apps-contract.md.
Related
The built-in terminal is the other place Omniscio starts a process on your behalf, and MCP servers covers the tools a running session can call. No sibling library page covers the dev-server preview surface itself; INDEX.md is the library index, the way to find the neighbouring pages on sessions and on the CLI control server that this panel's routes belong to.
Last verified 2026-09-28