[AAASM-3758] ✨ (hub): Add hub-level version/module switcher to docs landing#44
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cc1vBBiNxp9qLKQ5Gq85w8
A persistent, manifest-driven selector on every hub page: reads public/modules.json for the module list and each /<module>/versions.json for that module's versions/channels, then navigates to /<subpath>/<channel-or-tag>/. No hard-coded version strings. Modules without a versions.json (node-sdk, go-sdk) degrade to the module root; a standalone hub build with no manifests silently no-ops. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cc1vBBiNxp9qLKQ5Gq85w8
…tput Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cc1vBBiNxp9qLKQ5Gq85w8
✅ Claude Code review — APPROVE-readyCI: Scope vs AAASM-3758: matches all four ACs.
Side-effect check: no regression. The widget lives in the hub's own mdBook theme head, so it affects only hub pages — the per-module subsites (built by their own toolchains) and their restored switchers are untouched. The Validated by the agent: Ready to merge. — Claude Code |
|



Description
Adds a hub-level module + version switcher to the docs hub
(
docs.agent-assembly.com). Per-module switchers were restored in #41/#42/#43,but the hub landing itself had none — you had to open a module first to change
its version. This adds a persistent header on every hub page (rendered via
docs/theme/head.hbs, the same vanilla-JS widget-injection pattern as theexisting search / feedback / consent widgets) with a module dropdown and a
version/channel dropdown; selecting both navigates to
/<subpath>/<channel-or-tag>/.It is driven entirely by the aggregated manifests the build already produces —
no hard-coded version strings:
/modules.json— the build's own registry, now copied verbatim intopublic/by
docs/scripts/aggregate.sh; the widget reads each module'sname+subpath./<module>/versions.json— the same manifest each module's own per-versionswitcher reads. The widget handles both shapes the aggregation emits: the
mdBook
{channels[], archived[]}shape (core) and the mike array[{version,title,aliases}]shape (python-sdk).Graceful degradation (AC #4): a module with no
versions.json(node-sdk,go-sdk) is still listed and its option links to the module root; a hub builtstandalone with no aggregation has no
/modules.jsonand the widget silentlyno-ops (exactly like the Pagefind search widget above it).
The per-module switcher logic is not touched, and no release-ordering
dependency is introduced.
Type of Change
Related Issues
Documentation Checklist
cd docs && mdbook buildpasses locally with no warningsdocs/src/SUMMARY.md(N/A — header widget, not a new page)How verified
bash -n docs/scripts/aggregate.sh— syntax OK;cp $REGISTRY public/modules.jsonverify_manifest public/modules.jsongate added to the existingmanifest-presence checks.
cd docs && mdbook build— hub renders; renderedindex.htmlcontains the.aa-modswitchwidget;{{ path_to_root }}resolves correctly (ROOT=''atroot domain).
it under a Node DOM shim against a local HTTP server serving a mini aggregated
tree (real
modules.json+ core/pythonversions.json, node/go intentionallywithout one). Confirmed: module list = Core / Python SDK / Node SDK / Go SDK;
core lists
latest,pre-release, archived tags →/core/pre-release/;python lists mike versions+aliases →
/python-sdk/<v>/; node/go fall back to/node-sdk/,/go-sdk/roots.🤖 Generated with Claude Code
https://claude.ai/code/session_01Cc1vBBiNxp9qLKQ5Gq85w8