diff --git a/frontend/src/pages/FlowPilotPage.tsx b/frontend/src/pages/FlowPilotPage.tsx
new file mode 100644
index 00000000..6ff76b53
--- /dev/null
+++ b/frontend/src/pages/FlowPilotPage.tsx
@@ -0,0 +1,368 @@
+import { useEffect } from 'react'
+import { Sparkles, Send, Loader2, Flag, MessageSquare, Paperclip, Terminal, X, RotateCcw, ImagePlus, ListChecks, FileText } from 'lucide-react'
+import { cn } from '@/lib/utils'
+import { PageMeta } from '@/components/common/PageMeta'
+import { aiSessionsApi } from '@/api/aiSessions'
+import { ChatSidebar, ChatSidebarCollapsedBar } from '@/components/assistant/ChatSidebar'
+import { ChatMessage } from '@/components/assistant/ChatMessage'
+import { TaskLane } from '@/components/assistant/TaskLane'
+import { ConcludeSessionModal } from '@/components/assistant/ConcludeSessionModal'
+import { StatusUpdateModal } from '@/components/flowpilot/StatusUpdateModal'
+// TODO: uncomment after Task 4
+// import { ViewToggle } from '@/components/assistant/ViewToggle'
+import { useAssistantSession } from '@/hooks/useAssistantSession'
+
+export default function FlowPilotPage() {
+ const session = useAssistantSession()
+
+ // Handle prefill from dashboard / command palette
+ useEffect(() => {
+ session.handlePrefill('/assistant')
+ }, []) // eslint-disable-line react-hooks/exhaustive-deps
+
+ const handleTaskSubmit = async (responses: Array<{ type: string; state: string; value: string; text?: string; label?: string }>) => {
+ if (!session.activeChatId || session.loading) return
+
+ const parts: string[] = []
+ for (const r of responses) {
+ const name = r.type === 'question' ? `Q: ${r.text}` : r.label || 'Check'
+ if (r.state === 'done' && r.value.trim()) {
+ parts.push(`**${name}:**\n\`\`\`\n${r.value.trim()}\n\`\`\``)
+ } else if (r.state === 'skipped') {
+ parts.push(`**${name}:** _(skipped)_`)
+ }
+ }
+ const userMessage = parts.join('\n\n')
+ const sendChatId = session.activeChatId
+
+ session.setInput('')
+ session.setShowTaskLane(false)
+ session.setActiveQuestions([])
+ session.setActiveActions([])
+
+ try {
+ const response = await aiSessionsApi.sendChatMessage(sendChatId, { message: userMessage })
+ if (session.currentChatRef.current !== sendChatId) return
+ session.processResponse(response, sendChatId)
+
+ const hasQuestions = response.questions && response.questions.length > 0
+ const hasActions = response.actions && response.actions.length > 0
+ if (!hasQuestions && !hasActions) {
+ session.setShowTaskLane(false)
+ session.setActiveQuestions([])
+ session.setActiveActions([])
+ }
+ } catch {
+ // Error handled by processResponse guard
+ }
+ }
+
+ return (
+ <>
+
+ Ask me anything about IT infrastructure, networking, Active Directory, + cloud platforms, or troubleshooting. I'll also suggest relevant flows from your team's library. +
++ Your Senior Systems & Network Engineer. Ask anything about IT infrastructure, + or start a new chat to get personalized help with your team's flows. +
+ +