A personal AI assistant — single user, multi-device. Connects to Google Workspace (Gmail, Calendar, Drive, Docs, Sheets, Slides), GitHub, Notion, Railway, and Vercel to run background workflows (daily briefings, email triage, meeting prep) and answer questions about your day.
Slack and Linear still exist in design docs and catalog UI, but they do not have live backend integrations yet.
Start with the docs map when changing code or docs.
Architecture decisions are documented exhaustively in decisions.md.
Stack
| Layer | Choice |
|---|---|
| Monorepo | pnpm + Turborepo |
| Server | Elysia (Node) + Eden typed client |
| Web | Vite + TanStack Router (SPA) |
| Database | Postgres + pgvector (Railway) |
| Cache / Queue | Redis — BullMQ + Pub/Sub (Railway) |
| Sync | Replicache (multi-device) |
| Realtime | Postgres outbox → Redis Pub/Sub → SSE |
| Auth | Better Auth — Google OAuth + one-email allowlist |
| AI | Vercel AI SDK — Anthropic primary, Google fallback |
| Embeddings | Voyage (voyage-3.5, 1024 dim, HNSW) |
| Web search | Grounded Gemini 2.5 Flash via Google Search grounding |
| Resend transactional email | |
| Hosting | Railway |
Local setup
# 1. Start Postgres + Redis
docker-compose up -d
# 2. Install dependencies
corepack pnpm install
# 3. Create local env files
cp .env.example apps/server/.env
# apps/web/.env only needs browser-safe Vite vars:
printf 'VITE_API_URL=http://localhost:3001\nVITE_SENTRY_DSN=\nVITE_POSTHOG_KEY=\nVITE_POSTHOG_HOST=\n' > apps/web/.env
# 4. Fill in server secrets
vim apps/server/.env
# 5. Apply committed DB migrations
corepack pnpm db:migrate
# 6. Start dev servers
corepack pnpm dev
# → server on :3001, web on :3000
Use corepack pnpm rather than an arbitrary global pnpm; the repo pins the exact package-manager version in packageManager. No build step is required before corepack pnpm check-types; workspace packages export TypeScript source directly.
Environment variables
Server vars live in apps/server/.env; browser-safe Vite vars live in apps/web/.env. The committed root .env.example is the combined reference template.
Required server keys:
| Var | Purpose |
|---|---|
DATABASE_URL |
Postgres connection string |
REDIS_URL |
Redis connection string |
BETTER_AUTH_SECRET |
>=32-char random string |
BETTER_AUTH_URL |
Server base URL |
ALFRED_ALLOWED_EMAIL |
Comma-separated emails allowed to sign up |
RESEND_API_KEY |
Transactional email |
RESEND_FROM_EMAIL |
Sender address |
GOOGLE_OAUTH_CLIENT_ID |
Google sign-in + Workspace integration OAuth |
GOOGLE_OAUTH_CLIENT_SECRET |
Google sign-in + Workspace integration OAuth |
GOOGLE_OAUTH_REDIRECT_URI |
Workspace integration callback URL |
GITHUB_APP_ID |
GitHub App installation-token flow |
GITHUB_APP_SLUG |
GitHub App install URL |
GITHUB_APP_CLIENT_ID |
GitHub App user-to-server OAuth |
GITHUB_APP_CLIENT_SECRET |
GitHub App user-to-server OAuth |
GITHUB_APP_PRIVATE_KEY |
GitHub App JWT signing key |
GITHUB_WEBHOOK_SECRET |
GitHub webhook HMAC verification |
GITHUB_APP_REDIRECT_URI |
GitHub App callback URL |
LLM transport — required, boot validates. Every model call goes through the Cloudflare AI Gateway; there are no direct provider keys:
| Var | Purpose |
|---|---|
CLOUDFLARE_AI_GATEWAY_TOKEN + CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_GATEWAY_ID |
Cloudflare AI Gateway, Unified Billing |
Feature-gated or optional locally: VOYAGE_API_KEY (embeddings; called directly, the gateway does not proxy Voyage), GOOGLE_PUBSUB_* (Gmail push), VERCEL_*, CHAT_S3_*, ENTITY_ID_NAMESPACE, and observability keys (SENTRY_DSN, SENTRY_TRACES_SAMPLE_RATE, LANGFUSE_*, POSTHOG_API_KEY, VITE_SENTRY_DSN, VITE_POSTHOG_*).
ENTITY_ID_NAMESPACE (ADR-0067, user-model substrate) is the HMAC namespace for content-addressed stable entity IDs. It is optional today (no projection writes IDs yet) but once the P1 projection lands it must be set and backed up like an auth secret — changing it remints every entity ID on replay.
Commands
corepack pnpm dev # start both apps in watch mode
corepack pnpm build # production build of all packages
corepack pnpm verify:fast # architecture, static checks, format, and types
corepack pnpm verify # verify:fast plus each workspace test script except @alfred/db (much slower)
corepack pnpm verify:db # migrate, then each workspace test:db script (needs Postgres and Redis)
corepack pnpm format # write repository formatting changes
corepack pnpm db:generate # generate Drizzle migration from schema diff
corepack pnpm db:migrate # apply pending migrations
corepack pnpm db:studio # open Drizzle Studio
Docs
Use docs/README.md as the index. It maps current reference
docs, active plans, code owners, and ops scripts.
Implementation milestones
Current status is tracked in docs/reference/milestones.md. The original 15-milestone scaffold lives in docs/plans/scaffolding-plan.md.
Architecture decisions
Each non-obvious choice has a numbered ADR, one file per decision under docs/decisions/, indexed from decisions.md. Read the ones touching your change before proposing architectural changes — most alternatives have already been considered and rejected with reasoning.
