Skip to content

fix: resolve pinned nav rows from the bundled manifest instead of refetching it - #6437

Merged
atomantic merged 1 commit into
mainfrom
claim/issue-6362
Sep 6, 2026
Merged

fix: resolve pinned nav rows from the bundled manifest instead of refetching it#6437
atomantic merged 1 commit into
mainfrom
claim/issue-6362

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

Layout.jsx has imported NAV_COMMANDS statically since #5053, but it still fetched GET /api/palette/manifest on every mount to resolve the Pinned/Recent rows whose paths have no sidebar presentation (/wiki/log, /goals/tree, …) and every stored path that needs previousPaths migration.

Those rows rendered nothing until the request landed and then popped in — and stayed missing for the whole session whenever the request failed (network, or an expired session on a password-gated install), with only a console.warn.

Changes:

  • manifestEntryByPath is now derived from the manifest the bundle already carries, reusing the module-level commandByPath map that navRowForPath already builds from NAV_COMMANDS. The memo now depends only on isFeatureEnabled, so the feature gate is unchanged.
  • resolveNavEntry passes NAV_COMMANDS to migrateLegacyNavPath instead of the fetched copy.
  • Dropped the import * as api in Layout.jsx, whose only consumer was that fetch.

The endpoint itself is untouched — CmdKSearch.jsx and VoiceWidget.jsx still need its actions half, which only the server can hydrate from the voice tool registry, and docs/COMPANION_APP_API.md documents it for companion apps.

Test plan

  • Layout.test.jsx no longer mocks getPaletteManifest, so its nav assertions (including the existing eidoverse previousPaths case) now run against the real manifest rather than a hand-written one-entry fake.
  • New case pins /wiki/log — a manifest-only path with no sidebar leaf — and asserts the Pinned row is in the DOM on the first render, before any act() flush. Verified this fails against the pre-fix component even when the mock is widened to return the complete real manifest, so it pins the timing, not just the data.
  • cd client && npm test -- Layout → 115 passed.
  • Full client suite → 876 files, 10656 passed.
  • server/lib/navManifest.test.js + server/routes/palette.test.js unchanged → 75 passed.
  • cd client && npm run lint clean.

Closes #6362

…etching it (#6362)

Layout has imported NAV_COMMANDS statically since #5053, but it still
fetched GET /api/palette/manifest on every mount to resolve the Pinned and
Recent rows whose paths have no sidebar presentation (/wiki/log,
/goals/tree, and the previousPaths migrations). Those rows rendered nothing
until the request landed, then popped in — and stayed missing for the whole
session whenever the request failed, which a password-gated install with an
expired session hits routinely.

Derive manifestEntryByPath from the manifest the bundle already carries
(reusing the module-level commandByPath map), pass NAV_COMMANDS to
migrateLegacyNavPath, and drop the api import that existed only for the
fetch. The endpoint itself is unchanged: CmdK and the voice widget still
need the server to hydrate its actions half.

Layout.test.jsx no longer mocks getPaletteManifest, so its nav assertions
now run against the real manifest, and a new case pins /wiki/log and
asserts the row is present on the first render with no network at all.
@atomantic
atomantic merged commit 5abec41 into main Sep 6, 2026
7 checks passed
@atomantic
atomantic deleted the claim/issue-6362 branch September 6, 2026 22:14
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.

[code-quality-layout-manifest-fetch] Layout fetches the palette manifest it already imports statically

1 participant