Mobile browsers (iOS Safari especially) ignore window.scrollTo.
Use scrollIntoView on a ref at the top of the page instead,
which works reliably across mobile and desktop browsers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
requestAnimationFrame was still too early. Use a useEffect on
currentSlide so the scroll fires after React commits the new
slide to the DOM. Skips initial render to avoid scroll on load.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use requestAnimationFrame to defer scrollTo until after React
renders the new slide content, preventing the browser from
staying at the bottom of the page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
15+ responsive adjustments using sm: breakpoints for proper mobile
display: compact padding, flex-wrap metadata, stacked email input,
larger touch targets for drag-rank/range inputs, hidden brand text
on small screens, and tighter line heights.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Button component with CVA variants (primary, secondary, destructive, ghost, link)
- Add Input, Textarea, FormField, and Skeleton UI primitives
- Add focus trapping to Modal for WCAG accessibility compliance
- Add prefers-reduced-motion media query for motion-sensitive users
- Add route-level ErrorBoundary wrapping via page() helper in router
- Add route prefetching on sidebar nav hover for instant navigation
- Add PageMeta component with OG/Twitter meta tags (react-helmet-async)
- Add PageMeta to SharedSessionPage and SurveyPage for social sharing
- Replace lodash with custom debounce utility (saves ~71KB bundle)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changed CopilotPanel from fixed overlay to flex layout sibling so it
pushes main content instead of covering it during active sessions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace fixed positioning with in-flow flex layout. The outermost div
is now a horizontal flex row: content column (flex-1 min-w-0) + panel
(w-[380px] shrink-0). When the panel opens, the content column
automatically shrinks — no padding hacks or z-index stacking needed.
This guarantees the content shifts left and stays fully visible.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Panel now uses top:56px to sit below the app shell topbar instead of
covering it (matches the main-content grid cell area)
- Added slideInRight CSS animation for smooth drawer entrance
- Editor pages use dynamic paddingRight via PANEL_WIDTH constant
- ChatTab upgraded: markdown rendering, CopilotPanel-style message
bubbles, auto-focus input, Shift+Enter hint
- All borders use --glass-border for consistent glassmorphism
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Convert EditorAIPanel from in-flow flex child to fixed right-side drawer
overlay, same pattern as CopilotPanel and ScratchpadSidebar. The panel
is fixed at right:0 spanning full viewport height, and editor pages add
pr-[380px] padding when open so content shifts left without overlap.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The AI panel was nested inside the content area, only spanning the
step list / canvas section. Now it sits at the outermost flex level,
spanning the full page height alongside all content (toolbar,
collapsible sections, steps/canvas). This prevents the panel from
overlapping content and lets the editor area properly shrink.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The useEditorAI hook was ignoring result.working_tree from AI responses,
so generated steps/trees never appeared in the editor. Now:
- useEditorAI calls onFlowUpdate when working_tree is present in response
- ProceduralEditorPage handles steps + intake form updates via replaceSteps
- TreeEditorPage handles tree structure updates via replaceTreeStructure
- Both stores have new bulk-replace methods for AI integration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both editors now send name and description alongside the flow structure,
so the AI can reference what the flow is about when responding.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The AI panel now sends the current tree structure (troubleshooting) or
steps + intake form (procedural/maintenance) with each message. This
gives the AI full visibility into node details, questions, descriptions,
options, and intake form fields — not just the node ID.
- Backend: add flow_context param to schema, endpoint, and service
- Frontend: add getFlowContext callback to useEditorAI hook
- TreeEditorPage: passes treeStructure as flow context
- ProceduralEditorPage: passes steps + intakeForm as flow context
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the old /ai/chat page, AI wizard modal, and all associated
components/stores/types now replaced by the editor-embedded AI panel.
Deleted:
- AIChatBuilderPage, ai-chat/ components, aiChatStore, aiChat API, ai-chat types
- AIFlowBuilderModal, ai-builder/ components, aiFlowBuilderStore
Cleaned up:
- Router (removed /ai/chat route)
- Sidebar (removed Flow Assist nav item)
- MyTreesPage (removed AI builder modal and button)
- TreeLibraryPage (removed Flow Assist button)
- API and type barrel exports
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use .glass-card-static on AIPromptDialog card for consistent design system
- Add "Build with Flow Assist" button to maintenance section in CreateFlowDropdown
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace navigation to /ai/chat with an inline AIPromptDialog modal
that collects a single prompt, generates a flow via the editor AI API,
imports it, and navigates to the editor with the AI panel open.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AI-generated trees use descriptive IDs (e.g., "verify-account-exists")
instead of "root", causing the root node to be falsely flagged as orphaned.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Default AI_PROVIDER changed from gemini to anthropic
- AI_MODEL and AI_MODEL_ANTHROPIC updated to claude-sonnet-4-6
- Added "Shift + Enter for a new line" hint below all chat textareas
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- CreateFlowDropdown now shows "Build with Flow Assist" under each flow type
- Library page "Flow Assist" button respects current type filter
- Clean up unused AIFlowBuilderModal references
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add procedural-specific system prompts (schema, interview protocol, response format)
- Dispatch prompts by flow_type: procedural/maintenance use flat steps schema, troubleshooting uses decision tree schema
- Parse [STEPS_UPDATE] and [INTAKE_FORM] markers in AI responses
- Add validate_generated_procedural_steps() validator
- Handle intake form extraction in AI chat import endpoint
- Add StaticStepsPreview component for procedural flow preview
- Update store and page to render correct preview by flow type
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove XML builder, format query param, and XML tests
- Simplify ExportFlowModal (no format picker)
- Simplify rfflowParser (JSON-only)
- Remove format field from schemas and types
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: increase assistant chat input height from 1 to 3 rows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add Anthropic prompt caching to assistant chat
Cache the static system prompt and conversation history prefix across
turns, reducing input token costs by ~80% on multi-turn conversations.
RAG context is intentionally uncached since it changes per query.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add Microsoft Learn MCP integration + refine assistant system prompt
- Integrate Microsoft Learn MCP server via Anthropic's MCP connector
for real-time documentation lookups (docs search, fetch, code samples)
- Refine system prompt: clear persona, structured answer guidelines,
when to use RAG flows vs Microsoft Learn, guardrails against fabrication
- Add ENABLE_MCP_MICROSOFT_LEARN config toggle (default: True)
- Fix bugs from prior edit: wrong MCP URL, broken indentation, undefined
usage/token variables, NOT_GIVEN for disabled MCP params
- Log MCP tool usage and cache performance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: AI chat session conclusion + survey completion & management
AI Assistant - Conclude Session:
- 3-step modal: select outcome (resolved/escalated/paused), add notes, AI-generated summary
- AI generates structured ticket notes from conversation transcript (PSA-ready format)
- Copy to clipboard for pasting into ticketing systems
- "Resume in New Chat" for paused sessions (pre-loads context into new chat)
- Backend: POST /chats/{id}/conclude endpoint, conclusion_summary/outcome/concluded_at fields
- Migration 048: add conclusion fields to assistant_chats
Survey Completion Flow:
- Email-to-self option after submission (branded HTML email with formatted responses)
- Finish button navigates to /survey/thank-you page
- Thank you page with close-window message and feedback email callout
- Already-submitted state updated with same messaging
- Backend: POST /survey/email-copy public endpoint
Survey Admin Management:
- Read/unread indicators (cyan dot, bold name, auto-mark on expand)
- Unread count stat card
- Per-row context menu: mark read/unread, archive/unarchive, delete
- Bulk actions bar: select all, mark read/unread, archive, delete
- Show Archived toggle to filter archived responses
- Backend: 7 new admin endpoints (read, unread, archive, unarchive, delete, bulk)
- Migration 049: add is_read, archived_at to survey_responses
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: initialize VerifyEmailPage state from token to avoid setState in effect
Moves the no-token error case from useEffect into initial state to satisfy
the react-hooks/set-state-in-effect ESLint rule.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* chore: update Google Fonts to Bricolage Grotesque, IBM Plex Sans, JetBrains Mono
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: update Tailwind config to Slate & Ice theme colors and fonts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: update CSS variables and glass-card utilities for Slate & Ice theme
- Replace all color variables with Slate & Ice palette
- Add glass system vars (--glass-bg, --glass-blur, --shadow-float)
- Replace legacy glass-card with new variable-driven glass classes
- Add breatheGlow, bellWobble, slideDown, fadeInRight keyframes
- Update font references to IBM Plex Sans and Bricolage Grotesque
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: recolor BrandLogo to cyan gradient, split BrandWordmark for gradient Flow text
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: update TopBar with glassmorphism backdrop and cyan accent styling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: update Sidebar with glassmorphism backdrop
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add ambient atmosphere gradient orbs behind app shell
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: update QuickStats and SessionsPanel with glass-card styling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add WeeklyCalendar, QuickActions, OpenSessions, RecentActivity dashboard components
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: redesign dashboard layout with calendar, open sessions, and glass-card panels
New layout: greeting → calendar+actions → sessions+stats → activity
Replaces old QuickStats and SessionsPanel with new dashboard components
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace remaining purple hex references with ice-cyan accent
Sweep of hardcoded purple hex values (#818cf8, #6366f1) replaced with
new cyan accent (#06b6d4) in QuickActions, RecentActivity, QuickLaunch,
and SVG brand assets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: update CLAUDE.md branding and design system for Slate & Ice Modern
Updated Last Updated date, branding section (fonts, colors, glass
utilities, atmosphere orbs), component styling rules, and Design System
section to reflect the new ice-cyan glassmorphism theme.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add Slate & Ice Modern design doc and implementation plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: redesign login page with Slate & Ice Modern design system
Apply glassmorphism styling, atmosphere orbs, branded wordmark, and
consistent design tokens to match the updated app shell aesthetic.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: raise TopBar z-index so profile dropdown renders above main content
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add AI assistant with in-session copilot and standalone chat with RAG
Implements three-phase AI assistant feature:
- Phase 0: RAG infrastructure with pgvector embeddings, Voyage AI integration,
tree chunking service, and semantic search over team's flow library
- Phase 1: In-session copilot panel during flow navigation with contextual
AI help, current step awareness, and suggested related flows
- Phase 2: Standalone AI chat page with persistent conversation history,
pin/delete, and configurable retention policies (account-level)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add account management, email verification, AI fixes, and user guides
- Profile settings, account transfer, delete/leave account flows
- Email verification with JWT tokens and Resend integration
- AI assistant/copilot fixes: markdown rendering, shared RAG helpers,
token tracking, input refocus, model_validate usage
- User guides hub + detail pages with 13 topic guides
- Sidebar and top bar navigation for guides
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: prevent stale chunk errors after deployments
- Set Cache-Control no-cache on index.html in nginx so browsers always
fetch fresh chunk references after a deploy
- Auto-reload on chunk load failures (stale deploy detection) with
loop prevention via sessionStorage
- Show friendly "App Updated" message if auto-reload doesn't resolve it
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add email verification toggle to admin settings
Adds platform-level toggle to enable/disable email verification.
When disabled, the verification banner is hidden and the send
endpoint returns 403.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Added Dockerfile.dev for backend and frontend, docker-compose.dev.yml
for local development. Added *.sql to .gitignore to prevent accidental
commit of database dumps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Frontend: suppress unused-vars ESLint errors for callback params in
MaintenanceFlowDetailPage and StepLibraryPage.
Backend: add autouse fixture to mock settings.ai_enabled=True in
test_ai_chat.py so tests pass in CI where no ANTHROPIC_API_KEY is set.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- After generation, toolbar shows "Save to Flow Library" button
(replaces "Import to Editor")
- Button shows "Saving..." spinner state during API call
- Generate button shows animated spinner during generation
- Backend /import endpoint always creates a new Tree record
(removed generated_tree_id idempotency check)
- Navigates to tree editor after successful save
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename all "Build with AI" labels to "Flow Assist"
- Update CreateFlowDropdown description to "AI-powered flow builder"
- Add Flow Assist nav item with Sparkles icon to sidebar (both
expanded and collapsed states)
- Update AIFlowBuilderModal titles for consistency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- C1: Fix race condition in handleReset — await abandonSession before
starting new session to prevent store state corruption
- I1: Extract error messages from Axios response.data.detail instead of
generic error.message — users now see helpful backend messages (quota
limits, message caps, etc.)
- I2: Add isGenerating guard in generateTree store action to prevent
concurrent generation requests on double-click
- I3: Add isResponding guard in sendMessage to prevent concurrent sends
- M5: Remove redundant type casts on flowType
- M6: Add rate limiter to DELETE /sessions/{id} for consistency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- TypeScript types for chat session, messages, and responses
- API client module with all 6 endpoints
- Zustand store with session management, message sending, tree generation, import, resume
- 7 chat components: ChatMessage, ChatInput, ChatPanel, PhaseIndicator, ChatToolbar, EmptyPreview, StaticTreePreview
- AIChatBuilderPage with split-panel layout (60% chat / 40% preview)
- Route at /ai/chat with lazy loading
- "Build with AI" button on TreeLibraryPage
- Session resume via URL search params
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New ai-fix.ts types for request/response
- fixTree() method on treesApi
- "Fix with AI" button in ValidationSummary (shows for fixable errors)
- AIFixReviewModal with per-fix apply/skip and apply-all
- TreeEditorPage orchestrates the fix flow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The frontend validate button was not checking that decision nodes with
children have at least 2 branches, so it would pass validation but the
backend publish check would reject with a 422. The AI tree validator also
only checked options count, not children count — so AI-generated trees
with 2 options pointing to the same single child would pass generation
validation but fail at publish time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The handlePublish catch block was showing a generic "Failed to publish"
message instead of parsing the 422 response body for validation details.
Now matches the handleSaveDraft error handling pattern.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- StepLibraryPage: replace silent console.error with toast.error on edit/save
failures; replace manual setTimeout toast with toast.success helper
- BatchStatusPage: add error state with retry button for failed session loads
instead of showing ambiguous "No sessions found"
- StepDetailModal: guard clipboard copy against browser denial (no false
"Copied!" state on permission error); fix dead "See all reviews" button
with inline expand/collapse toggle
- StepLibraryBrowser: add "Try again" retry button to error state; retry
increments a counter that re-triggers both load effects
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>