[Bug]: The sidebar doesn't show a thread's running dev servers: the per-thread indicator exists only in the legacy sidebar and never counts servers the agent started#15238

openedOct 3, 2026byVVantrongs

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/web

Steps to reproduce

  1. In a Claude thread, have the agent start a dev server in the background, for example python3 -m http.server 5173.
  2. Look at the thread's row in the sidebar.

Expected behavior

The row shows that the thread has a server running and on which port, so I can open it or notice it is still up, as the legacy sidebar's globe does for a server started in a T3 terminal.

Actual behavior

The row shows nothing. The per-thread indicator, a globe with "Open localhost:PORT (+N)", exists only in LegacySidebar.tsx, which is off by default.

Even there it would miss this server. useThreadDiscoveredPorts keeps only ports whose terminal.threadId matches, and the port scanner links a listener to a thread only through registerTerminalProcesses, which only the terminal manager calls (terminal/Manager.ts). A server the agent starts as a background shell runs under the provider process, so it is discovered with terminal: null and belongs to no thread.

Agents start such servers often, for example to preview variants of a page, and the preview's "Local servers" list doesn't say which thread started them, so they pile up unnoticed.

A possible fix: link a listener to the thread whose provider process it descends from (the server already reads its descendant processes for diagnostics), and show the count and ports on the row in the default sidebar.

Related: discussion https://github.com/pingdotgg/t3code/discussions/14822 asks for a thread's servers on mobile; discussions https://github.com/pingdotgg/t3code/discussions/10089 and https://github.com/pingdotgg/t3code/discussions/11254 are about stopping T3 terminals when a thread settles.

Impact

Minor bug or occasional failure

Version or commit

0.0.46-nightly.20261003.2623 (fed41fa)

Environment

Desktop app on Linux (NixOS, Wayland, niri); Claude Code 2.1.288

Logs or stack traces

No response

Screenshots, recordings, or supporting files

No response

Workaround

No response

Note

Grok responding on behalf of Julius.

Triage

Thanks @Vantrongs for the detailed code reading. It held up on both counts.

Confirmed on current main. This is one visibility gap with two separate causes.

The default sidebar never shows a per-thread server. legacySidebarEnabled is off by default, and the globe that opens localhost:PORT only exists on the legacy row (LegacySidebar.tsx, fed by useThreadDiscoveredPorts). SidebarThreadRow shows a terminal icon for T3 terminal sessions but doesn't read discovered ports at all. Turning the legacy sidebar on (Settings, then General, then Legacy features) only helps partly. It brings back the globe for servers started inside a T3 terminal, but not for your repro.

Servers an agent starts in the background aren't linked to any thread, even in the legacy sidebar. useThreadDiscoveredPorts keeps a listener only when terminal.threadId matches, and PortDiscovery sets terminal only from PIDs the terminal manager registers (registerTerminalProcesses in terminal/Manager.ts). A server started from Claude's background shell descends from the provider process, not a T3 terminal, so it's recorded with terminal: null. If it serves HTML it still appears in Preview's "Local servers" list, but that list doesn't name a thread, which matches the pile-up you described.

Likely fix area

Linking listeners through the provider's process tree is the right idea, but the diagnostics snapshot can't do it on its own. Resource telemetry labels those processes server-child and stores no thread id, and Claude's session isn't registered with PortDiscovery as a root PID. The options look like this:

  • Register the provider's descendant PIDs the way terminals already do.
  • Walk up from the listener PID to a provider root that maps to a thread.

Either way, some edge cases stay out of reach: detached or double-forked processes fall off the parent chain, listeners that don't serve HTML never get discovered, and the Windows fallback without lsof has no PID to work from. Showing the count and ports on the default sidebar row is a separate UI change.

A maintainer will decide on the fix direction.

Not a duplicate. Discussion #14822 is about showing already-linked servers on mobile, and Discussions #10089 and #11254 are about stopping terminals or project actions when a thread settles.

Thanks for writing this up. It asks for new behaviour rather than reporting a defect, so it does not belong in the bug tracker and I'm closing it as not planned here. Feature ideas are discussed in Discussions: please post it there.