This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Tasky is a local-first personal task organization system. It combines an Obsidian markdown vault (the knowledge store), a SQLite database (structured operational state), a Python FastAPI backend, and a React frontend. The core design principle: AI proposes, human approves — all LLM-generated task changes flow through a proposal review step before any mutation is applied.
cd backend
uv sync # Install dependencies
uv run uvicorn app.main:app --reload --port 7400 # Start dev server on :7400
uv run pytest # Run all tests
uv run pytest tests/test_tasks.py # Run a single test modulecd frontend
npm install # Install dependencies
npm run dev # Start Vite dev server (proxies /api → :8000)
npm run build # Production buildcp backend/.env.example backend/.env
# Required: ANTHROPIC_API_KEY
# Optional: GITHUB_TOKEN, GMAIL_*, SLACK_*, CANVAS_* (validated when used)- Connectors (
backend/app/connectors/) fetch external data (GitHub, Gmail, Slack, Canvas) and return normalized batches. - Ingestion service stores batches into
IngestionBatchrecords and calls the LLM to generateTaskProposalrecords. - User reviews proposals via the frontend Proposals UI — approve, edit, or reject.
- Proposal service applies approved proposals by mutating
Taskrecords and writing audit entries toTaskStatusHistory.
app/api/— FastAPI routers (HTTP boundary only)app/services/— Business logic; all mutations go through hereapp/models/— SQLAlchemy ORM models (Task, TaskProposal, TaskStatusHistory, Experience, IngestionBatch, IngestionRun)app/connectors/— External data sources; implement thebase.pyprotocol, return{source_type, payload, metadata}app/llm/— Anthropic client wrapper, context builder, Pydantic schemas for structured outputapp/vault/— Obsidian vault reader; experiences and prompts are markdown files invault/
- Task — Core item. Status:
todo/in_progress/blocked/done/cancelled. Priority:low/medium/high/urgent. Supports subtasks viaparent_task_id. Linked to anExperience. - TaskProposal — Trust boundary for AI changes. Types:
create_task,update_task,change_status,cancel_task. Status:pending/approved/rejected/superseded. All proposals are logged for audit. - Experience — Long-running context (project, job, class). Each experience has a corresponding markdown file in
vault/Experiences/{folder_path}/. - IngestionRun / IngestionBatch — Metadata and raw payloads from each connector run.
- React 18 + Vite 5 + TypeScript + TanStack Query
- Vite dev server proxies
/api/*tohttp://localhost:8000 - Pages: Tasks, Proposals, Ingestion, Experiences, Prompts (in
src/pages/) - Server state managed with TanStack Query hooks in
src/api/
vault/ is git-tracked markdown. Key subdirectories:
Experiences/— One folder per experience with a markdown overviewPrompts/— System prompts editable from the UIDaily/,Weekly/,Monthly/— Summaries
- Python 3.12 (required), managed with
uv - FastAPI + SQLAlchemy + Alembic (migrations in
backend/app/db/migrations/) - SQLite at
data/app.db(git-ignored) - Anthropic SDK for LLM integration
- pytest with
asyncio_mode = auto(configured inpyproject.toml)