The /pilot/:id route renders AssistantChatPage, not FlowPilotSessionPage (the latter is dead code with no active route). The earlier magic-moment integration sat in the wrong file, so clicking Pick Up from the dashboard navigated to /pilot/:id?pickup=true and AssistantChatPage just loaded the chat surface with no claim — the senior never saw the magic-moment screen and the handoff stayed unclaimed (status escalated, permanently in the queue). Adds full pickup awareness to AssistantChatPage: - ?pickup=true on entry triggers a handoff fetch via handoffsApi.listHandoffs (account-scoped, no claim required). magicState transitions loading → visible (handoff found) or loading → dismissed (no handoff or fetch failed). The dismiss path also strips ?pickup=true from the URL so a refresh doesn't re-enter loading state. - The existing selectChat-from-URL effect is gated on magicState — it skips while we're loading or showing the magic-moment so the chat surface doesn't race the claim flow. After claim it re-fires and populates messages from conversation_messages because the senior is now escalated_to_id and GET succeeds. - Magic-moment renders as full-page take-over (sidebar hidden) until Start here. handleStartHere calls handoffsApi.claimHandoff, drops ?pickup=true, and dismisses — the regular chat then loads. - Toolbar Context button (visible when magicHandoff is in memory) re-opens the screen as a dismissible overlay. Lazy-fetches the handoff when needed. Verified tsc -b clean and Vite HMR picked the file up without errors. The wire-level integration was already verified in earlier commits: listHandoffs returns the unclaimed handoff for a senior pre-claim, claimHandoff flips status escalated → active and sets escalated_to_id. Note: the prior FlowPilotSessionPage magic-moment integration is now in dead code (file is unreferenced from router). Left in place for this commit; will come out in a follow-up cleanup once we're confident the AssistantChatPage path is solid in production. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Babel (or oxc when used in rolldown-vite) for Fast Refresh
- @vitejs/plugin-react-swc uses SWC for Fast Refresh
React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.
Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
You can also install eslint-plugin-react-x and eslint-plugin-react-dom for React-specific lint rules:
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])