This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
SpecDrafter is an AI collaboration tool that facilitates real-time specification drafting through dual-Claude architecture. It provides a browser-based interface where two Claude instances work together - one focused on requirements discovery and one on technical review - to create comprehensive technical specifications.
Note on Paths: All file paths in this documentation use placeholders like [project-root] which are dynamically resolved based on where the project is cloned. The system automatically handles path resolution for different installations.
# Install dependencies
npm install
# Start development servers (both frontend and backend)
npm start
# OR
npm run dev
# Run individual services
npm run server # Backend only (port 3002)
npm run frontend # Frontend only (port 3001)
# Build for production
npm run build
# Preview production build
npm run previewCurrently, no test framework or linting is configured. When implementing tests or linting:
- Consider adding ESLint for JavaScript/React linting
- Consider Jest or Vitest for testing React components
- Add appropriate scripts to package.json
Dual-Claude SDK Integration → Socket.IO Real-time Communication → React Frontend → Specification Generation
- Frontend: React 18 + Vite + Tailwind CSS + Socket.IO Client
- Backend: Node.js (ES Modules) + Express + Socket.IO
- AI Integration: Dual Claude instances via @anthropic-ai/claude-code SDK
- Real-time: WebSocket communication for chat and collaboration
- ClaudeSDKManager (
backend/lib/claude-sdk-manager.js): Manages individual Claude instances using the SDK - DualProcessOrchestrator (
backend/lib/dual-process-orchestrator.js): Coordinates between two Claude processes - MessageSplitter (
backend/lib/message-splitter.js): Context-aware splitter with sentence boundary detection for@review:markers - Workspace-based Architecture: Each Claude instance has mode-specific workspaces with custom CLAUDE.md instructions
-
Discovery AI (dynamic workspace based on project mode)
- New Projects:
backend/workspaces/new-project/discovery/ - Existing Projects:
backend/workspaces/existing-project/discovery/ - Uses Discovery AI instructions (via CLAUDE.md in its workspace)
- Focuses on user interaction and requirements gathering
- Identifies when specifications are ready for review
- Initiates AI-to-AI communication using
@review:markers
- New Projects:
-
Review AI (dynamic workspace based on project mode)
- New Projects:
backend/workspaces/new-project/review/ - Existing Projects:
backend/workspaces/existing-project/review/ - Backend service that only communicates with Discovery AI
- Lazy initialization - starts on-demand when Discovery AI needs review
- Provides technical analysis and feasibility review
- NEVER writes specifications - only provides feedback for Discovery AI to incorporate
- All output automatically routed to Discovery AI (no user interaction)
- New Projects:
-
Client → Server:
user_message: User chat messagesstart_processes: Initialize Discovery AI with optionalinitialMessageparameter (sent when user submits welcome form)list_specs: Request list of existing specificationsstart_with_existing_spec: Start session with existing spec (includes projectName, modelId, skillLevel)switch_process: Switch active AI (Discovery only - cannot switch to Review)trigger_review: Initiate specification reviewreset_session: Clear and restartchange_model: Switch between Claude 4 models (Opus/Sonnet)get_available_models: Request list of available modelsstop_ai_response: Immediately stop both AI processes
-
Server → Client:
discovery_message: Messages from Discovery AIai_collaboration_message: AI-to-AI communication eventstyping_indicator: Show which AI is typing in chat panelai_collaboration_typing: Show which AI is typing in collaboration panelcollaboration_detected: AI-to-AI interaction eventsspec_file_generated: New specification createdspec_file_updated: Existing specification modifiedspecs_list: List of available specificationsorchestrator_status: Current system stateprocesses_ready: Claude instances initializedavailable_models: List of available Claude modelsmodel_changed: Confirmation of model changeai_stopped: Confirmation that AI processes were stoppedprocesses_stopped: Event fired when all processes have been terminated
Initialization Flow:
- User chooses between "Start New Project" or "Continue Existing Project"
- For new projects:
- User fills welcome form with project details and technical background
- On submit, frontend emits
start_processeswith user's project info asinitialMessage - Server starts Discovery AI using project details as first prompt
- For existing projects:
- User selects technical background and chooses from available specifications
- Frontend emits
start_with_existing_specwith projectName, modelId, and skillLevel - Discovery AI receives spec file path and user's technical background
- Discovery AI adapts communication style based on technical background (Non-Tech, Tech-Savvy, or Software Professional)
- Session continues with contextual understanding
User-to-AI Communication:
- User sends message via ChatPanel
- Server always routes to Discovery AI (users cannot talk to Review AI)
- ClaudeSDKManager processes with Claude SDK
- Response emitted as
discovery_message - Frontend displays in chat panel
AI-to-AI Communication:
- Discovery AI includes
@review:marker at a valid sentence boundary - Orchestrator validates and splits: content before
@review:goes to user, content from@review:onward goes to Review AI - Message routed to Review AI via ClaudeSDKManager
ai_collaboration_messageevent emitted to frontend- CollaborationView displays real-time AI conversation
The system implements autonomous AI-to-AI communication:
Communication Flow:
@review:- Discovery AI sends messages to Review AI (must appear at sentence boundaries)- Review AI responses are automatically routed back to Discovery AI (no markers needed)
Message Routing:
- Discovery AI includes
@review:marker at a valid position to route to Review AI - Thinking tags are filtered out BEFORE routing check (prevents
@review:inside thinking from triggering) - MessageSplitter validates marker position - only triggers at:
- Start of message
- After newline (start of new line)
- After double newline (new paragraph)
- After sentence punctuation (. ! ?) followed by space
- Markers inside code blocks or mid-sentence are ignored
- First valid
@review:occurrence is used, invalid ones are skipped - Content before marker goes to user, content from marker onward goes to Review AI
- ALL Review AI output is automatically routed to Discovery AI via
ai_collaboration_message - Review AI operates as a backend service with no direct user interaction
- Real-time collaboration appears in CollaborationView.jsx panel
Implementation Details:
- Review AI uses lazy initialization - starts only when first needed
MessageSplitter.split()performs context-aware splitting with validation:- Detects code blocks (
code) and inline code (code) - Validates marker appears at sentence boundaries
- Returns first valid occurrence, tracks invalid occurrences skipped
- Detects code blocks (
handleDiscoveryOutput()filters thinking tags, uses splitter, then routes messageshandleAIToAICommunication()processes the Review AI portion of split messageshandleReviewOutput()filters thinking tags then automatically routes all Review output to Discovery- All AI-to-AI communication is logged and displayed in collaboration tab
- Thinking Tag Filtering: Backend
ClaudeMessageParser.filterThinkingTags()removes all<thinking>variations before routing (single source of truth) - Split Decision Logging: Every routing decision logged with
📊 Message split decisionincluding invalid occurrences count - Typing Indicators:
- Main chat uses
typing_indicatorevents, collaboration usesai_collaboration_typing - 100ms delays prevent race conditions when switching between AI speakers
- Discovery exit events don't clear collaboration typing during active AI-to-AI communication
- Discovery AI typing stops explicitly after processing Review feedback
hasReviewBeenTriggeredflag resets when Review AI exits to ensure proper state- Multi-chunk Messages: Typing indicators persist between message chunks (200ms re-show delay)
- Indicators only clear on
resultevent when Claude SDK signals query completion
- Main chat uses
The system automatically triggers Claude's thinking/reasoning mode for deeper analysis:
Automatic Triggers:
- User → Discovery AI: All user messages have "think hard" appended (invisible to users)
- AI
↔️ AI: All AI-to-AI messages have "think harder" appended (invisible in UI) - Generate & Review Button: Includes "ultrathink" keyword for maximum depth analysis
Implementation in Orchestrator:
- Located in
backend/lib/dual-process-orchestrator.js routeUserMessage(): Appends "think hard" to user messageshandleAIToAICommunication(): Appends "think harder" when routing to Review AIhandleReviewOutput(): Appends "think harder" when forwarding Review responses
Key Features:
- Completely invisible to users - original messages displayed in UI
- Triggers stored only in backend routing, not in conversation history
- Enables deeper reasoning for all interactions automatically
- "ultrathink" reserved for critical specification generation tasks
Logging:
- All thinking triggers logged with
hasThinkingTrigger: truefor debugging - Original message lengths preserved in logs for monitoring
- User Initiation: User clicks "Generate & Review Spec" button in chat panel
- Prompt Injection: System sends predefined technical-focused prompt to Discovery AI
- Specification Writing: Discovery AI creates technical spec at
[project-root]/specs/[ProjectName]/spec.md - Automatic Review: Discovery AI immediately sends
@review:message to Review AI - Technical Analysis: Review AI reads spec file and provides implementation feedback
- Iterative Refinement: Discovery uses
@review:, Review responses auto-route back - Real-time Display: File watcher detects changes and updates SpecView automatically
- Discovery Phase: Discovery AI gathers project details from user
- Draft Detection: When draft specification is detected, orchestrator notifies frontend
- AI-to-AI Review: Discovery AI sends
@review:message with specification - Technical Feedback: Review AI analyzes and responds (automatically routed to Discovery)
- Autonomous Iteration: AIs continue collaborating until consensus
- File Generation: Specifications saved to
specs/[ProjectName]/spec.md - UI Display: File watcher detects and displays final specs in UI
The system generates technical-focused specifications emphasizing:
- Implementation architecture and patterns
- Data models and schemas
- API endpoints and contracts
- Component structure and hierarchy
- Integration points and dependencies
- Security considerations
- Performance requirements
Explicitly avoids:
- Project timelines
- Budget information
- Non-technical content
The file watcher monitors the specs/ directory for markdown files:
Configuration (backend/lib/file-watcher.js):
- Watches pattern:
specs/**/*.mdfrom project root - Uses Chokidar library with
ignoreInitial: false - Detects both new files and modifications
- Converts markdown to HTML before emitting events
Events:
spec_file_generated: Emitted when new.mdfiles are created- Frontend auto-switches to spec view
- Shows latest created specification
spec_file_updated: Emitted when existing files are modified- Frontend updates content without view switching
- Preserves user's current view (chat/collaboration)
Important Behavior:
- Single Spec Display: System shows only ONE specification at a time
- Last Updated Wins: Most recently created/modified spec is displayed
- Continue Existing Projects: Users can now select and continue working on existing specifications
- Technical Background Adaptation: Discovery AI adapts communication style based on user's technical level
- Automatic Detection: All changes detected in real-time via WebSocket
The system includes a non-intrusive promotional modal for FreigeistAI (https://www.freigeist.dev):
Implementation (frontend/src/components/PromoModal.jsx):
- Displays 30 seconds after spec generation or update
- Shows creator's photo for personal touch
- Glassmorphism styling matching app aesthetic
- Three action buttons:
- "Check out FreigeistAI" - Opens website in new tab
- "Maybe later" - Closes modal for current session
- "Don't show again" - Permanently dismisses via localStorage
Trigger Logic (frontend/src/App.jsx):
triggerPromoModalTimer()function handles timing- Triggers on both events:
spec_file_generated- New specification filesspec_file_updated- Existing files being overwritten
- Only shows once per session
- Respects localStorage preference for permanent dismissal
- Timer resets if multiple specs are generated
Key Features:
- 30-Second Delay: Allows users to review spec before showing
- Session Control:
hasShownPromoThisSessionstate prevents spam - Persistent Preference:
specdrafter-promo-dismissedlocalStorage key - Human Touch: Includes creator photo at
frontend/src/assets/creator-photo.jpeg
- Node.js 18+ (for ES modules and Claude SDK support)
- Claude Code must be installed:
npm install -g @anthropic-ai/claude-code - Valid Claude API credentials in ~/.claude/.credentials.json
- Frontend development server: http://localhost:3001
- Backend Socket.IO server: http://localhost:3002
- Frontend proxies Socket.IO requests to backend
SpecDrafter/
├── backend/ # Server-side code
│ ├── server.js # Express/Socket.IO server
│ ├── lib/ # Backend libraries
│ │ ├── claude-sdk-manager.js # Claude SDK integration
│ │ ├── dual-process-orchestrator.js # AI process coordination
│ │ ├── message-splitter.js # Message splitting at @review: markers
│ │ ├── file-watcher.js # File system monitoring
│ │ ├── logger.js # Logging utilities
│ │ ├── claude-message-parser.js # Message parsing utilities
│ │ └── models.js # Claude model configuration
│ └── workspaces/ # Claude AI workspaces
│ ├── new-project/ # Workspaces for new project mode
│ │ ├── discovery/ # Discovery AI for new projects
│ │ │ ├── .claude/
│ │ │ │ └── settings.json
│ │ │ └── CLAUDE.md
│ │ └── review/ # Review AI for new projects
│ │ ├── .claude/
│ │ │ └── settings.json
│ │ └── CLAUDE.md
│ ├── existing-project/ # Workspaces for existing project mode
│ │ ├── discovery/ # Discovery AI for existing projects
│ │ │ ├── .claude/
│ │ │ │ └── settings.json
│ │ │ └── CLAUDE.md
│ │ └── review/ # Review AI for existing projects
│ │ ├── .claude/
│ │ │ └── settings.json
│ │ └── CLAUDE.md
├── frontend/ # Client-side code
│ ├── index.html # Main HTML entry point
│ ├── src/ # React source code
│ │ ├── App.jsx # Main React component
│ │ ├── main.jsx # React entry point
│ │ ├── components/ # React components
│ │ │ ├── ChatPanel.jsx # User chat interface
│ │ │ ├── CollaborationPanel.jsx # AI collaboration container
│ │ │ ├── CollaborationView.jsx # AI-to-AI conversation display
│ │ │ ├── Message.jsx # Individual message component
│ │ │ ├── SpecSelector.jsx # Existing spec selection
│ │ │ ├── SpecView.jsx # Generated spec display
│ │ │ ├── TypingIndicator.jsx # AI typing indicator
│ │ │ ├── WelcomeScreen.jsx # Initial project setup
│ │ │ └── PromoModal.jsx # Promotional modal for FreigeistAI
│ │ ├── config/ # Configuration files
│ │ │ └── models.js # Frontend model configuration
│ │ ├── assets/ # Static assets
│ │ │ └── creator-photo.jpeg # Creator photo for promo modal
│ │ ├── hooks/ # React hooks
│ │ │ └── useSocket.js # Socket.IO connection hook
│ │ └── styles/ # CSS styles
│ │ └── globals.css # Global CSS with Tailwind
│ ├── vite.config.js # Vite build configuration
│ ├── tailwind.config.js # Tailwind CSS configuration
│ └── postcss.config.js # PostCSS configuration
├── specs/ # Generated specifications (user deliverables)
├── dist/ # Production build output
├── .env.local # Environment variables
├── package.json # Project dependencies and scripts
├── package-lock.json # Locked dependency versions
├── README.md # Project documentation
├── LICENSE.md # Project license
└── CLAUDE.md # This file
- Each workspace has its own CLAUDE.md for custom behavior
- The
specs/directory at project root is auto-created if missing - Generated specifications follow pattern:
specs/[ProjectName]/spec.md - Backend and frontend code are cleanly separated into their respective directories
- Both Discovery and Review AIs have explicit knowledge of spec file locations
- Review AI can directly access spec files for iterative improvements
- Workspace configuration stored in
.claude/subdirectories
Critical for File Operations:
- Server runs from: Project root (where the project is cloned)
- Discovery AI workspace:
- New projects:
backend/workspaces/new-project/discovery/ - Existing projects:
backend/workspaces/existing-project/discovery/
- New projects:
- Review AI workspace:
- New projects:
backend/workspaces/new-project/review/ - Existing projects:
backend/workspaces/existing-project/review/
- New projects:
- File watcher monitors:
specs/**/*.mdrelative to project root - Discovery AI receives full paths: The system provides complete paths in messages
Why Absolute Paths Matter:
- Discovery AI's working directory is deep in the workspace hierarchy (now 4 levels deep)
- Relative paths from AI workspace would create files in wrong location
- File watcher only monitors the project root
specs/directory - Mismatched paths = files created but never detected
The system dynamically selects workspaces based on how the user starts their session:
New Project Mode (User clicks "Start New Project"):
- Orchestrator created with
projectMode: 'new' - Discovery AI uses:
backend/workspaces/new-project/discovery/ - Review AI uses:
backend/workspaces/new-project/review/ - Follows full 6-phase discovery workflow in CLAUDE.md
Existing Project Mode (User clicks "Continue Existing Project"):
- Orchestrator created with
projectMode: 'existing' - Discovery AI uses:
backend/workspaces/existing-project/discovery/ - Review AI uses:
backend/workspaces/existing-project/review/ - Starts with existing specification context
Implementation Details:
DualProcessOrchestratorconstructor acceptsprojectModeparameter- Workspace paths selected dynamically based on mode
- Each mode can have completely different CLAUDE.md instructions
- Currently both modes use identical instructions (can be customized later)
- Socket.IO handles all real-time messaging
- Auto-reconnection built-in for resilience
- Each Claude process maintains stateful conversations
- Session IDs preserved for conversation continuity
- Stop Button: Currently disabled via feature flag (
ENABLE_STOP_BUTTON = falsein ChatPanel.jsx)- When enabled: Terminates both AI processes mid-response
- Uses AbortController to cancel Claude SDK queries
- Disabled due to Claude SDK session preservation limitations (see STOP_BUTTON_IMPLEMENTATION.md)
- To re-enable: Set
ENABLE_STOP_BUTTON = truewhen session preservation is fixed
- Tailwind CSS with FreigeistAI-inspired design
- Custom animations defined in
tailwind.config.js - Glassmorphism effects using backdrop-blur
- Speaker identification (blue for Discovery AI, orange/red for Review AI)
- Real-time collaboration display with chat-like interface
- Uses
@anthropic-ai/claude-codepackage - Permission mode:
default- uses workspace settings for permissions - Models:
- Claude 4 Opus (
claude-opus-4-20250514): Best for complex reasoning and detailed analysis - Claude 4 Sonnet (
claude-sonnet-4-20250514): Balanced performance and speed (default)
- Claude 4 Opus (
- Model selection: Dynamic switching between models via UI
- Max turns: 10 per conversation segment
Fresh Session Behavior:
- New Projects: Both Discovery and Review AI start with completely empty context windows
- Existing Projects: Discovery AI starts fresh - only receives spec file path in initial message
- Review AI Initialization: Always starts fresh when first spawned in a project
- Key Mechanism:
usesContinue=falsein spawn() preventsresumeoption, ensuring clean slate
Session Continuity:
- Sessions persist using
resumeoption with session IDs whenusesContinue=true - Each Claude instance maintains independent session state
- Within a project session, follow-up messages maintain context via resume
- Session Isolation: Each project session is completely isolated - no cross-contamination
Technical Implementation:
ClaudeSDKManager.spawn()controls session behavior viausesContinueparameter- When
false: Noresumeoption added to query options → fresh session - When
true: Addsresume: this.sessionIdto maintain conversation context - AbortController Integration: Proper cancellation support for Claude SDK queries
- Each query gets its own AbortController instance
- Clean termination without leaving hanging processes
- Handles AbortError gracefully in catch blocks
Each AI workspace has its own permission configuration via .claude/settings.json. Permissions are identical for new and existing project modes, but the workspace paths differ:
Discovery AI Permissions (both new-project/discovery and existing-project/discovery):
- Directory Access: Limited to
specs/directory only (viaadditionalDirectories: ["../../../../specs"]) - Allowed Tools: Read, Write, LS, Glob, Grep, WebFetch, WebSearch, MCP tools (context7, deepwiki)
- Denied Tools: Bash, Task (no system commands or sub-agents)
- Purpose: Can read and write specifications, research technologies
Review AI Permissions (both new-project/review and existing-project/review):
- Directory Access: Limited to
specs/directory only (read-only, viaadditionalDirectories: ["../../../../specs"]) - Allowed Tools: Read, LS, Glob, Grep, WebFetch, WebSearch, Task, MCP tools
- Denied Tools: Write, Edit, MultiEdit, Bash (no modifications allowed)
- Purpose: Can ONLY read specifications for review, provide feedback to Discovery AI
- CRITICAL: Review AI cannot write specs - it only provides technical feedback that Discovery AI incorporates
Note: The additionalDirectories path is now ../../../../specs (4 levels up) instead of ../../../specs due to the deeper workspace structure
Security Benefits:
- Both AIs are sandboxed to the
specs/directory - No access to system commands or sensitive files
- Review AI cannot modify files (read-only)
- Discovery AI cannot spawn sub-agents
- Permissions tracked in version control for consistency
Local Overrides:
Developers can create .claude/settings.local.json in workspaces for personal overrides (gitignored)
- SDK errors propagated through EventEmitter pattern
- Process exit handling with automatic status updates
- Comprehensive logging at all stages
- Consider which Claude instance should handle the feature (Discovery vs Review AI)
- Update appropriate Socket.IO event handlers
- Maintain clear separation between discovery and review roles
- Consider impact on AI-to-AI communication protocol
- Test with both Claude instances active and autonomous collaboration
- Ensure CollaborationView properly displays new AI interactions
- For user-facing features, consider adding UI controls in ChatPanel
- Update both AI CLAUDE.md files if the feature affects their behavior
- Check browser console for frontend logs
- Server logs show Claude process initialization and messages
- Each Claude instance logs with role prefix (CLAUDE-DISCOVERY, CLAUDE-REVIEW)
- Orchestrator logs show routing decisions and AI-to-AI communication
- Message splitting: Look for
📊 Message split decisionlogs showing routing details - CollaborationView shows real-time AI conversation flow
- If messages don't appear: Check event name matching (discovery_message/ai_collaboration_message)
- If Claude doesn't respond: Verify SDK installation and credentials
- If sessions don't persist: Check session ID handling in ClaudeSDKManager
- If AI-to-AI communication fails:
- Check @review: marker is present at a valid position (sentence boundary)
- Verify marker is not inside code blocks or mid-sentence
- Check split decision logs for
invalidOccurrencescount - Verify MessageSplitter.split() validation is working correctly
- Ensure marker appears after punctuation, newline, or at message start
- If typing indicators don't show in AI collaboration:
- Check for
🔴 Review AI typing indicatorlogs to verify emission - Ensure Discovery process exit doesn't occur during active collaboration (check
collaborationState) - Verify 100ms delays are working to prevent race conditions
- Check
hasReviewBeenTriggeredflag is properly reset on Review AI exit
- Check for
- If spec files don't appear:
- Check file watcher is monitoring correct path (should be
specs/**/*.mdfrom project root) - Verify Discovery AI uses the full paths provided in messages
- Check server logs for file watcher events
- Check file watcher is monitoring correct path (should be
- If spec updates don't show: Ensure both
spec_file_generatedandspec_file_updatedhandlers exist in frontend
When working on this project, Claude Code should be aware of the dual-AI architecture and help maintain the separation of concerns between requirements discovery and technical review. The project demonstrates advanced AI-to-AI collaboration patterns using modern SDK integration instead of terminal-based approaches.