Pravah is a timeline-first task manager built around a horizontal week view. Tasks live either on the timeline (scheduled to a date) or in the inbox (unscheduled). Kairo, an AI copilot docked at the bottom, can reason about your schedule and add tasks on your behalf.
The mobile app (Expo / React Native) currently targets Android preview builds: inbox, timeline, goals, Kairo AI, and sync in the same mobile shell.
Pravah is currently designed and operated as a single-user system. Auth and ownerTokenIdentifier still scope records per signed-in identity, but that isolation exists for session safety, sync ownership, and legacy-data migration compatibility - not as a supported multi-user workspace model.
Stack:
- Web — Vite + React (
src/), Geist fonts, Framer Motion, dnd-kit - Backend — Convex (
convex/) with Better Auth - Mobile — Expo React Native (
apps/mobile/) - Automation CLI — bun-targeted package in
packages/cliwith authenticated JSON commands for agents and local workflows
- Install dependencies
bun install- Configure root
.env.local
CONVEX_DEPLOYMENT=your-deployment
VITE_CONVEX_URL=https://your-deployment.convex.cloud
VITE_CONVEX_SITE_URL=https://your-deployment.convex.site
VITE_GOOGLE_CLIENT_ID=your-google-web-client-id- Start Convex backend
bunx convex dev- Start the web app and confirm the shell loads
bun run devThen open the printed local URL and confirm the timeline shell renders before you move on to mobile or backend debugging.
| Command | Description |
|---|---|
bun run dev |
Start web dev server |
bun run build |
Type-check + production build |
bun run lint |
ESLint |
bun run test:run |
Vitest suite |
bun run pravah -- --help |
Pravah automation CLI |
bun run mobile:start |
Start Expo |
bun run mobile:android |
Android native build (auto-syncs env) |
bun run mobile:web |
Expo web |
Run cd packages/cli && bun link once when you want the package bin available directly as pravah. Use bun run pravah -- <namespace> <command> inside the checkout without linking.
src/ React web client
components/ Timeline, InboxSidebar, Kairo, QuickAdd, TaskPopup, ...
hooks/ Drag handlers, keyboard shortcuts, overlay state
lib/ Motion tokens, date utils, Kairo config
convex/ Backend: schema, queries, mutations, HTTP routes
apps/mobile/ Expo React Native app
docs/ Technical documentation
.agents/skills/ Repo-local agent skills
packages/cli/ Standalone bun-targeted automation CLI package
- Pravah is a personal planner for one signed-in user, not a shared multi-user workspace.
- Legacy Convex rows without
ownerTokenIdentifierare claimed by the current user during bootstrap because those rows come from earlier single-user app versions. - If the product ever expands to true multi-user support, ownership migration and review assumptions should be redesigned explicitly rather than inferred from today's schema.
Kairo sits in the bottom dock (⌘J to open). It uses your own API key — configure it in Settings with:
- Provider format: OpenAI-compatible or Anthropic
- API key: sent directly from your browser, never stored server-side
- Endpoint URL: e.g.
https://api.openai.com/v1/chat/completionsorhttps://api.anthropic.com/v1/messages - Model: e.g.
gpt-4o,claude-sonnet-4-6
Click outside the panel or press ⌘J to close.
CONVEX_DEPLOYMENT=your-deployment
VITE_CONVEX_URL=https://your-deployment.convex.cloud
VITE_CONVEX_SITE_URL=https://your-deployment.convex.site
VITE_GOOGLE_CLIENT_ID=your-google-web-client-idBETTER_AUTH_SECRET=generate-a-random-secret
SITE_URL=http://localhost:5173
GOOGLE_OAUTH_CLIENT_ID=your-google-web-client-id
GOOGLE_OAUTH_CLIENT_SECRET=your-google-web-client-secret
MOBILE_APP_SCHEME=pravah://
CONVEX_HTTP_API_KEY=your-http-api-key
# Required only for legacy API-key automation routes
PRAVAH_HTTP_OWNER_TOKEN_IDENTIFIER=your-auth-token-identifier
# Optional: additional comma-separated web origins trusted for Better Auth
# session routes and `/google/token` preflights (use for staging/preview deploys).
ALLOWED_CORS_ORIGINS=https://staging.example.com,https://preview.example.combun run mobile:env # generates apps/mobile/.env.local from root envmobile:start, mobile:android, and mobile:web run this automatically.
GitHub Actions runs on pull requests and pushes to main:
- Lint — ESLint
- Build — Vite production build + TypeScript check
- Release Please — automated release PR/tag flow for web (on
main)
Versioning and GitHub Releases for web are managed by release-please:
- On every push to
main, it scans Conventional Commits since the lastwebtag. - If releasable changes exist, it opens/updates a release PR that bumps root (
web) version only. - When that release PR merges, it creates
webtags and GitHub Releases.
Tag format:
web-vX.Y.Z
Mobile is intentionally decoupled from release-please version bumps.
apps/mobile/app.jsonexpo.versionis kept stable during JS-only UI rounds.- Publish JS-only changes with EAS Update (
--platform android) to branchpreview. - Bump mobile version only when intentionally rolling out a new APK/runtime.
See apps/mobile/build.md for the runtime-matching OTA playbook.
docs/architecture.md— system architecture and module mapdocs/development.md— local setup, environment, and workflowsdocs/api.md— HTTP routes and CLI automationdocs/google-oauth.md— Google OAuth setup and troubleshootingapps/mobile/docs/README.md— mobile documentation indexapps/mobile/docs/architecture.md— detailed mobile architecture and state/query ownershipapps/mobile/docs/ux-orchestration.md— mobile loading, keyboard, settings, motion, and Android back behaviorapps/mobile/MOBILE_TESTING.md— ADB-driven QA walk for the mobile appapps/mobile/DEBUGGING.md— log prefixes, ADB commands, and known dependency pins
- Never expose
GOOGLE_OAUTH_CLIENT_SECRETviaVITE_variables. - Keep secrets in deployment/server env only.
- Do not commit
.env.localor real credentials. - CLI credentials are stored at
$XDG_CONFIG_HOME/pravah/credentials.json(or~/.config/pravah/credentials.json) with user-only permissions. - Automation credentials are read-only by default; enable task-write scope only for trusted workflows.





