Cross-Platform UI Workbench
Last updated: 2026-01-09
- Audience: Developers (intermediate)
- Scope: Overview and essential workflows for this area
- Non-scope: Deep API reference or internal design rationale
- Owner: Platform Team (confirm)
- Review cadence: Quarterly (confirm)
This repository is a library-first monorepo for building consistent UI across ChatGPT widgets and standalone React applications.
A cross-platform UI workbench for building ChatGPT-style interfaces across multiple platforms:
- ChatGPT Widgets - Embedded widgets via OpenAI Apps SDK
- React Applications - Standalone web applications using
@design-studio/ui - MCP Integration - Model Context Protocol server for ChatGPT tool integration
@design-studio/ui- Reusable UI components (chat layout, header, sidebar, primitives)@design-studio/runtime- Host adapters + mocks (window.openaiwrapper, HostProvider)@design-studio/tokens- Design tokens (CSS variables, Tailwind preset)packages/widgets- Standalone widget bundles for ChatGPTpackages/cloudflare-template- Cloudflare Workers deployment template for MCP
See docs/architecture/PACKAGE_TAXONOMY.md before moving or reclassifying
template packages, validation fixtures, or app-pointer folders.
platforms/web/apps/web- Widget Gallery for visual testing and MCP widget buildsplatforms/web/apps/storybook- Component documentation and interactive developmentplatforms/desktop/apps/desktop- Desktop shell scaffold (Tauri placeholder)platforms/mcp- MCP server for ChatGPT integration
Note: apps/ is a navigation index only; canonical app paths remain under platforms/.
- Prerequisites
- Compatibility matrix
- Quick Start
- Onboarding Command Center
- Agent UI Preparation
- Verify
- Common tasks
- Widget Gallery & Development
- Documentation
- Troubleshooting
- Rules of the road
- Apps SDK UI integration
- Foundation tokens (audit layer)
- Host adapter seam
- Library exports
- Public API surface
- Public API policy
- Storybook navigation
- Release & versioning
- Using in Other Projects
- Creating New Components
- Development Workflow
- Architecture
- Node.js 18+
- pnpm 10.28.0 (see
packageManagerinpackage.json)
- React: 19.x (required by
@design-studio/uipeerDependencies) - TypeScript: 5.9+ (workspace devDependency)
- Node.js: 18+ (runtime baseline)
- Apps SDK UI: ^0.2.1 (from
@design-studio/uidependencies)
# Install dependencies
pnpm install
# Start development
pnpm dev # Widget Gallery at http://localhost:5173
pnpm dev:web # Widget Gallery only (http://localhost:5173)
pnpm dev:storybook # Storybook only (http://localhost:6006)
# Build for production
pnpm build # Build pipeline (web packages)
pnpm build:web # Web-only build
pnpm build:widgets # Widget bundles
pnpm build:widget # Single-file widget HTML (for MCP harness)For the canonical first-week onboarding path (humans + AI coding agents), use:
Task-first routes:
- Add a token safely
- Ship/update a widget
- Test MCP integration
- Full integration path (token + widget + MCP)
Before an AI coding agent edits a protected UI surface, run the design prepare command:
astudio design prepare --surface <path> --jsonThe detailed workflow authority is docs/guides/AGENT_DESIGN_WORKFLOW.md. Keep this README as the short front door: prepare is the implementation brief, and a protected UI change is not ready until safeForAutomaticImplementation is true or the PR explains the manual/proposal decision returned by openDecisions.
JSON is the canonical machine contract. For human review or PR handoff after the JSON path is understood, the same typed payload can render derived text:
astudio design prepare --surface <path> --format brief
astudio design prepare --surface <path> --format pr-evidenceFor local repo work, use the build-backed convenience wrapper in silent mode so stdout remains parseable JSON:
pnpm --silent agent-design:prepare --surface <path>That wrapper may build local workspace packages before invoking the CLI. The read-only operation contract belongs to astudio design prepare itself once the CLI is available. Before PR handoff for protected UI changes, run the changed-surface evidence gate:
pnpm agent-design:prepare:changedFor a targeted local check, pass one or more explicit surfaces through the gate:
pnpm agent-design:prepare:changed -- --surface <path>Supporting commands such as astudio design lint, export, components, coverage, and propose-abstraction are diagnostics rather than the normal pre-edit path.
For broader command routing, see docs/architecture/COMMAND_SURFACE.md. That page groups the canonical agent-design, repo health, product-surface, and compatibility commands so this README stays a short front door.
- Widget Gallery: open http://localhost:5173/
- Storybook: open http://localhost:6006/
Core scripts you'll use frequently:
# Development
pnpm dev # Widget Gallery only
pnpm dev:web # Widget Gallery only
pnpm dev:storybook # Storybook only
pnpm dev:widgets # Widget development mode
# MCP Server
pnpm mcp:dev # MCP server in development mode
pnpm mcp:start # MCP server in production mode
# Testing
pnpm test # UI unit tests (Vitest) - Tier 1
pnpm test:agent-browser # Built-preview smoke tests - Tier 2
pnpm test:agent-browser:ci # CI smoke tests (build + serve + test) - Tier 2
pnpm storybook:test # Component tests
pnpm test:e2e:web # End-to-end tests (Playwright)
pnpm test:a11y:widgets # Accessibility tests for widgets
pnpm test:visual:web # Visual regression tests (web)
pnpm test:visual:storybook # Visual regression tests (Storybook)
pnpm test:mcp-contract # MCP tool contract tests
# Code Quality
pnpm lint # Biome
pnpm format # Biome (write)
pnpm format:check # Biome (check only)
pnpm lint:compliance # Check compliance rules
pnpm docs:lint # Vale sync + markdown linting + link check
# Building
pnpm build # Full build pipeline
pnpm build:web # Web-only build
pnpm build:widgets # Widget bundles for production
pnpm build:widget # Single-file widget HTML for MCP
pnpm build:lib # Build @astudio packages only
# Utilities
pnpm new:component # Component generator
pnpm sync:versions # Sync package versions across workspace
pnpm validate:tokens # Validate design token consistencyThe repo includes a unified CLI wrapper for common dev/build/test/MCP tasks:
pnpm astudio --help
pnpm astudio dev
pnpm astudio build web
pnpm astudio test e2e-web
pnpm astudio mcp tools list
pnpm astudio doctorThe web app (platforms/web/apps/web) is a Widget Gallery for visual testing and MCP widget builds:
- Widget Gallery: http://localhost:5173/ (default) - Browse and test all aStudio widgets in iframe previews
- Widget Harness: http://localhost:5173/harness - Test individual widgets with modal controls
- 12+ widgets including Dashboard, Chat View, Search Results, Compose, and Kitchen Sink
- Iframe-based widget isolation for accurate testing
- Built-in modal testing (Settings, Icon Picker, Discovery Settings)
- Keyboard shortcuts (
?for help,Gfor next widget)
pnpm build:widgetThis creates platforms/web/apps/web/dist/widget.html (a single-file HTML bundle used by the MCP server).
If you're building a custom application with page routing, see PAGES_QUICK_START.md for guidance on adding new pages to your application.
Use this table to jump to the canonical doc surface. For more detail, see
docs/README.md.
| Area | Doc |
|---|---|
| Project overview | README.md |
| Docs index | docs/README.md |
| Guides index | docs/guides/README.md |
| Architecture | docs/architecture/README.md |
| Repo map | docs/architecture/repo-map.md |
| Build pipeline | docs/BUILD_PIPELINE.md |
| Restructure migration | docs/guides/repo-structure-migration.md |
| Web Widget Gallery | platforms/web/apps/web/README.md |
| Storybook | platforms/web/apps/storybook/README.md |
| MCP server | platforms/mcp/README.md |
| Tokens | packages/tokens/README.md |
| UI components (React) | packages/ui/README.md |
| Runtime host | packages/runtime/README.md |
| Widgets | packages/widgets/README.md |
Cause: pnpm is not installed. Fix:
npm install -g pnpmCause: MCP server is not running or the URL is wrong. Fix:
pnpm mcp:startThen confirm the MCP URL in the aStudio app settings panel (default http://localhost:8787).
Cause: Dependencies not installed or Node version mismatch. Fix:
pnpm install
node -v-
packages/ui
β UI only (components, layouts, stories)
β Depends on@openai/apps-sdk-uifor styling
β Icons come frompackages/ui/src/icons(Apps SDK UI first, Lucide fallback)
β Nowindow.openai
β No MCP logic
β No real network calls (only via injected host)
β No directlucide-reactimports (usepackages/ui/src/iconsadapter)
β No@mui/*(warn-only for now)
β No direct@radix-ui/*imports outsidepackages/ui/src/primitives(warn-only) -
packages/runtime
β Host interface + adapters
βcreateEmbeddedHost()wrapswindow.openai
βcreateStandaloneHost()uses your API/mocks
β No UI components -
platforms/web/apps/web
β Widget Gallery for visual testing
β Builds single-file widget HTML for MCP
β Standalone host adapter implementation
β No reusable UI source -
platforms/web/apps/storybook
β Component documentation and interactive development
β Design system showcase
β No reusable UI source -
platforms/mcp
β MCP server (serves widgets and defines tool contracts)
β ChatGPT integration layer
β Not required for library usage (only for ChatGPT integration)
This repo uses Apps SDK UI as the visual system. Import the CSS in both standalone and embedded builds:
@import "tailwindcss";
@import "@openai/apps-sdk-ui/css";
@import "@design-studio/tokens/foundations.css";
/* Tailwind v4 scanning */
@source "../node_modules/@openai/apps-sdk-ui";
@source "../../packages/ui/src";See: https://developers.openai.com/apps-sdk/
@design-studio/tokens encodes the PDF "Figma foundations" as:
packages/tokens/src/foundations.css(CSS variables)packages/tokens/src/*.ts(TS exports for Storybook foundations pages)
Source PDFs live in docs/foundations/chatgpt-apps/.
These tokens are audit/extension only. Use Apps SDK UI classes/components in UI.
packages/runtime exposes a Host interface + provider, so components stay host-agnostic:
import { HostProvider, createStandaloneHost } from "@design-studio/runtime";
const host = createStandaloneHost("http://localhost:8787");For embedded ChatGPT apps, use createEmbeddedHost() which wraps window.openai.
Runtime details and widgetSessionId guidance live in packages/runtime/README.md.
The UI package re-exports chat components and UI primitives from a single entry point.
import { Button, ChatHeader, ChatSidebar } from "@design-studio/ui";For production code, prefer subpath exports for better tree-shaking:
import { Button } from "@design-studio/ui/base";
import { ModelSelector } from "@design-studio/ui/navigation";
import { ChatSidebar } from "@design-studio/ui/chat";Demo pages and sandbox utilities are exposed from a separate entry to keep the production surface clean:
import { AStudioApp, DesignSystemPage } from "@design-studio/ui/dev";Experimental or fast-evolving APIs are exposed separately:
import { ChatFullWidthTemplate } from "@design-studio/ui/experimental";| Category | Exports (examples) |
|---|---|
| Chat UI components | ChatUIRoot, ChatHeader, ChatSidebar, ChatMessages, ChatInput, ComposeView |
| UI primitives | Button, Dialog, Tabs, Tooltip, and more |
| Icons | Icons adapter, ChatGPTIcons |
| Pages | DesignSystemPage, TypographyPage, SpacingPage (via @design-studio/ui/dev) |
| Templates | ChatFullWidthTemplate, ChatTwoPaneTemplate, DashboardTemplate (experimental) |
| Utilities | useControllableState |
- Stable:
@design-studio/uiroot exports and the@design-studio/ui/app,@design-studio/ui/chat,@design-studio/ui/modals,@design-studio/ui/settings,@design-studio/ui/base,@design-studio/ui/data-display,@design-studio/ui/feedback,@design-studio/ui/forms,@design-studio/ui/layout,@design-studio/ui/navigation,@design-studio/ui/overlays,@design-studio/ui/icons, and@design-studio/ui/showcasesubpaths. - Experimental:
@design-studio/ui/experimentaland@design-studio/ui/templates(subject to breaking changes). - Dev-only:
@design-studio/ui/devis for Storybook, docs, and local harnesses (not production).
- Overview: onboarding, galleries, and page previews
- Documentation: system docs + design system
- Components: UI primitives, chat surfaces, templates, icons, integrations
This repo uses Changesets for versioning and release automation:
pnpm changeset
pnpm version-packages
pnpm releaseRun the MCP harness (optional):
pnpm mcp:startCompliance warnings (non-blocking for now):
pnpm lint:complianceSet COMPLIANCE_STRICT=1 to turn warnings into errors.
Supported consumer paths today are:
- The same pnpm workspace / monorepo, using
workspace:* - Published packages from npm or a private registry
For a consistent UI setup, use the public stylesheet entry:
@import "tailwindcss";
@import "@design-studio/ui/styles.css";Do not import internal style subpaths such as @design-studio/ui/styles/ui.css or @design-studio/ui/styles/theme.css; those are implementation details bundled into @design-studio/ui/styles.css.
If your other projects are in the same monorepo:
{
"dependencies": {
"@design-studio/ui": "workspace:*",
"@design-studio/runtime": "workspace:*",
"@design-studio/tokens": "workspace:*"
}
}Publish to npm or GitHub Packages:
pnpm build:lib
pnpm changeset
pnpm version-packages
pnpm releaseThen install normally:
pnpm add @design-studio/ui @design-studio/runtime @design-studio/tokensRaw file: installs of packages/ui or a checked-out git submodule are not a supported consumer path. Those source manifests keep workspace:* links for local monorepo development, so use either a shared workspace or published packages instead.
Optional private guidance/enforcement package:
pnpm add -D @brainwav/design-system-guidance
npx design-system-guidance init .
npx design-system-guidance check .For CI-failing mode and onboarding details, see docs/guides/PRIVATE_GUIDANCE_PACKAGE.md.
Use the component generator:
# Create a primitive component (Button, Input, etc.)
pnpm new:component MyButton primitive
# Create a chat component
pnpm new:component ChatToolbar chat
# Create a template
pnpm new:component AdminTemplate template
# Create a page
pnpm new:component SettingsPage pageThis creates the component file and a Storybook story.
π For the complete component creation workflow including planning, testing, and release, see docs/guides/COMPONENT_CREATION.md.
- Design in Storybook -
pnpm dev:storybook- Interactive component development and documentation - Test in Widget Gallery -
pnpm dev:web- Visual testing of widget bundles in isolation - Build Widgets -
pnpm build:widgets- Create production widget bundles - Test in ChatGPT -
pnpm mcp:start- Run MCP server for ChatGPT integration
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Your Projects β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β React App β ChatGPT Widget β ... β
β (Standalone) β (Embedded) β β
βββββββββ¬ββββββββ΄βββββββββ¬βββββββββ΄βββββββββββββββββββββββββ
β β
ββββββββββββββββββ
β
βββββββββΌβββββββββββββββββββ
β @design-studio/ui (React) β
β Component Library β
ββββββββββββββββββββββββββββ€
β β’ Chat Components β
β β’ UI Primitives β
β β’ Templates β
β β’ Pages β
βββββββββ¬βββββββββββββββββββ
β
βββββββββΌβββββββββββββββββββ
β @design-studio/runtime β
β (Host Abstraction) β
ββββββββββββββββββββββββββββ€
β β’ createEmbeddedHost() β
β β’ createStandaloneHost()β
β β’ HostProvider β
βββββββββ¬βββββββββββββββββββ
β
βββββββββΌβββββββββββββββββββ
β @design-studio/tokens β
β (Design Tokens) β
ββββββββββββββββββββββββββββ€
β β’ CSS Variables β
β β’ Tailwind Preset β
β β’ Theme Configuration β
ββββββββββββββββββββββββββββ
The repository supports React implementations across web, widgets, and Tauri shells:
- React: Uses
@design-studio/ui,@design-studio/runtime, and@design-studio/tokens - Design Parity: All surfaces share the same design tokens and visual language from Apps SDK UI
brAInwav
from demo to duty
Official installation instructions are maintained in this repository only.
Third-party indexes or mirrors may list this project, but they are not affiliated with, endorsed by, or maintained by this project unless explicitly stated here.