agent-team-mail (atm)
agent-team-mail is the retained ATM CLI and daemon-backed runtime for local
ATM mailbox workflows.
This repository is now the source of truth for publishing:
agent-team-mail
agent-team-mail-core
The installed command remains atm.
What The Retained Line Includes
The retained release scope is the atm CLI plus the accepted same-host
daemon/SQLite runtime it bootstraps and talks to:
agent-team-mail — the atm CLI entrypoint
agent-team-mail-core — shared semantic and boundary code
atm-daemon — the retained same-host daemon runtime used by send, read,
ack, and doctor
This release line continues to consume the published sc-observability family
for retained logging and health reporting:
sc-observability
sc-observability-types
sc-observability-otlp
This repo does not publish the retired Claude-compatibility runtime, MCP, TUI,
or CI-monitor artifacts as part of the retained ATM surface.
Installation
GitHub Releases
Download the latest release from
GitHub Releases.
Published archives:
| Platform | Archive |
|---|
| Linux (x86_64) | atm__x86_64-unknown-linux-gnu.tar.gz |
| macOS (Intel) | atm__x86_64-apple-darwin.tar.gz |
| macOS (Apple Silicon) | atm__aarch64-apple-darwin.tar.gz |
| Windows (x86_64) | atm__x86_64-pc-windows-msvc.zip |
Extract the archive and place atm or atm.exe somewhere on your PATH.
Homebrew
brew tap randlee/tap
brew install randlee/tap/agent-team-mail
crates.io
cargo install agent-team-mail
The library crate is also published as:
cargo add agent-team-mail-core
winget
winget install randlee.agent-team-mail
winget is a new required 1.0 Windows channel rather than a historical
parity channel from the old repo. Public winget installability may lag by
1-2 days after release because Microsoft reviews new submissions and updates
before they become broadly visible.
Build From Source
git clone https://github.com/randlee/atm-core.git
cd atm-core
cargo install --path crates/atm --bin atm
Quick Start
ATM runs against the accepted ATM home/runtime layout and persists retained
mail state through the same-host daemon plus durable SQLite storage. Typical
flows:
Send a message
atm send teammate "Hello from ATM"
atm send teammate@other-team "Cross-team message"
atm send teammate "Please confirm" --requires-ack
Read your mailbox
atm read
atm peek --all
atm read --pending-ack-only
Acknowledge or clear messages
atm ack "Acknowledged"
atm clear
Inspect health and retained logs
atm doctor
atm log snapshot --level warn
Manage teams
atm teams
atm members my-team
atm teams add-member my-team teammate
atm teams backup my-team
atm teams restore my-team --from backup.tar.gz --dry-run
Run atm --help or atm --help for the full command surface.
CLI Surface
The retained CLI includes:
send
read
ack
clear
log
doctor
teams
members
The teams command also contains retained team-administration subcommands:
add-member
backup
restore
Configuration Notes
ATM resolves runtime identity and team context from the current CLI/config
surface and uses the accepted daemon/SQLite runtime for retained mail state.
Post-Send Hook
ATM ships one default post-send path for successful atm send and atm ack:
the built-in atm internal-nudge command. Most teams do not need any
.atm.toml hook configuration.
Use [[atm.post_send_hooks]] only for an explicit local override or
compatibility helper:
[[atm.post_send_hooks]]
recipient = "team-lead"
command = ["scripts/atm-nudge.sh", "team-lead"]
[[atm.post_send_hooks]]
recipient = "arch-ctm"
command = ["scripts/atm-nudge.sh", "arch-ctm"]
Behavior:
- If no matching external rule is configured, ATM falls back to the shipped
built-in
atm internal-nudge path.
- Each
[[atm.post_send_hooks]] rule binds one recipient and one command.
recipient matches either one exact member name or * for all recipients.
- Multiple matching rules all run, in config order.
- If
command[0] is path-like, ATM resolves it relative to the directory containing .atm.toml.
- Bare executables like
bash, python3, or tmux use normal PATH resolution.
- Recipient non-match is silent.
- ATM rejects retired
post_send_hook, post_send_hook_senders, post_send_hook_recipients, and post_send_hook_members keys with migration guidance.
- ATM sets
ATM_POST_SEND to a JSON payload with {from, to, sender, recipient, team, message_id, requires_ack} plus optional task_id when present.
- The hook gets 5 seconds to complete.
- Hook stderr is suppressed. Hook stdout may optionally return one JSON object with
level, message, and optional fields for ATM to log.
- For troubleshooting hook diagnostics, combine
--stderr-logs with ATM_LOG=debug to surface debug-level hook results on stderr.
- If the hook exits non-zero, fails to start, or times out,
atm send still succeeds and prints a warning.
Repo-local scripts/atm-nudge.sh / scripts/atm-nudge.py remain
compatibility-only helpers. They are not the shipped default.
Example ATM_POST_SEND payload:
{
"from": "team-lead@atm-dev",
"to": "arch-ctm@atm-dev",
"sender": "team-lead",
"recipient": "arch-ctm",
"team": "atm-dev",
"message_id": "01KWTMCQ418Q96BFRDTKGZMEAS",
"requires_ack": true
}
Example tmux auto-nudge hook for a Codex pane:
#!/usr/bin/env bash
set -euo pipefail
readarray -t fields < <(python3 - <<'PY'
import json, os
payload = json.loads(os.environ["ATM_POST_SEND"])
print(payload["to"].split("@", 1)[0])
print(payload["to"].split("@", 1)[1])
PY
)
recipient="${fields[0]}"
team="${fields[1]}"
tmux send-keys -t "$recipient" "You have unread ATM messages. Run: atm read --team $team" Enter
Optional structured hook result on stdout:
{"level":"debug","message":"arch-ctm nudged on pane %42","fields":{"pane_id":"%42"}}
Useful docs in this repo:
Development
Windows first-run prerequisites on a new machine:
- install Rust
1.94.1 with the MSVC toolchain
- install Visual Studio C++ build tools
- install
just (winget install Casey.Just)
- ensure
python resolves on PATH for repo scripts and helpers
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
Windows CI parity command:
$env:ATM_TEST_RECV_TIMEOUT_SECS="60"
cargo test --workspace --verbose