Monorepo Layout¶
Doable is managed with pnpm workspaces + Turborepo. The root pnpm-workspace.yaml defines four globs:
Top-level files¶
| File | Purpose |
|---|---|
package.json |
Root scripts (pnpm dev, pnpm build, etc.) — all delegate to Turborepo |
turbo.json |
Pipeline graph: which tasks depend on which |
pnpm-workspace.yaml |
Workspace globs |
tsconfig.base.json |
Shared TS config every package extends |
dev.ps1 |
Windows: launch all services in a psmux session |
start.sh |
Minimal launcher used by systemd / Docker |
setup-server.sh |
Bare-metal Ubuntu installer |
sync-codehub.ps1 |
Helper for syncing user projects to a Git repo |
.env.example |
Template environment file |
apps/web — Frontend¶
apps/web/
├── next.config.ts
├── tailwind.config.ts
├── postcss.config.mjs
├── components.json # shadcn/ui config
├── wrangler.jsonc # optional Cloudflare Pages deploy
└── src/
├── app/ # Next.js App Router
│ ├── (auth)/ # Login, signup, OAuth callbacks
│ ├── (dashboard)/ # Logged-in shell (projects, workspace, marketplace, billing, admin)
│ ├── auth/ # OAuth landing pages
│ ├── editor/ # The main editor route
│ ├── brew-haven/ # Demo / sample published site
│ └── globals.css
├── components/ # Shared UI components
├── modules/ # Feature modules — editor, dashboard, marketplace, billing, …
├── hooks/ # React hooks (useAuth, useWebSocket, …)
├── lib/ # Client utils — API client, fetcher, formatters
├── providers/ # React context providers
└── middleware.ts # Next middleware — auth gating
services/api — REST API¶
services/api/
├── package.json
├── src/
│ ├── index.ts # Bootstrap — Hono app, middleware, mountRoutes()
│ ├── routes.ts # Mounts every route module
│ ├── routes/ # 80+ route files (auth, projects, chat, …)
│ ├── ai/ # AI engine bridge (talks to docore)
│ ├── projects/ # File manager, dev server lifecycle, scaffolding
│ ├── db/ # SQL helpers, migrations runner
│ ├── middleware/ # Auth, rate-limit, error handlers
│ ├── deploy/ # Build & publish pipeline
│ ├── github/ # GitHub OAuth, repo sync, PR creation
│ ├── integrations/ # Connector framework (OAuth + tool bridge)
│ ├── mcp/ # Model Context Protocol manager
│ ├── templates/ # Project starter templates
│ ├── thumbnails/ # Puppeteer screenshots
│ ├── version-control/ # Per-project Git
│ ├── analytics/ # Usage events
│ ├── env/ # Env validation
│ ├── lib/ # Email, util, KV, etc.
│ ├── security/ # Secrets, encryption, CSRF helpers
│ └── visual-edit-bridge-inline.ts # JS injected into preview iframes
├── projects/ # Runtime: user project files (PROJECTS_ROOT)
└── thumbnails/ # Runtime: generated PNG screenshots
services/ws — WebSocket / Yjs¶
services/ws/
├── package.json
└── src/
├── index.ts # Bootstrap — Hono + WS server
├── message-handler.ts # Yjs sync + awareness protocol
├── collaboration/ # Per-project rooms, cursors, presence
└── rooms/ # Room registry
packages/db¶
packages/db/
├── migrations/ # Numbered .sql files (lexicographic order)
└── src/
├── index.ts # Exports the `sql` tagged template + `pg` instance
├── types.ts, types-core.ts, types-ai.ts
└── queries/ # One file per domain (projects.ts, billing.ts, …)
packages/shared¶
packages/shared/
└── src/
├── index.ts
├── constants.ts # Plan limits, model lists, etc.
├── kv-store.ts # In-memory ↔ Redis abstraction
├── ai/ # Shared AI types
└── types/ # Cross-package types
packages/docore — AI engine¶
packages/docore/
└── src/
├── engine.ts # DoCoreEngine — high-level session API
├── docore-server.ts # Optional standalone server mode
├── pool.ts # Process pool for many concurrent sessions
├── user-manager.ts # Per-user resource accounting
├── worker-pool.ts # Generic worker pool primitive
├── event-bus.ts # Typed pub/sub
├── event-mapper.ts # Normalizes Copilot SDK events → DoCoreEvent
├── events.ts # The DoCoreEvent union
├── tracer.ts # OpenTelemetry-style spans
├── isolator.ts # Process isolation orchestrator
├── sandbox.ts # Permission-handler sandbox
├── backends/ # nsjail / systemd / Job Object / direct
└── policy/ # Persisted tool/MCP policies
See docore for the public API.
packages/dovault — Runtime jail¶
packages/dovault/
└── src/
├── vault.ts # `Vault.spawn()` — entry point
├── config-guard.ts # Lock config files to safe templates
├── process-jail.ts # Node Permission Model wrapper
├── resource-limiter.ts # systemd cgroups / V8 heap limits
├── tracer.ts
├── types.ts
└── backends/ # direct / systemd / Windows job object / win-heap
See dovault.
docker/ — Container deployment¶
docker/
├── docker-compose.yml # All services
├── Dockerfile # Multi-stage: base → deps → build → service targets
├── setup.sh # One-shot installer (secrets, nginx, SSL, build)
├── .env.example # Compose env template
├── nginx.conf.template # Reverse proxy template
├── nginx-doctest.conf # nginx config used in CI / smoke tests
├── nginx-http.conf.template # HTTP-only variant (behind another TLS proxy)
├── init.sql # PostgreSQL extension creation
├── tmux-entrypoint.sh # Container entrypoint
└── README.md
How tasks flow (Turborepo)¶
turbo.json declares dependencies between tasks. Examples:
builddepends on the upstream packages'build.devruns persistently, withcache: false.db:migrateruns only in the@doable/apiworkspace.
When you run pnpm build at the root, Turborepo:
- Builds
@doable/db,@doable/shared,@doable/docore,@doable/dovault(in parallel where the graph allows). - Then builds
@doable/api,@doable/ws,@doable/web. - Caches results under
.turbo/— re-running is near-instant if nothing changed.
See also¶
- Architecture Overview — high-level diagram & lifecycle.
- Project structure reference — full file tree.