A local, AI-native learning operations platform. Declare a skill, generate a structured plan, work through lessons with notes and scheduling, evaluate your understanding, and verify mastery from one app.
- Backend: Python 3.10+ / FastAPI
- Frontend: React / Vite / TypeScript / Tailwind / shadcn UI
- LLM providers: Anthropic Claude, DeepSeek, OpenAI, or Google Gemini
- Storage: Local file storage in
praxis-db/
- Python 3.10+ with
python3 -m venvsupport. Python 3.12 is recommended. - Node.js 18+ and npm
- An API key for at least one supported LLM provider: Anthropic, DeepSeek, OpenAI, or Google Gemini
- Optional: Google Cloud OAuth credentials for Google Calendar sync. Praxis scheduling and
.icsexport work without Google.
The native workflow is still the recommended daily development path:
# First-time setup: creates backend/.venv and installs backend/frontend deps
./run.sh setup
# Start backend and frontend dev servers
./run.sh devOpen http://localhost:5173, then go to Settings -> API Keys.
Add an Anthropic, DeepSeek, OpenAI, or Gemini key, choose the active provider, and select a model from the provider model dropdown. If a model list cannot be loaded, Praxis falls back to manual model entry.
First-run flow:
- Run
./run.sh setup. - Run
./run.sh dev. - Open
http://localhost:5173. - Enter a local profile name when Praxis asks on first launch.
- Go to Settings -> API Keys and add at least one LLM provider key.
- Pick the active provider and model. Saving a key and choosing the active provider are separate steps.
- Create your first skill, or start with a roadmap for larger role/goal planning.
- Generate and save schedules in Praxis, then optionally configure Google Calendar from Settings -> Connectors or export
.icsfiles.
No .env files are required. Runtime config is managed in-app and persisted under praxis-db/. On macOS, secrets are stored in Keychain when available; otherwise they fall back to local config storage for development. API keys are never returned to the frontend; the API only exposes whether each key is configured.
If backend/.venv was created with an older Python, install Python 3.10+ and recreate the virtual environment:
rm -rf backend/.venv
./run.sh setupTo force a specific Python interpreter during setup:
PYTHON=python3.12 ./run.sh setup| Command | Description |
|---|---|
./run.sh setup |
Create Python venv and install backend/frontend dependencies |
./run.sh dev |
Start backend :8000 and frontend :5173 with hot reload |
./run.sh backend |
Start backend only |
./run.sh frontend |
Start frontend only |
./run.sh prod |
Build frontend, then start backend and frontend preview |
Add -q or --quiet to suppress console output. Logs are written to /tmp/praxis-backend.log and /tmp/praxis-frontend.log.
Default ports:
- Frontend dev server:
http://localhost:5173 - Frontend production preview:
http://localhost:4173 - Backend API:
http://localhost:8000
Local data:
praxis-db/is created at the repo root.- It stores app data, local config, jobs, generated plans, saved schedules, calendar sync state, notes, and progress.
- It should not be committed.
Docker Compose is optional. Use it for onboarding, a personal VM, or running the full backend + frontend app stack without installing Python and Node directly on the host. For daily local development, the recommended workflow is still:
./run.sh devStart the Docker app stack:
docker compose up -d --buildOpen http://localhost:5173.
Compose runs:
- Backend API on
http://localhost:8000 - Frontend dev server on
http://localhost:5173 - Persistent app data mounted at
./praxis-db
On Linux, API keys entered in Settings are stored in praxis-db/config.json.
Keep that directory private and uncommitted.
Make changes locally:
git add .
git commit -m "Describe the change"
git pushOn the VM, fetch and integrate the latest remote changes before rebuilding:
cd ~/code/Praxis
git pull
docker compose up -d --builddocker compose up starts or recreates the app services. docker compose build
rebuilds images, which is useful when Dockerfiles or dependency files change.
docker compose up -d --build
docker compose ps
docker compose logs -f
docker compose down
docker compose buildcd ~/code/Praxis
git pull
docker compose up -d --builddocker compose ps
docker compose logs -fdocker compose downFor a local production-style run:
./run.sh prodThis builds the frontend into frontend/dist/ and starts the backend on http://localhost:8000 without hot reload.
It also starts a frontend production preview server on http://localhost:4173.
This is a local production-style run, not a full hosted deployment guide. A hosted deployment should add durable storage, multi-user auth, server-side secret management, and deployment-specific frontend/API routing.
Go to Settings -> API Keys:
- Save an Anthropic, DeepSeek, OpenAI, or Gemini API key.
- Pick the active provider.
- Select a model from the dropdown.
Configured keys cannot be edited in place. Remove an existing key first if you want to replace it.
Saving a key does not automatically make that provider active. This keeps credentials and model selection separate: add one or more keys, then explicitly choose the provider Praxis should use.
Provider notes:
- Anthropic: create an API key in the Anthropic Console.
- DeepSeek: create an API key in the DeepSeek platform.
- OpenAI: create an API key in the OpenAI API platform.
- Gemini: create an API key in Google AI Studio. This is separate from the Google Cloud OAuth credentials used for Calendar sync.
Go to Settings -> Connectors for external app connections.
Google Calendar setup lives here, including the Google OAuth Client ID and Client Secret. Use Disconnect Google Calendar to remove the connected Google account and clear the stored OAuth credentials from this device.
The Dashboard is the home screen. It combines today's focus, in-progress lessons, review prompts, and high-level skill progress. If multiple lessons are in progress, the current focus stays compact and the in-progress section below shows the full list.
Use Roadmap when you are aiming at a larger role, domain, or multi-skill goal.
Roadmap workflow:
- Generate a roadmap from a target such as
Quant Developer. - Review the sequenced steps.
- Select one or more planned steps.
- Move selected steps to Skills.
- Open each generated skill and finish its plan.
Roadmap status behavior:
- A roadmap is planned until at least one step has been moved into Skills.
- A roadmap becomes active once one or more linked skills exist.
- A roadmap becomes completed when all linked steps are completed.
- Completing or progressing a linked skill updates the corresponding roadmap step.
Skill status is derived from the plan and lesson progress:
- Draft: no approved plan yet.
- Planning: a plan exists, but no lesson has been started.
- In progress: at least one lesson has moved away from not started.
- Paused: manually paused by the user.
- Completed: all active lessons are completed, or final review marks the skill complete.
Inside a lesson, the focus/Pomodoro control helps run a timed work block. Starting a lesson can move it into progress, and reverting a lesson back to not started resets the focus timer state for that lesson.
Praxis has three calendar levels:
- Generate schedule previews lesson placement. This is safe to experiment with and does not change the skill.
- Use this schedule saves the schedule inside Praxis, updates the skill's weekly hours, and shows the events on the main Calendar page.
- Sync to Google is optional and exports the saved lesson events into your primary Google Calendar.
Google Calendar is not required. If you do not connect Google, Praxis can still generate schedules, save them locally, show them on the Calendar page, and export them as .ics.
Calendar behavior:
- Preview schedule checks your Google Calendar busy time only when Google Calendar is connected.
- Without Google Calendar, preview/save still works, but conflict checks only use the selected scheduling window.
- Saved Praxis schedules appear on the main Calendar page as saved.
- Google-synced schedules appear as synced.
- Clearing a saved schedule removes it from Praxis.
- Unsync removes synced Praxis events from Google Calendar and clears that skill's saved calendar state.
- Removing a skill also attempts to remove that skill's synced Praxis calendar events.
Use Calendar -> Export .ics to export committed schedule events.
The export dialog supports:
- Skill multiselect with search
- Upcoming 30 days, upcoming 90 days, all events, or a custom date range
- Saved Praxis events, Google-synced events, or both
The .ics file can be imported into Apple Calendar, Google Calendar, Outlook, Fantastical, and most calendar apps. Praxis uses stable event UIDs such as praxis-{skill_id}-{lesson_id}@praxis.local so calendar apps have the best chance of updating existing Praxis events on re-import. Some calendar apps may still create duplicates; import behavior is app-specific.
Calendar sync is optional. Because Praxis runs locally, Google Calendar uses your own Google Cloud OAuth client.
Google Cloud setup:
- Open Google Cloud Console and create or select a project.
- Go to APIs & Services -> Library.
- Search for Google Calendar API and click Enable.
- Go to APIs & Services -> OAuth consent screen.
- Choose External unless you are using an internal Google Workspace app.
- Fill in the required app information.
- Keep the app in Testing mode for local use.
- Add the Google account you will sign in with as a Test user. For a local/testing OAuth app, you must add yourself here before Google will allow the connection.
- In the consent screen's data access/scopes section, add these scopes if Google asks you to declare them:
https://www.googleapis.com/auth/calendar.events
https://www.googleapis.com/auth/calendar.readonly
https://www.googleapis.com/auth/userinfo.email
openid
- Go to APIs & Services -> Credentials.
- Click Create Credentials -> OAuth client ID.
- Choose application type Web application.
- Add this authorized redirect URI exactly:
http://localhost:8000/api/calendar/oauth/callback
- Save the client, then copy the Client ID and Client Secret.
Then in Praxis:
- Go to Settings -> Connectors.
- In the Google Calendar connector, save the Google OAuth Client ID and Client Secret.
- Click Connect Google Calendar and complete the Google OAuth flow.
After a successful OAuth flow, Praxis redirects back to the Connectors tab and shows a connection success message.
Common Google OAuth issues:
Error 400: redirect_uri_mismatch: the authorized redirect URI must exactly matchhttp://localhost:8000/api/calendar/oauth/callback.Error 403: access_denied: add yourself/the signed-in Google account as a test user on the OAuth consent screen.- Unverified app warning: expected for a local testing app. Use Advanced and continue if it is your own project.
- The backend must be running on port
8000when Google redirects back to Praxis.
Praxis needs Python 3.10+. If backend startup fails with Python syntax/type errors, recreate the virtual environment:
rm -rf backend/.venv
PYTHON=python3.12 ./run.sh setupThe dev server expects ports 5173 and 8000. Stop the process using the port, then rerun:
./run.sh devIf AI actions fail with a provider configuration error, go to Settings -> API Keys, add a provider key, choose the active provider, and select a model.
If a provider model list cannot be fetched, Praxis shows manual model entry. You can paste a valid model name directly.
For redirect_uri_mismatch, check the redirect URI exactly. For access_denied, add the signed-in Google account as a test user in Google Cloud Console.
# Backend
cd backend && .venv/bin/pytest -q
# Frontend
cd frontend && npm test -- --run
# Frontend production build
cd frontend && npm run buildIntegration tests that call real LLM providers are skipped unless explicitly enabled with pytest --integration.
Praxis/
├── run.sh One-command launcher
├── backend/ FastAPI backend
│ ├── agent/ LLM providers, prompts, and strategies
│ ├── calendar_sync/ Google Calendar OAuth and scheduling
│ ├── routers/ HTTP endpoints
│ ├── storage/ Schemas and local file persistence
│ └── tests/
├── frontend/ React / Vite frontend
│ └── src/
│ ├── components/ Shared UI and app components
│ ├── pages/ Top-level routes
│ ├── skill/ Skill workspace panels
│ └── test/
└── praxis-db/ Runtime data generated locally
- Declare a skill: choose a skill, depth, pace, and weekly time commitment.
- Generate a plan: AI creates an outline, then expands it into modules, lessons, objectives, and resources.
- Execute: schedule lessons, take notes, track progress, and optionally export
.icsor sync to Google Calendar. - Evaluate: run assessment flows that update your learning profile and review queue.
- Verify: use final review and exports to summarize progress and mastery.