diff --git a/.agents/skills/reui/SKILL.md b/.agents/skills/reui/SKILL.md
index 160e7e5..d76c1c2 100644
--- a/.agents/skills/reui/SKILL.md
+++ b/.agents/skills/reui/SKILL.md
@@ -5,7 +5,7 @@ user-invocable: false
allowed-tools: Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *)
---
-> **ReUI skill version `0e224b0281`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
+> **ReUI skill version `42d70dcc3d`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
# ReUI for Agents
diff --git a/.agents/skills/reui/rules/cli.md b/.agents/skills/reui/rules/cli.md
index e603164..7c40844 100644
--- a/.agents/skills/reui/rules/cli.md
+++ b/.agents/skills/reui/rules/cli.md
@@ -29,6 +29,8 @@ REUI_LICENSE_KEY=your-license-key
}
```
+The shadcn CLI expands `${REUI_LICENSE_KEY}` from `.env.local` inside `components.json`, but an MCP client config never expands variables, so a ReUI MCP server config must carry the raw token instead (for example `reui_pat_your_token_here`).
+
The MCP `get_project_context` tool returns the right config. Full guide: https://reui.io/docs/registry
## Installing
diff --git a/.agents/skills/reui/rules/components.md b/.agents/skills/reui/rules/components.md
index 8767bbb..0c24578 100644
--- a/.agents/skills/reui/rules/components.md
+++ b/.agents/skills/reui/rules/components.md
@@ -1,6 +1,6 @@
# ReUI components
-The 17 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `filters`, `frame`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
+The 19 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
**Rule one: never guess a component's API. Read it first.** Call **`get_component(name)`** for its inline `api` (props + usage, no web fetch), and **share the result's `docsUrl`** (the component's API documentation page) with the user whenever you work with that component's API, so they have the full reference (the `/llms.txt` index is a further fallback). Then call **`get_examples(name)`** to install a worked example and copy real composition. The contracts below are first-try orientation (required props, composition shape, the one gotcha); the inline `api` is the full reference. No single block fits? Compose: search the components you need, read each `get_component`, install a `get_examples` example per component, and adapt.
@@ -32,6 +32,34 @@ Common mistakes:
- **Incorrect:** a raw `
` / hand-rolled pagination. **Correct:** use `data-grid`; read its API for sticky header, pagination, virtualization, row selection.
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the documented `ColumnMeta` (e.g. `cellClassName`, `headerTitle`).
+## event-calendar
+
+**Required:** events via `events`/`onEventsChange` (controlled) or `defaultEvents` (uncontrolled), plus a height on the root.
+**Shape:**
+
+```tsx
+
+
+
+
+```
+
+**Gotcha:** headless-first: `EventCalendarContent` renders the active view (month/week/day/days/agenda; a resource view activates when `resources` is passed) - there is no per-view JSX to compose. Events are `{ id, title, start, end (exclusive), allDay?, color?, recurrence?, resourceId? }`. Mutations flow through `onEventUpdate`/`canDropEvent` (return `false` to reject); the root needs an explicit height because it is a min-h-0 flex column.
+
+## gantt
+
+**Required:** `resources` (the left tree) plus bars via `events`/`defaultEvents` attached by `resourceId`.
+**Shape:**
+
+```tsx
+
+
+
+
+```
+
+**Gotcha:** bars move along the time axis only (never across rows) and are all-day spans with exclusive `end`; `progress` is 0-100. Scales are `day | week | month | quarter | year`. Zoom control, infinite scroll, summary rollups, and row checkboxes are ON by default - turn off what you do not need. Same `onEventUpdate`/`canDropEvent` commit pipeline as `event-calendar`; the root needs an explicit height.
+
## kanban
**Required:** `value` (`Record`), `onValueChange`, `getItemValue`
diff --git a/.claude/skills/reui/SKILL.md b/.claude/skills/reui/SKILL.md
index 160e7e5..d76c1c2 100644
--- a/.claude/skills/reui/SKILL.md
+++ b/.claude/skills/reui/SKILL.md
@@ -5,7 +5,7 @@ user-invocable: false
allowed-tools: Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *)
---
-> **ReUI skill version `0e224b0281`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
+> **ReUI skill version `42d70dcc3d`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
# ReUI for Agents
diff --git a/.claude/skills/reui/rules/cli.md b/.claude/skills/reui/rules/cli.md
index e603164..7c40844 100644
--- a/.claude/skills/reui/rules/cli.md
+++ b/.claude/skills/reui/rules/cli.md
@@ -29,6 +29,8 @@ REUI_LICENSE_KEY=your-license-key
}
```
+The shadcn CLI expands `${REUI_LICENSE_KEY}` from `.env.local` inside `components.json`, but an MCP client config never expands variables, so a ReUI MCP server config must carry the raw token instead (for example `reui_pat_your_token_here`).
+
The MCP `get_project_context` tool returns the right config. Full guide: https://reui.io/docs/registry
## Installing
diff --git a/.claude/skills/reui/rules/components.md b/.claude/skills/reui/rules/components.md
index 8767bbb..0c24578 100644
--- a/.claude/skills/reui/rules/components.md
+++ b/.claude/skills/reui/rules/components.md
@@ -1,6 +1,6 @@
# ReUI components
-The 17 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `filters`, `frame`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
+The 19 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
**Rule one: never guess a component's API. Read it first.** Call **`get_component(name)`** for its inline `api` (props + usage, no web fetch), and **share the result's `docsUrl`** (the component's API documentation page) with the user whenever you work with that component's API, so they have the full reference (the `/llms.txt` index is a further fallback). Then call **`get_examples(name)`** to install a worked example and copy real composition. The contracts below are first-try orientation (required props, composition shape, the one gotcha); the inline `api` is the full reference. No single block fits? Compose: search the components you need, read each `get_component`, install a `get_examples` example per component, and adapt.
@@ -32,6 +32,34 @@ Common mistakes:
- **Incorrect:** a raw `
` / hand-rolled pagination. **Correct:** use `data-grid`; read its API for sticky header, pagination, virtualization, row selection.
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the documented `ColumnMeta` (e.g. `cellClassName`, `headerTitle`).
+## event-calendar
+
+**Required:** events via `events`/`onEventsChange` (controlled) or `defaultEvents` (uncontrolled), plus a height on the root.
+**Shape:**
+
+```tsx
+
+
+
+
+```
+
+**Gotcha:** headless-first: `EventCalendarContent` renders the active view (month/week/day/days/agenda; a resource view activates when `resources` is passed) - there is no per-view JSX to compose. Events are `{ id, title, start, end (exclusive), allDay?, color?, recurrence?, resourceId? }`. Mutations flow through `onEventUpdate`/`canDropEvent` (return `false` to reject); the root needs an explicit height because it is a min-h-0 flex column.
+
+## gantt
+
+**Required:** `resources` (the left tree) plus bars via `events`/`defaultEvents` attached by `resourceId`.
+**Shape:**
+
+```tsx
+
+
+
+
+```
+
+**Gotcha:** bars move along the time axis only (never across rows) and are all-day spans with exclusive `end`; `progress` is 0-100. Scales are `day | week | month | quarter | year`. Zoom control, infinite scroll, summary rollups, and row checkboxes are ON by default - turn off what you do not need. Same `onEventUpdate`/`canDropEvent` commit pipeline as `event-calendar`; the root needs an explicit height.
+
## kanban
**Required:** `value` (`Record`), `onValueChange`, `getItemValue`
diff --git a/.cursor/rules/reui-mcp.mdc b/.cursor/rules/reui-mcp.mdc
new file mode 100644
index 0000000..5995edf
--- /dev/null
+++ b/.cursor/rules/reui-mcp.mdc
@@ -0,0 +1,111 @@
+---
+description: ReUI PRO (@reui) — MCP user-reui, Frame surface, kit, license, матрица выбора
+alwaysApply: true
+---
+
+# ReUI MCP — обязательно (PRO + free)
+
+Проект: **Base UI** (`style: base-nova`), surface lock **`frame`**.
+
+Связанные: [`shadcn-mcp.mdc`](shadcn-mcp.mdc), [`web-shadcn.mdc`](web-shadcn.mdc), [`web-shadcn.mdc`](web-shadcn.mdc), [`docs/ui-design-contract.md`](docs/ui-design-contract.md).
+
+| Документ | URL |
+|----------|-----|
+| **llms.txt** | https://reui.io/llms.txt |
+| **Get Started** | https://reui.io/docs/get-started |
+| **Styling** | https://reui.io/docs/styling |
+| **MCP** | https://reui.io/docs/mcp |
+| **Blocks** | https://reui.io/blocks |
+| **Settings blocks** | https://reui.io/blocks/application/settings |
+| **License** | https://reui.io/docs/license-setup |
+| **Base UI components** | https://reui.io/docs/components/base/ |
+
+## Primary MCP
+
+1. **`user-reui`** — `search` / `compose_page` / `get_block` / `get_component` / `get_install_command` / `validate_usage` / `get_audit_checklist`
+2. **`plugin-shadcn-shadcn`** — primitives `@shadcn`; для `@reui` — вторично
+
+**Обязательно** цитировать `previewUrl` + `docsUrl` для каждой UI-зоны.
+
+## Когда ReUI vs shadcn
+
+| Задача | Registry | Импорт |
+|--------|----------|--------|
+| Button, Sheet, Field, Sidebar, Tabs | `@shadcn` | `@evobgp/ui/components/*` |
+| PRO pages/sections (settings, stats, auth, dashboard) | `@reui` blocks | adapt → `apps/web/src/components/` / `reui-kit/` |
+| Data Grid | `@reui` | `@/components/reui/data-grid/*` → `ResourcePage` |
+| Filters | `@reui` | `@/components/reui/filters` |
+| Frame surface | `@reui` | `@/components/reui/frame` |
+| KPI | block [stats-12](https://reui.io/preview/base/stats-12) | `reui-kit/KpiStatGrid` (EvoBGP hybrid SoT) |
+| Quick Actions | Frame tiles sibling KPI | `reui-kit/QuickActionGrid` |
+| Semantic badge / alert | `@reui` | `@/components/reui/badge`, `@/components/reui/alert` |
+| Number / date / autocomplete / color / kanban | `@reui` | `@/components/reui/*` |
+
+**Сложные списки** — `ResourcePage` (Frame + data-grid + filters), не raw `
`, не DataGridCard.
+**Quick Actions** — только `QuickActionGrid` (не Card / Button grid).
+
+## MCP workflow
+
+0. Codegraph / поиск существующих `reui-kit/*`, `@/components/reui/*`
+1. `user-reui` `search` (`surface: "frame"`, `category` при известном)
+2. Страница целиком → `compose_page`; секция → `get_block`
+3. `get_component` для API primitives из `componentsUsed`
+4. CLI из `apps/web`: `pnpm dlx shadcn@latest add @reui/ --yes`
+5. Post-add: shadcn imports → `@evobgp/ui/components/*`
+6. Adapt by reuse → kit / route
+7. `validate_usage` + `get_audit_checklist`
+
+## Размещение
+
+| Слой | Путь | Импорт |
+|------|------|--------|
+| shadcn | `packages/ui/src/components/` | `@evobgp/ui/components/*` |
+| ReUI CLI | `apps/web/src/components/reui/` | `@/components/reui/*` |
+| PRO blocks (reference) | `apps/web/src/components/blocks/` | adapt into kit, не копипаст в routes |
+| Kit | `apps/web/src/components/reui-kit/` | `@/components/reui-kit/*` |
+
+## Установленные ReUI (apps/web)
+
+**Components:** `frame`, `data-grid/*`, `filters`, `kanban`, `badge`, `alert`, `autocomplete`, `number-field`, `date-selector`, `color-picker`, `timeline`, `rating`, `phone-input`, `icon-stack`
+
+**Kit:** `ResourcePage`, `KpiStatGrid`, `QuickActionGrid`, `OpsDashboard`, `KanbanBoard`, `DetailPanel`, `SettingsShell`
+
+**Blocks (reference):** `stats-12`, `card-35`, `auth-13`, `app-shell-12`, `settings-16`, `settings-8`, `empty-state-12`, `form-7`, `data-grid-filtering-2`, `dashboard-1`, …
+
+## License
+
+```env
+# .env.local (gitignored)
+REUI_LICENSE_KEY=
+```
+
+`apps/web/components.json` → `@reui` с `Authorization: Bearer ${REUI_LICENSE_KEY}`.
+
+## Эталоны preview
+
+| Зона | Preview |
+|------|---------|
+| KPI / Quick Actions | https://reui.io/preview/base/stats-12 · https://reui.io/preview/base/card-12 |
+| List | https://reui.io/preview/base/data-grid-filtering-2 |
+| Settings | https://reui.io/preview/base/settings-16 |
+| Auth | https://reui.io/preview/base/auth-13 |
+| Shell | https://reui.io/preview/base/app-shell-12 |
+| Empty | https://reui.io/preview/base/empty-state-12 |
+
+## Запрещено
+
+- Копипаст с reui.io без CLI
+- ReUI в `packages/ui` / импорт как `@evobgp/ui`
+- Radix-варианты docs — только Base UI
+- Raw `bg-emerald-*` вместо ReUI `variant`
+- Hand-roll data-grid/filters/KPI/Quick Actions/settings rows при наличии `@reui` / kit
+- Смешивать Card и Frame на ops-экране
+- Ставить shadcn/ui blocks выше ReUI PRO
+
+## Чеклист
+
+- [ ] `user-reui` search/get_block + previewUrl
+- [ ] `surface: frame`
+- [ ] CLI add из `apps/web` при новом item
+- [ ] Kit / `@/components/reui` / `@evobgp/ui` — правильный слой
+- [ ] `pnpm --filter @evobgp/web run build`
diff --git a/.cursor/rules/reui.mdc b/.cursor/rules/reui.mdc
index 48b05d0..2c881c6 100644
--- a/.cursor/rules/reui.mdc
+++ b/.cursor/rules/reui.mdc
@@ -11,7 +11,7 @@ user-invocable: false
allowed-tools: Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *)
---
-> **ReUI skill version `0e224b0281`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
+> **ReUI skill version `42d70dcc3d`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
# ReUI for Agents
diff --git a/.cursor/rules/web-shadcn.mdc b/.cursor/rules/web-shadcn.mdc
index 0c6b07c..5453f98 100644
--- a/.cursor/rules/web-shadcn.mdc
+++ b/.cursor/rules/web-shadcn.mdc
@@ -9,12 +9,12 @@ alwaysApply: false
# Web UI — React + shadcn/ui + ReUI
**Источники правды:**
+- **ReUI PRO first:** MCP `user-reui` ([`reui-mcp.mdc`](reui-mcp.mdc)) — pages / KPI / lists / settings / shell
+- shadcn primitives: MCP `plugin-shadcn-shadcn` (secondary)
+- ReUI Base UI: https://reui.io/docs/components/base/ · [llms.txt](https://reui.io/llms.txt)
- shadcn/ui React: https://ui.shadcn.com/docs/components
-- ReUI Base UI: https://reui.io/docs/components/base/
-- ReUI llms.txt: https://reui.io/llms.txt
-- MCP `plugin-shadcn-shadcn` (registries: `@shadcn`, `@reui`) — перед любой UI-задачей
-Общие правила Go/API: `.cursor/rules/engineering.mdc`. Стек ID: `.cursor/rules/context7-stack.mdc`.
+Иерархия: **ReUI PRO > shadcn**. Общие: `.cursor/rules/engineering.mdc`, `context7-stack.mdc`.
## Слои UI
@@ -23,18 +23,18 @@ alwaysApply: false
| shadcn-примитивы | `packages/ui/src/components/` | output `shadcn add` (не трогать под кейс) |
| ReUI enterprise | `apps/web/src/components/reui/` | output `shadcn add @reui/*` |
| Shared обёртки | `apps/web/src/components/` | PageHeader, QueryState, ConfirmDialog, StatusBadge, LoadingButton |
-| ReUI kit | `apps/web/src/components/reui-kit/` | ResourcePage, KpiStatGrid, OpsDashboard, SettingsShell |
+| ReUI kit | `apps/web/src/components/reui-kit/` | ResourcePage, KpiStatGrid, QuickActionGrid, OpsDashboard, SettingsShell |
| Роуты | `apps/web/src/routes/` | TanStack Router (file-based) |
-**Design contract:** [`docs/ui-design-contract.md`](../../docs/ui-design-contract.md). Surface: **frame**. KPI: [stats-12](https://reui.io/preview/base/stats-12). Lists: [data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2).
+**Design contract:** [`docs/ui-design-contract.md`](../../docs/ui-design-contract.md). Surface: **frame**. KPI hybrid SoT: [stats-12](https://reui.io/preview/base/stats-12). Lists: [data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2). Quick Actions: `QuickActionGrid`.
Тема: `packages/ui/src/styles/globals.css`. CLI из `apps/web`: `pnpm dlx shadcn@latest add `.
## Правила
-**WEB-01** | MUST | Перед новым UI — MCP `plugin-shadcn-shadcn`: `search_items_in_registries` → `get_item_examples_from_registries` → `get_add_command_for_items`. Только после — JSX.
-*Rationale:* единый источник правды и API.
-*Проверка:* review; нет самописных примитивов, если есть registry item.
+**WEB-01** | MUST | Перед новым UI — сначала MCP **`user-reui`** (`search` → `get_block` / `compose_page`, `surface: "frame"`) + cite `previewUrl`/`docsUrl`. Primitives — MCP `plugin-shadcn-shadcn`. Только после — JSX.
+*Rationale:* ReUI PRO выше shadcn; единый Frame surface.
+*Проверка:* review; [`reui-mcp.mdc`](reui-mcp.mdc).
**WEB-02** | MUST | Отсутствующий shadcn-примитив — `pnpm dlx shadcn@latest add ` (из `apps/web`). ReUI — `pnpm dlx shadcn@latest add @reui/`.
*Проверка:* файлы в `packages/ui/src/components/` (для shadcn) или `apps/web/src/components/reui/` (для ReUI).
@@ -73,7 +73,7 @@ alwaysApply: false
**WEB-14** | SHOULD | Нетривиальный UI — прочитать страницу компонента shadcn/ReUI (props, a11y).
-**WEB-15** | MUST | Сомнения — MCP `plugin-shadcn-shadcn` + shadcn CLI docs + `pnpm --filter @evobgp/web run typecheck`.
+**WEB-15** | MUST | Сомнения — MCP `user-reui` + `plugin-shadcn-shadcn` + docs + `pnpm --filter @evobgp/web run typecheck`.
**WEB-16** | MUST | Подтверждение удаления — `ConfirmDialog` из `@/components/confirm-dialog`, не `window.confirm`.
diff --git a/.cursor/skills/reui/SKILL.md b/.cursor/skills/reui/SKILL.md
index 160e7e5..d76c1c2 100644
--- a/.cursor/skills/reui/SKILL.md
+++ b/.cursor/skills/reui/SKILL.md
@@ -5,7 +5,7 @@ user-invocable: false
allowed-tools: Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *)
---
-> **ReUI skill version `0e224b0281`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
+> **ReUI skill version `42d70dcc3d`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
# ReUI for Agents
diff --git a/.cursor/skills/reui/rules/cli.md b/.cursor/skills/reui/rules/cli.md
index e603164..7c40844 100644
--- a/.cursor/skills/reui/rules/cli.md
+++ b/.cursor/skills/reui/rules/cli.md
@@ -29,6 +29,8 @@ REUI_LICENSE_KEY=your-license-key
}
```
+The shadcn CLI expands `${REUI_LICENSE_KEY}` from `.env.local` inside `components.json`, but an MCP client config never expands variables, so a ReUI MCP server config must carry the raw token instead (for example `reui_pat_your_token_here`).
+
The MCP `get_project_context` tool returns the right config. Full guide: https://reui.io/docs/registry
## Installing
diff --git a/.cursor/skills/reui/rules/components.md b/.cursor/skills/reui/rules/components.md
index 8767bbb..0c24578 100644
--- a/.cursor/skills/reui/rules/components.md
+++ b/.cursor/skills/reui/rules/components.md
@@ -1,6 +1,6 @@
# ReUI components
-The 17 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `filters`, `frame`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
+The 19 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
**Rule one: never guess a component's API. Read it first.** Call **`get_component(name)`** for its inline `api` (props + usage, no web fetch), and **share the result's `docsUrl`** (the component's API documentation page) with the user whenever you work with that component's API, so they have the full reference (the `/llms.txt` index is a further fallback). Then call **`get_examples(name)`** to install a worked example and copy real composition. The contracts below are first-try orientation (required props, composition shape, the one gotcha); the inline `api` is the full reference. No single block fits? Compose: search the components you need, read each `get_component`, install a `get_examples` example per component, and adapt.
@@ -32,6 +32,34 @@ Common mistakes:
- **Incorrect:** a raw `
` / hand-rolled pagination. **Correct:** use `data-grid`; read its API for sticky header, pagination, virtualization, row selection.
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the documented `ColumnMeta` (e.g. `cellClassName`, `headerTitle`).
+## event-calendar
+
+**Required:** events via `events`/`onEventsChange` (controlled) or `defaultEvents` (uncontrolled), plus a height on the root.
+**Shape:**
+
+```tsx
+
+
+
+
+```
+
+**Gotcha:** headless-first: `EventCalendarContent` renders the active view (month/week/day/days/agenda; a resource view activates when `resources` is passed) - there is no per-view JSX to compose. Events are `{ id, title, start, end (exclusive), allDay?, color?, recurrence?, resourceId? }`. Mutations flow through `onEventUpdate`/`canDropEvent` (return `false` to reject); the root needs an explicit height because it is a min-h-0 flex column.
+
+## gantt
+
+**Required:** `resources` (the left tree) plus bars via `events`/`defaultEvents` attached by `resourceId`.
+**Shape:**
+
+```tsx
+
+
+
+
+```
+
+**Gotcha:** bars move along the time axis only (never across rows) and are all-day spans with exclusive `end`; `progress` is 0-100. Scales are `day | week | month | quarter | year`. Zoom control, infinite scroll, summary rollups, and row checkboxes are ON by default - turn off what you do not need. Same `onEventUpdate`/`canDropEvent` commit pipeline as `event-calendar`; the root needs an explicit height.
+
## kanban
**Required:** `value` (`Record`), `onValueChange`, `getItemValue`
diff --git a/.opencode/skills/reui/SKILL.md b/.opencode/skills/reui/SKILL.md
index 160e7e5..d76c1c2 100644
--- a/.opencode/skills/reui/SKILL.md
+++ b/.opencode/skills/reui/SKILL.md
@@ -5,7 +5,7 @@ user-invocable: false
allowed-tools: Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *)
---
-> **ReUI skill version `0e224b0281`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
+> **ReUI skill version `42d70dcc3d`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
# ReUI for Agents
diff --git a/.opencode/skills/reui/rules/cli.md b/.opencode/skills/reui/rules/cli.md
index e603164..7c40844 100644
--- a/.opencode/skills/reui/rules/cli.md
+++ b/.opencode/skills/reui/rules/cli.md
@@ -29,6 +29,8 @@ REUI_LICENSE_KEY=your-license-key
}
```
+The shadcn CLI expands `${REUI_LICENSE_KEY}` from `.env.local` inside `components.json`, but an MCP client config never expands variables, so a ReUI MCP server config must carry the raw token instead (for example `reui_pat_your_token_here`).
+
The MCP `get_project_context` tool returns the right config. Full guide: https://reui.io/docs/registry
## Installing
diff --git a/.opencode/skills/reui/rules/components.md b/.opencode/skills/reui/rules/components.md
index 8767bbb..0c24578 100644
--- a/.opencode/skills/reui/rules/components.md
+++ b/.opencode/skills/reui/rules/components.md
@@ -1,6 +1,6 @@
# ReUI components
-The 17 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `filters`, `frame`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
+The 19 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
**Rule one: never guess a component's API. Read it first.** Call **`get_component(name)`** for its inline `api` (props + usage, no web fetch), and **share the result's `docsUrl`** (the component's API documentation page) with the user whenever you work with that component's API, so they have the full reference (the `/llms.txt` index is a further fallback). Then call **`get_examples(name)`** to install a worked example and copy real composition. The contracts below are first-try orientation (required props, composition shape, the one gotcha); the inline `api` is the full reference. No single block fits? Compose: search the components you need, read each `get_component`, install a `get_examples` example per component, and adapt.
@@ -32,6 +32,34 @@ Common mistakes:
- **Incorrect:** a raw `
` / hand-rolled pagination. **Correct:** use `data-grid`; read its API for sticky header, pagination, virtualization, row selection.
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the documented `ColumnMeta` (e.g. `cellClassName`, `headerTitle`).
+## event-calendar
+
+**Required:** events via `events`/`onEventsChange` (controlled) or `defaultEvents` (uncontrolled), plus a height on the root.
+**Shape:**
+
+```tsx
+
+
+
+
+```
+
+**Gotcha:** headless-first: `EventCalendarContent` renders the active view (month/week/day/days/agenda; a resource view activates when `resources` is passed) - there is no per-view JSX to compose. Events are `{ id, title, start, end (exclusive), allDay?, color?, recurrence?, resourceId? }`. Mutations flow through `onEventUpdate`/`canDropEvent` (return `false` to reject); the root needs an explicit height because it is a min-h-0 flex column.
+
+## gantt
+
+**Required:** `resources` (the left tree) plus bars via `events`/`defaultEvents` attached by `resourceId`.
+**Shape:**
+
+```tsx
+
+
+
+
+```
+
+**Gotcha:** bars move along the time axis only (never across rows) and are all-day spans with exclusive `end`; `progress` is 0-100. Scales are `day | week | month | quarter | year`. Zoom control, infinite scroll, summary rollups, and row checkboxes are ON by default - turn off what you do not need. Same `onEventUpdate`/`canDropEvent` commit pipeline as `event-calendar`; the root needs an explicit height.
+
## kanban
**Required:** `value` (`Record`), `onValueChange`, `getItemValue`
diff --git a/apps/web/src/components/layout/app-shell.tsx b/apps/web/src/components/layout/app-shell.tsx
index 848f6ec..7d46168 100644
--- a/apps/web/src/components/layout/app-shell.tsx
+++ b/apps/web/src/components/layout/app-shell.tsx
@@ -46,7 +46,6 @@ import { AppsMenu } from '@/components/layout/apps-menu'
import { CommandPalette, type CommandPaletteItem } from '@/components/layout/command-palette'
import { NavUser } from '@/components/layout/nav-user'
import { SystemMonitorPopover } from '@/components/layout/system-monitor-popover'
-import { ModeToggle } from '@/components/mode-toggle'
import { can, isAuthEnabled, permissionForPath } from '@/lib/auth'
interface NavItem {
@@ -219,7 +218,6 @@ export function AppShell({ children }: { children: ReactNode }) {