Skip to content

Monorepo Layout

Doable is managed with pnpm workspaces + Turborepo. The root pnpm-workspace.yaml defines four globs:

packages:
  - apps/*
  - services/*
  - packages/*

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:

  • build depends on the upstream packages' build.
  • dev runs persistently, with cache: false.
  • db:migrate runs only in the @doable/api workspace.

When you run pnpm build at the root, Turborepo:

  1. Builds @doable/db, @doable/shared, @doable/docore, @doable/dovault (in parallel where the graph allows).
  2. Then builds @doable/api, @doable/ws, @doable/web.
  3. Caches results under .turbo/ — re-running is near-instant if nothing changed.

See also