A self-hosted AI workspace in a single Node process. Tasks, documents, calendar, scheduling, time tracking, a password vault, and a team of AI agents — behind one login, with no database to provision and no build step.
OpenWorkspace is one Node process that hosts a suite of pluggable apps and AI
agents for a small team — the kind of internal tooling companies usually stitch
together from five SaaS subscriptions. It runs from a single npm start:
- No database — state is plain JSON / SQLite files next to the server.
- No build step — no webpack, no transpile, no framework. Open a file, edit, reload.
- Pluggable apps — every app is two files (
<id>-api.js+apps/<id>.mount.js). Copy a template, you have a new app. - A real agent layer — a chat assistant, a multi-agent framework you can scaffold new agents into, and an optional "AI OS" that gives the whole system presence, an event bus, and proactive insights.
- Built-in RAG — drop PDFs / Word / Excel into Documents and they're chunked, embedded, and searchable with hybrid keyword + vector retrieval (SQLite FTS5 + sqlite-vec). The agents answer grounded in your files — no external vector DB.
It scales from "a tasks app for my team" to "an AI-assisted operations workspace" without changing architecture.
| Dashboard | Agents |
|---|---|
![]() |
![]() |
| Tasks | Scheduler |
![]() |
![]() |
git clone https://github.com/avaldesbosch/openworkspace.git
cd openworkspace
npm install
npm start # http://localhost:8080 (set PORT to change)Sign in with the seeded admin:
| User | Password |
|---|---|
admin |
changeme |
You'll set a new password on first login. That's it — Tasks, Documents, Calendar, Scheduler, Time Tracking and the rest work immediately. All state is written to gitignored files next to the server.
| App | What it does |
|---|---|
| Tasks | Shared task tracker — assignees, priorities, due dates, projects, files, comments. |
| Documents | A full RAG engine, not just file storage. Upload PDFs / Word / Excel / images — text (and AI image descriptions) are extracted, chunked, and indexed for hybrid search: BM25 keyword (SQLite FTS5) + semantic vector search (sqlite-vec, 1024-dim embeddings) fused with reciprocal-rank. The agents answer questions grounded in your files. Per-user folder permissions throughout. |
| Calendar | Connect Microsoft 365 / Google calendars; free-busy lookups. |
| Scheduler | Cron-style recurring jobs that run prompts/agents inside the workspace. |
| Time Tracking | Log and report time; optional external time-system sync. |
| Passbolt | Credential vault (SSH keys, tokens, env bundles) the agents can use. |
| Arcade | A built-in game, because every workspace needs a break room. |
| Agents | Chat with the assistant roster (see below). |
| Command Center | Bug & idea tracker + triage board. |
| Admin | Users, app registry, AI model routing, agent scaffolding. |
| Agent | Role |
|---|---|
| Nexus | The always-on workspace assistant — reads across your apps and helps you act. |
| Forge | Ops / sysadmin agent — SSH, probes, log tails against a host allowlist. |
| Pulse | Scheduling agent. |
| Hunter | QA — drives the apps like a user and files bugs. |
| Builder | Writes docs + behavioral contracts for new agents. |
To turn the AI features on, point a model at any OpenAI-compatible endpoint
(OpenAI, Ollama, vLLM, LM Studio…). llm-config.json is auto-created from the
example on first boot — edit it, or use Admin → AI Manager → Models to add
one in the UI. Until then, the non-AI apps work fully and the AI surfaces show a
clear "no model configured" state.
The agents above aren't hardcoded — they're built on a framework you can extend:
- Scaffold a new agent in ~a minute. Copy
agent-templates/, give it a prompt and a tool list; it gets a full chat runtime, memory, and a registry entry. No restart. - Tools come from "packs." Every capability an agent has (read a file, send a notification, run a query, SSH a host) lives in a composable pack under
packs/. Grant packs per-agent. - MCP built in. Point a pack at any Model Context Protocol server (stdio) and its tools surface automatically — bring any MCP tool into the workspace.
- Agents are cross-aware and delegate. Each agent's prompt lists the others; an orchestrator can hand a focused subtask to a specialist (
ask_agent, one hop) and get a grounded answer back. - Contracts enforced by a gate. Builder writes a behavioral contract for every agent/app, and
lib/contract-coverage.jsis a programmatic gate that rejects shallow contract sets — so coverage is measured, not vibes. - Pick the model per agent.
ai-router.jsis one place to map "which model does this agent/role use right now?" — mix a cheap local model for background work with a frontier model for the assistant.
lib/aios/ is an ambient intelligence layer that sits over everything — ~38 small modules, off by default, enrolled per app:
- An event bus every meaningful action publishes to (tool calls, state changes, cron ticks, user actions, agent observations).
- A condition registry + judge — rules describe what might be worth a user's attention; a judgment step decides what actually is, so it doesn't spam.
- Daily insight passes — once a day it reads the day's activity and surfaces what no rule would catch.
- Autonomy — it can propose actions and carry them out on your confirmation, not just observe.
- Per-user behavior model + weekly self-evolution — it learns each user's rhythm and proposes platform-level improvements to itself every week.
Hit /api/health to see the event bus live.
Voice (optional): browser mic → Whisper (STT) and text → Piper (TTS) via voice-api.js, so any agent can be talked to and talk back.
server.js boots apps, builds a prefix-sorted route table
├─ lib/router.js the dispatcher
├─ apps/<id>.mount.js route declarations (data)
├─ <id>-api.js the app's HTTP handler + JSON state
└─ public/<id>/ the app's frontend
packs/ composable tools the agents call (+ MCP servers via lib/mcp-bridge.js)
ai-router.js which model each agent/role uses
lib/scaffolded-agent.js runtime for scaffolded agents
lib/contract-coverage.js the contract gate
doc-rag.js hybrid BM25 + vector RAG (SQLite FTS5 + sqlite-vec)
lib/aios/ optional "AI OS": event bus, conditions, insights, autonomy
voice-api.js optional STT (Whisper) + TTS (Piper)
Add an app in four steps — copy app-templates/, drop in two files, wire it
into server.js, add a registry entry. The dispatcher sorts routes by prefix
specificity, so order never matters.
| Env var | Default | Purpose |
|---|---|---|
PORT |
8080 |
HTTP port |
COOKIE_NAME |
workspace_session |
session cookie name |
PUSH_SUBJECT |
mailto:admin@example.com |
VAPID contact for web push |
Optional integrations (Microsoft/Google OAuth, a Passbolt server, external time-tracking) are configured by an admin in-app and are off by default.
Everything written at runtime — users.json, *-state.json, *.sqlite,
data/ — is gitignored. The only secret file is llm-config.json (also
gitignored; auto-created from llm-config.example.json on first boot). There are no credentials
in this repository.
Issues and PRs are welcome. The codebase is plain JavaScript with no build step,
so you can clone, npm start, and start editing immediately.
MIT.



