Commit Graph

368 Commits

Author SHA1 Message Date
chihlasm
e39819f8d0 Add Playwright e2e coverage and Node 20 pin 2026-03-16 02:29:22 -04:00
chihlasm
357f8e2d08 feat: sidebar redesign — activity feed, grouped nav, AI split (#107)
* docs: add 5 sidebar icon color concepts for UX review

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(ui): add semantic icon colors and updated icons to sidebar nav

Swap generic icons for more descriptive alternatives (Network, Wrench,
FileOutput, Library, Code2, Lightbulb) and assign each nav item a unique
semantic color for instant visual landmarks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(ui): default Sessions page to Active tab, reorder tabs

Active sessions are what engineers care about most. Tab order is now
Active, Prepared, Completed, All.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add sidebar grouping and AI naming concept mockups

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add sidebar redesign context and decision summary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add sidebar redesign spec and implementation plan

Design spec covers: activity zone with daily stats + session feed,
nav grouping (Resolve/Build/Insights), AI split (FlowPilot + Flow Assist),
pinned flows removal. Implementation plan has 5 chunks, 12 tasks, 39 steps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add sidebar stats Pydantic schemas

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add failing tests for sidebar stats endpoint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add sidebar stats endpoint with daily stats and activity feed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add sidebar API client, stats bar, activity feed components

New components: SidebarStatsBar, SidebarActivityFeed, ActivityItem.
New API client for sidebar stats endpoint. Pulse-dot CSS animation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: restructure sidebar with stats bar, activity feed, and grouped nav

Dashboard-first layout with Resolve/Build/Insights groups.
AI split: FlowPilot (Resolve) + Flow Assist (Build).
Stats bar: Resolved/Active/In Session daily counters.
Activity feed: active sessions with CW ticket #, recent completions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: remove pinned flows frontend (PinnedFlowsSection, store, API, pin buttons)

Removed: PinnedFlowsSection component, pinnedFlowsStore, pinnedFlows API client.
Cleaned: pin buttons from TreeGridView, TreeListView, TreeTableView.
Cleaned: favorites section from QuickStartPage, pin props from TreeLibraryPage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add FlowAssistPage placeholder and /flow-assist route

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: real-time sidebar stats via session-changed events

Sidebar now refreshes stats when sessions are created or completed,
not just on page navigation. Uses window event bus pattern (same as
folder-changed events in codebase).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: live-ticking In Session timer using active session start times

SidebarStatsBar now computes active session elapsed time client-side
from started_at timestamps, ticking every 60s. Backend only returns
completed session minutes to avoid double-counting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: sidebar In Session timer ticks every second and shows seconds

Timer now uses 1s interval (not 60s) and displays seconds when under
a minute so it matches the session timer in the flow UI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: trigger PR environment redeploy

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* debug: add console.log to SidebarStatsBar for timer investigation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: parse sidebar timestamps as UTC (append Z suffix)

Backend returns naive UTC timestamps without timezone indicator.
JS Date() treats bare ISO strings as local time, causing the timer
to compute negative elapsed time (future timestamps). Appending 'Z'
forces UTC parsing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: rename 'In Session' to 'Total Time' for clarity

Makes it clear the timer is an aggregate of all sessions today,
not just the current one.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 01:35:16 -04:00
chihlasm
46865882c6 feat: ConnectWise PSA integration (#106)
PSA abstraction layer with provider pattern, ConnectWise integration (connection management, ticket linking, note posting, status updates, member mapping), Integrations page UI, Fernet credential encryption, in-memory TTL cache, 6 DB migrations, ConnectWise API reference docs.
2026-03-15 01:45:35 -04:00
Michael Chihlas
80e094215f docs: add ConnectWise PSA integration design spec
Comprehensive design for ConnectWise PSA integration covering
credential management, service ticket integration, session-to-ticket
notes, and callback webhooks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 20:31:03 -04:00
chihlasm
d4dbf44781 feat: Script Generator Phase 1+2 — backend, engine, API, frontend, template editor, parameter detector
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>
2026-03-14 20:18:59 -04:00
chihlasm
83b13fcd26 polish: use 'step' instead of 'node' in procedural editor validation hints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:32:52 -04:00
chihlasm
45fb468db3 feat: add validation summary and Fix with AI to procedural editor
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:32:52 -04:00
chihlasm
f9315d2f60 feat: add data-step-id anchor to StepList for validation scroll-to
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:32:52 -04:00
chihlasm
b89d0859d4 feat: add validation state and validate() to proceduralEditorStore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:32:52 -04:00
chihlasm
b804c63754 fix: validation summary click-to-select now opens node editor panel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:32:52 -04:00
chihlasm
d989fabd90 Merge feat/kb-accelerator into main 2026-03-12 17:29:07 -04:00
Michael Chihlas
cfe112ac43 docs: add landing page assets and polish landing CSS
Add landing page .docx export, HTML mockup, docx generator script,
and refine landing page CSS formatting/spacing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:28:49 -04:00
chihlasm
042a12b190 feat: add landing page with beta signup + raise KB node limit to 100
Landing page at /landing with full marketing content: hero, features,
pricing, testimonials, and beta email signup form. Beta signups email
beta@resolutionflow.com via new public endpoint. Unauthenticated users
redirect to landing instead of login. Also raises KB Accelerator node
limit from 50 to 100 to accommodate dense troubleshooting articles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:23:29 -04:00
chihlasm
92c86cab80 fix: handle object-shaped validation errors in KB commit error toast
The commit endpoint returns {message, validation_errors} when
validation fails, but the error handler was passing the whole object
to toast.error(), crashing React with "Objects are not valid as a
React child".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:56:45 -04:00
chihlasm
458c2d9cab fix: prevent circular parent_node_id in KB troubleshooting import
AI-generated trees can have circular next_node_id references (e.g.,
node A → B → A). The parent mapping now checks for cycles before
assigning parent_node_id, preventing FK deadlocks during insert.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:46:49 -04:00
chihlasm
efafcff4b2 fix: topological insert for KB import nodes to satisfy parent FK
Nodes with parent_node_id references were inserted in a single batch,
causing FK violations when children were inserted before their parents.
Now inserts roots first, flushes, then children in subsequent passes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:41:25 -04:00
chihlasm
03390ed59f feat: enable Markdown (.md) file upload in KB Accelerator
Moved md from Phase 2 extensions to allowed formats, added extraction
handler (reuses txt handler), and updated plan_limits defaults to
include md for all plans.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:29:51 -04:00
chihlasm
fe3c651115 fix: remove "Let AI Decide" option from KB Accelerator upload
The uploader should know their content type — auto-detection adds
complexity and currently just defaults to troubleshooting anyway.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 22:56:40 -04:00
Michael Chihlas
963c0da10a docs: update CLAUDE.md with Railway and node field learnings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 21:19:51 -04:00
Michael Chihlas
9495b09e72 fix: copilot node context — use title/question/description over legacy content field
_build_flow_context() was reading node.get('content') which was only
present on old KB-imported steps. Now falls back through title →
question → description → content → label so all node types (decision,
action, solution, procedural step) show correctly in the copilot context.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 17:55:26 -04:00
Michael Chihlas
53b6878742 fix: KB procedural import — map step content to description field
Steps built by _build_procedural_tree() were stored under the "content"
key but StepDetail.tsx reads "description". Renamed the key so step
text and commands display correctly during session execution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 12:50:13 -04:00
Michael Chihlas
00e1e701ca fix: procedural KB import — add title field, correct step types, validation gate
- _build_procedural_tree now maps AI node types (step, action, warning) to
  valid procedural types (procedure_step, section_header, procedure_end)
- Generates 'title' field from content text — fixes "Unnamed step" in editor
- Auto-appends procedure_end step if AI didn't generate one
- Adds procedural validation gate at commit endpoint (same as troubleshooting)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 09:12:43 -04:00
Michael Chihlas
c920e825c6 fix: auto-reload on chunk load errors in ErrorBoundary
RouteError already handled stale chunk errors, but the Sentry ErrorBoundary
didn't — so errors from React lazy() imports hit the generic error UI.
Now auto-reloads with loop prevention (10s cooldown via sessionStorage).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 03:17:24 -04:00
Michael Chihlas
a976f16575 fix: session closure popover z-index — bypass stagger-item stacking context
The StaggerList wrapper creates per-item stacking contexts via CSS animation,
causing the absolute-positioned close popover to render behind sibling cards.
Replace StaggerList with inline stagger-item rendering so we can apply z-50
directly to the stagger-item wrapper when its popover is open.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 03:09:17 -04:00
Michael Chihlas
8c73233dd0 fix: KB conversion — increase max_tokens, add JSON repair, improve error handling
- Increase max_tokens from 8192 to 16384 to prevent truncation on long articles
- Add _try_repair_json() that fixes trailing commas and attempts to close
  unclosed brackets/braces from truncated AI responses
- Log full raw response (first 2000 chars) on parse failure for debugging
- Set status to 'failed' with user-friendly error message instead of leaving
  imports stuck in 'processing' state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:57:27 -04:00
Michael Chihlas
8b3033ca9d fix: tree navigation root ID + session closure popover z-index
- TreeNavigationPage: initialize currentNodeId from tree_structure.id
  instead of hardcoded 'root' — fixes "Invalid tree structure" for trees
  with non-'root' root IDs (KB Accelerator, AI Flow Builder)
- SessionHistoryPage: add relative z-10 to session card when close
  popover is open so it renders above sibling cards

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:54:00 -04:00
Michael Chihlas
2f23141daf fix: KB tree builder — post-build repair, validation gate, and root ID handling
- Add _repair_tree() post-build pass that fixes structural issues caused by
  placed-set race conditions: demotes decisions with <2 children to actions,
  hoists orphaned children as siblings, converts dead-end actions to solutions
- Add validation gate at commit endpoint — rejects trees that fail validation
  with a 422 and descriptive error messages instead of saving invalid trees
- Update test fixtures to create valid multi-node tree structures
- Frontend: initialize currentNodeId from tree's actual root ID instead of
  hardcoded 'root', fixing "Invalid tree structure" for KB-generated trees

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:53:55 -04:00
Michael Chihlas
c1fb2f180c fix: KB tree builder demotes decisions with < 2 branches to actions
Decision nodes with fewer than 2 buildable child targets now get
demoted to action nodes instead of creating invalid tree structures.
Also adds id fields to option objects (required by tree editor).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:31:17 -04:00
Michael Chihlas
416bb230e3 feat: close sessions from history page with inline popover
Add ability to close active sessions directly from the Session History
page via an inline popover with outcome selection and optional notes.
Adds two new outcomes: cancelled and resolved_externally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 01:59:12 -04:00
Michael Chihlas
91d2bc6df3 fix: KB Accelerator tree builder, approve all, canvas delete button
- Fix _build_troubleshooting_tree() to handle deep nesting, warning nodes,
  and DAG deduplication (placed set prevents duplicate IDs)
- Fix step_sync VARCHAR(255) overflow on publish by truncating title
- Add "Approve All" button to KB review screen
- Add delete button (hover-reveal) to flow canvas nodes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 01:59:03 -04:00
Michael Chihlas
71ff4a8c35 feat: KB Accelerator — convert KB articles into interactive flows
Full-stack implementation of the KB Accelerator feature that converts
static MSP knowledge base articles into interactive troubleshooting
and procedural flows using AI.

Backend:
- Migrations 054/055: kb_imports, kb_import_nodes tables + plan_limits KB columns
- SQLAlchemy models with relationships and self-referential node hierarchy
- Text extraction service (txt, paste, docx with structural metadata)
- AI conversion service with MSP-specialist prompts for both flow types
- 8 API endpoints: upload, get, list, convert, edit node, commit, delete, quota
- Tier-gated access via plan_limits (free: 3 lifetime, pro/team: unlimited)
- 8 integration tests covering upload, get/list, quota, commit, delete

Frontend:
- TypeScript types and API client for all KB Accelerator endpoints
- Multi-step wizard page: upload → processing → review → success
- Upload screen with paste/file tabs, drag-drop, target type selector
- Two-panel review screen with source highlighting and node cards
- Per-node actions: approve, edit, regenerate, insert, delete
- Confidence color indicators (green/amber/red)
- Sidebar navigation with Sparkles icon
- Code-split lazy-loaded route at /kb-accelerator

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 20:56:28 -04:00
chihlasm
c65aa4f0b7 chore: remove Sentry verification error from frontend 2026-03-10 10:09:35 -04:00
Michael Chihlas
9eed8ab848 chore: remove Sentry verification error from frontend
The test error was firing on every production page load — no longer needed
now that Sentry is confirmed working.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 09:57:41 -04:00
chihlasm
ccd06c9ed4 feat: flexible intake — deferred variables + prepared sessions (#103)
* feat: flexible intake — deferred variables + prepared sessions

Remove blocking intake form modal. Variables are now filled inline during
flow execution or pre-filled via prepared sessions. Adds PATCH /sessions/{id}/variables
endpoint, POST /sessions/prepare for session pre-staging, inline variable prompts
in StepDetail, editable Session Variables panel, and "Prepared for You" dashboard section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: pass treeData directly to startSession to avoid stale state

setTree(treeData) hasn't committed when startSession runs immediately
after, so tree is still null and getStepsFromTree returns []. This
caused the step detail area to render empty on new session start.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: wire PrepareSessionModal entry point in Flow Library

Add "Prepare session" button (clipboard icon) to grid, list, and table
views for procedural/maintenance flows. Clicking fetches tree intake
fields and account members, then opens PrepareSessionModal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 09:49:51 -04:00
chihlasm
4727106141 fix: race condition hardening across auth, counters, and data fetching (#102)
* fix: prevent race conditions in token operations and auth flows

Backend:
- Refresh token rotation: use atomic UPDATE...WHERE revoked_at IS NULL
  to prevent concurrent refresh requests from both succeeding
- Account invite codes: SELECT FOR UPDATE to prevent double-spend
- Platform invite codes: SELECT FOR UPDATE to prevent double-spend
- Password reset tokens: SELECT FOR UPDATE to prevent double-use
- Email verification tokens: SELECT FOR UPDATE to prevent double-use

Frontend:
- Token refresh subscriber arrays: swap before iterating so a throwing
  callback doesn't leave the queue in a dirty state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: atomic counters, plan limit re-check, and double-submit guard

Backend:
- Tree usage_count: use SQL-level UPDATE (Tree.usage_count + 1) instead
  of Python-level increment to prevent lost updates under concurrency
- Tag usage_count: same SQL-level atomic increment/decrement in both
  create_tree and update_tree (delete_tree already used this pattern)
- Plan tree limit: re-check count after db.flush() to close the TOCTOU
  window where two concurrent creates could both pass the pre-check

Frontend:
- TreeEditorPage: add isSaving early-return guard inside handleSaveDraft
  and handlePublish callbacks so Ctrl+S can't bypass the button disabled
  prop and fire duplicate save requests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: prevent stale API responses from overwriting newer data

- SessionHistoryPage: move loadSessions into effect with cancelled flag
  so rapid filter/tab changes discard outdated responses
- TreeLibraryPage: add request ID ref to loadTrees so stale responses
  from previous filter selections are discarded
- QuickStartPage: add request ID ref to debounced search so out-of-order
  responses don't overwrite newer search results

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add flexible intake design — deferred variables + prepared sessions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 01:57:22 -04:00
chihlasm
5095b0d8df refactor: adopt shared Input/Textarea components (#101)
* 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>
2026-03-09 16:12:21 -04:00
chihlasm
b28a096738 feat: add glow edge system with directional selection animation
Custom bezier edges with gradient glow for the flow editor:
- Default: subtle white/gray gradient with soft glow
- Downstream (cyan): animated flowing dashes from selected node through subtree
- Upstream (amber): animated flow from selected node back to root
- Cross-reference: dashed cyan with arrow markers
- SVG gradient + filter defs for performant rendering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 04:36:46 -04:00
chihlasm
d06abe5829 fix: restore tree editor visibility after Tailwind v4 upgrade and add Sentry DSN build arg
- 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>
2026-03-09 04:36:37 -04:00
chihlasm
a900408c3b fix: hardcode Sentry DSN to ensure it's available at build time
Vite env vars must be present during build — VITE_SENTRY_DSN was likely
undefined in Railway's build step, causing Sentry to silently not init.
DSN is a public client key (shipped in every browser bundle), not a secret.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:36:14 -04:00
chihlasm
5885888489 fix: use captureException for Sentry verification instead of captureMessage
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:13:16 -04:00
chihlasm
4d2f644bac feat: maximize Sentry free plan coverage for frontend and backend
- ErrorBoundary: use Sentry.ErrorBoundary with crash feedback dialog
- RouteError: capture route errors in Sentry (skip chunk load errors)
- User context: set Sentry user on login (frontend + backend)
- Backend: enable profiling (profiles_sample_rate)
- Frontend: add feedback integration, lower replay rate to conserve quota
- Add temporary verification message for production validation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:03:29 -04:00
chihlasm
2a2894496d fix: use session_id instead of id in AI flow builder
CreateFlowDropdown accessed `session.id` which is undefined — the API
returns `session_id`. The undefined value caused "undefined" to be
interpolated into URL paths, triggering 422 validation errors from
FastAPI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 17:41:22 -04:00
chihlasm
df46046c86 fix: resolve MissingGreenlet crash and add MCP fallback in AI Assistant
Capture user_id/account_id before try block so error handler survives
db.rollback() without triggering lazy loads in async context. Add
retry-without-MCP fallback when Anthropic MCP server returns rate limit
or connection errors.

Fixes PYTHON-FASTAPI-3, PYTHON-FASTAPI-4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 15:43:22 -04:00
chihlasm
94b428d168 refactor: enforce shared Modal component (#100)
* refactor: enforce shared Modal component in remaining custom modals

- ShareSessionModal: replaced custom modal markup with <Modal>
- CreateCategoryModal: replaced custom modal markup with <Modal>
- EditCategoryModal: replaced custom modal markup with <Modal>
- All now get focus trapping, Escape close, body scroll lock for free

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: adopt shared Button component in 18 modal components

Replace raw <button> elements with <Button> from ui/Button.tsx:
- Primary buttons (bg-gradient-brand) → <Button variant="primary">
- Secondary buttons (border-border) → <Button variant="secondary">
- Ghost buttons → <Button variant="ghost">
- Loading states use loading prop instead of manual Loader2 spinner

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: adopt shared Button component in 20 page/component files

Replace raw <button> elements with <Button> across pages and remaining
components. 38 total files now use the shared Button component consistently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 00:25:50 -05:00
chihlasm
d365c38b61 chore: Tailwind CSS v3 → v4 migration (#99)
* chore: run Tailwind v4 upgrade tool (Phase 1)

- Upgraded tailwindcss v3 → v4.2.1, postcss plugin to @tailwindcss/postcss
- Deleted tailwind.config.js, migrated theme to CSS @theme block in index.css
- Replaced @tailwind directives with @import 'tailwindcss'
- Added @custom-variant dark, @utility blocks for custom utilities
- Updated class names across 128 files (shadow-sm → shadow-xs, etc.)
- Removed autoprefixer (built into v4)
- Added migration plan doc

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: switch from @tailwindcss/postcss to @tailwindcss/vite (Phase 2)

- Replaced @tailwindcss/postcss with @tailwindcss/vite plugin
- Deleted postcss.config.js (no longer needed)
- Tailwind now runs as a native Vite plugin for faster HMR

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: convert to OKLCH colors, move keyframes into @theme (Phase 3-4)

- Replaced all HSL color indirection with direct OKLCH values in @theme
- Moved all keyframes inside @theme block (v4 pattern)
- Eliminated hsl(var(--x)) double-indirection across 17 component files
- Replaced hsl() inline styles with var(--color-*) theme references
- Cleaned up redundant rdp-* utility blocks
- Fixed @custom-variant dark syntax to use :where()
- Added sidebar/glass/shadow vars as OKLCH in :root

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:10:44 -05:00
Michael Chihlas
732ccba966 chore: remove /sentry-debug endpoint after verification
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:37:50 -05:00
Michael Chihlas
a96ed9138f feat: add /sentry-debug endpoint for verification
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:36:27 -05:00
chihlasm
e3a1e6fb75 feat: Sentry error monitoring for React frontend (#98)
* feat: add Sentry error monitoring, tracing, and session replay

- Install @sentry/react and @sentry/vite-plugin
- Create instrument.ts with error monitoring, browser tracing (20% prod),
  and session replay (10% sessions, 100% on errors)
- Wire React 19 reactErrorHandler() on createRoot error hooks
- Wrap router with wrapCreateBrowserRouterV7 for route-aware transactions
- Configure sentryVitePlugin for source map uploads
- Add VITE_SENTRY_DSN to .env.example

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add Sentry error monitoring and tracing to FastAPI backend

- Install sentry-sdk[fastapi] with auto-enabled FastAPI + Anthropic
  integrations
- Init before app = FastAPI() with env-aware sample rates
  (100% dev, 20% prod)
- Filter /health endpoint from traces to reduce noise
- Add SENTRY_DSN to config settings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:29:58 -05:00
chihlasm
96966c3b72 feat: Flow Transfer, Procedural Assist & UI Design System (#97)
* 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>
2026-03-07 18:44:14 -05:00
chihlasm
0dc6123c0c feat: flow export/import + procedural Flow Assist (#96)
* 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>
2026-03-07 15:51:37 -05:00