Skip to content

Docs v2: two-surface module docs, flatten catalog folders, DriverBase/LayoutBase split#38

Merged
ewowi merged 5 commits into
mainfrom
next-iteration
Jul 6, 2026
Merged

Docs v2: two-surface module docs, flatten catalog folders, DriverBase/LayoutBase split#38
ewowi merged 5 commits into
mainfrom
next-iteration

Conversation

@ewowi

@ewowi ewowi commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Completes the docs-v2 two-surface documentation migration and splits the driver/layout base classes into their own headers. Almost entirely docs + tooling; the one structural code change (DriverBase/LayoutBase split) is comment/include-only in effect (no logic, no hot-path change — KPI unchanged at 1416µs, flash unchanged).

What's in the branch (4 commits)

Docs v2 — two-surface module docs (the finish line). Every module now has exactly two surfaces: a hand-written summary/catalog page (end-user) and a technical page generated from the .h /// comments (developer). The ~30 standalone per-module .md files are gone — their content lives in the .h /// or a summary row, never both.

  • Deleted 22 module archive .md pages (core + light); their last present-tense content migrated into the class/member ///, forward-looking bits into docs/backlog/.
  • Embedded module card screenshots in the generated pages via a @card directive; trimmed inherited-member bloat from the moxygen template.
  • Promoted the web-UI system spec to a live page (docs/moonmodules/core/ui.md), de-duplicated against architecture.md § Web UI + HttpServerModule.
  • Flattened the single-file catalog folders (light/effects/effects.mdlight/effects.md, etc.) — the committed folder-structure decision's target layout, groundwork for future per-library page splits. ~230 relative links rewritten.
  • Consolidated 8 docs-overhaul plans into one shipped record; marked 7 shipped feature plans (shipped); pruned fully-shipped backlog studies.

DriverBase / LayoutBase split. DriverBase and LayoutBase move out of Drivers.h / Layouts.h into their own headers, symmetric with the existing EffectBase / ModifierBase pattern — so each now renders its own technical page + supporting card. Driver/layout subclasses include the lighter base directly (like effects include EffectBase); main.cpp + container-using tests gained explicit container includes. No logic change.

Tooling / drift guards.

  • New check_specs.py gate validating every main.cpp registerType docPath resolves to a real page + #anchor (catches the docs-rename-breaks-UI-help-link drift class).
  • Signature name-highlight on the generated pages (accent name, muted type/args); coloured headings site-wide.
  • Retired the temporary migration cross-check banner (all archives now deleted).

Reviews processed

  • 🐇 CodeRabbit (on 869a857): the driver docPaths pointing at deleted pages — already fixed to drivers.md#anchor; the web-installer/README + E131Packet stale links — fixed; the CI gap (no docPath validation) — fixed with the new gate. The AudioModule platform/platform.h include finding — rejected (that header is the platform-abstraction seam core depends on, 18 core files include it).
  • 👾 Reviewer agent (whole-branch, pre-merge): architecturally clean (net −836 lines — the split is a verbatim text move symmetric with EffectBase/ModifierBase; the duplication model holds; bespoke doc-tooling bits each carry a stated reason). 8 findings, all documentation/process drift (no architecture blockers): 7 one-to-few-line fixes applied on the branch (stale nested-folder refs in coding-standards.md + CLAUDE.md → flat paths; dead archive-migration narration removed; drivers.md window-controls link → DriverBase; app.js + workflow example paths; 4 absence-narration comments → present-tense; FireEffect's detached /// block merged so its description reaches the page). Finding F2 (plan consolidation vs "plans are kept") resolved by a PO-approved clause allowing a shipped multi-phase effort's per-phase plans to consolidate into one record. F8 (a backlog item referenced from a .h) accepted as a watch-item (precedent in Palette.h).

Gates

Commit gates passed on every commit (3 with full KPI, the last with a documented comment-only ESP32/KPI skip). Pre-merge: docs build 0 link warnings, check_specs clean (incl. the new docPath gate), host tests green, no new module/control/endpoint (doc-sync inherently satisfied), no tick-path logic change (no perf snapshot needed). Lessons carried to decisions.md.

…omation guide

Restructures the core-services docs (renamed the summary page, fixed broken help-link anchors, split overflowing cards into detail sections), adds a Home automation use-case guide (Homebridge over MQTT + driving Hue lights), and populates the Preview column of the core/driver/container catalog cards with fresh UI screenshots. Also fixes real bugs in the screenshot tool so child and peripheral module cards capture correctly.

KPI: 16384lights | PC:666KB | tick:168/92/118/15/2/281/59/17/21/161/116/18/1/37us(FPS:5952/10869/8474/66666/500000/3558/16949/58823/47619/6211/8620/55555/1000000/27027) | ESP32:1369KB | tick:2206us(FPS:453) | heap:158KB

Core
- main.cpp: repointed the core registerType docPaths — every user-facing module now links to core/services/services.md#anchor (was the stale, unpublished core/<Name>.md); FilesystemModule points at core/supporting/supporting.md#filesystem (it's a non-UI engine, moved out of the services table). MqttModule.h + app.js cross-refs follow the rename. These are string-literal/comment changes only — no logic.

Docs
- Renamed docs/moonmodules/core/ui/ui.md → core/services/services.md ("Core services", matching the folder-named-summary-page convention and pairing with core/supporting/). Added explicit <a id="..."> anchors before each ### card so the ? help-link #anchors actually resolve on the rendered catalog page (they were silently broken — the table transform consumes the ### headings).
- Split the overflowing MQTT / File Manager / IR cards: moved topics table, Homebridge config, tree/toolbar/editor behaviour, and action/status prose into ## <Name> — details sections (linked via ⌄ details), leaving each card a short description + its real controls. Moved Filesystem into supporting.md. Added the File Manager `file browser` surface as a control, and the Drivers `on` (master power) + `brightness` controls.
- New use case: docs/usecases/home-automation.md (+ "Use cases" nav entry) — Homebridge over MQTT (install a broker + Homebridge per-OS: Pi / macOS / Windows, then the host-neutral config), driving Hue lights as effect pixels (recommend a 1×N grid), and an "Other platforms" section for Home Assistant etc.
- Populated the Preview column of every core-services, driver, and container card with a UI screenshot (services ×10, drivers LED-output, containers Layer/Layers/Layouts/Drivers). Replaced the IR photo (.jpeg) with an actual card screenshot. Backlog: generic control + state MQTT topics (the automation escape hatch).

Scripts / MoonDeck
- screenshot_modules.py: fixed find_core_module_names to RECURSE the tree (Network's children Mqtt/Devices/Improv were invisible to a flat scan → "not in state"); added CORE_NAV_ROOT so a child module captures as its OWN card (nav to parent, screenshot the child) instead of nested in the parent; extended CORE_MODULES with the new modules. Peripheral cards (Audio/I2C/IR/Improv/RmtLed) captured against real ESP32 boards, the rest against a desktop server.

Light domain
- deviceModels.json: the Shelly model runs RainbowEffect (was SolidEffect).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MoonModules

Copy link
Copy Markdown
Owner

@coderabbitai, please hook in into this pr

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

@MoonModules Got it — I'll hook into this PR and run a review now.

(⌐■_■)ノ

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 25fdad6b-3406-4080-891f-e27df35a959a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR migrates documentation references from the retired core/ui/ui.md path to the new core/services/services.md page across README, docs, and code comments, reorganizes services.md into anchored sections with new "details" subsections, adds a Filesystem docs section, adds illustrative images to light module docs, adds a new home-automation use case page with MQTT/Hue/Homebridge guidance, updates mkdocs nav and docs tooling (catalog pages, screenshot module discovery/routing), and changes a device model's effect from Solid to Rainbow.

Changes

Core Services Documentation Restructure

Layer / File(s) Summary
Reorganize services.md with anchors and details sections
docs/moonmodules/core/services/services.md, docs/moonmodules/core/supporting/supporting.md
services.md is renamed conceptually from "Core UI modules" to "Core services," gains HTML anchors and module control images per section, and adds new MQTT/File Manager/IR "details" subsections; supporting.md gains a new Filesystem persistence section.
Update documentation links across pages and code comments
README.md, docs/architecture.md, docs/backlog/README.md, docs/backlog/backlog-core.md, docs/gettingstarted.md, mkdocs.yml, src/core/MqttModule.h, src/main.cpp, src/ui/app.js
All references to core/ui/ui.md are retargeted to core/services/services.md (with FilesystemModule pointing to core/supporting/supporting.md#filesystem), and a new MQTT generic-API backlog item is added.
Update docs tooling for catalog and screenshots
moondeck/docs/mkdocs_hooks.py, moondeck/docs/screenshot_modules.py
Catalog page target swapped to services.md with column label change to "Controls"; screenshot script expands CORE_MODULES/CORE_NAV_ROOT, recurses /api/state for module discovery, and routes child modules through parent nav roots.
Add illustrative images to light module docs
docs/moonmodules/light/drivers/drivers.md, docs/moonmodules/light/supporting/supporting.md
New screenshots are added for Layer, Layers, Layouts, and Drivers sections, plus expanded documentation of on and brightness controls.

Estimated code review effort: 2 (Simple) | ~12 minutes

Home Automation Use Case

Layer / File(s) Summary
Add home-automation use case page and nav entry
docs/usecases/home-automation.md, mkdocs.yml
New page documents MQTT/Homebridge/Apple Home integration, driving Hue lights from device layers, other-platform guidance, and troubleshooting; linked under a new "Use cases" nav group.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • MoonModules/projectMM#33: Both PRs update runtime help-doc path references from core/ui/ui.md toward the services docs and touch related MkDocs site linking/build wiring.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is specific and broadly matches the docs/navigation overhaul and module documentation refresh in this PR.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch next-iteration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/backlog/backlog-core.md`:
- Line 392: The visible link label in the File Manager description is stale and
still advertises the retired path, so update the markdown reference in the
backlog docs to match the moved target. Adjust the link text in the sentence
containing the File Manager description so it names services.md instead of
ui.md, keeping the existing destination consistent with the new location.

In `@docs/gettingstarted.md`:
- Around line 186-195: The module references in gettingstarted.md are pointing
to the generic services.md page instead of the specific section anchors for
SystemModule, AudioModule, FirmwareUpdateModule, and the related Network/Devices
entries. Update the markdown links in the affected getting-started sections so
each reference uses the matching anchor in
moonmodules/core/services/services.md, keeping the existing symbol names as the
guide for the correct target sections.

In `@docs/moonmodules/core/services/services.md`:
- Around line 179-200: The Homebridge mqttthing example in services.md still
includes separate brightness topic mappings even though setHSV/getHSV already
cover brightness through the combined HSV value. Update the Homebridge JSON
example to remove the getBrightness and setBrightness entries from the topics
object, keeping only the on and HSV topic mappings, so the example matches the
actual supported configuration.

In `@docs/usecases/home-automation.md`:
- Around line 12-15: The navigation entries in the home automation guide use
roadmap-style wording that mentions future additions instead of only current
content. Update the table-of-contents links in the home automation markdown to
describe the existing sections in present tense, and adjust the related section
text in the guide (including the “Other platforms” area) to remove phrases like
“as they land” or “to be added.” Keep the focus on what the Homebridge, Drive
Hue lights, and Other platforms walkthroughs currently cover.
- Around line 65-71: Add an explicit LAN-facing Mosquitto example in the
home-automation docs because `mosquitto -v` by itself only binds to loopback on
Mosquitto 2.x. Update the broker example to use an explicit `listener 1883`
configuration (or clearly state that the current `mosquitto` command is
localhost-only), and make sure the surrounding text in the broker section
matches the behavior described.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: aaa215f8-4b9b-4603-9cfd-057d10d0dc65

📥 Commits

Reviewing files that changed from the base of the PR and between 5f4c67e and 208cfa5.

⛔ Files ignored due to path filters (36)
  • docs/assets/core/AudioModule.png is excluded by !**/*.png
  • docs/assets/core/DevicesModule.png is excluded by !**/*.png
  • docs/assets/core/FileManagerModule.png is excluded by !**/*.png
  • docs/assets/core/FirmwareUpdateModule.png is excluded by !**/*.png
  • docs/assets/core/I2cScanModule.png is excluded by !**/*.png
  • docs/assets/core/ImprovProvisioningModule.png is excluded by !**/*.png
  • docs/assets/core/IrModule.jpeg is excluded by !**/*.jpeg
  • docs/assets/core/IrModule.png is excluded by !**/*.png
  • docs/assets/core/MqttModule.png is excluded by !**/*.png
  • docs/assets/core/NetworkModule.png is excluded by !**/*.png
  • docs/assets/core/SystemModule.png is excluded by !**/*.png
  • docs/assets/light/Drivers.png is excluded by !**/*.png
  • docs/assets/light/Layer.png is excluded by !**/*.png
  • docs/assets/light/Layers.png is excluded by !**/*.png
  • docs/assets/light/Layouts.png is excluded by !**/*.png
  • docs/assets/light/drivers/NetworkSendDriver.png is excluded by !**/*.png
  • docs/assets/light/drivers/PreviewDriver.png is excluded by !**/*.png
  • docs/assets/light/drivers/RmtLedDriver.png is excluded by !**/*.png
  • docs/assets/light/effects/FireEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/LavaLampEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/LinesEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/MetaballsEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/NoiseEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/ParticlesEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/PlasmaEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/RainbowEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/RingsEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/RipplesEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/SpiralEffect.png is excluded by !**/*.png
  • docs/assets/light/layouts/GridLayout.png is excluded by !**/*.png
  • docs/assets/light/modifiers/CheckerboardModifier.png is excluded by !**/*.png
  • docs/assets/light/modifiers/MultiplyModifier.png is excluded by !**/*.png
  • docs/assets/ui/moondeck_esp32.png is excluded by !**/*.png
  • docs/assets/ui/moondeck_live.png is excluded by !**/*.png
  • docs/assets/ui/moondeck_pc.png is excluded by !**/*.png
  • docs/assets/ui/ui_overview.png is excluded by !**/*.png
📒 Files selected for processing (17)
  • README.md
  • docs/architecture.md
  • docs/backlog/README.md
  • docs/backlog/backlog-core.md
  • docs/gettingstarted.md
  • docs/moonmodules/core/services/services.md
  • docs/moonmodules/core/supporting/supporting.md
  • docs/moonmodules/light/drivers/drivers.md
  • docs/moonmodules/light/supporting/supporting.md
  • docs/usecases/home-automation.md
  • mkdocs.yml
  • moondeck/docs/mkdocs_hooks.py
  • moondeck/docs/screenshot_modules.py
  • src/core/MqttModule.h
  • src/main.cpp
  • src/ui/app.js
  • web-installer/deviceModels.json

Comment thread docs/backlog/backlog-core.md Outdated
Comment thread docs/gettingstarted.md Outdated
Comment on lines +179 to +200
**Homebridge** — install [`homebridge-mqttthing`](https://github.com/arachnetech/homebridge-mqttthing) and add a `lightbulb` accessory. Use the device's own MAC suffix (read it from the `mqtt_status`/topics, or `mosquitto_sub -t 'projectMM/#'`) in place of `563cfe`:

```json
{
"accessory": "mqttthing",
"type": "lightbulb",
"name": "projectMM",
"url": "mqtt://<broker>:1883",
"username": "<user>",
"password": "<pass>",
"topics": {
"getOn": "projectMM/563cfe/on/get",
"setOn": "projectMM/563cfe/on/set",
"getBrightness": "projectMM/563cfe/brightness/get",
"setBrightness": "projectMM/563cfe/brightness/set",
"getHSV": "projectMM/563cfe/hsv/get",
"setHSV": "projectMM/563cfe/hsv/set"
},
"onValue": "true",
"offValue": "false"
}
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the referenced documentation section and nearby context.
FILE="docs/moonmodules/core/services/services.md"
wc -l "$FILE"
sed -n '160,215p' "$FILE"

# Look for any other references to the Homebridge example or hsv/brightness topics.
rg -n "getBrightness|setBrightness|getHSV|setHSV|mqttthing|Homebridge" "$FILE" docs -g '*.md' -g '*.mdx' || true

Repository: MoonModules/projectMM

Length of output: 1965


🌐 Web query:

homebridge-mqttthing setHSV ignore brightness hue saturation topics documentation

💡 Result:

In homebridge-mqttthing, if the setHSV topic is configured, the plugin uses a combined value for hue, saturation, and brightness (value) [1]. When this topic is populated, the plugin intentionally ignores any individual brightness, hue, saturation, or color temperature topics [2][1]. Regarding the behavior of on/off state when using setHSV: - If a separate setOn topic is configured, it will be used for on/off commands [1]. - If no separate setOn topic is defined, the plugin manages on/off state by setting the V (value) component to 0 when the light is turned off [1]. This design ensures that state changes are handled through the combined topic, preventing conflicts that could arise from simultaneous updates to individual component topics [1].

Citations:


Remove the brightness topics from this Homebridge example. setHSV already covers brightness as part of the combined HSV value, so getBrightness/setBrightness are ignored here and only add misleading config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/moonmodules/core/services/services.md` around lines 179 - 200, The
Homebridge mqttthing example in services.md still includes separate brightness
topic mappings even though setHSV/getHSV already cover brightness through the
combined HSV value. Update the Homebridge JSON example to remove the
getBrightness and setBrightness entries from the topics object, keeping only the
on and HSV topic mappings, so the example matches the actual supported
configuration.

Comment thread docs/usecases/home-automation.md Outdated
Comment thread docs/usecases/home-automation.md Outdated
…inherited-member bloat

Adds a @card image directive so each module's generated technical page shows its UI card screenshot, trims the moxygen inherited-member dump (a link to the base class is enough), fixes AudioModule's class description not rendering, and gives every catalog module a short technical one-line class description. Also sweeps the image assets so every non-board image is referenced, parking the strays.

KPI: 16384lights | PC:666KB | tick:121/97/123/15/2/275/59/17/20/162/120/17/1/36us(FPS:8264/10309/8130/66666/500000/3636/16949/58823/50000/6172/8333/58823/1000000/27777) | ESP32:1369KB | tick:2272us(FPS:440) | heap:157KB

Scripts / MoonDeck
- gen_api.py: new @card <file> directive — a plain-text line in a class /// comment that the generator post-processes into an <img> on the technical page (resolving ../../../assets/<domain>/<file>). Doxygen with GENERATE_HTML=NO drops \image/@htmlonly/raw <img> from the XML, but preserves plain text, so @card survives Doxygen→moxygen and is rendered here; a missing asset drops the directive (no broken link). Matches @card anywhere on the line since a rich multi-paragraph comment flows the directive inline.
- moxygen class.md template: stop re-listing the full inherited-member interface on every subclass — the `> **Inherits:** [Base]` link already points to the base's own page where those members are documented once. Re-dumping MoonModule/EffectBase's large surface on every subclass was bloat (a RainbowEffect page went 118→26 lines). No-duplication applied to generated pages.

Docs
- AudioModule.h: moved the class /// comment from the top of the file (before the includes + `namespace mm {`) to directly above `class AudioModule`, so Doxygen attaches it — its whole class description was silently missing from the technical page. It was the only file with a detached class comment (swept all pages to confirm).
- Added a short technical one-line class description to the 72 catalog effect/modifier/layout/driver .h files that had none (their user-facing prose stays in the catalog summary pages; this is a distinct terse type label, not a duplicate).
- Added @card lines to the 37 modules that have a card screenshot (core services + light drivers/containers/effects). Renamed the Hue driver asset "Hue driver.png" → HueDriver.png (no space, matches convention) + updated the catalog reference.
- Image sweep: deleted 7 redundant effect/modifier PNGs whose module @cards the animated .gif instead; parked 5 genuinely-stray images (superseded UI/installer shots + a Hue screenshot) under docs/backlog/archive_images/unused/. Renamed docs/backlog/moonlight_images → archive_images (now holds moonlight/ migration pool + unused/ orphan park). Every non-board image is now referenced; the 15-photo board library under assets/boards/ is left as the installer's photo pool.

Reviews
- 🐇 backlog-core File Manager link text (ui.md → services.md), gettingstarted module-link anchors, home-automation future-tense wording + the macOS Mosquitto localhost-only listener: all fixed. clientId/brightness-topic finding skipped (the device has genuine separate brightness topics driving HomeKit's slider, distinct from the HSV colour picker).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/usecases/home-automation.md`:
- Around line 65-73: The Mosquitto launch command uses a hardcoded Apple Silicon
path, which breaks the walkthrough on other Homebrew installs. Update the broker
invocation in the home-automation example to use a portable path lookup such as
brew --prefix mosquitto or command -v mosquitto, keeping the rest of the
test.conf and foreground-run instructions unchanged.

In `@src/core/AudioModule.h`:
- Around line 3-13: Move the platform-specific dependency out of AudioModule.h
so the core header stays portable; remove the direct platform/platform.h include
from the core API and keep any platform wiring in a source file or narrow
adapter instead. Update AudioModule and related core declarations so they only
depend on core types like MoonModule, AudioFrame, AudioLevel, AudioBands, and
math8, preserving the src/core/** platform-independent contract.

In `@src/light/modifiers/RippleXZModifier.h`:
- Line 25: The class summary for RippleXZModifier should be reworded to match
what the implementation actually does. Update the documentation comment above
RippleXZModifier so it describes folding/collapsing coordinates on an axis
rather than producing or propagating a ripple effect; keep the wording
consistent with the adjacent note about the omitted MoonLight buffer-shift
ripple behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4031e901-49b6-43da-b49f-6146e1e15b2a

📥 Commits

Reviewing files that changed from the base of the PR and between 208cfa5 and adde7dc.

⛔ Files ignored due to path filters (32)
  • docs/assets/light/drivers/HueDriver.png is excluded by !**/*.png
  • docs/assets/light/effects/LavaLampEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/NoiseEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/PlasmaEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/RingsEffect.png is excluded by !**/*.png
  • docs/assets/light/effects/RipplesEffect.png is excluded by !**/*.png
  • docs/assets/light/modifiers/CheckerboardModifier.png is excluded by !**/*.png
  • docs/assets/light/modifiers/MirrorModifier.png is excluded by !**/*.png
  • docs/backlog/archive_images/moonlight/drivers/Art-Net-In.png is excluded by !**/*.png
  • docs/backlog/archive_images/moonlight/drivers/ArtNetInControls.png is excluded by !**/*.png
  • docs/backlog/archive_images/moonlight/drivers/ArtNetOutControls.png is excluded by !**/*.png
  • docs/backlog/archive_images/moonlight/drivers/FastLED-Audio.png is excluded by !**/*.png
  • docs/backlog/archive_images/moonlight/drivers/FastLED-Driver.png is excluded by !**/*.png
  • docs/backlog/archive_images/moonlight/drivers/IMUDriverControls.png is excluded by !**/*.png
  • docs/backlog/archive_images/moonlight/drivers/MPU-6050.jpg is excluded by !**/*.jpg
  • docs/backlog/archive_images/moonlight/effects/E_Ball2D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/E_Cosmic3D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/E_Geq2D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/E_Hello1D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/E_Noise2D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/E_Noise3D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/E_Orbit2D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/E_Oscillate2D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/E_Random1D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/E_Sweep2D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/E_Vu1D.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/moonlight/effects/layers.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/unused/Hue device disco.png is excluded by !**/*.png
  • docs/backlog/archive_images/unused/installer2.png is excluded by !**/*.png
  • docs/backlog/archive_images/unused/installer3.png is excluded by !**/*.png
  • docs/backlog/archive_images/unused/moondeck.gif is excluded by !**/*.gif
  • docs/backlog/archive_images/unused/ui_light.png is excluded by !**/*.png
📒 Files selected for processing (94)
  • docs/backlog/backlog-core.md
  • docs/gettingstarted.md
  • docs/moonmodules/light/drivers/drivers.md
  • docs/usecases/home-automation.md
  • moondeck/docs/gen_api.py
  • moondeck/docs/moxygen-templates/cpp/class.md
  • src/core/AudioModule.h
  • src/core/DevicesModule.h
  • src/core/FileManagerModule.h
  • src/core/FilesystemModule.h
  • src/core/FirmwareUpdateModule.h
  • src/core/I2cScanModule.h
  • src/core/ImprovProvisioningModule.h
  • src/core/IrModule.h
  • src/core/MqttModule.h
  • src/core/NetworkModule.h
  • src/core/SystemModule.h
  • src/light/drivers/Drivers.h
  • src/light/drivers/HueDriver.h
  • src/light/drivers/LcdLedDriver.h
  • src/light/drivers/NetworkSendDriver.h
  • src/light/drivers/ParallelLedDriver.h
  • src/light/drivers/ParlioLedDriver.h
  • src/light/drivers/PreviewDriver.h
  • src/light/drivers/RmtLedDriver.h
  • src/light/effects/AudioSpectrumEffect.h
  • src/light/effects/AudioVolumeEffect.h
  • src/light/effects/BlurzEffect.h
  • src/light/effects/BouncingBallsEffect.h
  • src/light/effects/DemoReelEffect.h
  • src/light/effects/DistortionWavesEffect.h
  • src/light/effects/FireEffect.h
  • src/light/effects/FixedRectangleEffect.h
  • src/light/effects/FreqMatrixEffect.h
  • src/light/effects/FreqSawsEffect.h
  • src/light/effects/GEQ3DEffect.h
  • src/light/effects/GEQEffect.h
  • src/light/effects/GameOfLifeEffect.h
  • src/light/effects/LavaLampEffect.h
  • src/light/effects/LinesEffect.h
  • src/light/effects/LissajousEffect.h
  • src/light/effects/MetaballsEffect.h
  • src/light/effects/NetworkReceiveEffect.h
  • src/light/effects/Noise2DEffect.h
  • src/light/effects/NoiseEffect.h
  • src/light/effects/NoiseMeterEffect.h
  • src/light/effects/PaintBrushEffect.h
  • src/light/effects/ParticlesEffect.h
  • src/light/effects/PlasmaEffect.h
  • src/light/effects/PraxisEffect.h
  • src/light/effects/RainbowEffect.h
  • src/light/effects/RandomEffect.h
  • src/light/effects/RingsEffect.h
  • src/light/effects/RipplesEffect.h
  • src/light/effects/RubiksCubeEffect.h
  • src/light/effects/SineEffect.h
  • src/light/effects/SolidEffect.h
  • src/light/effects/SphereMoveEffect.h
  • src/light/effects/SpiralEffect.h
  • src/light/effects/StarFieldEffect.h
  • src/light/effects/StarSkyEffect.h
  • src/light/effects/TetrixEffect.h
  • src/light/effects/TextEffect.h
  • src/light/effects/WaveEffect.h
  • src/light/layers/Layer.h
  • src/light/layers/Layers.h
  • src/light/layouts/CarLightsLayout.h
  • src/light/layouts/CubeLayout.h
  • src/light/layouts/GridLayout.h
  • src/light/layouts/HumanSizedCubeLayout.h
  • src/light/layouts/Layouts.h
  • src/light/layouts/PanelLayout.h
  • src/light/layouts/PanelsLayout.h
  • src/light/layouts/RingLayout.h
  • src/light/layouts/Rings241Layout.h
  • src/light/layouts/SingleColumnLayout.h
  • src/light/layouts/SingleRowLayout.h
  • src/light/layouts/SphereLayout.h
  • src/light/layouts/SpiralLayout.h
  • src/light/layouts/TorontoBarGourdsLayout.h
  • src/light/layouts/TubesLayout.h
  • src/light/layouts/WheelLayout.h
  • src/light/modifiers/BlockModifier.h
  • src/light/modifiers/CheckerboardModifier.h
  • src/light/modifiers/CircleModifier.h
  • src/light/modifiers/MirrorModifier.h
  • src/light/modifiers/MultiplyModifier.h
  • src/light/modifiers/PinwheelModifier.h
  • src/light/modifiers/RandomMapModifier.h
  • src/light/modifiers/RegionModifier.h
  • src/light/modifiers/RippleXZModifier.h
  • src/light/modifiers/RotateModifier.h
  • src/light/modifiers/TransposeModifier.h
  • src/light/moonlive/MoonLiveEffect.h

Comment thread docs/usecases/home-automation.md
Comment thread src/core/AudioModule.h
Comment on lines +3 to +13
#include "core/MoonModule.h"
#include "core/AudioFrame.h"
#include "core/AudioLevel.h"
#include "core/AudioBands.h"
#include "core/math8.h" // beatsin8 / sin8 — the simulated-audio oscillators
#include "light/WLEDAudioSyncPacket.h" // WLED audio-sync wire format (send/receive)
#include "platform/platform.h"

#include <cstdint>
#include <cstdio> // snprintf for the read-out strings
#include <cstring>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Keep src/core/AudioModule.h platform-agnostic.

The new include set pulls platform/platform.h into a core header, which violates the src/core/** contract and leaks platform-specific dependencies into every consumer. Please move the platform wiring behind a source file or narrow adapter so the core API stays portable. As per path instructions, "Core infrastructure: MoonModule base, Controls, Scheduler, types, color math. Must be platform-independent — no platform includes."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/AudioModule.h` around lines 3 - 13, Move the platform-specific
dependency out of AudioModule.h so the core header stays portable; remove the
direct platform/platform.h include from the core API and keep any platform
wiring in a source file or narrow adapter instead. Update AudioModule and
related core declarations so they only depend on core types like MoonModule,
AudioFrame, AudioLevel, AudioBands, and math8, preserving the src/core/**
platform-independent contract.

Source: Path instructions

Comment thread src/light/modifiers/RippleXZModifier.h Outdated
Gives drivers and layouts their own base-class files (matching effects/modifiers), so DriverBase and LayoutBase now render as standalone technical pages with supporting cards. Reworks the LED-driver header docs to a compact-class-comment/detail-on-members standard, adds coloured headings plus a name-only highlight to the generated API pages, deletes the six migrated driver detail pages, and renames the installer image dir to deviceModels for consistency.

KPI: 16384lights | PC:666KB | tick:119/91/119/14/2/271/57/17/20/157/114/16/1/34us(FPS:8403/10989/8403/71428/500000/3690/17543/58823/50000/6369/8771/62500/1000000/29411) | ESP32:1369KB | tick:1416us(FPS:706) | heap:155KB | src:176(34639) | test:122(17897) | lizard:125w

Core:
- DriverBase.h / LayoutBase.h: split the base classes out of Drivers.h / Layouts.h into their own headers, so each has its own moxygen technical page + supporting card, symmetric with EffectBase / ModifierBase.
- Drivers.h / Layouts.h: reduced to the container class, now including the split-out base header.

Light domain:
- LED drivers (Rmt/Parallel/Lcd/Parlio/NetworkSend/Hue/Preview): compacted each class comment to identity + defining contract and distributed the per-control / per-method detail onto the attributes and methods themselves (every public member now carries a `///`), so the generated page reads as a documented list rather than one class blurb; no logic change.
- RmtLedDriver: carried the modern-RMT-v2-vs-legacy rationale and the classic-ESP32 whole-frame-loopback cap into the `.h` `///` (were archive-only).
- driver subclasses + concrete layouts: include the lighter DriverBase.h / LayoutBase.h directly (matching how effects include EffectBase); main.cpp + the container-using tests gained an explicit Drivers.h / Layouts.h include.
- RippleXZModifier: reworded the class summary to describe the axis collapse/fold it actually does (was "ripples").

UI:
- extra.css: coloured h1/h2/h3 site-wide (the slate theme rendered every heading the same grey), and a name-only signature highlight on the technical pages (accent name, muted type/args).

Scripts / MoonDeck:
- gen_api.py: post-process wrapping each generated member-signature name in a `.mm-sig-name` span so the theme can highlight the name while type/args stay muted.
- check_devices.py / preview_installer.py: follow the docs/assets/boards -> docs/assets/deviceModels rename.

Tests:
- 33 effect/layout unit tests: explicit `#include "light/layouts/Layouts.h"` where they construct the container fixture (they previously got it transitively through a layout header now switched to the lighter base).

Docs / CI:
- docs/assets/boards -> docs/assets/deviceModels (34 images git-renamed; deviceModels.json, install.js, README, release.yml, mkdocs references updated).
- coding-standards.md: documented the compact-class-comment/detail-on-members standard and the two moxygen shaping levers.
- drivers/effects/layouts/modifiers/supporting/MoonLiveEffect catalog pages: repointed card links to the generated moxygen pages; deleted the six migrated driver detail pages (content now lives in the `.h` `///`).
- home-automation.md: portable `$(brew --prefix)/sbin/mosquitto` path (was hardcoded Apple-Silicon); led-signal-integrity.md use-case guide added.
- backlog-core.md: parked the open Homebridge brightness-vs-HSV question (resolve on hardware).

Reviews:
- 🐇 File Manager link / gettingstarted anchors / roadmap wording / bare `mosquitto -v`: verified already-correct in current code, no change.
- 🐇 Homebridge example redundant brightness topics: accepted-with-note — brightness is one of the three first-class MQTT controls, so kept in the example; parked the mqttthing-config nuance in backlog for a hardware check.
- 🐇 AudioModule.h platform/platform.h include: rejected — that header IS the platform-abstraction seam core depends on (18 core files include it, incl. MoonModule.h); the boundary check forbids `<esp_*>`/`<freertos/*>`, not this.
- 🐇 Apple-Silicon mosquitto path + RippleXZ "ripples" summary: fixed.

KPI Details:
    [doctest] test cases: 638 | 638 passed | 0 failed | 0 skipped
    PC tick: 119/91/119/14/2/271/57/17/20/157/114/16/1/34 us (per scenario)
    19 scenario(s), 19 passed, 0 failed
    Platform boundary: PASS
    ESP32 (esp32, classic ESP32-D0WD-V3): tick 1416 us (FPS 706), heap free 159152, flash 1369KB
    ESP32 builds verified: esp32 (RMT) + esp32s3-n16r8 (LCD_CAM) + esp32p4-eth (Parlio)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MoonModules

Copy link
Copy Markdown
Owner

@coderabbitai, please review 869a857 and report your findings in a copy/pastable text for agents

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
gh api repos/MoonModules/projectMM/commits/869a8579db13abb9ec3ea19a956eac601d362d0d --jq '.files[] | .filename' 2>&1 | head -100
echo "---DIFF---"
gh api repos/MoonModules/projectMM/commits/869a8579db13abb9ec3ea19a956eac601d362d0d --jq '.files[] | .patch' 2>&1 | head -2000

Length of output: 178022


🏁 Script executed:

#!/bin/bash
set -euo pipefail
git clone --depth 1 https://github.com/MoonModules/projectMM.git repo 2>&1 | tail -5 || true
cd repo 2>/dev/null || exit 0
git fetch --depth 1 origin pull/38/head:pr38 2>&1 | tail -5 || true
git checkout pr38 2>&1 | tail -5 || true

echo "--- searching for now-removed doc files being referenced ---"
rg -n "drivers/(RmtLedDriver|LcdLedDriver|ParlioLedDriver|NetworkSendDriver|PreviewDriver|HueDriver)\.md" --type md --type cpp -g '!*/moxygen/*' . 2>&1 | head -80

echo "--- check core/ui path remnants ---"
rg -n "core/ui/ui.md" . 2>&1 | head -50

echo "--- check LcdLedDriver.md / ParlioLedDriver.md referenced from .h prose comments ---"
rg -n "LcdLedDriver\.md|ParlioLedDriver\.md|RmtLedDriver\.md|HueDriver\.md|NetworkSendDriver\.md|PreviewDriver\.md" src/ 2>&1

echo "--- check mkdocs_hooks / gen_api for archive references ---"
rg -n "archive/" moondeck/docs 2>&1

echo "--- verify docs/moonmodules/light/drivers/*.md exist for removed files ---"
fd . docs/moonmodules/light/drivers/ 2>&1

Length of output: 8221


🏁 Script executed:

#!/bin/bash
set -euo pipefail
cd repo 2>/dev/null || { echo "no repo dir, retry clone"; exit 1; }

echo "--- archive folder contents ---"
fd . docs/moonmodules -t d 2>&1
find docs/moonmodules -type d -name archive 2>&1
fd . docs/moonmodules/light/archive 2>&1 || true
fd . docs/moonmodules/core/archive 2>&1 || true

echo "--- full main.cpp registerType block for light drivers ---"
grep -n "registerType" src/main.cpp | head -40

echo "--- confirm these referenced .md files actually don't exist ---"
for f in HueDriver NetworkSendDriver PreviewDriver RmtLedDriver LcdLedDriver ParlioLedDriver; do
  echo "$f:"; fd "^${f}\.md$" docs/moonmodules 2>&1
done

echo "--- web-installer/README.md context ---"
sed -n '100,130p' web-installer/README.md

Length of output: 9333


🏁 Script executed:

#!/bin/bash
set -euo pipefail
cd repo 2>/dev/null || exit 1

echo "--- how is the help-link second arg used (does it map to a doc file check)? ---"
rg -n "registerType" src/core/ModuleFactory.h src/core/*.h 2>&1 | head -5
rg -n "helpLink\|docLink\|docPath" src/core -n 2>&1 | head -20
ast-grep run --pattern 'registerType<$T>($NAME, $DOC)' --lang cpp src/main.cpp | head -5

echo "--- check_specs.py: does it validate main.cpp registerType doc paths exist? ---"
rg -n "registerType|\.md" moondeck/check/check_specs.py | head -40

Length of output: 1485


🏁 Script executed:

#!/bin/bash
set -euo pipefail
cd repo 2>/dev/null || exit 1
sed -n '20,60p' src/core/ModuleFactory.h

Length of output: 2633


Confirmed — this is a real, live-breaking regression in commit 869a857, not just a doc-nit. Here's the copy/pastable report:


CodeRabbit review — commit 869a8579db13abb9ec3ea19a956eac601d362d0d

🔴 Bug: src/main.cpp — broken in-UI help links for 6 light drivers

This commit deletes the per-driver detail pages (docs/moonmodules/light/drivers/{HueDriver,NetworkSendDriver,PreviewDriver,RmtLedDriver,LcdLedDriver,ParlioLedDriver}.md) in favor of generated moxygen/<Module>.md technical pages, and updates drivers.md links accordingly. However, src/main.cpp's ModuleFactory::registerType<T>() calls for these six drivers were not updated and still pass the old, now-deleted paths as docPath:

// src/main.cpp — still pointing at deleted files
mm::ModuleFactory::registerType<mm::HueDriver>("HueDriver", "light/drivers/HueDriver.md");
mm::ModuleFactory::registerType<mm::NetworkSendDriver>("NetworkSendDriver", "light/drivers/NetworkSendDriver.md");
mm::ModuleFactory::registerType<mm::PreviewDriver>("PreviewDriver", "light/drivers/PreviewDriver.md");
mm::ModuleFactory::registerType<mm::RmtLedDriver>("RmtLedDriver", "light/drivers/RmtLedDriver.md");
mm::ModuleFactory::registerType<mm::LcdLedDriver>("LcdLedDriver", "light/drivers/LcdLedDriver.md");
mm::ModuleFactory::registerType<mm::ParlioLedDriver>("ParlioLedDriver", "light/drivers/ParlioLedDriver.md");

Per src/core/ModuleFactory.h (Line ~23): "docPath is the module's spec page relative to docs/moonmodules/... the UI builds a help link from it." Confirmed on the PR branch HEAD that none of these six .md files exist anymore under docs/moonmodules/light/drivers/ (only the catalog drivers.md remains) — every "❓/help" link the UI renders for these six cards now 404s.

Fix: update each docPath to the new generated technical page, matching the pattern already used elsewhere in this same commit for HttpServerModule, SystemModule, etc. (core/services/services.md#...):

mm::ModuleFactory::registerType<mm::HueDriver>("HueDriver", "light/moxygen/HueDriver.md");
mm::ModuleFactory::registerType<mm::NetworkSendDriver>("NetworkSendDriver", "light/moxygen/NetworkSendDriver.md");
mm::ModuleFactory::registerType<mm::PreviewDriver>("PreviewDriver", "light/moxygen/PreviewDriver.md");
mm::ModuleFactory::registerType<mm::RmtLedDriver>("RmtLedDriver", "light/moxygen/RmtLedDriver.md");
mm::ModuleFactory::registerType<mm::LcdLedDriver>("LcdLedDriver", "light/moxygen/LcdLedDriver.md");
mm::ModuleFactory::registerType<mm::ParlioLedDriver>("ParlioLedDriver", "light/moxygen/ParlioLedDriver.md");

(Or route to the drivers.md#<anchor> catalog entry if that's the intended user-facing target instead of the generated technical page — whichever convention the rest of main.cpp's light-driver registrations should follow going forward.)

Note: moondeck/check/check_specs.py does not currently validate that main.cpp's registerType doc paths resolve to an existing file, so this class of drift isn't caught by CI — worth a follow-up check if this kind of rename happens again.


🟡 Secondary: stale link in web-installer/README.md

Line ~118 still links to the deleted detail page:

needs the full 8-lane bus — see the [LcdLedDriver spec](../moonmodules/light/drivers/LcdLedDriver.md);

Should be updated to ../moonmodules/light/moxygen/LcdLedDriver.md (or drivers.md#lcdled).


Non-issues / lower priority (historical, not live docs)

  • docs/history/plans/*.md and docs/moonmodules/*/archive/*.md still reference the old per-module .md paths (e.g. HueDriver.md, ui.md) — these are historical/archived records per the project's own documentation-model convention ("Live docs never link an archive/ file"), so no action needed there.
  • src/light/E131Packet.h comment mentions NetworkSendDriver.md in prose (not a hyperlink) — cosmetic only.

Let me know if you'd like me to open a GitHub issue for the main.cpp fix, or if it's small enough to just push directly.

[resolve]

…une backlog

Finishes the docs-v2 arc: deletes the retired per-module archive pages (content absorbed into the .h /// comments or the summary rows), promotes the UI system spec to a live page, flattens the single-file catalog folders (effects/effects.md → effects.md, groundwork for future per-library splits), and consolidates the docs-overhaul plans + prunes shipped backlog items. src/ changes are comment/docPath-string only — no logic.

Core:
- AudioModule / DevicesModule / FirmwareUpdateModule / ImprovProvisioningModule / MoonModule / NetworkModule / SystemModule: migrated the last present-tense content from the retired archive .md pages into the class/member /// comments (wire contracts, error taxonomies, runtime add/remove lifecycle, eth-pin control detail, wifiCoproc C6 detail); removed dangling "see the moxygen page for X" pointers that pointed at generated-from-this-.h content.
- MqttModule: repointed a /// docs-path after the catalog-folder flatten.
- main.cpp: all registerType docPaths repointed — the 6 deleted driver detail pages and 4 container pages now resolve to drivers.md#anchor / supporting.md#anchor, and every path follows the flattened light/effects.md (not light/effects/effects.md) layout.

Light domain:
- E131Packet.h: prose reference to a deleted NetworkSendDriver.md now names the driver's universeStart control instead.

Scripts / MoonDeck:
- check_specs.py: new registerType-docPath gate — validates every main.cpp docPath resolves to a real page + #anchor (catches the class of drift a docs rename introduces; flagged by CodeRabbit). Also fixed the internal path list for the flattened catalog folders.
- gen_api.py: retired the temporary "Migration cross-check" banner (all archives now deleted) in favour of a permanent one-line Source: <.h> GitHub link on each generated page.
- mkdocs_hooks.py: _CATALOG_PAGES paths updated for the flattened folders.

UI:
- (no src/ui change) — the web-UI spec moved from an archived .md to a live docs page (see Docs).

Docs / CI:
- Deleted 22 module archive .md pages (core + light) — content lives in the .h /// + summary rows; forward-looking AudioModule content moved to docs/backlog/audio-dsp-roadmap.md.
- Promoted the UI system spec to a live page docs/moonmodules/core/ui.md (de-duplicated against architecture.md § Web UI + HttpServerModule); fixed architecture.md's stale services.md → ui.md pointers.
- Flattened the single-file catalog folders (core/services/services.md → core/services.md, light/{effects,layouts,modifiers,drivers,supporting}/…, light/moonlive/MoonLiveEffect.md); rewrote ~230 relative links across referencing docs; per the committed folder-structure decision (effects_<library>.md is a future page-name split, not a folder).
- Consolidated 8 docs-overhaul plans into one shipped record (Plan-20260702 - Docs system overhaul); marked 7 shipped feature plans (shipped); deleted the fully-shipped docs-system-overhaul.md backlog study and the redundant Virtual-layer history plan (its backlog study is the single home).
- Backlog prune: slimmed folder-structure-proposal.md to a decision record, fixed stale effects_<library>.md framing in moonlight-effect-inventory.md, deleted 3 orphaned staged images, and moved installer2/3.png to docs/assets/ui/ (fixing MoonDeck.md's broken image links).
- README / MqttModule /// / home-automation.md / web-installer/README.md: repointed docs paths after the flatten + archive deletions.
- CLAUDE.md: documented the new check_specs docPath validation.

Reviews:
- 🐇 main.cpp driver docPaths pointing at deleted pages: already fixed (drivers.md#anchor); verified all 88 resolve.
- 🐇 web-installer/README.md + E131Packet.h stale links to deleted driver .md: fixed.
- 🐇 CI gap (check_specs didn't validate registerType docPaths): fixed — added the docPath gate.
- 🐇 AudioModule.h platform/platform.h include: rejected — that header IS the platform-abstraction seam core depends on (18 core files include it), not a boundary violation.

ESP32 build + KPI gates skipped: the src/ changes are comment (///, //) and main.cpp docPath-string only — no binary or hot-path impact, so the desktop build already proves them well-formed and there is no perf number to re-capture.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MoonModules

Copy link
Copy Markdown
Owner

@coderabbitai, please review ab4ae6f
and report your findings in a copy/pastable text for agents

@ewowi ewowi changed the title Docs: rename core UI page to services, card screenshots, home-automation guide Docs v2: two-surface module docs, flatten catalog folders, DriverBase/LayoutBase split Jul 6, 2026
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
gh api repos/MoonModules/projectMM/commits/ab4ae6f0d9bc150f4d891be7e432d291e245e961 --jq '.files[] | .filename' 2>&1 | head -100
echo "---DIFF---"
gh api repos/MoonModules/projectMM/commits/ab4ae6f0d9bc150f4d891be7e432d291e245e961 --jq '.files[] | .patch' 2>&1 | head -3000

Length of output: 240398


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "=== FULL FILE LIST ==="
gh api repos/MoonModules/projectMM/commits/ab4ae6f0d9bc150f4d891be7e432d291e245e961 --jq '.files[] | .filename' 2>&1

echo "=== main.cpp patch ==="
gh api repos/MoonModules/projectMM/commits/ab4ae6f0d9bc150f4d891be7e432d291e245e961 --jq '.files[] | select(.filename=="src/main.cpp") | .patch' 2>&1

echo "=== mkdocs.yml patch ==="
gh api repos/MoonModules/projectMM/commits/ab4ae6f0d9bc150f4d891be7e432d291e245e961 --jq '.files[] | select(.filename=="mkdocs.yml") | .patch' 2>&1

echo "=== mkdocs_hooks.py patch ==="
gh api repos/MoonModules/projectMM/commits/ab4ae6f0d9bc150f4d891be7e432d291e245e961 --jq '.files[] | select(.filename=="moondeck/docs/mkdocs_hooks.py") | .patch' 2>&1

echo "=== check_specs.py patch ==="
gh api repos/MoonModules/projectMM/commits/ab4ae6f0d9bc150f4d891be7e432d291e245e961 --jq '.files[] | select(.filename | contains("check_specs.py")) | .patch' 2>&1

Length of output: 32058


🏁 Script executed:

#!/bin/bash
set -euo pipefail
cd repo 2>/dev/null || { git clone --depth 1 https://github.com/MoonModules/projectMM.git repo; cd repo; }
git fetch --depth 1 origin pull/38/head:pr38 2>&1 | tail -3
git checkout pr38 2>&1 | tail -3

echo "--- stale nested path references anywhere ---"
rg -n "light/effects/effects\.md|light/modifiers/modifiers\.md|light/layouts/layouts\.md|light/drivers/drivers\.md|light/supporting/supporting\.md|core/services/services\.md|core/supporting/supporting\.md|light/moonlive/MoonLiveEffect\.md|core/ui/ui\.md|light/drivers/(HueDriver|NetworkSendDriver|PreviewDriver|RmtLedDriver|LcdLedDriver|ParlioLedDriver)\.md" . 2>&1 | grep -v '^Binary'

echo "--- anchors present in light/drivers.md ---"
grep -n '^#\|<a id=' docs/moonmodules/light/drivers.md

echo "--- anchors present in core/services.md ---"
grep -n '^#\|<a id=' docs/moonmodules/core/services.md

echo "--- anchors present in core/supporting.md ---"
grep -n '^#\|<a id=' docs/moonmodules/core/supporting.md

echo "--- anchors present in light/supporting.md ---"
grep -n '^#\|<a id=' docs/moonmodules/light/supporting.md

echo "--- verify MoonLiveEffect.md exists at new path ---"
fd MoonLiveEffect.md docs/moonmodules

echo "--- web-installer/README.md remaining stale link check ---"
grep -n "LcdLedDriver\|drivers/drivers\|effects/effects" web-installer/README.md || true

echo "--- E131Packet.h reference ---"
grep -n "NetworkSendDriver" src/light/E131Packet.h || true

Length of output: 8241


🏁 Script executed:

#!/bin/bash
set -euo pipefail
cd repo

echo "--- anchors in effects.md (sample check) ---"
grep -n '<a id=' docs/moonmodules/light/effects.md | head -50

echo "--- anchors in modifiers.md ---"
grep -n '<a id=' docs/moonmodules/light/modifiers.md

echo "--- anchors in layouts.md ---"
grep -n '<a id=' docs/moonmodules/light/layouts.md

echo "--- confirm deleted files referenced by MoonDeck.md ---"
fd "NetworkReceiveEffect.md|NetworkSendDriver.md|PreviewDriver.md" docs/moonmodules/light 2>&1 || true
ls docs/moonmodules/light/ 2>&1
ls docs/moonmodules/light/effects 2>&1 || echo "no effects dir"
ls docs/moonmodules/light/drivers 2>&1 || echo "no drivers dir"

Length of output: 2878


@MoonModules Reviewed commit ab4ae6f0d9bc150f4d891be7e432d291e245e961. Good news first: this commit is well-executed — it flattens the nested doc paths (core/services/services.mdcore/services.md, light/effects/effects.mdlight/effects.md, light/drivers/drivers.mdlight/drivers.md, light/supporting/supporting.mdlight/supporting.md, core/supporting/supporting.mdcore/supporting.md, light/moonlive/MoonLiveEffect.mdlight/MoonLiveEffect.md) and updates src/main.cpp, mkdocs.yml, and moondeck/docs/mkdocs_hooks.py consistently. I cross-checked every registerType(...) docPath + anchor in main.cpp against the actual <a id="..."> anchors in effects.md, modifiers.md, layouts.md, drivers.md, core/services.md, core/supporting.md, and light/supporting.mdall resolve correctly, no dangling anchors.

This commit also adds check_registertype_docpaths() to moondeck/check/check_specs.py, which parses every registerType<T>("Name", "docPath") in main.cpp and validates the file + #anchor actually resolve — this is exactly the class of drift that broke the six light-driver help links I flagged in commit 869a857. Good, durable fix — nice to see it land as a standing CI gate rather than a one-off correction.

Copy/pastable report for agents:


CodeRabbit review — commit ab4ae6f0d9bc150f4d891be7e432d291e245e961

✅ Verified correct

  • All registerType() docPath + anchor pairs in src/main.cpp resolve against the flattened doc pages (spot-checked every anchor programmatically).
  • mkdocs.yml nav and mkdocs_hooks.py's _CATALOG_PAGES set updated in lockstep with the path flattening.
  • New check_registertype_docpaths() in moondeck/check/check_specs.py now guards this exact class of bug going forward (file-not-found + missing-anchor detection).

🟡 Minor: stale example path in src/ui/app.js comment (Line 523)

// "core/services/services.md#audio" or "light/effects/effects.md#fire"); omitted if none.

This comment example still uses the pre-flatten nested paths. Should read "core/services.md#audio" / "light/effects.md#fire" to match the new convention. Cosmetic only (not a real link), but worth a follow-up sweep since it'll mislead anyone reading the comment as documentation of the current convention.

🟡 Broken links (pre-existing, not touched by this commit): moondeck/MoonDeck.md

Three links point at per-module .md files that no longer exist (folded into the consolidated catalog pages by an earlier commit in this same doc-overhaul arc):

Line 234: [NetworkReceiveEffect](../docs/moonmodules/light/effects/NetworkReceiveEffect.md)
Line 234: [NetworkSendDriver](../docs/moonmodules/light/drivers/NetworkSendDriver.md)
Line 257: [PreviewDriver](../docs/moonmodules/light/drivers/PreviewDriver.md)

Confirmed docs/moonmodules/light/effects/ and docs/moonmodules/light/drivers/ no longer exist as directories — these should be repointed to:

../docs/moonmodules/light/effects.md#networkreceive
../docs/moonmodules/light/drivers.md#networksend
../docs/moonmodules/light/drivers.md#preview

Non-issues (historical records, correctly left alone)

  • docs/history/plans/*.md, docs/history/release-notes-v1.0.0.md — pinned to historical state (the release-notes links even pin to the v1.0.0 git tag), consistent with the project's "live docs never restate an archived/historical path" convention.

Let me know if you'd like me to open a follow-up issue for the MoonDeck.md links + the app.js comment, since neither is in this commit's diff.

[resolve]

Fixes the documentation/process drift the Reviewer agent and CodeRabbit surfaced on the docs-v2 branch — stale references to the folder layout the branch itself flattened, absence-narration comments, and a detached doc-comment. src/ changes are comment-only; no logic.

Core:
- Drivers.h / Layouts.h / main.cpp: rewrote the split-out base-header include comments to present tense (state what is — "the container casts its children to DriverBase/LayoutBase; subclasses include the base directly" — not what changed).
- FireEffect.h: merged the detached /// description block (separated from the class by the // Author: line, so Doxygen dropped it) and removed the duplicate one-line brief — its full description now reaches the generated page.

Light domain:
- (no light-domain logic change) — FireEffect above is a comment fix.

UI:
- app.js: the docPath example comment now uses the flat convention (core/services.md#audio, not the pre-flatten nested path).

Scripts / MoonDeck:
- MoonDeck.md: repointed 3 links to deleted per-module .md pages (NetworkReceiveEffect, NetworkSendDriver, PreviewDriver) at the flat catalog pages + anchors.
- gen_api.py: trimmed the _source_header docstring's absence-narration parenthetical (the cross-check link "is gone…") to just the standing purpose.
- write-behaviour-tests.js (workflow): flat effects.md / modifiers.md spec paths.

Docs / CI:
- coding-standards.md: rewrote the two-surface layout bullet to the flat page paths (light/effects.md, core/services.md, …) and shrank the completed archive-migration paragraph to the standing "no per-module detail .md" rule (net deletion).
- CLAUDE.md: same flat-path + no-archive update to the documentation-model summary; added the docPath check to the check_specs description; added a clause permitting a shipped multi-phase effort's per-phase plans to consolidate into one record (resolves the Reviewer's plan-pruning-vs-"plans are kept" finding).
- drivers.md: the source-window (start/count) link points at DriverBase's page (where the window controls now live after the split), not the Drivers container.
- decisions.md: carried two lessons from this branch — a code-embedded docPath drifts silently when docs move (gate it), and verify a generated anchor against the built HTML not a re-derived slug.

Reviews:
- 👾 Reviewer agent (whole-branch, pre-merge): architecturally clean (net-subtractive split, symmetric with EffectBase/ModifierBase); F1-F7 fixed here, F2 resolved via the CLAUDE.md consolidation clause, F8 (a backlog item referenced from a .h) accepted as a watch-item (precedent in Palette.h).
- 🐇 CodeRabbit (ab4ae6f): clean verdict, all docPaths verified resolving; the app.js example-path finding was already fixed (Reviewer F5); the MoonDeck.md broken links fixed here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ewowi ewowi merged commit bcb085b into main Jul 6, 2026
3 checks passed
@ewowi ewowi deleted the next-iteration branch July 6, 2026 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants