Swadhin Biswas feat: implement mervelas cli engine, built-in tools, and reactive UI · 4/3/2026
0358986
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
* Team Discovery - Utilities for discovering teams and teammate status
*
* Scans ~/.mervelas/teams/ to find teams where the current session is the leader.
* Used by the Teams UI in the footer to show team status.
*/
import { isPaneBackend, type PaneBackendType } from './swarm/backends/types.js'
import { readTeamFile } from './swarm/teamHelpers.js'
export type TeamSummary = {
name: string
memberCount: number
runningCount: number
idleCount: number
}
export type TeammateStatus = {
name: string
agentId: string
agentType?: string
model?: string
prompt?: string
status: 'running' | 'idle' | 'unknown'
color?: string
idleSince?: string // ISO timestamp from idle notification
tmuxPaneId: string
cwd: string
worktreePath?: string
isHidden?: boolean // Whether the pane is currently hidden from the swarm view
backendType?: PaneBackendType // The backend type used for this teammate
mode?: string // Current permission mode for this teammate
}
/**
* Get detailed teammate statuses for a team
* Reads isActive from config to determine status
*/
export function getTeammateStatuses(teamName: string): TeammateStatus[] {
const teamFile = readTeamFile(teamName)
if (!teamFile) {
return []
}
const hiddenPaneIds = new Set(teamFile.hiddenPaneIds ?? [])
const statuses: TeammateStatus[] = []
for (const member of teamFile.members) {
// Exclude team-lead from the list
if (member.name === 'team-lead') {
continue
}
// Read isActive from config, defaulting to true (active) if undefined
const isActive = member.isActive !== false
const status: 'running' | 'idle' = isActive ? 'running' : 'idle'
statuses.push({
name: member.name,
agentId: member.agentId,
agentType: member.agentType,
model: member.model,
prompt: member.prompt,
status,
color: member.color,
tmuxPaneId: member.tmuxPaneId,
cwd: member.cwd,
worktreePath: member.worktreePath,
isHidden: hiddenPaneIds.has(member.tmuxPaneId),
backendType:
member.backendType && isPaneBackend(member.backendType)
? member.backendType
: undefined,
mode: member.mode,
})
}
return statuses
}
// Note: For time formatting, use formatRelativeTimeAgo from '../utils/format.js'