FastLED
FastLED/FastLED/CLAUDE.md
[!IMPORTANT] Routine PR and master CI runs the explicit native/Python smoke inventories in ci/native_ci.py and skips the board matrix. Use ci-full for complete native, Python, example, and board validation before platform-sensitive merges; hosted Intel and Apple Silicon macOS run only with ci-full or release validation. Before choosing a narrower board or test label, run bash ci-labels list --json and use an emitted name. See CI modes. A version bump on master is not evidence that full CI passed. Dispatch the…
- Commits and pushes
What's in it
- FastLED AI Agent Guidelines
- Read the Right File for Your Task
- Key Commands
- Core Rules (ALL AGENTS)
- Git and Code Publishing
- Hook Error Policy
- Test Failure Debug Policy
- Error Fixing Policy
- Examples Policy
- Command Execution
- USB VID/PID identities live in FastLED/boards — ALWAYS
- Deployment (flash / upload) is fbuild's job — ALWAYS
- Code Standards
- Code Review Rule
- Memory Refresh Rule
- Workflow
- Core Principles
# FastLED AI Agent Guidelines > [!IMPORTANT] > Routine PR and `master` CI runs the explicit native/Python smoke inventories > in `ci/native_ci.py` and skips the board matrix. Use `ci-full` for complete > native, Python, example, and board validation before platform-sensitive > merges; hosted Intel and Apple > Silicon macOS run only with `ci-full` or release validation. Before choosing > a narrower board or test label, run `bash ci-labels list --json` and use an emitted > name. See [CI modes](docs/CI_MODES.md). A version bump on `master` is not > evidence that full CI passed. Dispatch the exact-SHA full sweep and run the > manual release evidence gate before tagging; see [CI modes](docs/CI_MODES.md). ## Read the Right File for Your Task **By what you're doing:** | Task | Read | |------|------| | Writing/editing C++ code | `agents/docs/cpp-standards.md` | | Verifying a peripheral exists on a chip before writing driver code | `agents/docs/peripheral-existence.md` (halt on phantom — do not fabricate missing `<Peripheral>_Type` in vendor headers) | | Adding or changing a board USB VID/PID | `agents/docs/usb-vid-pid-registry.md` (it lands in FastLED/boards first — never as a new literal in `ci/`) | | Defining a register map / accessing MCU peripherals | `agents/docs/register-maps.md` (use vendor CMSIS PAL — do not hand-roll shims) | | Looking up MCU datasheets / user manuals | Prefer https://github.com/FastLED/datasheets when available, then vendor primary documentation | | Creating an API wrapper type | `agents/docs/cpp-standards.md` → "API Object Pattern" | | Adding a global setting / configuration knob | `agents/docs/cpp-standards.md` → "Public Settings Pattern" (new setters go on `CFastLED`, not as bare `fl::set_*` free functions) | | Choosing a default pin for an example, or porting an example off a hardcoded pin | `agents/docs/cpp-standards.md` -> "Default Example Pins" (platform declares `FL_PIN_CLOCKLESS_1`; undeclared falls back to 3) | | Writing/editing Python code | `agents/docs/python-standards.md` | | Editing meson.build files | `agents/docs/build-system.md` | | Running tests, Docker, WASM, QEMU | `agents/docs/testing-commands.md` | | Test-Driven Development (TDD) | Use `/tdd` or `/tdd-implement` skills | | Editing `.fled` container docs or `src/fl/fled/` | `agents/docs/fled-format.md` | | Hardware autoresearch / `bash autoresearch` | `agents/docs/hardware-autoresearch.md` | | Hardware driver bring-up evidence or postmortems | `agents/docs/driver-bringup-postmortems.md` | | Debugging a C++ crash | `agents/docs/debugging.md` | | Investigating binary size / flash bloat | `agents/docs/binary-size-analysis.md` | | Checking or ingesting colour-profile artifacts | `agents/docs/color-profile-artifacts.md` (freshness findings are **status, not errors** — exempt from the fix-immediately policy; ingest only on explicit maintainer request) | | Changing the MP3 decoder, or profiling it | `agents/docs/mp3-decoder-performance.md` (one command measures a change: `bash mp3measure`. Edit `src/third_party/minimp3/minimp3_synth_fixed.h` for the synthesis back-end and `src/third_party/minimp3/minimp3.h` for the IMDCT and the shared arithmetic helpers; profile scalar with `-DMINIMP3_NO_SIMD`; minimp3-fixed is 1.13x Helix on an ESP32-C6, and host and device have disagreed in both direction and magnitude -- quote the device number) | | Creating a new C++ linter | `agents/docs/linter-architecture.md` | | Detailed command reference | `agents/docs/commands-reference.md` | | Workflow and task management | `agents/docs/workflow.md` | **By directory:** `src/`/`tests/` → `agents/docs/cpp-standards.md` | `src/fl/fled/` → `agents/docs/fled-format.md` | `ci/` → `agents/docs/python-standards.md`, `agents/ci.md` | `tests/` → `agents/tests.md` | `examples/` → `agents/examples.md` | `meson.build` → `agents/docs/build-system.md` ## Key Commands **CRITICAL: Always use bash wrapper scripts (NOT direct Python invocation):** - `bash test` / `bash test --cpp` / `bash test TestName` — Run tests - `bash lint` — Code formatting/linting - `bash compile wasm --examples Blink` — Compile example (WASM is default target) - `bash compile <platform> --examples Blink` — Compile for specific hardware (only when explicitly requested) - `bash autoresearch --parlio` — Live device testing (must specify driver) - `bash profile <function>` — Performance profiling - `bash bloat <board>` — Per-symbol flash/RAM bloat report (see `agents/docs/binary-size-analysis.md`) **NEVER use:** `uv run python test.py` — use `bash test` or `uv run test.py` **FORBIDDEN:** `--no-fingerprint` (use `bash test --clean`), the PlatformIO tool (banned repo-wide, lint enforced — fbuild is the only board build backend), bare `meson`/`ninja`/`clang++` See `agents/docs/commands-reference.md` for Docker, fbuild, WASM, profiling, example compilation, and override mechanism. See `agents/docs/build-system.md` for full command execution rules and forbidden patterns. ## Core Rules (ALL AGENTS) ### Git and Code Publishing - **Default mindset: finish the job.** Agents should not leave uncommitted changes dangling on `master`/`main`. If you made edits on `master`, the correct end-state is a feature branch + pushed PR — not a dirty working tree. - **Feature branches — full autonomy, no user consent required.** Agents may freely create branches, commit, push, and open PRs against any branch that is NOT `master`/`main`. Do this proactively when work is complete. - **`master`/`main` — extra caution required.** - NEVER commit directly to `master`/`main`. - NEVER push directly to `master`/`main`. - NEVER force-push to `master`/`main` (or any branch with an open PR others may be reviewing). - If changes exist on `master`, move them: `git checkout -b feat/<topic>` carries the working-tree changes to a feature branch, then commit + push + open a PR there. - **Recovery pattern for uncommitted changes on `master`:** 1. `git status` — confirm scope 2. `git checkout -b <descriptive-branch>` — changes follow to new branch 3. `git add <specific files>` + `git commit` (conventional commit format) 4. `git push -u origin <branch>` and `gh pr create` 5. `git status` again to confirm clean tree ### Hook Error Policy - **ALWAYS stop and fix Write/Edit hook errors immediately** before writing the next file - **IWYU errors may be deferred** when laying down multiple new files in a batch ### Test Failure Debug Policy - **When ANY test fails in quick mode, you MUST immediately re-run it in debug mode**: `bash test <TestName> --debug` - Debug mode enables ASAN/LSAN/UBSAN sanitizers that catch memory errors, undefined behavior, and leaks - Quick mode failures without debug re-run are INCOMPLETE — the root cause is often only visible with sanitizers - Do NOT attempt to fix the code based only on quick-mode output — always get debug output first ### Error Fixing Policy - **Fix ALL encountered errors immediately**, even pre-existing ones unrelated to your current task ### Examples Policy - **Keep the `examples/` tree minimal.** Do NOT create new one-off `.ino` sketches to try out functionality. - **Test new functionality in `examples/AutoResearch/AutoResearch.ino`** — that is the canonical scratch target for live/device testing. - A `PreToolUse` hook (`ci/hooks/protect_example_ino.py`) **blocks creation of any new `.ino` under `examples/`**. Editing an existing `.ino` is always allowed. - **Override (only when a genuinely new example is required):** prepend a comment containing the `FL_AGENT_ALLOW_NEW_EXAMPLE` directive to the file (e.g. `// FL_AGENT_ALLOW_NEW_EXAMPLE`), or launch with the `FL_AGENT_ALLOW_NEW_EXAMPLE=1` env var. ### Command Execution - **Always use bash wrapper scripts** (`bash test`, `bash compile`, `bash lint`, `bash autoresearch`) - **Stay in project root** — never `cd` to subdirectories - **Python scripts**: Always use `uv run python script.py` (never bare `python`) - **Platform compilation timeout**: 15 minutes minimum for platform builds - **Override**: `FL_AGENT_ALLOW_ALL_CMDS=1` prefix bypasses forbidden command checks - See `agents/docs/build-system.md` for full rules ### USB VID/PID identities live in FastLED/boards — ALWAYS - **Never introduce a board/device USB VID:PID into this repo as the place it first exists.** [FastLED/boards](https://github.com/FastLED/boards) is the source of truth; it publishes a zstd-compressed protobuf (`usb-vids.proto.zstd`) that fbuild ingests at build time and falls back to from its cache root. FastLED consumes it through `fbuild port scan` / `fbuild deploy`. - **Missing identity ⇒ fix the registry, then cascade.** Add it on the FastLED/boards data branch, let the `site.yml` workflow republish, cut an fbuild release, then move the `fbuild==X.Y.Z` pin in `pyproject.toml` and run `uv sync` to pick it up. `uv.lock` is gitignored here, so the pin is the only committed half of the cascade — but you must still relock/sync locally or you keep running the old wheel. - **The legacy tables are retired.** Runtime USB identities and environment-aware port selection come from FastLED/boards through fbuild. Test fixtures may use concrete literals; they must never become runtime defaults. - Full rule, pipeline diagram, and cascade procedure: `agents/docs/usb-vid-pid-registry.md`. fbuild mirrors it in its own `CLAUDE.md` → "USB VID/PID source of truth" and `docs/usb-vidpid-audit.md`. ### Deployment (flash / upload) is fbuild's job — ALWAYS - **Never invoke flash tools directly from FastLED code.** No `pyocd`, `lpc21isp`, `esptool`, `avrdude`, `bossac`, `stm32flash`, `openocd load`, `dfu-util`, `teensy_loader_cli`, `JLinkExe`, or equivalents anywhere under `ci/`, `tests/`, `examples/`, or `src/`. - **The only permitted deploy entrypoint is `fbuild deploy`.** `bash autoresearch` runs `fbuild build` + `fbuild deploy` and then opens the VCOM — it does not flash. - If fbuild is missing a deploy backend for your target: **file the gap at https://github.com/FastLED/fbuild/issues and let the caller fail loudly.** Do not add a "temporary" direct flash call — those become permanent and skip the hardening (timeout guards, probe preflight, ISP fallback, VCOM unwedge) the fbuild path enforces. - Full rule and rationale: `agents/docs/build-system.md` → "Deployment (flash / upload) is fbuild's job — ALWAYS". History: LPC-Link2 CMSIS-DAP v1.0.7 firmware hung pyocd's Windows HID for 8 minutes per invocation on 2026-07-01 — a fbuild-owned platform-integration problem that was leaking into every FastLED script. The nxplpc deployer (lpc21isp UART ISP path) shipped in FastLED/fbuild#595 (refined in #923, #928); autoresearch now delegates to it via `fbuild deploy`. ### Code Standards - **C++**: See `agents/docs/cpp-standards.md` (span convention, DMA patterns, naming, macros) - **C++ public settings**: New global setters MUST go on `CFastLED` (`FastLED.setX()`), not as bare `fl::set_*` free functions — see `agents/docs/cpp-standards.md` → "Public Settings Pattern" - **C++ pointer lifetime**: Long-lived pointers (stored, returned from an accessor, or held across async/reconfiguration) MUST be `fl::shared_ptr`; a raw pointer is OK only in sync code where the target provably outlives the use. Compile it out on small-memory tiers (`!FL_PLATFORM_HAS_LARGE_MEMORY`) — see `agents/docs/cpp-standards.md` → "Long-Lived Pointers Are `fl::shared_ptr`" - **JavaScript**: Run `bash lint --js` after modifying JS files ### Code Review Rule **ALL AGENTS: Run `/code-review` after making code changes.** Before opening a feature PR, show its real production path (in-repo or a named downstream integration) and end-to-end evidence for the claimed behavior. Do not add a broad, default-off prerequisite API for a niche feature with only fake users and call the issue done; justify why it must land separately or choose a smaller fix or an explicit limitation. Reviewers apply this value gate even when lint and unit tests pass (see `.claude/skills/code-review/review-rules.md`). ### Memory Refresh Rule **ALL AGENTS: Read the relevant agents doc before concluding work.** ## Workflow See `agents/docs/workflow.md` for full workflow orchestration and task management. - **Plan first** for non-trivial tasks (3+ steps) — use plan mode - **Subagents** for research, exploration, and parallel analysis - **Self-improvement**: Update `agents/tasks/lessons.md` after corrections - **Verify before done** — prove it works with tests, logs, demonstrations - **Test simplicity**: Keep tests simple, avoid mocks. See `agents/tests.md` - **On-device / hardware tests go through `examples/AutoResearch/AutoResearch.ino`** — prefer reusing or augmenting its existing test harness (e.g. `AutoResearchSimd.h`, run via `bash autoresearch <board> --simd`/`--parlio`/etc.) rather than creating a new `.ino` in `examples/`. New example sketches bloat the CI compile matrix; AutoResearch already has the RPC/serial plumbing. - **TDD for features/bugs**: Use `/tdd` (guided cycle) or `/tdd-implement` (full feature). Write tests FIRST. - **Orchestrated sub-agents skip `bash test`** — when a sub-agent is one step of a multi-step plan, the orchestrator runs `bash test --cpp` once at the end (the `Stop` hook covers this for free). Per-step sub-agents run `bash lint` only. See `agents/tests.md` → "Orchestrated Sub-Agent Carve-Out". The orchestrator must say so explicitly in the dispatch prompt. ## Core Principles - **Simplicity First**: Make every change as simple as possible. Minimal code impact. - **No Laziness**: Find root causes. No temporary fixes. Senior developer standards. - **Minimal Impact**: Changes should only touch what's necessary. Avoid introducing bugs.
More agent context in FastLED/FastLED
25 other files this repository gives its agents.
Skill
- address-reviews.claude/skills/address-reviews/SKILL.md
- ci-fix.claude/skills/ci-fix/SKILL.md
- code-review-asm-xtensa.claude/skills/code-review-asm-xtensa/SKILL.md
- code-review-riscv.claude/skills/code-review-riscv/SKILL.md
- code-review.claude/skills/code-review/SKILL.md
- driver-review.claude/skills/driver-review/SKILL.md
- embedded-debug.claude/skills/embedded-debug/SKILL.md
- esp32-arch-review.claude/skills/esp32-arch-review/SKILL.md
- esp32-log-triage.claude/skills/esp32-log-triage/SKILL.md
- esp32-test-plan.claude/skills/esp32-test-plan/SKILL.md
- expert-rmt5.claude/skills/expert-rmt5/SKILL.md
- feature-contract.claude/skills/feature-contract/SKILL.md
- fix-board.claude/skills/fix-board/SKILL.md
- fix-int.claude/skills/fix-int/SKILL.md
- gh-debug.claude/skills/gh-debug/SKILL.md
- gh-healthcheck.claude/skills/gh-healthcheck/SKILL.md
- git-historian.claude/skills/git-historian/SKILL.md
- lint.claude/skills/lint/SKILL.md
- memory-audit.claude/skills/memory-audit/SKILL.md
- new-cpp-lint.claude/skills/new-cpp-lint/SKILL.md
- platform-port.claude/skills/platform-port/SKILL.md
- tdd-implement.claude/skills/tdd-implement/SKILL.md
- tdd.claude/skills/tdd/SKILL.md
- test.claude/skills/test/SKILL.md
- timing-analysis.claude/skills/timing-analysis/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

