@exxatdesignux/ui 0.5.10 → 0.5.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/bin/cli.mjs +70 -1
- package/bin/init.mjs +18 -4
- package/bin/sync-extras.mjs +28 -4
- package/consumer-extras/README.md +41 -5
- package/consumer-extras/cursor-rules/exxat-accessibility.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-board-cards.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +4 -2
- package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-command-menu.mdc +3 -2
- package/consumer-extras/cursor-rules/exxat-data-tables.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +7 -0
- package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +13 -2
- package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-hub-supported-views.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +6 -5
- package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +6 -2
- package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-nav-single-active.mdc +4 -3
- package/consumer-extras/cursor-rules/exxat-no-image-pixel-copy.mdc +25 -14
- package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +8 -2
- package/consumer-extras/cursor-rules/exxat-no-toast.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-no-vaul.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-page-header-actions.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-sidebar-shell.mdc +13 -7
- package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-table-row-preview.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-tabs-chrome.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +6 -0
- package/consumer-extras/cursor-rules/exxat-ux-discovery-protocol.mdc +92 -12
- package/consumer-extras/cursor-rules/exxat-ux-principles.mdc +1 -0
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-kpi-trends/SKILL.md +5 -3
- package/consumer-extras/cursor-skills/exxat-senior-ux/SKILL.md +70 -17
- package/consumer-extras/patterns/command-menu-pattern.md +2 -2
- package/consumer-extras/patterns/consumer-upgrade-checklist.md +1 -1
- package/consumer-extras/patterns/jobs/README.md +1 -1
- package/consumer-extras/patterns/perf-memory-pattern.md +115 -150
- package/consumer-extras/scripts/dev-guard.mjs +156 -0
- package/consumer-extras/templates/README.md +23 -0
- package/consumer-extras/templates/handoff.md +190 -0
- package/dist/hooks/use-app-theme.d.ts +1 -1
- package/package.json +2 -2
- package/{template → template-vite}/.claude/skills/exxat-ds-skill/SKILL.md +184 -23
- package/template-vite/.cursor/rules/exxat-accessibility.mdc +40 -0
- package/template-vite/.cursor/rules/exxat-board-cards.mdc +28 -0
- package/template-vite/.cursor/rules/exxat-breadcrumbs-no-back.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-card-vs-list-rows.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-centralized-list-dataset.mdc +46 -0
- package/template-vite/.cursor/rules/exxat-collaboration-access.mdc +33 -0
- package/{template → template-vite}/.cursor/rules/exxat-command-menu.mdc +5 -5
- package/template-vite/.cursor/rules/exxat-data-tables.mdc +47 -0
- package/template-vite/.cursor/rules/exxat-dedicated-search-surfaces.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-drawer-vs-dialog.mdc +23 -0
- package/template-vite/.cursor/rules/exxat-ds-agents.mdc +87 -0
- package/template-vite/.cursor/rules/exxat-fontawesome-icons.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-hub-supported-views.mdc +56 -0
- package/{template → template-vite}/.cursor/rules/exxat-kbd-shortcuts.mdc +1 -0
- package/template-vite/.cursor/rules/exxat-kpi-flat-band.mdc +29 -0
- package/template-vite/.cursor/rules/exxat-kpi-max-four.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-kpi-trends.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-library-hub-header.mdc +29 -0
- package/template-vite/.cursor/rules/exxat-list-page-connected-views.mdc +28 -0
- package/template-vite/.cursor/rules/exxat-list-page-view-shells.mdc +32 -0
- package/{template → template-vite}/.cursor/rules/exxat-mono-ids.mdc +1 -0
- package/template-vite/.cursor/rules/exxat-nav-single-active.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-no-image-pixel-copy.mdc +46 -0
- package/template-vite/.cursor/rules/exxat-no-slds-leakage.mdc +84 -0
- package/{template → template-vite}/.cursor/rules/exxat-no-toast.mdc +2 -2
- package/template-vite/.cursor/rules/exxat-no-vaul.mdc +26 -0
- package/template-vite/.cursor/rules/exxat-page-header-actions.mdc +33 -0
- package/{template → template-vite}/.cursor/rules/exxat-page-vs-drawer.mdc +5 -3
- package/template-vite/.cursor/rules/exxat-person-identity-display.mdc +48 -0
- package/template-vite/.cursor/rules/exxat-primary-nav-secondary-panel.mdc +53 -0
- package/template-vite/.cursor/rules/exxat-reuse-before-custom.mdc +37 -0
- package/template-vite/.cursor/rules/exxat-sidebar-shell.mdc +41 -0
- package/template-vite/.cursor/rules/exxat-table-properties-drawer.mdc +79 -0
- package/template-vite/.cursor/rules/exxat-table-row-preview.mdc +25 -0
- package/template-vite/.cursor/rules/exxat-tabs-chrome.mdc +33 -0
- package/template-vite/.cursor/rules/exxat-token-discipline.mdc +109 -0
- package/template-vite/.cursor/rules/exxat-ux-discovery-protocol.mdc +202 -0
- package/template-vite/.cursor/rules/exxat-ux-principles.mdc +187 -0
- package/template-vite/.cursor/skills/exxat-accessibility/SKILL.md +282 -0
- package/template-vite/.cursor/skills/exxat-board-cards/SKILL.md +68 -0
- package/template-vite/.cursor/skills/exxat-card-vs-list-rows/SKILL.md +20 -0
- package/template-vite/.cursor/skills/exxat-centralized-list-dataset/SKILL.md +99 -0
- package/template-vite/.cursor/skills/exxat-collaboration-access/SKILL.md +35 -0
- package/template-vite/.cursor/skills/exxat-dedicated-search-surfaces/SKILL.md +45 -0
- package/template-vite/.cursor/skills/exxat-drawer-vs-dialog/SKILL.md +20 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/SKILL.md +893 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/accessibility.md +142 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/coach-marks.md +169 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/data-table-pattern.md +392 -0
- package/template-vite/.cursor/skills/exxat-fontawesome-icons/SKILL.md +31 -0
- package/template-vite/.cursor/skills/exxat-kpi-flat-band/SKILL.md +38 -0
- package/template-vite/.cursor/skills/exxat-kpi-max-four/SKILL.md +19 -0
- package/template-vite/.cursor/skills/exxat-kpi-trends/SKILL.md +29 -0
- package/template-vite/.cursor/skills/exxat-list-page-view-shells/SKILL.md +36 -0
- package/template-vite/.cursor/skills/exxat-mono-ids/SKILL.md +56 -0
- package/template-vite/.cursor/skills/exxat-primary-nav-secondary-panel/SKILL.md +49 -0
- package/template-vite/.cursor/skills/exxat-senior-ux/SKILL.md +198 -0
- package/template-vite/.cursor/skills/exxat-token-economy/SKILL.md +287 -0
- package/template-vite/.cursor/skills/exxat-ux-audit/SKILL.md +303 -0
- package/{template → template-vite}/components/ask-leo-sidebar.tsx +10 -8
- package/{template → template-vite}/components/command-menu.tsx +1 -1
- package/{template → template-vite}/components/data-views/library-folder-tree-branch.tsx +1 -1
- package/{template → template-vite}/components/dedicated-search-recents.tsx +1 -1
- package/{template → template-vite}/components/dedicated-search-url-composer.tsx +1 -1
- package/{template → template-vite}/components/library-client.tsx +1 -1
- package/{template → template-vite}/components/library-hub-client.tsx +2 -2
- package/{template → template-vite}/components/library-secondary-nav.tsx +2 -2
- package/{template → template-vite}/components/library-table.tsx +35 -27
- package/{template → template-vite}/components/new-library-item-form.tsx +1 -1
- package/{template → template-vite}/components/page-breadcrumb-trail.tsx +1 -1
- package/{template → template-vite}/components/settings-client.tsx +1 -1
- package/{template → template-vite}/components/sidebar/app-sidebar.tsx +2 -2
- package/{template → template-vite}/components/sidebar/nav-main.tsx +1 -1
- package/{template → template-vite}/components/sidebar/nav-user.tsx +1 -1
- package/{template → template-vite}/components/sidebar/secondary-nav.tsx +1 -1
- package/{template → template-vite}/components/system-banner-slot.tsx +1 -1
- package/{template → template-vite}/components/templates/discovery-hub-template.tsx +2 -2
- package/{template → template-vite}/components/templates/new-focus-template.tsx +1 -1
- package/{template → template-vite}/components/tokens-secondary-nav.tsx +2 -2
- package/{template → template-vite}/components/tokens-themes-client.tsx +1 -1
- package/{template → template-vite}/hooks/use-secondary-panel-hub-nav.ts +1 -1
- package/template-vite/index.html +49 -0
- package/template-vite/lib/next-compat.tsx +98 -0
- package/{template → template-vite}/package.json +15 -27
- package/template-vite/scripts/port-next-imports.mjs +70 -0
- package/template-vite/src/App.tsx +103 -0
- package/template-vite/src/main.tsx +50 -0
- package/{template/app/(app)/error.tsx → template-vite/src/pages/_error.tsx} +12 -24
- package/{template/app/(app)/loading.tsx → template-vite/src/pages/_loading.tsx} +4 -2
- package/template-vite/src/pages/_not-found.tsx +17 -0
- package/template-vite/src/pages/dashboard.tsx +48 -0
- package/{template/app/(app)/help/page.tsx → template-vite/src/pages/help.tsx} +3 -2
- package/{template/app/(app)/library/layout.tsx → template-vite/src/pages/library/_layout.tsx} +18 -16
- package/{template/app/(app)/library/all/page.tsx → template-vite/src/pages/library/all.tsx} +1 -1
- package/{template/app/(app)/library/new/page.tsx → template-vite/src/pages/library/new.tsx} +12 -18
- package/template-vite/src/routes.tsx +72 -0
- package/{template/app → template-vite/src/styles}/globals.css +6 -2
- package/{template → template-vite}/tsconfig.json +5 -14
- package/template-vite/vite.config.ts +52 -0
- package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +0 -53
- package/template/.agents/skills/shadcn/SKILL.md +0 -242
- package/template/.agents/skills/shadcn/agents/openai.yml +0 -5
- package/template/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
- package/template/.agents/skills/shadcn/assets/shadcn.png +0 -0
- package/template/.agents/skills/shadcn/cli.md +0 -257
- package/template/.agents/skills/shadcn/customization.md +0 -202
- package/template/.agents/skills/shadcn/evals/evals.json +0 -47
- package/template/.agents/skills/shadcn/mcp.md +0 -94
- package/template/.agents/skills/shadcn/rules/base-vs-radix.md +0 -306
- package/template/.agents/skills/shadcn/rules/composition.md +0 -195
- package/template/.agents/skills/shadcn/rules/forms.md +0 -192
- package/template/.agents/skills/shadcn/rules/icons.md +0 -101
- package/template/.agents/skills/shadcn/rules/styling.md +0 -162
- package/template/.cursor/rules/exxat-accessibility.mdc +0 -33
- package/template/.cursor/rules/exxat-data-tables.mdc +0 -32
- package/template/.cursor/rules/exxat-ds-agents.mdc +0 -26
- package/template/.cursor/rules/exxat-list-page-connected-views.mdc +0 -16
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +0 -40
- package/template/.nvmrc +0 -1
- package/template/.prettierignore +0 -7
- package/template/Logo/Exxat_Prism.svg +0 -39
- package/template/Logo/Exxat_one.svg +0 -36
- package/template/app/(app)/dashboard/loading.tsx +0 -18
- package/template/app/(app)/dashboard/page.tsx +0 -36
- package/template/app/(app)/layout.tsx +0 -77
- package/template/app/global-error.tsx +0 -63
- package/template/app/layout.tsx +0 -133
- package/template/app/page.tsx +0 -9
- package/template/docs/HANDBOOK.md +0 -187
- package/template/docs/blueprints/README.md +0 -86
- package/template/docs/blueprints/_template.md +0 -91
- package/template/docs/blueprints/board-card.md +0 -123
- package/template/docs/blueprints/data-table.md +0 -139
- package/template/docs/blueprints/key-metrics.md +0 -128
- package/template/docs/blueprints/list-page-template.md +0 -123
- package/template/docs/blueprints/page-header.md +0 -130
- package/template/docs/card-vs-rows-pattern.md +0 -36
- package/template/docs/collaboration-access-pattern.md +0 -116
- package/template/docs/command-menu-pattern.md +0 -45
- package/template/docs/component-selection-guide.md +0 -224
- package/template/docs/components-audit-2026-05.md +0 -158
- package/template/docs/consumer-upgrade-checklist.md +0 -52
- package/template/docs/data-views-pattern.md +0 -185
- package/template/docs/drawer-vs-dialog-pattern.md +0 -50
- package/template/docs/glossary.md +0 -59
- package/template/docs/hub-supported-views-pattern.md +0 -53
- package/template/docs/jobs/README.md +0 -59
- package/template/docs/jobs/record-detail.md +0 -177
- package/template/docs/kpi-flat-band-pattern.md +0 -57
- package/template/docs/kpi-strip-max-four-pattern.md +0 -30
- package/template/docs/kpi-trend-pattern.md +0 -58
- package/template/docs/large-dataset-strategy.md +0 -155
- package/template/docs/library-hub-header-pattern.md +0 -25
- package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +0 -95
- package/template/docs/migrations/0002-exxat-token-namespace.md +0 -154
- package/template/docs/migrations/0003-globals-css-canonical.md +0 -110
- package/template/docs/migrations/README.md +0 -100
- package/template/docs/migrations/_template.md +0 -64
- package/template/docs/modern-saas-patterns.md +0 -165
- package/template/docs/perf-memory-pattern.md +0 -206
- package/template/docs/reference-implementations.md +0 -153
- package/template/docs/shell-surface-elevation-pattern.md +0 -52
- package/template/docs/token-taxonomy.md +0 -416
- package/template/docs/voice-and-tone.md +0 -262
- package/template/ecosystem.config.cjs +0 -32
- package/template/next.config.mjs +0 -216
- package/template/postcss.config.mjs +0 -8
- package/template/public/favicon/favicon.ico +0 -0
- package/template/tests/setup.ts +0 -26
- package/template/vitest.config.ts +0 -18
- /package/{template → template-vite}/.cursor/rules/exxat-dashboard-view-charts.mdc +0 -0
- /package/{template → template-vite}/.prettierrc +0 -0
- /package/{template → template-vite}/AGENTS.md +0 -0
- /package/{template → template-vite}/README.md +0 -0
- /package/{template → template-vite}/components/.gitkeep +0 -0
- /package/{template → template-vite}/components/ask-leo-composer.tsx +0 -0
- /package/{template → template-vite}/components/brand-color-picker.tsx +0 -0
- /package/{template → template-vite}/components/chart-area-interactive.tsx +0 -0
- /package/{template → template-vite}/components/charts-overview.tsx +0 -0
- /package/{template → template-vite}/components/collaboration-access-flow.tsx +0 -0
- /package/{template → template-vite}/components/columns-client.tsx +0 -0
- /package/{template → template-vite}/components/columns-showcase.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-promo-banner.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-quota-progress-card.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-report-charts.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-section-heading.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-tabs.tsx +0 -0
- /package/{template → template-vite}/components/data-table/filter-date-calendar.tsx +0 -0
- /package/{template → template-vite}/components/data-table/filter-text-value-input.tsx +0 -0
- /package/{template → template-vite}/components/data-table/index.tsx +0 -0
- /package/{template → template-vite}/components/data-table/pagination.tsx +0 -0
- /package/{template → template-vite}/components/data-table/types.ts +0 -0
- /package/{template → template-vite}/components/data-table/use-table-state.test.ts +0 -0
- /package/{template → template-vite}/components/data-table/use-table-state.ts +0 -0
- /package/{template → template-vite}/components/data-views/board-card-primitives.tsx +0 -0
- /package/{template → template-vite}/components/data-views/data-row-list.tsx +0 -0
- /package/{template → template-vite}/components/data-views/finder-panel-view.tsx +0 -0
- /package/{template → template-vite}/components/data-views/folder-grid-view.tsx +0 -0
- /package/{template → template-vite}/components/data-views/hub-table.tsx +0 -0
- /package/{template → template-vite}/components/data-views/index.ts +0 -0
- /package/{template → template-vite}/components/data-views/list-page-board-card.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-board-template.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-connected-view-body.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-details-placeholder.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-hub-chrome.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-hub-tokens.ts +0 -0
- /package/{template → template-vite}/components/data-views/list-page-tree-column-header.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-tree-panel-shell.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-view-frame.tsx +0 -0
- /package/{template → template-vite}/components/data-views/os-folder-glyph.tsx +0 -0
- /package/{template → template-vite}/components/data-views/outline-tree-menu.tsx +0 -0
- /package/{template → template-vite}/components/data-views/table-cells.tsx +0 -0
- /package/{template → template-vite}/components/dev-chunk-load-recovery.tsx +0 -0
- /package/{template → template-vite}/components/export-drawer.test.tsx +0 -0
- /package/{template → template-vite}/components/export-drawer.tsx +0 -0
- /package/{template → template-vite}/components/exxat-product-logo.tsx +0 -0
- /package/{template → template-vite}/components/folder-details-shell.tsx +0 -0
- /package/{template → template-vite}/components/form-layout-01.tsx +0 -0
- /package/{template → template-vite}/components/hub-tree-panel-view.tsx +0 -0
- /package/{template → template-vite}/components/invite-collaborators-drawer.tsx +0 -0
- /package/{template → template-vite}/components/key-metrics-ask-leo-bridge.tsx +0 -0
- /package/{template → template-vite}/components/key-metrics.tsx +0 -0
- /package/{template → template-vite}/components/leo-insight-indicator.tsx +0 -0
- /package/{template → template-vite}/components/leo-typing-dots.tsx +0 -0
- /package/{template → template-vite}/components/library-board-view.tsx +0 -0
- /package/{template → template-vite}/components/library-dashboard-charts.tsx +0 -0
- /package/{template → template-vite}/components/library-favorite-button.tsx +0 -0
- /package/{template → template-vite}/components/library-new-folder-sheet.tsx +0 -0
- /package/{template → template-vite}/components/library-os-folder-view.tsx +0 -0
- /package/{template → template-vite}/components/library-page-header.tsx +0 -0
- /package/{template → template-vite}/components/library-panel-activator.tsx +0 -0
- /package/{template → template-vite}/components/list-hub-status-badge.tsx +0 -0
- /package/{template → template-vite}/components/list-page-dashboard-charts.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/getting-started.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/index.ts +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-01.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-02.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-03.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-04.tsx +0 -0
- /package/{template → template-vite}/components/page-header.tsx +0 -0
- /package/{template → template-vite}/components/product-switcher.tsx +0 -0
- /package/{template → template-vite}/components/product-wordmark.tsx +0 -0
- /package/{template → template-vite}/components/settings-appearance-card.tsx +0 -0
- /package/{template → template-vite}/components/settings-form-row.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/app-sidebar-dynamic.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/index.ts +0 -0
- /package/{template → template-vite}/components/sidebar/nav-documents.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/nav-secondary.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/secondary-panel.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-auto-collapse.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-auto-open.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-shell.tsx +0 -0
- /package/{template → template-vite}/components/site-header.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/column-row.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/draggable-list.ts +0 -0
- /package/{template → template-vite}/components/table-properties/drawer-button.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/drawer.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/filter-card.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/index.ts +0 -0
- /package/{template → template-vite}/components/table-properties/sort-card.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/types.ts +0 -0
- /package/{template → template-vite}/components/task-list-panel.tsx +0 -0
- /package/{template → template-vite}/components/task-priority-badge.tsx +0 -0
- /package/{template → template-vite}/components/templates/dedicated-search-landing-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/dedicated-search-results-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/list-page.tsx +0 -0
- /package/{template → template-vite}/components/templates/nested-secondary-panel-shell.tsx +0 -0
- /package/{template → template-vite}/components/templates/primary-page-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/secondary-panel-hub-template.tsx +0 -0
- /package/{template → template-vite}/components/theme-color-sync.tsx +0 -0
- /package/{template → template-vite}/components/theme-provider.tsx +0 -0
- /package/{template → template-vite}/components/tinted-icon-disc.tsx +0 -0
- /package/{template → template-vite}/components/tokens-hub-auxiliary-views.tsx +0 -0
- /package/{template → template-vite}/components/tokens-themes-section.tsx +0 -0
- /package/{template → template-vite}/components/ui/accordion.tsx +0 -0
- /package/{template → template-vite}/components/ui/ai-thinking-surface.tsx +0 -0
- /package/{template → template-vite}/components/ui/alert-dialog.tsx +0 -0
- /package/{template → template-vite}/components/ui/avatar.tsx +0 -0
- /package/{template → template-vite}/components/ui/badge.tsx +0 -0
- /package/{template → template-vite}/components/ui/banner.tsx +0 -0
- /package/{template → template-vite}/components/ui/breadcrumb.tsx +0 -0
- /package/{template → template-vite}/components/ui/button.tsx +0 -0
- /package/{template → template-vite}/components/ui/calendar.tsx +0 -0
- /package/{template → template-vite}/components/ui/card.tsx +0 -0
- /package/{template → template-vite}/components/ui/chart.tsx +0 -0
- /package/{template → template-vite}/components/ui/checkbox.tsx +0 -0
- /package/{template → template-vite}/components/ui/coach-mark.tsx +0 -0
- /package/{template → template-vite}/components/ui/collapsible.tsx +0 -0
- /package/{template → template-vite}/components/ui/command.tsx +0 -0
- /package/{template → template-vite}/components/ui/context-menu.tsx +0 -0
- /package/{template → template-vite}/components/ui/date-picker-field.tsx +0 -0
- /package/{template → template-vite}/components/ui/dialog.tsx +0 -0
- /package/{template → template-vite}/components/ui/dot-pattern.tsx +0 -0
- /package/{template → template-vite}/components/ui/drag-handle-grip.tsx +0 -0
- /package/{template → template-vite}/components/ui/dropdown-menu.tsx +0 -0
- /package/{template → template-vite}/components/ui/field.tsx +0 -0
- /package/{template → template-vite}/components/ui/form.tsx +0 -0
- /package/{template → template-vite}/components/ui/hover-card.tsx +0 -0
- /package/{template → template-vite}/components/ui/input-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/input-mask.tsx +0 -0
- /package/{template → template-vite}/components/ui/input.tsx +0 -0
- /package/{template → template-vite}/components/ui/kbd.tsx +0 -0
- /package/{template → template-vite}/components/ui/label.tsx +0 -0
- /package/{template → template-vite}/components/ui/leo-icon.tsx +0 -0
- /package/{template → template-vite}/components/ui/payment-card-fields.tsx +0 -0
- /package/{template → template-vite}/components/ui/popover.tsx +0 -0
- /package/{template → template-vite}/components/ui/radio-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/resizable.tsx +0 -0
- /package/{template → template-vite}/components/ui/scroll-area.tsx +0 -0
- /package/{template → template-vite}/components/ui/select.tsx +0 -0
- /package/{template → template-vite}/components/ui/selection-tile-grid.tsx +0 -0
- /package/{template → template-vite}/components/ui/separator.tsx +0 -0
- /package/{template → template-vite}/components/ui/sheet.tsx +0 -0
- /package/{template → template-vite}/components/ui/sidebar.tsx +0 -0
- /package/{template → template-vite}/components/ui/skeleton.tsx +0 -0
- /package/{template → template-vite}/components/ui/slider.tsx +0 -0
- /package/{template → template-vite}/components/ui/sonner.tsx +0 -0
- /package/{template → template-vite}/components/ui/status-badge.tsx +0 -0
- /package/{template → template-vite}/components/ui/table.tsx +0 -0
- /package/{template → template-vite}/components/ui/tabs.tsx +0 -0
- /package/{template → template-vite}/components/ui/textarea.tsx +0 -0
- /package/{template → template-vite}/components/ui/tip.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle-switch.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle.tsx +0 -0
- /package/{template → template-vite}/components/ui/tooltip.tsx +0 -0
- /package/{template → template-vite}/components/ui/view-segmented-control.tsx +0 -0
- /package/{template → template-vite}/components.json +0 -0
- /package/{template → template-vite}/contexts/chart-variant-context.tsx +0 -0
- /package/{template → template-vite}/contexts/command-menu-context.tsx +0 -0
- /package/{template → template-vite}/contexts/dashboard-view-context.tsx +0 -0
- /package/{template → template-vite}/contexts/product-context.tsx +0 -0
- /package/{template → template-vite}/contexts/system-banner-context.tsx +0 -0
- /package/{template → template-vite}/eslint.config.mjs +0 -0
- /package/{template → template-vite}/fontawesome-subset.manifest.json +0 -0
- /package/{template → template-vite}/hooks/.gitkeep +0 -0
- /package/{template → template-vite}/hooks/use-app-theme.ts +0 -0
- /package/{template → template-vite}/hooks/use-coach-mark.ts +0 -0
- /package/{template → template-vite}/hooks/use-location-hash.ts +0 -0
- /package/{template → template-vite}/hooks/use-mobile.ts +0 -0
- /package/{template → template-vite}/hooks/use-mod-key-label.ts +0 -0
- /package/{template → template-vite}/hooks/use-sidebar-reflow-zoom.ts +0 -0
- /package/{template → template-vite}/lib/.gitkeep +0 -0
- /package/{template → template-vite}/lib/ask-leo-route-context.ts +0 -0
- /package/{template → template-vite}/lib/chart-keyboard-selection.test.ts +0 -0
- /package/{template → template-vite}/lib/chart-keyboard-selection.ts +0 -0
- /package/{template → template-vite}/lib/chart-line-dash.ts +0 -0
- /package/{template → template-vite}/lib/chunk-load-error.ts +0 -0
- /package/{template → template-vite}/lib/coach-mark-registry.ts +0 -0
- /package/{template → template-vite}/lib/collaborator-access.ts +0 -0
- /package/{template → template-vite}/lib/command-menu-config.ts +0 -0
- /package/{template → template-vite}/lib/command-menu-search-data.ts +0 -0
- /package/{template → template-vite}/lib/conditional-rule-match.ts +0 -0
- /package/{template → template-vite}/lib/dashboard-customize-coach-mark.ts +0 -0
- /package/{template → template-vite}/lib/dashboard-layout-merge.ts +0 -0
- /package/{template → template-vite}/lib/data-list-display-options.ts +0 -0
- /package/{template → template-vite}/lib/data-list-persistence.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view-registry.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view-surface.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view.ts +0 -0
- /package/{template → template-vite}/lib/data-view-dashboard-storage.ts +0 -0
- /package/{template → template-vite}/lib/date-filter.ts +0 -0
- /package/{template → template-vite}/lib/dedicated-search-recents.ts +0 -0
- /package/{template → template-vite}/lib/dedicated-search-url.ts +0 -0
- /package/{template → template-vite}/lib/dev-log.test.ts +0 -0
- /package/{template → template-vite}/lib/dev-log.ts +0 -0
- /package/{template → template-vite}/lib/discovery-hub.ts +0 -0
- /package/{template → template-vite}/lib/editable-target.ts +0 -0
- /package/{template → template-vite}/lib/exxat-palette.json +0 -0
- /package/{template → template-vite}/lib/exxat-palette.ts +0 -0
- /package/{template → template-vite}/lib/floating-sheet-panel.ts +0 -0
- /package/{template → template-vite}/lib/full-hub-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/hub-connected-view-renderers.ts +0 -0
- /package/{template → template-vite}/lib/initials-from-name.ts +0 -0
- /package/{template → template-vite}/lib/library-authoring.ts +0 -0
- /package/{template → template-vite}/lib/library-dedicated-search.ts +0 -0
- /package/{template → template-vite}/lib/library-hub-search.ts +0 -0
- /package/{template → template-vite}/lib/library-nav.ts +0 -0
- /package/{template → template-vite}/lib/library-recent-searches.ts +0 -0
- /package/{template → template-vite}/lib/library-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/list-hub-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/list-page-table-properties.ts +0 -0
- /package/{template → template-vite}/lib/list-status-badges.ts +0 -0
- /package/{template → template-vite}/lib/logo-dev.ts +0 -0
- /package/{template → template-vite}/lib/mailto.ts +0 -0
- /package/{template → template-vite}/lib/mock/dashboard.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-folders.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-header-collaborators.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-inspector.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-kpi.ts +0 -0
- /package/{template → template-vite}/lib/mock/library.ts +0 -0
- /package/{template → template-vite}/lib/mock/navigation.tsx +0 -0
- /package/{template → template-vite}/lib/motion-ui.ts +0 -0
- /package/{template → template-vite}/lib/product-brand.ts +0 -0
- /package/{template → template-vite}/lib/raf-throttle.ts +0 -0
- /package/{template → template-vite}/lib/row-height.ts +0 -0
- /package/{template → template-vite}/lib/sidebar-state-cookie.ts +0 -0
- /package/{template → template-vite}/lib/stock-portrait.ts +0 -0
- /package/{template → template-vite}/lib/table-state-lifecycle.ts +0 -0
- /package/{template → template-vite}/lib/utils.test.ts +0 -0
- /package/{template → template-vite}/lib/utils.ts +0 -0
- /package/{template → template-vite}/public/.gitkeep +0 -0
- /package/{template → template-vite}/public/Illustration/Rotation.svg +0 -0
- /package/{template → template-vite}/public/avatars/user.svg +0 -0
- /package/{template/public → template-vite/public/favicon}/favicon.ico +0 -0
- /package/{template/app → template-vite/public}/favicon.ico +0 -0
- /package/{template → template-vite}/public/folders/icons8-folder-windows-11.svg +0 -0
- /package/{template → template-vite}/public/logos/exxat-one.svg +0 -0
- /package/{template → template-vite}/public/logos/exxat-prism.svg +0 -0
- /package/{template → template-vite}/public/mock-schools/emory.svg +0 -0
- /package/{template → template-vite}/public/mock-schools/rush.svg +0 -0
- /package/{template → template-vite}/scripts/fontawesome-subset-audit.mjs +0 -0
- /package/{template → template-vite}/scripts/pm2-startup-macos.sh +0 -0
- /package/{template → template-vite}/skills-lock.json +0 -0
- /package/{template/app/(app)/columns/page.tsx → template-vite/src/pages/columns.tsx} +0 -0
- /package/{template/app/(app)/library/find/page.tsx → template-vite/src/pages/library/find.tsx} +0 -0
- /package/{template/app/(app)/library/page.tsx → template-vite/src/pages/library/index.tsx} +0 -0
- /package/{template/app/(app)/library/list/page.tsx → template-vite/src/pages/library/list.tsx} +0 -0
- /package/{template/app/(app)/settings/page.tsx → template-vite/src/pages/settings.tsx} +0 -0
- /package/{template/app/(app)/tokens-themes/page.tsx → template-vite/src/pages/tokens-themes.tsx} +0 -0
- /package/{template → template-vite}/stores/app-store.ts +0 -0
- /package/{template → template-vite}/types/react-payment-inputs.d.ts +0 -0
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: exxat-senior-ux
|
|
3
3
|
description: >-
|
|
4
|
-
Make the agent behave like a senior UX designer —
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
Make the agent behave like a senior UX designer — STOP before writing
|
|
5
|
+
code, understand the problem, study how modern SaaS solves the same job,
|
|
6
|
+
propose a design brief, WAIT for user go-ahead, then build. Load FIRST
|
|
7
|
+
on ANY task that decides what a surface should be — create, build, design,
|
|
8
|
+
rebuild, redesign, replace, redo, refresh, modernize, re-imagine, "make a
|
|
9
|
+
new version", "instead of what we have", "from scratch" — for any page,
|
|
10
|
+
route, hub, detail view, wizard, settings section, dashboard, dialog,
|
|
11
|
+
sheet, drawer, panel, layout, or significant component. Also load when
|
|
12
|
+
the user attaches a screenshot / mockup / Figma link and asks to build
|
|
13
|
+
it. Load BEFORE opening AGENTS.md, blueprints, or any other DS doc.
|
|
9
14
|
user-invocable: true
|
|
10
15
|
---
|
|
11
16
|
|
|
@@ -17,15 +22,32 @@ products). You design for the **user's job**, not the user's words.
|
|
|
17
22
|
|
|
18
23
|
## When to load this skill
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- The user attaches a screenshot or mockup.
|
|
23
|
-
- The user asks "how should I build X" / "design X" / "make it modern".
|
|
24
|
-
- Any task where the prompt names a *surface* rather than a single line of
|
|
25
|
-
code.
|
|
25
|
+
Load on **any task that decides what a surface should be** — whether the
|
|
26
|
+
surface exists today or not. The user's verb is the strongest signal:
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
| Phrase in the prompt | Load? |
|
|
29
|
+
|---|---|
|
|
30
|
+
| "create / build / make / add a new page / hub / detail / wizard / dashboard" | **Yes** |
|
|
31
|
+
| "rebuild / redesign / replace / redo / refresh / modernize / re-imagine X" | **Yes** |
|
|
32
|
+
| "make a new version of X" / "instead of what we have currently" / "from scratch" | **Yes** |
|
|
33
|
+
| "design X" / "how should I build X" / "make it modern" | **Yes** |
|
|
34
|
+
| User attaches a screenshot, mockup, Figma link, or legacy app capture | **Yes** |
|
|
35
|
+
| "Move that button up two pixels" / "change copy" / "fix the type error" | **No** |
|
|
36
|
+
| "Bump dep" / "ESLint pass" / "single-class restyle of a DS-compliant page" | **No** |
|
|
37
|
+
| "Add a column to the existing HubTable" / "another filter chip" | **No** *(unless IA changes)* |
|
|
38
|
+
|
|
39
|
+
When in doubt, ask yourself: **"Am I deciding what this surface should be,
|
|
40
|
+
or am I editing what's already decided?"** Decide → load. Edit → don't.
|
|
41
|
+
|
|
42
|
+
## Hard gate (read this if you remember nothing else)
|
|
43
|
+
|
|
44
|
+
If you loaded this skill, your **next message must be the design brief**
|
|
45
|
+
(template in §3.1). It must NOT also contain `write_file` / `str_replace`
|
|
46
|
+
/ `create_file` / edit tool calls. End the turn after the brief with
|
|
47
|
+
"Ready to build — confirm or edit." The user's reply is your green light.
|
|
48
|
+
|
|
49
|
+
Silence, a thumbs-up, or "ok" all count as confirmation. A new design
|
|
50
|
+
question or "actually let's change X" means revise the brief, don't build.
|
|
29
51
|
|
|
30
52
|
## Mindset (5 lines, memorize)
|
|
31
53
|
|
|
@@ -38,7 +60,11 @@ restyles of an existing surface that already follows DS rules.
|
|
|
38
60
|
5. **The DS is the vocabulary, not the design.** Composition is the means;
|
|
39
61
|
clarity for the user is the end.
|
|
40
62
|
|
|
41
|
-
## The five-step protocol (mandatory on
|
|
63
|
+
## The five-step protocol (mandatory on any surface decision)
|
|
64
|
+
|
|
65
|
+
The five steps are **sequential checkpoints**, not a single turn. Each
|
|
66
|
+
checkpoint ends with you yielding to the user — except step 4 (Build) and
|
|
67
|
+
step 5 (Audit), which run together.
|
|
42
68
|
|
|
43
69
|
### 1. Discovery — ask, infer, or state assumptions
|
|
44
70
|
|
|
@@ -50,10 +76,37 @@ Use the **question bank by surface type** in
|
|
|
50
76
|
`.cursor/rules/exxat-ux-discovery-protocol.mdc`.
|
|
51
77
|
|
|
52
78
|
If the user said "no questions, build it", still output the brief + your
|
|
53
|
-
assumptions
|
|
79
|
+
assumptions.
|
|
54
80
|
|
|
55
81
|
### 2. Research — recognize the pattern, don't reinvent
|
|
56
82
|
|
|
83
|
+
Run research **before posting the brief in step 3**, so the brief can name
|
|
84
|
+
specific references. (See research methods below.)
|
|
85
|
+
|
|
86
|
+
### 3. Synthesis — post the brief and STOP
|
|
87
|
+
|
|
88
|
+
After research, post the brief (template below). **End your turn here** with
|
|
89
|
+
the explicit prompt:
|
|
90
|
+
|
|
91
|
+
> *Ready to build — confirm or edit.*
|
|
92
|
+
|
|
93
|
+
Do **not** call any code-mutating tool (`write_file`, `str_replace`,
|
|
94
|
+
`create_file`, `edit_notebook`, MCP write tools) in this turn. The user's
|
|
95
|
+
next message is your green light.
|
|
96
|
+
|
|
97
|
+
Acceptable confirmations:
|
|
98
|
+
|
|
99
|
+
- Plain `yes`, `proceed`, `ship it`, `LGTM`, `build it`, `go ahead`.
|
|
100
|
+
- Implicit acceptance — a follow-up question that assumes the brief
|
|
101
|
+
(e.g. "and add a section for X").
|
|
102
|
+
- Silence followed by a new design question — treat as accepted.
|
|
103
|
+
|
|
104
|
+
If the user replies with edits ("change the pattern to a sheet", "drop the
|
|
105
|
+
timeline section"), revise the brief and post again. Only build after a
|
|
106
|
+
confirmed brief.
|
|
107
|
+
|
|
108
|
+
### Research methods (used inside step 2)
|
|
109
|
+
|
|
57
110
|
1. Check this repo first — does a canonical reference solve the same **job**?
|
|
58
111
|
See `apps/web/docs/jobs/`.
|
|
59
112
|
2. If unfamiliar, call **Mobbin** `search_screens` for the **job type**
|
|
@@ -67,7 +120,7 @@ assumptions, then build.
|
|
|
67
120
|
5. Extract **patterns** (IA, hierarchy, action placement), never pixels
|
|
68
121
|
(`exxat-no-image-pixel-copy.mdc`).
|
|
69
122
|
|
|
70
|
-
### 3.
|
|
123
|
+
### 3.1 Brief template (copy verbatim into chat)
|
|
71
124
|
|
|
72
125
|
```
|
|
73
126
|
Problem: <one sentence — the user's pain, not the feature>
|
|
@@ -82,7 +135,7 @@ Out of scope: <what this surface intentionally does not do>
|
|
|
82
135
|
Open questions: <max 2; ideally 0>
|
|
83
136
|
```
|
|
84
137
|
|
|
85
|
-
|
|
138
|
+
End the turn with: *Ready to build — confirm or edit.*
|
|
86
139
|
|
|
87
140
|
### 4. Build — compose, don't invent
|
|
88
141
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Global command palette (⌘K)
|
|
2
2
|
|
|
3
|
-
**Code:** `components/command-menu.tsx`, config **`buildCommandMenuConfig()`** in **`lib/command-menu-config.ts`**, wired in **`
|
|
3
|
+
**Code:** `components/command-menu.tsx`, config **`buildCommandMenuConfig()`** in **`lib/command-menu-config.ts`**, wired in **`src/App.tsx`** via **`CommandMenuProvider`**. Searchable row data is built in **`lib/command-menu-search-data.ts`** (not inside the shell component).
|
|
4
4
|
|
|
5
5
|
## Role
|
|
6
6
|
|
|
@@ -34,7 +34,7 @@ The command menu is the app’s **global search and AI entry**—one place to ju
|
|
|
34
34
|
| Palette UI | `components/command-menu.tsx` |
|
|
35
35
|
| Static groups + `buildCommandMenuConfig` | `lib/command-menu-config.ts` (`CommandMenuGroup.searchOnly`) |
|
|
36
36
|
| Row → menu items (placements, etc.) | `lib/command-menu-search-data.ts` |
|
|
37
|
-
| Provider + `dataGroups` | `
|
|
37
|
+
| Provider + `dataGroups` | `src/App.tsx` |
|
|
38
38
|
|
|
39
39
|
## Sidebar
|
|
40
40
|
|
|
@@ -21,7 +21,7 @@ Overwrites only **`.cursor/skills/exxat-*`** and **`docs/exxat-ds/*.md`** (inclu
|
|
|
21
21
|
|
|
22
22
|
The npm package includes a full Next.js reference under:
|
|
23
23
|
|
|
24
|
-
**`node_modules/@exxatdesignux/ui/template/`**
|
|
24
|
+
**`node_modules/@exxatdesignux/ui/template-vite/`**
|
|
25
25
|
|
|
26
26
|
Use it when you need to know **what files exist**, **how shims re-export** `@exxatdesignux/ui`, or **what AGENTS / layout** patterns look like for the current release. Porting is manual: diff template vs your repo and apply intentional changes (imports, new components, CSS entrypoints).
|
|
27
27
|
|
|
@@ -25,7 +25,7 @@ contract.**
|
|
|
25
25
|
| **Review a record's full state** | [`record-detail.md`](./record-detail.md) | Students / Placements / Library detail |
|
|
26
26
|
| **Triage a list of records** (find at-risk / actionable) | *future* | `PlacementsClient`, `ComplianceClient` |
|
|
27
27
|
| **Compose / create a new record** | *future* | `new-library-item-form.tsx` |
|
|
28
|
-
| **Configure preferences or workspace settings** | *future* | `
|
|
28
|
+
| **Configure preferences or workspace settings** | *future* | `src/views/settings.tsx` |
|
|
29
29
|
| **Scan many metrics for anomalies** | *future* | Dashboard route, `DashboardTabs` |
|
|
30
30
|
| **Search / find anything** | *future* | `CommandMenu`, `DedicatedSearch*` |
|
|
31
31
|
| **Onboarding / first-run setup** | *future* | `getting-started.tsx`, `CoachMark` |
|
|
@@ -1,206 +1,171 @@
|
|
|
1
|
-
# Dev memory tuning for
|
|
1
|
+
# Dev memory tuning for Vite + Node 24
|
|
2
2
|
|
|
3
3
|
> **Audience:** humans + AI agents.
|
|
4
|
-
> **Companion to:** [`HANDBOOK.md`](./HANDBOOK.md). Read this when `
|
|
5
|
-
> RSS climbs past ~
|
|
6
|
-
>
|
|
4
|
+
> **Companion to:** [`HANDBOOK.md`](./HANDBOOK.md). Read this when `pnpm dev`
|
|
5
|
+
> RSS climbs past ~1.5 GB or when two designers are running dev servers on
|
|
6
|
+
> one machine.
|
|
7
7
|
|
|
8
|
-
A fresh `
|
|
9
|
-
the settings below. Without them
|
|
10
|
-
|
|
8
|
+
A fresh `pnpm dev` against this app stabilizes around **~250–500 MB RSS**
|
|
9
|
+
with the settings below. Without them — or running multiple Vite
|
|
10
|
+
instances against the same monorepo — total system memory drifts to
|
|
11
|
+
1.5 GB+ per process and designers' laptops start to swap.
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
> **History:** before PR-6 (May 2026) `apps/web` ran on Next.js + Turbopack
|
|
14
|
+
> with a 1.4–4 GB baseline per dev server. Migrating to Vite + react-router
|
|
15
|
+
> dropped the steady-state RSS by **8×** and cold start from 8–12 s to
|
|
16
|
+
> 150–300 ms. The full migration story is in commits `49e9adf` (PR-1) →
|
|
17
|
+
> `d16ec77` (PR-6).
|
|
18
|
+
|
|
19
|
+
## 1. The four knobs that matter
|
|
13
20
|
|
|
14
21
|
| # | Knob | Why it matters | Where it lives |
|
|
15
22
|
|---|------|----------------|----------------|
|
|
16
|
-
| 1 | `
|
|
17
|
-
| 2 | `
|
|
18
|
-
| 3 | `
|
|
19
|
-
| 4 | `
|
|
20
|
-
| 5 | `experimental.webpackMemoryOptimizations: true` | Drops large in-memory webpack caches at the cost of slightly slower rebuilds. **Only the `pnpm dev:webpack` fallback uses webpack** — Turbopack ignores this flag. Keep it on for the rare cases where the webpack path is needed. | `next.config.mjs` |
|
|
21
|
-
| 6 | `target: ES2022` (tsconfig) | The TS compiler emits less polyfill scaffolding for `async/await`, optional chaining, nullish coalescing, etc. tsserver in-memory AST shrinks proportionally. Safe with React 19 + Next 16 + Node 24. | `tsconfig.json` |
|
|
22
|
-
|
|
23
|
-
## 2. NODE_OPTIONS propagation
|
|
23
|
+
| 1 | `dev-guard` predev hook | Blocks a second `pnpm dev` from booting against the same checkout. The #1 source of memory inflation in practice — two parallel Vite servers double total system RSS for zero throughput. | `package.json` `predev*` scripts → `exxat-ui dev-guard` (in `packages/ui/consumer-extras/scripts/dev-guard.mjs`) |
|
|
24
|
+
| 2 | `optimizeDeps.include` for hot deps | Pre-bundles `react`, `react-dom`, `react-router-dom` so the first request doesn't trigger a 600+ ms esbuild dep-scan. Drops first-paint TTFB by ~30%. | `vite.config.ts` |
|
|
25
|
+
| 3 | `optimizeDeps.exclude: ["@exxatdesignux/ui"]` | The shared UI package is a pnpm workspace package. Eager pre-bundling fights pnpm's strict node_modules layout (esbuild can't resolve `radix-ui`, `cmdk`, etc. when crawling the package's own `dist/`). Excluding it lets Vite resolve through the consumer's module resolver — which sees peer deps correctly. | `vite.config.ts` |
|
|
26
|
+
| 4 | `resolve.dedupe: ["react", "react-dom", "react-router-dom"]` | Prevents two React instances from being bundled when `apps/web` and `packages/ui` resolve different versions in pnpm. The classic "Invalid hook call" runtime error and a hidden 30+ MB heap duplicate. | `vite.config.ts` |
|
|
24
27
|
|
|
25
|
-
`NODE_OPTIONS` is
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
`NODE_OPTIONS` is **not** required under Vite — V8's default heap is fine
|
|
29
|
+
for a 250–500 MB process. The Next-era `--max-old-space-size=6144` was
|
|
30
|
+
fighting Turbopack's mmap'd FS cache; that whole class of problem is gone.
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
because Next dev is only run from POSIX shells.
|
|
31
|
-
- **PM2 daemon:** set in `ecosystem.config.cjs` `env` (which becomes the child
|
|
32
|
-
environment).
|
|
33
|
-
- **CI:** set in the workflow `env:` block on the same step that runs `next`.
|
|
34
|
-
- **VS Code / Cursor terminals:** these inherit the parent shell env, so the
|
|
35
|
-
`package.json` script is enough.
|
|
32
|
+
## 2. Don't run two Vite servers against the same checkout
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
A single `vite` process (Vite + the React plugin + Tailwind plugin)
|
|
35
|
+
stabilizes at ~280 MB RSS once the route tree is warm. Two parallel
|
|
36
|
+
servers stabilize at ~560 MB, three at ~840 MB — they don't share dep
|
|
37
|
+
caches across processes.
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
The `predev` hook (`exxat-ui dev-guard`) detects an already-running
|
|
40
|
+
`vite` instance under the same checkout and exits with a friendly
|
|
41
|
+
message instead of starting a second one. Unconditionally honour it —
|
|
42
|
+
do not bypass with `--no-predev` unless you've explicitly killed the
|
|
43
|
+
other server.
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
To check what's running:
|
|
42
46
|
|
|
43
47
|
```bash
|
|
44
|
-
|
|
45
|
-
# 3.2G .next
|
|
48
|
+
ps aux | grep -E "vite/bin/vite" | grep -v grep
|
|
46
49
|
```
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
**Do not disable** the FS cache (`turbopackFileSystemCacheForDev: false`) — cold-start dev becomes painful (~15–30 s every restart on this app). Instead, **bust the cache** when it grows past 1–2 GB:
|
|
51
|
+
If you legitimately need two designer servers (e.g. comparing two
|
|
52
|
+
branches side-by-side), use the dedicated alternate ports:
|
|
51
53
|
|
|
52
54
|
```bash
|
|
53
|
-
pnpm
|
|
54
|
-
pnpm dev:
|
|
55
|
+
pnpm dev # http://localhost:3000
|
|
56
|
+
pnpm dev:3001 # http://localhost:3001
|
|
57
|
+
pnpm dev:3005 # http://localhost:3005
|
|
55
58
|
```
|
|
56
59
|
|
|
57
|
-
|
|
60
|
+
These all share the same `dev-guard` so a third can't sneak in.
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
- `.next` is > 2 GB and dev memory is climbing.
|
|
61
|
-
- HMR starts skipping updates or compilation gets stuck on a stale module.
|
|
62
|
+
## 3. Clearing the dep cache
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
Vite caches pre-bundled deps under `node_modules/.vite/`. The cache is
|
|
65
|
+
small (10–50 MB typical) but can grow stale after major dependency
|
|
66
|
+
changes:
|
|
64
67
|
|
|
65
68
|
```bash
|
|
66
|
-
pnpm clean
|
|
69
|
+
pnpm clean:cache # removes node_modules/.vite
|
|
70
|
+
pnpm dev:fresh # clean + restart
|
|
67
71
|
```
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
Bust the cache when:
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
- A `pnpm install` changed `@exxatdesignux/ui` or any framework dep.
|
|
76
|
+
- HMR starts skipping updates.
|
|
77
|
+
- The browser console shows `[vite] (client) Re-optimizing dependencies` looping repeatedly.
|
|
72
78
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
If you see two `next-server` lineages in `ps`, check:
|
|
79
|
+
For a full nuke (build artefacts too):
|
|
76
80
|
|
|
77
81
|
```bash
|
|
78
|
-
|
|
79
|
-
lsof -p <pid> | grep '\.next/dev/cache' | head -5 # which checkout owns it
|
|
82
|
+
pnpm clean
|
|
80
83
|
```
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
| Scenario | Symptom | Fix |
|
|
85
|
-
|----------|---------|-----|
|
|
86
|
-
| Two checkouts of the same monorepo (e.g. `DS_Workspace/` and `Exxat-DS-Workspace/`) both running `pnpm dev:web` | Two `next-server` parents, both in `apps/web/.next/...` paths but on different absolute roots | Quit one. Pin to a single checkout per machine. |
|
|
87
|
-
| A customer app (e.g. `test-9`) + the monorepo `apps/web` running at the same time | Different cache hashes (`ee6e79b1/`) under different roots | Stop whichever you're not actively touching: `pm2 stop exxat-ds` or `Ctrl+C` |
|
|
88
|
-
| A stale pm2 daemon from a prior `nvm use 22` session left running after upgrading to Node 24 | One Node-22 + one Node-24 dev server | `pm2 delete exxat-ds` then `pnpm dev:daemon` to re-launch under Node 24 |
|
|
89
|
-
| `next build` running in another tab while `next dev` is up | Three or four `next-server` for the duration of the build | Wait for the build, or kill the dev server until the build is done |
|
|
90
|
-
|
|
91
|
-
## 5. Two `next-server` processes per app is normal
|
|
85
|
+
## 4. Diagnose a memory regression
|
|
92
86
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
- **`next-server` (main)** — HTTP entry, watcher, router.
|
|
96
|
-
- **`next-server` (render worker)** — RSC + SSR pipeline.
|
|
97
|
-
|
|
98
|
-
Both inherit `NODE_OPTIONS`, so the 6 GB cap applies to **each**. With the
|
|
99
|
-
config in this app the totals stabilize around **~1.4 GB + ~0.6 GB ≈ 2 GB**.
|
|
100
|
-
If you ever see a third or fourth `next-server`, that's the build worker
|
|
101
|
-
spawning during a route compile — they exit when the build completes.
|
|
102
|
-
|
|
103
|
-
## 6. Diagnose a memory regression
|
|
104
|
-
|
|
105
|
-
When dev RSS climbs past 4 GB and stays there:
|
|
87
|
+
When dev RSS climbs past 1 GB and stays there:
|
|
106
88
|
|
|
107
89
|
```bash
|
|
108
|
-
#
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
#
|
|
117
|
-
ls -lt .next/diagnostics | head -3
|
|
90
|
+
# Check the boring stuff first
|
|
91
|
+
ps aux | grep -E "vite" | grep -v grep | wc -l # > 1 = duplicate dev servers
|
|
92
|
+
du -sh node_modules/.vite # > 200 MB = bust the cache
|
|
93
|
+
|
|
94
|
+
# Then check the active dep graph
|
|
95
|
+
# Vite ships a built-in module-graph endpoint at /__inspect/ when
|
|
96
|
+
# `vite-plugin-inspect` is installed; not currently wired in apps/web,
|
|
97
|
+
# but a one-line `pnpm add -D vite-plugin-inspect` plus the plugin
|
|
98
|
+
# import gives instant visibility for one-off investigations.
|
|
118
99
|
```
|
|
119
100
|
|
|
120
|
-
Common culprits
|
|
101
|
+
Common culprits:
|
|
121
102
|
|
|
122
103
|
| Symptom | Likely cause | Fix |
|
|
123
104
|
|---------|--------------|-----|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
| Heap grows on every HMR cycle, never shrinks |
|
|
129
|
-
|
|
|
130
|
-
| tsserver alone is > 1.5 GB | TS strict + large lib check | `skipLibCheck: true` (already on), drop `allowJs` if not needed |
|
|
131
|
-
| Turbopack worker RSS keeps growing past 4 GiB | `turbopack.memoryLimit` not set | Apply knob 2 |
|
|
105
|
+
| Two or more `vite` processes in `ps` | Dual dev server across checkouts | Stop the duplicate (see §2) |
|
|
106
|
+
| `[vite] (client) Re-optimizing dependencies` looping every save | Dep cache invalidated on every change | `pnpm clean:cache && pnpm dev` |
|
|
107
|
+
| Initial paint + first navigation feel slow but steady-state is fine | `optimizeDeps.include` is missing a hot dep | Add it to the list (knob 2) |
|
|
108
|
+
| `Invalid hook call` runtime error | Two React copies in the bundle | Verify `dedupe` (knob 4) is set |
|
|
109
|
+
| Heap grows on every HMR cycle, never shrinks | Module-level `Map` / `Set` that never gets cleared | Move to request-scoped storage |
|
|
110
|
+
| tsserver alone is > 1.5 GB | TS strict + large lib check | `skipLibCheck: true` is already on; drop `allowJs` if not needed |
|
|
132
111
|
|
|
133
|
-
##
|
|
112
|
+
## 5. Node 24 features we leverage
|
|
134
113
|
|
|
135
114
|
Node 24 (LTS-track) is required by `engines.node` in `package.json` and
|
|
136
115
|
pinned in `.nvmrc`. Specifically:
|
|
137
116
|
|
|
138
|
-
- **V8 13.6 with Maglev JIT default-on** — faster startup, lower base
|
|
139
|
-
Steady-state RSS for the
|
|
140
|
-
- **Improved incremental marking GC** — fewer long pauses during HMR;
|
|
141
|
-
perceived "stutter" when saving a large file is gone.
|
|
142
|
-
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
- **`--heap-prof` / `--cpu-prof` always-on** — the `dev:profile` script in
|
|
150
|
-
`package.json` uses these to drop snapshots into `.next/diagnostics/`
|
|
151
|
-
without any third-party profiler dependency.
|
|
152
|
-
- **`--experimental-strip-types`** — Node 24 can run `.ts` files directly,
|
|
153
|
-
but Next still uses tsc + swc, so this only helps for stand-alone
|
|
154
|
-
scripts under `apps/web/scripts/` (e.g. `fa:subset-audit`) if they're
|
|
155
|
-
converted from `.mjs` to `.ts`.
|
|
156
|
-
- **Smaller initial heap allocations** — V8 13.6 starts with ~50 MB less
|
|
157
|
-
reserved arena vs V8 12.x. Most visible in fast CI test runs.
|
|
158
|
-
|
|
159
|
-
## 8. Anti-patterns
|
|
117
|
+
- **V8 13.6 with Maglev JIT default-on** — faster startup, lower base
|
|
118
|
+
heap. Steady-state RSS for the Vite parent is ~12% lower vs Node 22.
|
|
119
|
+
- **Improved incremental marking GC** — fewer long pauses during HMR;
|
|
120
|
+
the perceived "stutter" when saving a large file is gone.
|
|
121
|
+
- **`node --run <script>`** — replaces `npm run` for one-off scripts
|
|
122
|
+
with ~30 ms less per-invocation overhead. Use it in any CI step that
|
|
123
|
+
runs a workspace script directly: `node --run typecheck`.
|
|
124
|
+
- **Smaller initial heap allocations** — V8 13.6 starts with ~50 MB
|
|
125
|
+
less reserved arena vs V8 12.x. Most visible in fast CI test runs.
|
|
126
|
+
|
|
127
|
+
## 6. Anti-patterns
|
|
160
128
|
|
|
161
129
|
| Anti-pattern | Why it's wrong |
|
|
162
130
|
|--------------|----------------|
|
|
163
|
-
|
|
|
164
|
-
|
|
|
165
|
-
|
|
|
166
|
-
| `NODE_OPTIONS=--inspect` in normal dev | Allocates an extra inspector arena per process (~200 MB). Use only when actively debugging. |
|
|
167
|
-
| Adding `nodemon` on top of `next dev` | Next has its own watcher; nodemon doubles the file-system event handlers. |
|
|
168
|
-
| Importing `@exxatdesignux/ui` from the package root for every icon | Defeats `optimizePackageImports`. Always import from the leaf path the DS exposes. |
|
|
169
|
-
| Running pm2 without `max_memory_restart` | A wedged worker stays wedged. The 7 GB ceiling lets pm2 recycle before the OS swaps. |
|
|
170
|
-
| Disabling `turbopackFileSystemCacheForDev` because "cache is the problem" | Cold starts go from ~1s to ~15–30s every restart. Bust with `pnpm clean:cache` instead. |
|
|
131
|
+
| Bypassing `dev-guard` with `npm run dev --ignore-scripts` | Defeats the only protection against parallel servers. The `predev` hook is the cheapest possible safety net. |
|
|
132
|
+
| Adding `nodemon` on top of `vite` | Vite has its own watcher; nodemon doubles the file-system event handlers. |
|
|
133
|
+
| Importing `@exxatdesignux/ui` from the package root for every icon | Bypasses tree-shaking. Always import from the leaf path the DS exposes (e.g. `@exxatdesignux/ui/components/button`). |
|
|
171
134
|
| Two checkouts of the same monorepo both running dev | Caches don't share — 2× total RSS. Pin to one checkout per machine. |
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
1
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
3. `
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
`
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
`
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
135
|
+
| Running `vite dev` with `--inspect` in normal dev | Allocates an extra inspector arena per process (~200 MB). Use only when actively debugging. |
|
|
136
|
+
|
|
137
|
+
## 7. Upgrading an existing customer app to the Vite stack
|
|
138
|
+
|
|
139
|
+
If your customer repo was scaffolded before `@exxatdesignux/ui@0.5.10`
|
|
140
|
+
on the legacy Next stack, the migration path is the one this repo took
|
|
141
|
+
in PR-1 → PR-6:
|
|
142
|
+
|
|
143
|
+
1. **PR-1**: add `dev-guard` predev hook + bump Node engines to 24.
|
|
144
|
+
2. **PR-2**: scaffold `template-vite/` alongside Next; designers move first.
|
|
145
|
+
3. **PR-3**: set up `vite.config.ts` with `next/*` aliases pointing at
|
|
146
|
+
shims so existing component code keeps compiling.
|
|
147
|
+
4. **PR-4**: smoke `pnpm build:vite` and fix any cross-stack env vars
|
|
148
|
+
(`process.env.NEXT_PUBLIC_*` ⇄ `import.meta.env.VITE_*`).
|
|
149
|
+
5. **PR-5**: flip `pnpm dev` from Next to Vite; demote Next variants to `:next` slot.
|
|
150
|
+
6. **PR-6**: codemod all `next/*` imports to `react-router-dom` direct,
|
|
151
|
+
delete `app/`, `next.config.mjs`, `next-env.d.ts`, the shim directory,
|
|
152
|
+
and remove `next` + `eslint-config-next` + `@next/bundle-analyzer`
|
|
153
|
+
from `package.json`.
|
|
154
|
+
|
|
155
|
+
A reusable codemod for step 6 lives in commit `d16ec77` under
|
|
156
|
+
`apps/web/scripts/codemod-next-to-rr.mjs` (deleted in the same commit
|
|
157
|
+
to keep the tree clean — pull it from git history if you need it).
|
|
158
|
+
|
|
159
|
+
The full sequence took roughly an afternoon of focused work end-to-end
|
|
160
|
+
on the canonical app. For repos with significant Next-only surfaces
|
|
161
|
+
(RSC server actions, `next/image` heavy use, custom Next middleware),
|
|
162
|
+
expect to spend additional time on those specific subsystems — they
|
|
163
|
+
were not present in `apps/web`.
|
|
199
164
|
|
|
200
165
|
## See also
|
|
201
166
|
|
|
202
167
|
- [`HANDBOOK.md`](./HANDBOOK.md) — workspace orientation
|
|
203
168
|
- [`consumer-upgrade-checklist.md`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/packages/ui/consumer-extras/patterns/consumer-upgrade-checklist.md) — what to do after `pnpm add @exxatdesignux/ui@latest`
|
|
204
|
-
- [
|
|
169
|
+
- [Vite — Performance](https://vite.dev/guide/performance.html)
|
|
205
170
|
- [Node.js — Diagnostics](https://nodejs.org/api/cli.html#--heap-profheap_dir)
|
|
206
171
|
- [V8 — Maglev](https://v8.dev/blog/maglev)
|