Skip to content

Fix Claude background task lifecycle UI#259

Open
brsbl wants to merge 2 commits into
mainfrom
bb/fix-claude-background-task-lifecycle
Open

Fix Claude background task lifecycle UI#259
brsbl wants to merge 2 commits into
mainfrom
bb/fix-claude-background-task-lifecycle

Conversation

@brsbl

@brsbl brsbl commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes three confirmed Claude background-task lifecycle failures:

  • keeps open workflows/background commands visible in the latest timeline response even when their lifecycle row is outside the latest segment window
  • shows the thread working indicator while an active background task is pending, even after the provider turn has completed and runtime status is idle
  • makes Claude bridge same-session thread/resume idempotent so a reconnect/resume for the live provider session does not close the SDK session and stop background work

Root Cause Evidence

  • Packaged-app DB evidence from the takeover thread showed Claude workflows commonly outlive their turn: 32 of 35 materialized Claude background tasks completed after the next turn/completed; one example completed roughly 39,974s after the turn completed. That confirms the shared lifecycle mismatch: turn done is not background work done.
  • The latest timeline active-card projection was derived from selected timeline rows. If an open task started/progressed outside the latest segment, activeWorkflow / activeBackgroundCommands could be empty even though the task was still open.
  • The spinner path only checked runtime display status. Claude turns go idle at turn/completed, so a still-running background workflow had no working indicator.
  • Same-provider thread/resume previously closed an existing live Claude SDK session before starting/resuming, which could interrupt open background tasks.

Unverified/not changed here: subagent/monitor task materialization remains intentionally excluded by current filters, and quick completed tasks can still leave the active-card list immediately because active cards represent only pending tasks.

Changes

  • Added a DB helper that returns the latest non-terminal lifecycle row for each open background task on a thread.
  • Backfilled those open task rows into latest timeline responses for projection, using a thread-scoped progress snapshot when the only latest state is an old turn-scoped item/started.
  • Updated the detail and timeline-panel working indicator to account for active background tasks.
  • Added an idempotent Claude bridge resume path when the requested provider thread already has a live session.
  • Added regression tests for the open-task timeline window gap, DB helper behavior, and same-session resume behavior.
  • Added smoke coverage for both active-card surfaces: server route smoke for stale-window local_workflow and local_bash, plus app render smoke for background-only working indicators.

Validation

  • pnpm exec turbo run test --filter=@bb/server
  • pnpm exec turbo run test --filter=@bb/db
  • pnpm exec turbo run test --filter=@bb/agent-runtime
  • pnpm exec turbo run test --filter=@bb/app -- --run src/components/thread/timeline/ThreadTimelinePanelContent.test.tsx
  • pnpm exec turbo run test --filter=@bb/server -- --run test/public/public-thread-data.test.ts -t "surfaces active"
  • pnpm exec turbo run typecheck --filter=@bb/db
  • pnpm exec turbo run typecheck --filter=@bb/server
  • pnpm exec turbo run typecheck --filter=@bb/agent-runtime
  • pnpm exec turbo run typecheck --filter=@bb/app

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant