# Astrolabe Project > **Purpose**: Onboarding document for AI agents (and humans) working on Astrolabe. --- ## Project Overview **Astrolabe** is a browser-based snippet manager for Vega-Lite visualizations. A user keeps a local library of **snippets** (saved Vega-Lite specs), edits each as JSON with live validation and a live chart preview, and reuses **datasets** across many snippets. Fully local, offline-capable, no account. It is a **spec-driven rebuild** on an architecture adapted from its sibling project Syto. The authoritative behavioral contract is **`docs/spec/`** (sections 00–10). Implement *to the spec*; do not port legacy code. ### Technical Stack | Layer | Technology | |-------|------------| | Build | Vite, TypeScript, Vitest (happy-dom) | | UI | React, Zustand, CSS Modules | | Editor | Monaco (JSON + Vega-Lite schema service) | | Charts | Vega-Lite + vega-embed | | Storage | IndexedDB (snippets, datasets), localStorage (settings/prefs), URL hash (view state) | | Offline | `vite-plugin-pwa` (Workbox), `registerType: 'prompt'` | --- ## Architecture (non-negotiable) - **`src/core/` is portable** — no browser APIs, no React, no Monaco. All spec operations live here and are tested hardest. - **`src/app/`** — React + Zustand UI. State in Zustand **stores**; browser specifics in **`src/app/infrastructure/`** adapters (IndexedDB / localStorage / URL hash). The rest of the app never touches `window`/`indexedDB` directly. - **Modals** go through a registry + coordinator + shell, not ad-hoc rendering. - **CSS Modules + design tokens** (`styles/tokens.css`); themes flip `[data-theme]`. - **No shared library with Syto** — patterns are adapted, never imported. See [`docs/architecture/`](docs/architecture/00-overview.md) for the patterns behind each layer (state, persistence, modals, routing, rendering, inference, relationships) and `docs/IMPLEMENTATION-PLAN.md` for the milestone sequence. Both are **self-contained** — no external repo is needed to work from them. --- ## Directory Structure ``` src/ ├── core/ # Portable spec engine (no browser/React/Monaco) ├── app/ │ ├── components/ # React UI (CSS Modules co-located) │ ├── stores/ # Zustand stores │ ├── services/ # Business logic │ └── infrastructure/ # IndexedDB, localStorage, URL hash adapters styles/ # Global CSS (tokens, base) docs/ ├── spec/ # Authoritative behavioral specification (00–10) — the WHAT ├── architecture/ # Architecture playbook (00–08) — the HOW (self-contained) └── IMPLEMENTATION-PLAN.md ``` --- ## Development ```bash npm run dev # Dev server npm run build # Typecheck + production build (+ PWA) npm run typecheck # tsc --noEmit npm test # Vitest (run once) npm run test:watch # Vitest watch npm run format # Prettier ``` ### AI Developer Protocol - **No git on your own initiative** — don't `add`/`commit`/`push` unless explicitly invited. - **Verify** — run `npm run typecheck` and `npm test` after changes. - **Spec is the contract** — when in doubt, read `docs/spec/`. If the spec is wrong or silent, raise it; change the spec deliberately rather than drifting from it. - **Core-first** — for each feature, build the pure `src/core/` logic with tests before UI. ### Project skills Invoke with `/` (defined in `.claude/skills/`): - **`/alignment`** — review uncommitted/staged changes for quality, test coverage, and alignment with `docs/spec/` + `docs/architecture/`. Fixes issues directly and leaves `// TODO:` breadcrumbs at code sites for out-of-scope observations. - **`/doc-update`** — capture session-discovered knowledge gaps into the right doc layer (`docs/spec/` for behavior, `docs/architecture/` for patterns). - **`/release`** — bump version, update the changelog, prepare a git tag. ### Versioning Simplified semver `0.x.y` (pre-1.0): minor for features/behavior, patch for fixes. Single source of truth is `version` in `package.json`, injected as `__APP_VERSION__`. ### Testing Philosophy High coverage on `src/core/` (parsing, detection, profiling, reference resolution, fit transforms, import normalization). Lighter on components. Extract testable logic out of components into core/stores where practical.