rename team lifecycle events to Joined/Left
test / unit + widget + golden + a11y (push) Failing after 27s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 28s
test / unit + widget + golden + a11y (push) Failing after 27s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 28s
TeamMemberBorn -> TeamMemberJoined, TeamMemberDied -> TeamMemberLeft (kinds member-joined/member-left). Less morbid and a better fit for teammates coming and going. No consumers yet, so a plain rename. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
/// `tmuxPaneId` (`%N`, empty for the lead), `name`, `agentType`, `model`,
|
||||
/// `color`, `cwd`, `joinedAt`. Polling `tmux -L clide list-panes -a` and
|
||||
/// correlating live pane ids with `tmuxPaneId` gives a dependable
|
||||
/// born/died signal and full identity — no transcript needed.
|
||||
/// joined/left signal and full identity — no transcript needed.
|
||||
/// - **Fragile — per-teammate transcript join.** A teammate's transcript is
|
||||
/// a subagent file `<munged-cwd>/<leadSessionId>/subagents/agent-<hex>.jsonl`
|
||||
/// whose only ids are a random hex (the filename) and a `slug`; it carries
|
||||
@@ -137,8 +137,8 @@ class _LiveMember {
|
||||
final TranscriptPublisher? publisher;
|
||||
}
|
||||
|
||||
/// Watches a workspace's tmux team and emits [TeamMemberBorn] /
|
||||
/// [TeamMemberDied] as panes appear/disappear, publishing each teammate's
|
||||
/// Watches a workspace's tmux team and emits [TeamMemberJoined] /
|
||||
/// [TeamMemberLeft] as panes appear/disappear, publishing each teammate's
|
||||
/// transcript onto the [MessageBus] under its per-agent channel.
|
||||
class TeamObserver {
|
||||
TeamObserver({
|
||||
@@ -200,7 +200,7 @@ class TeamObserver {
|
||||
}
|
||||
|
||||
/// One poll cycle (public for tests). Diffs the config roster against the
|
||||
/// live panes and emits born/died.
|
||||
/// live panes and emits joined/left.
|
||||
Future<void> tick() async {
|
||||
final config = await discoverTeam(workspacePath, teamsBase: _teamsBase);
|
||||
if (config == null) {
|
||||
@@ -215,19 +215,19 @@ class TeamObserver {
|
||||
final paneLive = livePanes.contains(m.tmuxPaneId);
|
||||
final tracked = _live.containsKey(m.agentId);
|
||||
if (paneLive && !tracked) {
|
||||
await _born(config, m);
|
||||
await _joined(config, m);
|
||||
} else if (!paneLive && tracked) {
|
||||
await _died(m.agentId);
|
||||
await _left(m.agentId);
|
||||
}
|
||||
}
|
||||
|
||||
// A member dropped from the config (team reshaped) also counts as died.
|
||||
// A member dropped from the config (team reshaped) also counts as left.
|
||||
for (final id in _live.keys.toList()) {
|
||||
if (!configIds.contains(id)) await _died(id);
|
||||
if (!configIds.contains(id)) await _left(id);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _born(TeamConfig config, TeamMember m) async {
|
||||
Future<void> _joined(TeamConfig config, TeamMember m) async {
|
||||
final path = await _resolveTranscript(config, m);
|
||||
TranscriptPublisher? pub;
|
||||
if (path != null) {
|
||||
@@ -238,7 +238,7 @@ class TeamObserver {
|
||||
);
|
||||
}
|
||||
_live[m.agentId] = _LiveMember(m, config.team, pub);
|
||||
_events.emit(TeamMemberBorn(
|
||||
_events.emit(TeamMemberJoined(
|
||||
team: config.team,
|
||||
agentId: m.agentId,
|
||||
name: m.name,
|
||||
@@ -251,16 +251,16 @@ class TeamObserver {
|
||||
));
|
||||
}
|
||||
|
||||
Future<void> _died(String agentId) async {
|
||||
Future<void> _left(String agentId) async {
|
||||
final live = _live.remove(agentId);
|
||||
if (live == null) return;
|
||||
await live.publisher?.dispose();
|
||||
_events.emit(TeamMemberDied(team: live.team, agentId: agentId, paneId: live.member.tmuxPaneId));
|
||||
_events.emit(TeamMemberLeft(team: live.team, agentId: agentId, paneId: live.member.tmuxPaneId));
|
||||
}
|
||||
|
||||
Future<void> _killAll() async {
|
||||
for (final id in _live.keys.toList()) {
|
||||
await _died(id);
|
||||
await _left(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,8 +111,8 @@ class DaemonEvent extends ClideEvent {
|
||||
/// taken from the team config, so it is reliable regardless of transcript
|
||||
/// drift (T-139, D-75). [transcriptPath] is the best-effort resolved
|
||||
/// subagent transcript, or null if it could not be joined yet.
|
||||
class TeamMemberBorn extends ClideEvent {
|
||||
const TeamMemberBorn({
|
||||
class TeamMemberJoined extends ClideEvent {
|
||||
const TeamMemberJoined({
|
||||
required this.team,
|
||||
required this.agentId,
|
||||
required this.name,
|
||||
@@ -142,7 +142,7 @@ class TeamMemberBorn extends ClideEvent {
|
||||
@override
|
||||
String get subsystem => 'team';
|
||||
@override
|
||||
String get kind => 'member-born';
|
||||
String get kind => 'member-joined';
|
||||
@override
|
||||
Map<String, Object?> payload() => {
|
||||
'team': team,
|
||||
@@ -159,8 +159,8 @@ class TeamMemberBorn extends ClideEvent {
|
||||
|
||||
/// A Claude Code tmux teammate's pane went away (it exited or the team
|
||||
/// dissolved) — T-139.
|
||||
class TeamMemberDied extends ClideEvent {
|
||||
const TeamMemberDied({
|
||||
class TeamMemberLeft extends ClideEvent {
|
||||
const TeamMemberLeft({
|
||||
required this.team,
|
||||
required this.agentId,
|
||||
required this.paneId,
|
||||
@@ -173,7 +173,7 @@ class TeamMemberDied extends ClideEvent {
|
||||
@override
|
||||
String get subsystem => 'team';
|
||||
@override
|
||||
String get kind => 'member-died';
|
||||
String get kind => 'member-left';
|
||||
@override
|
||||
Map<String, Object?> payload() => {'team': team, 'agentId': agentId, 'paneId': paneId};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user