agent-team-mail 1.0.1

Daemon-free CLI for local agent team mail workflows.
agent-team-mail-1.0.1 is not a library.

agent-team-mail (atm)

agent-team-mail is the retained 1.0 CLI and core library 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 1.0 Includes

The retained 1.0 release scope is the daemon-free CLI/core pair:

  • agent-team-mail — the atm CLI
  • agent-team-mail-core — the core Rust library used by the CLI

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 legacy daemon, MCP, TUI, or CI-monitor artifacts as part of the retained 1.0 surface.

Installation

GitHub Releases

Download the latest release from GitHub Releases.

Published archives:

Platform Archive
Linux (x86_64) atm_<version>_x86_64-unknown-linux-gnu.tar.gz
macOS (Intel) atm_<version>_x86_64-apple-darwin.tar.gz
macOS (Apple Silicon) atm_<version>_aarch64-apple-darwin.tar.gz
Windows (x86_64) atm_<version>_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 works against the local Claude team mailbox layout under ~/.claude/teams. 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 read --all --no-mark
atm read --pending-ack-only

Acknowledge or clear messages

atm ack <message-id> "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 <command> --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 local Claude team directory layout for mailbox storage.

Post-Send Hook

atm send can run an optional post-send hook configured in .atm.toml:

[atm]
post_send_hook = ["scripts/tmux-nudge.sh", "--team", "atm-dev"]
post_send_hook_senders = ["team-lead"]
post_send_hook_recipients = ["arch-ctm", "*"]

Behavior:

  • post_send_hook is a command argv array. If the first entry is a relative path, ATM resolves it relative to the directory containing .atm.toml.
  • post_send_hook_senders matches the resolved sender identity.
  • post_send_hook_recipients matches the resolved recipient agent name.
  • Omitted or empty sender/recipient lists do not match on that axis.
  • * in either list matches all senders or all recipients unconditionally.
  • If both sender and recipient lists are omitted or empty, the hook is effectively disabled and ATM does not emit a skip warning for that case.
  • The hook runs once if either sender or recipient matching succeeds.
  • ATM rejects retired post_send_hook_members with a migration error.
  • ATM sets ATM_POST_SEND to a JSON payload with {from, to, message_id, requires_ack, hook_match} 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.

Example ATM_POST_SEND payload:

{
  "from": "team-lead@atm-dev",
  "to": "arch-ctm@atm-dev",
  "message_id": "550e8400-e29b-41d4-a716-446655440000",
  "requires_ack": true,
  "hook_match": {
    "sender": false,
    "recipient": 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

cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace