Agent teams for Ryu — a persisted, named, ordered collection of agents plus a coordination strategy, addressed as one unit via @team.
The public home of
ryu-teams. Source, builds, and releases live here — binaries for every platform are attached to each release.This tree is generated from the Ryu monorepo, so commits pushed here directly are replaced on the next sync. Pull requests are welcome — open them here and they are ported into the monorepo, then flow back out. Ryu as a whole: https://github.com/amajorai/ryu
- Binary:
ryu-teamsfrom the Ryu releases. - Crate:
cargo install ryu-teams.
Apache-2.0 — see LICENSE.
Agent teams: a persisted, named, ordered collection of agents plus a coordination
strategy, addressable as one unit (@team in chat) so a single message fans out to every
member.
backend/(ryu-teams) — an extracted Core capability crate: the SQLiteTeamStore(agent-id membership only) and the/api/teams/*HTTP surface. The surface is now served OUT-OF-PROCESS by theryu-teamssidecar bin (below) via the manifestpublic_mount— there is no in-processteams_routesmerge and noteamscargo feature. The crate stays a non-optional path-dep only for the@teamchat types the session loop consumes (see the weld below), not for the moved surface. This crate has zero dependency onapps/core: its only cross-cutting need — the data-dir path — is injected by the host atTeamStore::open.backend/src/main.rs(ryu-teamsbin) — the same crate also builds a standalone out-of-process sidecar ([[bin]] name = "ryu-teams"): a loopback axum server that opens the node'steams.db, nests the crate'sroutes()under/api/teams, and gates every route with the Core-injectedRYU_EXT_TOKENbearer (fail-closed;/healthis the one un-gated probe). It reuses the crate lib, so nothing is duplicated. Core spawns it via thekind: localsidecar spec in@ryu/teams(RYU_TEAMS_BIN/RYU_TEAMS_PORT, default:7994) and proxies/api/teams/*to it — exactly likeryu-mail.- No companion UI. Teams surface through Core's own Library/desktop pages; there is no
ui/here. @teamchat orchestration stays in Core. The fan-out is welded to Core's streaming session loop (apps/core/src/sidecar/adapters/mod.rs), which consumes this crate'sTeamRecord/Coordinationtypes. That coupling is inseparable from the chat kernel, so — unlike quests/clips/meetings — there is noTeamsHosttrait: nothing in the moved store + CRUD surface reaches back into Core.
- id
@ryu/teams, no runnables, nopermission_grants. It is a governance shell over the in-crate store — no documents, no external dependencies. - contributes three
hook_events—team.created,team.updated,team.deleted— raised fromapi.rsviaryu-app-eventsso hooks and workflows can react to a roster change without polling. The HTTP surface is the right place to raise them because the sidecar ownsteams.dboutright: Core reaches it over loopback (teams_client.rs), so every mutation, including its ownagent_builder's, passes through those handlers once.
/api/teams (list/create) · per-team :id · :id/members and :id/members/:agent_id
(membership edits). Types: TeamRecord, Coordination, CreateTeam, UpdateTeam.
Membership is agent-id references only, so any agent card can join any team; the coordination strategy is a stored enum, not hardcoded behavior.