Skip to content

fix: thread state and timeline fixes (upstream G4) - #997

Merged
rynfar merged 10 commits into
pylonfrom
upstream/2026-10-03-g4-thread-state
Oct 3, 2026
Merged

rynfar merged 10 commits into
pylonfrom
upstream/2026-10-03-g4-thread-state

Conversation

@rynfar

@rynfar rynfar commented Oct 3, 2026 •

Copy link
Copy Markdown
Collaborator

Ports upstream group G4 (thread state and timeline) from T3 Code. The main behavior change: a thread whose agent finished but left a command running, such as a dev server, no longer reads as Waiting. It now shows as completed and unread. Only subagents and monitors still hold a thread at Waiting, because they will wake the agent again. The group also fixes three timeline and layout problems and shows the remote machine in the thread panel.

Sources

Upstream Outcome Notes
bb7997709d thread panel shows the remote machine a thread runs on (#14972) Adopted (clean cherry-pick) Uses Pylon's existing shouldShowEnvironmentIndicator. A lone non-primary environment gets a static label.
3a7058da50 new worktree threads no longer flicker while starting (#15019) Adopted (import conflict resolved) Pylon's ChatView.logic.ts imports ComposerSubmissionIntent only, so I kept that import and added derivePhase. Pylon's derivePhase is identical to upstream's.
db514607f4 sending on an older thread no longer jumps to the top (#15059) Adopted (clean) Runless folds are now decided per prompt, on both web and mobile.
a5b34b2537 a dev server left running no longer says the thread is waiting (#15114) Adopted (test conflict resolved) Pylon lacks upstream's subagent display-name tests, so I kept Pylon's test set and added upstream's new command-only presentation test.
f68e24fb41 a thread that left a shell running shows its unseen completion (#14910) Adapted Details below.
44b4965017 reduce the gap above the draft composer (#15196) Adopted (clean)
a0bf1eee48 mobile: dev server running no longer shows the waiting bolt (#15194) Adopted (clean) FloatingWorkingStatus waiting → background with a waiting flag. It had no other Pylon consumers.

Pylon adaptations (f68e24fb41)

  • ThreadNotificationCoordinator.tsx: skipped the upstream hunk and kept Pylon's version. Pylon's notifications go through projectAwarenessStates / reconcileAwarenessNotifications in packages/shared/src/agentAwareness.ts. That code reads the raw shell activityRunStatus ?? status and already uses backgroundWorkHoldsCompletion to treat a command-only roster as completed. Notification behavior and auto-settle are unchanged.
  • Sidebar.logic.ts: minimal edits, kept well apart from G1's working-timer code.
    • Kept Pylon's status-model header comment.
    • Added one clause to the Working-shelf doc comment.
    • Took upstream's resolveThreadStatusPill change (backgroundWorkHoldsCompletion replaces the non-empty roster check).
    • Left isSidebarThreadWorking alone. It keeps the feat(web): beta Working sidebar section (upstream) #991 hasUnseenCompletion early return and the delegating/monitoring folding.
  • Sidebar.logic.test.ts: adapted the upstream unseen completion with background work test. Upstream expects a monitor-waiting thread with an unseen completion in the Working shelf. Pylon's Working section (feat(web): beta Working sidebar section (upstream) #991) keeps every unseen completion in the inbox, so the test expects isSidebarThreadWorking === false for both rosters. The pill, top-status and recede expectations are unchanged.
  • Client runtime (models.ts shellRuntime, threadExecution.ts deriveThreadRuntime) and mobile threadListV2.ts: adopted as upstream. A command-only roster no longer parks the runtime at idle.

Docs

  • docs/user/status-indicators.md: explains that subagents, monitors and other background tasks keep a thread at Waiting, while commands left running (a dev server) do not. Such a thread shows as completed, unread until you open it.

Review follow-up

  • Reworded the docs paragraph as above.
  • Moved the mobile bolt-or-terminal icon choice into backgroundStatusSymbol in floating-working-status.ts and added a test for it. apps/mobile floating-working-status.test.ts passes (6 tests) and vp run -F @t3tools/mobile typecheck reports no errors.

Verification

  • vp test run apps/web/src/components/ChatView.logic.test.ts apps/web/src/components/chat/MessagesTimeline.logic.test.ts apps/web/src/components/Sidebar.logic.test.ts packages/client-runtime/src/state/threadExecution.test.ts packages/client-runtime/src/state/entities.test.ts packages/shared/src/agentAwareness.test.ts packages/shared/src/orchestrationV2PendingBackgroundWork.test.ts: 7 files, 588 tests passed.
  • apps/mobile: vp test run src/features/threads/threadListV2.test.ts src/lib/threadActivity.test.ts src/features/threads/floating-working-status.test.ts: 3 files, 185 tests passed.
  • vp run -F @t3tools/web typecheck, vp run -F @t3tools/mobile typecheck and vp run -F @t3tools/client-runtime typecheck: each ran tsc --noEmit with no errors. Client-runtime printed only existing Effect suggestions in untouched tests.
  • vp lint on the changed files: 7 warnings, the same 7 as on origin/pylon. None are in changed lines.
  • vp fmt --check on the changed files passes, with one exception. When checked together with files from other packages, apps/mobile/src/features/threads/threadListV2.ts is flagged. It passes under vp fmt --check apps/mobile, and the unchanged base file is flagged the same way in that combined run.

Not verified

  • No browser, simulator or device checks were run under the porting constraints, so there are no before/after captures. Not checked visually:
    • the composer gap (44b4965017)
    • the worktree-setup card and working-header layout (3a7058da50)
    • the thread panel environment row (bb7997709d)
    • the mobile terminal icon (a0bf1eee48)
  • apps/desktop was not typechecked because it was not touched.

Part of upstream cycle #996.

🤖 Generated with Claude Code

t3dotgg and others added 8 commits October 3, 2026 13:22
…972)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit bb7997709dd5ed91a3aa18c091286f5f5331b0ef)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 3a7058da50c91906158c89fc3f845e6c04379414)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…059)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit db514607f4026cd2bbb7b96674168bb227ac043a)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…waiting (#15114)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit a5b34b25378fbbf90ce36ee101a11528ccf11c7e)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ion (#14910)

Co-authored-by: Theo Browne <me@t3.gg>
(cherry picked from commit f68e24fb419c985269cd0acb841e203af1419c43)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 44b49650170a76e6171642d6f8de946cf1d1c821)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…lt (#15194)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit a0bf1eee48d1537ec38e0f1fa5243f10ffd4e870)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Oct 3, 2026
@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 4.9 KiB 4.9 KiB −40 B (−0.8%) 6.8 KiB ✅
Codex Thread snapshot wire 3.7 KiB 3.7 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.1 KiB −40 B (−3.3%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 20.4 KiB 20.4 KiB −41 B (−0.2%) 29.3 KiB ✅
Codex Live turn messages 2 1 −1 (−50.0%) 8 ✅
Claude Total thread wire 4.9 KiB 4.9 KiB −41 B (−0.8%) 6.8 KiB ✅
Claude Thread snapshot wire 3.7 KiB 3.7 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB −41 B (−3.4%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 20.8 KiB 20.7 KiB −41 B (−0.2%) 29.3 KiB ✅
Claude Live turn messages 2 1 −1 (−50.0%) 8 ✅

Baseline: 30ec43a · PR result: 98814d5 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 106.1 KiB
  • Claude decoded thread snapshot: 106.4 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

rynfar and others added 2 commits October 3, 2026 13:40
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@rynfar
rynfar merged commit dff1642 into pylon Oct 3, 2026
23 checks passed
rynfar added a commit that referenced this pull request Oct 3, 2026
Provide ThreadCommandExecutor to the ProviderEventIngestor layer in the
LegacyAdapterV2SessionManager test added by #1002. Expect the `waiting`
flag that #997 added to the pending background work shown for subagent
display names.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants