CLAUDE.md@libs/uipack · git:20251222.dacd86a · 2025-12-22 · sha256 dc1cd8e22b0586a5

CLAUDE.md@libs/uipack git:20251222.dacd86aA

Immutable. This exact content never changes and is served at /api/v1/blob/dc1cd8e22b0586a5.

# @frontmcp/uipack - Development Guidelines

## Overview

`@frontmcp/uipack` provides **bundling, build tools, HTML components, and platform adapters** for MCP UI development - all without requiring React.

This is the React-free core package. For React components and hooks, use `@frontmcp/ui`.

**Key Principles:**

- Zero React dependency
- Pure HTML string generation
- Zod schema validation for all component inputs
- Platform-aware theming and CDN configuration
- HTMX support for dynamic interactions

## Architecture

```text
libs/uipack/src/
├── adapters/           # Platform adapters (OpenAI, Claude, etc.)
├── base-template/      # Default HTML wrappers with polyfills
├── bridge/             # Multi-platform MCP bridge
├── build/              # Build-time API (buildToolUI, etc.)
├── bundler/            # esbuild/SWC bundling
├── components/         # HTML string components (button, card, etc.)
├── dependency/         # CDN resolution and import maps
├── handlebars/         # Handlebars template engine
├── layouts/            # Page layout templates
├── pages/              # Pre-built pages (consent, error)
├── registry/           # Tool UI registry
├── renderers/          # HTML/MDX renderers
├── runtime/            # Runtime utilities (template helpers)
├── styles/             # Style variant definitions
├── theme/              # Theme system and CDN config
├── tool-template/      # Tool template utilities
├── types/              # TypeScript type definitions
├── typings/            # .d.ts type fetching
├── utils/              # Utilities (escapeHtml, safeStringify)
├── validation/         # Zod validation utilities
├── web-components/     # Custom HTML elements
├── widgets/            # OpenAI widget utilities
└── index.ts            # Main barrel exports
```

## Package Split

| Package            | Purpose                                                   | React Required |
| ------------------ | --------------------------------------------------------- | -------------- |
| `@frontmcp/uipack` | Bundling, build tools, HTML components, platform adapters | No             |
| `@frontmcp/ui`     | React components, hooks, SSR rendering                    | Yes            |

## Entry Points

| Path                              | Purpose                               |
| --------------------------------- | ------------------------------------- |
| `@frontmcp/uipack`                | Main exports                          |
| `@frontmcp/uipack/adapters`       | Platform adapters and meta builders   |
| `@frontmcp/uipack/base-template`  | Default HTML templates with polyfills |
| `@frontmcp/uipack/bridge`         | MCP bridge for multiple platforms     |
| `@frontmcp/uipack/build`          | Build-time API                        |
| `@frontmcp/uipack/bundler`        | esbuild/SWC bundling                  |
| `@frontmcp/uipack/components`     | HTML string components                |
| `@frontmcp/uipack/dependency`     | CDN resolution                        |
| `@frontmcp/uipack/handlebars`     | Handlebars integration                |
| `@frontmcp/uipack/layouts`        | Page layouts                          |
| `@frontmcp/uipack/pages`          | Pre-built pages                       |
| `@frontmcp/uipack/registry`       | Tool UI registry                      |
| `@frontmcp/uipack/renderers`      | HTML/MDX renderers                    |
| `@frontmcp/uipack/runtime`        | Runtime utilities                     |
| `@frontmcp/uipack/styles`         | Style variants                        |
| `@frontmcp/uipack/theme`          | Theme system                          |
| `@frontmcp/uipack/types`          | Type definitions                      |
| `@frontmcp/uipack/utils`          | Utilities                             |
| `@frontmcp/uipack/validation`     | Zod validation                        |
| `@frontmcp/uipack/web-components` | Custom elements                       |
| `@frontmcp/uipack/widgets`        | OpenAI widgets                        |

## Component Development

### 1. Create Schema First

Every component must have a Zod schema with `.strict()` mode:

```typescript
// component.schema.ts
import { z } from 'zod';

export const ComponentOptionsSchema = z
  .object({
    variant: z.enum(['primary', 'secondary']).optional(),
    size: z.enum(['sm', 'md', 'lg']).optional(),
    disabled: z.boolean().optional(),
    className: z.string().optional(),
    htmx: z
      .object({
        get: z.string().optional(),
        post: z.string().optional(),
        target: z.string().optional(),
        swap: z.string().optional(),
      })
      .strict()
      .optional(),
  })
  .strict(); // IMPORTANT: Reject unknown properties

export type ComponentOptions = z.infer<typeof ComponentOptionsSchema>;
```

### 2. Validate Inputs in Component

```typescript
// component.ts
import { validateOptions } from '../validation';
import { ComponentOptionsSchema, type ComponentOptions } from './component.schema';

export function component(content: string, options: ComponentOptions = {}): string {
  const validation = validateOptions<ComponentOptions>(options, {
    schema: ComponentOptionsSchema,
    componentName: 'component',
  });

  if (!validation.success) {
    return validation.error; // Returns styled error box HTML
  }

  const { variant = 'primary', size = 'md' } = validation.data;
  return `<div class="...">${escapeHtml(content)}</div>`;
}
```

### 3. Always Escape User Content

```typescript
import { escapeHtml } from '../utils';

const html = `<div title="${escapeHtml(title)}">${escapeHtml(content)}</div>`;
```

## Theme System

### Default Theme (GitHub/OpenAI)

```typescript
import { DEFAULT_THEME, createTheme } from '@frontmcp/uipack/theme';

// Colors
DEFAULT_THEME.colors.semantic.primary; // '#24292f' (near-black)
DEFAULT_THEME.colors.semantic.secondary; // '#57606a' (medium gray)
DEFAULT_THEME.colors.semantic.accent; // '#0969da' (blue accent)
```

### Custom Themes

```typescript
const customTheme = createTheme({
  name: 'my-theme',
  colors: {
    semantic: { primary: '#0969da' },
  },
  cdn: {
    fonts: {
      preconnect: ['https://fonts.googleapis.com'],
      stylesheets: ['https://fonts.googleapis.com/css2?family=Roboto&display=swap'],
    },
  },
});
```

## Platform Support

### Available Platforms

```typescript
import { getPlatform, OPENAI_PLATFORM, CLAUDE_PLATFORM } from '@frontmcp/uipack/theme';

OPENAI_PLATFORM.network; // 'open' - can fetch external resources
CLAUDE_PLATFORM.network; // 'blocked' - needs inline scripts
```

### Building Platform-Aware HTML

```typescript
import { buildCdnScriptsFromTheme, DEFAULT_THEME } from '@frontmcp/uipack/theme';

// For platforms with network access
const scripts = buildCdnScriptsFromTheme(DEFAULT_THEME, { inline: false });

// For blocked-network platforms (Claude)
const inlineScripts = buildCdnScriptsFromTheme(DEFAULT_THEME, { inline: true });
```

## Build API

```typescript
import { buildToolUI, getOutputModeForClient } from '@frontmcp/uipack/build';

// Build tool UI HTML
const html = await buildToolUI({
  template: '<div>{{output.data}}</div>',
  context: { input: {}, output: { data: 'Hello' } },
  platform: 'openai',
});

// Get output mode for client
const mode = getOutputModeForClient('openai');
```

## Testing Requirements

- **Coverage**: 95%+ across statements, branches, functions, lines
- **Validation Tests**: Every component must test invalid inputs
- **XSS Tests**: Test HTML escaping for user-provided content
- **Platform Tests**: Test behavior across platform configurations

## Dependencies

```json
{
  "dependencies": {
    "@swc/core": "^1.5.0",
    "enclave-vm": "^1.0.3",
    "esbuild": "^0.27.1",
    "handlebars": "^4.7.8",
    "zod": "^4.0.0"
  }
}
```

Note: No React dependency!

## Anti-Patterns to Avoid

- Using `any` type without justification
- Missing `.strict()` on Zod schemas
- Not validating component options
- Exposing internal error details
- Skipping XSS escaping
- Hard-coding CDN URLs (use theme.cdn)
- Adding React dependencies (use @frontmcp/ui for React)

## Related Packages

- **@frontmcp/ui** - React components, hooks, SSR rendering
- **@frontmcp/sdk** - Core FrontMCP SDK
- **@frontmcp/testing** - E2E testing utilities