Skip to main content

Assistant UI Package

@maya/assistant-ui is the production-grade React workspace UI package for Maya applications. It packages the workspace shell, route model, composer, transcript, settings, auth, sharing, theming, and operational contracts needed to ship an assistant surface with host-owned product data. It is not a grab bag of generic UI primitives; standalone entries let hosts adopt focused parts of the same assistant workspace experience.

This file is the single documentation source for consuming the package: install shape, peer dependencies, CSS assets, public subentries, tokens, controller wiring, accessibility expectations, and performance guidance all live here.

The package is UI-only. Host applications own protocol mapping, backend calls, persistence, command runtimes, and environment-specific adapters before passing data into the public controller types.

Workspace Composition Boundary

WCP-012 names @maya/claude-workspace as the owner for Claude product defaults: built-in route descriptors, sidebar descriptors, settings and customize surfaces, transcript/tool/activity renderer descriptors, fallback surfaces, and default policy. WCP-019 adds its private package root for descriptors and the deterministic runtime builder.

React page components still live in this package until migration is complete. Claude built-in render pack exports remain deferred to post-v0 @maya/claude-workspace work. New composition work should move product ownership toward @maya/claude-workspace while keeping generic rendering, scoped tokens, primitives, and AssistantWorkspace execution inside @maya/assistant-ui.

@maya/assistant-ui must not import @maya/claude-workspace, discover render packs automatically, resolve grants, or create hidden global render state.

Scoped Render Runtime

@maya/assistant-ui/render-runtime exposes the WCP-015 foundation for executing opaque composition render handles through explicit host-provided React render packs. It is a scoped runtime factory, not a package-level registry.

Use this subentry only when the host already has a WorkspaceComposition from @maya/assistant-composition and wants to execute handles without placing React components inside the headless composition output:

import { createReactRenderRuntime } from '@maya/assistant-ui/render-runtime';
import type { ReactRenderPack } from '@maya/assistant-ui/render-runtime';

const renderRuntime = createReactRenderRuntime({
packs: [claudeRenderPack, dataLabProdRenderPack] satisfies ReactRenderPack[],
mode: 'client',
});

Render runtimes accept explicit ReactRenderPack arrays only. They do not scan packages, auto-discover modules, install code, use remote ESM, mutate global state, or register providers at import time. A host can create multiple runtime instances for multiple workspaces, tenants, or test cases, and each runtime keeps its own diagnostics, events, providers, and subscribers.

The runtime diagnostics are structured WorkspaceDiagnostic objects with origin: 'render-runtime'. Grants remain UI activation contracts; backend authorization, secrets, persistence, and network execution stay outside this package.

Install

Published consumers install from the registry:

pnpm add @maya/assistant-composition @maya/assistant-ui react react-dom

For unpublished release candidates, validate with the tarballs produced by pnpm pack:dry-run or with workspace links inside this monorepo. Switch external consumers to the registry install only after the requested package version has been published.

import '@maya/assistant-ui/styles.css';
import { AssistantWorkspace } from '@maya/assistant-ui';

Import @maya/assistant-ui/global.css only when the host wants the optional document-level reset.

Peer Dependencies

PeerRangeRequiredNotes
@maya/assistant-composition>=0.1.0 <0.2.0YesShared headless composition contract. Hosts install it explicitly so UI and modules use one ABI.
react>=18.2.0 <20YesReact 18 and React 19 are supported.
react-dom>=18.2.0 <20YesMatch the host application's React major.
mermaid^11.15.0NoOptional peer used only when transcript code blocks render Mermaid diagrams.

lucide-react is a package dependency. Host apps do not need to install it separately. @maya/assistant-ui must not bundle or redeclare @maya/assistant-composition types; public declarations import the headless contract package as the ABI owner.

CSS And Global Opt-In

Use these CSS entries deliberately:

CSS entryScopeUse
@maya/assistant-ui/styles.cssComponent-scoped under .aui-rootRequired for visible components. Includes the generated token variables and package font-face declarations. It must not reset host body, host buttons, or non-package controls.
Component CSS subentries such as @maya/assistant-ui/composer.cssComponent-scoped under .aui-rootImport for lightweight standalone components when the host does not render the full workspace. These files are generated from the same CSS partials as styles.css; they are not a second style source.
@maya/assistant-ui/tokens.cssToken-only custom propertiesImport instead of styles.css only when the host wants generated --aui-* variables without component CSS or JavaScript token data.
@maya/assistant-ui/global.cssDocument-level opt-inOptional reset layer. Import once at the application edge, not inside reusable widgets.

Wrap rendered package surfaces in .aui-root unless a component already creates the root wrapper:

import '@maya/assistant-ui/styles.css';

export function AssistantPane() {
return (
<section className="aui-root" data-theme="system" data-resolved-theme="light">
<AssistantWorkspace {...workspaceControllers} />
</section>
);
}

Subentry Import Matrix

Prefer the lightest subentry that fits the use case. Public imports are exact; private source paths are not part of the package contract.

Package pathUse whenExported symbols
@maya/assistant-uiApplication shell wants the main public surface.AssistantSharedChatPage, AssistantSharedChatPageProps, AssistantUiAuthLabels, AssistantUiComposerLabels, AssistantUiLocalization, AssistantUiLocalizationLabels, AssistantUiMessageLabels, AssistantUiRouteListLabels, AssistantUiSettingsLabels, AssistantUiSharedChatLabels, AssistantUiTextDirection, AssistantUiTranscriptLabels, AssistantUiTranslateValue, AssistantUiTranslateValues, AssistantUiWorkspaceLabels, AssistantWorkspace, AssistantWorkspaceArtifactsController, AssistantWorkspaceChatController, AssistantWorkspaceCompositionInput, AssistantWorkspaceDirectoryController, AssistantWorkspaceGroupedInput, AssistantWorkspaceGroupedProps, AssistantWorkspaceInput, AssistantWorkspaceProjectsController, AssistantWorkspaceSettingsController, AssistantWorkspaceShellController, AuthEntry, AuthEntryProps, WorkspaceShellStatus, WorkspaceShellStatusLevel
@maya/assistant-ui/authRender the auth entry screen.AssistantUiAuthLabels, AssistantUiLocalization, AssistantUiLocalizationLabels, AssistantUiTextDirection, AssistantUiTranslateValue, AssistantUiTranslateValues, AuthEntry, AuthEntryProps
@maya/assistant-ui/workspaceRender the workspace shell or type grouped workspace controllers and composition input.AssistantUiAuthLabels, AssistantUiComposerLabels, AssistantUiLocalization, AssistantUiLocalizationLabels, AssistantUiMessageLabels, AssistantUiRouteListLabels, AssistantUiSettingsLabels, AssistantUiSharedChatLabels, AssistantUiTextDirection, AssistantUiTranscriptLabels, AssistantUiTranslateValue, AssistantUiTranslateValues, AssistantUiWorkspaceLabels, AssistantWorkspace, AssistantWorkspaceArtifactsController, AssistantWorkspaceChatController, AssistantWorkspaceCompositionInput, AssistantWorkspaceDirectoryController, AssistantWorkspaceGroupedInput, AssistantWorkspaceGroupedProps, AssistantWorkspaceInput, AssistantWorkspaceProjectsController, AssistantWorkspaceSettingsController, AssistantWorkspaceShellController, MaybePromise, Nullable, WorkspaceAccountSession, WorkspaceActivity, WorkspaceActivityAction, WorkspaceArtifactPreview, WorkspaceArtifactUpdateInput, WorkspaceArtifactVersion, WorkspaceAttachment, WorkspaceAttachmentEncoding, WorkspaceAttachmentUpload, WorkspaceCapabilities, WorkspaceChatPrivacySnapshot, WorkspaceCitation, WorkspaceCitationSource, WorkspaceCodeBranch, WorkspaceCodeRepository, WorkspaceCompletionReason, WorkspaceConnector, WorkspaceConnectorCreateInput, WorkspaceDataExportReceipt, WorkspaceInteraction, WorkspaceListItem, WorkspaceMessage, WorkspaceMessageErrorCode, WorkspaceMessageVersion, WorkspaceModel, WorkspacePlugin, WorkspacePluginCreateInput, WorkspaceProjectAccess, WorkspaceProjectAccessEntity, WorkspaceProjectAccessEntityKind, WorkspaceProjectCreateInput, WorkspaceProjectCustomConnectorCreateInput, WorkspaceProjectDirectoryCard, WorkspaceProjectDirectoryCardsBySection, WorkspaceProjectDirectoryConnectorCreateInput, WorkspaceProjectDirectorySection, WorkspaceProjectKnowledge, WorkspaceProjectKnowledgeCreateInput, WorkspaceProjectKnowledgeStats, WorkspaceProjectSortMode, WorkspaceProjectSyncSource, WorkspaceProjectSyncSourceType, WorkspaceProjectUpdateInput, WorkspaceSettingsActionId, WorkspaceSettingsActionReceipt, WorkspaceSettingsSection, WorkspaceSettingsSummary, WorkspaceSettingsUpdateInput, WorkspaceSharedChat, WorkspaceShellStatus, WorkspaceShellStatusLevel, WorkspaceSkill, WorkspaceSkillCreateInput, WorkspaceToolCall, WorkspaceToolResult, WorkspaceUsageNotice
@maya/assistant-ui/routesBuild workspace links, labels, route guards, and sidebar behavior outside the full workspace.WorkspaceCustomizeView, WorkspaceRoute, WorkspaceRouteCapabilities, WorkspaceRouteCapabilityKey, WorkspaceRouteMeta, WorkspaceSettingsRouteSection, WorkspaceSidebarPolicyContext, WorkspaceSidebarPreference, WorkspaceSidebarResolutionInput, WorkspaceSidebarSection, workspaceCustomizeViewFromPath, workspaceCustomizeViews, workspaceDesktopSidebarMinWidth, workspaceHasSettingsSectionLocation, workspaceHrefForCustomizeView, workspaceHrefForRoute, workspaceLabelForCustomizeView, workspaceLabelForRoute, workspaceMobileSidebarMaxWidth, workspaceMobileSidebarMediaQuery, workspacePrimaryRoutes, workspaceProductRoutes, workspaceResolveSidebarOpen, workspaceRouteEnabledByCapabilities, workspaceRouteFromPath, workspaceRouteMeta, workspaceRoutesForSidebarSection, workspaceSettingsPathForSection, workspaceSettingsRouteFromLocation, workspaceSettingsSectionFromLocation, workspaceSettingsSectionHashes, workspaceSettingsSectionRoutes, workspaceShouldCollapseSidebar, workspaceShouldForceClosedSidebar, workspaceSidebarCanPersistPreference, workspaceSidebarDefaultOpen, workspaceSidebarPreferenceFromBoolean, workspaceSidebarPreferenceStorageKey, workspaceSidebarPreferenceToBoolean
@maya/assistant-ui/shareRender a shared-chat page or type shared-chat data.AssistantSharedChatPage, AssistantSharedChatPageProps, AssistantUiLocalization, AssistantUiLocalizationLabels, AssistantUiMessageLabels, AssistantUiSharedChatLabels, AssistantUiTextDirection, AssistantUiTranslateValue, AssistantUiTranslateValues, WorkspaceMessage, WorkspaceSharedChat
@maya/assistant-ui/tokensRead JavaScript token data or a generated token manifest.AssistantUiColorTheme, AssistantUiTokenCategory, AssistantUiTokenManifestEntry, AssistantUiTokenMetadata, AssistantUiTokenVisibility, AssistantUiTokens, assistantUiColorThemes, tokenManifest, tokenMetadata, tokens
@maya/assistant-ui/composerUse the standalone message composer.AssistantUiComposerLabels, AssistantUiLocalization, AssistantUiLocalizationLabels, AssistantUiTextDirection, AssistantUiTranslateValue, AssistantUiTranslateValues, Composer, ComposerProps
@maya/assistant-ui/transcriptUse the standalone transcript renderer.AssistantUiLocalization, AssistantUiLocalizationLabels, AssistantUiMessageLabels, AssistantUiTextDirection, AssistantUiTranscriptLabels, AssistantUiTranslateValue, AssistantUiTranslateValues, Transcript, TranscriptProps
@maya/assistant-ui/dialogUse the standalone dialog primitive.Dialog, DialogProps
@maya/assistant-ui/menuUse the standalone menu primitive.Menu, MenuProps
@maya/assistant-ui/route-listUse route list rendering without the full workspace.AssistantUiLocalization, AssistantUiLocalizationLabels, AssistantUiRouteListLabels, AssistantUiTextDirection, AssistantUiTranslateValue, AssistantUiTranslateValues, RouteList, RouteListItem, RouteListProps
@maya/assistant-ui/render-runtimeCreate scoped React render runtimes from explicit host-provided render packs.CreateReactRenderRuntimeOptions, ReactPreloadMode, ReactRenderAdmissionDecision, ReactRenderAdmissionInput, ReactRenderAdmissionPolicy, ReactRenderBlockedHandle, ReactRenderComponent, ReactRenderComponentStackSummary, ReactRenderContext, ReactRenderCoverageEventSummary, ReactRenderCoverageResult, ReactRenderDuplicateProvider, ReactRenderErrorEvent, ReactRenderErrorSummary, ReactRenderEventHandleSummary, ReactRenderEventTargetSummary, ReactRenderFallbackProps, ReactRenderFallbackReason, ReactRenderModule, ReactRenderPack, ReactRenderPreloadOverride, ReactRenderPreloadPolicy, ReactRenderPreloadProps, ReactRenderPreloadRequest, ReactRenderPreloadResult, ReactRenderProps, ReactRenderProvider, ReactRenderProviderSummary, ReactRenderResolution, ReactRenderRuntime, ReactRenderRuntimeEvent, ReactRenderRuntimeListener, ReactRenderRuntimeMode, ReactRenderRuntimeSchemaVersion, ReactRenderTarget, ReactRenderTestOptions, ReactRenderTrustTier, ReactRenderUnsupportedProvider, ReactRenderableContribution, createReactRenderRuntime
@maya/assistant-ui/settings-dialogRender settings as a packaged dialog.AssistantUiLocalization, AssistantUiLocalizationLabels, AssistantUiSettingsLabels, AssistantUiTextDirection, AssistantUiTranslateValue, AssistantUiTranslateValues, SettingsAccountSession, SettingsActionId, SettingsActionReceipt, SettingsConnector, SettingsCustomizeView, SettingsDataExportReceipt, SettingsDialog, SettingsDialogProps, SettingsModel, SettingsPlugin, SettingsSection, SettingsSkill, SettingsSummary
@maya/assistant-ui/auth.cssImport AuthEntry CSS without the full workspace stylesheet.CSS asset
@maya/assistant-ui/composer.cssImport Composer CSS without the full workspace stylesheet.CSS asset
@maya/assistant-ui/dialog.cssImport Dialog CSS without the full workspace stylesheet.CSS asset
@maya/assistant-ui/menu.cssImport Menu CSS without the full workspace stylesheet.CSS asset
@maya/assistant-ui/route-list.cssImport RouteList CSS without the full workspace stylesheet.CSS asset
@maya/assistant-ui/settings-dialog.cssImport SettingsDialog CSS without the full workspace stylesheet.CSS asset
@maya/assistant-ui/share.cssImport shared-chat page CSS without the full workspace stylesheet.CSS asset
@maya/assistant-ui/transcript.cssImport Transcript CSS without the full workspace stylesheet.CSS asset
@maya/assistant-ui/styles.cssImport component CSS.CSS asset
@maya/assistant-ui/global.cssOpt into the document-level reset.CSS asset
@maya/assistant-ui/tokens.cssImport generated CSS variables without component CSS.CSS asset
@maya/assistant-ui/package.jsonLet tooling inspect package metadata.Metadata asset

API Change Scope

The public package API includes export specifiers, exported symbols and types, CSS asset entries, public --aui-* variables, documented component states, grouped workspace controllers, public data attributes, and token manifest entries. Private source paths, Storybook fixtures, host adapters, generated reports, and .tmp artifacts are outside the package API.

The public API surface gate snapshots bundled .d.ts files and classifies declaration changes by the release levels defined in .docs/release-governance.md. Byte-only declaration changes with no modeled entry, symbol, member, or union change are patch. Adding optional view-model fields, exported symbols, subentries, or union literals is minor; adding required fields, removing exports, narrowing unions, or changing existing member signatures is major unless a deprecation path is already documented. When multiple API classifiers report changes, the package release level is the highest reported level.

Production Readiness / Adoption Playbook

Use the package as a React workspace component kit: start from the complete workspace when the host is shipping a Maya-style assistant surface, then reach for standalone subentries only when embedding a deliberate slice of that product experience.

Adoption modeUseProduction checks
Full assistant workspaceRender AssistantWorkspace with grouped controllers for a complete assistant shell.Import styles.css, mount under .aui-root, wire route and sidebar state, preserve message and project ids, and run workspace Storybook coverage.
Focused assistant surfaceRender Composer, Transcript, route lists, dialogs, or settings screens inside an existing host shell.Pair each JS subentry with its CSS asset when styles.css is not already present, keep callbacks stable, and verify keyboard paths plus loading, empty, error, and long-content states.
Shared or signed-out surfaceRender AssistantSharedChatPage or AuthEntry without the full workspace shell.Pass sanitized view models, keep host auth and sharing rules outside the package, and verify mobile, zoom, theme, and high-contrast states.
Token or route integrationConsume @maya/assistant-ui/tokens or @maya/assistant-ui/routes for host-side tooling.Use public --aui-* tokens and route helpers only; do not copy package internals into host docs or source trees.

Before adopting in a product release, confirm these items:

  • The host owns data loading, protocol mapping, persistence, command execution, auth, and environment adapters.
  • The assistant UI is mounted inside one theme scope with data-theme and data-resolved-theme set by the host.
  • Optional Mermaid support is installed only for transcript diagram rendering.
  • Storybook product states, package build, public API surface gate, docs/API parity gate, consumer smoke, and application typecheck pass for the release branch.
  • Host-specific notes link back to this guide instead of copying the install matrix, export matrix, token policy, or release rules.

Storybook Product Documentation

Storybook is the package's product documentation and verification surface for visible states. It is not a second install guide or API matrix. The canonical package consumption guide remains this file, while Storybook shows how the public components behave across states, themes, keyboard paths, and host-owned data.

The Storybook coverage matrix is machine-readable in projects/claude-ui/stories/storyMetadata.ts and is checked by pnpm verify:ui-stories. Every public package entry maps to a story contract:

Public surfaceStorybook responsibility
Components such as Composer, Transcript, Dialog, Menu, RouteList, SettingsDialog, AuthEntry, and AssistantSharedChatPageShow default, empty, loading, error, long-content, disabled, mobile, theme, and interaction states where they apply.
AssistantWorkspaceShow grouped-controller compositions for route, shell, project, settings, artifact, long-list, contrast, and reduced-motion states.
@maya/assistant-ui/routesShow route labels and href helpers without exposing private route tables.
@maya/assistant-ui/tokensRender the token catalog and theme axes from tokenManifest, with motion and forced-colors listed as style behavior contracts.
CSS entriesExplain scoped component CSS, generated token CSS, and global opt-in CSS behavior.

Storybook stories can use controls, play checks, visual scenarios, axe checks, and render budgets. Long-form installation, peer dependency, controller ownership, and package governance text should stay here so there is not a second prose source to keep in sync.

Component Lifecycle

Every public Storybook surface has machine-readable lifecycle metadata in projects/claude-ui/stories/storyMetadata.ts: status, introducedIn, releaseImpact, replacement, deprecatedSince, and removalTarget.

StatusMeaning
previewAvailable for feedback but not allowed in the stable public export map.
stablePart of the public component-library contract.
deprecatedStill shipped, but has a documented replacement, deprecation version, and removal target.
removedNo longer shipped; kept only in release history and migration notes.
internal-contractUsed by package tooling or docs and not exported as public component API.

Public component changes follow the release levels in .docs/release-governance.md. Value-only visual tuning that preserves semantics is patch; adding public props, states, subentries, or token hooks is minor; removing or repurposing public props, DOM landmarks, keyboard behavior, data attributes, CSS variables, or documented states is major. Deprecations require a reason, replacement, migration path, and target removal version before the old surface can be removed.

Grouped Controllers

AssistantWorkspace receives AssistantWorkspaceGroupedProps for grouped-controller rendering. The controller groups remain the host-owned data and callback contract:

import type { AssistantWorkspaceGroupedProps } from '@maya/assistant-ui/workspace';
import { AssistantWorkspace } from '@maya/assistant-ui/workspace';

export function WorkspaceHost(props: AssistantWorkspaceGroupedProps) {
return <AssistantWorkspace {...props} />;
}

Controller ownership is split by domain:

ControllerOwns
AssistantWorkspaceShellControllerCurrent route, navigation, sidebar, viewport, account shell state.
AssistantWorkspaceChatControllerMessages, composer state, attachments, model choice, send and stream callbacks.
AssistantWorkspaceProjectsControllerProject lists, project detail state, knowledge, access, sync sources, project actions.
AssistantWorkspaceSettingsControllerSettings sections, account sessions, connectors, plugins, skills, data export, privacy controls.
AssistantWorkspaceArtifactsControllerStream artifacts, artifact version state, artifact update callbacks.
AssistantWorkspaceDirectoryControllerDirectory cards, directory connector creation, route-scoped directory data.

Shell status semantics are explicit: workspaceStatus accepts WorkspaceShellStatus with WorkspaceShellStatusLevel values loading, refreshing, degraded, and unavailable; workspaceError maps to degraded when no status is supplied, and isWorkspaceLoading maps to loading only when neither status nor error is supplied. The rendered status uses role="alert" and assertive live-region behavior only for unavailable; the other levels use polite status announcements. onWorkspaceRetry receives the current WorkspaceShellStatus when the retry button is pressed.

The UI package receives view models and emits callbacks. It does not fetch, persist, read local storage for product data, or import host runtime adapters.

Composition Rendering Happy Path

AssistantWorkspace can also render a WorkspaceComposition through a scoped render runtime when the host opts into composition rendering. The host still owns controllers, module runtime resolution, permissions, persistence, and render pack construction.

  1. Host resolves modules and owns persistent controllers outside the UI package.
  2. Host calls composeWorkspace(...) from @maya/assistant-composition.
  3. Host builds explicit render packs with controller objects.
  4. Host creates createReactRenderRuntime({ packs, fallback, admissionPolicy }).
  5. Host may call renderRuntime.validateCoverage(composition) before rendering.
  6. Host renders the workspace:
import { AssistantWorkspace } from '@maya/assistant-ui/workspace';
import { createReactRenderRuntime } from '@maya/assistant-ui/render-runtime';

const renderRuntime = createReactRenderRuntime({ packs });

<AssistantWorkspace
{...groupedControllers}
activeRoutePath="/data-lab"
composition={composition}
renderRuntime={renderRuntime}
/>;

Composition rendering is explicit. The UI package does not call composeWorkspace(), create render runtimes, discover packages, install modules, resolve grants, read module runtime state, or accept a generic controllers or moduleState escape hatch. composition and renderRuntime must be provided together; invalid half-mode fallback means that if a JavaScript caller supplies only a composition object, the workspace keeps the grouped-controller route path and does not execute handles.

Assistant UI does not accept raw modules, does not use a global registry, does not create iframe plugin surfaces, does not provide a plugin marketplace, does not load remote ESM, and does not support local patching built-in pages. Hosts wire WorkspaceComposition and scoped render runtimes explicitly.

activeRouteKey and activeRoutePath are explicit selectors for composed routes. Once both composition and renderRuntime are present, the main route outlet is all-or-nothing: it renders the selected composed route through renderRuntime.render(...) or renders an explicit composition route-miss fallback. It must not silently fall back to the grouped-controller route switch. Built-in product parent routes may use their descriptor pathMatchers to keep host-owned detail state such as chat, project, or Customize subviews under the parent composed route; module routes are still selected by explicit key or static path only.

Localization And Direction

Public assistant surfaces accept an optional localization object through their props or through AssistantWorkspaceShellController.localization. The same AssistantUiLocalization and AssistantUiLocalizationLabels types are exported from the root entry and from component subentries that consume them: auth, workspace, share, composer, transcript, route-list, and settings-dialog. Leaf label types such as AssistantUiComposerLabels, AssistantUiMessageLabels, and AssistantUiSettingsLabels are exported where those labels are relevant.

localization.locale and localization.dir set the rendered lang and dir attributes for that surface and its package-owned descendants. Label overrides are shallow, domain-scoped override bags, so hosts can replace one group such as composer, message, or the stable workspace chrome/status labels without copying the default English catalog. Dynamic typed labels remain functions where stable public components need counts, filenames, artifact titles, or message roles. translate(key, fallback, values) provides the fallback hook for long-tail product-kit strings such as workspace routes, directory dialogs, project detail panels, model controls, attachment upload states, and settings rows without making every microcopy key part of the typed public ABI. values is typed as AssistantUiTranslateValues and carries named primitives such as title, count, name, noun, percent, or bytes when the package builds a dynamic fallback. formatDate and formatBytes let hosts align shared-chat metadata, project source metadata, and attachment sizes with their locale policy.

Route utility helpers such as workspaceLabelForRoute() return default English fallback labels for host-side routing and documentation tools. Localized rendered workspace navigation goes through the workspace text resolver and translate; host shells that render their own route chrome should call their own i18n layer around the route helper fallback.

Localization is a view concern only. Hosts still own translated product data, route names, project names, legal copy, auth rules, backend errors, and any content supplied through controller view models. Do not import private localization source files; use the subentry-exported types and the documented props.

Tokens And Theme

tokens/theme.ts is the package token source and publishes these JavaScript exports through @maya/assistant-ui/tokens: tokens, tokenManifest, tokenMetadata, assistantUiColorThemes, AssistantUiColorTheme, AssistantUiTokens, AssistantUiTokenManifestEntry, AssistantUiTokenMetadata, AssistantUiTokenCategory, and AssistantUiTokenVisibility.

Use public CSS variables as semantic --aui-* values. Component-private exact values may exist inside package CSS, but host themes should target public semantic variables only.

tokens contains the base light token object for ergonomic JavaScript access. Tooling that needs the full theme matrix, selector scope, changeLevel, or themeAxis should use tokenManifest.

The package also builds dist/token-manifest.json for tooling inside the published tarball. The public JavaScript entry is still @maya/assistant-ui/tokens; the JSON file mirrors the generated manifest so smoke tests and documentation gates can verify package contents.

Token Layers

Token metadata is part of the package contract. Every manifest entry includes name, cssVar, category, layer, role, usage, doNotUseFor, cssProperty, cssProperties, guidanceSource, themeAxis, changeLevel, status, introducedIn, fallback, owner, path, public, visibility, selector, theme, and value fields.

LayerVisibilityUse
semanticPublicApp-wide semantic roles such as canvas, surface, text, border, focus, primary action, status, code, radius, font, and elevation.
componentPublic but scoped by roleStable component-region tokens such as sidebar colors. These are public only for the named component region.
themeInternal source-onlyReserved for raw appearance/color/contrast objects inside tokens/theme.ts. The published tokenManifest contains public semantic and component entries only until the gates explicitly add internal manifest support.

Public token names use --aui-* and are scoped to .aui-root or .aui-root[...] theme selectors. Host applications may override public semantic variables under their own .aui-root boundary, but should not override private selectors, private --_aui-* component variables, or alternate unscoped :root definitions.

Component CSS can keep exact private values for layout details that are not product theme API. Promote a value into tokens/theme.ts only when host applications are expected to theme it or when multiple public components need the same semantic role.

Theme attributes:

AttributeMeaning
.aui-rootScope root for package styles.
data-themeHost preference: light, dark, or system.
data-resolved-themeRuntime result after resolving system preference.
data-color-themeOptional named product color theme.
data-high-contrast-darkEnables high-contrast dark adjustments.
data-motionMotion preference such as system or reduced; this affects interaction styling, not token value generation.

Token Change Policy

Token changes apply the release levels in .docs/release-governance.md to public token API:

ChangeLevel
Value tuning for an existing public token without changing its semantic rolepatch
Adding a new public semantic or component tokenminor
Removing, renaming, or repurposing a public token rolemajor
Marking a token as deprecated while keeping its value and documenting a replacementminor

Initial public tokens are normally marked minor because they create stable theme API. A small source allowlist may mark foundational reset/default tokens as patch when the token exists only to expose an already-shipped CSS fallback such as the default font or accent text value. Later value tuning for an existing public token is patch; adding a new public semantic or component token is minor; removing, renaming, or repurposing a public token is major.

changeLevel describes the expected release impact for the current token entry. themeAxis identifies whether a value belongs to base variables, appearance, color theme, or contrast. doNotUseFor is required so consumers do not turn a narrow semantic token into a broad brand or layout escape hatch.

Required gates verify explicit public token approval, release-impact classification, color-theme domain parity, tokens.css, styles.css, token-manifest.json, Storybook token catalog stories, and this documentation against src/tokens/theme.ts.

SSR, Vite, And Next

Vite consumers can import CSS in the application entry and import components from the exact subentry they render.

Next.js App Router consumers should render interactive components from a client component boundary:

'use client';

import '@maya/assistant-ui/styles.css';
import { Composer } from '@maya/assistant-ui/composer';

Server-rendered shells can pass serialized view models into client components. Keep backend payload mapping outside the UI package boundary and pass camelCase view models into the controllers.

For optional Mermaid rendering, install mermaid only in applications that render diagram blocks. Lightweight imports such as @maya/assistant-ui/composer, @maya/assistant-ui/dialog, @maya/assistant-ui/menu, and @maya/assistant-ui/route-list must not eagerly load workspace surfaces or Mermaid.

A11y Contract

The package components are expected to provide accessible structure and keyboard behavior:

AreaPackage responsibilityHost responsibility
DialogLabel wiring, focus trap, initial focus, Escape close, focus restore, and background inert behavior.Provide meaningful titles and close callbacks.
MenuRoving keyboard navigation, focus-visible behavior, Escape close, and stable item roles.Supply item labels and disabled state truthfully.
ComposerProper upload progress/live regions and submit state.Announce host-side failures through controller state.
TranscriptMessage semantics, copy/action labels, and code block controls.Provide message authoring state and content that is safe to render.
RouteListCurrent route indication, list semantics, and keyboard reachable items.Keep route ids and hrefs stable.
SettingsDialogSection navigation, dialog semantics, keyboard operation, and form labels.Wire callbacks to durable settings state.

Required verification covers keyboard navigation, axe checks, desktop/mobile layout, 200 percent zoom, forced colors or high contrast, and reduced motion.

Performance Guidance

Choose subentries by weight:

  • Use @maya/assistant-ui/composer, @maya/assistant-ui/dialog, @maya/assistant-ui/menu, or @maya/assistant-ui/route-list for lightweight use cases.
  • Pair lightweight JS subentries with their matching CSS subentry, such as @maya/assistant-ui/composer.css, when the host is not already importing styles.css.
  • Use @maya/assistant-ui/workspace only when the full assistant workspace is rendered.
  • Install mermaid only for transcript diagram rendering.
  • Keep long message lists and large route/project lists stable by preserving ids and callback references.
  • Batch streaming message updates in the host runtime before passing message arrays into Transcript or AssistantWorkspace.
  • Keep tokens and CSS imported once at the application edge.

Bundle and render budgets are enforced outside the package docs. Performance reports are temporary build artifacts and are not committed documentation sources.

Migration

For source-path consumers migrating to the package boundary:

  1. Replace source-path imports with package subentries from the matrix above.
  2. Move protocol or backend payload conversion into the host application boundary.
  3. Create grouped controller objects and pass AssistantWorkspaceGroupedProps into AssistantWorkspace.
  4. Import styles.css for the full component stylesheet, a matching component CSS subentry for lightweight standalone components, tokens.css only for token-only consumers, and global.css only at the application edge.
  5. Update route, token, composer, transcript, dialog, menu, route-list, settings, and share imports to exact subentries.
  6. Run the package build, public API surface gate, docs/API parity gate, tools/verify-agent-capability-map.mjs, consumer smoke, and application typecheck before release.

Documentation Source

Canonical package consumption docs stay in .docs/packages/assistant-ui.md. Package-root README copies, generated dist docs, and copied package docs are intentionally not published so consumers and maintainers have no duplicate docs and do not have two documentation truths.