You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #6365, which shipped the tabGroup/getPageNavTabs(group) mechanism in server/lib/navManifest.js and converted six of the fourteen pages named in the original audit: Calendar, Goals, Insights, Privacy, Messages, Wiki. This issue covers the remaining eight.
Problem
server/lib/navManifest.js still has no tabGroup for the tab sets declared by:
navManifest.test.js's TABBED_PAGES still scrapes each of these via extractConstArrayBlock/extractConstIds/extractTabPaths (kind: 'ids' for the first six, kind: 'links' for Sharing) instead of the manifest being the one registry.
Brain has a real pre-existing gap, not just a naming mismatch:constants.js declares spotify and youtube tabs (TABS array, ids spotify/youtube) with no corresponding NAV_COMMANDS entry at all — they are unreachable from ⌘K and voice ui_navigate today, contrary to the rule in root AGENTS.md ("Adding a <Route> without a NAV_COMMANDS entry leaves the page unreachable"). Converting Brain to derive TABS from getPageNavTabs('brain') requires adding nav.brain.spotify and nav.brain.youtube manifest entries first (pick paths /brain/spotify and /brain/youtube to match the existing /brain/<id> pattern), or the conversion will silently drop those two tabs from the page.
Add tabGroup: '<page>' ('brain', 'cos', 'digital-twin', 'meatspace', 'media', 'music', 'system-resources') plus tabId to each relevant NAV_COMMANDS entry. Add tabLabel for any page-local label that differs from the manifest label (the original audit's 17-differing-labels count includes at least /system-resources/queues "Queues" vs "Active Queues", /music/generate "Generate" vs "Music Designer", and /digital-twin/legacy "Legacy" vs "Legacy Bundle" — none of these are in the six already shipped).
allowBasePrefix: true pages (MediaGen, Music, SystemHealthPage) — confirm whether that flag is still needed once the manifest owns the id list; it exists in the current scraper to also allow the bare /media//music//system-resources path with no tab id. If the bare-path manifest entry already exists as a separate NAV_COMMANDS row without a tabId/tabGroup (default-tab redirect), the flag has no equivalent to carry over into getPageNavTabs and can likely be dropped — verify against the live route.
Sharing is the odd one out — SECTIONS is a list of { to/path, label, ...nested links }, not a flat { id, label } tab array like the other kind-'ids' pages, and mixes in-page tabs with cross-links (the old kind: 'links' filtering logic in navManifest.test.js already separates them). Decide the tabGroup shape needed to cover it, or carve it into its own follow-up if it doesn't fit the same getPageNavTabs contract cleanly.
Remove each migrated page's row from TABBED_PAGES in server/lib/navManifest.test.js as it converts. Once ALL eight are done, delete the now-dead extractConstArrayBlock/extractSwitchCases/extractConstIds/extractTabPathskind: 'ids'/kind: 'links' machinery and nestedIdSources, per the original [code-quality-page-tabs-from-manifest] Derive the fourteen hand-maintained page tab lists from the nav manifest #6365 acceptance criteria — TABBED_PAGES should end up listing only the POST switch page.
Same as #6365: the POST switch (tab) dispatch (kind: 'switch') and Settings.jsx's switch (activeTab) parity stay as-is; getSectionNavTabs and the App.jsx route scan are untouched.
Acceptance criteria
Brain, CoS, Digital Twin, MeatSpace, Media Gen, Music, Sharing and System Resources each derive TABS/RESOURCE_TABS/SECTIONS from getPageNavTabs(<group>) plus a local presentation map.
nav.brain.spotify and nav.brain.youtube manifest entries exist and Brain's Spotify/YouTube tabs are reachable via ⌘K/voice.
navManifest.test.js's TABBED_PAGES contains only the POST switch row; the ids/links parsers and nestedIdSources are deleted.
cd client && npm test and cd server && npx vitest run lib/navManifest.test.js pass.
Follow-up to #6365, which shipped the
tabGroup/getPageNavTabs(group)mechanism inserver/lib/navManifest.jsand converted six of the fourteen pages named in the original audit: Calendar, Goals, Insights, Privacy, Messages, Wiki. This issue covers the remaining eight.Problem
server/lib/navManifest.jsstill has notabGroupfor the tab sets declared by:client/src/components/brain/constants.js(TABS)client/src/components/cos/constants.js(TABS)client/src/components/digital-twin/constants.js(TABS)client/src/components/meatspace/constants.js(TABS)client/src/pages/MediaGen.jsx(TABS,allowBasePrefix: true)client/src/pages/Music.jsx(TABS,allowBasePrefix: true)client/src/pages/Sharing.jsx(SECTIONS,kind: 'links'— a different source shape than the rest)client/src/pages/SystemHealthPage.jsx(RESOURCE_TABS,allowBasePrefix: true)navManifest.test.js'sTABBED_PAGESstill scrapes each of these viaextractConstArrayBlock/extractConstIds/extractTabPaths(kind: 'ids'for the first six,kind: 'links'for Sharing) instead of the manifest being the one registry.Brain has a real pre-existing gap, not just a naming mismatch:
constants.jsdeclaresspotifyandyoutubetabs (TABSarray, idsspotify/youtube) with no correspondingNAV_COMMANDSentry at all — they are unreachable from ⌘K and voiceui_navigatetoday, contrary to the rule in rootAGENTS.md("Adding a<Route>without aNAV_COMMANDSentry leaves the page unreachable"). Converting Brain to deriveTABSfromgetPageNavTabs('brain')requires addingnav.brain.spotifyandnav.brain.youtubemanifest entries first (pick paths/brain/spotifyand/brain/youtubeto match the existing/brain/<id>pattern), or the conversion will silently drop those two tabs from the page.Fix
Same mechanism as #6365, applied per page:
tabGroup: '<page>'('brain','cos','digital-twin','meatspace','media','music','system-resources') plustabIdto each relevantNAV_COMMANDSentry. AddtabLabelfor any page-local label that differs from the manifestlabel(the original audit's 17-differing-labels count includes at least/system-resources/queues"Queues" vs "Active Queues",/music/generate"Generate" vs "Music Designer", and/digital-twin/legacy"Legacy" vs "Legacy Bundle" — none of these are in the six already shipped).getPageNavTabs(group)returns entries in declaration order, not alphabetical (see [code-quality-page-tabs-from-manifest] Derive the fourteen hand-maintained page tab lists from the nav manifest #6365's Messages/Wiki/Calendar reorders for the pattern).nav.brain.spotify,nav.brain.youtube) before converting Brain.fullBleed, any other page-only flag) keyed by tab id, and buildsTABSviagetPageNavTabs(group).map(...), throwing at module load if a manifest tab has no presentation entry — same shape asclient/src/pages/Wiki.jsxafter [code-quality-page-tabs-from-manifest] Derive the fourteen hand-maintained page tab lists from the nav manifest #6365.allowBasePrefix: truepages (MediaGen, Music, SystemHealthPage) — confirm whether that flag is still needed once the manifest owns the id list; it exists in the current scraper to also allow the bare/media//music//system-resourcespath with no tab id. If the bare-path manifest entry already exists as a separateNAV_COMMANDSrow without atabId/tabGroup(default-tab redirect), the flag has no equivalent to carry over intogetPageNavTabsand can likely be dropped — verify against the live route.SECTIONSis a list of{ to/path, label, ...nested links }, not a flat{ id, label }tab array like the other kind-'ids' pages, and mixes in-page tabs with cross-links (the oldkind: 'links'filtering logic innavManifest.test.jsalready separates them). Decide thetabGroupshape needed to cover it, or carve it into its own follow-up if it doesn't fit the samegetPageNavTabscontract cleanly.TABBED_PAGESinserver/lib/navManifest.test.jsas it converts. Once ALL eight are done, delete the now-deadextractConstArrayBlock/extractSwitchCases/extractConstIds/extractTabPathskind: 'ids'/kind: 'links'machinery andnestedIdSources, per the original [code-quality-page-tabs-from-manifest] Derive the fourteen hand-maintained page tab lists from the nav manifest #6365 acceptance criteria —TABBED_PAGESshould end up listing only the POSTswitchpage.client/src/pages/Wiki.test.jsx's post-[code-quality-page-tabs-from-manifest] Derive the fourteen hand-maintained page tab lists from the nav manifest #6365 shape) assertingTABSmatchesgetPageNavTabs(group)in id/label/order.Out of scope
Same as #6365: the POST
switch (tab)dispatch (kind: 'switch') andSettings.jsx'sswitch (activeTab)parity stay as-is;getSectionNavTabsand the App.jsx route scan are untouched.Acceptance criteria
TABS/RESOURCE_TABS/SECTIONSfromgetPageNavTabs(<group>)plus a local presentation map.nav.brain.spotifyandnav.brain.youtubemanifest entries exist and Brain's Spotify/YouTube tabs are reachable via ⌘K/voice.navManifest.test.js'sTABBED_PAGEScontains only the POSTswitchrow; theids/linksparsers andnestedIdSourcesare deleted.cd client && npm testandcd server && npx vitest run lib/navManifest.test.jspass.Scope: large