Next.js app for the MLabs portfolio: companies, goals, projects, milestones, team roster, Slack-assisted workflows, and an in-app AI assistant. Tracker data is a single JSON document in Upstash Redis with optimistic locking (revision + compare-and-set).
Where to read more
- docs/strategic-tracker.md — Roadmap doc index (data model, Slack, UI, AI); see also docs/project-outline.md for strategic framing
- docs/environment.md — Environment variables (Redis, AI, Blob, Slack tokens)
- docs/data-storage.md — Redis key, seed/import, backups, images
- docs/operations.md — CI, health check, caching, AI rate limits, PII in prompts
- docs/onboarding.md — New hire Slack detection, pilot recommender, Team onboarding, digest lines
- docs/roadmap-slack-scrape.md — Slack Roadmap scan: threads, two-pass AI (suggest + reconcile), Redis pending queue, approve/reject, daily Vercel cron
- docs/unreplied-asks.md — Followups: founder Slack asks in Slack (channels + group DMs, AI classify-once, nudge via AI-drafted thread reply)
- docs/design-system.md — Brand primitives (glass surfaces, spotlight, buttons) and CSS tokens
Shared UI lives under src/components/brand/: Logo, PageHeader, GlassSurface, PremiumButton, DashboardMain (dashboard background + subtle pointer spotlight), AmbientPad / AmbientSpotlightLayers + useSpotlightCssVars (grid highlight). Global tokens and utilities (.brand-gradient-text, .brand-aurora, focus --ring, --surface-toolbar / --surface-group-header for tracker chrome) are in src/app/globals.css. The app body uses Inter via next/font in src/app/layout.tsx. Roadmap / Team / Companies share PageToolbar and EmptyState in src/components/tracker/. Favicon and Open Graph images are generated from src/app/icon.tsx, src/app/apple-icon.tsx, and src/app/opengraph-image.tsx.
- Node.js 20+ (LTS recommended; Node 21 may show engine warnings from some dependencies)
-
Clone the repo and install dependencies:
npm install
-
Copy environment variables:
copy .env.example .env.local
On macOS/Linux use
cp .env.example .env.local. -
Edit
.env.local: setSESSION_SECRETand Redis (KV_REST_API_URL+KV_REST_API_TOKENorUPSTASH_*). Redis is required for local dev and production. SetANTHROPIC_API_KEYfor AI features. Optional: Blob and Slack — see docs/environment.md. Sign-in: seed a password withnpx tsx scripts/set-password.ts <email> <password>(people must exist in tracker JSON with that email), then sign in at/loginwith email + password. Founders can also set passwords from Team → Login after the first account works. -
Start the dev server:
npm run dev
-
Open http://localhost:3000 and sign in. Use the sidebar for Roadmap, Followups (under Communication), Companies, and Team. The Team page shows a New hires strip (first 30 days, only until a pilot project exists) with Assign onboarding project (streaming AI recommender: multi-select existing unowned pilots and/or queue new projects via Create with AI…; Continue runs one Assignment message + optional
conversations.invitepass per pilot; onboarding-partner picker matches Roadmap owner UX) and Skip (dismiss someone from the strip until their join date changes). Assigned hires move to the main roster with an Onboarding badge; use the Onboarding filter or row … → Onboard employee to find or reopen the flow. See docs/onboarding.md.
Roadmap UI: goal rows use a darker band than the project list; each project is a bordered card under the goal; milestones sit on a light shelf under the project bar (compact rows); project rows are indented vs goals; owner cells are compact avatars; goal Slack uses a compact channel chip (hash + add icon when unset). Collapsed goals show a clickable goal delivery strip after the Slack column: an overlapping owner avatar stack (distinct project owners sorted by autonomy desc), rollup on-time %, AI confidence, and a one-line summary (rollup from child milestone likelihoods + assessGoalOneLiner). Clicking opens a goal delivery popover with stats, reasoning, a per-project drill-down (worst-first), and an Actions → New message in channel… composer that posts a top-level message to the goal's Slack channel via postGoalChannelMessage. See docs/strategic-tracker-slack.md. Goal Due date / Progress are rollups (latest milestone due date across projects; milestone completion across projects). Milestone auto-complete: when the AI-estimated progress for a milestone's Slack thread reaches 100%, the milestone is automatically marked Done (one-shot per thread reply-count; respects manual reversion until new activity re-triggers the AI). See docs/strategic-tracker-roadmap-ui.md.
Redis key ecc:tracker:data; schema in src/lib/schemas/tracker.ts. Seed with npm run seed:kv -- path/to/tracker.json. See docs/data-storage.md. Followups state lives under a separate key ecc:unrepliedAsks:data (docs/unreplied-asks.md).
| Command | Description |
|---|---|
npm run dev |
Next.js development server |
npm run lint |
ESLint (Next.js config) |
npm run typecheck |
TypeScript (tsc --noEmit) |
npm run build |
Production build (run when you want a release build) |
npm run seed:kv -- <file.json> |
Validate and upload a tracker JSON file to Upstash (needs Redis in .env.local) |
npx tsx scripts/set-password.ts <email> <password> |
Set bcrypt login password for a roster person in Redis (bootstrap / CLI rotation) |
- CI — GitHub Actions runs
npm run lintandnpm run typecheckon pushes and PRs tomain/master. GET /api/health— JSON liveness: RedisPING(no login). Details: docs/operations.md.- Draft goal/project AI — The first “ideas” shortlist when opening the dialog is server-cached for 10 minutes (per company for new goals, per parent goal for new projects). The cache is dropped immediately when substantive goal or project fields change, or after TTL. See docs/operations.md.
- Daily executive digest — Vercel Cron posts an AI summary to
#executive-prioritiesevery morning at 12:00 UTC (≈ 8:00 AM ET) fromGET /api/cron/executive-digest. It reads the last 7 days of channel messages, cross-references the tracker, and only surfaces new / interesting / problematic items since the previous digest (deduped in Redis). ConfigureSLACK_EXECUTIVE_PRIORITIES_CHANNEL_ID,ECC_PUBLIC_BASE_URL(defaulthttps://admin.mlabs.vc), andCRON_SECRET— see docs/environment.md and docs/operations.md. - Onboarding detector — Vercel Cron calls
GET /api/cron/onboarding-detectorthree times daily to scan Slack for new-hire welcome threads and update the roster. SameCRON_SECRETauth. See docs/onboarding.md and docs/operations.md. - Followups scan — Vercel Cron calls
GET /api/cron/unreplied-asks-scanhourly to classify new founder Slack messages and refresh thread reply state (Redis keyecc:unrepliedAsks:data). SameCRON_SECRETauth. Refresh now on Followups usesPOST /api/unreplied-asks/scanand streams NDJSON progress to the UI. See docs/unreplied-asks.md and docs/operations.md. - Roadmap Slack sync — Vercel Cron calls
GET /api/cron/slack-roadmap-synconce daily (UTC midnight, seevercel.json) to scan each company’s Slack (threaded history, 2-day window) and refresh the pending review queue in Redis (ecc:slackSuggestions:data). The transcript sent to the model includes human-authored messages only (bot-only webhooks are dropped) so automated billing/alerts don’t spawn goals. SameCRON_SECRETauth and Slack user token as other Slack features. The/syncpage lists pending items with company + type filters, collapsible company groups (with logos), Approve all (with confirmation), per-card Reject / Revise with AI / Approve, and streams Revise viaPOST /api/slack-suggestions/revise. Troubleshooting in Vercel: runtime logs are structured JSON; filter byecc:slackRoadmapSync. See docs/roadmap-slack-scrape.md and docs/operations.md.
Stale Next.js cache: see docs/development.md.
| Doc | Contents |
|---|---|
| docs/strategic-tracker.md | Roadmap doc index (links to data model, Slack, UI, AI) |
| docs/strategic-tracker-data-model.md | Companies, Team, hierarchy, Redis |
| docs/strategic-tracker-slack.md | Slack import, channels, milestone threads |
| docs/strategic-tracker-roadmap-ui.md | Roadmap editing, filters, URLs |
| docs/strategic-tracker-ai-auth.md | Auth, Assistant, AI create/update |
| docs/environment.md | .env.local reference (Redis, AI, Blob, Slack) |
| docs/data-storage.md | Redis key, seed, backup, uploads |
| docs/operations.md | CI, health, cache tags, AI rate limits, PII redaction |
| docs/onboarding.md | New hire detection, pilot recommender, Team onboarding |
| docs/unreplied-asks.md | Followups: founder Slack asks with no teammate reply (wall + nudge) |
| docs/roadmap-slack-scrape.md | Slack Roadmap scan, pending queue, cron, approvals |
| docs/development.md | Local dev troubleshooting |
| docs/design-system.md | Brand components, spotlight intensities, tokens |
Other files under docs/ (e.g. internal prompts or rollout notes) are supplementary.