Files
Atomizer/docs/07_DEVELOPMENT/DASHBOARD_IMPROVEMENT_PLAN.md
Antoine 9eed4d81eb feat: Add Claude Code terminal integration to dashboard
- Add embedded Claude Code terminal with xterm.js for full CLI experience
- Create WebSocket PTY backend for real-time terminal communication
- Add terminal status endpoint to check CLI availability
- Update dashboard to use Claude Code terminal instead of API chat
- Add optimization control panel with start/stop/validate actions
- Add study context provider for global state management
- Update frontend with new dependencies (xterm.js addons)
- Comprehensive README documentation for all new features

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 15:02:13 -05:00

21 KiB

Atomizer Dashboard Improvement Plan

Executive Summary

This document outlines a comprehensive plan to enhance the Atomizer dashboard into a self-contained, professional optimization platform with integrated AI assistance through Claude Code.


Current State

Existing Pages

  • Home (/): Study selection with README preview
  • Dashboard (/dashboard): Real-time monitoring, charts, control panel
  • Results (/results): AI-generated report viewer

Existing Features

  • Study selection with persistence
  • README display on study hover
  • Convergence plot (Plotly)
  • Pareto plot for multi-objective
  • Parallel coordinates
  • Parameter importance chart
  • Console output viewer
  • Control panel (start/stop/validate)
  • Optuna dashboard launch
  • AI report generation

Proposed Improvements

Phase 1: Core UX Enhancements

1.1 Unified Navigation & Branding

  • Logo & Brand Identity: Professional Atomizer logo in sidebar
  • Breadcrumb Navigation: Show current path (e.g., Atomizer > m1_mirror > Dashboard)
  • Quick Study Switcher: Dropdown in header to switch studies without returning to Home
  • Keyboard Shortcuts: Ctrl+K for command palette, Ctrl+1/2/3 for page navigation

1.2 Study Overview Card (Home Page Enhancement)

When a study is selected, show a summary card with:

  • Trial progress ring/chart
  • Best objective value with trend indicator
  • Last activity timestamp
  • Quick action buttons (Start, Validate, Open)
  • Thumbnail preview of convergence

1.3 Real-Time Status Indicators

  • Global Status Bar: Shows running processes, current trial, ETA
  • Live Toast Notifications: Trial completed, error occurred, validation done
  • Sound Notifications (optional): Audio cue on trial completion

1.4 Dark/Light Theme Toggle

  • Persist theme preference in localStorage
  • System theme detection

Phase 2: Advanced Visualization

2.1 Interactive Trial Table

  • Sortable/filterable data grid with all trial data
  • Column visibility toggles
  • Export to CSV/Excel
  • Click row to highlight in plots
  • Filter by FEA vs Neural trials

2.2 Enhanced Charts

  • Zoomable Convergence: Brushing to select time ranges
  • 3D Parameter Space: Three.js visualization of design space
  • Heatmap: Parameter correlation matrix
  • Animation: Play through optimization history

2.3 Comparison Mode

  • Side-by-side comparison of 2-3 trials
  • Diff view for parameter values
  • Overlay plots

2.4 Design Space Explorer

  • Interactive sliders for design variables
  • Predict objective using neural surrogate
  • "What-if" analysis without running FEA

Phase 3: Claude Code Integration (AI Chat)

3.1 Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                    Atomizer Dashboard                        │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌─────────────────────────┐  ┌──────────────────────────┐  │
│  │                         │  │                          │  │
│  │    Main Dashboard       │  │   Claude Code Panel      │  │
│  │    (Charts, Controls)   │  │   (Chat Interface)       │  │
│  │                         │  │                          │  │
│  │                         │  │  ┌────────────────────┐  │  │
│  │                         │  │  │ Conversation       │  │  │
│  │                         │  │  │ History            │  │  │
│  │                         │  │  │                    │  │  │
│  │                         │  │  └────────────────────┘  │  │
│  │                         │  │                          │  │
│  │                         │  │  ┌────────────────────┐  │  │
│  │                         │  │  │ Input Box          │  │  │
│  │                         │  │  └────────────────────┘  │  │
│  │                         │  │                          │  │
│  └─────────────────────────┘  └──────────────────────────┘  │
│                                                              │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
                    ┌─────────────────┐
                    │   Backend API    │
                    │   /api/claude    │
                    └────────┬────────┘
                             │
                             ▼
                    ┌─────────────────┐
                    │  Claude Agent   │
                    │  SDK Backend    │
                    │  (Python)       │
                    └────────┬────────┘
                             │
                    ┌────────┴────────┐
                    │                 │
               ┌────▼────┐      ┌─────▼─────┐
               │ Atomizer│      │ Anthropic │
               │ Tools   │      │ Claude API│
               └─────────┘      └───────────┘

3.2 Backend Implementation

New API Endpoints:

# atomizer-dashboard/backend/api/routes/claude.py

@router.post("/chat")
async def chat_with_claude(request: ChatRequest):
    """
    Send a message to Claude with study context

    Request:
        - message: User's message
        - study_id: Current study context
        - conversation_id: For multi-turn conversations

    Returns:
        - response: Claude's response
        - actions: Any tool calls made (file edits, commands)
    """

@router.websocket("/chat/stream")
async def chat_stream(websocket: WebSocket):
    """
    WebSocket for streaming Claude responses
    Real-time token streaming for better UX
    """

@router.get("/conversations")
async def list_conversations():
    """Get conversation history for current study"""

@router.delete("/conversations/{conversation_id}")
async def delete_conversation(conversation_id: str):
    """Delete a conversation"""

Claude Agent SDK Integration:

# atomizer-dashboard/backend/services/claude_agent.py

from anthropic import Anthropic
import json

class AtomizerClaudeAgent:
    def __init__(self, study_id: str = None):
        self.client = Anthropic()
        self.study_id = study_id
        self.tools = self._load_atomizer_tools()
        self.system_prompt = self._build_system_prompt()

    def _build_system_prompt(self) -> str:
        """Build context-aware system prompt"""
        prompt = """You are Claude Code embedded in the Atomizer optimization dashboard.

You have access to the current optimization study and can help users:
1. Analyze optimization results
2. Modify study configurations
3. Create new studies
4. Explain FEA/Zernike concepts
5. Suggest design improvements

Current Study Context:
{study_context}

Available Tools:
- read_study_config: Read optimization configuration
- modify_config: Update design variables, objectives
- query_trials: Get trial data from database
- create_study: Create new optimization study
- run_analysis: Perform custom analysis
- edit_file: Modify study files
"""
        if self.study_id:
            prompt = prompt.format(study_context=self._get_study_context())
        else:
            prompt = prompt.format(study_context="No study selected")
        return prompt

    def _load_atomizer_tools(self) -> list:
        """Define Atomizer-specific tools for Claude"""
        return [
            {
                "name": "read_study_config",
                "description": "Read the optimization configuration for the current study",
                "input_schema": {
                    "type": "object",
                    "properties": {},
                    "required": []
                }
            },
            {
                "name": "query_trials",
                "description": "Query trial data from the Optuna database",
                "input_schema": {
                    "type": "object",
                    "properties": {
                        "filter": {
                            "type": "string",
                            "description": "SQL-like filter (e.g., 'state=COMPLETE')"
                        },
                        "limit": {
                            "type": "integer",
                            "description": "Max results to return"
                        }
                    }
                }
            },
            {
                "name": "modify_config",
                "description": "Modify the optimization configuration",
                "input_schema": {
                    "type": "object",
                    "properties": {
                        "path": {
                            "type": "string",
                            "description": "JSON path to modify (e.g., 'design_variables[0].max')"
                        },
                        "value": {
                            "type": "any",
                            "description": "New value to set"
                        }
                    },
                    "required": ["path", "value"]
                }
            },
            {
                "name": "create_study",
                "description": "Create a new optimization study",
                "input_schema": {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string"},
                        "description": {"type": "string"},
                        "model_path": {"type": "string"},
                        "design_variables": {"type": "array"},
                        "objectives": {"type": "array"}
                    },
                    "required": ["name"]
                }
            }
        ]

    async def chat(self, message: str, conversation_history: list = None) -> dict:
        """Process a chat message with tool use"""
        messages = conversation_history or []
        messages.append({"role": "user", "content": message})

        response = await self.client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=4096,
            system=self.system_prompt,
            tools=self.tools,
            messages=messages
        )

        # Handle tool calls
        if response.stop_reason == "tool_use":
            tool_results = await self._execute_tools(response.content)
            messages.append({"role": "assistant", "content": response.content})
            messages.append({"role": "user", "content": tool_results})
            return await self.chat("", messages)  # Continue conversation

        return {
            "response": response.content[0].text,
            "conversation": messages + [{"role": "assistant", "content": response.content}]
        }

3.3 Frontend Implementation

Chat Panel Component:

// atomizer-dashboard/frontend/src/components/ClaudeChat.tsx

import React, { useState, useRef, useEffect } from 'react';
import { Send, Bot, User, Sparkles, Loader2 } from 'lucide-react';
import ReactMarkdown from 'react-markdown';
import { useStudy } from '../context/StudyContext';

interface Message {
  role: 'user' | 'assistant';
  content: string;
  timestamp: Date;
  toolCalls?: any[];
}

export const ClaudeChat: React.FC = () => {
  const { selectedStudy } = useStudy();
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const messagesEndRef = useRef<HTMLDivElement>(null);

  const sendMessage = async () => {
    if (!input.trim() || isLoading) return;

    const userMessage: Message = {
      role: 'user',
      content: input,
      timestamp: new Date()
    };

    setMessages(prev => [...prev, userMessage]);
    setInput('');
    setIsLoading(true);

    try {
      const response = await fetch('/api/claude/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          message: input,
          study_id: selectedStudy?.id,
          conversation_history: messages
        })
      });

      const data = await response.json();

      setMessages(prev => [...prev, {
        role: 'assistant',
        content: data.response,
        timestamp: new Date(),
        toolCalls: data.tool_calls
      }]);
    } catch (error) {
      // Handle error
    } finally {
      setIsLoading(false);
    }
  };

  // Suggested prompts for new conversations
  const suggestions = [
    "Analyze my optimization results",
    "What parameters have the most impact?",
    "Create a new study for my bracket",
    "Explain the Zernike coefficients"
  ];

  return (
    <div className="flex flex-col h-full bg-dark-800 rounded-xl border border-dark-600">
      {/* Header */}
      <div className="px-4 py-3 border-b border-dark-600 flex items-center gap-2">
        <Bot className="w-5 h-5 text-primary-400" />
        <span className="font-medium text-white">Claude Code</span>
        {selectedStudy && (
          <span className="text-xs bg-dark-700 px-2 py-0.5 rounded text-dark-300">
            {selectedStudy.id}
          </span>
        )}
      </div>

      {/* Messages */}
      <div className="flex-1 overflow-y-auto p-4 space-y-4">
        {messages.length === 0 ? (
          <div className="text-center py-8">
            <Sparkles className="w-12 h-12 mx-auto mb-4 text-primary-400 opacity-50" />
            <p className="text-dark-300 mb-4">Ask me anything about your optimization</p>
            <div className="flex flex-wrap gap-2 justify-center">
              {suggestions.map((s, i) => (
                <button
                  key={i}
                  onClick={() => setInput(s)}
                  className="px-3 py-1.5 bg-dark-700 hover:bg-dark-600 rounded-lg
                           text-sm text-dark-300 hover:text-white transition-colors"
                >
                  {s}
                </button>
              ))}
            </div>
          </div>
        ) : (
          messages.map((msg, i) => (
            <div key={i} className={`flex gap-3 ${msg.role === 'user' ? 'justify-end' : ''}`}>
              {msg.role === 'assistant' && (
                <div className="w-8 h-8 rounded-lg bg-primary-600 flex items-center justify-center flex-shrink-0">
                  <Bot className="w-4 h-4 text-white" />
                </div>
              )}
              <div className={`max-w-[80%] rounded-lg p-3 ${
                msg.role === 'user'
                  ? 'bg-primary-600 text-white'
                  : 'bg-dark-700 text-dark-200'
              }`}>
                <ReactMarkdown className="prose prose-sm prose-invert">
                  {msg.content}
                </ReactMarkdown>
              </div>
              {msg.role === 'user' && (
                <div className="w-8 h-8 rounded-lg bg-dark-600 flex items-center justify-center flex-shrink-0">
                  <User className="w-4 h-4 text-dark-300" />
                </div>
              )}
            </div>
          ))
        )}
        {isLoading && (
          <div className="flex gap-3">
            <div className="w-8 h-8 rounded-lg bg-primary-600 flex items-center justify-center">
              <Loader2 className="w-4 h-4 text-white animate-spin" />
            </div>
            <div className="bg-dark-700 rounded-lg p-3 text-dark-400">
              Thinking...
            </div>
          </div>
        )}
        <div ref={messagesEndRef} />
      </div>

      {/* Input */}
      <div className="p-4 border-t border-dark-600">
        <div className="flex gap-2">
          <input
            type="text"
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
            placeholder="Ask about your optimization..."
            className="flex-1 px-4 py-2 bg-dark-700 border border-dark-600 rounded-lg
                     text-white placeholder-dark-400 focus:outline-none focus:border-primary-500"
          />
          <button
            onClick={sendMessage}
            disabled={!input.trim() || isLoading}
            className="px-4 py-2 bg-primary-600 hover:bg-primary-500 disabled:opacity-50
                     text-white rounded-lg transition-colors"
          >
            <Send className="w-4 h-4" />
          </button>
        </div>
      </div>
    </div>
  );
};

3.4 Claude Code Capabilities

When integrated, Claude Code will be able to:

Capability Description Example Command
Analyze Results Interpret optimization progress "Why is my convergence plateauing?"
Explain Physics Describe FEA/Zernike concepts "Explain astigmatism in my mirror"
Modify Config Update design variables "Increase the max bounds for whiffle_min to 60"
Create Studies Generate new study from description "Create a study for my new bracket"
Query Data SQL-like data exploration "Show me the top 5 trials by stress"
Generate Code Write custom analysis scripts "Write a Python script to compare trials"
Debug Issues Diagnose optimization problems "Why did trial 42 fail?"

Phase 4: Study Creation Wizard

4.1 Guided Study Setup

Multi-step wizard for creating new studies:

  1. Model Selection

    • Browse NX model files
    • Auto-detect expressions
    • Preview 3D geometry (if possible)
  2. Design Variables

    • Interactive table to set bounds
    • Baseline detection from model
    • Sensitivity hints from similar studies
  3. Objectives

    • Template selection (stress, displacement, frequency, Zernike)
    • Direction (minimize/maximize)
    • Target values and weights
  4. Constraints

    • Add geometric/physical constraints
    • Feasibility preview
  5. Algorithm Settings

    • Protocol selection (10/11/12)
    • Sampler configuration
    • Neural surrogate options
  6. Review & Create

    • Summary of all settings
    • Validation checks
    • One-click creation

Phase 5: Self-Contained Packaging

5.1 Electron Desktop App

Package the dashboard as a standalone desktop application:

Atomizer.exe
├── Frontend (React bundled)
├── Backend (Python bundled with PyInstaller)
├── NX Integration (optional)
└── Claude API (requires key)

Benefits:

  • No Node.js/Python installation needed
  • Single installer for users
  • Offline capability (except AI features)
  • Native file dialogs
  • System tray integration

5.2 Docker Deployment

# docker-compose.yml
version: '3.8'
services:
  frontend:
    build: ./atomizer-dashboard/frontend
    ports:
      - "3000:3000"

  backend:
    build: ./atomizer-dashboard/backend
    ports:
      - "8000:8000"
    volumes:
      - ./studies:/app/studies
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}

Implementation Priority

Phase Feature Effort Impact Priority
1.1 Unified Navigation Medium High P1
1.2 Study Overview Card Low High P1
1.3 Real-Time Status Medium High P1
2.1 Interactive Trial Table Medium High P1
3.1 Claude Chat Backend High Critical P1
3.3 Claude Chat Frontend Medium Critical P1
2.2 Enhanced Charts Medium Medium P2
2.4 Design Space Explorer High High P2
4.1 Study Creation Wizard High High P2
5.1 Electron Packaging High Medium P3

Technical Requirements

Dependencies to Add

Backend:

anthropic>=0.18.0  # Claude API
websockets>=12.0   # Real-time chat

Frontend:

@radix-ui/react-dialog  # Modals
@radix-ui/react-tabs    # Tab navigation
cmdk                    # Command palette
framer-motion           # Animations

API Keys Required

  • ANTHROPIC_API_KEY: For Claude Code integration (user provides)

Security Considerations

  1. API Key Storage: Never store API keys in frontend; use backend proxy
  2. File Access: Sandbox Claude's file operations to study directories only
  3. Command Execution: Whitelist allowed commands (no arbitrary shell)
  4. Rate Limiting: Prevent API abuse through the chat interface

Next Steps

  1. Review and approve this plan
  2. Prioritize features based on user needs
  3. Create GitHub issues for each feature
  4. Begin Phase 1 implementation
  5. Set up Claude API integration testing

Document Version: 1.0 Created: 2024-12-04 Author: Claude Code