diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..85fdcb3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,90 @@ +# CLAUDE.md + +## Project Overview + +trails.cool is a federated, self-hostable platform for outdoor enthusiasts with two apps: + +- **Planner** (`apps/planner`) — Stateless collaborative route editor. Real-time editing via Yjs, routing via BRouter, no user accounts, sessions are anonymous and ephemeral. +- **Journal** (`apps/journal`) — Federated social platform for routes and activities. User accounts, ActivityPub federation via Fedify, PostgreSQL + PostGIS. + +Full architecture: `docs/architecture.md` +Philosophy: `docs/philosophy.md` +OpenSpec change: `openspec/changes/phase-1-mvp/` + +## Principles + +- **Privacy-first**: The Planner collects zero user data. The Journal documents all data collection in a privacy manifest. Never add tracking, analytics, or data collection without updating the manifest. +- **Data ownership**: All user data must be exportable in open formats (GPX, JSON). Never create data lock-in. +- **Simplicity**: Start with the simplest thing that works. Don't add abstractions, config options, or features unless real users need them. +- **Open standards**: Use GPX, ActivityPub, OpenStreetMap, WebFinger. Don't invent proprietary formats. +- **Inclusive language**: Use "host" not "master", "allowlist" not "whitelist", etc. + +## Tech Stack + +- **Language**: TypeScript (strict mode) +- **Frontend**: React + Tailwind CSS + React Router 7 (Remix stack) +- **Maps**: Leaflet + OpenStreetMap tiles +- **CRDT**: Yjs + y-websocket (Planner only) +- **Federation**: Fedify (Journal only, Phase 2) +- **Database**: PostgreSQL + PostGIS +- **Media storage**: S3-compatible (Garage) +- **Routing engine**: BRouter (Java, runs as separate Docker container) +- **i18n**: react-i18next (English + German) +- **Monorepo**: pnpm workspaces + Turborepo + +## Repository Structure + +``` +apps/ + planner/ — Planner app (React Router 7) + journal/ — Journal app (React Router 7 + Fedify) +packages/ + types/ — Shared TypeScript interfaces (Route, Activity, Waypoint) + ui/ — Shared React components (Tailwind) + map/ — Leaflet map wrappers and tile layer configs + gpx/ — GPX parsing, generation, validation + i18n/ — react-i18next config + translations +infrastructure/ — Terraform + Docker Compose +openspec/ — OpenSpec specs and changes +docs/ — Architecture, philosophy, tooling docs +docker/brouter/ — BRouter Docker image +``` + +## Development Commands + +```bash +pnpm install # Install dependencies +turbo dev # Start both apps in dev mode +turbo build # Build all packages and apps +turbo typecheck # Type-check all packages +turbo lint # Lint all packages +turbo test # Run tests +``` + +## Code Conventions + +- All user-facing strings must use i18n (`useTranslation()` hook, never hardcode strings) +- Use `@trails-cool/types` for shared interfaces — don't duplicate type definitions +- Map components go in `@trails-cool/map`, not in individual apps +- GPX parsing/generation goes in `@trails-cool/gpx` +- Database schemas: `planner.*` for Planner data, `journal.*` for Journal data +- Route geometry must be stored as PostGIS LineString (extracted from GPX on save) + +## Key Architecture Decisions + +- **Planner is stateless**: No user accounts, no persistent user data. Sessions are anonymous. +- **Journal is the source of truth**: Routes live on the owner's Journal instance. +- **Routing host pattern**: One client per Planner session talks to BRouter (elected via Yjs awareness). +- **JWT callbacks**: Planner saves back to Journal via scoped JWT tokens in callback URLs. +- **Sequential versioning**: Route versions are v1, v2, v3. Yjs state vectors enable conflict-free merging. +- **Single domain**: Each instance uses one domain for both web UI and ActivityPub handles. +- **Simple permissions**: View + Edit only. No fine-grained permissions. + +## OpenSpec Workflow + +Specs live in `openspec/`. Use these slash commands: + +- `/opsx:propose` — Create a new change with proposal, design, specs, and tasks +- `/opsx:apply` — Implement tasks from an existing change +- `/opsx:explore` — Think through ideas before proposing +- `/opsx:archive` — Archive a completed change diff --git a/README.md b/README.md new file mode 100644 index 0000000..b846560 --- /dev/null +++ b/README.md @@ -0,0 +1,94 @@ +# trails.cool + +Collaborative route planning and federated activity sharing for outdoor +enthusiasts. + +**Planner** — Plan routes together in real-time. Share a link, invite friends, +edit waypoints collaboratively. Powered by [BRouter](https://github.com/abrensch/brouter) +for intelligent routing with elevation awareness. + +**Journal** — Track your adventures. Import activities from Garmin, Strava, or +Wahoo. Share routes and rides with friends. Self-host your own instance and +federate with others via ActivityPub. + +## Status + +Early development. See the [architecture plan](docs/architecture.md) and +[project philosophy](docs/philosophy.md). + +## Project Structure + +This is a TypeScript monorepo using pnpm workspaces and Turborepo. + +``` +apps/ + planner/ Collaborative route editor (React Router 7 + Yjs + Leaflet) + journal/ Activity social platform (React Router 7 + Fedify + PostGIS) + +packages/ + types/ Shared TypeScript interfaces + ui/ Shared React components (Tailwind) + map/ Leaflet map wrappers + gpx/ GPX parsing and generation + i18n/ Internationalization (English + German) +``` + +## Getting Started + +Prerequisites: Node.js 20+, pnpm + +```bash +# Clone +git clone https://github.com/trails-cool/trails.git +cd trails + +# Install dependencies +pnpm install + +# Start development +turbo dev +``` + +## Development Tools + +This project uses AI-assisted, spec-driven development. See +[docs/tooling.md](docs/tooling.md) for details. + +| Tool | Purpose | +|------|---------| +| [cmux](https://cmux.dev) | Native macOS terminal for running multiple AI coding sessions | +| [Claude Code](https://claude.ai/claude-code) | AI coding assistant (primary development tool) | +| [Crit](https://github.com/tomasz-tomczyk/crit) | Browser-based inline code review | +| [OpenSpec](https://openspec.dev) | Spec-driven development workflow | + +## Self-Hosting + +The Journal is designed to be self-hosted. A single Docker Compose file gets +you running: + +```bash +curl -O https://raw.githubusercontent.com/trails-cool/trails/main/infrastructure/docker-compose.yml +docker compose up -d +``` + +See [docs/architecture.md](docs/architecture.md) for details on self-hosting +configuration. + +## Philosophy + +- **Privacy by design** — The Planner collects zero user data +- **Data ownership** — Export everything, self-host, no lock-in +- **Open source** — MIT licensed, built on open standards +- **Simplicity** — Start simple, add complexity only when needed + +Read more: [docs/philosophy.md](docs/philosophy.md) + +## Contributing + +Human contributions are welcome! This project is built with AI-assisted +development (Claude Code + OpenSpec), but we value human judgment, design taste, +and community input. + +## License + +MIT diff --git a/docs/tooling.md b/docs/tooling.md new file mode 100644 index 0000000..f9c69b9 --- /dev/null +++ b/docs/tooling.md @@ -0,0 +1,109 @@ +# Development Tooling + +This project is built using AI-assisted, spec-driven development. Here are the +main tools used in the development workflow. + +## cmux + +**Native macOS terminal for AI coding agents** + +- Website: https://cmux.dev +- GitHub: https://github.com/manaflow-ai/cmux + +cmux is a native macOS terminal app purpose-built for running AI coding agents +like Claude Code. It provides vertical tabs, split panes, and smart +notifications that show which panes need attention — ideal for running multiple +Claude Code sessions in parallel across different parts of the monorepo. + +Key features we use: +- Split panes for Planner and Journal development side by side +- Notification badges when a Claude Code session needs input +- Native performance (Swift/AppKit, not Electron) + +## Claude Code + +**AI coding assistant (CLI)** + +- Website: https://claude.ai/claude-code +- Docs: https://docs.anthropic.com/en/docs/claude-code + +Claude Code is the primary development tool for this project. It reads the +codebase, understands the architecture (via `CLAUDE.md`), and implements +features from OpenSpec tasks. + +Key integrations: +- `CLAUDE.md` at repo root provides project context +- OpenSpec slash commands (`/opsx:propose`, `/opsx:apply`, etc.) +- Crit integration for code review + +## Crit + +**Inline code review tool** + +- GitHub: https://github.com/tomasz-tomczyk/crit + +Crit provides browser-based inline review for files and diffs. It's used in +the development workflow for reviewing architecture plans, specs, and code +changes before committing. + +How we use it: +- Review architecture and design documents with inline comments +- Claude Code addresses review comments and re-opens for another round +- Iterate until the reviewer clicks "Finish Review" with no comments (approved) + +Usage: +```bash +crit # Review a specific file +crit # Review git diff (uncommitted or branch changes) +crit share # Share a review via URL +``` + +## OpenSpec + +**AI-native spec-driven development** + +- Website: https://openspec.dev +- GitHub: https://github.com/Fission-AI/OpenSpec + +OpenSpec structures the development workflow around specifications. Each feature +starts as a "change" with four artifacts: + +1. **proposal.md** — Why this change is needed and what capabilities it adds +2. **design.md** — Technical decisions and architecture +3. **specs/** — Testable requirements with WHEN/THEN scenarios +4. **tasks.md** — Implementation checklist + +Workflow: +```bash +# Propose a new feature (generates all artifacts) +/opsx:propose "add route sharing" + +# Implement tasks from a change +/opsx:apply + +# Archive when done +/opsx:archive +``` + +OpenSpec files live in `openspec/` at the repo root. The current active change +is `openspec/changes/phase-1-mvp/`. + +## How They Work Together + +``` +1. Plan cmux + Claude Code + Crit + Draft architecture → review with Crit → iterate + +2. Specify Claude Code + OpenSpec + /opsx:propose → generates proposal, design, specs, tasks + +3. Implement cmux + Claude Code + OpenSpec + /opsx:apply → Claude Code works through tasks + Run multiple sessions in cmux split panes + +4. Review Crit + Review changes in browser → address comments → approve + +5. Ship Claude Code + Commit, push, deploy +```