Skip to content
Merged
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
1 change: 1 addition & 0 deletions frontend/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Frontend

- When building new UI components, ship a Ladle story alongside the component (`*.stories.tsx` next to the source). Cover the meaningful states (empty, loading, error, success, edge cases) so the component can be reviewed and iterated on in isolation without booting the whole dashboard. Run with `pnpm dev:ladle` from `frontend/`. Existing example: [src/app/runner-pool-error-popover.stories.tsx](src/app/runner-pool-error-popover.stories.tsx).
- HTTP responses can be mocked end-to-end in dev via MSW. Append `?mock=1` to any dashboard URL (dev only, gated by `import.meta.env.DEV` in [src/lib/agent-mocks.ts](src/lib/agent-mocks.ts)) to boot the worker. Then in DevTools / agent-browser console: `window.__rivetMock("*/actors/:id/kv/keys/*", { status: 503, body: { group: "guard", code: "service_unavailable", message: "..." } })`. Mocks persist across reloads via sessionStorage; `window.__rivetClearMocks()` resets. Use this to exercise error UIs without standing up real engine state. Prod bundle is unaffected (dynamic `import("msw/browser")` behind the dev gate).
330 changes: 168 additions & 162 deletions frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,163 +1,169 @@
{
"name": "@rivetkit/engine-frontend",
"private": true,
"version": "2.0.21",
"type": "module",
"scripts": {
"dev": "vite",
"check-types": "tsc --noEmit",
"build": "NODE_OPTIONS='--max-old-space-size=8192' vite build --mode=production",
"preview": "vite preview",
"test": "vitest run",
"test:watch": "vitest",
"dev:ladle": "ladle dev",
"build:ladle": "ladle build"
},
"dependencies": {
"@codemirror/autocomplete": "^6.18.7",
"@codemirror/commands": "^6.8.1",
"@codemirror/lang-javascript": "^6.2.4",
"@codemirror/lang-json": "^6.0.2",
"@codemirror/lang-sql": "^6.8.0",
"@codemirror/lint": "^6.8.5",
"@codemirror/merge": "^6.10.2",
"@codemirror/state": "^6.5.2",
"@codemirror/view": "^6.38.2",
"@date-fns/utc": "^1.2.0",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.6",
"@hookform/resolvers": "^5.2",
"@ladle/react": "^5.1.1",
"@marsidev/react-turnstile": "^1.5.0",
"@microsoft/fetch-event-source": "^2.0.1",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-progress": "^1.1.7",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slider": "^1.3.6",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-toggle": "^1.1.10",
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"@radix-ui/react-visually-hidden": "^1.2.3",
"@rivet-gg/cloud": "*",
"@rivet-gg/icons": "workspace:*",
"@rivetkit/engine-api-full": "workspace:*",
"@rivetkit/shared-data": "workspace:*",
"@rivetkit/traces": "workspace:*",
"@sentry/react": "^8.55.0",
"@sentry/vite-plugin": "^2.23.1",
"@shikijs/langs": "^3.12.2",
"@shikijs/transformers": "^3.12.2",
"@stepperize/react": "^5.1.8",
"@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/typography": "^0.5.16",
"@tanstack/history": "^1.133.28",
"@tanstack/pacer": "^0.21.0",
"@tanstack/query-core": "^5.87.1",
"@tanstack/react-hotkeys": "^0.3.0",
"@tanstack/react-query": "^5.87.1",
"@tanstack/react-query-devtools": "^5.87.3",
"@tanstack/react-router": "^1.167.1",
"@tanstack/react-router-devtools": "^1.166.8",
"@tanstack/react-store": "^0.7.5",
"@tanstack/react-table": "^8.21.3",
"@tanstack/react-virtual": "^3.13.12",
"@tanstack/router-devtools": "^1.166.8",
"@tanstack/router-plugin": "^1.166.10",
"@tanstack/store": "^0.7.5",
"@tanstack/zod-adapter": "^1.131.36",
"@types/bcryptjs": "^2.4.6",
"@types/canvas-confetti": "^1.9.0",
"@types/d3-array": "^3.2.1",
"@types/escape-html": "^1.0.4",
"@types/file-saver": "^2.0.7",
"@types/lodash": "^4.17.20",
"@types/mdx": "^2.0.13",
"@types/node": "^20.19.13",
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/reconnectingwebsocket": "^1.0.10",
"@uiw/codemirror-extensions-basic-setup": "^4.25.1",
"@uiw/codemirror-theme-github": "^4.25.1",
"@uiw/react-codemirror": "^4.25.1",
"@visx/axis": "^3.12.0",
"@visx/brush": "^3.12.0",
"@visx/curve": "^3.12.0",
"@visx/event": "^3.12.0",
"@visx/grid": "^3.12.0",
"@visx/group": "^3.12.0",
"@visx/pattern": "^3.12.0",
"@visx/responsive": "^3.12.0",
"@visx/scale": "^3.12.0",
"@visx/shape": "^3.12.0",
"@visx/tooltip": "^3.12.0",
"@vitejs/plugin-react": "^4.7.0",
"@xyflow/react": "^12.10.0",
"actor-core": "^0.6.3",
"autoprefixer": "^10.4.21",
"bcryptjs": "^2.4.3",
"better-auth": "^1.5.6",
"canvas-confetti": "^1.9.3",
"cbor-x": "^1.6.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"d3-array": "^3.2.4",
"date-fns": "^4.1.0",
"es-toolkit": "^1.45.1",
"esast-util-from-js": "^2.0.1",
"escape-html": "^1.0.3",
"estree-util-to-js": "^2.0.0",
"fast-deep-equal": "^3.1.3",
"fast-json-patch": "^3.1.1",
"favigo": "^1.1.0",
"file-saver": "^2.0.5",
"filesize": "^11.0.2",
"framer-motion": "^11.18.2",
"input-otp": "^1.4.2",
"lodash": "^4.17.21",
"postcss": "^8.5.6",
"posthog-js": "^1.275.1",
"react": "^19.1.1",
"react-day-picker": "8.10.1",
"react-dom": "^19.1.1",
"react-error-boundary": "^6.0.3",
"react-hook-form": "^7.62.0",
"react-inspector": "^6.0.2",
"react-resizable-panels": "^2.1.9",
"recharts": "^2.15.4",
"reconnectingwebsocket": "^1.0.0",
"rivetkit": "workspace:*",
"shiki": "^3.12.2",
"sonner": "^1.7.4",
"tailwind-merge": "^2.6.0",
"tailwindcss": "^3.4.17",
"tailwindcss-animate": "^1.0.7",
"ts-pattern": "^5.8.0",
"typescript": "^5.9.2",
"typescript-plugin-css-modules": "^5.2.0",
"unplugin-macros": "^0.18.3",
"usehooks-ts": "^3.1.1",
"vite": "^5.4.20",
"vite-plugin-favicons-inject": "^2.2.0",
"vite-tsconfig-paths": "^5.1.4",
"zod": "^3.25.76"
},
"devDependencies": {
"vitest": "^4.0.18"
}
}
"name": "@rivetkit/engine-frontend",
"private": true,
"version": "2.0.21",
"type": "module",
"scripts": {
"dev": "vite",
"check-types": "tsc --noEmit",
"build": "NODE_OPTIONS='--max-old-space-size=8192' vite build --mode=production",
"preview": "vite preview",
"test": "vitest run",
"test:watch": "vitest",
"dev:ladle": "ladle dev",
"build:ladle": "ladle build"
},
"dependencies": {
"@codemirror/autocomplete": "^6.18.7",
"@codemirror/commands": "^6.8.1",
"@codemirror/lang-javascript": "^6.2.4",
"@codemirror/lang-json": "^6.0.2",
"@codemirror/lang-sql": "^6.8.0",
"@codemirror/lint": "^6.8.5",
"@codemirror/merge": "^6.10.2",
"@codemirror/state": "^6.5.2",
"@codemirror/view": "^6.38.2",
"@date-fns/utc": "^1.2.0",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.6",
"@hookform/resolvers": "^5.2",
"@ladle/react": "^5.1.1",
"@marsidev/react-turnstile": "^1.5.0",
"@microsoft/fetch-event-source": "^2.0.1",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-progress": "^1.1.7",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slider": "^1.3.6",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-toggle": "^1.1.10",
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"@radix-ui/react-visually-hidden": "^1.2.3",
"@rivet-gg/cloud": "*",
"@rivet-gg/icons": "workspace:*",
"@rivetkit/engine-api-full": "workspace:*",
"@rivetkit/shared-data": "workspace:*",
"@rivetkit/traces": "workspace:*",
"@sentry/react": "^8.55.0",
"@sentry/vite-plugin": "^2.23.1",
"@shikijs/langs": "^3.12.2",
"@shikijs/transformers": "^3.12.2",
"@stepperize/react": "^5.1.8",
"@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/typography": "^0.5.16",
"@tanstack/history": "^1.133.28",
"@tanstack/pacer": "^0.21.0",
"@tanstack/query-core": "^5.87.1",
"@tanstack/react-hotkeys": "^0.3.0",
"@tanstack/react-query": "^5.87.1",
"@tanstack/react-query-devtools": "^5.87.3",
"@tanstack/react-router": "^1.167.1",
"@tanstack/react-router-devtools": "^1.166.8",
"@tanstack/react-store": "^0.7.5",
"@tanstack/react-table": "^8.21.3",
"@tanstack/react-virtual": "^3.13.12",
"@tanstack/router-devtools": "^1.166.8",
"@tanstack/router-plugin": "^1.166.10",
"@tanstack/store": "^0.7.5",
"@tanstack/zod-adapter": "^1.131.36",
"@types/bcryptjs": "^2.4.6",
"@types/canvas-confetti": "^1.9.0",
"@types/d3-array": "^3.2.1",
"@types/escape-html": "^1.0.4",
"@types/file-saver": "^2.0.7",
"@types/lodash": "^4.17.20",
"@types/mdx": "^2.0.13",
"@types/node": "^20.19.13",
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/reconnectingwebsocket": "^1.0.10",
"@uiw/codemirror-extensions-basic-setup": "^4.25.1",
"@uiw/codemirror-theme-github": "^4.25.1",
"@uiw/react-codemirror": "^4.25.1",
"@visx/axis": "^3.12.0",
"@visx/brush": "^3.12.0",
"@visx/curve": "^3.12.0",
"@visx/event": "^3.12.0",
"@visx/grid": "^3.12.0",
"@visx/group": "^3.12.0",
"@visx/pattern": "^3.12.0",
"@visx/responsive": "^3.12.0",
"@visx/scale": "^3.12.0",
"@visx/shape": "^3.12.0",
"@visx/tooltip": "^3.12.0",
"@vitejs/plugin-react": "^4.7.0",
"@xyflow/react": "^12.10.0",
"actor-core": "^0.6.3",
"autoprefixer": "^10.4.21",
"bcryptjs": "^2.4.3",
"better-auth": "^1.5.6",
"canvas-confetti": "^1.9.3",
"cbor-x": "^1.6.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"d3-array": "^3.2.4",
"date-fns": "^4.1.0",
"es-toolkit": "^1.45.1",
"esast-util-from-js": "^2.0.1",
"escape-html": "^1.0.3",
"estree-util-to-js": "^2.0.0",
"fast-deep-equal": "^3.1.3",
"fast-json-patch": "^3.1.1",
"favigo": "^1.1.0",
"file-saver": "^2.0.5",
"filesize": "^11.0.2",
"framer-motion": "^11.18.2",
"input-otp": "^1.4.2",
"lodash": "^4.17.21",
"postcss": "^8.5.6",
"posthog-js": "^1.275.1",
"react": "^19.1.1",
"react-day-picker": "8.10.1",
"react-dom": "^19.1.1",
"react-error-boundary": "^6.0.3",
"react-hook-form": "^7.62.0",
"react-inspector": "^6.0.2",
"react-resizable-panels": "^2.1.9",
"recharts": "^2.15.4",
"reconnectingwebsocket": "^1.0.0",
"rivetkit": "workspace:*",
"shiki": "^3.12.2",
"sonner": "^1.7.4",
"tailwind-merge": "^2.6.0",
"tailwindcss": "^3.4.17",
"tailwindcss-animate": "^1.0.7",
"ts-pattern": "^5.8.0",
"typescript": "^5.9.2",
"typescript-plugin-css-modules": "^5.2.0",
"unplugin-macros": "^0.18.3",
"usehooks-ts": "^3.1.1",
"vite": "^5.4.20",
"vite-plugin-favicons-inject": "^2.2.0",
"vite-tsconfig-paths": "^5.1.4",
"zod": "^3.25.76"
},
"devDependencies": {
"msw": "^2.14.4",
"vitest": "^4.0.18"
},
"msw": {
"workerDirectory": [
"public"
]
}
}
Loading
Loading