Compare commits

...

2 Commits

Author SHA1 Message Date
AndyMik90 4debd7d2ef fix: use zero initial progress for XState phase transitions to prevent regression
Setting phaseProgress and overallProgress to 0 (instead of 50) when
XState emits a phase-change event ensures the progress bar only moves
forward. Previously, XState would set progress to 50%, then the agent
would send its actual progress (e.g. 10%), causing the bar to visually
regress from 50% → 10%.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 12:20:37 +01:00
AndyMik90 c8e24eb720 fix: sync kanban card stage with live agent phase (fixes #1885)
The emitPhaseFromState method in TaskStateManager was using Date.now()
as the sequenceNumber for TASK_EXECUTION_PROGRESS events. Since agent
processes use small sequential integers (1, 2, 3...) for their sequence
numbers, the timestamp-based value (e.g., 1708512345678) was always
much larger. This caused the out-of-order drop check in updateExecutionProgress
to permanently block all subsequent agent execution-progress events once
XState emitted any phase update.

The result: after XState fired the initial "planning" phase via emitPhaseFromState,
all agent events reporting the "coding" (or later) phase would be silently dropped
because their sequential numbers were less than the stored timestamp. The kanban
card would remain frozen on the "planning" badge while the task detail view
(which reads from task logs) correctly showed the "coding" stage.

Fix: use sequenceNumber=0 in emitPhaseFromState. With value 0, the incoming
sequence check (incomingSeq > 0 && currentSeq > 0) is not triggered, so the
XState phase update always applies. Subsequent agent events with their small
sequential numbers are then correctly accepted and can continue updating
phaseProgress.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 21:48:33 +01:00
+9 -4
View File
@@ -362,17 +362,22 @@ export class TaskStateManager {
const phase = XSTATE_TO_PHASE[xstateState] || 'idle';
// Emit execution progress with the phase derived from XState
// Emit execution progress with the phase derived from XState.
// IMPORTANT: Do NOT use Date.now() as sequenceNumber here — doing so would
// permanently block all subsequent agent execution-progress events, because
// the agent uses small sequential integers (1, 2, 3…) that are always less
// than a timestamp. Instead emit with sequenceNumber=0 so the agent's own
// events can continue updating phaseProgress once the phase is established.
safeSendToRenderer(
this.getMainWindow,
IPC_CHANNELS.TASK_EXECUTION_PROGRESS,
taskId,
{
phase,
phaseProgress: phase === 'complete' ? 100 : 50,
overallProgress: phase === 'complete' ? 100 : 50,
phaseProgress: phase === 'complete' ? 100 : 0,
overallProgress: phase === 'complete' ? 100 : 0,
message: `State: ${xstateState}`,
sequenceNumber: Date.now() // Use timestamp as sequence to ensure it's newer
sequenceNumber: 0
},
projectId
);