Skip to content

feat(ui): UIPage.Route (was Slug) + drop UIPage.Icon + WebDir static handler#104

Merged
I-am-nothing merged 2 commits into
mainfrom
feat/uipage-route-icon-drop
May 25, 2026
Merged

feat(ui): UIPage.Route (was Slug) + drop UIPage.Icon + WebDir static handler#104
I-am-nothing merged 2 commits into
mainfrom
feat/uipage-route-icon-drop

Conversation

@I-am-nothing

Copy link
Copy Markdown
Contributor

Summary

Pre-compact in-flight work. Brings UIPage's URL field in line with the catch-all page on the platform side (route-segment shape, `"/"` for index) instead of the bare slug shape, and drops the per-page Icon in favor of `Config.Icon` (one icon per module, set on the nav rail).

This PR is a dependency of #103 (PlatformAuth) — both ship at the same time so ms-app-modules consumers can pick up a coherent SDK. The two PRs touch disjoint files but oauth-core needs both.

Changes

  • Rename `UIPage.Slug` → `UIPage.Route`. Route is a full path-from-root (`"/"`, `"/users"`, `"/settings/audit"`) matching the segments the platform's `[[...page]]` catch-all sees. Validation moves to per-segment checks against the same regex.
  • Drop `UIPage.Icon`. Per-page icons aren't surfaced anywhere in the platform today; `Config.Icon` is the source of truth for the nav rail.
  • New `system.WebHandler` + `Config.WebDir`: SDK serves the module's React bundle directory at `/__mirrorstack/web/*` (CORS open) so the platform's ModuleMount can dynamic-import a stable URL. Path-traversal guarded by `EvalSymlinks` on both root and target.

Test plan

  • `go test ./...` clean except for the same pre-existing flake in `internal/refcache.TestSlowPath_SingleflightCoalesces` (passes on retry)
  • New `system/web_test.go` covers the static handler (CORS, path traversal, missing WebDir)
  • `internal/registry/ui_test.go` updated for Route validation + nested segment cases

🤖 Generated with Claude Code

…handler

Pre-compact in-flight: brings UIPage's URL field in line with the
catch-all page on the platform side (route-segment shape, "/" for
index) instead of the bare slug shape, and drops the per-page Icon
in favor of Config.Icon (one icon per module, set on the nav rail).

- Rename UIPage.Slug → UIPage.Route. Route is a full path-from-root
  ("/", "/users", "/settings/audit") matching the segments the
  platform's [[...page]] catch-all sees. Validation moves to per-
  segment checks against the same regex.
- Drop UIPage.Icon. Per-page icons aren't surfaced anywhere in the
  platform today; Config.Icon is the source of truth for the nav rail.
- New system.WebHandler + Config.WebDir: SDK serves the module's
  React bundle directory at /__mirrorstack/web/* (CORS open) so the
  platform's ModuleMount can dynamic-import a stable URL. Path-
  traversal guarded by EvalSymlinks on both root and target.

Tests updated for the rename + new web handler. Whole-repo tests
clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@I-am-nothing I-am-nothing merged commit 77beee0 into main May 25, 2026
1 check passed
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.

1 participant