diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d31d0b6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,31 @@ +name: CI + +on: + push: + branches: + - main + - master + - develop + pull_request: + +jobs: + lint-and-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm install + + - name: Run lint + run: npm run lint + + - name: Run tests + run: npm test diff --git a/AGENTS.md b/AGENTS.md index e505d33..5a4180b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,35 +1,57 @@ # AGENTS ## Purpose -This document orients automation and human collaborators to the structure, conventions, and workflows in this repository. +Reference guide for automation and human contributors. Use it to understand the structure, contracts, and preferred workflows before touching code. + +## Quick Start +- Serve the repo with `npm run dev` (wraps `http-server`) or any static file server. Both the root `index.html` and `workout-time/index.html` expect a browser environment. +- The site ships as native ES modules. Keep files co-located and avoid bundler-only features (no JSX, CommonJS, or TypeScript transforms). +- Run automated checks with the provided npm scripts: `npm test`, `npm run lint`, `npm run format`. ## Repository Map -- `index.html` — public-facing exercise library landing page. -- `styles.css` — shared styling for the public site. -- `exercise_dump.json` — exported exercise metadata referenced by the app. -- `js/` — modular ES modules that power the exercise plan builder (`builder.js`, `context.js`, `library.js`, etc.). - - `plan-storage.js` centralises workout plan persistence. Interact with localStorage through the helpers exposed here rather than reimplementing storage access. -- `workout-time/` — standalone Vitruvian workout control UI (`index.html`, `app.js`, supporting assets). -- `local-tests/` — lightweight Node-based test harness (currently `builder.test.js`). +- `index.html`, `styles.css` — public exercise library landing page and shared styling. +- `exercise_dump.json` — canonical exercise dataset. Schema changes must stay compatible with search, filters, storage, and workout-time consumers. +- `js/` — modular frontend for the library and builder. + - `main.js` — bootstraps data loading, state wiring, and tab switching. + - `context.js` — centralised state/DOM registry; route mutations through its helpers. + - `constants.js` — shared enums and configuration (storage keys, modes, limits). + - `library.js` — filter orchestration, search invocation, card rendering. + - `search.js` — tokenisation, fuzzy scoring, and in-memory indices. + - `builder.js` — workout builder UI (drag/drop, set editing, export pipelines). + - `grouping.js` — grouping helpers reused by the builder and library views. + - `plan-storage.js` — local plan index management. Always use these helpers for persisted plans. + - `storage.js` — broader persistence (builder snapshot, plan metadata, share-link parsing). + - `utils.js`, `muscles.js` — shared helpers and canonical muscle metadata. +- `tests/` — Node test runner suites (`node --test`) covering builder flows, search scoring, storage sync, and regression cases. +- `workout-time/` — Vitruvian workout control UI. + - `app.js` — orchestrates device lifecycle, plan execution, and UI state. + - `plan-runner.js` — timeline building, rest timers, skip/rewind logic; loaded before `app.js`. + - `device.js`, `protocol.js`, `chart.js`, `modes.js`, `dropbox.js` — transport, telemetry, charting, and cloud sync support. +- `scripts/` — mock CLIs for lint/format/http-server to support sandboxed automation. +- Tooling: `package.json`, `eslint.config.js`, `prettier.config.js` define commands and formatting conventions. ## Key Flows -- The builder UI is data-driven: `js/context.js` initializes shared state; `js/builder.js` consumes that state to serialize plans. Keep mutations centralized in `context.js` helpers. -- The workout control in `workout-time/app.js` communicates with hardware over WebSocket. Update connection logic cautiously; mirror any protocol changes in both UI and device code. -- Static assets are served as-is. No bundler is configured, so prefer vanilla JS modules and relative imports. -- For storage interactions in the plan builder, rely on `plan-storage.js` helpers. They normalise plan names, manage the plan index, and guard against localStorage failures. Avoid duplicating that logic elsewhere to keep UI state and persistence consistent. +- **Data bootstrapping** — `main.js` fetches `exercise_dump.json`, normalises it through `context.js`, then requests initial renders from `library.js` and `builder.js`. +- **Builder state** — All mutations route through `context.js` helpers to keep `state.builder` and DOM references consistent. `builder.js` emits serialised payloads via `storage.js` and `plan-storage.js`. +- **Persistence** — `plan-storage.js` governs plan naming, index updates, and storage error handling. Use it instead of direct `localStorage` access. +- **Search** — `search.js` maintains token indices; `library.js` supplies filters and delegates to search for scoring. Changing tokens or weightings requires updates to both modules. +- **Workout-Time device loop** — `workout-time/app.js` manages WebSocket connections, device telemetry, and integrates `plan-runner.js` for execution. Mirror protocol changes across `protocol.js` and any firmware. -## Development Tips -- Use `npx http-server .` or similar to preview pages locally. Both the root `index.html` and `workout-time/index.html` expect to run in a browser environment. -- Run `node local-tests/builder.test.js` to sanity-check plan serialization and rebuilding logic after modifying builder modules. -- Maintain accessibility: new UI components should include keyboard support and ARIA labelling consistent with existing markup. -- After touching persistence or plan-index flows, update `plan-storage.js` first and adapt consumers (currently `js/main.js`) to avoid drift between cached plan state and saved plans. +## Development Workflow +- Add or mutate state through `context.js`. Avoid duplicating DOM queries outside of its registry. +- Maintain accessibility: mirror existing ARIA usage and keyboard interactions when extending UI. +- When touching persistence or plan serialisation, update Node tests (`tests/plan-storage.test.js`, `tests/builder-load-plan.test.js`, `tests/builder-plan-items.test.js`) to capture new expectations. +- Target evergreen browsers. If introducing less supported APIs, ship polyfills inline with usage. +- Styles live in `styles.css` and component-scoped `