diff --git a/client/src/components/cos/tabs/AgentCard.jsx b/client/src/components/cos/tabs/AgentCard.jsx index 4ee8eb15ff..50cf738c58 100644 --- a/client/src/components/cos/tabs/AgentCard.jsx +++ b/client/src/components/cos/tabs/AgentCard.jsx @@ -329,6 +329,15 @@ export default function AgentCard({ agent, onPause, onKill, onDelete, onResume, ), [inactive, fullOutput, liveOutput, agent.output]); const lastOutput = output.length > 0 ? output[output.length - 1]?.line : null; + // Why this run has NO "Open Shell" link. Scoped to the one case where the user + // configured a TUI provider and got no shell anyway: a public-review stage is + // forced headless regardless (`spawnHeadless = publicReview || !isTui`). An + // ordinary headless CLI agent gets no chip — nobody expected a shell there, and + // one on every card would be the noise this exists to remove. + const noShellReason = !agent.metadata?.tuiSessionId && agent.metadata?.publicReviewPosture + ? 'No shell: a public-review stage always runs headless, even when you configure it onto a TUI provider — the screened PR content stays inside the sandboxed child. Watch the live output below to see what it is doing.' + : null; + // Extract recent tool activity (last few tool lines) for live display const recentActivity = useMemo(() => { if (inactive || output.length === 0) return []; @@ -616,6 +625,15 @@ export default function AgentCard({ agent, onPause, onKill, onDelete, onResume, {agent.metadata.tuiSessionId.slice(0, 6)} )} + {!inactive && noShellReason && ( + + + )} {!remote && (