Documentation

session-manager

The Node service that owns Vibe Studio workspaces — sessions, deploys, planner, git, cohost.

session-manager is the server side of Vibe Studio. It runs a per-builder workspace session, spawns the agent process, exposes a REST + Socket.IO API to the editor UI, and holds credentials the browser is never allowed to see — most importantly the SpinForge partner key.

The repo is /Users/imzee/projects/agent-zero/session-manager/. It's TypeScript, Express, Socket.IO, Redis (or filesystem) for persistence.

What it owns

  • Workspaces on diskworkspaces/<orgId>/<projectName>/ directories with the actual files the agent edits.
  • Agent processes — spawned per session, isolated, with env vars containing the builder's JWT.
  • The Socket.IO bridgebridge.service.ts proxies events between the editor UI and the agent.
  • The SpinForge partner keysfpk_… lives in env, never leaves the server.
  • Conversation history — every chat thread is persisted under data/conversations/.
  • Planner data.vibe/planner.json per workspace.
  • Cohost tokens — view-only collaboration tokens.
  • Deploy job state — running, finished, failed jobs with their step events.

Routes

The full route surface is in src/routes/index.ts. Highlights:

Sessions

POST/api/sessionsJWT
GET/api/sessions/:userIdJWT
DELETE/api/sessions/:sessionIdJWT

Create / inspect / terminate a workspace session. Body: { userId, orgId, projectName, metadata, priority }. Returns the session id, workspace path, and status.

Dev environments

POST/api/dev-envsJWT
GET/api/dev-envs/:orgIdJWT
DELETE/api/dev-envs/:orgId/:projectNameJWT
POST/api/dev-envs/:orgId/:projectName/sync-ai-instructionsJWT
GET/api/dev-envs/:orgId/:projectName/downloadJWT

CRUD on workspaces. Create stamps .vibe/project.json, scaffolds files (or skips if a description is provided so the agent can pick a framework). Sync route back-fills identity files for older workspaces. Download streams a zip.

Planner

GET/api/planner/:orgId/:projectNameJWT
PUT/api/planner/:orgId/:projectNameJWT
PATCH/api/planner/:orgId/:projectName/cards/:cardIdJWT
POST/api/planner/:orgId/:projectName/cards/:cardId/logsJWT
PATCH/api/planner/:orgId/:projectName/cards/:cardId/criteria/:acIdJWT

Read / write the project planner. Whole-doc PUT, per-card PATCH, log append, acceptance-criterion flip. Every successful write emits a planner:updated socket event so frontends viewing the same project refresh in real time.

Conversations

GET/api/conversations/:orgId/:projectNameJWT
POST/api/conversations/:orgId/:projectNameJWT
GET/api/conversations/:orgId/:projectName/:conversationIdJWT
PATCH/api/conversations/:orgId/:projectName/:conversationIdJWT
DELETE/api/conversations/:orgId/:projectName/:conversationIdJWT

Per-project chat history. Each conversation persists message turns, tool calls, and tool results.

Git

GET/api/git/:orgId/:projectName/statusJWT
POST/api/git/:orgId/:projectName/initJWT
POST/api/git/:orgId/:projectName/cloneJWT
POST/api/git/:orgId/:projectName/commitJWT
POST/api/git/:orgId/:projectName/remoteJWT
POST/api/git/:orgId/:projectName/pushJWT
POST/api/git/:orgId/:projectName/pullJWT
GET/api/git/:orgId/:projectName/logJWT

Wraps real git on the workspace folder. Pushes accept an inline token so the editor doesn't need shell access to your git provider.

Cohost

POST/api/cohost/:orgId/:projectNameJWT
GET/api/cohost/:tokenNo auth
GET/api/cohost/host/:userIdJWT
DELETE/api/cohost/:tokenJWT

View-only collaboration tokens. The host creates a token, shares the URL, the guest joins read-only. Useful for screen-sharing-without-Zoom — the guest sees the editor and the agent stream live.

Deploy

POST/api/deploy/:provider/:orgId/:projectNameJWT
GET/api/deploy/jobs/:orgId/:projectNameJWT
GET/api/deploy/job/:jobIdJWT
GET/api/deploy/job/:jobId/streamJWT
GET/api/deploy/:provider/:orgId/:projectName/statusJWT
POST/api/deploy/:provider/:orgId/:projectName/sync-aliasesJWT
DELETE/api/deploy/:provider/:orgId/:projectNameJWT

Provider-aware deploys. Default provider is spinforge. The deploy is async — POST returns a job id immediately and you stream events via SSE on the /stream route.

Templates

GET/api/templatesJWT
POST/api/templates/applyJWT

Pre-built starter HTML files the studio can scaffold into a workspace.

Preview

GET/preview/:orgId/:projectNameNo auth
GET/preview/:orgId/:projectName/*No auth

Serves workspace files for the iframe preview. Path-traversal-guarded.

Session lifecycle

1. User opens a workspace in Vibe Studio
2. Studio POSTs /api/sessions → resourceManager allocates a session
3. Session manager spawns the agent (a-full) as a subprocess
4. Agent process gets env vars: APPMINT_*, SESSION_MANAGER_URL
5. Bridge wires the editor's Socket.IO to the agent's stdio
6. Editor sends prompts, agent emits tool calls, bridge ferries them
7. User closes the workspace → /api/sessions DELETE → process killed, session freed

Idle sessions get a soft termination after the configured timeout (default 30 minutes). Reconnects within the timeout window resume the same session.

Configuration

src/config/config.ts reads from environment:

VarPurposeDefault
SESSION_MANAGER_PORTHTTP port5600
MAX_CONCURRENT_SESSIONSCap50
WORKSPACE_BASE_PATHWorkspaces folder./workspaces
REDIS_URLOptional persistenceunset (file fallback)
SPINFORGE_PARTNER_KEYsfpk_… for SpinForgerequired for deploy
APPMINT_API_URLAppMint base URLrequired

Persistence

Two backends:

  • Redis (recommended for production) — fast, distributed, TTLs.
  • Filesystem (fallback) — JSON under data/, no external dependencies.

Redis is configured by setting REDIS_URL. session-manager auto-falls-back to filesystem if Redis isn't reachable on boot.

Resource management

resource-manager.service.ts allocates ports for the agent processes from a configured range, monitors memory, and queues new sessions when the cap is reached. Metrics at GET /api/metrics.

The queue can be paused / resumed administratively:

POST/api/resources/pauseJWT
POST/api/resources/resumeJWT
PATCH/api/resources/limitsJWT

Useful for maintenance windows.

Auth

session-manager doesn't own auth — every protected endpoint expects an Authorization: Bearer <appmint JWT> header. The middleware validates the token against AppEngine. There's no local user store.

Auth endpoints (/profile/user/signin, magic-link) are explicitly NOT proxied — the route table comments call this out: "Auth endpoints removed — auth is owned entirely by the AppMint server."

Running it

cd agent-zero/session-manager
npm install
cp .env.example .env
# edit .env to set SPINFORGE_PARTNER_KEY, APPMINT_API_URL, etc.
npm run build
npm start

Production deploys typically put session-manager behind a reverse proxy (nginx, Cloudflare) with TLS termination. The Vibe Studio frontend is configured with SESSION_MANAGER_URL pointing at the public URL.

Related