The old /assistant/chats/* CRUD endpoints and assistant_chat_service
chat functions were unused — the frontend exclusively uses
/ai-sessions/{id}/chat (unified_chat_service) for all chat operations.
Removed:
- Chat CRUD endpoints (create, list, get, send, delete, conclude)
- assistant_chat_service: create_chat, send_message,
generate_conclusion_summary, CONCLUSION_SYSTEM_PROMPT
- Frontend: assistantChatApi chat methods, dead types
(AssistantChat, AssistantChatMessage, ConcludeChatRequest, etc.)
Kept:
- /assistant/retention endpoints (used by ChatRetentionSettingsPage)
- Shared AI infrastructure (_call_ai, _call_anthropic_cached,
ASSISTANT_SYSTEM_PROMPT, _auto_title) — imported by unified_chat_service
Moved:
- fetch_upload_images + resize_image_for_vision → storage_service.py
(shared location, not tied to dead endpoint)
Also added "Image Analysis" section to system prompt so Claude knows
to describe attached screenshots.
-650 lines of dead code removed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The frontend calls /ai-sessions/{id}/chat (unified_chat_service), not
/assistant/chats/{id}/messages (assistant_chat_service). The previous
commit wired images into the wrong backend. This fixes it:
- ai_session.py schema: add upload_ids to ChatMessageRequest
- ai_sessions.py endpoint: fetch images via _fetch_upload_images
- unified_chat_service: accept and forward images to _call_ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Backend: ChatMessageRequest accepts upload_ids, endpoint fetches
images from S3, base64-encodes them, passes to Claude as multimodal
content blocks (vision API)
- Backend: add download_file() to storage_service for fetching from S3
- Frontend: handleSend collects completed upload IDs from pendingUploads
and includes them in the sendChatMessage API call
- Frontend: prefill handler passes upload IDs from dashboard nav state
- Enables paste-screenshot → AI-sees-it flow end-to-end
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add session_type ('guided'|'chat') and title columns to ai_sessions,
enabling both FlowPilot guided sessions and assistant chat sessions to
live in a single table. This is the foundation for a unified session
history and consistent UX across both interaction modes.
Backend:
- Migration 066: session_type + title columns
- unified_chat_service: chat sessions on ai_sessions with same AI/RAG
- POST /ai-sessions supports session_type='chat' creation
- POST /ai-sessions/{id}/chat for chat messages
- DELETE /ai-sessions/{id} for session deletion
- session_type filter on GET /ai-sessions
Frontend:
- AssistantChatPage rewired to aiSessionsApi (no more assistantChatApi)
- /assistant/:sessionId route for deep-linking
- Session history: type filter pills (All/Guided/Chat), type icons
- Dashboard: both types shown with correct routing and icons
- Fixed glass-border → border-default in dashboard components
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full-stack beta feedback system:
Backend:
- BetaFeedback model with reaction, category, text, page context
- POST /feedback/beta (any auth user), GET /feedback/beta (admin, filtered)
- Alembic migration 065 with indexes on user_id, reaction, created_at
Frontend:
- Persistent "Feedback" tab on right edge of all authenticated pages
- Slide-out panel: quick reaction (👍😐👎), category pills, optional text
- Auto-captures page URL and FlowPilot session ID
- Hidden on mobile (<640px), closes on Escape/outside click
- Shows "Thanks!" confirmation then auto-closes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Engineers can now generate AI-powered status updates during active FlowPilot
sessions and after resolve/escalate. Three audiences (Ticket Notes, Client
Update, Email Draft) with Quick/Detailed length options. Copy to clipboard
with one click. Client names auto-inserted from intake/PSA context.
Backend: new endpoint POST /ai-sessions/{id}/status-update with audience-aware
system prompts. Frontend: StatusUpdateModal with 2-step selection flow,
Share Update button in action bar, Share Resolution/Escalation on completed
sessions. Also updates Solutions Library spec with Community tier design.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract JSONB messages array from script_builder_sessions into a proper
script_builder_messages table with individual columns for role, content,
script, tokens, etc. Migration handles data migration from JSONB to rows.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Message bar now fixed-positioned above action bar with full-width
layout (respects both app sidebar and session sidebar)
- Added abandon_session endpoint (POST /ai-sessions/{id}/abandon)
- Added "Close" button to FlowPilot action bar with confirmation dialog
- Session can now be closed without resolving or escalating
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add language column (powershell/bash/python) to script_templates model and schemas
- Seed 'AI Generated' script category via migration 063
- Add mine and shared query params to list_templates endpoint
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Script Builder service with language-specific system prompts (PowerShell, Bash, Python)
- AI-powered script generation with code block extraction and filename detection
- Context window management (last 20 messages) and session message limits
- REST API: CRUD sessions, send messages, save to Script Library
- Rate limiting on message endpoint (10/min), max 5 concurrent sessions per user
- Registered script_build action in AI model tier routing (standard tier)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Users without team_id (solo accounts, pro plans) couldn't see
escalations because the query filtered by team_id which was NULL.
Now falls back to account_id scoping for both the escalation queue
endpoint and the sidebar badge count.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add escalation_count to sidebar stats (team-wide requesting_escalation)
- Show badge on Escalations nav item in sidebar
- Remove user_id filter from escalation queue — show all team escalations
including your own (needed for solo users and visibility)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The same model_validate bug existed in link_ticket endpoint (line 467).
Extracted the manual AISessionDetail construction into a shared helper
_build_session_detail() used by both get_session and link_ticket.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: AISessionDetail.model_validate(session) tried to validate the
ORM relationship 'steps' which has field 'id', but AISessionStepResponse
expects 'step_id'. This caused a Pydantic ValidationError on every session
detail load.
Fix: Construct AISessionDetail manually from ORM fields, passing the
already-built step_responses list directly instead of relying on
model_validate to serialize the ORM steps relationship.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Temporary debug commit — surfaces the actual exception when GET /ai-sessions/{id}
fails with 500, instead of generic "Internal server error" from middleware.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: embedding generation could break the DB transaction via a failed
SQL statement. The except block caught the Python error but left the transaction
in a failed state. Subsequent queries (_record_usage → subscription lookup)
then failed with InFailedSQLTransactionError.
Fixes:
- session_embedding_service: use begin_nested() savepoint so failures don't
poison the parent transaction
- ai_sessions.py: add db.rollback() before _record_usage in all 3 error
handlers (create, respond, pickup) to recover from broken transactions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix AISession.ticket_id → psa_ticket_id in list_sessions filter query
- Add Gallery nav item (LayoutGrid icon) to AdminSidebar navItems array
- Remove ForeignKey from FileUpload.session_id (Python model) + migration b8d2f4a6c091 to drop DB constraint, allowing column to reference either session type
- Add 400ms debounce on AI session search input in SessionHistoryPage (aiSearchInput state + useRef timeout pattern)
- Show friendly 503 error message in RichTextInput upload error handler (both initial upload and retry paths)
- Add overflow-x-auto to FlowPilotAnalyticsPage tab bar container
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds vector-based similar session discovery using the existing Voyage AI
embedding infrastructure and pgvector cosine similarity search.
- New AISessionEmbedding model with vector(1024) column
- session_embedding_service: generate + upsert embeddings, find similar sessions
- Embeddings generated on session create (from problem_summary/domain) and
updated on resolve (adds resolution_summary)
- GET /ai-sessions/{id}/similar endpoint returns top-N similar sessions
- Migration a7c9e3b1f402 creates ai_session_embeddings table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- POST /uploads: multipart upload with content-type/size validation, per-session limits, S3 storage
- GET /uploads/{id}/url: presigned download URL with account ownership check
- GET /uploads: list uploads for a session
- DELETE /uploads/{id}: delete with ownership enforcement (403 for non-owners)
- Returns 503 gracefully when STORAGE_ENDPOINT is not configured
- 15 integration tests covering auth, validation, 503 behavior, and ownership
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Issue 1: Normalize domain lookup to lowercase on both sides (flow category names and session problem_domain) to fix case-sensitive mismatch in coverage endpoint
- Issue 2: Count distinct ai_session_id (not PsaPostLog.id) in doc_pushed funnel step to avoid inflating counts on retried sessions
- Issue 3: Clamp recency_score to [0.0, 1.0] with min/max to handle negative days_since from future timestamps (clock skew/test data)
- Issue 4: Wrap func.sum(case(...)) results with int() in dashboard endpoint to handle Decimal returns from asyncpg
- Issue 5: Remove dead domain_flow_counts_result query (result fetched but never consumed) to eliminate unnecessary DB round-trip
- Issue 6: Replace select(Tree) with select(Tree.id, Tree.name, Tree.tree_type) in flow-quality endpoint to avoid loading large tree_structure JSONB column
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Log `note_posted` and `time_entry_posted` activities to `psa_activity_logs`
after each successful PSA push in `psa_documentation_service.py`; errors
are caught and logged without blocking the main push flow
- Add `PsaFunnel`, `PsaDailyTrend`, and `EnhancedPsaMetrics` Pydantic schemas
- Add `GET /analytics/flowpilot/psa-metrics?period=30d` endpoint (team_admin,
rate-limited 15/min) returning time entry totals, push funnel
(sessions → linked → doc pushed → time entry logged), and daily trend
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add branding_logo_url, branding_primary_color, branding_company_name columns to Account model
- Add Alembic migration (58e3f27f3e8f) for branding and SSO columns
- Add GET/PATCH /accounts/me/branding endpoints (owner-only for PATCH)
- Add BrandingSettingsPage with logo URL input, color picker, preview section
- Add /account/branding route (ProtectedRoute owner) in router.tsx
- Add Branding link card in AccountSettingsPage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add super-admin-only backend endpoints for toggling is_gallery_featured and
gallery_sort_order on flows and scripts, plus a frontend GalleryManagementPage
with toggle switches, editable sort order fields, and name/featured filters.
13 integration tests; all pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements a no-auth read-only API for the public templates gallery page:
- Schemas in schemas/public_templates.py (PublicFlowTemplate, PublicScriptTemplate, PublicGalleryResponse, PublicFlowDetail, PublicScriptDetail)
- Five endpoints under /api/v1/public/templates: listing, flow detail, script detail, categories with counts, full-text search
- Tree preview truncated to 3 levels max; script_body never exposed
- Rate limited at 30/minute; paginated with category/type/sort filters
- 25 passing integration tests covering feature flags, truncation, script body protection, search, categories, and 404 behavior
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>
Implements Phase 1 of the FlowPilot-First pivot — the core AI session
experience where engineers describe a problem and FlowPilot guides them
through structured diagnosis with selectable options, free-text escape
hatches, and auto-generated documentation on resolution.
Backend: AISession + AISessionStep models, FlowPilot Engine (LLM
orchestration with structured JSON output), Flow Matching Engine v1
(semantic + keyword + recency scoring), 8 API endpoints with auth,
rate limiting, and AI quota enforcement.
Frontend: Intake screen, conversational session view with sidebar,
step cards with options/actions/resolution suggestions, resolve/escalate
modals, documentation view with rating, session history integration,
and /pilot route with sidebar navigation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Query supporting data in the export endpoint and pass to markdown, text,
HTML, and PSA export generators. Each format renders text snippets and
screenshot placeholders in its native style.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add paletteIntent utility for command palette query classification
Detects query intent ('question' | 'keyword' | 'page' | 'empty') to drive
smart result ordering in the enhanced command palette.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add recentFlows localStorage utility for command palette empty state
Tracks recently visited flows (capped at 10) with deduplication by id,
surfaced in command palette when query is empty.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: rewrite CommandPalette with categorized results and smart ranking
- Adds FlowPilot AI result (always present when query is non-empty)
- Intent-aware ordering: question → FlowPilot prominent; page → pages first;
keyword → FlowPilot at top with flows/sessions/tags below
- Pages section with admin-gated items (uses useAuthStore)
- Tags extracted from flow search results with ?tag= navigation
- Quick Actions for create/import/scripts
- Empty state shows recent flows + quick actions
- Grouped rendering with section labels per design system
- Keyboard nav flattened across groups
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add FlowPilot prefill handoff from command palette to AssistantChatPage
When navigated to /assistant with location.state.prefill, automatically
creates a new chat and sends the prefill message without user interaction.
Clears location state after handling to prevent re-trigger on back navigation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: track recently visited flows for command palette empty state
Calls addRecentFlow after tree data loads in both TreeNavigationPage and
ProceduralNavigationPage so the command palette can surface recent flows
when the query is empty.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: use useMemo instead of useCallback for groups builder in CommandPalette
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add PSA ticket context Pydantic schemas (Task 6)
Add TicketDetails, CompanyInfo, ContactInfo, ConfigItem, TicketNote,
RelatedTicket, and TicketContext models in schemas/psa_context.py for
structured ticket context enrichment used by AI prompt injection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add ticket context prompt formatter (Task 7)
format_ticket_context_for_prompt() in services/psa/ticket_context.py
serializes TicketContext into structured text for AI system prompts,
with 10-note limit, 200-char text previews, and human-readable timestamps.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add get_ticket_context() to ConnectWise provider (Task 8)
Fetches ticket details, company, contact, configurations, notes, and
related open tickets in parallel via asyncio.gather with partial failure
tolerance. Results are cached with a 5-minute TTL per ticket/connection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add GET /integrations/psa/tickets/{id}/context endpoint (Task 9)
Returns rich TicketContext for a ticket ID. Handles PSA auth failures
(returns structured error), ticket-not-found (404), and general PSA
errors (502). Requires active PSA connection for the user's account.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: inject PSA ticket context into copilot system prompt (Task 10)
When a copilot conversation has an associated session with a linked PSA
ticket, fetch the ticket context and append it to the system prompt.
Failure is non-critical — errors are logged and the copilot proceeds
without context rather than failing the request.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add PSA context API client with TypeScript interfaces
Defines TicketDetails, CompanyInfo, ContactInfo, ConfigItemInfo,
TicketNote, RelatedTicket, and TicketContext interfaces matching backend
psa_context.py schemas. Exports psaContextApi with getTicketContext().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add useTicketContext hook for PSA ticket context fetching
Accepts psaTicketId and psaConnectionId, fetches context on mount
when both IDs are present, and exposes refresh() for manual re-fetch.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add TicketContextPanel component with accordion sections
Glass-card panel showing ticket summary, status/priority/SLA, and
accordion sections for Client, Contact, Devices, Notes, and Related
tickets. Matches design system with font-label labels and ice-cyan accents.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: mount TicketContextPanel in session runners when ticket is linked
ProceduralNavigationPage renders panel in left sidebar below step checklist.
TreeNavigationPage renders panel above breadcrumb trail. Both use
useTicketContext hook and show panel only when psa_ticket_id is set.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add fallback_steps to TypeScript types (Task 15)
Add optional fallback_steps field to ProceduralStep interface.
Add FallbackStepRecord interface and fallback_decisions field to Session.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add backend validation for fallback steps (Task 16)
Validate fallback_steps in procedural flow validation: required fields,
no nested fallback_steps, no duplicate IDs. Add FallbackStepRecord schema
and fallback_decisions field to SessionResponse.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: create FallbackSteps UI component (Task 17)
Collapsible component supporting edit and execute modes. Edit mode
provides title/description inputs with add/remove controls. Execute
mode shows "This worked" / "Didn't help" action buttons with emerald/
rose styling. Amber accent styling throughout.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: integrate FallbackSteps into editor and session runner (Task 18)
Wire FallbackSteps edit mode into StepEditor for procedure_step type
with add/remove/update handlers using crypto.randomUUID(). Add execute
mode rendering in ProceduralNavigationPage with fallbackDecisions state
tracking per parent step.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add session-to-flow request/response schemas (Task 19)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add session-to-flow AI generation service (Task 20)
Converts completed troubleshooting sessions into reusable procedural flows
with fallback branches. Includes PSA ticket context integration and
AI-generated step validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add POST /ai/session-to-flow endpoint (Task 21)
Converts a completed session into a reusable procedural flow using AI.
Includes quota checking, usage recording, and proper error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add Create Flow from Session button to session detail page (Task 22)
Adds sessionToFlow API client, exports from api/index.ts, and integrates
a prominent "Create Flow from Session" button on SessionDetailPage for
completed sessions. Generates a procedural flow via AI then navigates
to the procedural editor.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: cast tree_type to TreeType in session-to-flow creation
Fixes build error where string was not assignable to TreeType.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: update Playwright test selectors to match actual UI
- Use Control+k instead of Meta+k (Linux/CI compatibility)
- Use 'AI Assistant' group label instead of 'FlowPilot AI'
- Match actual FlowPilot chat page elements (Start a Conversation, New Chat, textarea)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: update Playwright test selectors to match actual UI
- Use specific command palette placeholder to avoid ambiguous matches
- Fix 'Quick Actions' scoping (two elements with same text)
- Fix 'Resolved' exact match on session detail page
- Fix tree editor to use getByText instead of getByDisplayValue
- Fix 'Add Step' strict mode by using .first()
- Fix fallback description placeholder text
- Update playwright.config.ts to use port 5433 and resolutionflow DB
- Update FlowPilot chat selectors to match actual page layout
11/17 new tests now passing. Remaining 6 need procedural session
navigation investigation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: resolve all Playwright test failures — 16/16 passing
- Fix procedural session tests: sessions auto-start, no Start button
- Fix strict mode violations: use getByRole('heading') for step titles
- Fix FlowPilot chat: use button role selector for New Chat
- Fix command palette page nav: scope Analytics click to palette modal
- Fix fallback runner: remove non-existent Start button click
- Update playwright.config to port 5433 for local Docker
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 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>
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>
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>
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>
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>
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>
- _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>
- 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>
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>