References implementation on feat/ai-chat-panel branch. Covers architecture, components used, enabling steps, and remaining TODO items.
5.2 KiB
Executable File
AI Chat Panel
status: disabled
branch: feat/ai-chat-panel
overview
a collapsible right-side chat panel that mirrors the left sidebar's behavior. uses prompt-kit components (shadcn-compatible AI primitives) for the chat UI. styled to match the sidebar's color scheme (bg-sidebar, text-sidebar-foreground). currently uses mock responses - structured for a real AI backend later.
enabling the feature
to re-enable, update src/app/dashboard/layout.tsx:
import { cookies } from "next/headers"
import { ChatPanel } from "@/components/chat-panel"
import { ChatPanelTrigger } from "@/components/chat-panel-trigger"
import { ChatPanelProvider } from "@/hooks/use-chat-panel"
// inside the component:
const cookieStore = await cookies()
const chatPanelOpen = cookieStore.get("chat_panel_state")?.value === "true"
// wrap SidebarProvider contents with:
<ChatPanelProvider defaultOpen={chatPanelOpen}>
{/* existing sidebar + content */}
<ChatPanel />
<ChatPanelTrigger />
</ChatPanelProvider>
file structure
src/
├── components/
│ ├── ui/
│ │ ├── chat-container.tsx (prompt-kit: auto-scrolling message area)
│ │ ├── message.tsx (prompt-kit: message with avatar + content)
│ │ ├── prompt-input.tsx (prompt-kit: auto-resize textarea + actions)
│ │ ├── prompt-suggestion.tsx (prompt-kit: button-style suggestion pills)
│ │ ├── markdown.tsx (prompt-kit dep: markdown rendering)
│ │ └── code-block.tsx (prompt-kit dep: syntax highlighted code)
│ ├── chat-panel.tsx (panel shell - gap div + fixed container)
│ ├── chat-panel-trigger.tsx (floating FAB button, bottom-right)
│ └── chat-panel-content.tsx (messages + input + suggestions inner UI)
├── hooks/
│ └── use-chat-panel.tsx (context provider, cookie persistence, Ctrl+I)
└── lib/
└── chat-suggestions.ts (route-based suggestion configs)
components used
prompt-kit (installed via shadcn registry: https://prompt-kit.com/c/[name].json)
ChatContainerRoot/ChatContainerContent/ChatContainerScrollAnchor- wrapsuse-stick-to-bottomfor auto-scroll behaviorMessage/MessageAvatar/MessageContent- composable message layout with avatar supportPromptInput/PromptInputTextarea/PromptInputActions/PromptInputAction- compound input component with auto-resize, enter-to-submit, tooltip actionsPromptSuggestion- button-based suggestions with highlight support
dependencies added:
use-stick-to-bottom- handles the auto-scroll-to-bottom behavior in the chat container
how it works
panel architecture:
mirrors the left sidebar's pattern exactly:
- a "gap" div in the flex flow that transitions width (0 <-> 24rem) to push content
- a fixed container that transitions its
rightposition to slide in/out - inner div uses
bg-sidebarto match the sidebar's color
state management:
ChatPanelProviderwraps everything, provides open/close state- cookie persistence via
chat_panel_statecookie (7-day max-age) - keyboard shortcut:
Cmd/Ctrl+I(doesn't conflict with sidebar'sCmd+B) - mobile: renders as a Sheet from the right side
styling approach:
uses sidebar CSS variables throughout to maintain visual consistency:
bg-sidebar/text-sidebar-foregroundfor panel backgroundbg-sidebar-accent/text-sidebar-accent-foregroundfor user messagesbg-sidebar-foreground/10for assistant messagesborder-sidebar-foreground/20for borders/inputbg-sidebar-primaryfor the send button
mock responses:
currently uses a random canned response with a simulated delay (800-1500ms). the message handling is structured to be easily swapped for a real streaming backend.
what's left to do
-
real AI backend - replace the mock
setTimeoutinchat-panel-content.tsxwith actual API calls (vercel AI SDKuseChatwould slot in nicely here) -
streaming responses - the
MessageContentcomponent supports markdown rendering (markdownprop). when streaming is added, use it for formatted AI responses -
token usage - the prompt-kit components support more features than currently used:
MessageActions/MessageActionfor copy/thumbs-up/thumbs-down on messagesPromptSuggestionhighlight mode for autocomplete-style suggestions- multiple file attachment via the prompt input actions area
-
context awareness - the suggestion system (
chat-suggestions.ts) currently just matches pathname prefix. could be enhanced to include:- current project data in the prompt
- file contents when on the files route
- schedule data when on the schedule route
-
message persistence - messages are currently in React state (lost on navigation). could persist to localStorage or a server-side store
-
panel width - currently hardcoded to 24rem. could be made resizable with
react-resizable-panels(already in deps) -
animation polish - the panel slide animation works but could benefit from the same
data-stateattribute pattern the sidebar uses for more granular CSS control