Skip to content

feat(website): host A2UI playground at /a2ui#2533

Merged
Huxpro merged 1 commit into
lynx-family:mainfrom
Huxpro:Huxpro/host-a2ui-playground
May 3, 2026
Merged

feat(website): host A2UI playground at /a2ui#2533
Huxpro merged 1 commit into
lynx-family:mainfrom
Huxpro:Huxpro/host-a2ui-playground

Conversation

@Huxpro
Copy link
Copy Markdown
Collaborator

@Huxpro Huxpro commented Apr 28, 2026

Summary

Host the A2UI playground as a standalone SPA at lynx-stack.dev/a2ui, following the same pattern as the REPL playground at lynx-stack.dev/repl.

  • Add ASSET_PREFIX support to rsbuild config and set copyOnBuild: true for the www/ public dir so the Lynx bundle is included in the production build output
  • Fix URL construction to be base-path aware: use new URL() instead of origin string concatenation, and make DEFAULT_DEMO_URL relative (./main.web.js instead of /main.web.js)
  • Add "A2UI" nav link to the website navbar
  • Add CI workflow steps to build dependencies, Lynx bundle, and the playground SPA, then copy to doc_build/a2ui/

Test plan

  • Verify ASSET_PREFIX=/a2ui/ pnpm --filter a2ui-playground build produces correct asset paths in HTML
  • Verify main.web.js is present in dist/ (from copyOnBuild: true)
  • Verify the deployed site at lynx-stack.dev/a2ui loads correctly after CI completes
  • Verify the "A2UI" nav link appears in the website header

Summary by CodeRabbit

  • New Features

    • A2UI Playground is now integrated into the documentation website
    • Added A2UI navigation menu item for convenient access
  • Infrastructure

    • Updated build process to properly handle playground assets and serve them within the documentation site

Copilot AI review requested due to automatic review settings April 28, 2026 10:38
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 28, 2026

⚠️ No Changeset found

Latest commit: d43a28a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

📝 Walkthrough

Walkthrough

This PR integrates the A2UI Playground build output into the website deployment pipeline by establishing asset prefixing, adjusting URL resolution from absolute to relative paths, and extending website navigation. The workflow builds A2UI dependencies and the playground with computed asset prefixes, then copies the dist output into the website build directory.

Changes

A2UI Playground Integration

Layer / File(s) Summary
Asset & URL Resolution Configuration
packages/genui/a2ui-playground/rsbuild.config.ts, packages/genui/a2ui-playground/src/utils/demoUrl.ts
Rsbuild now reads ASSET_PREFIX from environment; DEFAULT_DEMO_URL changes from absolute path /main.web.js to relative ./main.web.js.
URL Generation Logic
packages/genui/a2ui-playground/src/utils/renderUrl.ts
buildRenderUrl signature changes from baseOrigin to baseUrl parameter; URL construction now uses new URL('render.html', baseUrl) with query parameters set via searchParams.
Page Component Integration
packages/genui/a2ui-playground/src/pages/DemosPage.tsx
Compute baseUrl from window.location.href with hash stripped; pass baseUrl to buildRenderUrl and update render URL construction from /render.html to render.html; update hook dependency from origin to baseUrl.
Website Navigation
website/rspress.config.ts
Add top-level A2UI navigation item routing to /a2ui.
CI/CD Build & Deployment
.github/workflows/workflow-website.yml
Build A2UI dependencies, Lynx bundle, and Playground with computed ASSET_PREFIX from Pages base path; copy dist output into website/doc_build/a2ui.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

platform:Web

Suggested reviewers

  • Sherry-hue
  • colinaaa

Poem

🐰 A2UI hops into the site so bright,
With asset paths that point just right,
From baseOrigin to baseUrl's grace,
The playground finds its proper place!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main objective: hosting the A2UI playground at the /a2ui path on the website, which aligns with all changes across the workflow, configs, and page updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: Turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get your free trial and get 200 agent minutes per Slack user (a $50 value).


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread .github/workflows/workflow-website.yml Dismissed
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/genui/a2ui-playground/src/pages/Dynamic.tsx (1)

83-90: ⚠️ Potential issue | 🔴 Critical

Custom mode still uses origin, breaking /a2ui URL resolution.
Preset mode uses baseUrl, but custom mode still passes origin, so it can generate the wrong render.html path in subpath deployments.

🔧 Proposed fix
     const url = buildRenderUrl(
       {
         protocol,
         demoUrl,
         messages: parsed,
       },
-      origin,
+      baseUrl,
     );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/genui/a2ui-playground/src/pages/Dynamic.tsx` around lines 83 - 90,
The custom mode is incorrectly passing origin into buildRenderUrl which breaks
subpath deployments; in the URL construction where buildRenderUrl is called (the
call that currently passes { protocol, demoUrl, messages: parsed } and origin),
detect when custom mode is active and pass baseUrl (or a computed baseUrl
fallback) instead of origin so render.html resolves under the app subpath;
update the call site that references the origin variable to use baseUrl (or a
fallback to origin only if baseUrl is undefined) so both preset and custom modes
generate correct URLs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/genui/a2ui-playground/src/pages/Dynamic.tsx`:
- Around line 83-90: The custom mode is incorrectly passing origin into
buildRenderUrl which breaks subpath deployments; in the URL construction where
buildRenderUrl is called (the call that currently passes { protocol, demoUrl,
messages: parsed } and origin), detect when custom mode is active and pass
baseUrl (or a computed baseUrl fallback) instead of origin so render.html
resolves under the app subpath; update the call site that references the origin
variable to use baseUrl (or a fallback to origin only if baseUrl is undefined)
so both preset and custom modes generate correct URLs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a73940c3-55c2-4459-a30d-e44ca46a6f10

📥 Commits

Reviewing files that changed from the base of the PR and between e15852f and 73f8b8d.

📒 Files selected for processing (8)
  • .github/workflows/workflow-website.yml
  • packages/genui/a2ui-playground/rsbuild.config.ts
  • packages/genui/a2ui-playground/src/pages/DemosPage.tsx
  • packages/genui/a2ui-playground/src/pages/Dynamic.tsx
  • packages/genui/a2ui-playground/src/pages/Static.tsx
  • packages/genui/a2ui-playground/src/utils/demoUrl.ts
  • packages/genui/a2ui-playground/src/utils/renderUrl.ts
  • website/rspress.config.ts

Sherry-hue
Sherry-hue previously approved these changes Apr 29, 2026
Similar to how the REPL is hosted at lynx-stack.dev/repl, this adds
the A2UI playground as a standalone SPA at lynx-stack.dev/a2ui.

Changes:
- Add ASSET_PREFIX support and copyOnBuild for the www/ public dir
- Fix URL construction to be base-path aware (use URL API instead of
  origin concatenation, relative demoUrl)
- Add "A2UI" nav link to the website
- Add CI workflow steps to build and deploy the playground
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/genui/a2ui-playground/src/pages/DemosPage.tsx`:
- Line 95: The baseUrl computed as window.location.href.replace(/#.*$/, '') can
lack a trailing slash and cause new URL('render.html', baseUrl) in
buildRenderUrl (and the usage at line 177) to resolve incorrectly; fix by
normalizing baseUrl to always end with '/' and memoize it with useMemo so you
only read window.location once per component render, then have buildRenderUrl
and the QR/iframe URL creation use this normalizedMemoized baseUrl.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 612cb420-e87b-4f86-826e-362cd3332da3

📥 Commits

Reviewing files that changed from the base of the PR and between 73f8b8d and d43a28a.

📒 Files selected for processing (5)
  • .github/workflows/workflow-website.yml
  • packages/genui/a2ui-playground/rsbuild.config.ts
  • packages/genui/a2ui-playground/src/pages/DemosPage.tsx
  • packages/genui/a2ui-playground/src/utils/demoUrl.ts
  • packages/genui/a2ui-playground/src/utils/renderUrl.ts
✅ Files skipped from review due to trivial changes (4)
  • packages/genui/a2ui-playground/src/utils/demoUrl.ts
  • packages/genui/a2ui-playground/rsbuild.config.ts
  • .github/workflows/workflow-website.yml
  • packages/genui/a2ui-playground/src/utils/renderUrl.ts

const [lynxDevCopied, setLynxDevCopied] = useState(false);

const origin = window.location.origin;
const baseUrl = window.location.href.replace(/#.*$/, '');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

baseUrl may lack a trailing slash, causing incorrect relative URL resolution.

new URL('render.html', baseUrl) (used at line 177 and inside buildRenderUrl) resolves render.html relative to the last slash in the base path. If the page is ever served at https://lynx-stack.dev/a2ui (no trailing slash), the URL API treats a2ui as a filename, strips it, and resolves to https://lynx-stack.dev/render.html instead of https://lynx-stack.dev/a2ui/render.html.

GitHub Pages typically redirects directory paths to the slash form, so this is low-probability — but it's a silent failure that produces a wrong QR code/iframe URL with no error. Pairing the fix with useMemo also avoids reading the DOM API on every render:

🛡️ Proposed fix — normalize trailing slash + memoize
-  const baseUrl = window.location.href.replace(/#.*$/, '');
+  const baseUrl = useMemo(() => {
+    // Strip hash, then ensure the path ends with a slash so that
+    // new URL('render.html', baseUrl) always resolves into the same
+    // directory rather than replacing the last path segment.
+    const stripped = window.location.href.replace(/#.*$/, '');
+    const url = new URL(stripped);
+    if (!url.pathname.endsWith('/')) {
+      url.pathname = url.pathname.replace(/\/[^/]*$/, '/');
+    }
+    return url.toString();
+  }, []);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/genui/a2ui-playground/src/pages/DemosPage.tsx` at line 95, The
baseUrl computed as window.location.href.replace(/#.*$/, '') can lack a trailing
slash and cause new URL('render.html', baseUrl) in buildRenderUrl (and the usage
at line 177) to resolve incorrectly; fix by normalizing baseUrl to always end
with '/' and memoize it with useMemo so you only read window.location once per
component render, then have buildRenderUrl and the QR/iframe URL creation use
this normalizedMemoized baseUrl.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 2, 2026

Merging this PR will improve performance by 18.85%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
✅ 79 untouched benchmarks
⏩ 26 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
008-many-use-state-destroyBackground 9.5 ms 8 ms +18.85%
transform 1000 view elements 46.8 ms 43 ms +8.83%

Comparing Huxpro:Huxpro/host-a2ui-playground (d43a28a) with main (7abb0a9)2

Open in CodSpeed

Footnotes

  1. 26 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (08aa667) during the generation of this report, so 7abb0a9 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 2, 2026

Web Explorer

#9324 Bundle Size — 900.03KiB (0%).

d43a28a(current) vs 7abb0a9 main#9309(baseline)

Bundle metrics  Change 2 changes
                 Current
#9324
     Baseline
#9309
No change  Initial JS 44.46KiB 44.46KiB
No change  Initial CSS 2.22KiB 2.22KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 9 9
No change  Assets 11 11
Change  Modules 228(-0.87%) 230
No change  Duplicate Modules 11 11
Change  Duplicate Code 27.29%(+0.04%) 27.28%
No change  Packages 10 10
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#9324
     Baseline
#9309
No change  JS 495.9KiB 495.9KiB
No change  Other 401.92KiB 401.92KiB
No change  CSS 2.22KiB 2.22KiB

Bundle analysis reportBranch Huxpro:Huxpro/host-a2ui-playgrou...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 2, 2026

React Example (Element Template)

#19 Bundle Size — 198.61KiB (0%).

d43a28a(current) vs 7abb0a9 main#4(baseline)

Bundle metrics  Change 2 changes
                 Current
#19
     Baseline
#4
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 79(-1.25%) 80
No change  Duplicate Modules 23 23
Change  Duplicate Code 40.5%(-0.44%) 40.68%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#19
     Baseline
#4
No change  IMG 145.76KiB 145.76KiB
No change  Other 52.85KiB 52.85KiB

Bundle analysis reportBranch Huxpro:Huxpro/host-a2ui-playgrou...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 2, 2026

React External

#866 Bundle Size — 680.82KiB (0%).

d43a28a(current) vs 7abb0a9 main#851(baseline)

Bundle metrics  no changes
                 Current
#866
     Baseline
#851
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 17 17
No change  Duplicate Modules 5 5
No change  Duplicate Code 8.59% 8.59%
No change  Packages 0 0
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#866
     Baseline
#851
No change  Other 680.82KiB 680.82KiB

Bundle analysis reportBranch Huxpro:Huxpro/host-a2ui-playgrou...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 2, 2026

React Example

#7751 Bundle Size — 225.52KiB (0%).

d43a28a(current) vs 7abb0a9 main#7736(baseline)

Bundle metrics  no changes
                 Current
#7751
     Baseline
#7736
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 180 180
No change  Duplicate Modules 69 69
No change  Duplicate Code 44.54% 44.54%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#7751
     Baseline
#7736
No change  IMG 145.76KiB 145.76KiB
No change  Other 79.77KiB 79.77KiB

Bundle analysis reportBranch Huxpro:Huxpro/host-a2ui-playgrou...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 2, 2026

React MTF Example

#883 Bundle Size — 196.68KiB (0%).

d43a28a(current) vs 7abb0a9 main#868(baseline)

Bundle metrics  no changes
                 Current
#883
     Baseline
#868
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 174 174
No change  Duplicate Modules 66 66
No change  Duplicate Code 44.05% 44.05%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#883
     Baseline
#868
No change  IMG 111.23KiB 111.23KiB
No change  Other 85.45KiB 85.45KiB

Bundle analysis reportBranch Huxpro:Huxpro/host-a2ui-playgrou...Project dashboard


Generated by RelativeCIDocumentationReport issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants