# Plan: Sync fv-gallery-ui with fv-module-gallery repo state **Date**: 2026-07-29 **Author**: Mavis (root session, per operator directive) **Status**: PROPOSAL — operator to review and approve ## Why this plan exists The `fv-module-gallery` repo (the data source) has grown massively since the UI was last built (Jul 17). The `fv-gallery-ui` repo (the React/Vite app at gallery.freshvibeapps.com) is now showing stale data and missing widgets for the new structure. ### The mismatch (data vs UI) | Field | UI type expects (old) | Repo now has (new) | Used? | |---|---|---|---| | `tier` | `'proprietary' \| 'off-the-shelf' \| 'generic'` | `tier` not in module entries | ❌ UI expects it, repo doesn't have it | | `tags` | `string[]` | `_module_kind`-based taxonomy | ⚠️ UI uses for chrome/engine split | | `category` / `subcategory` | `string` | (removed) | ❌ | | `default_facet` / `available_facets` | `string` / `string[]` | (in facets.json per module) | ❌ | | `deprecated` | `boolean` | top-level `deprecated_modules` array | ❌ | | `_module_kind` | (missing) | `'gallery-mirror' \| 'original' \| 'borrowed' \| 'app-fork' \| 'gallery-original'` | ✅ NEW — needs widget | | `_canonical_source` | (missing) | `avidtech6//` | ✅ NEW — needs widget | | `_mirror_status` | (missing) | `'healthy' \| 'orphaned' \| 'promoted'` | ✅ NEW — needs widget | | `_last_verified` | (missing) | ISO 8601 timestamp | ✅ NEW — needs widget | | `_cleanup_threshold_days` | (missing) | `number` (30) | ✅ NEW — needs widget | | `fvw_doctrine_refs` | (missing) | `string[]` of FVW sections | ✅ NEW — needs widget | | `fvw_doctrine_version` | (missing) | `'8.3.0'` | ✅ NEW — needs widget | | `layout` | (missing) | `'top-level' \| 'top-level-submodules' \| 'bundle-local'` | ✅ NEW — needs widget | | `submodules` (in bundle) | `submodule_count: number` | full `submodules[]` array with detail | ⚠️ UI shows count, not list | | `apps` | (missing) | 4 app-pointer entries | ✅ NEW — needs new page | | `forks` | (missing) | fork list | ✅ NEW — needs section | | `module_kind_index` | (missing) | grouped by `_module_kind` | ✅ NEW — needs filter | ### The mismatch (data growth) | Item | Jul 17 (UI built) | Jul 23 (now) | |---|---|---| | Modules | 1 (ai-toast) | 29 (14 ai-bundle + 11 fvw-aligned + 4 apps) | | Bundles | 1 (ai-bundle, manifest only) | 1 (ai-bundle, 12 submodules documented) | | Apps | 0 | 4 (vibecoder, freshcards, vibescope, fvs) | | FVW version | 8.0 | 8.3.0 | | Mirror state | n/a | 5 states: healthy / orphaned / promoted / reattached / failed | ## Current UI state (what works, what doesn't) ### Pages that exist | Page | Route | What it shows | Status | |---|---|---|---| | HomePage | `/` | Hero + featured modules + featured bundles | Works but only shows 1 module | | ModulesPage | `/modules` | List of all modules | Works but uses old schema | | ModuleDetailPage | `/modules/:id` | Module detail with facets + deps + variants | Broken — looks for `tier`/`category` that don't exist | | BundlesPage | `/bundles` | List of bundles | Works | | BundleDetailPage | `/bundles/:id` | Bundle detail | Partial — shows count but not the 12 submodules list | | VariantsPage | `/variants` | Forks + mirrors | Exists but empty (no forks in registry yet) | | DocsPage | `/docs`, `/docs/fvw`, `/docs/pact` | FVW + pact docs | Works | ### Pages that DON'T exist (need to be added) | Page | Route | Why | |---|---|---| | AppsPage | `/apps` | 4 app-pointers in registry, no page to show them | | AppDetailPage | `/apps/:id` | Per-app view: modules it uses, FVW alignment, TODOs | | ForksPage | `/forks` | Fork lifecycle (per FVW v8.3 §17.7) | | DoctrinePage | `/doctrine` | Cross-link to FVW v8.3 sections (17.5, 17.6, 17.7, 17.5.7) | | MirrorStatusPage | `/mirrors` | Per-mirror-status: 25 healthy / 0 orphaned / 0 promoted | | RecipeBookPage | `/modules/:id/recipe-book` | The 10-item recipe book: 3 main + 5 provenance + 2 workflow | ### Components that need to be added | Component | Purpose | |---|---| | `ModuleKindBadge` | Color-coded badge: original (green) / borrowed (blue) / gallery-original (purple) / gallery-mirror (orange) / app-fork (red) | | `MirrorStatusIndicator` | Health dot: healthy (green) / orphaned (yellow) / promoted (red) / reattached (blue) | | `FVWComplianceBar` | Shows which FVW sections a module complies with (§11, §11.2, §11.9, §17.5.7) | | `CanonicalSourceLink` | Clickable link to the source repo (e.g. `avidtech6/oscar-platform/...`) | | `RecipeBookChecklist` | 10-item checklist (3 main + 5 provenance + 2 workflow) with file presence indicators | | `DoctrineLinkList` | List of FVW section refs as deep-links to the doctrine page | | `BundleSubmoduleList` | The 12 ai-bundle submodules with visibility badges (public/private) | | `AppCard` | Card for the new Apps page | | `AppConsumerGraph` | Visual: app → modules it uses | | `ForkCard` | Forks page entry (revibe-style) | | `ToolsList` | Tools section (if there are tools to show — TBD by operator) | ### What the operator means by "widgets and tools etc" Looking at the new state, these are the "widgets and tools" that need to exist in the UI: 1. **Module kind badges** — 5 colors, on every module card 2. **Mirror health dots** — 4 states, on every module card 3. **FVW compliance bar** — which sections each module is compliant with 4. **Canonical source link** — click-through to the source repo 5. **Recipe book completeness** — 10-item progress bar per module 6. **Bundle submodule list** — 12 submodules with public/private badges 7. **App cards** — the 4 app entries 8. **App-to-modules graph** — visual consumer graph 9. **Fork visualization** — fork tree (when forks exist) 10. **Doctrine deep-links** — FVW §11, §11.2, §11.9, §17.5, §17.5.7 11. **Last-verified timestamp** — freshness indicator 12. **Cleanup countdown** — "X days until orphan → gallery-original promotion" 13. **The 4 app-pointers as a "consumers" view** — who uses what 14. **Bundle manifest viewer** — the full JSON of `bundle-manifest.json` rendered 15. **A "Promote to gallery-original" action** — operator-only, triggers §17.6 flow ## The plan (3 phases, ~3-5 days) ### Phase 1 — Data layer (registry types + loader) [Day 1, ~4h] **Goal**: Make the UI understand the new registry schema. Files to update: - `src/types/registry.ts` — extend the type with all the new fields - `src/data/registry-loader.ts` — already loads from live + bundled, no change - `src/data/docs-loader.ts` — already loads docs, no change - `src/state/gallery-store.ts` — add new derived selectors (by_module_kind, by_mirror_status, by_consumer, etc.) Tasks: - [ ] Extend `RegistryModule` with `_module_kind`, `_canonical_source`, `_canonical_version`, `_mirror_status`, `_last_verified`, `_cleanup_threshold_days`, `fvw_doctrine_refs`, `fvw_doctrine_version`, `layout`, `feature`, `bundle`, `visibility` - [ ] Extend `RegistryBundle` with `submodules[]` (full list with per-submodule detail), `layout`, `_module_kind` - [ ] Add new top-level fields: `apps[]`, `forks[]`, `module_kind_index` - [ ] Add 5 new derived selectors in store: - `useModulesByKind(kind: ModuleKind)` — grouped by `_module_kind` - `useModulesByStatus(status: MirrorStatus)` — grouped by `_mirror_status` - `useApps()` — apps list - `useForks()` — forks list - `useConsumersForModule(id)` — apps that consume this module - [ ] Add types for `App`, `Fork`, `ModuleKind` (`'original' | 'borrowed' | 'gallery-original' | 'gallery-mirror' | 'app-fork'`), `MirrorStatus` (`'healthy' | 'orphaned' | 'promoted' | 'reattached' | 'failed'`) - [ ] Update bundled `public/registry.json` to the new shape (Jul 23 data, 25 modules) ### Phase 2 — Widgets (the "tools" the operator wants) [Day 2-3, ~10h] **Goal**: Add all the missing widgets so users can see the new structure. Files to add (in `src/components/`): - [ ] `ModuleKindBadge.tsx` + `.css` — 5 colors, icon per kind - [ ] `MirrorStatusIndicator.tsx` + `.css` — 4 states, last-verified tooltip - [ ] `FVWComplianceBar.tsx` + `.css` — horizontal bar with section tags - [ ] `CanonicalSourceLink.tsx` + `.css` — repo + path with copy-to-clipboard - [ ] `RecipeBookChecklist.tsx` + `.css` — 10-item checklist - [ ] `DoctrineLinkList.tsx` + `.css` — list of FVW refs as anchor tags - [ ] `BundleSubmoduleList.tsx` + `.css` — list with visibility badges - [ ] `AppCard.tsx` + `.css` — like ModuleCard but for apps - [ ] `AppConsumerGraph.tsx` + `.css` — SVG graph: app → module → submodule - [ ] `ForkCard.tsx` + `.css` — for the forks page - [ ] `ToolsList.tsx` + `.css` — admin tools (Promote, Reattach, etc.) - [ ] `LastVerifiedTime.tsx` + `.css` — relative time + absolute tooltip Tasks: - [ ] Wire `ModuleKindBadge` into `ModuleCard` (replaces or augments the tier badge) - [ ] Wire `MirrorStatusIndicator` into `ModuleCard` (next to the version) - [ ] Wire `FVWComplianceBar` into `ModuleDetailPage` - [ ] Wire `CanonicalSourceLink` into `ModuleDetailPage` - [ ] Wire `RecipeBookChecklist` into `ModuleDetailPage` - [ ] Wire `BundleSubmoduleList` into `BundleDetailPage` (replaces the count) - [ ] Wire `AppCard` into new `AppsPage` - [ ] Wire `AppConsumerGraph` into new `AppDetailPage` - [ ] Wire `ForkCard` into new `ForksPage` - [ ] Wire `DoctrineLinkList` into Module + Bundle + App detail pages ### Phase 3 — Pages + routing [Day 3-4, ~6h] **Goal**: Add the missing pages so the new widgets have a home. Files to add (in `src/pages/`): - [ ] `AppsPage.tsx` + `.css` — grid of 4 apps - [ ] `AppDetailPage.tsx` + `.css` — app detail with consumer graph - [ ] `ForksPage.tsx` + `.css` — fork list (empty for now, but page exists) - [ ] `DoctrinePage.tsx` + `.css` — FVW v8.3 sections table of contents - [ ] `MirrorStatusPage.tsx` + `.css` — dashboard: 25 healthy / 0 orphaned / 0 promoted - [ ] `RecipeBookPage.tsx` + `.css` — full recipe book view (3 main + 5 provenance + 2 workflow) Tasks: - [ ] Add routes in `App.tsx`: - `/apps`, `/apps/:id` - `/forks` - `/doctrine`, `/doctrine/:section` - `/mirrors` - `/modules/:id/recipe-book` - [ ] Add nav links in `AppShell.tsx`: - Apps (with badge `4`) - Doctrine (with badge `v8.3.0`) - Mirrors (with badge `25 healthy`) - Forks (only if `forks.length > 0`) - [ ] Add a "Tools" section visible only to operator (auth-gated later, visible to all for now) ### Phase 4 — Polish + deploy [Day 5, ~4h] **Goal**: Verify everything works end-to-end, deploy to VPS. Tasks: - [ ] Run `pnpm typecheck` and fix all type errors - [ ] Run `pnpm build` and verify bundle size - [ ] Update `public/registry.json` to Jul 23 state - [ ] Update `public/bundles/` with new submodules - [ ] Update `public/docs/` with FVW v8.3 - [ ] SFTP `dist/` to `/var/www/freshvibeapps/clients/gallery/` on VPS - [ ] Verify gallery.freshvibeapps.com shows 25 modules + 1 bundle + 4 apps + FVW v8.3 - [ ] Take screenshots, document in STATUS.md - [ ] Update the operator panel deploy script to include the gallery (so it's part of `git pull + rebuild`) ## Effort estimate | Phase | Hours | Notes | |---|---|---| | 1: Data layer | 4h | Mostly mechanical, extend types + selectors | | 2: Widgets | 10h | New components, need design + CSS | | 3: Pages + routing | 6h | New pages, routing, nav updates | | 4: Polish + deploy | 4h | Type check, build, deploy, verify | | **Total** | **~24h** | **~3-5 working days for 1 dev** | ## Open questions for the operator Before I start, I need to know: 1. **Tools section**: You said "tools etc" — what tools? The 5 admin actions in my list (#15 above)? Or are there specific tools in mind (a `gallery-ci` tool, a `promote-mirror` CLI, etc.)? 2. **Auth for admin tools**: The Promote/Reattach buttons need to be operator-only. Do you want a hard-coded "operator mode" flag in the URL, or actual auth (PocketBase)? 3. **App-to-modules graph**: SVG or table? SVG is prettier but more code; table is simpler. 4. **Mirror status dashboard**: A simple count is fine, or do you want a timeline (when was each verified, days since)? 5. **Doc integration**: Should the DocsPage now show FVW v8.3 sections with deep-links to the actual `.md` files? Currently it just lists file names. 6. **Live registry refresh**: Should the UI auto-refresh every X minutes, or stay cached? Currently it's `load on mount`. 7. **Mobile**: The current UI is desktop-first. With more widgets, mobile may need a separate layout. ## Next step If approved, I'll start with Phase 1 (data layer) — it's the foundation. Then Phase 2 (widgets) can be done in parallel chunks. Phase 3 (pages) wires it all up. If you want to scope this down, the highest-value widgets are: - **ModuleKindBadge** (5 colors, on every module card) — biggest visual change - **MirrorStatusIndicator** (4 states, on every module card) — most operationally useful - **BundleSubmoduleList** (replaces the count) — biggest data reveal - **AppsPage + AppCard** (4 new cards) — new section These 4 alone would make the UI feel "current". The rest can come in v2. --- **The plan is at `/workspace/PLAN-fv-gallery-ui-sync.md`. Approve + scope, and I'll start with Phase 1.**