A living map for solo travelers.
为独自旅行者设计的"活地图"——打开就是地图,地图上自动显示周边值得做的事。
Not another travel app. Not a Google Maps clone. Not a small-red-book replacement.
A map-first, experience-as-unit, AI-curated companion for people traveling alone — where every dot on the map is a thing worth doing, not just a place that exists.
Three design pillars (non-negotiable):
| Layer | Role | Principle |
|---|---|---|
| Map | Root | Always the home screen. No tabs, no drawer, no onboarding flow. |
| Experience | Unit | Not "places" — concrete, time-bound, story-rich things to do. |
| AI | Soul | Filters candidates from 1000 to 5. Never decides for the user. |
AI doesn't travel for you. AI helps you travel better.
For the full product brief, see docs/PRODUCT_BRIEF.md.
solo-compass/
├── apps/
│ ├── web/ # Pre-MVP: Next.js + Mapbox (Phase 2)
│ ├── ios/ # Native iOS app (Phase 3)
│ └── bot/ # Telegram bot for low-cost validation
├── packages/
│ ├── core/ # Shared domain types: Experience, Place, User, etc.
│ ├── ai/ # Prompts, recommendation engine, Claude wrappers
│ ├── data/ # OSM/Wikivoyage ingestion, schema, seeders
│ └── ui/ # Shared design tokens (web only — iOS uses native)
├── docs/ # Product brief, architecture, decisions
├── scripts/ # Cold-start data pipelines, dev tooling
└── seeds/ # Hand-curated seed experiences (Chiang Mai 50)
Boundary discipline: core/, ai/, data/ are platform-agnostic and have no UI dependencies. Each app pulls only what it needs. You can run any one app without the others.
Requires Node 20+, pnpm 9+. iOS app requires Xcode 15+ (added in Phase 3).
# Clone
git clone https://github.com/kubbot/solo-compass.git
cd solo-compass
# Install all workspaces
pnpm install
# Copy env templates
cp .env.example .env.local
# Then fill in: ANTHROPIC_API_KEY, MAPBOX_TOKEN, SUPABASE_URL, SUPABASE_KEY
# Run the web app (Phase 2)
pnpm --filter @solo-compass/web dev
# Run the bot (low-cost validation)
pnpm --filter @solo-compass/bot devSee CONTRIBUTING.md for development workflow.
This project follows a strict validate-before-build roadmap. Each phase has a clear stop/go gate.
| Phase | What | Duration | Stop/go gate |
|---|---|---|---|
| 0 | Field week — go to Chiang Mai, do 7 experiences, write seeds | 1 week | 7 experiences with emotional weight |
| 1 | Notion DB + Figma prototype — show to 10 friends | 2–3 weeks | 30s comprehension test passes |
| 2 | Web Pre-MVP — Next.js + Mapbox, manual check-in | 4 weeks | 30+ users in Chiang Mai, week-1 retention >40% |
| 3 | iOS native — background GPS, push notifications, real magic | 2–3 months | Production launch |
Currently in: Phase 3 — v1.1 TestFlight prep.
iOS native app is feature-complete for v1.1: SwiftData persistence, AI cost control + caching, three-state Solo Score, freemium with 7-day free trial (StoreKit 2), Supabase cross-device sync (feature-flagged), zh-Hans localization, privacy manifest, first-run consent sheet. See docs/APP_STORE_METADATA.md for the App Store Connect submission package.
The data layer (packages/data, packages/core) and AI layer (packages/ai) are platform-shared and stable.
- Monorepo: pnpm workspaces + Turborepo
- Language: TypeScript everywhere except iOS (Swift)
- Web: Next.js 15 (App Router), Mapbox GL JS, Tailwind
- iOS: SwiftUI + MapKit (Phase 3)
- Bot: Telegraf
- DB: Supabase (Postgres + PostGIS for geospatial)
- AI: Anthropic Claude API
- Data sources: OpenStreetMap (Overpass), Wikivoyage, Wikipedia, Reddit, YouTube transcripts
Because the data schema is more valuable than the data itself, and we want the schema to become a standard.
If "experience-as-unit" is the right abstraction for travel, it should outlive any one product. The codebase here defines what an experience is — anyone can fork the data layer and build a different front-end.
What we keep proprietary (in private repos):
- Curated seed experiences for each city
- Prompt engineering for content quality
- User-generated experience corpus
Every push and pull request is automatically scanned for accidentally committed secrets using gitleaks.
Run locally before pushing:
# Install gitleaks (macOS)
brew install gitleaks
# Scan the working tree (no git history required)
gitleaks detect --source . --no-gitWhat the .gitleaks.toml allowlist exempts — and why:
| Pattern | File | Reason |
|---|---|---|
pk.eyJ… |
.env.example |
Mapbox public-token placeholder; not a real secret, intentionally shown as a format hint |
xxxxx.supabase.co |
.env.example |
Supabase placeholder URL; xxxxx is obviously not a real project ID |
sk-replace-me |
.env.example |
Literal placeholder string; not a key that could authenticate against any API |
Real values must never be committed. Copy .env.example to .env (gitignored) and fill in actual keys there.
MIT — see LICENSE.
Pre-alpha. Don't use this in production. The schema will change.
If you're a solo traveler in Chiang Mai and want to be a seed user, open an issue tagged seed-user.
Built by @cubxxw and friends. Started 2026.