Junior is a self-hosted fork of Sentry Junior. It keeps Junior's agent runtime, dashboard, memory, Slack, ACP, plugin API, and provider packages while replacing its hosted runtime services:
- Models use any OpenAI-compatible
/v1endpoint. - Agent commands and files run in
just-bash, not a remote VM. - Attachments live under
JUNIOR_DATA_DIRon local disk. - Wake-up queues run in the Node process; SQL remains the durable mailbox.
- Nitro builds a normal Node server. No Vercel deployment, Blob, Queue, Sandbox, AI Gateway, or OIDC account is required.
The repository keeps Junior's Vite+ and npm setup. Use vp run <script> for package scripts because Vite+ built-ins and package scripts are separate commands.
Requirements: Node 24+, npm 12, Vite+, Docker, and an OpenAI-compatible model endpoint.
vp install
cp apps/junior/.env.example apps/junior/.env
docker compose up -d --wait postgres redis
vp run cli -- upgrade
vp run devThe server listens on http://localhost:3000 by default. Point these settings at your model host:
OPENAI_BASE_URL=http://localhost:8000/v1
OPENAI_API_KEY=
AI_MODEL=your-chat-model
AI_FAST_MODEL=your-fast-model
AI_EMBEDDING_MODEL=your-embedding-modelOPENAI_API_KEY is optional for endpoints that allow unauthenticated access. Model ids pass through unchanged to the endpoint.
Build and start the Node output with:
vp run build
node apps/junior/.output/server/index.mjsRun one app process per persistent data directory. The local queue is intentionally an in-process wake-up transport; Junior's SQL mailbox and heartbeat recovery remain durable. Before scaling to several replicas, replace that transport with Redis Streams, Postgres SKIP LOCKED, or another self-hosted queue.
Call /api/internal/heartbeat once per minute and /api/internal/retention daily from your own cron or scheduler. Set JUNIOR_SCHEDULER_SECRET and send it as Authorization: Bearer <secret>.
Each conversation gets a durable directory under JUNIOR_DATA_DIR/sandboxes. just-bash mounts only that directory at /workspace. It provides an emulated shell, text tools, Python, and JavaScript. It does not expose the host shell, host filesystem, Docker daemon, package manager, or ambient network.
This changes one Junior capability: plugin skills that expect a native CLI installed into a remote sandbox need a just-bash custom command adapter before they can execute that CLI. Their manifests, prompts, auth hooks, routes, dashboard pages, and direct runtime tools remain reusable.
vp check
vp test
vp run typecheckThe original Junior license and attribution are retained in LICENSE.
