A developer productivity dashboard that pulls your work from every tool into one prioritized surface — with AI summaries and urgency ranking so you always know what to do next.
Upright connects GitHub, Slack, Google Calendar, Sentry, Jira, Linear, Notion, and more, then ranks everything by urgency, blocker impact, and review state. Instead of tab-hopping across a dozen tools to figure out what needs your attention, you open one page.
Upright started as a private product (it ran at upright.dev). I've decided to open source the entire codebase under the MIT license so anyone can self-host it, learn from it, or build on top of it.
If you've ever wanted a single, self-hostable "mission control" for your engineering work — or you're curious how to wire up OAuth for a dozen developer tools, encrypt tokens at rest, and rank work with AI — clone it, run it, and make it yours. Contributions are very welcome.
- One operational surface — aggregates signals from every connected tool into a single ranked view.
- Urgency prioritization — scores work by deadline pressure, blocker impact, dependency context, and review state (
lib/urgency.ts). - AI summaries — turns raw activity into a scan-friendly briefing via Groq + LLaMA 3.3-70B (
lib/groq.ts). - Sentry root-cause assist — correlates production issues to the PRs most likely responsible, using blame, stacktrace, and diff evidence.
- Reviewer prediction — surfaces review state, ownership, and the next action around code changes.
- Daily digests & reminders — scheduled summaries and notification loops via cron endpoints.
- Secure by design — OAuth tokens are encrypted at rest with AES-256-GCM; Supabase RLS isolates every user's data.
| Category | Services |
|---|---|
| Code & PRs | GitHub, GitLab, Bitbucket |
| Issues & projects | Jira, Linear, Shortcut, Asana |
| Communication | Slack, Gmail |
| Calendar | Google Calendar |
| Observability | Sentry |
| Docs & design | Notion, Figma |
| AI | Groq (LLaMA 3.3-70B) |
Most integrations use OAuth; a few support legacy token modes for self-hosting. See .env.local.example for the full list.
The tour uses safe sample data and highlights the Work queue, Team Insights, and Calendar surfaces.
- Framework — Next.js 16 (App Router), React 19, TypeScript
- Data — Supabase (Postgres + Auth + RLS), TanStack React Query
- State — Zustand (client) + React Context (settings/org)
- Styling — Tailwind CSS v4
- AI — Groq SDK (LLaMA 3.3-70B)
- Analytics & flags — PostHog
- Testing — Vitest
- Node.js 20+
- A Supabase project (free tier is fine)
- OAuth app credentials for whichever integrations you want (GitHub and Google get you the core experience)
git clone <your-fork-url> upright
cd upright
npm installcp .env.local.example .env.localAt minimum, fill in:
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Supabase anon key |
SUPABASE_SERVICE_ROLE_KEY |
Supabase service role key (server only) |
ENCRYPTION_KEY |
64-char hex key — generate with openssl rand -hex 32 |
GITHUB_OAUTH_CLIENT_ID / _SECRET |
GitHub OAuth app |
GOOGLE_OAUTH_CLIENT_ID / _SECRET |
Google OAuth app (Calendar/Gmail) |
GROQ_API_KEY |
AI summaries |
Everything else is optional and enables additional integrations. See .env.local.example for the complete, annotated list.
The SQL migrations live in scripts/. Apply them to your Supabase project (via the SQL editor or the Supabase CLI) — start with the migration_*.sql files, then the add_*.sql column additions.
npm run dev # http://localhost:3000- Slack on localhost — Slack OAuth rejects
http://. PointAPP_URLat an HTTPS tunnel (e.g. ngrok) and register the same/api/auth/slack/callbackURL in your Slack app. - Cron jobs — digests/reminders are protected by
CRON_SECRET(sent asAuthorization: Bearer <CRON_SECRET>).ENABLE_REMINDERS_CRON=falseby default for hobby/self-host setups. - Test routes — anything under
/api/test/is for local debugging only and is disabled whenNODE_ENV=production.
React Hooks (useGitHub, useShortcut, …)
↓ TanStack React Query (2-min stale time)
↓ API Routes (/api/github, /api/shortcut, …)
↓ lib/* (github.ts, shortcut.ts, …)
↓ External APIs + Supabase (encrypted token storage)
- Auth — Supabase Auth with SSR.
src/proxy.tsrefreshes the session and redirects unauthenticated users to/login. - Tokens — encrypted with AES-256-GCM (
lib/encryption.ts) and resolved on demand (lib/token-resolver.ts). - Adding an integration — create
lib/[service].ts, an OAuth config, an API route, a hook, and a section component. See CLAUDE.md for the full recipe and conventions.
src/
├── app/ # Next.js App Router pages + API routes
│ └── api/ # github, slack, sentry, jira, cron, … route handlers
├── components/ # AppShell + per-service section components
├── hooks/ # useGitHub, useShortcut, … (React Query)
└── lib/ # API wrappers, urgency scoring, encryption, AI summaries
scripts/ # SQL migrations + setup helpers
docs/ # Setup guides
npm run dev # start the dev server
npm run build # production build
npm run start # serve the production build
npm run lint # ESLint
npm run typecheck # tsc --noEmit
npm run test # VitestContributions, issues, and feature requests are welcome!
- Fork the repo and create a branch (
git checkout -b feat/my-feature). - Make your change and keep it covered:
npm run typecheck && npm run lint && npm run test. - Run a production build to catch type errors:
npm run build. - Open a pull request describing what changed and why.
See CLAUDE.md for architecture conventions and design principles the codebase follows.
- Never commit secrets.
.env*and.mcp.jsonare gitignored. - All third-party tokens are encrypted at rest (AES-256-GCM) before hitting the database.
- Found a vulnerability? Please open a private security advisory rather than a public issue.
MIT © Ozan Sozuoz