Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/REPOSITORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ A map for people. (AI coding agents get the same map with more rules in [`../AGE
| `firmware/` | The ESP32-S3 firmware. `patternflow/` is the sketch: `patternflow.ino`, `config.h` (pins, brightness, limits, calibration), `net_config.h` (Wi-Fi, OTA, update defaults), `src/` (the engine: HUB75 driver, encoders, canvas, colour, noise, Wi-Fi, web console — the **core**, compiled unchanged into every published firmware), `features/` (everything optional: OSC, audio, the microphone, MQTT, MIDI, shows, weather, clock, BLE — attached through hooks the core exposes), `presets/` (the curated patterns), `abi/` (the frozen contract a `.pfm` module is compiled against), `console/` (the device's web pages as plain HTML). `bundles/` names the compositions — the shelf editions `audio` and `performance`, plus `clock` and `midi`, which CI keeps compiling but the shelf does not carry — and holds `build.sh` and `shelf.sh`. `toolchain/` is the repo-level scripts: build a module, make the Basics pack, and the `check_*.py` that CI runs. `modules/` is the module toolchain's working folder, not a place patterns are contributed to. `encoder_test/` is a standalone sketch for checking the four encoders, and `CUSTOM_PATTERNS.md` the hands-on pattern route | [`firmware/README.md`](../firmware/README.md) for building; [`EDITIONS.md`](EDITIONS.md) before touching anything |
| `hardware/` | `pcb/` (KiCad source, Gerbers per revision, schematic PDF), `case/` (STLs by printer bed size, knob plates, the Blender source, legacy v2 cases, the old v1/v2 laser-cut drawings in `legacy_lasercut/`, and `remixes/` — enclosures other people designed and built, one folder each), `bom/` (the CSV that is the BOM source of truth) | [`hardware/README.md`](../hardware/README.md) |
| `web/` | The Next.js site at patternflow.work: landing page, the interactive guide (`/guide`, with `/guide/build`, `/guide/play`, `/guide/make` and `/guide/audio`), Live Editor, Pattern Lab, the community (only on the community host), the browser flasher (the **Flash Patternflow** button on the Pattern tab and in the Play guide; the images it installs are `public/flash/`), edition shelf, feature catalogue, device update handoff, journal, roadmap. The JS presets in `src/lib/presets/` are the source of truth for the firmware's preset headers. The breadboard build guide is a React page here, `src/app/build/breadboard/` | [`web/README.md`](../web/README.md), then [`web/ARCHITECTURE.md`](../web/ARCHITECTURE.md) |
| `shared/` | `constants.json`, the values the firmware and the site both carry: the panel geometries, the knob count, the encoder's 24 detents a turn, the bus maximum and the button timings. `npm run gen:shared` in `web/` writes `firmware/patternflow/src/core_shared.h` and `web/src/lib/shared/constants.ts` from it. Neither is edited by hand, and `check:shared` fails while either is stale. The folder exists because the lab counted 20 detents a turn, against the encoder's 24, until 31 July 2026 | [`constants.json`](../shared/constants.json) |
| `docs/` | Contracts other software is built against, how the firmware is put together, walk-throughs, the audio guide (`AUDIO_GUIDE.md`), the assembly map, the legacy v2.x build guide (`legacy/`), the writing voice (`voice.md` and `voice-banned.txt`), project records (`releases/`, one file per release) and media | [`README.md`](README.md) |
| `tools/` | Clients Patternflow ships that run on their own: the audio-react browser extension (also the authoring source of the device's `/audio-in` page), the Android capture app, an RTP-MIDI probe. Also `case-models/`, the scripts that make the /build page's 3D model of each case, the official one and every remix on its case switch | [`tools/README.md`](../tools/README.md) |
| `integrations/` | Bridges that run inside or beside someone else's software (Ableton / Max for Live today) and talk to the panel only through the contracts in `docs/` | [`integrations/README.md`](../integrations/README.md) |
Expand Down
11 changes: 7 additions & 4 deletions firmware/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,13 @@ Library Manager:
> not the plain device.

> The HUB75 library is also **vendored** under `patternflow/src/hub75/`, and that
> copy is the one that compiles — it carries Patternflow's additions
> (`resumeDMAoutput()` for sleep, the brightness hook the power clamp uses). The
> installed/cloned copy only needs to satisfy headers, so its exact version does
> not matter. See `src/hub75/VENDORED.md`.
> copy is the one that compiles. [`UPSTREAM.md`](patternflow/src/hub75/UPSTREAM.md)
> there names the upstream tag and commit it was copied from, and each upstream
> commit taken since. Every line Patternflow changed is in `patternflow.patch`
> beside it, and [`VENDORED.md`](patternflow/src/hub75/VENDORED.md) says why.
> After an edit under `src/hub75/`, rebuild the patch with the command in
> `UPSTREAM.md` instead of editing it. The installed/cloned copy only needs to
> satisfy headers, so its exact version does not matter.

OSC uses the ESP32 Arduino core's built-in `WiFi` and `WiFiUdp` libraries, so it does not require an extra OSC library. The MQTT client (`pubsubclient`) and the HUB75 driver are vendored under `patternflow/src/`.

Expand Down
4 changes: 2 additions & 2 deletions web/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Cross-component landing state (active tab, virtual knob values, bloom toggle, th
Mirrors the firmware; the same JS runs in the browser, in the community's sandbox iframe and in the lab's worker.

- **`src/lib/presets/`** — JS pattern sources, one file per pattern. **Source of truth** for the firmware preset `.h` files (`firmware/patternflow/presets/`; the web has more presets than the firmware — the cut list is in `firmware/patternflow/README.md`). `_TEMPLATE.ts` is the skeleton; `index.ts` the registry.
- **`src/lib/pattern/harness.ts`** — runs pattern JS on a 128×64 virtual matrix with 4 virtual encoders (24 detents/turn), matching device semantics (`knobDeltas`, `btnPressed`/`btnHeld`); also the OKLab/OKLCH colour ramp math and the LUT builders. `public/pattern-sandbox.html` is **built from it** — `scripts/build-sandbox.ts` bundles `src/sandbox/sandbox.ts` (the canvas, the live loop, the postMessage protocol) with the runtime it imports, and `check:sandbox-sync` fails when the committed page is not that build. It was a hand-kept ES5 port until 3.9.4, and it drifted (`next.config.ts` records one such bug; another was 20 detents a turn against the lab's 24).
- **`src/lib/pattern/harness.ts`** — runs pattern JS on a 128×64 virtual matrix with 4 virtual encoders (24 detents/turn), matching device semantics (`knobDeltas`, `btnPressed`/`btnHeld`); also the OKLab/OKLCH colour ramp math and the LUT builders. `public/pattern-sandbox.html` is **built from it** — `scripts/build-sandbox.ts` bundles `src/sandbox/sandbox.ts` (the canvas, the live loop, the postMessage protocol) with the runtime it imports, and `check:sandbox-sync` fails when the committed page is not that build. It was a hand-kept ES5 port until 3.9.4, and it drifted (`next.config.ts` records one such bug; another was 20 detents a turn against the lab's 24). The 24 now comes from `src/lib/shared/constants.ts`, and so do the panel size and the knob count. `npm run gen:shared` writes that file from `shared/constants.json` at the repository root, the same source as the firmware's `core_shared.h`.
- **Annotations** — a pattern's frame, ramp, knob ranges and layer stack travel *inside its code* as one-line comments so they survive every copy: `@matrix` (`src/lib/pattern/matrix.ts`), `@ramp` (`src/lib/pattern/ramp.ts`), `@knobs` (`src/lib/pattern/knobs.ts` — the lab's knob state in `src/lib/lab/annotations.ts` and the community's card reader in `src/lib/community/knobs.ts` both build on it), `@stack` (`src/lib/lab/stackShare.ts`).
- **`src/lib/pattern/controls.ts`** — knob-scale constants shared with the firmware.
- **`src/lib/pattern/share.ts`** — licence header + attribution footer, injected at export time only.
Expand All @@ -77,7 +77,7 @@ A layered, dockable workspace: nine panels over a layer-stack project. A panel i

Each panel owns its stylesheet (`panels/<Panel>.module.css`); `PatternLab.module.css` keeps only what two or more files draw with, and `LabPanels.module.css` the dock chrome. The lab reaches the community through exactly one file, `community.ts` (the publish and send modals, the configured switches, the handoff, the `.pfs` reader) — ESLint refuses any other import of `@/components/community` or `@/lib/community` from under the lab.

Exports flatten the visible stack to one standalone pattern (`flatten.ts`); `hExport.ts` writes the C++ header; `HardwareModal.tsx` sends it to the build service or the panel. Persistence is `localStorage`: the project (`serialize.ts`, `patternflow_lab_project_v2`), the dock layout, a ring of parked sessions (`sessions.ts`), capture settings and shaders under their own keys, and the legacy v1 draft/gallery keys read by `src/lib/lab/legacyDraft.ts`.
Exports flatten the visible stack to one standalone pattern (`flatten.ts`); `hExport.ts` writes the C++ header; `HardwareModal.tsx` sends it to the build service or the panel. Persistence is `localStorage`: the project (`serialize.ts`, `patternflow_lab_project_v2`), the dock layout, a ring of parked sessions (`sessions.ts`), capture settings and shaders under their own keys, the generated gallery (`patternflow_lab_gallery_v1`, still the live key, read and written by `src/lib/lab/legacyDraft.ts`), and the draft and ramp keys the lab stopped writing at Pattern Lab v2 on 27 July 2026, which `migrateLegacyDraft` in `serialize.ts` lifts into a project when none restores.

## Community (`src/lib/community/` + `src/components/community/`)

Expand Down
Loading