Tracks OpenCode sessions to detect active work and display current commands.
src/lib/sessionActivity.ts- Core utilities for monitoring sessionssrc/hooks/useSessionActivity.ts- React hook for componentssrc/components/layout/Footer.session-activity.example.tsx- Usage examplesdemo-session-activity.ts- Standalone demo script
Get the most recently active session from OpenCode server.
import { getActiveSession } from './lib/sessionActivity.ts';
const activity = await getActiveSession();
console.log(activity?.title); // "Verify Phase 05 plans (@gsd-plan-checker subagent)"
console.log(activity?.isActive); // true if updated within last 60 seconds
console.log(activity?.currentActivity); // "gsd-plan-checker: running"Returns:
SessionActivity | null- Activity info or null if no sessions
Listen to session events and track real-time activity.
import { monitorSessionActivity } from './lib/sessionActivity.ts';
const cleanup = monitorSessionActivity((activity) => {
console.log(`Activity: ${activity.currentActivity}`);
});
// Stop listening when done
cleanup();Callback receives:
SessionActivity- Current activity state
Returns:
() => void- Cleanup function to stop listening
React hook for tracking session activity in components.
import { useSessionActivity } from './hooks/useSessionActivity.ts';
function MyComponent() {
const activity = useSessionActivity();
if (!activity) return <Text>No sessions</Text>;
if (activity.isActive) {
return <Text color="cyan">● {activity.currentActivity}</Text>;
}
return <Text>○ Idle</Text>;
}Display running command in the TUI footer:
import { Box, Text } from 'ink';
import { useSessionActivity } from '../hooks/useSessionActivity.ts';
export function Footer() {
const activity = useSessionActivity();
return (
<Box>
<Text dimColor>
{activity?.isActive && activity.currentActivity && (
<Text color="cyan" bold>
● {activity.currentActivity} |{' '}
</Text>
)}
Tab: tabs | q: quit
</Text>
</Box>
);
}Show session status as a dedicated component:
import { Text } from 'ink';
import { useSessionActivity } from '../hooks/useSessionActivity.ts';
export function SessionStatus() {
const activity = useSessionActivity();
if (!activity) return <Text dimColor>No sessions</Text>;
if (!activity.isActive) return <Text dimColor>○ Idle</Text>;
return <Text>● {activity.currentActivity}</Text>;
}Run standalone demo to see real-time activity:
bun demo-session-activity.tsOutput:
🔍 OpenCode Session Activity Monitor
Press Ctrl+C to stop
📊 Current: Verify Phase 05 plans (@gsd-plan-checker subagent)
Active: yes
Activity: gsd-plan-checker: running
[1:54:19 PM] ● Active
Verify Phase 05 plans (@gsd-plan-checker subagent)
→ gsd-plan-checker: running
Active sessions are detected by:
- Checking
time.updatedfromsession.list() - Sessions updated within 60 seconds are considered "active"
- Current activity extracted from session title parsing
Title patterns detected:
Phase XX: Description→ "Working on Phase XX"@subagent-name→ "subagent running"Verb something→ "verifying / planning / executing"
The monitor listens to OpenCode SSE events:
message.part.updatedwithtype="task"→ Shows subagent name and statusmessage.part.updatedwithtype="tool"→ Shows tool name and statusmessage.part.updatedwithtype="reasoning"→ Shows reasoning preview
opencode serve --port 4096must be running@opencode-ai/sdkpackage installed- For TUI integration: Ink component
- Session activity is cached per minute to avoid excessive API calls
- Uses 60-second threshold for "active" status
- Events are filtered to current session to avoid noise from other sessions
- SDK types don't include all event fields → uses
anywith biome-ignore comments