Hermes notification toolkit — bus message sender, tmux notifier
Project description
hermes-notify
Role in the Hermes messaging ecosystem: hermes-notify is the CLI sender layer — two commands (notify-hermes, notify-agent) for injecting messages into the ecosystem. It sends; it does not receive or process. The other two packages in the ecosystem are:
- hermes-bus — transport daemon that routes JSON messages between endpoints via Unix Socket
- hermes-bus-plugin — receive-side agent plugin that consumes bus messages and routes them to terminal output, LLM context injection, or command execution
Together: notify → bus → plugin. Route rules live in ~/.hermes/bus-rules.yaml.
Hermes Messaging Ecosystem
The ecosystem has four layers:
Layer 1 — CLI / User Space (this package)
notify-hermes ──→ hermes-bus (Unix Socket)
notify-agent ──→ tmux session (send-keys)
Layer 2 — Transport
hermes-bus daemon — JSON routing, session management
Layer 3 — Agent / Plugin
hermes-bus-plugin — print · context · command · channel routing
Layer 4 — Gateway / Platform
Platform adapters — WeChat · Feishu · WeCom · DingTalk → Users
| Layer | Package | Role |
|---|---|---|
| 1 — CLI | hermes-notify (this package) | Send messages into the ecosystem |
| 2 — Transport | hermes-bus | Route JSON messages between endpoints |
| 3 — Plugin | hermes-bus-plugin | Consume messages: terminal output, LLM context, commands, channel routing |
| 4 — Gateway | (downstream) | Platform adapters deliver replies to end users. Zero agent code changes |
Install
pip install hermes-notify
Or from source:
git clone https://github.com/mlinquan/hermes-notify.git
cd hermes-notify && pip install -e .
notify-hermes — Send Through the Bus
Sends a JSON message to any bus endpoint via short-lived Unix Socket connection (hermes_bus.client.send_message). The message is routed by the bus daemon to the target endpoint. Route processing (print, context injection, command execution) is handled by hermes-bus-plugin on the receiving end.
Syntax
notify-hermes --to <endpoint> [options] "message text"
notify-hermes --to <endpoint> --body '{"text":"hello","key":"value"}'
Parameters
| Argument | Required | Default | Description |
|---|---|---|---|
--to |
yes | — | Target bus endpoint name (e.g. lead-agent, hermes-bus, worker-alpha) |
"message" |
* | — | Plain text message (positional, last argument). Mutually exclusive with --body |
--body |
* | — | Full JSON body dict as a string. Mutually exclusive with positional message |
--type |
no | none | Application-level message type (see table below) |
--channel |
no | none | Reply routing token: platform:chat_id or platform (falls back to *_HOME_CHANNEL env var) |
--from |
no | auto | Override sender name. Auto-detected from tmux session via role_map in bus-rules.yaml |
--socket |
no | auto | Custom Unix socket path. Default: $HERMES_HOME/hermes-bus.sock |
--config |
no | auto | Path to bus-rules.yaml. Default: $HERMES_HOME/bus-rules.yaml |
* Either "message" or --body is required, but not both.
--type values
The values below are common conventions —
--typeaccepts any string,bus-rules.yamlmatches them exactly.
--type |
Meaning | Receiver behavior (via bus-rules.yaml) |
|---|---|---|
directive |
Task assignment (coordinator → worker) | context=true (silent injection) |
ack |
Acknowledgement | print=true (terminal only) |
task_start |
Task started | context=true |
progress |
Intermediate progress update | context=true |
task_done |
Task completed | print=true + context=true + command (audio + gateway-forward) |
plan_ready |
Plan ready for review | print=true + context=true + command |
task_error |
Error / escalation | print=true + context=true + command |
need_decision |
Decision needed | print=true + context=true + command |
--channel values
| Value | Resolves to |
|---|---|
feishu:oc_abc123 |
Feishu, chat oc_abc123 directly |
wecom:ww456 |
WeCom, chat ww456 directly |
dingtalk:cid789 |
DingTalk, chat cid789 directly |
feishu |
Feishu, fallback to FEISHU_HOME_CHANNEL env var |
wecom |
WeCom, fallback to WECOM_HOME_CHANNEL env var |
The channel token is an opaque routing string. Agents pass it through unmodified. Only the bus-plugin at final delivery acts on it.
Message body assembly
When using "message text" (positional):
{"text": "message text", "type": "task_done", "channel": "feishu:oc_abc123"}
When using --body:
{"text": "hello", "type": "ack", "custom_field": "value"}
--type and --channel are merged into the body dict. --body takes precedence for fields it already defines.
Examples
# Simple acknowledgement
notify-hermes --to lead-agent --type ack "Received, starting work"
# Task completion with channel for reply routing
notify-hermes --to lead-agent --type task_done \
--channel feishu:oc_abc123 \
"Auth middleware refactor complete. 5/5 endpoints migrated."
# Progress update (silent — context injection only, no terminal noise)
notify-hermes --to lead-agent --type progress \
--channel feishu:oc_abc123 \
"Phase 2 of 4: extracted token validation module"
# Error escalation with channel
notify-hermes --to lead-agent --type task_error \
--channel wecom_ops \
"Production outage detected — database connection pool exhausted"
# Full JSON body for custom payloads
notify-hermes --to lead-agent \
--body '{"text":"Deploy complete","type":"task_done","version":"2.1.0","commit":"abc123"}'
# Custom sender name override
notify-hermes --to lead-agent --type ack --from ci-pipeline "Build #142 passed"
notify-agent — Send to a tmux Session
Sends text directly to a tmux session via send-keys. Does NOT go through the bus. Used for direct inter-agent communication within the same machine.
Syntax
notify-agent [--from SENDER] <tmux-session-name> "message text"
Parameters
| Argument | Required | Description |
|---|---|---|
<session> |
yes | Target tmux session name (the name passed to tmux new-session -s). This is NOT a bus endpoint or agent name |
--from |
no | Sender display name. Auto-detected from session name if omitted |
"message" |
yes | Plain text message (positional, last argument) |
Examples
# Start two agent sessions
tmux new-session -d -s lead-agent 'claude'
tmux new-session -d -s worker-alpha 'claude'
# Send a message
notify-agent lead-agent "Task queue is empty, ready for next assignment"
# With explicit sender
notify-agent --from worker-alpha lead-agent "Build complete, 3 tests passing"
Important: The target must be a running tmux session. Use notify-hermes for bus-routed messages that can be processed by hermes-bus-plugin.
Configuration
Route rules, role mappings, and sender auto-detection are configured in ~/.hermes/bus-rules.yaml. See hermes-bus-plugin for the full rule format.
Role mapping (for --from auto-detection)
# bus-rules.yaml
role_map:
lead-agent: {name: "Lead", color: "bold_cyan"}
worker-alpha: {name: "Alpha", color: "bold_yellow"}
worker-beta: {name: "Beta", color: "bold_magenta"}
unknown: {name: "Unknown", color: "white"}
default_sender: notify-agent
When --from is omitted, notify-hermes reads the current tmux session name, looks it up in role_map, and uses the mapped name as the sender.
Skill Registration
When installed as a Hermes plugin, hermes-notify registers the notify-cli skill — agents can discover CLI notification tools (notify-hermes, notify-agent) via snow_search without reading source code or man pages.
Quickstart
# 1. Install all three packages
pip install hermes-bus hermes-notify hermes-bus-plugin
# 2. Start the bus daemon
hermes-busd start
# 3. Start agent sessions
tmux new-session -d -s lead-agent 'claude'
tmux new-session -d -s worker-alpha 'claude'
# 4. Send messages
notify-hermes --to lead-agent --type ack "Hello from worker-alpha"
notify-agent --from worker-alpha lead-agent "Direct message, no bus"
# 5. Check bus status
hermes-busd status
Architecture
notify-hermes ──→ hermes-bus (Unix Socket) ──→ hermes-bus-plugin (agent)
notify-agent ──→ tmux send-keys ──→ target session terminal
Message routing (print / context injection / command execution)
is handled by hermes-bus-plugin via ~/.hermes/bus-rules.yaml.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hermes_notify-0.5.0.tar.gz.
File metadata
- Download URL: hermes_notify-0.5.0.tar.gz
- Upload date:
- Size: 8.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e54b37e3ed4c3905e4332d1cd02154ef2051c30b73ca0f3bd861903c394de1b6
|
|
| MD5 |
abf60dff094b01409348dd7e3f6291b3
|
|
| BLAKE2b-256 |
79c92788fdb078ba8916b960bc028ac49893a49bc64c237683408d4410c1d2f8
|
File details
Details for the file hermes_notify-0.5.0-py3-none-any.whl.
File metadata
- Download URL: hermes_notify-0.5.0-py3-none-any.whl
- Upload date:
- Size: 8.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e32ea2e23fe5b5d9514762f972d191a7f8e7a82773a4655ba11ebea031487534
|
|
| MD5 |
f201fde05177ec1ed5c03dde8ddf2c2c
|
|
| BLAKE2b-256 |
a821fc981acedf3c6168cb76985f16c863164611a885870d6214a41213b49fe9
|