agent-notify sends compact completion notifications for coding agents.
Current support:
- Agents: Codex, Claude Code, Kimi Code
- Channel: Telegram
- Distribution target: one small Go binary, no runtime dependencies
The default message is intentionally small: host, directory, time, the first sentence of the prompt, and the agent's final reply. Git repository, branch, and duration are included only when the agent exposes enough local context to determine them. Field labels include emoji for readability. It does not send diffs, command output, or logs.
Install the latest Linux/macOS release:
curl -fsSL https://raw.githubusercontent.com/hxy91819/agent-notify/main/scripts/install-release.sh | bashThis installs agent-notify to ~/.local/bin/agent-notify and configures both
Codex and Claude Code hooks. Use --setup codex, --setup claude,
--setup kimi, --setup all, or --setup none when you want a different
install scope.
Build and install from this checkout:
bash scripts/install.shThen follow the prompts for your Telegram bot token and chat id. To let
agent-notify read the latest chat id from Telegram after you message your
bot:
TELEGRAM_BOT_TOKEN=123456:example bash scripts/install-release.sh --auto-chat-id --testIf you already know both values:
TELEGRAM_BOT_TOKEN=123456:example TELEGRAM_CHAT_ID=123456789 bash scripts/install-release.sh --testCodex or Claude Code may ask you to review and trust the new hooks in /hooks
the next time you start a session.
go build -o agent-notify ./cmd/agent-notify
./agent-notify --helpManual setup:
./agent-notify setup codex-telegram \
--bot-token "$TELEGRAM_BOT_TOKEN" \
--chat-id "$TELEGRAM_CHAT_ID" \
--bin "$(pwd)/agent-notify" \
--testClaude Code setup:
./agent-notify setup claude-telegram \
--bot-token "$TELEGRAM_BOT_TOKEN" \
--chat-id "$TELEGRAM_CHAT_ID" \
--bin "$(pwd)/agent-notify" \
--testKimi Code setup:
./agent-notify setup kimi-telegram \
--bot-token "$TELEGRAM_BOT_TOKEN" \
--chat-id "$TELEGRAM_CHAT_ID" \
--bin "$(pwd)/agent-notify" \
--testThis writes:
~/.config/agent-notify/config.json~/.codex/hooks.json~/.claude/settings.json~/.kimi-code/config.toml
Existing Codex, Claude Code, and Kimi Code hooks are preserved. Installed hook
commands include absolute --config, --state-file, and --log-file paths so
they do not depend on the environment variables available inside a running
agent session.
GitHub Releases publish prebuilt archives for:
linux_amd64linux_arm64darwin_amd64darwin_arm64
Each release includes checksums.txt for SHA-256 verification. Manual install:
tar -xzf agent-notify_v0.1.0_linux_amd64.tar.gz
install -m 755 agent-notify_v0.1.0_linux_amd64/agent-notify ~/.local/bin/agent-notify
agent-notify setup codex-telegram
agent-notify setup claude-telegram
agent-notify setup kimi-telegramRemove installed hooks without touching unrelated hooks:
agent-notify setup remove-hooks --agent codex
agent-notify setup remove-hooks --agent claude
agent-notify setup remove-hooks --agent kimi
agent-notify setup remove-hooks --agent both
agent-notify setup remove-hooks --agent allOn macOS, if the downloaded binary is quarantined:
xattr -d com.apple.quarantine ~/.local/bin/agent-notifyThe bot token identifies the bot. The chat id identifies where the bot should send messages.
- Open Telegram and send your bot a message.
- Run:
agent-notify setup codex-telegram --bot-token "$TELEGRAM_BOT_TOKEN" --auto-chat-id
agent-notify setup claude-telegram --bot-token "$TELEGRAM_BOT_TOKEN" --auto-chat-id
agent-notify setup kimi-telegram --bot-token "$TELEGRAM_BOT_TOKEN" --auto-chat-idFor group notifications, add the bot to the group, send a group message, and
then use --auto-chat-id. Group chat ids are often negative.
agent-notify setup codex-telegram --help
agent-notify setup claude-telegram --help
agent-notify setup kimi-telegram --help
agent-notify setup remove-hooks --agent codex
agent-notify telegram test --dry-run
agent-notify telegram test
agent-notify codex cache < user-prompt-submit.json
agent-notify codex notify --dry-run < stop.json
agent-notify claude cache < user-prompt-submit.json
agent-notify claude notify --dry-run < stop.json
agent-notify kimi cache < user-prompt-submit.json
agent-notify kimi notify --dry-run < stop.jsonAgent hook commands are designed to be non-blocking. Invalid hook JSON, missing Telegram config, or Telegram network failures are logged as warnings and exit successfully so the coding agent can finish normally.
Message fields:
Repo: git remote repository name, only when the current directory is in a git repository.Branch: current git branch ordetached@<sha>, only when available.Duration: elapsed time between agentUserPromptSubmitandStophooks, only when the start hook was captured.Result:last_assistant_message, capped bymax_result_chars.
Hook diagnostics are written to:
~/.local/state/agent-notify/hook.log
Default config path:
~/.config/agent-notify/config.json
Example:
{
"telegram": {
"bot_token": "123456:example",
"chat_id": "123456789"
},
"defaults": {
"max_prompt_chars": 120,
"max_result_chars": 200,
"timezone": "Asia/Shanghai"
}
}Environment variables override the file:
TELEGRAM_BOT_TOKENTELEGRAM_CHAT_ID
For migration, agent-notify also reads the earlier prototype file
~/.codex/telegram-notify.env when present.
go test ./...
go build -o agent-notify ./cmd/agent-notify
golangci-lint run
bash scripts/lint-static.shscripts/lint-static.sh protects project-specific invariants that generic Go
linters cannot infer, such as absolute hook paths, agent-scoped state keys, and
safe stale-lock recovery.
Optional local git hooks:
cp scripts/hooks/secret-scan.sh .git/hooks/pre-commit
cp scripts/hooks/secret-scan.sh .git/hooks/pre-push
chmod +x .git/hooks/pre-commit .git/hooks/pre-pushThe hook scans staged content before commit and tracked HEAD content before
push for common credentials such as Telegram bot tokens, API keys, GitHub
tokens, private keys, and sensitive env/config file paths.
The earlier Python prototype is kept under examples/codex-python-hook/ as a
reference implementation. The supported CLI is the Go binary.
Simulate Codex hooks:
tmpdir=$(mktemp -d)
printf '%s\n' '{"telegram":{"bot_token":"dummy","chat_id":"123"},"defaults":{"max_prompt_chars":80,"timezone":"Asia/Shanghai"}}' > "$tmpdir/config.json"
printf '%s\n' '{"hook_event_name":"UserPromptSubmit","cwd":"/tmp/project","prompt":"First sentence. Second sentence.","session_id":"s1","turn_id":"t1"}' \
| ./agent-notify codex cache --config "$tmpdir/config.json" --state-file "$tmpdir/state.json"
printf '%s\n' '{"hook_event_name":"Stop","cwd":"/tmp/project","session_id":"s1","turn_id":"t1"}' \
| ./agent-notify codex notify --config "$tmpdir/config.json" --state-file "$tmpdir/state.json" --dry-runSimulate Claude Code hooks by replacing codex with claude in the two
commands above.
MIT