mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-01-31 14:43:35 +00:00
feat: Add conversational AI assistant panel for project codebase Q&A
Implement a slide-in chat panel that allows users to ask questions about their codebase using Claude Opus 4.5 with read-only access to project files. Backend changes: - Add SQLAlchemy models for conversation persistence (assistant_database.py) - Create AssistantChatSession with read-only Claude SDK client - Add WebSocket endpoint for real-time chat streaming - Include read-only MCP tools: feature_get_stats, feature_get_next, etc. Frontend changes: - Add floating action button (bottom-right) to toggle panel - Create slide-in panel component (400px width) - Implement WebSocket hook with reconnection logic - Add keyboard shortcut 'A' to toggle assistant Key features: - Read-only access: Only Read, Glob, Grep, WebFetch, WebSearch tools - Persistent history: Conversations saved to SQLite per project - Real-time streaming: Text chunks streamed as Claude generates response - Tool visibility: Shows when assistant is using tools to explore code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,8 @@ import { AddFeatureForm } from './components/AddFeatureForm'
|
||||
import { FeatureModal } from './components/FeatureModal'
|
||||
import { DebugLogViewer } from './components/DebugLogViewer'
|
||||
import { AgentThought } from './components/AgentThought'
|
||||
import { AssistantFAB } from './components/AssistantFAB'
|
||||
import { AssistantPanel } from './components/AssistantPanel'
|
||||
import { Plus, Loader2 } from 'lucide-react'
|
||||
import type { Feature } from './lib/types'
|
||||
|
||||
@@ -31,6 +33,7 @@ function App() {
|
||||
const [setupComplete, setSetupComplete] = useState(true) // Start optimistic
|
||||
const [debugOpen, setDebugOpen] = useState(false)
|
||||
const [debugPanelHeight, setDebugPanelHeight] = useState(288) // Default height
|
||||
const [assistantOpen, setAssistantOpen] = useState(false)
|
||||
|
||||
const { data: projects, isLoading: projectsLoading } = useProjects()
|
||||
const { data: features } = useFeatures(selectedProject)
|
||||
@@ -84,9 +87,17 @@ function App() {
|
||||
setShowAddFeature(true)
|
||||
}
|
||||
|
||||
// A : Toggle assistant panel (when project selected)
|
||||
if ((e.key === 'a' || e.key === 'A') && selectedProject) {
|
||||
e.preventDefault()
|
||||
setAssistantOpen(prev => !prev)
|
||||
}
|
||||
|
||||
// Escape : Close modals
|
||||
if (e.key === 'Escape') {
|
||||
if (showAddFeature) {
|
||||
if (assistantOpen) {
|
||||
setAssistantOpen(false)
|
||||
} else if (showAddFeature) {
|
||||
setShowAddFeature(false)
|
||||
} else if (selectedFeature) {
|
||||
setSelectedFeature(null)
|
||||
@@ -98,7 +109,7 @@ function App() {
|
||||
|
||||
window.addEventListener('keydown', handleKeyDown)
|
||||
return () => window.removeEventListener('keydown', handleKeyDown)
|
||||
}, [selectedProject, showAddFeature, selectedFeature, debugOpen])
|
||||
}, [selectedProject, showAddFeature, selectedFeature, debugOpen, assistantOpen])
|
||||
|
||||
// Combine WebSocket progress with feature data
|
||||
const progress = wsState.progress.total > 0 ? wsState.progress : {
|
||||
@@ -244,6 +255,21 @@ function App() {
|
||||
onHeightChange={setDebugPanelHeight}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Assistant FAB and Panel */}
|
||||
{selectedProject && (
|
||||
<>
|
||||
<AssistantFAB
|
||||
onClick={() => setAssistantOpen(!assistantOpen)}
|
||||
isOpen={assistantOpen}
|
||||
/>
|
||||
<AssistantPanel
|
||||
projectName={selectedProject}
|
||||
isOpen={assistantOpen}
|
||||
onClose={() => setAssistantOpen(false)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user