herdr-plugin-amq 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -268
- package/docs/architecture.md +50 -0
- package/docs/cli-and-workflows.md +72 -0
- package/docs/images/agmail-agent-activity.webp +0 -0
- package/docs/images/agmail-mobile-new-task.webp +0 -0
- package/docs/images/agmail-task-drawer.webp +0 -0
- package/docs/installation.md +70 -0
- package/docs/security-and-testing.md +33 -0
- package/docs/ui-screenshots.md +21 -0
- package/package.json +11 -5
- package/skills/herdr-amq/SKILL.md +4 -3
- package/src/actions.mjs +2 -2
- package/src/bridge.mjs +159 -53
- package/src/fleet.mjs +12 -10
- package/src/herdr.mjs +68 -14
- package/src/index.mjs +1 -0
- package/src/protocol.mjs +315 -67
- package/src/runtime-models.mjs +118 -0
- package/src/server.mjs +81 -37
- package/src/store.mjs +219 -34
- package/src/templates.mjs +118 -0
- package/src/web/app.js +487 -105
- package/src/web/index.html +130 -11
- package/src/web/style.css +1022 -39
package/README.md
CHANGED
|
@@ -3,305 +3,72 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/herdr-plugin-amq)
|
|
4
4
|
[](https://github.com/cabra-lat/herdr-plugin-amq/actions/workflows/ci.yml)
|
|
5
5
|
[](https://github.com/cabra-lat/herdr-plugin-amq/actions/workflows/security.yml)
|
|
6
|
-
[](https://github.com/cabra-lat/herdr-plugin-amq)
|
|
7
|
-
[](https://github.com/cabra-lat/herdr-plugin-amq)
|
|
8
6
|
[](https://opensource.org/licenses/MIT)
|
|
9
|
-
[](https://vibecoded.fyi/)
|
|
10
7
|
|
|
11
|
-
>
|
|
12
|
-
> Combines native pure-JS Maildir inter-agent messaging, an autonomous **Doorbell Bridge**, decentralized file-based task coordination, and the **AGmail** webmail dashboard.
|
|
8
|
+
> The asynchronous nervous system for autonomous AI agent swarms in [Herdr](https://herdr.dev/).
|
|
13
9
|
|
|
14
|
-
|
|
10
|
+
Herdr AMQ combines native pure-JS Maildir messaging, lifecycle-aware doorbells, a decentralized task bus, immutable CAS evidence, and the local-first **AGmail** dashboard.
|
|
15
11
|
|
|
16
|
-
##
|
|
12
|
+
## Why it exists
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
> — Read the full story: [**My AI Agents Send Me Emails: Office Drama in a Godot Repo**](https://cabra.pw/my-ai-agents-send-me-emails.html)
|
|
14
|
+
LLM agents are turn-based: when an agent finishes a response or tool sequence, it goes idle. A persistent inbox is useful, but it needs a doorbell. Herdr AMQ watches agent panes, wakes only idle or done agents with unread mail or assigned backlog work, and leaves working panes alone.
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
1. **Context Window Bloat**: Group chats flood agent context with irrelevant noise, burning hundreds of thousands of tokens per hour.
|
|
23
|
-
2. **Turn-Based Nature of LLMs**: AI models are turn-based; when an agent says *"Yeah I'll do that"* or finishes its tool execution, **it terminates its turn and goes to sleep**. It cannot run a busy-wait loop.
|
|
24
|
-
3. **Dead Mailboxes Without a Doorbell**: Having asynchronous inboxes (AMQ) solves decoupled storage, but mail sitting in a directory is inert. If an agent is asleep, incoming messages sit unread forever.
|
|
16
|
+
The result is an asynchronous workflow:
|
|
25
17
|
|
|
26
|
-
|
|
18
|
+
1. A coordinator or human sends a message or creates a task.
|
|
19
|
+
2. The bridge detects the unread item and checks the Herdr pane state.
|
|
20
|
+
3. An idle agent receives a precise drain/claim prompt.
|
|
21
|
+
4. The agent works in its isolated worktree and replies on the original thread.
|
|
22
|
+
5. AGmail provides a human view of messages, activity, tasks, and evidence.
|
|
27
23
|
|
|
28
|
-
|
|
24
|
+
## Documentation map
|
|
29
25
|
|
|
30
|
-
|
|
26
|
+
- [Architecture and live model reporting](docs/architecture.md)
|
|
27
|
+
- [Installation and Herdr setup](docs/installation.md)
|
|
28
|
+
- [CLI, fleet lifecycle, and templates](docs/cli-and-workflows.md)
|
|
29
|
+
- [Security and testing](docs/security-and-testing.md)
|
|
30
|
+
- [AGmail visual tour](docs/ui-screenshots.md)
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
flowchart TD
|
|
34
|
-
subgraph Storage ["Persistent Transport Layer"]
|
|
35
|
-
AMQ[".agent-mail/ (Maildir + RFC 5322)<br/>Decoupled Markdown Transmissions"]
|
|
36
|
-
BUS[".agent-mail/bus/ (Decentralized Task Cards)<br/>backlog/ → doing/ → blocked/ → done/"]
|
|
37
|
-
CAS[".agent-mail/blobs/ (CAS Blobstore)<br/>SHA-256 Render Strips & Proofs"]
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
subgraph Bridge ["The Autonomous Nervous System"]
|
|
41
|
-
DAEMON["Bridge Daemon (herdr-amq bridge-daemon)<br/>Watches mailboxes & checks Herdr agent states"]
|
|
42
|
-
DOORBELL{"Agent Status in Herdr?"}
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
subgraph Execution ["Herdr PTY / Terminal Swarm"]
|
|
46
|
-
H_BUSY["working → Leave alone (no spam)"]
|
|
47
|
-
H_BLOCKED["blocked → Alert coordinator / human"]
|
|
48
|
-
H_IDLE["idle / done → RING DOORBELL<br/>(herdr agent prompt)"]
|
|
49
|
-
AGENT["Awakened Agent<br/>1. herdr-amq drain --me <handle><br/>2. Executes task in isolated worktree<br/>3. herdr-amq send / reply --id ...<br/>4. Goes back to sleep"]
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
subgraph Oversight ["Human-in-the-Loop & Mission Control"]
|
|
53
|
-
AGMAIL["AGmail Webmail & Kanban Dashboard<br/>http://127.0.0.1:8505 (Strictly Local)"]
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
AMQ -->|New mail arrives| DAEMON
|
|
57
|
-
DAEMON --> DOORBELL
|
|
58
|
-
DOORBELL -->|working| H_BUSY
|
|
59
|
-
DOORBELL -->|blocked| H_BLOCKED
|
|
60
|
-
DOORBELL -->|idle/done| H_IDLE
|
|
61
|
-
H_IDLE --> AGENT
|
|
62
|
-
AGENT -->|Sends mail + CAS attachments| AMQ
|
|
63
|
-
AGENT -->|Claims / updates tasks| BUS
|
|
64
|
-
AGENT -->|Pins render artifacts| CAS
|
|
65
|
-
AMQ -.->|Monitored & inspected by| AGMAIL
|
|
66
|
-
BUS -.->|Rendered live in Kanban| AGMAIL
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## Key Features
|
|
72
|
-
|
|
73
|
-
### 1. The Autonomous Doorbell Bridge
|
|
74
|
-
- **Lifecycle-Aware Wakeups**: Rings doorbells (`herdr agent prompt`) only when agents are `idle` or `done`, preventing command interleaving during active turns.
|
|
75
|
-
- **Dual-Queue Wakeups (Mail & Tasks)**: Evaluates both unread Maildir messages and pending backlog tasks assigned to idle agents, prompting agents with specific drainage and claim actions.
|
|
76
|
-
- **De-duplication**: Tracks delivered message and task IDs in persistent state (`bridge-state.json`) so agents are never doorbelled twice for the same event.
|
|
77
|
-
- **Self-Healing Panes**: Automatically detects and renames desynced terminal titles back to their canonical agent handles (`herdr agent rename`).
|
|
78
|
-
- **Blocked State Alerts**: When an agent with unread mail is blocked on external input, logs actionable alert directives for human intervention.
|
|
79
|
-
|
|
80
|
-
### 2. Pure-JS Maildir & RFC 5322 Engine (Zero Runtime Dependencies)
|
|
81
|
-
- **100% Self-Contained ESM**: No external Go binary, Python scripts, or npm supply-chain dependencies required.
|
|
82
|
-
- **DJB Atomic Delivery**: Uses classic `tmp/` -> `new/` atomic filesystem renames to prevent partial reads or race conditions between concurrent agents.
|
|
83
|
-
- **RFC 5322 In-Reply-To & References**: Full thread tracking and conversation reconstruction from standard message headers.
|
|
84
|
-
|
|
85
|
-
### 3. AGmail Dashboard (Mission Control)
|
|
86
|
-
- **Authentic Webmail Interface**: Real folders (Inbox, Sent, Drafts, Starred, Trash) powered by live Maildir storage.
|
|
87
|
-
- **Rich Visual Attachment Cards**: Previews render strips, PNG contact sheets, and test output generated by headless tools (like Godot via VirtualGL) directly in email threads.
|
|
88
|
-
- **Interactive Kanban Board**: Visual task lane tracking (`backlog/`, `doing/`, `blocked/`, `done/`) with real-time SSE updates.
|
|
89
|
-
- **Human-in-the-Loop Interventions**: Compose and inject executive orders directly into the swarm's queue from your browser.
|
|
90
|
-
- **Fuzzy Search & Filtering**: Fast multi-attribute filtering (`from:spotter with-images:true kind:status`).
|
|
91
|
-
|
|
92
|
-
### 4. Git Worktree Isolation & Task Bus
|
|
93
|
-
- **Multi-Lane Isolation**: Automatically provisions and manages dedicated Git worktrees (`.worktrees/<agent>`) so parallel agents never step on each other's unstaged files.
|
|
94
|
-
- **Decentralized File-Based Task Cards**: Directory-based task bus (`.agent-mail/bus/`) immune to concurrent merge conflicts.
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## Requirements
|
|
99
|
-
|
|
100
|
-
- **Node.js** >= 18
|
|
101
|
-
- **[Herdr](https://herdr.dev/)** >= 0.7.0 *(Terminal workspace manager & agent lifecycle supervisor)*
|
|
102
|
-
- **Zero npm runtime dependencies**
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## Installation & Linking
|
|
107
|
-
|
|
108
|
-
Link the plugin into your local Herdr configuration:
|
|
32
|
+
## Quick start
|
|
109
33
|
|
|
110
34
|
```bash
|
|
111
|
-
|
|
112
|
-
cd herdr-plugin-amq
|
|
113
|
-
|
|
114
|
-
# Link into Herdr
|
|
35
|
+
npm ci --ignore-scripts
|
|
115
36
|
herdr plugin link .
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
Verify that the plugin and its actions are active:
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
herdr plugin list
|
|
122
|
-
herdr plugin action list --plugin cabra.amq
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## Herdr Actions & Keybindings
|
|
128
|
-
|
|
129
|
-
Add keybindings to `~/.config/herdr/config.toml` for instant access:
|
|
130
|
-
|
|
131
|
-
```toml
|
|
132
|
-
[[keys.command]]
|
|
133
|
-
key = "prefix+m"
|
|
134
|
-
type = "plugin_action"
|
|
135
|
-
command = "cabra.amq.bridge-status"
|
|
136
|
-
description = "Check AMQ mailbox status"
|
|
137
|
-
|
|
138
|
-
[[keys.command]]
|
|
139
|
-
key = "prefix+M"
|
|
140
|
-
type = "plugin_action"
|
|
141
|
-
command = "cabra.amq.doorbell-check"
|
|
142
|
-
description = "Ring AMQ doorbells for idle agents"
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### Available Plugin Actions
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
# Check queue status, active daemon, and unread mail per agent
|
|
149
|
-
herdr plugin action invoke cabra.amq.bridge-status
|
|
150
|
-
|
|
151
|
-
# Start background bridge daemon
|
|
152
|
-
herdr plugin action invoke cabra.amq.bridge-start
|
|
153
|
-
|
|
154
|
-
# Stop background bridge daemon
|
|
155
|
-
herdr plugin action invoke cabra.amq.bridge-stop
|
|
156
|
-
|
|
157
|
-
# Trigger an immediate one-shot doorbell check
|
|
158
|
-
herdr plugin action invoke cabra.amq.doorbell-check
|
|
159
|
-
|
|
160
|
-
# Launch the AGmail webmail dashboard
|
|
161
|
-
herdr plugin action invoke cabra.amq.open-dashboard
|
|
162
|
-
|
|
163
|
-
# Migrate legacy message attachments into immutable CAS blobs or pinned Git commits
|
|
164
|
-
herdr plugin action invoke cabra.amq.migrate
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Herdr Terminal Panes
|
|
168
|
-
|
|
169
|
-
Open modal terminal panes inside Herdr:
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
# Fast terminal inbox peek popup
|
|
173
|
-
herdr plugin pane open --plugin cabra.amq --entrypoint inbox-popup
|
|
174
|
-
|
|
175
|
-
# Dashboard server in dedicated pane
|
|
176
|
-
herdr plugin pane open --plugin cabra.amq --entrypoint dashboard
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
---
|
|
180
|
-
|
|
181
|
-
## CLI Reference (`herdr-amq`)
|
|
182
|
-
|
|
183
|
-
The plugin ships an executable CLI dispatcher (`bin/herdr-amq.mjs`) used by both agents and operators:
|
|
184
|
-
|
|
185
|
-
```bash
|
|
186
|
-
# Start AGmail webmail dashboard (default: http://127.0.0.1:8505)
|
|
37
|
+
herdr-amq bootstrap --kind opencode
|
|
187
38
|
herdr-amq dashboard
|
|
188
|
-
|
|
189
|
-
# Start the continuous bridge daemon
|
|
190
|
-
herdr-amq bridge-daemon
|
|
191
|
-
|
|
192
|
-
# Messaging
|
|
193
|
-
herdr-amq send --to spotter --subject "Check ADS alignment" --body @/tmp/prompt.txt
|
|
194
|
-
herdr-amq reply --id 20260922-120000-001@swarm --body "Approved. Commit with explicit pathspec."
|
|
195
|
-
herdr-amq drain --me coordinator
|
|
196
|
-
|
|
197
|
-
# Decentralized Kanban Task Bus
|
|
198
|
-
herdr-amq task list
|
|
199
|
-
herdr-amq task drain --me range
|
|
200
|
-
herdr-amq task next --me range
|
|
201
|
-
herdr-amq task claim TSK-402 --me worker-alpha
|
|
202
|
-
herdr-amq task done TSK-402 --proof "Proof of Sabotage: INV-29 passed with non-zero exit on mutation"
|
|
203
|
-
herdr-amq task block TSK-402 --reason "Waiting on asset import lock"
|
|
204
|
-
|
|
205
|
-
# Attachment Migration (historical CAS blob / Git pinning)
|
|
206
|
-
herdr-amq migrate [--dry-run] [--verbose]
|
|
207
|
-
|
|
208
|
-
# Fleet Discovery & Cold Start (unions .opencode, .agents, .pi, AGENTS.md)
|
|
209
|
-
herdr-amq fleet status
|
|
210
|
-
herdr-amq fleet prepopulate
|
|
211
|
-
herdr-amq fleet up [--kind agy|opencode|pi] [--agents a,b,c] [--dry-run]
|
|
212
|
-
|
|
213
|
-
# Instant One-Shot Swarm Cold-Start (prepopulate + launch + daemon + doorbell)
|
|
214
|
-
herdr-amq bootstrap [--kind agy]
|
|
215
|
-
|
|
216
|
-
# Print or install the agentic skill
|
|
217
|
-
herdr-amq --skill
|
|
218
|
-
herdr-amq --skill --install .opencode/skills/herdr-amq
|
|
219
39
|
```
|
|
220
40
|
|
|
221
|
-
|
|
41
|
+
The dashboard is local-only at `http://127.0.0.1:8505`. The CLI and agent protocol are documented in the [workflow guide](docs/cli-and-workflows.md).
|
|
222
42
|
|
|
223
|
-
##
|
|
43
|
+
## AGmail preview
|
|
224
44
|
|
|
225
|
-
|
|
45
|
+

|
|
226
46
|
|
|
227
|
-
|
|
228
|
-
Run a single command to discover external tool personas, provision isolated worktrees, and launch interactive agent sessions:
|
|
47
|
+
The activity card reports live harness state and the current model when Herdr/OpenCode exposes it. Profile configuration remains a fallback, with the source exposed in the API.
|
|
229
48
|
|
|
230
|
-
|
|
231
|
-
herdr-amq bootstrap [--kind agy|opencode|pi]
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
Under the hood, this pipeline automatically:
|
|
235
|
-
1. **Unifies Personas**: Scans `.opencode/agents/`, `.agents/`, `.pi/agents/`, `.claude/agents/`, rule declarations in `AGENTS.md` (e.g. `Handles: coordinator, ...`), and established `.worktrees/`.
|
|
236
|
-
2. **Prepopulates Storage & Worktrees**: Generates clean Maildir queues (`.agent-mail/agents/<handle>/`) and dedicated Git worktrees (`.worktrees/<handle>`) on `agent/<handle>`.
|
|
237
|
-
3. **Pre-authorizes Workspace Trust**: Injects worktree paths into `trustedWorkspaces` in `~/.gemini/antigravity-cli/settings.json` so `agy` bypasses interactive TUI trust confirmation dialogs.
|
|
238
|
-
4. **Environment Sanitation**: Seeds child PTYs with robust PATH resolution (`~/.local/bin`, Nix profiles) so agent CLIs and local binaries are found unconditionally.
|
|
239
|
-
5. **Supervised Lifecycle**: Launches Herdr terminal tabs with shell-boot backoff, starts the Doorbell Bridge daemon, and executes an initial doorbell pass.
|
|
240
|
-
|
|
241
|
-
### 2. Context Resilience (Do agents lose context on cold start?)
|
|
242
|
-
**No.** Context is completely decoupled from the terminal scrollback:
|
|
243
|
-
* **Persistent Transmissions**: All messages, decisions, reviews, and CAS/Git attachments live as RFC 5322 markdown files in `.agent-mail/`.
|
|
244
|
-
* **Decentralized Task Bus**: Tasks live in `.agent-mail/bus/{backlog,doing,blocked,done}/`.
|
|
245
|
-
* **Code Branch Isolation**: Staged and uncommitted edits remain intact in `.worktrees/<handle>` on the agent's branch.
|
|
246
|
-
* **Turn-Based Epistolary Execution**: When an agent wakes up, it drains its inbox (`herdr-amq mail drain --me <handle>`), reads its assigned task card, inspects `git status`, and resumes work without relying on monolithic LLM chat memory.
|
|
247
|
-
|
|
248
|
-
---
|
|
49
|
+

|
|
249
50
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
AI coding agents (Antigravity, Claude Code, OpenCode, Aider) can consume the skill definition directly to learn the protocol without human instruction:
|
|
253
|
-
|
|
254
|
-
```bash
|
|
255
|
-
# Output full YAML-frontmattered SKILL.md
|
|
256
|
-
herdr-amq --skill
|
|
257
|
-
|
|
258
|
-
# Auto-install directly into your workspace
|
|
259
|
-
herdr-amq --skill --install .opencode/skills/herdr-amq/SKILL.md
|
|
260
|
-
```
|
|
51
|
+
The compact mobile task form keeps its owner warning and action row visible at narrow widths.
|
|
261
52
|
|
|
262
|
-
|
|
53
|
+

|
|
263
54
|
|
|
264
|
-
##
|
|
265
|
-
|
|
266
|
-
> [!CAUTION]
|
|
267
|
-
> **The AGmail dashboard and AMQ bridge are strictly local development tools.**
|
|
268
|
-
> Because agent communications contain source code, system prompts, execution logs, and orchestration commands, **this interface must never be exposed to public networks, WANs, or untrusted LANs.**
|
|
269
|
-
|
|
270
|
-
By design, `herdr-plugin-amq` implements strict defense-in-depth protections verified by continuous red-team exploit tests:
|
|
271
|
-
|
|
272
|
-
* **Exclusive Loopback Binding**: The HTTP server strictly binds to `127.0.0.1` IPv4 loopback (dropping non-local external TCP requests at the OS level).
|
|
273
|
-
* **DNS Rebinding Protection**: Inspects the HTTP `Host` header on every request. Any foreign domain (e.g. `attacker.com` pointing to 127.0.0.1) receives immediate `403 Forbidden`.
|
|
274
|
-
* **Null-Byte Injection Neutralization**: Any request containing `%00` or `\0` is blocked with `403 Forbidden`.
|
|
275
|
-
* **Mandatory Security Headers**: Injected on all HTTP responses:
|
|
276
|
-
- `X-Content-Type-Options: nosniff` (prevents MIME-type confusion attacks)
|
|
277
|
-
- `X-Frame-Options: DENY` (anti-clickjacking)
|
|
278
|
-
- `Referrer-Policy: no-referrer` (prevents URL leakage)
|
|
279
|
-
- `Content-Security-Policy: frame-ancestors 'none';`
|
|
280
|
-
* **Path Traversal Jailing**: Strict `isPathSafe` resolution disallows reading outside authorized workspace/scratch trees and strictly forbids access to `.ssh`, `.env`, `/etc/passwd`, credentials, or `.git/config`.
|
|
281
|
-
|
|
282
|
-
---
|
|
55
|
+
## Requirements
|
|
283
56
|
|
|
284
|
-
|
|
57
|
+
- Node.js >= 18
|
|
58
|
+
- Herdr >= 0.7.0
|
|
59
|
+
- Chrome/Chromium for browser journeys only
|
|
60
|
+
- Zero npm runtime dependencies
|
|
285
61
|
|
|
286
|
-
|
|
62
|
+
## Verification
|
|
287
63
|
|
|
288
64
|
```bash
|
|
289
|
-
# Run 95 automated unit, integration, simulation & security tests
|
|
290
65
|
npm test
|
|
291
|
-
|
|
292
|
-
# Run red-team security penetration audit suite
|
|
293
|
-
npm run test:security
|
|
294
|
-
|
|
295
|
-
# Run tests with experimental coverage reporting (80%+ lines and functions)
|
|
296
|
-
npm run test:coverage
|
|
297
|
-
|
|
298
|
-
# Validate JavaScript module syntax across all files
|
|
66
|
+
npm run test:e2e
|
|
299
67
|
npm run check
|
|
68
|
+
npm audit --audit-level=high
|
|
300
69
|
```
|
|
301
70
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
---
|
|
71
|
+
The browser suite uses an isolated Maildir, board, and fake Herdr socket, so screenshots and tests never touch the live swarm.
|
|
305
72
|
|
|
306
73
|
## License
|
|
307
74
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
Herdr AMQ is the coordination layer between turn-based coding agents and a human operator. It keeps transport, task state, and oversight separate so a sleeping agent can be woken without sharing a chat context.
|
|
4
|
+
|
|
5
|
+
## Why the bridge exists
|
|
6
|
+
|
|
7
|
+
Synchronous group chat does not fit autonomous coding sessions:
|
|
8
|
+
|
|
9
|
+
1. Group messages consume context with irrelevant activity.
|
|
10
|
+
2. An agent turn ends after a response or tool sequence; it cannot busy-wait for the next instruction.
|
|
11
|
+
3. A Maildir inbox preserves messages, but an idle agent needs a lifecycle-aware wakeup.
|
|
12
|
+
|
|
13
|
+
AMQ provides persistent Maildir messages, a file-based task bus, and immutable CAS attachments. The bridge watches Herdr panes and prompts only agents that are `idle` or `done`. Working panes are left alone; blocked panes raise an actionable alert.
|
|
14
|
+
|
|
15
|
+
## Data flow
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
flowchart TD
|
|
19
|
+
AMQ[".agent-mail/ Maildir messages"] --> BRIDGE["Bridge daemon"]
|
|
20
|
+
BUS[".agent-mail/bus/ task cards"] --> BRIDGE
|
|
21
|
+
BRIDGE --> STATUS{"Herdr pane state"}
|
|
22
|
+
STATUS -->|working| IDLE["Leave pane alone"]
|
|
23
|
+
STATUS -->|blocked| ALERT["Alert coordinator"]
|
|
24
|
+
STATUS -->|idle or done| DOORBELL["herdr agent prompt"]
|
|
25
|
+
DOORBELL --> WAKE["Agent drains mail and tasks"]
|
|
26
|
+
WAKE --> AMQ
|
|
27
|
+
WAKE --> BUS
|
|
28
|
+
AMQ --> DASH["AGmail dashboard"]
|
|
29
|
+
BUS --> DASH
|
|
30
|
+
WAKE --> CAS[".agent-mail/blobs/ CAS evidence"]
|
|
31
|
+
CAS --> DASH
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Components
|
|
35
|
+
|
|
36
|
+
| Component | Responsibility |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `src/bridge.mjs` | Lifecycle-aware Maildir/task doorbells, deduplication, blocked alerts |
|
|
39
|
+
| `src/herdr.mjs` | Herdr socket snapshot/events and live pane activity |
|
|
40
|
+
| `src/runtime-models.mjs` | Best-effort live model lookup from harness metadata and OpenCode sessions |
|
|
41
|
+
| `src/store.mjs` | Maildir parsing, profiles, attachments, and agent discovery |
|
|
42
|
+
| `src/board.mjs` | Backlog, claimed, blocked, and done task cards |
|
|
43
|
+
| `src/server.mjs` | Loopback API, SSE updates, and AGmail static assets |
|
|
44
|
+
| `src/web/` | Responsive webmail, activity sheet, and Kanban UI |
|
|
45
|
+
|
|
46
|
+
## Live model reporting
|
|
47
|
+
|
|
48
|
+
The profile model is configuration metadata, not proof of the model currently selected by a running harness. When Herdr exposes model fields, AGmail uses them first. For OpenCode panes, the Herdr `agent_session.value` is resolved against the local OpenCode session database and rendered as `provider/model (variant)`. The API also returns `modelSource` so the UI and operators can distinguish live harness data from a profile fallback.
|
|
49
|
+
|
|
50
|
+
The resolver is best-effort: unavailable Herdr/OpenCode data leaves the configured profile visible rather than inventing a model.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# CLI and workflows
|
|
2
|
+
|
|
3
|
+
`herdr-amq` is the executable dispatcher in `bin/herdr-amq.mjs`. It is usable from an agent shell, a Herdr pane, or a human operator session.
|
|
4
|
+
|
|
5
|
+
## Core commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
herdr-amq dashboard
|
|
9
|
+
herdr-amq bridge-daemon
|
|
10
|
+
herdr-amq status
|
|
11
|
+
|
|
12
|
+
herdr-amq send --to spotter --subject "Check ADS alignment" --body @/tmp/prompt.txt
|
|
13
|
+
herdr-amq reply --id <message-id> --body "Reply on the original thread"
|
|
14
|
+
herdr-amq drain --me coordinator --include-body
|
|
15
|
+
|
|
16
|
+
herdr-amq task list
|
|
17
|
+
herdr-amq task drain --me <handle>
|
|
18
|
+
herdr-amq task next --me <handle>
|
|
19
|
+
herdr-amq task claim <task-id> --me <handle>
|
|
20
|
+
herdr-amq task done <task-id> --proof "Verification evidence"
|
|
21
|
+
herdr-amq task block <task-id> --reason "Waiting on an external dependency"
|
|
22
|
+
|
|
23
|
+
herdr-amq migrate [--dry-run] [--verbose]
|
|
24
|
+
herdr-amq --skill
|
|
25
|
+
herdr-amq --skill --install .opencode/skills/herdr-amq/SKILL.md
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Mail messages use Maildir delivery and RFC 5322 threading headers. Attachments are stored through the CAS blobstore or pinned to a Git object when migrating historical files.
|
|
29
|
+
|
|
30
|
+
## Fleet lifecycle
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
herdr-amq fleet status
|
|
34
|
+
herdr-amq fleet prepopulate
|
|
35
|
+
herdr-amq fleet up --kind opencode --agents coordinator,range,qa
|
|
36
|
+
herdr-amq bootstrap --kind opencode
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Bootstrap discovers supported persona directories and worktrees, provisions Maildirs, delivers first-registration welcomes, prepares isolated worktrees, starts the bridge daemon, and performs an initial doorbell pass.
|
|
40
|
+
|
|
41
|
+
## Local prompt templates
|
|
42
|
+
|
|
43
|
+
Optional files customize local policy:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
.agent-mail/templates/welcome.md
|
|
47
|
+
.agent-mail/templates/doorbell.md
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Templates support scalar substitutions only. The doorbell always appends the required drain/claim actions and conditional-reply guidance, so a template cannot disable delivery or make an unrequested reply.
|
|
51
|
+
|
|
52
|
+
Supported doorbell variables:
|
|
53
|
+
|
|
54
|
+
| Variable | Meaning |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `agent.handle` | Recipient handle |
|
|
57
|
+
| `mail.count` | Unread message count |
|
|
58
|
+
| `mail.senders` | Sanitized sender list |
|
|
59
|
+
| `board.backlog` | Assigned backlog count |
|
|
60
|
+
| `board.blocked` | Assigned blocked count |
|
|
61
|
+
| `board.doing` | Assigned in-progress count |
|
|
62
|
+
| `board.done` | Assigned completed count |
|
|
63
|
+
| `board.total` | Total board cards |
|
|
64
|
+
|
|
65
|
+
## Agent skill
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
herdr-amq --skill
|
|
69
|
+
herdr-amq --skill --install .opencode/skills/herdr-amq/SKILL.md
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The skill teaches an agent to drain first, claim before editing, preserve threads on replies, and include proof when completing a card.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Installation and Herdr setup
|
|
2
|
+
|
|
3
|
+
## Requirements
|
|
4
|
+
|
|
5
|
+
- Node.js 18 or newer
|
|
6
|
+
- Herdr 0.7.0 or newer
|
|
7
|
+
- A repository with a `.agent-mail` queue, or run fleet bootstrap to create one
|
|
8
|
+
- Chrome/Chromium only for the optional browser journeys
|
|
9
|
+
|
|
10
|
+
The runtime has no npm production dependencies. `playwright-core` is a development-only dependency for the browser suite.
|
|
11
|
+
|
|
12
|
+
## Link the plugin
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
git clone https://github.com/cabra-lat/herdr-plugin-amq.git herdr-plugin-amq
|
|
16
|
+
cd herdr-plugin-amq
|
|
17
|
+
herdr plugin link .
|
|
18
|
+
herdr plugin list
|
|
19
|
+
herdr plugin action list --plugin cabra.amq
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The dashboard and queue root are discovered from the current workspace. The web server binds to `127.0.0.1` and refuses foreign `Host` headers.
|
|
23
|
+
|
|
24
|
+
## Herdr actions
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
herdr plugin action invoke cabra.amq.bridge-status
|
|
28
|
+
herdr plugin action invoke cabra.amq.bridge-start
|
|
29
|
+
herdr plugin action invoke cabra.amq.bridge-stop
|
|
30
|
+
herdr plugin action invoke cabra.amq.doorbell-check
|
|
31
|
+
herdr plugin action invoke cabra.amq.open-dashboard
|
|
32
|
+
herdr plugin action invoke cabra.amq.migrate
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Example keybindings for `~/.config/herdr/config.toml`:
|
|
36
|
+
|
|
37
|
+
```toml
|
|
38
|
+
[[keys.command]]
|
|
39
|
+
key = "prefix+m"
|
|
40
|
+
type = "plugin_action"
|
|
41
|
+
command = "cabra.amq.bridge-status"
|
|
42
|
+
description = "Check AMQ mailbox status"
|
|
43
|
+
|
|
44
|
+
[[keys.command]]
|
|
45
|
+
key = "prefix+M"
|
|
46
|
+
type = "plugin_action"
|
|
47
|
+
command = "cabra.amq.doorbell-check"
|
|
48
|
+
description = "Ring AMQ doorbells for idle agents"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Panes
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
herdr plugin pane open --plugin cabra.amq --entrypoint inbox-popup
|
|
55
|
+
herdr plugin pane open --plugin cabra.amq --entrypoint dashboard
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The dashboard entrypoint is also available as `herdr-amq dashboard` and defaults to `http://127.0.0.1:8505`.
|
|
59
|
+
|
|
60
|
+
## Browser verification
|
|
61
|
+
|
|
62
|
+
The browser suite uses an isolated Maildir, board, and fake Herdr socket. It never reads or writes the live swarm.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm ci --ignore-scripts
|
|
66
|
+
CHROMIUM_BIN="$(command -v chromium)" npm run test:e2e
|
|
67
|
+
E2E_ARTIFACT_DIR="$PWD/artifacts/e2e" CHROMIUM_BIN="$(command -v chromium)" npm run test:e2e
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The suite covers desktop, 390×844 mobile, and 320×568 compact journeys, including the activity sheet, task drawer, sticky message header, pull-to-refresh guard, and New Task action visibility. Screenshots and `report.json` are written under `artifacts/e2e/`.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Security and testing
|
|
2
|
+
|
|
3
|
+
## Threat model
|
|
4
|
+
|
|
5
|
+
AGmail and the AMQ bridge are strictly local development tools. Agent communications can contain source code, prompts, logs, and execution commands, so the dashboard must not be exposed to a WAN or untrusted LAN.
|
|
6
|
+
|
|
7
|
+
The server applies:
|
|
8
|
+
|
|
9
|
+
- Loopback-only binding
|
|
10
|
+
- DNS-rebinding protection through `Host` validation
|
|
11
|
+
- Null-byte request rejection
|
|
12
|
+
- `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`, and CSP headers
|
|
13
|
+
- Path-traversal and credential-path denial
|
|
14
|
+
- Bounded, symlink-rejected local prompt templates
|
|
15
|
+
- No-store headers for dashboard HTML, JavaScript, and CSS
|
|
16
|
+
|
|
17
|
+
Do not place secrets in profiles, briefs, prompt templates, task descriptions, or screenshots.
|
|
18
|
+
|
|
19
|
+
## Test layers
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm test
|
|
23
|
+
npm run test:security
|
|
24
|
+
npm run test:coverage
|
|
25
|
+
npm run check
|
|
26
|
+
npm run test:e2e
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`npm test` runs the native unit, integration, simulation, registration-security, and red-team suites. `npm run test:e2e` uses a temporary queue and fake Herdr socket, then captures desktop/mobile journeys without touching live mailboxes.
|
|
30
|
+
|
|
31
|
+
## Definition of done
|
|
32
|
+
|
|
33
|
+
A change is ready when syntax, unit/integration tests, browser journeys, audit, and diff checks pass. Report skipped or unavailable gates explicitly; do not turn a missing signal into a pass.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# AGmail visual tour
|
|
2
|
+
|
|
3
|
+
These captures come from the isolated browser fixture. They contain no live mailbox data and are checked by the desktop/mobile journey suite.
|
|
4
|
+
|
|
5
|
+
## Agent activity
|
|
6
|
+
|
|
7
|
+
The activity sheet combines the live Herdr state, assigned task, unread count, pane ID, and the model reported by the running harness. The model is sourced from Herdr/OpenCode session metadata when available, rather than blindly displaying the profile fallback.
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Task dossier
|
|
12
|
+
|
|
13
|
+
The task drawer keeps the stage controls, owner, linked AMQ thread, transmissions, and dispatch composer together while preserving the board context behind the drawer.
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
## Compact New Task flow
|
|
18
|
+
|
|
19
|
+
At 320×568, the owner tip and sticky action row remain visible. The form warns before assigning a card to an owner with claimed or blocked work.
|
|
20
|
+
|
|
21
|
+

|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "herdr-plugin-amq",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Herdr plugin for AMQ (Agent Message Queue) autonomous bridge, status monitoring, and AGmail dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.mjs",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"bin/",
|
|
12
12
|
"src/",
|
|
13
13
|
"skills/",
|
|
14
|
+
"docs/",
|
|
14
15
|
"herdr-plugin.toml",
|
|
15
16
|
"README.md",
|
|
16
17
|
"LICENSE"
|
|
@@ -19,9 +20,11 @@
|
|
|
19
20
|
"node": ">=18.0.0"
|
|
20
21
|
},
|
|
21
22
|
"scripts": {
|
|
22
|
-
"test": "node --test test/*.test.mjs",
|
|
23
|
-
"test:coverage": "mkdir -p coverage && node --test --experimental-test-coverage --test-reporter=spec --test-reporter=lcov --test-reporter-destination=stdout --test-reporter-destination=coverage/lcov.info test/*.test.mjs",
|
|
24
|
-
"
|
|
23
|
+
"test": "HERDR_DISABLE_PROMPT=1 node --test test/*.test.mjs",
|
|
24
|
+
"test:coverage": "mkdir -p coverage && HERDR_DISABLE_PROMPT=1 node --test --experimental-test-coverage --test-reporter=spec --test-reporter=lcov --test-reporter-destination=stdout --test-reporter-destination=coverage/lcov.info test/*.test.mjs",
|
|
25
|
+
"test:e2e": "HERDR_DISABLE_PROMPT=1 node --test test/e2e/*.test.mjs",
|
|
26
|
+
"test:visual": "npm run test:e2e",
|
|
27
|
+
"check": "node --check bin/herdr-amq.mjs src/*.mjs src/web/app.js test/*.test.mjs test/e2e/*.mjs",
|
|
25
28
|
"test:security": "node --test test/security.test.mjs",
|
|
26
29
|
"coverage:summary": "node tools/coverage-summary.mjs",
|
|
27
30
|
"status": "node bin/herdr-amq.mjs status",
|
|
@@ -46,5 +49,8 @@
|
|
|
46
49
|
"agmail"
|
|
47
50
|
],
|
|
48
51
|
"author": "cabra.lat",
|
|
49
|
-
"license": "MIT"
|
|
52
|
+
"license": "MIT",
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"playwright-core": "1.48.2"
|
|
55
|
+
}
|
|
50
56
|
}
|