Split the monolithic CLAUDE.md into a durable handoff system:
- .ai/PROJECT_CONTEXT.md — stable architectural truth (stack, structure,
SaaS shape, ConnectWise, coding standards, frontend patterns, critical
lessons). Ported verbatim from the previous CLAUDE.md.
- .ai/CURRENT_TASK.md — single active task with DoD + out-of-scope.
- .ai/HANDOFF.md — resume point, kept under ~2K tokens.
- .ai/TODO.md — backlog, read only when CURRENT_TASK complete.
- .ai/DECISIONS.md — append-only architectural decision log.
- .ai/SESSION_LOG.md — append-only chronological history.
- .ai/README.md — human-facing explanation of the system.
Root agent files share a byte-identical protocol block (verified via diff):
- CLAUDE.md — primary agent, with GitNexus + gstack tooling and the
Claude Opus 4.7 co-author trailer.
- AGENTS.md — OpenAI Codex resume agent, with grep/rg fallbacks and the
Codex co-author trailer. Steps in when Claude hits session/weekly
limits.
Legacy root-level SESSION-HANDOFF.md deleted — superseded by .ai/HANDOFF.md.
It was a self-describing one-off from the Design System v4 migration and
had no external references.
Supersedes previous CLAUDE.md. Old version recoverable via
`git show pre-ai-handoff:CLAUDE.md` (tag points at commit e110fed).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The "AI parrots example content from system prompt" bug bit us twice in
one day across two different prompt sites. Patching individual prompts
is treating the symptom; this commit makes the rule structural.
Audit + sanitize:
- assistant_chat_service.ASSISTANT_SYSTEM_PROMPT — already cleaned in
prior commits, but the [FORK] schema still had literal "Brief reason"
/ "Short name" / "One sentence" placeholders. Replaced with
<angle-bracket> placeholders. Anti-parrot rule itself rewritten to
describe the failure mode abstractly instead of naming "jsmith" so
the rule no longer trips the guardrail (and so the model doesn't
see "jsmith" as a token at all).
- ai_chat_service.py — removed three concrete-example offenders:
"Get-Service ADSync" command literal, the "DC01 server_name" intake
form payload (in two places), and the inline interview demos using
"Azure AD Sync failures" / "Exchange Online mailbox migration".
Replaced with technology-neutral schema descriptions.
- ai_tree_generator_service.BRANCH_DETAIL_SYSTEM_PROMPT — replaced the
fully-fleshed DNS troubleshooting tree (with literal Dnscache /
ipconfig / google.com / Start-Service) with a placeholder schema
showing only ID-linkage shape.
- kb_conversion_service.PROCEDURAL_SYSTEM_PROMPT — replaced the worked
Server Manager + DC01 example payload with a placeholder schema.
Guardrail (tests/test_prompt_anti_parrot.py):
- Imports every module under app/services/ and app/core/ and walks
every uppercase string constant ending in _PROMPT, _SCHEMA,
_PROTOCOL, _FORMAT, or _CONTEXT.
- test 1: known-leaked-token list (jsmith, DC01, ADSync, Dnscache,
google.com, "Outlook keeps", "Teams drops") must not appear in any
prompt constant. Add to the list when a new leak shows up in prod —
the list IS the audit trail.
- test 2: marker blocks ([QUESTIONS], [ACTIONS], [SUGGEST_FIX], etc.)
must contain placeholders only. Distinguishes JSON keys (followed
by ':', allowed) from JSON values (followed by ',' / ']' / '}',
must be <placeholder>); allows pipe-separated enum types
(text|password|select) and a small set of fixed enum values
(question, diagnostic_check, decision, action, ...). Verified by
feeding the test a known-bad block — caught it correctly.
Documented the rule in CLAUDE.md → AI / FlowPilot lessons, naming
the test as the enforcement point so future contributors know how to
extend it (add to the known-leaked list when a new leak surfaces).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Trim from 570 → 264 lines. Archived lessons and fixes-in-code remain in
docs/LESSONS-ARCHIVE.md; CLAUDE.md now only carries what a fresh session
can't derive from the repo state.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add PSABoard type + list_boards() to CW provider (cached 1h)
- Extend search_tickets with assigned_to_me, unassigned, board_ids, page, page_size
- New GET /integrations/psa/boards endpoint
- New TicketQueue dashboard component: My Tickets / Unassigned tabs,
multi-select board filter, Load more pagination, Start Session per ticket
- Add TicketQueue to QuickStartPage after active sessions
- FlowPilotSessionPage auto-starts with ticket context when navigated
from TicketQueue (psaTicketId + psaTicket in location.state)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove mandatory "MUST run before every edit" rules — they add overhead
without value for additive/isolated changes. Keep the tools table and
use-it-when-it-matters guidance.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Race condition: on page remount, selectChat(oldId) loads session data async.
If the user clicks New Chat before the API returns, the old session's
pending_task_lane was being applied to the new session's state, showing
stale tasks and blocking new ones from appearing.
Fix: currentChatRef tracks the most recently requested chat ID synchronously.
All chat-creation paths (selectChat, handleNewChat, handleResumeNew) update it
immediately. After each await in selectChat, bail if the ref no longer matches.
Also documents the pattern as Lesson 106 in CLAUDE.md for future reference.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Accent: #f97316 (orange) → #60a5fa/#2563eb (electric blue)
- Info: new cyan (#67e8f9/#0891b2) since blue took the accent slot
- Warning: #eab308 (yellow) → #fbbf24/#d97706 (amber reclaimed)
- Surfaces: deeper charcoal range for better layer separation
- Full light mode semantic color variants specified
- Based on competitive research: no MSP tool uses this blue register
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Renamed fc01_add_pending_task_lane → 068_add_pending_task_lane with
revision ID "068" and down_revision "067". Added migration naming
convention to CLAUDE.md to prevent future hex-hash migrations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restructure QuickStartPage for a more professional, informative layout:
- Left-aligned hero greeting (text-4xl) with date context and inline stat strip
- GreetingStatStrip shows resolved/active/MTTR at a glance
- Remove collapsible toggle — dashboard stats always visible
- Section labels with trailing border lines for visual hierarchy
- Suggestion chips with category icons, card-style hover, press feedback
- Fix cyan focus ring and icon color to ember orange design system
- Session cards: line-clamp-2 descriptions, font-medium text, problem_domain metadata
- Widen container max-w-3xl → max-w-4xl for breathing room
- Add .impeccable.md and .github/copilot-instructions.md design context
- CLAUDE.md audit: fix stale references, remove duplication, update counts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix system prompt to ensure [QUESTIONS]/[ACTIONS] markers in AI responses
- Add format reminder injection to user messages for marker compliance
- Wire TaskLane activation in prefill and resume paths
- Add ActionCardGroup component for structured question/action rendering
- Update FlowPilot session and step card components
- Update ai-session schemas and types for marker data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Swap accent color from cyan (#22d3ee) to ember orange (#f97316) site-wide.
Cyan caused contrast issues and felt generic — orange brings warmth and
urgency fitting for a troubleshooting tool.
Changes:
- CSS variables: accent, accent-hover, accent-dim, accent-text, primary, ring
- Warning color shifted from amber (#fbbf24) to yellow (#eab308) for
semantic separation from orange accent
- Brand SVGs: logo gradient updated to orange
- 50+ component files: all hardcoded cyan hex values, Tailwind cyan-*
classes, and rgba(34,211,238,...) glow values replaced
- landing.css: all 45+ cyan references + 5 old border color fixes
- DESIGN-SYSTEM.md bumped to v5 with decisions log
- CLAUDE.md: all color references synced to charcoal palette + orange accent
- PWA theme-color meta tag updated to match sidebar (#10121a)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 94: Frontend chat uses unified_chat_service (not assistant_chat)
- 95: Image upload → AI vision pipeline end-to-end flow
- 96: bg-accent is cyan — never use for code/kbd elements
- 97: Railway Object Storage bucket is provisioned
- 98: lazyWithRetry pattern for stale chunk errors
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add DESIGN-SYSTEM.md as single source of truth for all design decisions
- Update CLAUDE.md branding and design system sections to reference new system
- Archive UI-DESIGN-SYSTEM.md to docs/archive/design-docs/
- Update tech stack styling line and quick reference table
The new design system moves from glassmorphism/gradients to a flat,
high-contrast dark theme inspired by Sentry/PostHog. Light mode planned.
CSS implementation to follow in a separate branch.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixed positioning, abandon session, date filters, Script Builder,
FlowPilot GUI vs script preference.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added lessons for varchar(30) status column, get_db rollback, action
bar height chain, dashboard prefill auto-submit, navigation guard,
and manual Alembic migration preference. Updated project structure
and frontend patterns for new dashboard cockpit and sidebar sections.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 4 plan corrections:
- Remove shadcn/ui from tech stack (not used in project)
- Replace shadcn Sheet with Tailwind slide-up panel for mobile modals
- Specify exact CSS variable names for custom branding overrides
- Add SEO crawlability note (deferred to Phase 5)
Phase 4 plan enhancements:
- Add notification retry mechanism with NotificationLog model + APScheduler
- Specify weasyprint for PDF export with Dockerfile deps
- Add "Copy to Clipboard" as primary export option
- Add Task 6.5: in-app notification center extending existing NotificationsPanel
- Specify slowapi for IP-based public endpoint rate limiting
- Add low-priority gallery analytics tracking section (PostHog events)
CLAUDE.md: fix BasePsaProvider → PSAProvider (matches actual class name)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix escalation status mismatch: hook set 'escalated' but backend returns
'requesting_escalation'
- Fix list_sessions to include sessions picked up by Engineer B via
escalation_package->>'picked_up_by' JSONB query
- Fix sidebar escalation icon color: was Tailwind class 'text-amber-400'
passed to style={{color}}, now hex '#fbbf24'
- Replace window.location.reload() after ticket linking with
onReloadSession callback to preserve session state
- Update CLAUDE.md: Tailwind CSS v3 → v4 (@tailwindcss/vite, CSS-only config)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move early lessons (fixes baked into codebase) to docs/LESSONS-ARCHIVE.md.
Condense lessons 41-65 to one-liners. Reduces system prompt token usage
by ~34% while preserving all actively relevant context.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete Script Generator feature including:
Backend:
- ScriptCategory, ScriptTemplate, ScriptGeneration models
- ScriptTemplateEngine with substitution, filters, sanitization
- CRUD + share API endpoints with permission checks
- Integration tests for permissions and sharing
- Migration 057 with AD User Management seed templates
Frontend — Script Library:
- Browse templates with category tabs and search
- Configure pane with parameter form and script generation
- Script preview with live substitution and copy/download
- scriptGeneratorStore Zustand store
Frontend — Template Editor:
- Full CRUD form with metadata, script body (Monaco Editor), parameters
- ParameterSchemaBuilder with visual builder + JSON toggle
- ScriptManagePage with routing and nav link
Frontend — Parameter Detector:
- Client-side PowerShell parameter detection engine
- Detects script-level param() blocks and variable assignments
- Type inference from PS type annotations and value patterns
- ParameterDetectorStepper one-by-one review UI with accept/skip
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: adopt shared Input/Textarea components across 15 files
Replace 42 raw <input>/<textarea> elements with <Input>/<Textarea>
from components/ui/. Consistent focus states, error handling, and
styling across all form fields.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: replace hardcoded rgba/hex colors with Tailwind tokens
- rgba(255,255,255,0.xx) → bg-white/[0.xx], border-white/[0.xx]
- rgba(6,182,212,0.3) → border-primary/30 (focus states)
- #0a0a0a → bg-background
- Inline style hex colors → var(--color-primary), var(--color-brand-gradient-to)
- 28 files updated, zero hardcoded rgba() patterns remaining
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add PageMeta to 16 pages for SEO and proper browser tab titles
Public pages (Login, Register, Forgot/Reset Password, Verify Email,
Survey Thank You) get descriptions for SEO. Authenticated pages
(Dashboard, Flow Library, My Flows, Session History, AI Assistant,
Account Settings, Step Library, My Shares, Feedback, Guides) get
proper tab titles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add page transitions and staggered list animations
- ViewTransitionOutlet: wraps Outlet with fade-in-up animation keyed
to route path. Sidebar/topbar stay still, only content area animates.
- StaggerList: reusable component that cascades children with
incremental delay (50ms default). Pure CSS via @utility stagger-item.
- Applied stagger to TreeGridView, MyTreesPage cards, SessionHistoryPage.
- New stagger-fade-in keyframe in @theme block.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: ViewTransitionOutlet needs h-full for React Flow canvas
The wrapper div broke the height chain needed by TreeEditorPage's
h-full layout, causing React Flow canvas to collapse to zero height.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: main-content flex layout for tree editor + scrollable pages
Main content area is now flex-col so the ViewTransitionOutlet wrapper
gets an explicit computed height via flex-1 min-h-0. This makes h-full
resolve correctly in the tree editor (React Flow canvas) while still
allowing overflow-y-auto scrolling for normal pages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve ESLint errors in Button and Skeleton components
- Button: suppress react-refresh/only-export-components for buttonVariants re-export
- Skeleton: replace empty interface with type alias, replace Math.random() with static widths array
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add PageMeta, animation classes, and layout fixes to remaining pages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Add missing `flex` class on TreeEditorPage editor wrapper (collapsed canvas to 0 height)
- Rewrite React Flow CSS overrides to use --xy-* custom properties (v12 compat with TW4)
- Move React Flow CSS import from component to index.css (CSS layer ordering)
- Add VITE_SENTRY_DSN build arg to Dockerfile for Railway builds
- Use env var for Sentry DSN in instrument.ts with hardcoded fallback
- Add lessons learned #53-55 to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add flow export/import backend (migration, endpoints, schemas)
Add .rfflow file export/import support:
- Migration 050: import_metadata JSONB column on trees
- GET /trees/{id}/export?format=json|xml endpoint
- POST /trees/import endpoint (creates draft, resolves categories/tags)
- FlowExportEnvelope, FlowImportRequest/Response schemas
- import_metadata field on TreeResponse
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add flow export/import frontend + backend tests
Frontend:
- ExportFlowModal with JSON/XML format selection + download
- ImportFlowModal with drag-drop file picker + preview step
- rfflowParser for client-side JSON/XML .rfflow parsing
- Export buttons on editor toolbar and library action menus
- Import button on library page next to Create New
- Provenance display for imported flows in editor
- flowTransfer API client + types
Backend:
- Fix regex->pattern deprecation in export endpoint
- 12 integration tests covering export, import, round-trip,
access control, tag/category creation, version validation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove XML export, JSON-only for .rfflow files
- 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: match Flow Assist chat input to AI Assistant styling + strengthen one-question prompt
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add procedural flow support to AI chat builder (Flow Assist)
- 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>
* feat: add flow type selection to Flow Assist entry points
- 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>
* docs: update CLAUDE.md with AI chat builder and intake form learnings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: refine assistant chat prompt for concise answers and focused questions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: switch AI provider to Claude Sonnet 4.6 + add shift+enter hint to chat inputs
- 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>
* docs: update CLAUDE.md with AI provider and chat input learnings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add editor-embedded Flow Assist design document
Design for replacing the standalone /ai/chat page with context-aware
AI side panels embedded in each editor (Troubleshooting + Procedural).
Covers ghost node suggestion system, output-based thresholds,
config-driven model routing, knowledge integration, and per-flow
chat persistence.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add editor-embedded Flow Assist implementation plan
25-task plan across 9 phases covering backend foundation, frontend
infrastructure, tree/procedural editor integration, AI-assisted create,
old code removal, action-type dispatch, suggestion audit trail, and
build verification.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use actual root node ID in orphan validation check
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>
* feat: add config-driven AI model tier routing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: extend AI chat session with tree_id and archived_at
Add tree_id FK (CASCADE) for editor-embedded sessions and archived_at
timestamp column to ai_chat_sessions table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add AI suggestion audit trail table
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add action_type and focal_node_id to AI chat message API
- Add VALID_ACTION_TYPES literal and action_type/focal_node_id fields to
AIChatMessageRequest schema
- Add tree_id field to AIChatStartRequest schema for editor-embedded sessions
- Update send_message() signature with action_type and focal_node_id params
- Update start_chat_session() signature with tree_id param
- Pass new params through endpoints to service functions
- All new params have defaults so existing behavior is unchanged
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: route AI model selection through action-type config
Update get_ai_provider() to accept an optional model override parameter
(applied only to AnthropicProvider; Gemini always uses its own model).
Thread action_type-based model resolution through send_message() and
generate_final_tree() in the AI chat service.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add TypeScript types for editor-embedded AI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add shared ContextMenu component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add useEditorAI hook and editorAI API client
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add EditorAIPanel component with Chat and Suggestions tabs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: integrate AI panel, context menu, and ghost nodes in tree editor
- Add AI Assist panel toggle button to tree editor toolbar
- Wire EditorAIPanel alongside TreeEditorLayout with single-panel rule
- Thread onNodeContextMenu through TreeEditorLayout → FlowCanvas → FlowCanvasNode
- Add right-click context menu with Generate Branch, Explain Node, Delete actions
- Add ghost node detection (_suggestion flag) with dashed border + opacity styling
- Add Accept/Dismiss overlay buttons on ghost nodes for future suggestion handling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: integrate AI panel, context menu, and ghost steps in procedural editor
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add AI prompt dialog and wire into CreateFlowDropdown
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>
* fix: add glassmorphism to AI prompt dialog + maintenance Flow Assist button
- 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>
* refactor: remove standalone Flow Assist page and old AI chat components
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>
* feat: add delta response parsing and action-type prompt dispatch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add AI suggestion audit trail endpoints
Create/list/resolve endpoints for tracking AI-applied changes to flows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add APScheduler task to auto-archive stale AI chat sessions
Archives AI chat sessions with no activity for 30 days, runs daily at 3 AM.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: update project status for editor-embedded Flow Assist
- Add Editor-Embedded Flow Assist to CURRENT-STATE.md in-progress items
- Update CLAUDE.md: fix stale lessons (#41, #46), add new patterns (#47 editor AI architecture, #48 orphan validation)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use correct model alias in AI_MODEL_TIERS standard tier
The dated model ID `claude-sonnet-4-6-20250514` was causing 502 errors.
Use the alias `claude-sonnet-4-6` which matches AI_MODEL_ANTHROPIC.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: send live flow context to AI Assist for full editor awareness
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>
* feat: include flow name and description in AI Assist context
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>
* fix: increase AI timeout to 120s and limit retries to 1
The 45s timeout was too short for generation tasks with full flow
context in the system prompt. The Anthropic SDK's default 2 retries
caused requests to hang for ~136s before failing. Now: 120s timeout
with max 1 retry = faster failure if it does timeout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: wire AI-generated flow structures into editor stores
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>
* docs: add lessons learned for full-stack integration, Anthropic retries, model tiers
#49 Always verify frontend consumes backend response fields
#50 Anthropic SDK max_retries=1 to avoid 3× timeout
#51 AI model tier routing via settings.get_model_for_action()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: move AI Assist panel to full-height side layout in both editors
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>
* fix: AI Assist panel as fixed right drawer (matching Copilot/Scratchpad)
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>
* fix: AI Assist panel sits below topbar with slide-in animation
- 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>
* fix: AI Assist panel as in-flow flex sibling (not fixed/overlay)
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>
* fix: AI Copilot panel as in-flow flex sibling in session navigation pages
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>
* docs: remove duplicate CLAUDE.md lessons #47-48
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: UI design system primitives, accessibility, and performance improvements
- 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>
* fix: mobile-responsive SurveyPage with touch-friendly targets
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>
* fix: survey invite links use FRONTEND_URL config instead of hardcoded URL
PR environments were generating survey links pointing to production
(resolutionflow.com) because the URL was hardcoded. Now uses the
existing settings.FRONTEND_URL, falling back to localhost (debug)
or production (release).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: scroll to top after survey slide transition renders
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>
* fix: scroll to top on survey slide change via useEffect
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>
* fix: survey scroll-to-top on mobile using scrollIntoView
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>
* docs: add mobile scrollIntoView lesson (#52) to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add flow export/import backend (migration, endpoints, schemas)
Add .rfflow file export/import support:
- Migration 050: import_metadata JSONB column on trees
- GET /trees/{id}/export?format=json|xml endpoint
- POST /trees/import endpoint (creates draft, resolves categories/tags)
- FlowExportEnvelope, FlowImportRequest/Response schemas
- import_metadata field on TreeResponse
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add flow export/import frontend + backend tests
Frontend:
- ExportFlowModal with JSON/XML format selection + download
- ImportFlowModal with drag-drop file picker + preview step
- rfflowParser for client-side JSON/XML .rfflow parsing
- Export buttons on editor toolbar and library action menus
- Import button on library page next to Create New
- Provenance display for imported flows in editor
- flowTransfer API client + types
Backend:
- Fix regex->pattern deprecation in export endpoint
- 12 integration tests covering export, import, round-trip,
access control, tag/category creation, version validation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove XML export, JSON-only for .rfflow files
- 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: match Flow Assist chat input to AI Assistant styling + strengthen one-question prompt
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add procedural flow support to AI chat builder (Flow Assist)
- 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>
* feat: add flow type selection to Flow Assist entry points
- 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>
* docs: update CLAUDE.md with AI chat builder and intake form learnings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: refine assistant chat prompt for concise answers and focused questions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: switch AI provider to Claude Sonnet 4.6 + add shift+enter hint to chat inputs
- 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>
* docs: update CLAUDE.md with AI provider and chat input learnings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add editor-embedded Flow Assist design document
Design for replacing the standalone /ai/chat page with context-aware
AI side panels embedded in each editor (Troubleshooting + Procedural).
Covers ghost node suggestion system, output-based thresholds,
config-driven model routing, knowledge integration, and per-flow
chat persistence.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add editor-embedded Flow Assist implementation plan
25-task plan across 9 phases covering backend foundation, frontend
infrastructure, tree/procedural editor integration, AI-assisted create,
old code removal, action-type dispatch, suggestion audit trail, and
build verification.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use actual root node ID in orphan validation check
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>
* feat: add config-driven AI model tier routing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: extend AI chat session with tree_id and archived_at
Add tree_id FK (CASCADE) for editor-embedded sessions and archived_at
timestamp column to ai_chat_sessions table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add AI suggestion audit trail table
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add action_type and focal_node_id to AI chat message API
- Add VALID_ACTION_TYPES literal and action_type/focal_node_id fields to
AIChatMessageRequest schema
- Add tree_id field to AIChatStartRequest schema for editor-embedded sessions
- Update send_message() signature with action_type and focal_node_id params
- Update start_chat_session() signature with tree_id param
- Pass new params through endpoints to service functions
- All new params have defaults so existing behavior is unchanged
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: route AI model selection through action-type config
Update get_ai_provider() to accept an optional model override parameter
(applied only to AnthropicProvider; Gemini always uses its own model).
Thread action_type-based model resolution through send_message() and
generate_final_tree() in the AI chat service.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add TypeScript types for editor-embedded AI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add shared ContextMenu component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add useEditorAI hook and editorAI API client
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add EditorAIPanel component with Chat and Suggestions tabs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: integrate AI panel, context menu, and ghost nodes in tree editor
- Add AI Assist panel toggle button to tree editor toolbar
- Wire EditorAIPanel alongside TreeEditorLayout with single-panel rule
- Thread onNodeContextMenu through TreeEditorLayout → FlowCanvas → FlowCanvasNode
- Add right-click context menu with Generate Branch, Explain Node, Delete actions
- Add ghost node detection (_suggestion flag) with dashed border + opacity styling
- Add Accept/Dismiss overlay buttons on ghost nodes for future suggestion handling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: integrate AI panel, context menu, and ghost steps in procedural editor
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add AI prompt dialog and wire into CreateFlowDropdown
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>
* fix: add glassmorphism to AI prompt dialog + maintenance Flow Assist button
- 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>
* refactor: remove standalone Flow Assist page and old AI chat components
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>
* feat: add delta response parsing and action-type prompt dispatch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add AI suggestion audit trail endpoints
Create/list/resolve endpoints for tracking AI-applied changes to flows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add APScheduler task to auto-archive stale AI chat sessions
Archives AI chat sessions with no activity for 30 days, runs daily at 3 AM.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: update project status for editor-embedded Flow Assist
- Add Editor-Embedded Flow Assist to CURRENT-STATE.md in-progress items
- Update CLAUDE.md: fix stale lessons (#41, #46), add new patterns (#47 editor AI architecture, #48 orphan validation)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use correct model alias in AI_MODEL_TIERS standard tier
The dated model ID `claude-sonnet-4-6-20250514` was causing 502 errors.
Use the alias `claude-sonnet-4-6` which matches AI_MODEL_ANTHROPIC.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: send live flow context to AI Assist for full editor awareness
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>
* feat: include flow name and description in AI Assist context
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>
* fix: increase AI timeout to 120s and limit retries to 1
The 45s timeout was too short for generation tasks with full flow
context in the system prompt. The Anthropic SDK's default 2 retries
caused requests to hang for ~136s before failing. Now: 120s timeout
with max 1 retry = faster failure if it does timeout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: wire AI-generated flow structures into editor stores
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>
* docs: add lessons learned for full-stack integration, Anthropic retries, model tiers
#49 Always verify frontend consumes backend response fields
#50 Anthropic SDK max_retries=1 to avoid 3× timeout
#51 AI model tier routing via settings.get_model_for_action()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: move AI Assist panel to full-height side layout in both editors
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>
* fix: AI Assist panel as fixed right drawer (matching Copilot/Scratchpad)
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>
* fix: AI Assist panel sits below topbar with slide-in animation
- 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>
* fix: AI Assist panel as in-flow flex sibling (not fixed/overlay)
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>
* fix: AI Copilot panel as in-flow flex sibling in session navigation pages
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>
* docs: remove duplicate CLAUDE.md lessons #47-48
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Bump migration count to 49
- Add chat conclusion and survey management to recently completed
- Add lessons #41-43: assistant chat state pattern, public page fetch pattern, EmailService pattern
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>
Migrations must use sequential numbered prefixes (e.g., 040_desc.py) with
--rev-id flag. Never use auto-generated revision IDs. Updated both the
lessons learned section and the development commands.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Added lessons learned: AI tests need ai_enabled mock in CI (#28),
ESLint no-unused-vars lacks argsIgnorePattern (#29). Added Linux venv
activation path and gh CLI commands for CI debugging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrote 03-DEVELOPMENT-ROADMAP.md — replaced outdated week-by-week format with
phase-based structure reflecting actual project state. Integrated all 13 open
GitHub issues into appropriate phases. Added "After Completing Work" checklist
to CLAUDE.md coding standards and roadmap/issues to quick reference table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: maintenance flow UX redesign — batch status hub, context strip, detail page upgrades (#85)
- Add BatchStatusPage (/flows/:id/batches/:batchId): per-target Start/Resume/View cards, progress bar, 5s polling while in-progress, completion outcome summary
- Add BatchStatusCard: handles not-started/in-progress/complete states with step progress for in-progress targets
- Add ActiveBatchBanner: amber banner on detail page when a batch is running, links to BatchStatusPage
- Add MaintenanceContextStrip: amber strip in ProceduralNavigationPage for maintenance flows showing target name, batch progress (X/Y complete), and Back to Batch nav
- Update MaintenanceFlowDetailPage: active batch banner, clickable run history rows with mini progress dots and outcome summaries, Run button loading state, post-launch navigates to BatchStatusPage
- Update ProceduralNavigationPage: renders MaintenanceContextStrip between top bar and content when tree_type === 'maintenance'; fetches batch progress once on mount
- Add batch_id filter to GET /sessions backend endpoint and SessionListParams frontend type
- Add /flows/:id/batches/:batchId route to router
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: session detail page — completion action + outcome summary card
- In-progress sessions: amber banner with "Complete Session" button opens
SessionOutcomeModal to set outcome/notes/next-steps and finalize
- Completed sessions: colored outcome summary card (icon + outcome label +
duration + notes + next steps) replaces dense header metadata; "Copy for
Ticket" promoted to primary action inside the card
- Export toolbar de-emphasized to secondary row of smaller controls below
the summary card
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add library-page action props to StepCard (edit/delete/save)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: pass library-page action props through StepLibraryBrowser + refreshKey
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: StepFormModal wrapper + submitLabel/isSubmitting props on StepForm
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: Step Library page — create, edit, delete, save-to-library
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add RuntimeStep union type for procedural custom steps
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: StepChecklist accepts RuntimeStep[], renders amber Custom badge
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: StepDetail accepts RuntimeStep, renders Custom Step badge for custom steps
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: custom step insertion in procedural flow sessions
Engineers can add custom steps inline during execution. Steps are
persisted to session.custom_steps and restored on resume.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: suppress StepFeedback on custom steps, fix resume stepState seeding, functional updater for step index
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add tree forking UI design doc
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add tree fork UI implementation plan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add ForkInfo type and fork fields to Tree/TreeListItem
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: align ForkInfo type with backend schema, remove redundant fork fields
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: ForkInfo placement, required fork_info field, add JSDoc
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add ForkModal component with name and reason fields
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: ForkModal accessibility and UX (escape, click-outside, labels, maxLength)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: open ForkModal on fork action in TreeLibraryPage
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add ForkModal to MyTreesPage
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: show Fork chip badge on forked tree cards
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add flow-to-library step sync design doc
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add flow-to-library sync implementation plan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add sync tracking columns to step_library
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add sync columns and source_tree relationship to StepLibrary model
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add group_label to StepContent, is_flow_synced/source_tree_name to StepLibraryResponse
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: include is_flow_synced and source_tree_name in step list/detail responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: add is_flow_synced and source_tree_name to step list response
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: add selectinload and sync fields to search and get_step endpoints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add step_sync module with extraction and upsert logic
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: safe NOT IN placeholders for asyncpg, add deactivate docstring
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: trigger step library sync on tree publish and deactivate on delete
- Call sync_steps_from_tree in update_tree whenever the tree is published
(status transitions to 'published' or is already published and structure changes)
- Call deactivate_synced_steps_for_tree in delete_tree before db.commit()
so the FK SET NULL does not nullify source_tree_id before the WHERE clause runs
- Fix ::jsonb cast syntax in step_sync.py (asyncpg rejects :: operator in text()
queries; replaced with CAST(:content AS jsonb))
- Add UniqueConstraint('source_tree_id','source_node_id') to StepLibrary model
so Base.metadata.create_all (used by tests) creates the constraint that the
ON CONFLICT clause in sync_steps_from_tree depends on
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add is_flow_synced and source_tree_name to Step types
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: show From Flow badge and lock icon on flow-synced StepCard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: show source flow name in StepDetailModal for synced steps
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add Library Visibility select to procedural StepEditor
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: address code review issues in flow-to-library sync
- Fix sync trigger: only fire on publish transition, not every PUT
- Add TestSyncOnPublish integration tests (2 tests, 16 total passing)
- Add group_label to frontend StepContent interface
- Guard Library Visibility select to procedure_step nodes only
- Block API edits to flow-synced steps (400 read-only guard)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: handle None author_id in step sync to avoid invalid UUID error
When a system/default tree has no author (author_id is None),
str(None) produces the literal string 'None' which asyncpg
rejects as an invalid UUID for the created_by column.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: add ResolutionFlow service account to own default tree steps in library
Default/system trees had no author_id (NULL), causing a NOT NULL violation
when syncing steps to step_library.created_by on publish.
- Add is_service_account flag to users table (migration 4f4137ce)
- Add service_account.py: idempotent ensure_service_account() creates
noreply@resolutionflow.com with unusable password on startup
- Cache service account ID on app.state at lifespan startup
- Add get_service_account_id() FastAPI dep (returns None in tests)
- sync_steps_from_tree: resolve author_id or service_account_id as created_by
- create_tree: set author_id=service_account_id for is_default trees
- Migration 1490781700bc: backfill author_id on 31 existing default trees
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: AI-assisted flow builder with 4-stage wizard
Implements the complete AI flow builder feature using a guided 4-stage
wizard (Foundation → Scaffold → Branch Detail → Review & Assemble).
AI assists at bounded points using Claude Haiku for cost-efficient
structured JSON generation (~$0.01-0.03/flow).
Backend: new models (ai_conversations, ai_usage), Alembic migration,
quota enforcement with billing anchor, Anthropic API integration with
prompt caching, tree validation, conversation CRUD with 24h TTL,
APScheduler cleanup job, 5 API endpoints, Pydantic schemas.
Frontend: TypeScript types, API client, Zustand store for wizard state,
7 components (modal, step indicator, foundation form, branch selector,
branch detail view, tree preview, quota display), MyTreesPage integration
with "Build with AI" button (hidden when AI not configured).
Tests: 14 validator unit tests + 11 endpoint integration tests with
mocked Anthropic (zero real API spend). All 25 tests passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: dashboard design doc and implementation plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: Phase 1 — pinnedFlowsStore, pagination hook, cached quota hook, sidebar refactor
- Add pin() to pinnedFlowsApi
- Create pinnedFlowsStore (Zustand) — single source of truth for pin state
- Add dashboardMyFlowsView preference to userPreferencesStore
- Create usePaginationParams hook (URL-synced)
- Create useCachedQuota hook (5-min TTL)
- Sidebar uses pinnedFlowsStore instead of local state
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: Phase 2 — pin/favorite buttons on all library view components
- TreeGridView: star in top-right corner of cards
- TreeListView: star at end of each row
- TreeTableView: dedicated leftmost Favorite column
- All with proper a11y (aria-label), event isolation, loading states
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: Phase 3 — Library page create dropdown + AI Builder + pin wiring
- Replace single Create link with dropdown menu (3 flow types + AI Builder)
- Wire pinnedFlowsStore to all view components
- AI Builder modal integration via useCachedQuota hook
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: Phase 4 — Dashboard refactor with Favorites grid + paginated My Flows
- Favorites section: compact grid from pinnedFlowsStore, max 2 rows, expandable
- My Flows: author_id filter, URL-synced pagination (10/25/50/All)
- View toggle (grid/list/table) with independent preference
- Skeleton loaders, empty states with CTAs
- Create dropdown with AI Builder option
- 500-item ceiling for "Show All" mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: Phase 5 — Sidebar pinned section dual collapse + show more/less
- Header collapse hides entire section, resets to 5 items on re-expand
- List truncation: show first 5, "Show more (N)" expands to all
- Clicking a flow auto-collapses back to 5
- Smooth max-height CSS transition (250ms ease-out)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: stabilize usePaginationParams to prevent infinite re-render loop
allowedPageSizes array was recreated every render as a useMemo dep,
causing infinite updates. Use useRef to stabilize the reference.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove Set-based Zustand selectors causing infinite re-render loop
Zustand selectors returning new Set() on every call fail Object.is
equality check, triggering continuous re-renders. Replaced with
useMemo-derived Sets in consuming components.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: pin route ordering and star icon overlap in grid view
Move GET /pinned and PATCH /pinned/reorder before GET /{tree_id} to
prevent FastAPI from matching "pinned" as a UUID path parameter (422).
Relocate star button from absolute positioning into the header row to
avoid overlapping privacy icons and category badges.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: code review fixes — date calc, input validation, rate limits, shared components
- Fix monthly_reset_at crash when billing anchor day exceeds next month's length
- Add environment_tags sanitization (max 20 tags, 100 chars each) to prevent prompt injection
- Add @limiter.limit("10/minute") rate limiting to all AI endpoints
- Use getTreeNavigatePath() routing helper instead of hardcoded paths
- Extract shared CreateFlowDropdown component from QuickStartPage and TreeLibraryPage
- Clear useCachedQuota on logout to prevent stale data across user sessions
- Add useRef guard to scaffold useEffect to prevent potential double-fire
- Use node.id as React key instead of array index in BranchDetailView
- Remove redundant dead logic in ai_tree_validator
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: correct Anthropic model ID to full dated version
claude-haiku-4-5 is not a valid model alias — Anthropic requires the
full dated model ID claude-haiku-4-5-20251001.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: strip markdown code fences from AI JSON responses
Haiku sometimes wraps its JSON in ```json ... ``` despite the prompt
instructing otherwise. Strip fences before parsing to avoid JSONDecodeError
at char 0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: increase branch_detail max_tokens to 8192 and add response logging
Truncated output at 4096 tokens produces invalid JSON mid-generation.
Also logs stop_reason and output_tokens per attempt to diagnose failures.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: pass explicit status='draft' when creating AI-generated flow
Tree model defaults to 'published' in the DB schema, but passing status=None
from the constructor overrides that default, causing a nullable=False violation
and a 500 on save.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: auto-advance branch detail and pin navigation bar
- Auto-advance to next undetailed branch after generation completes,
using a useEffect that watches the count of detailed branches
- Cap tree preview at max-h-48 with internal scroll so the nav bar
is never pushed off screen
- Make nav bar sticky bottom-0 with bg-card so it stays visible
regardless of content height
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: increase branch retries to 3 and relax cross-reference validation on final attempt
next_node_id mismatches are a common model hallucination that the retry
prompt doesn't reliably fix. On the final (3rd) attempt, accept the branch
with strict=False so only truly fatal errors (missing fields, dead ends,
bad JSON) cause a hard failure. Cross-reference issues are minor and
fixable in the tree editor.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: strengthen prompt to prevent next_node_id mismatches, keep strict validation
Rather than lowering the validation bar, improve the system prompt:
- Rule 6 now explicitly states next_node_id must match a direct child's id
- Added rule 10: build tree bottom-up to avoid forward-reference errors
- Corrective prompt now calls out the ID mismatch constraint specifically
Reverts the strict=False fallback — flows must be correct before saving.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: persist branch viewing index in store to survive phase remounts
Local useState resets to 0 every time phase transitions from 'generating'
back to 'detailing', causing the view to snap back to branch 1.
Move viewingIndex to store's currentBranchIndex (already existed) and
advance it in generateBranchDetail after success. Component reads from
store so remounts no longer lose position.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: correct publish validation to check title instead of action/solution fields
The publish validator was checking for an 'action' field on action nodes
and a 'solution' field on solution nodes, but the actual node schema
(confirmed from seed data and frontend types) uses 'title'/'description'.
This caused all AI-generated trees to fail publish validation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: correct action node schema and improve AI flow quality
- Fix action nodes to use next_node_id (not children) for continuation,
matching how TreeNavigationPage.tsx navigates action nodes
- Validator now requires next_node_id on all action nodes and flags
missing ones as broken dead ends
- Update _check_branch_termination: action nodes are not dead ends since
they continue via next_node_id (validated separately)
- Improve scaffold prompt: branch names must describe observable symptoms
users can self-identify, not internal category names
- Update branch_detail prompt with clearer action node schema, corrected
few-shot example showing proper next_node_id on action nodes
- Improve assemble_tree root question to be more user-facing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add AI flow builder gotchas to CLAUDE.md (#23-25)
- Action nodes use next_node_id (not children) for navigation
- Anthropic model IDs require full dated version string
- Claude API may wrap JSON in markdown fences
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: resolve CI lint errors and httpx dependency conflict
- Fix httpx version conflict: requirements-dev.txt now uses >=0.27.0 to match requirements.txt
- Extract CSAT helper functions to csatUtils.ts to fix react-refresh/only-export-components
- Remove default export from admin/EmptyState.tsx shim (same rule)
- Fix empty catch block in Modal.tsx (no-empty)
- Add eslint-disable comments for intentional setState-in-effect patterns in
FlowAnalyticsPanel, QuickLaunch, NodeEditorPanel, useCachedQuota,
MyAnalyticsPage, TeamAnalyticsPage
- Add eslint-disable comments for intentional _children destructure in NodeEditorPanel
- Fix _parentId unused var in useTreeLayout.ts
- Rewrite usePaginationParams.ts to avoid reading refs during render
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: update tests to match action node schema (next_node_id, not children)
- Update _make_valid_tree() in test_ai_tree_validator to use next_node_id
on action nodes (solution is a sibling, not a child)
- Fix test_dead_end_action_node → test_dead_end_decision_node (action nodes
don't have child-based dead ends; dead ends are decision nodes with no children)
- Add test_action_missing_next_node_id for the new validation rule
- Update BRANCH_DETAIL_JSON in test_ai_endpoints to use next_node_id pattern
- Update test_draft_trees.py to use "title" field for action/solution nodes
(tree_validation.py was updated this branch to require "title" not "action"/"solution")
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: update remaining tests and session_to_tree for title field rename
- test_tree_validation.py: replace "action"/"solution" content fields with "title"
- test_procedural_flows.py: update solution node fixtures to use "title"
- test_save_session_as_tree.py: update fixtures and assertions for "title" field
- session_to_tree.py: generate "title" instead of "action"/"solution" on converted nodes;
fall back to legacy field names when reading from old tree snapshots for compatibility
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>