docs: reorganize navigation and group detector pages by ecosystem - #358
Conversation
Reorders manifest.json so the docs read in the order people need them: Installation before Tutorial, Commands moved into "How it works" next to the pipeline stages it drives, Bomly Guard promoted there too, and the Architecture/Network/Security deep dives moved into Reference. Operations now comes before Reference. Evidence no longer renders first in Reference by accident of array position. Detector docs move from docs/detectors/ecosystems/<eco>/<pm>.md to docs/detectors/<eco>/<pm>.md, and only ecosystems with a native detector get a directory. Everything reachable through Syft alone collapses into a single docs/detectors/syft.md instead of 23 near-identical pages. That takes the nav from 31 ecosystem entries to 15 while keeping related managers grouped — python now lists pip, pipenv, poetry, and uv, with pdm and setuppy described on the Syft page. SUPPORT_MATRIX.md still lists every ecosystem and manager. Also adds a marketplace section to INTEGRATIONS.md and mirrors the new group order in docs/README.md. No slugs are added or removed, so the manifest stays in 1:1 sync with the top-level docs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe PR moves generated detector documentation from ecosystem-specific pages to per-detector pages, adds a Syft fallback reference, updates generated-doc tests and prose, and reorganizes documentation navigation and marketplace guidance. ChangesDetector documentation generation
Documentation navigation
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant WriteComponentDocs
participant writeDetectorDocs
participant DetectorRegistry
participant DocsOutput
WriteComponentDocs->>writeDetectorDocs: generate detector documentation
writeDetectorDocs->>DetectorRegistry: classify native and Syft-only chains
DetectorRegistry-->>writeDetectorDocs: detector metadata
writeDetectorDocs->>DocsOutput: write README, detector pages, and syft.md
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
Bomly Diff SummaryCompared Overview
Dependency Changes✅ No dependency changes. Vulnerabilities✅ No vulnerability changes. License Changes✅ No license changes. Project Posture✅ No project posture changes ( Policy Findings✅ No policy differences were identified. |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
internal/support/component_docs.go (1)
711-717: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLoop variable
osshadows theospackage.Compiles only because this function doesn't touch
os; any futureos.*call here breaks confusingly.♻️ Rename the loop variable
- for _, os := range registry.SupportedOperatingSystems() { - name := os.Name - if len(os.Aliases) > 0 { - name += " (" + strings.Join(os.Aliases, ", ") + ")" - } - _, _ = fmt.Fprintf(&b, "| %s | `%s` | %s |\n", name, os.Provider, os.VersionSource) + for _, osEntry := range registry.SupportedOperatingSystems() { + name := osEntry.Name + if len(osEntry.Aliases) > 0 { + name += " (" + strings.Join(osEntry.Aliases, ", ") + ")" + } + _, _ = fmt.Fprintf(&b, "| %s | `%s` | %s |\n", name, osEntry.Provider, osEntry.VersionSource)🤖 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 `@internal/support/component_docs.go` around lines 711 - 717, Rename the loop variable in the registry.SupportedOperatingSystems() iteration from os to a non-conflicting name, and update its Name, Aliases, Provider, and VersionSource references accordingly so the os package remains accessible within the function.internal/support/generate_test.go (1)
102-110: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExistence-only checks won't catch a broken Syft/native split.
If
isSyftOnlyChainstops matching (seecomponent_docs.go),syft.mdis still written — just empty — and the legacy tree could reappear. Two cheap assertions pin the migration down.♻️ Suggested additional assertions
if _, err := os.Stat(filepath.Join(tmp, "detectors", "ecosystems")); !os.IsNotExist(err) { t.Fatalf("legacy detectors/ecosystems tree should not be generated: %v", err) } syft, err := os.ReadFile(filepath.Join(tmp, "detectors", "syft.md")) if err != nil { t.Fatalf("read syft page: %v", err) } if !strings.Contains(string(syft), "## Package managers covered") || strings.Contains(string(syft), "covered | 0 ") { t.Fatalf("syft page missing Syft-only coverage:\n%s", syft) }As per coding guidelines, "Add unit tests for new logic".
🤖 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 `@internal/support/generate_test.go` around lines 102 - 110, Strengthen the generation test around the expected detector outputs by asserting that the legacy detectors/ecosystems directory is not created, then read detectors/syft.md and verify it contains the “## Package managers covered” section with nonzero coverage. Add the required strings import if needed, keeping the existing path-existence checks and generation behavior unchanged.Source: Coding guidelines
🤖 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 `@CONTRIBUTING.md`:
- Line 136: Update the documentation generation entry in CONTRIBUTING.md to
describe detector pages recursively, using docs/detectors/ or an explicit
recursive pattern instead of docs/detectors/*.md so nested paths such as
maven/maven.md are included.
In `@docs/README.md`:
- Line 51: Update the Detector Reference description in docs/README.md to use
“per-detector” wording, accurately stating that it contains one page per native
detector plus the Syft fallback. Keep the existing links unchanged and align
terminology with docs/DETECTORS.md.
In `@internal/support/component_docs.go`:
- Around line 586-591: Update writeDetectorDocs to stop deleting the entire
outputDir with os.RemoveAll. Before recreating the directory, remove only known
generated detector artifacts, such as generated ecosystem .md pages and syft.md,
while preserving hand-written and unrelated files; retain the existing
error-wrapping behavior for cleanup and directory creation.
In `@internal/support/prose/README.md`:
- Line 68: Update the documentation path guidance near the detector and matcher
examples to reflect native detector pages under
docs/detectors/<ecosystem>/<name>.md, while preserving the Syft fallback path as
docs/detectors/syft.md and the existing matcher path.
---
Nitpick comments:
In `@internal/support/component_docs.go`:
- Around line 711-717: Rename the loop variable in the
registry.SupportedOperatingSystems() iteration from os to a non-conflicting
name, and update its Name, Aliases, Provider, and VersionSource references
accordingly so the os package remains accessible within the function.
In `@internal/support/generate_test.go`:
- Around line 102-110: Strengthen the generation test around the expected
detector outputs by asserting that the legacy detectors/ecosystems directory is
not created, then read detectors/syft.md and verify it contains the “## Package
managers covered” section with nonzero coverage. Add the required strings import
if needed, keeping the existing path-existence checks and generation behavior
unchanged.
🪄 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: CHILL
Plan: Pro Plus
Run ID: de378d31-7aaf-4805-bbd8-68d3ba4bbcfa
📒 Files selected for processing (100)
CONTRIBUTING.mddocs/DETECTORS.mddocs/INTEGRATIONS.mddocs/README.mddocs/SBOM.mddocs/detectors/README.mddocs/detectors/cpp/conan.mddocs/detectors/dart/pub.mddocs/detectors/dotnet/nuget.mddocs/detectors/ecosystems/README.mddocs/detectors/ecosystems/alpm/README.mddocs/detectors/ecosystems/alpm/alpm.mddocs/detectors/ecosystems/apk/README.mddocs/detectors/ecosystems/apk/apk.mddocs/detectors/ecosystems/conda/README.mddocs/detectors/ecosystems/conda/conda.mddocs/detectors/ecosystems/cpp/README.mddocs/detectors/ecosystems/dart/README.mddocs/detectors/ecosystems/dotnet/README.mddocs/detectors/ecosystems/dpkg/README.mddocs/detectors/ecosystems/dpkg/dpkg.mddocs/detectors/ecosystems/elixir/README.mddocs/detectors/ecosystems/erlang/README.mddocs/detectors/ecosystems/erlang/otp.mddocs/detectors/ecosystems/erlang/rebar.mddocs/detectors/ecosystems/github-actions/README.mddocs/detectors/ecosystems/go/README.mddocs/detectors/ecosystems/haskell/README.mddocs/detectors/ecosystems/haskell/cabal.mddocs/detectors/ecosystems/haskell/stack.mddocs/detectors/ecosystems/homebrew/README.mddocs/detectors/ecosystems/homebrew/homebrew.mddocs/detectors/ecosystems/lua/README.mddocs/detectors/ecosystems/lua/luarocks.mddocs/detectors/ecosystems/maven/README.mddocs/detectors/ecosystems/nix/README.mddocs/detectors/ecosystems/nix/nix.mddocs/detectors/ecosystems/npm/README.mddocs/detectors/ecosystems/ocaml/README.mddocs/detectors/ecosystems/ocaml/opam.mddocs/detectors/ecosystems/php/README.mddocs/detectors/ecosystems/php/pear.mddocs/detectors/ecosystems/portage/README.mddocs/detectors/ecosystems/portage/portage.mddocs/detectors/ecosystems/prolog/README.mddocs/detectors/ecosystems/prolog/swipl-pack.mddocs/detectors/ecosystems/python/README.mddocs/detectors/ecosystems/python/pdm.mddocs/detectors/ecosystems/python/setuppy.mddocs/detectors/ecosystems/r/README.mddocs/detectors/ecosystems/r/r-package.mddocs/detectors/ecosystems/rpm/README.mddocs/detectors/ecosystems/rpm/rpm.mddocs/detectors/ecosystems/ruby/README.mddocs/detectors/ecosystems/ruby/gemspec.mddocs/detectors/ecosystems/rust/README.mddocs/detectors/ecosystems/sbom/README.mddocs/detectors/ecosystems/scala/README.mddocs/detectors/ecosystems/snap/README.mddocs/detectors/ecosystems/snap/snap.mddocs/detectors/ecosystems/swift/README.mddocs/detectors/ecosystems/terraform/README.mddocs/detectors/ecosystems/terraform/terraform.mddocs/detectors/ecosystems/wordpress/README.mddocs/detectors/ecosystems/wordpress/wordpress.mddocs/detectors/elixir/mix.mddocs/detectors/github-actions/github-actions.mddocs/detectors/go/gomod.mddocs/detectors/maven/gradle.mddocs/detectors/maven/maven.mddocs/detectors/npm/bun.mddocs/detectors/npm/npm.mddocs/detectors/npm/pnpm.mddocs/detectors/npm/yarn.mddocs/detectors/php/composer.mddocs/detectors/python/pip.mddocs/detectors/python/pipenv.mddocs/detectors/python/poetry.mddocs/detectors/python/uv.mddocs/detectors/ruby/bundler.mddocs/detectors/rust/cargo.mddocs/detectors/sbom/sbom.mddocs/detectors/scala/sbt.mddocs/detectors/swift/cocoapods.mddocs/detectors/swift/swiftpm.mddocs/detectors/syft.mddocs/manifest.jsoninternal/support/component_docs.gointernal/support/generate_test.gointernal/support/prose/README.mdinternal/support/prose/detectors/gradle.mdinternal/support/prose/detectors/maven.mdinternal/support/prose/detectors/npm.mdinternal/support/prose/detectors/pip.mdinternal/support/prose/detectors/pipenv.mdinternal/support/prose/detectors/pnpm.mdinternal/support/prose/detectors/poetry.mdinternal/support/prose/detectors/syft.mdinternal/support/prose/detectors/uv.mdinternal/support/prose/detectors/yarn.md
💤 Files with no reviewable changes (56)
- docs/detectors/ecosystems/erlang/rebar.md
- docs/detectors/ecosystems/elixir/README.md
- docs/detectors/ecosystems/prolog/README.md
- docs/detectors/ecosystems/apk/apk.md
- docs/detectors/ecosystems/alpm/alpm.md
- docs/detectors/ecosystems/terraform/README.md
- docs/detectors/ecosystems/maven/README.md
- docs/detectors/ecosystems/ruby/README.md
- docs/detectors/ecosystems/dpkg/dpkg.md
- docs/detectors/ecosystems/ocaml/opam.md
- docs/detectors/ecosystems/erlang/README.md
- docs/detectors/ecosystems/python/README.md
- docs/detectors/ecosystems/r/r-package.md
- docs/detectors/ecosystems/dotnet/README.md
- docs/detectors/ecosystems/README.md
- docs/detectors/ecosystems/php/README.md
- docs/detectors/ecosystems/python/pdm.md
- docs/detectors/ecosystems/wordpress/README.md
- docs/detectors/ecosystems/wordpress/wordpress.md
- docs/detectors/ecosystems/nix/nix.md
- docs/detectors/ecosystems/npm/README.md
- docs/detectors/ecosystems/cpp/README.md
- docs/detectors/ecosystems/github-actions/README.md
- docs/detectors/ecosystems/homebrew/README.md
- docs/detectors/ecosystems/python/setuppy.md
- docs/detectors/ecosystems/sbom/README.md
- docs/detectors/ecosystems/rpm/README.md
- docs/detectors/ecosystems/haskell/stack.md
- docs/detectors/ecosystems/snap/README.md
- docs/detectors/ecosystems/dart/README.md
- docs/detectors/ecosystems/snap/snap.md
- docs/detectors/ecosystems/nix/README.md
- docs/detectors/ecosystems/lua/README.md
- docs/detectors/ecosystems/homebrew/homebrew.md
- docs/detectors/ecosystems/conda/README.md
- docs/detectors/ecosystems/apk/README.md
- docs/detectors/ecosystems/rpm/rpm.md
- docs/detectors/ecosystems/lua/luarocks.md
- docs/detectors/ecosystems/ocaml/README.md
- docs/detectors/ecosystems/haskell/cabal.md
- docs/detectors/ecosystems/ruby/gemspec.md
- docs/detectors/ecosystems/alpm/README.md
- docs/detectors/ecosystems/terraform/terraform.md
- docs/detectors/ecosystems/dpkg/README.md
- docs/detectors/ecosystems/rust/README.md
- docs/detectors/ecosystems/scala/README.md
- docs/detectors/ecosystems/r/README.md
- docs/detectors/ecosystems/prolog/swipl-pack.md
- docs/detectors/ecosystems/swift/README.md
- docs/detectors/ecosystems/go/README.md
- docs/detectors/ecosystems/portage/README.md
- docs/detectors/ecosystems/conda/conda.md
- docs/detectors/ecosystems/portage/portage.md
- docs/detectors/ecosystems/erlang/otp.md
- docs/detectors/ecosystems/haskell/README.md
- docs/detectors/ecosystems/php/pear.md
|
|
||
| - `internal/config/config.go` — regenerates `docs/CONFIG_REFERENCE.md` | ||
| - `sdk/catalog.go`, `sdk/support_matrix.go`, `internal/registry/support.go` — regenerates `docs/SUPPORT_MATRIX.md` and `docs/detectors/ecosystems/*.md` | ||
| - `sdk/catalog.go`, `sdk/support_matrix.go`, `internal/registry/support.go` — regenerates `docs/SUPPORT_MATRIX.md` and `docs/detectors/*.md` |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Document the recursive detector-page output path.
The generated pages now live below nested directories such as docs/detectors/maven/maven.md; docs/detectors/*.md only denotes files directly under docs/detectors. Use docs/detectors/ or an explicit recursive pattern so contributors do not miss migrated pages when regenerating documentation.
Proposed wording
-- `sdk/catalog.go`, `sdk/support_matrix.go`, `internal/registry/support.go` — regenerates `docs/SUPPORT_MATRIX.md` and `docs/detectors/*.md`
+- `sdk/catalog.go`, `sdk/support_matrix.go`, `internal/registry/support.go` — regenerates `docs/SUPPORT_MATRIX.md` and all pages under `docs/detectors/`📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - `sdk/catalog.go`, `sdk/support_matrix.go`, `internal/registry/support.go` — regenerates `docs/SUPPORT_MATRIX.md` and `docs/detectors/*.md` | |
| `sdk/catalog.go`, `sdk/support_matrix.go`, `internal/registry/support.go` — regenerates `docs/SUPPORT_MATRIX.md` and all pages under `docs/detectors/` |
🤖 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 `@CONTRIBUTING.md` at line 136, Update the documentation generation entry in
CONTRIBUTING.md to describe detector pages recursively, using docs/detectors/ or
an explicit recursive pattern instead of docs/detectors/*.md so nested paths
such as maven/maven.md are included.
| - [JSON Schemas](SCHEMAS.md) — scan, explain, diff output shapes | ||
| - [Glossary](GLOSSARY.md) — every term, one sentence each | ||
| - [Detector Ecosystem Guides](detectors/ecosystems/) — per-ecosystem detector chains | ||
| - [Detector Reference](detectors/) — per-ecosystem detector pages, plus [Syft fallback](detectors/syft.md) for everything else |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use “per-detector” wording here.
The reference now contains one page per native detector plus the Syft fallback, so “per-ecosystem detector pages” is misleading and conflicts with the terminology used in docs/DETECTORS.md.
-- [Detector Reference](detectors/) — per-ecosystem detector pages, plus [Syft fallback](detectors/syft.md) for everything else
+- [Detector Reference](detectors/) — per-detector pages, plus [Syft fallback](detectors/syft.md) for everything else📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - [Detector Reference](detectors/) — per-ecosystem detector pages, plus [Syft fallback](detectors/syft.md) for everything else | |
| - [Detector Reference](detectors/) — per-detector pages, plus [Syft fallback](detectors/syft.md) for everything else |
🤖 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/README.md` at line 51, Update the Detector Reference description in
docs/README.md to use “per-detector” wording, accurately stating that it
contains one page per native detector plus the Syft fallback. Keep the existing
links unchanged and align terminology with docs/DETECTORS.md.
| if err := os.RemoveAll(outputDir); err != nil { | ||
| return fmt.Errorf("clean %s: %w", outputDir, err) | ||
| } | ||
| if err := os.MkdirAll(outputDir, 0o755); err != nil { | ||
| return fmt.Errorf("create %s: %w", outputDir, err) | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd . docs/detectors --type f | head -100
rg -n 'regenerated by' docs/detectors --files-without-match --glob '*.md'Repository: bomly-dev/bomly-cli
Length of output: 896
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## candidate file outline"
ast-grep outline internal/support/component_docs.go --view expanded || true
echo
echo "## relevant component_docs.go section"
sed -n '480,630p' internal/support/component_docs.go
echo
echo "## docs/detectors directory tree"
fd --type f . docs/detectors | sort
echo
echo "## search for generated/generation/doc guard markers"
rg -n 'detectors|document|generated|generated-only|regenerated|wip|write' README.md CONTRIBUTING.md docs internal/support -g '!vendor' -g '!dist' -g '!build' | head -200
echo
echo "## component docs usages"
rg -n 'docs/detectors|outputDir|componentDocs|BuildComponentDocs' -g '*.go' -g '*.md' .Repository: bomly-dev/bomly-cli
Length of output: 50377
Limit the docs/detectors wipe before recreating.
writeDetectorDocs deletes every entry under docs/detectors, which removes the ecosystem-generated .md pages as well as any future hand-written files that land there. Remove only known generator artifacts such as the generated ecosystem .md pages or syft.md instead of os.RemoveAll.
🤖 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 `@internal/support/component_docs.go` around lines 586 - 591, Update
writeDetectorDocs to stop deleting the entire outputDir with os.RemoveAll.
Before recreating the directory, remove only known generated detector artifacts,
such as generated ecosystem .md pages and syft.md, while preserving hand-written
and unrelated files; retain the existing error-wrapping behavior for cleanup and
directory creation.
| 2. Run `make generate`. | ||
| 3. The new content appears at the bottom of the corresponding | ||
| `docs/detectors/ecosystems/<name>.md` or `docs/matchers/<name>.md`. | ||
| `docs/detectors/<name>.md` or `docs/matchers/<name>.md`. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Path is now inaccurate for native detectors.
Generated native pages land at docs/detectors/<ecosystem>/<name>.md; only the Syft fallback is docs/detectors/syft.md.
📝 Proposed wording
- `docs/detectors/<name>.md` or `docs/matchers/<name>.md`.
+ `docs/detectors/<ecosystem>/<name>.md` (or `docs/detectors/syft.md`
+ for the Syft fallback) or `docs/matchers/<name>.md`.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| `docs/detectors/<name>.md` or `docs/matchers/<name>.md`. | |
| `docs/detectors/<ecosystem>/<name>.md` (or `docs/detectors/syft.md` | |
| for the Syft fallback) or `docs/matchers/<name>.md`. |
🤖 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 `@internal/support/prose/README.md` at line 68, Update the documentation path
guidance near the detector and matcher examples to reflect native detector pages
under docs/detectors/<ecosystem>/<name>.md, while preserving the Syft fallback
path as docs/detectors/syft.md and the existing matcher path.
Reorganizes the docs navigation and restructures the generated detector pages.
docs/manifest.jsondrives the site nav, so this is what the landing page will pick up on the next release sync.Navigation order
Reorders
manifest.jsonso pages sit where people look for them:No slugs are added or removed, so the manifest stays in 1:1 sync with the top-level docs and
TestDocsManifestMatchesTopLevelDocspasses unchanged.Detector pages
Generated pages move from
docs/detectors/ecosystems/<eco>/<pm>.mdtodocs/detectors/<eco>/<pm>.md, and only ecosystems with a native detector get a directory. Everything reachable through Syft alone collapses into a singledocs/detectors/syft.mdinstead of 23 near-identical pages.That takes the nav from 31 ecosystem entries to 15 while keeping related managers grouped. Python is the clearest example: it now lists
pip,pipenv,poetry, anduv, withpdmandsetuppydescribed on the Syft page instead of each getting a page that says the same thing.SUPPORT_MATRIX.mdis untouched and still lists every ecosystem and package manager.Prose files keep their existing names, so no hand-written content moved — only their relative link depth changed. New hand-written prose for the Syft page lives at
internal/support/prose/detectors/syft.md.Also
INTEGRATIONS.md, pointing at https://bomly.dev/marketplace and explaining what the origin labels mean.docs/README.mdmirrors the new group order, as CONTRIBUTING requires.CONTRIBUTING.mdregenerate-triggers list updated for the new output path.Verification
make generateis clean (generated output committed),go test ./internal/support/... ./internal/registry/...passes, and every relative link and anchor across all 77 docs resolves. Three em-dash heading anchors flagged by my local checker are pre-existing onmainand pass lychee there.The landing page side is bomly-dev/bomly-landing-page#261 — it already reads both layouts and has redirects staged for the URL move, so it can merge independently and ahead of this.
🤖 Generated with Claude Code
Summary by CodeRabbit