Documentation

How to run VibeGhost safely, manage local terminal data, use Workspaces and source control, and connect optional Pi extensions.

Overview

VibeGhost is a local, browser-accessible terminal manager for AI coding sessions, dev servers, scripts, multiplexers, and everyday shells. It runs terminals on your computer and lets you control them from the browser or phone, with Workspace context around the terminal instead of a flat list of tabs.

The app is agent-agnostic. You can use Claude Code, Codex, Pi, Gemini, opencode, tmux, Zellij, Screen, a dev server, or a plain shell. Pi integration is optional. VibeGhost works first as a terminal and session manager; Pi extensions only add a deeper bridge for people who already use Pi.

The current app is organized around Workspaces. Each Workspace has its own session list, route, and visual icon. Inside a Workspace, sessions are grouped by working directory so related shells, agents, dev servers, and repo work stay together.

The useful mental model is: Workspace for organization, working directory for repo context, and session for the actual terminal process. Optional Pi extensions can add session tools and Workspace Memory without changing that model.

Installation

Clone VibeGhost from GitHub. You need Node.js 20.9 or newer, npm, and a local shell. New sessions use zsh by default.

terminal
git clone https://github.com/junaid33/vibeghost.git
cd vibeghost
npm install

# Start on the default port (4021)
npm run dev

# Or run on a custom port
PORT=4022 npm run dev

The app is available at http://localhost:4021 by default. Local setups can put an HTTPS proxy or a private Tailscale address in front of that port.

Run a production build

Use the integrated production server when you are not actively changing the app:

npm run build
npm start

Mobile Access

VibeGhost is designed for desktop and mobile browsers. The practical mobile setup is to run VibeGhost on your computer and connect from your phone through a private network such as Tailscale.

terminal
# On the computer running VibeGhost
tailscale ip -4

# On your phone, open:
http://100.x.x.x:4021

Replace 100.x.x.x with the machine's Tailscale address and adjust the port if your VibeGhost server uses a different one.

Turn on App Lock before opening the dashboard from another device. On mobile, the terminal input toolbar keeps Tab, Esc, arrows, Ctrl+C, Ctrl+D, page navigation, and paste actions close at hand.

Security and remote access

Treat the VibeGhost dashboard like a local shell. Anyone who can use it can type into terminals, start processes, inspect project files, and change Git repositories.

Protect the dashboard

Use Protect Dashboard at the bottom of the session sidebar before connecting from another computer or phone. Set a strong password and, if useful, a username. A new browser or device must unlock before session APIs and terminal WebSockets work. Sign Out clears the current browser's unlock token and locks it immediately.

App Lock protects remote browser access, but it is not a network firewall. Requests made directly on the host through loopback are trusted. Keep the computer account protected and keep VibeGhost on localhost or a private network.

Use a private tailnet

A direct Tailscale IP works inside your private tailnet. For an HTTPS tailnet URL, proxy the local VibeGhost port with Tailscale Serve, then use the URL shown by the status command:

terminal
tailscale serve --bg http://127.0.0.1:4021
tailscale serve status

HTTPS is preferable on phones because browsers restrict some clipboard and file APIs on insecure origins. If you change VibeGhost's port, change the Serve target too.

Do not port-forward VibeGhost or enable Tailscale Funnel for ordinary remote use. Funnel makes the service reachable from the public internet; Tailscale Serve is private to the tailnet by default.

Local data and cleanup

VibeGhost keeps its state on the host. Terminal recordings can contain prompts, command output, paths, environment details, and other sensitive text, so do not treat~/.vibeghost as disposable public cache data.

Default data layout
~/.vibeghost/
  workspaces.json          # Workspace definitions
  config.json              # Local app settings
  secrets.json             # App Lock hash and salt
  control/
    uploads/               # Pasted and uploaded images
    <session-id>/
      session.json         # Session metadata
      stdout               # Recorded terminal output

Set VIBEGHOST_CONTROL_DIR before starting the server to isolate session metadata, recordings, sockets, and uploads in another control directory. Workspace, app, and lock settings still live under ~/.vibeghost.

Stop and clean are different

  • Stopping a running session terminates its process but keeps its metadata and recorded output.
  • Cleaning an exited session removes that session's directory, including its metadata and terminal recording.
  • Cleaning all exited sessions removes every exited session directory. It does not remove Workspace definitions or the shared uploads directory.
  • Oversized exited recordings may be compacted on server startup, so session history should not be your only archive.
Cleanup cannot be undone. Save any terminal output or uploaded files you need before cleaning a session or deleting files under the control directory.

Platform and browser support

macOS is the currently verified host platform. VibeGhost relies on a local PTY,zsh defaults, filesystem access, and Git tools installed on that host. Lid Awake and hardware-temperature features are macOS-specific.

Use a current Chromium-based browser for the verified browser path. Safari and Firefox may work, but they are not part of the current compatibility guarantee. Clipboard, image paste, virtual keyboards, and browser shortcuts can also vary by browser and device. Include the host OS, browser, and versions when reporting a bug.

The terminal stream requires WebSockets. Reverse proxies must pass WebSocket upgrades as well as normal HTTP requests.

Workspaces

The Workspace rail is the top-level way to move around VibeGhost. Each Workspace has an icon, name, session counts, and its own route. The Workspace switcher dropdown lets you switch Workspaces, edit the current Workspace, or create a new one.

Creating or editing a Workspace sets its visible identity: name, icon color, and icon shape. The active Workspace determines where new sessions appear and which session list is shown. A Pi session can also bind optional Workspace Memory to that Workspace.

Workspace dropdown

  • Shows each Workspace with its icon and running/session count
  • Switches the active Workspace without changing the terminal process itself
  • Provides Edit current Workspace for name, color, and shape
  • Provides Create Workspace for adding a new operating context

Workspaces are different from project groups. A Workspace is stored asworkspaceId on the session. A project group is derived fromworkingDir. The Workspace answers which operating context is this terminal part of? The working directory answers which repo or folder did this terminal start in?

FieldWhat it controls
workspaceIdActive Workspace route, session filtering, and optional Workspace Memory profile.
workingDirTerminal cwd, project grouping inside the Workspace, git context, file browser root, and repo files the agent sees first.
tagsLightweight role hints such as pi, dev, codex, claude, or new.

Sessions

A session is a real local terminal process. VibeGhost sessions can run shells, Claude Code, Codex, Pi, Gemini, opencode, Crush, Droid, dev servers, test watchers, logs, scripts, tmux, Zellij, Screen, and ordinary commands.

New Session dropdown

The New Session button opens a compact dropdown rather than a single create form. It has the current session creation paths:

  • Quick create: starts a new zsh shell in the active Workspace default directory.
  • New session: opens the full dialog for name, tags, command, Workspace, working directory, and options.
  • Projects: duplicates or starts a sibling session in an existing working directory group.
  • Multiplexer: attaches to tmux, Zellij, or Screen sessions on the host, or creates a new multiplexer session.

New session dialog

The full dialog defaults to zsh and offers quick command buttons forzsh, node, pi, claude,gemini, opencode, crush, and droid. It also lets you pick the target Workspace and search or paste a working directory.

The options panel controls native terminal spawning when the server supports it, and terminal title mode. Title mode can be none, filter, orstatic.

SessionInfo
interface SessionInfo {
  id: string
  workspaceId?: string
  name: string
  tags?: string[]
  command: string[]
  workingDir: string
  status: "starting" | "running" | "exited"
  piSessionId?: string
  piSessionPath?: string
}

Ghostty Web

VibeGhost renders terminal sessions with Ghostty Web. Each browser terminal connects to a real local PTY stream and keeps terminal output, resize, scrollback, input, and lifecycle state in sync.

The terminal layer handles large pastes safely, mobile keyboard behavior, scroll controls, reconnection, and activity indicators without turning the browser into a separate fake terminal environment.


Input Component

VibeGhost keeps prompt composition out of the raw terminal by providing a dedicated input area below the terminal. This makes multi-line prompts, paste, mobile editing, and explicit submit behavior more reliable than typing everything directly into the terminal surface.

  • Multi-line editing with Enter to send and Shift+Enter for a new line
  • Paste handling for large text blocks
  • Abort control that sends Ctrl+C to the terminal
  • Scroll controls and connection status
  • Mobile quick keys for common terminal shortcuts

Pasting Images

VibeGhost supports image drag, drop, and paste flows for multimodal agents. Images are saved into the VibeGhost control area and the absolute path is sent to the terminal so the agent can read the file.

~/.vibeghost/control/uploads/[generated-id].[extension]

On mobile, image paste is exposed through the input toolbar so screenshots can be sent from the phone browser without switching to a desktop session.


Keybindings

Browser shortcuts such as Cmd+T, Cmd+W, and browser tab switching remain with the browser. Terminal shortcuts such as Ctrl+C,Ctrl+D, Ctrl+Z, Ctrl+L, and Ctrl+Rare routed to the terminal.

On mobile, the quick-keys toolbar gives touch-friendly access to the terminal keys that native mobile keyboards usually hide.


Pi extension model

Pi support is optional. VibeGhost is useful with Codex, Claude Code, Pi, Gemini, opencode, tmux, Zellij, Screen, dev servers, scripts, and plain shells. The Pi extensions are adapters for users who want Pi to understand VibeGhost Workspaces, control VibeGhost sessions, and report working, waiting, or idle lifecycle state.

Pi extensions are TypeScript modules loaded by Pi. Global extensions live in~/.pi/agent/extensions/; project-local extensions live in.pi/extensions/ inside a trusted project. They can listen to Pi lifecycle events, register LLM tools, add slash commands, persist state, inject prompt context, and update Pi status UI. After changing one, run /reload in Pi or restart the Pi session.

If you do not use Pi, skip this whole group. VibeGhost still provides browser terminals, Workspaces, mobile access, session grouping, file inspection, activity signals, and HTTP APIs. Any shell-capable agent can call those APIs directly.

Install the bundled Pi extensions

The VibeGhost repo includes optional Pi extension packages under extensions/pi. They are not part of the main VibeGhost app build; install them only if you want Pi to get VibeGhost session-control tools or Workspace Memory commands. From a cloned VibeGhost repo, copy both extension folders into Pi's global extension directory and install each extension's dependencies:

Install VibeGhost Pi extensions
cd vibeghost
mkdir -p ~/.pi/agent/extensions
cp -R extensions/pi/vibeghost-session ~/.pi/agent/extensions/vibeghost-session
cp -R extensions/pi/workspace ~/.pi/agent/extensions/workspace
npm install --prefix ~/.pi/agent/extensions/vibeghost-session
npm install --prefix ~/.pi/agent/extensions/workspace

Then restart Pi or run /reload inside the Pi session. After reload, the session extension exposes VibeGhost terminal-control tools, and the Workspace extension adds commands such as /workspace status, /workspace memory on, and /workspace memory refresh.

For project-local setup, copy the same folders into .pi/extensions/ inside a trusted project instead of ~/.pi/agent/extensions/. Only install Pi extensions from sources you trust; they run with your local user permissions.


VibeGhost session extension

The VibeGhost session extension gives Pi first-class tools for the VibeGhost session and Workspace APIs. It is for session control and metadata, not for the terminal spinner. It can identify the current VibeGhost session, update a title and tags, list sessions, inspect bounded semantic Pi activity or the raw terminal screen, create new visible terminals, send input, and stop sessions when the user explicitly asks.

It also syncs Pi session identifiers back to VibeGhost when available, so exited Pi sessions can be easier to restore or fork later. For fast lifecycle status it can use the local VibeGhost API socket, while normal session operations use the same HTTP API any other agent can call.

Pi tools exposed by the session extension
update_vibeghost_session({ title, tags })
list_vibeghost_sessions({ status, workingDirIncludes })
get_vibeghost_session({ sessionId })
create_vibeghost_session({ name, workingDir, workspaceId, command: ["zsh"], tags })
send_vibeghost_session_input({ sessionId, text, submit: true })
read_vibeghost_session_text({ sessionId })
stop_vibeghost_session({ sessionId })

The same ideas also exist as a terminal-control skill. The skill is not a Pi extension; it is written guidance and curl examples. A non-Pi agent can follow the skill and call /api/workspaces or /api/sessions directly.


Workspace Memory extension

Workspace Memory is optional and only applies to Pi sessions. It binds a Pi session to the active VibeGhost Workspace. It is off by default. When you turn it on, Pi gets compact Workspace memory, user memory, session recall, and scheduler tools for that Workspace.

Pi commands
/workspace status
/workspace memory on
/workspace memory off
/workspace memory refresh
/workspace memory list workspace
/workspace memory add workspace <compact durable fact>
/workspace sessions query <phrase>
/workspace cron list

The profile is based on the Workspace, not on the current folder. The session cwd is still used for terminal status, search roots, git context, and file inspection, but normal memory writes go to Workspace memory or user memory.

Tools added when memory is on

  • workspace_memory: add, replace, remove, or list compact durable memory entries.
  • session_search: search and read past Pi sessions in this Workspace.
  • cronjob: create, list, pause, resume, run, remove, or tick scheduled jobs in this Workspace profile.

Frozen snapshots

A Pi session captures a frozen memory snapshot when /workspace memory onruns. Memory writes persist immediately, but they affect newer sessions first. Run/workspace memory refresh when a long-running Pi session needs to see newer memory writes.

What belongs in memory

Save stable facts, user preferences, workspace operating rules, hard-to-rediscover lessons, and durable repo conventions. Do not save raw logs, full audit reports, temporary TODO lists, secrets, or information that belongs in repo files such ascontext.md, progress.md, or normal documentation.


Activity Signals

VibeGhost distinguishes idle, busy, progress, and waiting states through terminal signals and session metadata. The most portable path is terminal-nativeOSC 9;4 progress from the PTY stream. That keeps the UI from scraping terminal text or guessing that every line of stdout means the agent is working.

Agents that emit progress signals work without product-specific parsing. The optional Pi session extension reports richer working, waiting, and idle lifecycle state through the local VibeGhost API.

VibeGhost also tracks shell activity such as commandRunning andpromptIdle. Keeping transport progress, shell state, and integration metadata separate makes session cards responsive without guessing from terminal text.


WebSocket transport

Terminal output streams over a binary WebSocket protocol. A shared client multiplexes session subscriptions over one connection and handles stdout, input, resize events, snapshots, session events, reconnection, and activity metadata.


Integrated Server

VibeGhost runs as one local app that serves the browser UI and terminal API. The server wires together Workspace storage, session routes, PTY management, WebSocket streaming, and a local API socket for fast extension status updates.

  • Next.js for the browser UI
  • Express for local /api/* routes
  • node-pty for local pseudo-terminal processes
  • Workspace storage for Workspace definitions and counts
  • WebSocket streaming for terminal output and input
  • API socket for fast local status updates from extensions

API Reference

The terminal-control tools normally hide these details, but the local HTTP API is still useful for debugging or shell automation.

Current endpoints
GET    /api/workspaces
POST   /api/workspaces
PATCH  /api/workspaces/:workspaceId
DELETE /api/workspaces/:workspaceId

GET    /api/sessions?workspaceId=default
GET    /api/sessions?allWorkspaces=1
GET    /api/sessions/:id
GET    /api/sessions/identify?tty=...&cwd=...&pid=...
POST   /api/sessions
PATCH  /api/sessions/:id
POST   /api/sessions/:id/input
GET    /api/sessions/:id/inspect?mode=semantic
GET    /api/sessions/:id/inspect?mode=raw
DELETE /api/sessions/:id
DELETE /api/sessions/:id/cleanup

Prefer workspaceId when listing or creating sessions. UseallWorkspaces=1 only for intentional cross-workspace inspection.


Files and source control

VibeGhost provides file and change inspection beside the terminal. The Workspace inspector shows a file explorer rooted at the terminal's workingDir, git-aware file status, Monaco previews, and inline diffs.

The Source tab shows the current repository and branch, staged and unstaged files, recent history, and per-file actions. You can stage, unstage, or revert selected changes, review a diff, edit a file, and commit staged work with a message you write or generate through the configurable commit assistant.

Source control actions affect the local repository. Review the selected files and diff before staging, reverting, or committing anything.

Using VibeGhost as a software factory

A software factory is a repeatable operating system for turning an idea into working, reviewed software. VibeGhost is the control surface for that system. It does not replace your repositories, coding agents, databases, test runners, or deployment tools. It gives all of them a durable place to run, a shared structure, and a visible workflow that a person can supervise.

Our own factory is Pi-powered. We use VibeGhost with Pi Coding Agent and two Pi extensions we built: one gives Pi direct control over VibeGhost sessions, and the other gives every Workspace durable, workspace-scoped memory. Together they turn the terminal manager into the operating environment described throughout this guide.

Required ingredients for this workflow: Pi Coding Agent · VibeGhost session extension · Workspace Memory extension. These sit on top of VibeGhost and give the orchestrator session control, shared context, session recall, and workspace-local automation.

We use this setup as the starting point for the Openfront family. When a new vertical begins, we do not start with a pile of unrelated terminal tabs. We start with a VibeGhost Workspace, its related repositories and memory, a durable coordinating session, explicit workers, a runtime session, and a review loop. The factory is the operating model, not an autonomous black box: people still choose priorities, define constraints, review source changes, approve migrations, test the product, and decide what ships.

The factory floor: how the pieces map

VibeGhost primitiveFactory responsibility
WorkspaceThe boundary for one product, vertical, or long-lived program. It can contain sessions rooted in multiple related repositories while keeping identity and Pi-powered memory together.
Working directoryThe exact repository or folder a session operates in. It determines terminal cwd, file browsing, git context, and project grouping.
SessionA durable process with one responsibility: coordination, implementation, tests, migrations, runtime, logs, or review.
Tags and titlesFast operational signals that identify what a session is and make the factory readable at a glance.
Files, Monaco, and diffsThe inspection station. They let you examine implementation output before staging, reverting, committing, or assigning follow-up work.
Workspace MemoryA compact continuity layer for stable decisions, project rules, and lessons that future Pi sessions should inherit.
Mobile controlA remote supervision surface for checking status, reading output, answering prompts, or intervening without returning to the development machine.

1. Start with a product boundary

Create one Workspace for the product, vertical, or long-lived program you intend to operate over time. A Workspace should be broad enough to contain its implementation, runtime, review, and documentation work, but narrow enough that its context stays coherent. Openfront Restaurant and Openfront Hotel are separate Workspaces because their domain models, workflows, risks, and priorities differ even when they share architectural patterns.

The Workspace is not a repository, and it is not limited to one repository. It is the operational envelope around all the repositories that belong to the same product. A Workspace might include the main application, an independent storefront, product documentation, infrastructure, or integration repositories. Each session'sworkingDir still points to one exact repository or folder, preserving the correct terminal cwd, file browser root, and git context.

The Workspace also has its own durable memory when the Workspace Memory extension is enabled. That memory belongs to the product boundary rather than any one repository, so an orchestrator and workers operating across related codebases can share the same stable rules, decisions, and lessons without copying them into every repo.

2. Establish one durable orchestrator

Give each product one long-lived coordinating session. Its job is to understand the product boundary, inspect current state, break work into safe slices, create focused sessions, watch their progress, and reconcile their results. It should not become a giant implementation session that edits every feature itself.

A good orchestrator knows the repository conventions, current blockers, runtime and database mode, migration ownership, test commands, and which work is safe to perform in parallel. When it delegates, each worker receives a bounded task with explicit files, constraints, validation requirements, and a clear definition of completion.

Example workspace shape
Openfront Restaurant Workspace
├── orchestrator     product context, planning, handoffs
├── ordering flow    focused implementation worker
├── payments review  focused security/integration worker
├── server           long-running development runtime
├── tests            build, typecheck, and regression output
└── migration        schema generation and database verification

3. Use workers as bounded production cells

A worker session should have one outcome. Examples include implementing a booking flow, auditing access control, repairing onboarding data, generating a migration, reviewing a payment adapter, updating one documentation slice, or running the app. Narrow responsibility reduces overlapping edits and makes review more meaningful.

  • Implementation workers change one feature or resolve one bounded defect.
  • Audit workers inspect architecture, security, parity, or documentation without silently rewriting the product.
  • Runtime sessions keep dev servers, logs, watchers, and local services alive independently of coding sessions.
  • Migration sessions own schema generation, database selection, application, and verification as an explicit operational task.
  • Review sessions inspect a completed slice, run checks, and report risks before integration.
Parallel work is safest when sessions own different feature slices or perform read-only analysis. Do not assign multiple writers to the same files unless one session explicitly owns integration and everyone understands the overlap.

4. Carry shared context without turning memory into a dumping ground

The Workspace establishes the memory boundary; each Pi session chooses whether to load it. Turn on Workspace Memory in the orchestrator and workers that need shared product context. Store only compact facts that should survive across sessions: architectural rules, stable environment facts, product boundaries, durable user preferences, and lessons that are expensive to rediscover.

Pi session bootstrap
/workspace memory on

# After another session changes shared memory:
/workspace memory refresh

Detailed plans, audits, feature matrices, migration notes, and progress reports belong in repository files such as docs/progress.md, context.md, or normal product documentation. Memory should point a session toward those sources, not attempt to replace them. This keeps prompt context small and the repository auditable.

5. Make runtime and data choices explicit

Treat the running application and its database as first-class factory resources. Keep the dev server in its own session so implementation agents can exit, restart, or fail without taking the runtime with them. Before migrations or destructive tests, decide whether the task uses the existing development database, a persistent local database, or a fresh disposable database.

The orchestrator should record which runtime is active, who owns migrations, and what validation is required. A successful source edit is not the same as a successful product change: the schema may still need migration, generated artifacts may be stale, seeded data may no longer match, or the browser workflow may fail against real state.

6. Put review gates between generation and integration

VibeGhost's file viewer, Monaco editor, diff checker, and source-control surfaces are the quality gate between an agent saying “done” and the repository accepting the work. Inspect the changed files, confirm that the diff matches the assigned scope, run the relevant tests, and only then stage or commit selected changes.

  1. Read the worker's final report and note any unverified claims.
  2. Inspect changed and untracked files from the correct working directory.
  3. Review the diff for accidental scope expansion, secrets, generated noise, and destructive operations.
  4. Run targeted tests first, then the repository's broader type, lint, build, and migration checks as appropriate.
  5. Exercise the actual browser or API workflow when correctness depends on runtime behavior.
  6. Stage and commit only the reviewed slice, or return a precise follow-up task to a worker.

7. Supervise the factory instead of babysitting terminals

Session status, terminal output, titles, tags, and activity signals let one operator see which cells are working, idle, waiting for input, or finished. From mobile, you can inspect the same sessions, answer a prompt, send a control key, or review progress while the processes continue running on the host machine.

The VibeGhost session extension is the control bridge for this workflow. It lets the Pi orchestrator list sessions, inspect bounded semantic activity, create a durable worker terminal, send work to it, and update titles and tags. The Workspace Memory extension supplies the shared context and recall that lets those workers begin from the product's established operating rules instead of an empty prompt.

8. Close the loop and preserve the starting point

At the end of a work cycle, the orchestrator reconciles what changed. It updates repository progress documents, records only genuinely durable memory, identifies remaining risks, and leaves the Workspace in a state where the next session can begin from evidence instead of reconstructing history from terminal scrollback.

This is what makes VibeGhost a reusable starting point rather than a one-off dashboard. A new product begins with the same operational skeleton—Workspace, orchestrator, bounded workers, runtime, review, and durable context—then replaces generic assumptions with its own domain model, workflows, integrations, security requirements, and release gates.

How we apply the model to Openfront

Openfront is a family of open-source business applications built around source ownership, owned data, direct customer relationships, and software operators can adapt and deploy on their terms. We begin with E-commerce, Restaurant, Gym, Hotels, and Grocery, then apply the same factory model to the remaining verticals without pretending they are identical products.

E-commerce
Coffee shop
Restaurant
Barbershop
Salon
Gym
Convenience
Grocery
Rental
Hotels
Real estate
Analytics
Dealership
Law firm
Construction
Hospital
Pharmacy
Airline

Shared architecture can accelerate a new vertical, but the factory must preserve domain boundaries. A hotel's room inventory and booking lifecycle are not a renamed restaurant order. A hospital requires different privacy and safety controls than an e-commerce store. Reuse the operating system and proven infrastructure; require each vertical to earn its own product model, tests, migrations, security review, and documentation.

Start every new product with structure, not automation theater: one clear Workspace, one accountable orchestrator, focused workers, an isolated runtime strategy, visible diffs, explicit review gates, and durable context stored in the right place.