diff --git a/apps/desktop/src/app/chat/composer/status-stack/index.tsx b/apps/desktop/src/app/chat/composer/status-stack/index.tsx
index 93c8a2dc1af..df394e20323 100644
--- a/apps/desktop/src/app/chat/composer/status-stack/index.tsx
+++ b/apps/desktop/src/app/chat/composer/status-stack/index.tsx
@@ -118,48 +118,59 @@ export function ComposerStatusStack({ queue, sessionId }: ComposerStatusStackPro
const hasBackgroundGroup = groups.some(g => g.type === 'background')
- const sections: { key: string; node: ReactNode }[] = groups.map(group => ({
- key: group.type,
- node: (
-
- {t.statusStack.agents}
-
- ) : undefined
- }
- defaultCollapsed={group.type !== 'todo'}
- icon={}
- label={groupLabel(group, t.statusStack)}
- >
- {group.items.map(item => (
- dismissBackgroundProcess(sessionId, id) : undefined}
- onOpen={() => openSubagent(item)}
- onStop={sessionId ? id => void stopBackgroundProcess(sessionId, id) : undefined}
- />
- ))}
- {group.type === 'background' && previewRows}
-
- )
- }))
+ const previewBlock =
{previewRows}
+
+ const sections: { key: string; node: ReactNode }[] = []
+
+ for (const group of groups) {
+ sections.push({
+ key: group.type,
+ node: (
+
+ {t.statusStack.agents}
+
+ ) : undefined
+ }
+ defaultCollapsed={group.type !== 'todo'}
+ icon={}
+ label={groupLabel(group, t.statusStack)}
+ >
+ {group.items.map(item => (
+ dismissBackgroundProcess(sessionId, id) : undefined}
+ onOpen={() => openSubagent(item)}
+ onStop={sessionId ? id => void stopBackgroundProcess(sessionId, id) : undefined}
+ />
+ ))}
+
+ )
+ })
+
+ // Preview links belong to the background group (a localhost dev server and
+ // its preview are the same thing), but they must stay VISIBLE even when that
+ // group is collapsed — the whole point is a one-tap open. Render them as an
+ // always-visible block right after the background section, not as collapsible
+ // children that get swallowed the moment a background task appears.
+ if (group.type === 'background' && previewRows.length > 0) {
+ sections.push({ key: 'preview', node: previewBlock })
+ }
+ }
// No background group to host them (e.g. a standalone on-disk file preview):
- // keep the previews as their own row block so they don't disappear.
+ // still render them as their own always-visible block.
if (previewRows.length > 0 && !hasBackgroundGroup) {
- sections.push({
- key: 'preview',
- node: {previewRows}
- })
+ sections.push({ key: 'preview', node: previewBlock })
}
if (queue) {