Problem
When background agents are running, the status line showing current activity (e.g., → Fuzu-Production-Db_query:) flashes very briefly and then disappears. This causes:
- Flickering - Status line appears for ~1 second then vanishes
- Layout jumping - Screen jumps when status line appears/disappears
- Worse with multiple agents - More agents = more jumping
Screenshots
Without status line (most of the time):
- Shows only:
◉ Research-Specialist Task "Analyze PhD user recommendations"
With status line (brief flash):
- Shows:
◉ Research-Specialist Task "Analyze PhD user recommendations" - Plus:
→ Fuzu-Production-Db_query:
Root Cause Analysis
THE BUG: Missing initial session registration causes race condition
When a task spawns a subagent:
TaskTool creates child session (task.ts:169-199)
- Returns
sessionId in metadata: ctx.metadata({ metadata: { sessionId: session.id } }) - Session is persisted to storage via
Session.createNext
Task component renders activity (index.tsx:1805-1807)
constchildMessages=createMemo(()=>props.metadata.sessionId ? (sync.data.message[props.metadata.sessionId]??[]) : [],)
- Immediately looks up
sync.data.message[props.metadata.sessionId]
Sync context message store is EMPTY for new session (sync.tsx:228-266)
sync.data.message[childSessionID] is undefined initially- Child session's messages arrive via "message.updated" events after a delay
- During this delay,
childMessages() returns [], activity() returns null
Sync.session.sync() only runs on parent session (index.tsx:173-187)
- The
createEffect in Session component calls sync.session.sync(route.sessionID) for parent only - Child session is never synced, so its messages never populate the store via sync
Result: Activity line flashes → vanishes → reappears
- T0: Task component renders with
sessionId but no messages → no activity line - T1 (~1 sec): First "message.updated" event arrives → activity line appears briefly
- T2 (~2 sec): State update clears
sync.data.message[childSessionId] temporarily - T3: When stable, activity line stays visible (if at all)
Key Files
| File | Lines | Purpose |
|---|
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx | 1790-1888 | Task component renders subagent status |
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx | 1805-1807 | childMessages memo lookup |
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx | 1810-1838 | activity memo calculation |
packages/opencode/src/cli/cmd/tui/context/sync.tsx | 228-266 | "message.updated" event handler |
packages/opencode/src/tool/task.ts | 163-199, 225-250 | Child session creation and metadata |
Suggested Fix Approaches
Option 1: Fetch child session messages on demand
// In packages/opencode/src/cli/cmd/tui/routes/session/index.tsxfunctionTask(props: ToolProps<typeofTaskTool>){constsync=useSync()// NEW: Ensure child session data is loadedcreateEffect(async()=>{constchildSessionId=props.metadata.sessionIdif(!childSessionId)returnconsthasMessages=!!sync.data.message[childSessionId]?.lengthif(!hasMessages){awaitsync.session.sync(childSessionId)}})// ... rest of component ...}Option 2: Add activity placeholder state
constactivity=createMemo(()=>{constmsgs=childMessages()consthasPending=props.part.state.status==="running"||props.part.state.status==="pending"if(msgs.length===0&&hasPending&&props.metadata.sessionId){return"Starting..."}// ... existing logic ...})Option 3: Reserve layout space
Prevent jumping by always reserving space for the status line when a task is running.
Related Issues
Priority
Medium - UX issue affecting usability when running parallel agents
Problem
When background agents are running, the status line showing current activity (e.g.,
→ Fuzu-Production-Db_query:) flashes very briefly and then disappears. This causes:Screenshots
Without status line (most of the time):
◉ Research-Specialist Task "Analyze PhD user recommendations"With status line (brief flash):
◉ Research-Specialist Task "Analyze PhD user recommendations"→ Fuzu-Production-Db_query:Root Cause Analysis
THE BUG: Missing initial session registration causes race condition
When a task spawns a subagent:
TaskTool creates child session (
task.ts:169-199)sessionIdin metadata:ctx.metadata({ metadata: { sessionId: session.id } })Session.createNextTask component renders activity (
index.tsx:1805-1807)sync.data.message[props.metadata.sessionId]Sync context message store is EMPTY for new session (
sync.tsx:228-266)sync.data.message[childSessionID]is undefined initiallychildMessages()returns[],activity()returnsnullSync.session.sync() only runs on parent session (
index.tsx:173-187)createEffectin Session component callssync.session.sync(route.sessionID)for parent onlyResult: Activity line flashes → vanishes → reappears
sessionIdbut no messages → no activity linesync.data.message[childSessionId]temporarilyKey Files
packages/opencode/src/cli/cmd/tui/routes/session/index.tsxpackages/opencode/src/cli/cmd/tui/routes/session/index.tsxchildMessagesmemo lookuppackages/opencode/src/cli/cmd/tui/routes/session/index.tsxactivitymemo calculationpackages/opencode/src/cli/cmd/tui/context/sync.tsxpackages/opencode/src/tool/task.tsSuggested Fix Approaches
Option 1: Fetch child session messages on demand
Option 2: Add activity placeholder state
Option 3: Reserve layout space
Prevent jumping by always reserving space for the status line when a task is running.
Related Issues
Priority
Medium - UX issue affecting usability when running parallel agents