From a73f7c3a4f4afac5b8900b8c52bff87b569996d2 Mon Sep 17 00:00:00 2001 From: arkon Date: Thu, 29 Jan 2026 12:04:14 +0100 Subject: [PATCH] fix: prevent stale subagent data from showing in windows - Reduce getRecentSubagents window from 60 to 15 minutes - Skip old/completed agents when restoring window states (10 min cutoff) - Clear old activity data when new agent with same ID is discovered - Force close existing window for agentId before opening fresh one Fixes issue where old prompts/input from previous Ralph Loop runs were displayed when clicking on subagent windows. Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 2 +- package.json | 2 +- src/web/public/app.js | 21 ++++++++++++++++++--- src/web/server.ts | 4 ++-- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index e32e4443..65841163 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,7 +16,7 @@ When user says "COM": 1. Increment version in BOTH `package.json` AND `CLAUDE.md` 2. Run: `git add -A && git commit -m "chore: bump version to X.XXXX" && git push && npm run build && systemctl --user restart claudeman-web` -**Version**: 0.1425 (must match `package.json`) +**Version**: 0.1426 (must match `package.json`) ## Project Overview diff --git a/package.json b/package.json index bb91b9eb..fb220d81 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claudeman", - "version": "0.1425", + "version": "0.1426", "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 c6fcf4cb..77411da2 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -1792,8 +1792,14 @@ class ClaudemanApp { addListener('subagent:discovered', async (e) => { const data = JSON.parse(e.data); + // Clear all old data for this agentId (in case of ID reuse) this.subagents.set(data.agentId, data); this.subagentActivity.set(data.agentId, []); + this.subagentToolResults.delete(data.agentId); + // Close any existing window for this agentId (will be reopened fresh) + if (this.subagentWindows.has(data.agentId)) { + this.forceCloseSubagentWindow(data.agentId); + } this.renderSubagentPanel(); // Find which Claudeman session owns this subagent (by working directory) @@ -7447,12 +7453,18 @@ class ClaudemanApp { } // Restore minimized state, but verify session mapping is correct + // Skip old agents from previous runs to avoid confusion + const cutoffTime = Date.now() - 10 * 60 * 1000; // 10 minutes for (const [savedSessionId, agentIds] of Object.entries(states.minimized || {})) { if (Array.isArray(agentIds) && agentIds.length > 0) { for (const agentId of agentIds) { const agent = this.subagents.get(agentId); if (!agent) continue; // Agent no longer exists + // Skip completed or old agents + const agentStartTime = agent.startedAt ? new Date(agent.startedAt).getTime() : 0; + if (agent.status === 'completed' || agentStartTime < cutoffTime) continue; + // Use discovered parentSessionId, or validate saved sessionId exists const correctSessionId = agent.parentSessionId || (this.sessions.has(savedSessionId) ? savedSessionId : null); @@ -7467,11 +7479,14 @@ class ClaudemanApp { } } - // Restore open windows (for non-completed agents only) + // Restore open windows (for recent, non-completed agents only) + const now = Date.now(); + const maxAgeMs = 10 * 60 * 1000; // 10 minutes - don't restore windows for old agents for (const { agentId, position } of (states.open || [])) { const agent = this.subagents.get(agentId); - // Only restore window if agent exists and is still active/idle (not completed) - if (agent && agent.status !== 'completed') { + // Only restore window if agent exists, is recent, and is still active/idle + const agentAge = agent?.startedAt ? now - new Date(agent.startedAt).getTime() : Infinity; + if (agent && agent.status !== 'completed' && agentAge < maxAgeMs) { this.openSubagentWindow(agentId); // Restore position if saved (with viewport bounds check) if (position) { diff --git a/src/web/server.ts b/src/web/server.ts index c04191d2..fa08ee3c 100644 --- a/src/web/server.ts +++ b/src/web/server.ts @@ -4600,7 +4600,7 @@ NOW: Generate the implementation plan for the task above. Think step by step.`; scheduledRuns: Array.from(this.scheduledRuns.values()), respawnStatus, globalStats: this.store.getAggregateStats(activeSessionTokens), - subagents: subagentWatcher.getRecentSubagents(60), // Last hour of subagent activity + subagents: subagentWatcher.getRecentSubagents(15), // Last 15 min - filter out stale agents from previous runs timestamp: Date.now(), }; } @@ -4630,7 +4630,7 @@ NOW: Generate the implementation plan for the task above. Think step by step.`; scheduledRuns: Array.from(this.scheduledRuns.values()), respawnStatus, globalStats: this.store.getAggregateStats(activeSessionTokens), - subagents: subagentWatcher.getRecentSubagents(60), + subagents: subagentWatcher.getRecentSubagents(15), // 15 min to avoid stale agents timestamp: Date.now(), }; }