add tmux team observer + member lifecycle events (T-139, D-75)
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 24s
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 24s
team_observer.dart is the single drift-containment point for Claude Code's experimental tmux team mode. It discovers the active team for a workspace (~/.claude/teams/<team>/config.json, matched by member cwd), polls `tmux -L clide list-panes -a`, and correlates live panes with the config's tmuxPaneId to emit TeamMemberBorn / TeamMemberDied — identity (name, agentType, model, colour, pane) comes from the config, so it's reliable regardless of transcript drift. Each teammate's subagent transcript is resolved best-effort and streamed on a per-agent MessageBus channel via TranscriptPublisher (TranscriptReader gains an explicit `file:` for this). The config<->transcript join is the fragile part: no shared key, so it uses a sibling .meta.json agentType when present, else zips members-by-joinedAt against files-by-mtime. This join needs validation against a live team run. App wiring + visible surfacing land with the teammate tiles (T-140). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -718,6 +718,31 @@ void main() {
|
||||
'reply number 199',
|
||||
);
|
||||
});
|
||||
|
||||
test('explicit file: tails that exact file, ignoring newest-discovery', () async {
|
||||
// A teammate reader (T-139) points at one fixed subagent file rather
|
||||
// than the newest .jsonl in the munged dir.
|
||||
final dir = await Directory.systemTemp.createTemp('explicit_file_');
|
||||
addTearDown(() => dir.delete(recursive: true));
|
||||
final target = File('${dir.path}/agent-abc.jsonl');
|
||||
writeLines(target, [assistantText('a1', 'from the explicit file')]);
|
||||
|
||||
final reader = TranscriptReader(
|
||||
'/unused/workspace',
|
||||
projectsBase: '/nonexistent',
|
||||
pollInterval: const Duration(milliseconds: 20),
|
||||
file: target.path,
|
||||
);
|
||||
final collected = <ConversationItem>[];
|
||||
final sub = reader.stream.listen(collected.add);
|
||||
|
||||
await pumpUntil(() => collected.isNotEmpty);
|
||||
|
||||
await sub.cancel();
|
||||
await reader.dispose();
|
||||
|
||||
expect(collected.whereType<AssistantTextMessage>().single.text, 'from the explicit file');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user