feat(agents): team updates on Matrix, with a sign-in, rate-limited post script and a skill #2606

Merged
hckrman101 merged 1 commit from agents/team-updates into main 2026-11-12 03:18:05 +00:00
hckrman101 commented 2026-11-12 01:37:40 +00:00 (Migrated from github.com)

Agents working on Hookshot have no shared place to say what they claimed, found or opened, so two of them can fix the same thing without knowing. This adds a team room on Matrix (#agent-updates:magicbean.dev) that agents sign in to with Discord and post to sparingly, and that people read too. Each post is also copied to Discord #dev-agents under the poster's Discord name.

How it works for a contributor

  1. You ask your agent to enable auto updates (/team-updates in Claude Code, or just "turn on team updates").
  2. It sends you to sign in on git.magicbean.dev with Discord. That's the only thing you do; the first time creates your account.
  3. From then on, it posts to the channel on its own: a check about once an hour that posts only when something happened (a claim, a finding, a PR, a blocker, finished work), and never "still working" or "no updates". You can also ask it to post an update, or to stop, at any time.

What changed

  • scripts/team_chat.py (standard library only, Windows and Linux): login, whoami, status, read, post, logout.
    • login signs in with Discord through the server's single sign-on: it prints the link, and the browser comes back to a one-time listener on 127.0.0.1. --access-token-stdin takes a token from Element instead.
    • The session is saved outside the repo (~/.config/hookshot/team_chat.json, %APPDATA%\Hookshot\team_chat.json), mode 600.
    • post sends at most one message an hour (configurable) and never the same text twice. It exits 3 with the reason otherwise. --force skips the hour, for when the person asked for an update. Posts carry a 🤖 prefix so readers can tell agents from people.
    • read prints the room's latest messages, so agents check others' claims before claiming.
  • .claude/skills/team-updates/SKILL.md (/team-updates in Claude Code, plain steps for other agents): guided setup, what is worth posting (claims, findings, PRs, blockers, finished work) and what isn't ("still working", "no updates"), message format, and hourly updates as a recurring check (/loop 60m /team-updates) that only posts when something happened. It repeats the rule about game files.
  • AGENTS.md: a short Team updates section. docs/workflow.md: the room in Where work comes from and in For agents.

Testing

  • tests/test_team_chat.py runs the whole flow against a stand-in homeserver on 127.0.0.1: the sign-on redirect to the listener, session file permissions, joining the room once, the prefix, the hourly refusal, --force, the repeat refusal (also with --force), the configurable interval, read order, a revoked session and logout.

  • tests/test_team_chat.py passes in CI on Linux and Windows. The other red Python checks and appimage fail the same way on main (8568959, Game-free source regressions and Linux AppImage), not from this PR.

  • Against the live server (matrix.magicbean.dev, behind Cloudflare): login --access-token-stdin, whoami, status and read work. That run found that Cloudflare answers 403 to urllib's default Python-urllib User-Agent, so the script now sends its own, and the test checks every request does.

  • End to end, live, from this branch, as a contributor would: login printed the link, I signed in with Discord through git.magicbean.dev, and the tab came back to the script, which saved the session (mode 600). post went to #agent-updates (exit 0). A second post right after was refused with exit 3 and "next can go out in 60 minutes". read shows the post, and it reached Discord #dev-agents under my Discord name and avatar a few seconds later.

Not tested

Windows: the script uses only the standard library and the test runs in CI on Windows, but nobody has run the browser login there yet.

Agents working on Hookshot have no shared place to say what they claimed, found or opened, so two of them can fix the same thing without knowing. This adds a team room on Matrix (`#agent-updates:magicbean.dev`) that agents sign in to with Discord and post to sparingly, and that people read too. Each post is also copied to Discord #dev-agents under the poster's Discord name. ## How it works for a contributor 1. **You ask your agent to enable auto updates** (`/team-updates` in Claude Code, or just "turn on team updates"). 2. **It sends you to sign in on git.magicbean.dev with Discord.** That's the only thing you do; the first time creates your account. 3. **From then on, it posts to the channel on its own**: a check about once an hour that posts only when something happened (a claim, a finding, a PR, a blocker, finished work), and never "still working" or "no updates". You can also ask it to post an update, or to stop, at any time. ## What changed - **`scripts/team_chat.py`** (standard library only, Windows and Linux): `login`, `whoami`, `status`, `read`, `post`, `logout`. - `login` signs in with Discord through the server's single sign-on: it prints the link, and the browser comes back to a one-time listener on 127.0.0.1. `--access-token-stdin` takes a token from Element instead. - The session is saved outside the repo (`~/.config/hookshot/team_chat.json`, `%APPDATA%\Hookshot\team_chat.json`), mode 600. - `post` sends **at most one message an hour** (configurable) and never the same text twice. It exits 3 with the reason otherwise. `--force` skips the hour, for when the person asked for an update. Posts carry a 🤖 prefix so readers can tell agents from people. - `read` prints the room's latest messages, so agents check others' claims before claiming. - **`.claude/skills/team-updates/SKILL.md`** (`/team-updates` in Claude Code, plain steps for other agents): guided setup, what is worth posting (claims, findings, PRs, blockers, finished work) and what isn't ("still working", "no updates"), message format, and hourly updates as a recurring check (`/loop 60m /team-updates`) that only posts when something happened. It repeats the rule about game files. - **`AGENTS.md`**: a short *Team updates* section. **`docs/workflow.md`**: the room in *Where work comes from* and in *For agents*. ## Testing - `tests/test_team_chat.py` runs the whole flow against a stand-in homeserver on 127.0.0.1: the sign-on redirect to the listener, session file permissions, joining the room once, the prefix, the hourly refusal, `--force`, the repeat refusal (also with `--force`), the configurable interval, `read` order, a revoked session and logout. - `tests/test_team_chat.py` passes in CI on Linux and Windows. The other red Python checks and `appimage` fail the same way on `main` (8568959, *Game-free source regressions* and *Linux AppImage*), not from this PR. - Against the live server (`matrix.magicbean.dev`, behind Cloudflare): `login --access-token-stdin`, `whoami`, `status` and `read` work. That run found that Cloudflare answers 403 to urllib's default `Python-urllib` User-Agent, so the script now sends its own, and the test checks every request does. - **End to end, live**, from this branch, as a contributor would: `login` printed the link, I signed in with Discord through git.magicbean.dev, and the tab came back to the script, which saved the session (mode 600). `post` went to `#agent-updates` (exit 0). A second `post` right after was refused with exit 3 and "next can go out in 60 minutes". `read` shows the post, and it reached Discord #dev-agents under my Discord name and avatar a few seconds later. ## Not tested Windows: the script uses only the standard library and the test runs in CI on Windows, but nobody has run the browser login there yet.
Commenting is not possible because the repository is archived.
No description provided.