Skip to content

Fix disappearing parent threads in GUI list on partial refresh #493

@amanthanvi

Description

@amanthanvi

Summary

When CodexMonitor refreshes thread lists, parent threads can disappear from the GUI while still existing in Codex CLI. Their child subagents remain visible and appear "promoted" to root rows.

Impact

  • Active in-progress agent threads can vanish from the workspace thread list.
  • Subagent hierarchy becomes visually incorrect (children appear as roots).
  • User trust degrades because CLI and GUI disagree on thread existence.
  • Detached review/subagent navigation becomes harder when parent anchors are missing.

Reproduction (observed class)

  1. Have a parent thread with one or more child subagent threads.
  2. Keep parent/child links in reducer state (threadParentById).
  3. Trigger a list refresh path that returns a partial slice for the workspace (e.g. batched/global list query with per-workspace filtering/cursor pressure).
  4. Parent summary is omitted from the incoming setThreads payload while child summaries remain present.
  5. GUI computes rows with visible-parent resolution and promotes orphaned children to root rows.

Root Cause

setThreads currently replaces threadsByWorkspace[workspaceId] wholesale with the latest visible payload. That replacement can drop locally-known anchor rows that are still semantically active/needed for hierarchy continuity:

  • active thread summary
  • currently processing thread summaries
  • ancestors required to render child depth correctly

Since threadParentById is retained, the hierarchy graph still exists, but missing parent summaries cause row builder fallback to root placement.

Proposed Fix

In reducer setThreads, preserve incoming payload order as primary, but append previously-known anchor summaries when absent from incoming data:

  1. Active thread for the workspace (if locally known and not hidden)
  2. Processing threads for the workspace (if locally known and not hidden)
  3. Missing ancestors of incoming visible threads, resolved via threadParentById and existing local summaries (if not hidden)

Rules:

  • Never resurrect hidden threads (hiddenThreadIdsByWorkspace).
  • Do not synthesize placeholder parent summaries.
  • Do not override incoming server ordering; append anchors after incoming rows.
  • Keep sort key updates intact.

Acceptance Criteria

  • Parent thread no longer disappears from GUI solely because an incremental/partial list payload omits it.
  • Child rows stay nested under parent when parent summary exists locally.
  • Hidden threads remain hidden across refreshes.
  • Existing thread-list pagination and ordering behavior remain unchanged for non-anchor rows.

Tests

Add regressions for:

  1. Reducer-level setThreads keeps active/processing/ancestor anchors when missing from incoming payload.
  2. Integration-level hierarchy remains nested after a refresh that omits parent summary but includes child summary.

Scope

Frontend reducer + tests only. No backend or RPC contract changes expected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions