From 0f9caa9d29693dcdf7ac58f3c2cd3c3f927b16ee Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 25 Jan 2026 05:00:43 +0100 Subject: [PATCH] feat: improve respawn display readability and AI check info (v0.1338) - State label now white on green pill for better visibility - AI check shows detailed status with color-coded badges: - Blue: Analyzing terminal output - Green: Idle confirmed - Yellow: Working detected - Gray: Disabled - Shows time since last check when recent (<2min) - Bump version to 0.1338 Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 2 +- package.json | 2 +- src/web/public/app.js | 31 ++++++++++++++++++++++++++----- src/web/public/styles.css | 31 ++++++++++++++++++++++++++++--- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a08a92ca..8ae7369f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,7 +17,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co Claudeman is a Claude Code session manager with a web interface and autonomous Ralph Loop. It spawns Claude CLI processes via PTY, streams output in real-time via SSE, and supports scheduled/timed runs. -**Version**: 0.1337 +**Version**: 0.1338 **Tech Stack**: TypeScript (ES2022/NodeNext, strict mode), Node.js, Fastify, Server-Sent Events, node-pty diff --git a/package.json b/package.json index 40374494..fa7b6255 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claudeman", - "version": "0.1337", + "version": "0.1338", "description": "The missing control plane for Claude Code - run 20 autonomous agents with real-time monitoring and session persistence", "type": "module", "main": "dist/index.js", diff --git a/src/web/public/app.js b/src/web/public/app.js index e891610b..5c74a95d 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -2016,20 +2016,41 @@ class ClaudemanApp { confidenceEl.style.display = 'none'; } - // Simplified AI check display + // AI check display - informative but clear if (aiCheckEl && detection.aiCheck) { const ai = detection.aiCheck; let aiText = ''; + let aiClass = 'detection-ai-check'; + if (ai.status === 'checking') { - aiText = 'AI analyzing...'; + aiText = '🔍 AI: Analyzing terminal output...'; + aiClass += ' ai-checking'; } else if (ai.status === 'cooldown' && ai.cooldownEndsAt) { const remaining = Math.ceil((ai.cooldownEndsAt - Date.now()) / 1000); - if (remaining > 0) aiText = `Cooldown ${remaining}s`; + if (remaining > 0) { + if (ai.lastVerdict === 'WORKING') { + aiText = `⏳ AI: Working detected, retry in ${remaining}s`; + aiClass += ' ai-working'; + } else { + aiText = `✓ AI: Idle confirmed, cooldown ${remaining}s`; + aiClass += ' ai-idle'; + } + } } else if (ai.status === 'disabled') { - aiText = 'AI disabled'; + aiText = `⚠ AI: Disabled (${ai.disabledReason || 'errors'})`; + aiClass += ' ai-disabled'; + } else if (ai.lastVerdict && ai.lastCheckTime) { + const ago = Math.round((Date.now() - ai.lastCheckTime) / 1000); + if (ago < 120) { + aiText = ai.lastVerdict === 'IDLE' + ? `✓ AI: Idle (${ago}s ago)` + : `⏳ AI: Working (${ago}s ago)`; + aiClass += ai.lastVerdict === 'IDLE' ? ' ai-idle' : ' ai-working'; + } } - // Don't show "last verdict" - it's noise + aiCheckEl.textContent = aiText; + aiCheckEl.className = aiClass; aiCheckEl.style.display = aiText ? '' : 'none'; } else if (aiCheckEl) { aiCheckEl.style.display = 'none'; diff --git a/src/web/public/styles.css b/src/web/public/styles.css index 5d703949..7b25d64d 100644 --- a/src/web/public/styles.css +++ b/src/web/public/styles.css @@ -566,8 +566,11 @@ body { } .respawn-state { - color: var(--green); - font-weight: 500; + color: #fff; + font-weight: 600; + background: rgba(34, 197, 94, 0.3); + padding: 0.15rem 0.5rem; + border-radius: 3px; } .respawn-spacer { @@ -601,8 +604,30 @@ body { } .detection-ai-check { - color: var(--accent); font-size: 0.7rem; + padding: 0.1rem 0.4rem; + border-radius: 3px; + background: rgba(255, 255, 255, 0.1); +} + +.detection-ai-check.ai-checking { + color: var(--accent); + background: rgba(59, 130, 246, 0.15); +} + +.detection-ai-check.ai-idle { + color: var(--green); + background: rgba(34, 197, 94, 0.15); +} + +.detection-ai-check.ai-working { + color: var(--yellow); + background: rgba(234, 179, 8, 0.15); +} + +.detection-ai-check.ai-disabled { + color: var(--text-muted); + background: rgba(255, 255, 255, 0.05); } .detection-confidence {