feat: Add session management and global Claude terminal
Phase 1 - Accurate study status detection: - Add is_optimization_running() to check for active processes - Add get_accurate_study_status() with proper status logic - Status now: not_started, running, paused, completed - Add "paused" status styling (orange) to Home page Phase 2 - Global Claude terminal: - Create ClaudeTerminalContext for app-level state - Create GlobalClaudeTerminal floating component - Terminal persists across page navigation - Shows green indicator when connected - Remove inline terminal from Dashboard 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
FolderOpen
|
||||
} from 'lucide-react';
|
||||
import { useStudy } from '../context/StudyContext';
|
||||
import { useClaudeTerminal } from '../context/ClaudeTerminalContext';
|
||||
|
||||
interface ClaudeTerminalProps {
|
||||
isExpanded?: boolean;
|
||||
@@ -26,17 +27,24 @@ export const ClaudeTerminal: React.FC<ClaudeTerminalProps> = ({
|
||||
onClose
|
||||
}) => {
|
||||
const { selectedStudy } = useStudy();
|
||||
const { setIsConnected: setGlobalConnected } = useClaudeTerminal();
|
||||
const terminalRef = useRef<HTMLDivElement>(null);
|
||||
const xtermRef = useRef<Terminal | null>(null);
|
||||
const fitAddonRef = useRef<FitAddon | null>(null);
|
||||
const wsRef = useRef<WebSocket | null>(null);
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
const [isConnected, setIsConnectedLocal] = useState(false);
|
||||
const [isConnecting, setIsConnecting] = useState(false);
|
||||
const [_error, setError] = useState<string | null>(null);
|
||||
const [cliAvailable, setCliAvailable] = useState<boolean | null>(null);
|
||||
const [contextSet, setContextSet] = useState(false);
|
||||
const [settingContext, setSettingContext] = useState(false);
|
||||
|
||||
// Sync local connection state to global context
|
||||
const setIsConnected = useCallback((connected: boolean) => {
|
||||
setIsConnectedLocal(connected);
|
||||
setGlobalConnected(connected);
|
||||
}, [setGlobalConnected]);
|
||||
|
||||
// Check CLI availability
|
||||
useEffect(() => {
|
||||
fetch('/api/terminal/status')
|
||||
@@ -251,9 +259,13 @@ export const ClaudeTerminal: React.FC<ClaudeTerminalProps> = ({
|
||||
if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN || !selectedStudy?.id) return;
|
||||
|
||||
setSettingContext(true);
|
||||
// Send context message - Claude should use CLAUDE.md and .claude/skills/ for guidance
|
||||
const contextMessage = `Context: Working on study "${selectedStudy.id}" at studies/${selectedStudy.id}/. ` +
|
||||
`Read .claude/skills/ for task protocols. Use atomizer conda env. Acknowledge briefly.`;
|
||||
// Send context message with POS bootstrap instructions and study context
|
||||
const contextMessage =
|
||||
`You are helping with Atomizer optimization. ` +
|
||||
`First read: .claude/skills/00_BOOTSTRAP.md for task routing. ` +
|
||||
`Then follow the Protocol Execution Framework. ` +
|
||||
`Study context: Working on "${selectedStudy.id}" at studies/${selectedStudy.id}/. ` +
|
||||
`Use atomizer conda env. Acknowledge briefly.`;
|
||||
wsRef.current.send(JSON.stringify({ type: 'input', data: contextMessage + '\n' }));
|
||||
|
||||
// Mark as done after Claude has had time to process
|
||||
|
||||
Reference in New Issue
Block a user