Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .agents/skills/implement-platform/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: implement-platform
description: Implement or review Sim's new Platform UI from Paper in apps/sim/platform, including shared foundations, Base UI dropdowns, component promotion, responsive product compositions and fixture-only previews. Use on new work, migration, drift review or resumption; not for the legacy UI.
---

# Implement Platform from Paper

Read `apps/sim/platform/AGENTS.md` first. It is the canonical ownership and code contract. Follow `$sim-paper-design` for live Paper locations, design rules and continuity; use its references, not a remembered native ID. If the skill or live Paper is unavailable, verify what is possible locally and explicitly identify what remains unverified. Do not invent missing designs.

1. **Scope the phase.** Foundations, recipes and evidence are Phase 1. Approved product screens and their unique parts are Phase 2. Route integration, persisted state and authorization belong to Phase 3. Keep UI-only requests isolated; do not advance phases just to make a demo look real.
2. **Resolve the contract.** Inventory the live Shared and Platform libraries and the relevant Core/Chat/Workspaces product use. Compare the actual Base, usage and any theme counterpart. Read the applicable Dashboard/Issues/Changelog/Logs contract. Record key, current file/page/node, roles, named parts, states, approved parameters and ancestor use in a task-local checkpoint. Match slots by meaning. Do not treat the archived libraries, Marcus's work, canvas guides or a copied instance as alternative masters.
3. **Choose one owner.** Search the existing component exports and catalog evidence. Reuse a master and a single code implementation. New reusable behavior needs an evidenced Paper Base before a code variant. Register in Shared if it could serve another system; otherwise use Platform with a reason. A page-only composition lives by its feature; its styling stays in the central `design-system/features/<feature>/` owner. Route-private modules only compose. On second use, promote it once and update both imports together. Fix an existing master centrally; propagate the corrected recipe to every affected use. Never create a variant just to fill a gallery.
4. **Translate anatomy, not artboard coordinates.** Consult the installed Next docs in `node_modules/next/dist/docs` (especially project structure, CSS, Server/Client Components). Use semantic DOM, native or accessible behaviors, intrinsic size and responsive relationships. A 560px Paper modal is a preferred maximum, not a fixed width. The same modal should fit 647px and 390px viewports without new variants. Use centralized Tailwind roles, the type and material contracts, shared icon geometry and slots. Confirm the rendered DOM has the intended behavior. A searchable field accepts text, a disclosure opens by keyboard, a modal part composes directly, and a table renders the caller’s records. Repeated data takes an array, never a fixed list of numbered specimen props. Register a named native component for these cases. A new size requires a distinct, evidenced use; it isn't a device enum. Never pass styles through a composition. Trace repeated rows to their registered item and preserve the surrounding layout. Accept a typed collection, then render empty, short and longer-than-specimen data to prove that any example count can change. Keep different semantic roles distinct. Wrap Base UI primitives in EMCN when behavior involves floating layers, list navigation, cascading actions or focus management. Main-view and modal dropdowns share the same surface and rows. Preserve the caller’s value, accessible label and form submission through the owner. When editing generated files, change the source contract or compiler and regenerate the affected set.
5. **Exercise the right states.** Build a matrix of actual themes, relevant content sizes, resting, hover, selected, error and disabled states, keyboard navigation, long data, zoom and widths between Paper examples. The workbench is tooling, not a Phase 2 product screen. Entities, including organizations, workspaces, members and chats, come only through the server fixture gate. Render empty or absent data distinctly. Focusing a control or typing in it preserves its resting chrome; verify there is no focus paint on the control or its wrappers. Test keyboard focus and restoration separately. For cascading menus, test hover travel, arrow keys, Escape one level at a time, and bounds at either edge of the viewport and inside a modal. Client interaction may open, dismiss or change steps; no authentication, persistence or network effects.
6. **Prove it.** Run the structural audit against real code, regenerate/check relevant files, render the app in a real browser, and compare computed type/material/geometry and screenshots with live Paper. Exercise empty, full, stress and flag-off. Retire unused variants and resolve every affected use. Verify isolation and the repository gates. Report covered keys/states separately from visual comparisons; record unresolved differences and durable verification paths. Stop at the authorized phase.

**Resume:** read the task checkpoint and refresh the specific live node(s) before edits. Merge current work; do not replay an old export. The skill and repo contract are standing policy, not the checkpoint. Keep root, Claude and Cursor directives as pointers to that one policy.

**Examples:** “implement the workspace issue rows” starts from the Issues contract and registered row plus its actual Use, not a screenshot-derived card. “Add quiet to a button” requires an existing component or product use for that treatment. “Use the workspace item in chat too” is a promotion and import migration, not a second copy. “Preview an org with no workspaces” selects the empty fixture; it never creates a record.
4 changes: 4 additions & 0 deletions .agents/skills/implement-platform/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Implement Sim Platform"
short_description: "Implement Sim Platform from canonical Paper designs"
default_prompt: "Use $implement-platform to implement the next Paper Platform design in Sim."
2 changes: 2 additions & 0 deletions .claude/rules/emcn-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ paths:

# EMCN Components

This guide applies to the existing app. For `apps/sim/platform/**`, use `apps/sim/platform/AGENTS.md`.

Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from the `@sim/emcn/icons` subpath, and CSS modules from their file path. Never deep-import other component subpaths. The **chip family** is the platform's primary chrome — always reach for it over the legacy primitives it is progressively replacing (`Input`→`ChipInput`, `Textarea`→`ChipTextarea`, `Modal`→`ChipModal`, `Select`/`Combobox`→`ChipSelect`/`ChipCombobox`/`ChipDropdown`, date field→`ChipDatePicker`). `ChipSwitch` is a segmented choice between options, not a replacement for `Switch`: a boolean on/off toggle stays `Switch`. For context/action menus the canonical control is `DropdownMenu` — the standard menu (not a chip, and never a hand-rolled popover).

## Chip chrome — single source of truth
Expand Down
7 changes: 7 additions & 0 deletions .claude/rules/platform-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
description: Sim Platform implementation from Paper
paths:
- "apps/sim/platform/**"
---

Use the canonical contract in `apps/sim/platform/AGENTS.md` and the `implement-platform` skill. Legacy EMCN and app styling rules do not govern this separate project.
2 changes: 2 additions & 0 deletions .claude/rules/sim-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ paths:

# Sim App Architecture

This guide applies to the existing app. For `apps/sim/platform/**`, use `apps/sim/platform/AGENTS.md`.

Repository layout, package boundaries, the application operation boundary, naming, and utils placement are in the root `CLAUDE.md`. This file holds the app-internal boundaries.

## The `'use client'` server boundary
Expand Down
2 changes: 2 additions & 0 deletions .claude/rules/sim-styling.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ paths:

# Styling Rules

This guide applies to the existing app. For `apps/sim/platform/**`, use `apps/sim/platform/AGENTS.md`.

## Tailwind

1. **No inline styles** - Use Tailwind classes. Exception: a genuinely dynamic
Expand Down
1 change: 1 addition & 0 deletions .claude/skills/implement-platform
2 changes: 2 additions & 0 deletions .cursor/rules/emcn-components.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ globs: ["packages/emcn/**"]

# EMCN Components

This guide applies to the existing app. For `apps/sim/platform/**`, use `apps/sim/platform/AGENTS.md`.

Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from the `@sim/emcn/icons` subpath, and CSS modules from their file path. Never deep-import other component subpaths. The **chip family** is the platform's primary chrome — always reach for it over the legacy primitives it is progressively replacing (`Input`→`ChipInput`, `Textarea`→`ChipTextarea`, `Modal`→`ChipModal`, `Select`/`Combobox`→`ChipSelect`/`ChipCombobox`/`ChipDropdown`, date field→`ChipDatePicker`). `ChipSwitch` is a segmented choice between options, not a replacement for `Switch`: a boolean on/off toggle stays `Switch`. For context/action menus the canonical control is `DropdownMenu` — the standard menu (not a chip, and never a hand-rolled popover).

## Chip chrome — single source of truth
Expand Down
8 changes: 8 additions & 0 deletions .cursor/rules/platform-design.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
description: "Sim Platform implementation from Paper"
globs: ["apps/sim/platform/**"]
---

<!-- Generated from .claude/rules/platform-design.md by `bun run skills:sync`. Edit the source, not this file. -->

Use the canonical contract in `apps/sim/platform/AGENTS.md` and the `implement-platform` skill. Legacy EMCN and app styling rules do not govern this separate project.
2 changes: 2 additions & 0 deletions .cursor/rules/sim-architecture.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ globs: ["apps/sim/**"]

# Sim App Architecture

This guide applies to the existing app. For `apps/sim/platform/**`, use `apps/sim/platform/AGENTS.md`.

Repository layout, package boundaries, the application operation boundary, naming, and utils placement are in the root `CLAUDE.md`. This file holds the app-internal boundaries.

## The `'use client'` server boundary
Expand Down
2 changes: 2 additions & 0 deletions .cursor/rules/sim-styling.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ globs: ["apps/sim/**/*.tsx","apps/sim/**/*.css"]

# Styling Rules

This guide applies to the existing app. For `apps/sim/platform/**`, use `apps/sim/platform/AGENTS.md`.

## Tailwind

1. **No inline styles** - Use Tailwind classes. Exception: a genuinely dynamic
Expand Down
44 changes: 44 additions & 0 deletions .github/workflows/platform-design.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: platform-design

on:
pull_request:
paths:
- 'apps/sim/platform/**'
- 'apps/sim/package.json'
- 'scripts/check-platform-design*'
- 'scripts/platform-variant-usage.ts'
- 'scripts/sync-platform-*.ts'
- '.github/workflows/platform-design.yml'
- 'bun.lock'
workflow_dispatch:

permissions:
contents: read

concurrency:
group: platform-design-${{ github.ref }}
cancel-in-progress: true

jobs:
browser:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
persist-credentials: false
- uses: ./.github/actions/setup
with:
provider: github
- run: bun run --cwd apps/sim build:platform
- run: bunx --no-install playwright install --with-deps --only-shell chromium
working-directory: apps/sim
- run: bun run --cwd apps/sim test:platform:e2e
env:
PLATFORM_REPORT_PATH: ${{ runner.temp }}/platform-design/report.json
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: failure()
with:
name: platform-design-browser
path: ${{ runner.temp }}/platform-design
retention-days: 7
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package-lock.json
/apps/**/coverage
.vitest/
/apps/*/test-results
/apps/sim/platform/checks/test-results/
/packages/*/test-results

# next.js
Expand Down
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ The `'use client'` server boundary, the app/worker runtime env split, and featur

## Styling and EMCN

The isolated Platform in `apps/sim/platform/` follows [its design contract](apps/sim/platform/AGENTS.md) and the `implement-platform` skill. The EMCN and styling rules below apply to the existing application.

- Tailwind only. Inline `style` only for a genuinely dynamic value or a CSS variable; type size is a named token, never `text-[Npx]` (`check:source-conventions` ratchets both). Never update global styles; keep styling local to the component. `cn()` from `@sim/emcn` for conditional classes. `size-*` for equal height and width (icons default `size-[14px]`), never `h-N w-N`.
- Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons from `@sim/emcn/icons`; CSS modules by file path. Never deep-import other component subpaths.
- The chip family is the canonical chrome: `ChipInput`, `ChipTextarea`, `ChipModal`/`ChipModalField`, `ChipSelect`/`ChipCombobox`/`ChipDropdown`, `ChipSwitch` (a segmented choice; a boolean toggle stays `Switch`), `ChipDatePicker`, `Chip`/`ChipLink`, `ChipTag`; `DropdownMenu` for context/action menus. Components own their chrome: consumers pass props (`error`, `icon`, `endAdornment`, `inputClassName`) and `className` carries only layout/sizing. Every labeled field inside a `ChipModalBody` is a `ChipModalField`.
Expand Down
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ The `'use client'` server boundary, the app/worker runtime env split, and featur

## Styling and EMCN

The isolated Platform in `apps/sim/platform/` follows [its design contract](apps/sim/platform/AGENTS.md) and the `implement-platform` skill. The EMCN and styling rules below apply to the existing application.

- Tailwind only. Inline `style` only for a genuinely dynamic value or a CSS variable; type size is a named token, never `text-[Npx]` (`check:source-conventions` ratchets both). Never update global styles; keep styling local to the component. `cn()` from `@sim/emcn` for conditional classes. `size-*` for equal height and width (icons default `size-[14px]`), never `h-N w-N`.
- Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons from `@sim/emcn/icons`; CSS modules by file path. Never deep-import other component subpaths.
- The chip family is the canonical chrome: `ChipInput`, `ChipTextarea`, `ChipModal`/`ChipModalField`, `ChipSelect`/`ChipCombobox`/`ChipDropdown`, `ChipSwitch` (a segmented choice; a boolean toggle stays `Switch`), `ChipDatePicker`, `Chip`/`ChipLink`, `ChipTag`; `DropdownMenu` for context/action menus. Components own their chrome: consumers pass props (`error`, `icon`, `endAdornment`, `inputClassName`) and `className` carries only layout/sizing. Every labeled field inside a `ChipModalBody` is a `ChipModalField`.
Expand Down
2 changes: 2 additions & 0 deletions apps/sim/AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Sim App Scope

For `platform/**`, use [the Platform design contract](platform/AGENTS.md) and `$implement-platform`. The existing app styling rules apply elsewhere.

Applies to `apps/sim/**` on top of the root [AGENTS.md](/AGENTS.md), which holds the repo-wide rules. Before editing in an area, read its rule file under `.claude/rules/`:

- API routes, contracts, route builders, boundary annotations, `requestJson`: `sim-api-contracts.md`
Expand Down
7 changes: 7 additions & 0 deletions apps/sim/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
},
"scripts": {
"dev": "bun run build:cli-runtime && bun run dev:cache:cap && next dev --port 3000",
"dev:platform": "cd platform && next dev --webpack --port 3100",
"build:platform": "cd platform && next build --webpack",
"test:platform:e2e": "playwright test --config platform/checks/playwright.config.ts",
"start:platform": "cd platform && next start --port 3100",
"dev:capped": "bun run build:cli-runtime && bun run dev:cache:cap && NODE_OPTIONS='--max-old-space-size=4096' next dev --port 3000",
"dev:cache:cap": "bun run ../../scripts/prune-turbopack-cache.ts",
"dev:clean": "rm -rf .next/dev/cache",
Expand Down Expand Up @@ -93,6 +97,7 @@
"@aws-sdk/s3-request-presigner": "3.1150.0",
"@azure/communication-email": "1.1.0",
"@azure/storage-blob": "12.27.0",
"@base-ui/react": "1.9.0",
"@better-auth/oauth-provider": "1.6.27",
"@better-auth/sso": "1.6.27",
"@better-auth/stripe": "1.6.27",
Expand Down Expand Up @@ -202,6 +207,7 @@
"croner": "^9.0.0",
"cronstrue": "3.3.0",
"csv-parse": "7.0.3",
"d3-shape": "3.2.0",
"date-fns": "4.4.0",
"decimal.js": "10.6.0",
"diff": "9.0.0",
Expand Down Expand Up @@ -305,6 +311,7 @@
"@types/archiver": "8.0.0",
"@types/busboy": "1.5.4",
"@types/chrome": "0.3.6",
"@types/d3-shape": "3.1.8",
"@types/hast": "3.0.5",
"@types/heic-convert": "2.1.1",
"@types/html-to-text": "9.0.4",
Expand Down
Loading
Loading