add the team chat inbox over the broker

Renders broker traffic as a chat timeline and makes the user a first-class
participant. The broker grows a Stream<TeamMessage> and a recipient field,
auto-registers a virtual `user` member, and gains sendAsUser. A Flutter-free
TeamChatModel (owned by the orchestrator) accumulates the feed and exposes
postAsUser with @-routing (a new at_commands helper mirroring slash) and an
optional interrupt that cancels the target's turn before delivery. One model
backs two surfaces: a compact cockpit widget that pops out into a full
workspace chat pane. CLI parity via clide.team-chat.open / .post.

T-180.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-05-31 10:49:04 +02:00
co-authored by Claude
parent e3c0b0146b
commit a0636c2e5a
17 changed files with 1656 additions and 31 deletions
@@ -261,7 +261,9 @@ void main() {
memberName: 'tyre',
));
expect(orch.sessions, hasLength(2));
expect(orch.broker.members, hasLength(2));
// Broker has 2 agent members + 1 virtual 'user' member (T-180).
final agentMembers = orch.broker.members.where((m) => m.id != 'user');
expect(agentMembers, hasLength(2));
final ids = orch.sessions.map((m) => m.id).toList();
for (final id in ids) {
@@ -269,7 +271,9 @@ void main() {
}
expect(orch.sessions, isEmpty);
expect(orch.broker.members, isEmpty);
// Only the virtual 'user' member remains after closing all sessions.
final agentMembersAfter = orch.broker.members.where((m) => m.id != 'user');
expect(agentMembersAfter, isEmpty);
});
});
}