herdr-plugin-amq 0.1.7 → 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 CHANGED
@@ -3,302 +3,72 @@
3
3
  [![npm version](https://img.shields.io/npm/v/herdr-plugin-amq.svg)](https://www.npmjs.com/package/herdr-plugin-amq)
4
4
  [![CI](https://github.com/cabra-lat/herdr-plugin-amq/actions/workflows/ci.yml/badge.svg)](https://github.com/cabra-lat/herdr-plugin-amq/actions/workflows/ci.yml)
5
5
  [![Security](https://github.com/cabra-lat/herdr-plugin-amq/actions/workflows/security.yml/badge.svg)](https://github.com/cabra-lat/herdr-plugin-amq/actions/workflows/security.yml)
6
- [![Tests](https://img.shields.io/badge/tests-95%20passing-brightgreen.svg)](https://github.com/cabra-lat/herdr-plugin-amq)
7
- [![Coverage](https://img.shields.io/badge/coverage-80%25-brightgreen.svg)](https://github.com/cabra-lat/herdr-plugin-amq)
8
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
- [![Proudly Vibe Coded - Plasma Mix](https://vibecoded.fyi/badges/flat/main/proudly-vibe-coded-plasma-mix.svg)](https://vibecoded.fyi/)
10
7
 
11
- > **The asynchronous nervous system for autonomous AI agent swarms in [Herdr](https://herdr.dev/).**
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
- ## The Origin & The Problem
12
+ ## Why it exists
17
13
 
18
- > *"If you follow AI news, you have probably seen endless hype around 'multi-agent swarms' talking to each other... That is cute for a 30-second screen recording. In a real codebase with actual physics, compiler errors, and Git history, it is a complete disaster."*
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
- When coordinating swarms of AI coding agents across complex codebases, synchronous chat rooms and blocking `wait` loops fall apart:
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
- ### The Missing Piece: The Doorbell Bridge
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
- This plugin bridges **AMQ** (the persistent storage) and **Herdr** (the terminal multiplexer and agent lifecycle supervisor).
24
+ ## Documentation map
29
25
 
30
- The **Bridge Daemon** continuously inspects agent inboxes. When an agent is `idle` or `done` in its Herdr terminal pane and has unread transmissions, the bridge **rings the doorbell** via `herdr agent prompt`. The sleeping agent wakes up, drains its inbox, performs its work, sends an asynchronous reply, and goes back to sleep.
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
- ```mermaid
33
- flowchart TD
34
- subgraph Storage ["Persistent Transport Layer"]
35
- AMQ[".agent-mail/ (Maildir + RFC 5322)<br/>Decoupled Markdown Transmissions"]
36
- BUS[".opencode/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
- - **De-duplication**: Tracks delivered message IDs in persistent state (`bridge-state.json`) so agents are never doorbelled twice for the same mail.
76
- - **Self-Healing Panes**: Automatically detects and renames desynced terminal titles back to their canonical agent handles (`herdr agent rename`).
77
- - **Blocked State Alerts**: When an agent with unread mail is blocked on external input, logs actionable alert directives for human intervention.
78
-
79
- ### 2. Pure-JS Maildir & RFC 5322 Engine (Zero Runtime Dependencies)
80
- - **100% Self-Contained ESM**: No external Go binary, Python scripts, or npm supply-chain dependencies required.
81
- - **DJB Atomic Delivery**: Uses classic `tmp/` -> `new/` atomic filesystem renames to prevent partial reads or race conditions between concurrent agents.
82
- - **RFC 5322 In-Reply-To & References**: Full thread tracking and conversation reconstruction from standard message headers.
83
-
84
- ### 3. AGmail Dashboard (Mission Control)
85
- - **Authentic Webmail Interface**: Real folders (Inbox, Sent, Drafts, Starred, Trash) powered by live Maildir storage.
86
- - **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.
87
- - **Interactive Kanban Board**: Visual task lane tracking (`backlog/`, `doing/`, `blocked/`, `done/`) with real-time SSE updates.
88
- - **Human-in-the-Loop Interventions**: Compose and inject executive orders directly into the swarm's queue from your browser.
89
- - **Fuzzy Search & Filtering**: Fast multi-attribute filtering (`from:spotter with-images:true kind:status`).
90
-
91
- ### 4. Git Worktree Isolation & Task Bus
92
- - **Multi-Lane Isolation**: Automatically provisions and manages dedicated Git worktrees (`.worktrees/<agent>`) so parallel agents never step on each other's unstaged files.
93
- - **Decentralized File-Based Task Cards**: Directory-based task bus (`.opencode/bus/`) immune to concurrent merge conflicts.
94
-
95
- ---
96
-
97
- ## Requirements
98
-
99
- - **Node.js** >= 18
100
- - **[Herdr](https://herdr.dev/)** >= 0.7.0 *(Terminal workspace manager & agent lifecycle supervisor)*
101
- - **Zero npm runtime dependencies**
102
-
103
- ---
104
-
105
- ## Installation & Linking
106
-
107
- Link the plugin into your local Herdr configuration:
32
+ ## Quick start
108
33
 
109
34
  ```bash
110
- # Clone or navigate to the repository
111
- cd herdr-plugin-amq
112
-
113
- # Link into Herdr
35
+ npm ci --ignore-scripts
114
36
  herdr plugin link .
115
- ```
116
-
117
- Verify that the plugin and its actions are active:
118
-
119
- ```bash
120
- herdr plugin list
121
- herdr plugin action list --plugin cabra.amq
122
- ```
123
-
124
- ---
125
-
126
- ## Herdr Actions & Keybindings
127
-
128
- Add keybindings to `~/.config/herdr/config.toml` for instant access:
129
-
130
- ```toml
131
- [[keys.command]]
132
- key = "prefix+m"
133
- type = "plugin_action"
134
- command = "cabra.amq.bridge-status"
135
- description = "Check AMQ mailbox status"
136
-
137
- [[keys.command]]
138
- key = "prefix+M"
139
- type = "plugin_action"
140
- command = "cabra.amq.doorbell-check"
141
- description = "Ring AMQ doorbells for idle agents"
142
- ```
143
-
144
- ### Available Plugin Actions
145
-
146
- ```bash
147
- # Check queue status, active daemon, and unread mail per agent
148
- herdr plugin action invoke cabra.amq.bridge-status
149
-
150
- # Start background bridge daemon
151
- herdr plugin action invoke cabra.amq.bridge-start
152
-
153
- # Stop background bridge daemon
154
- herdr plugin action invoke cabra.amq.bridge-stop
155
-
156
- # Trigger an immediate one-shot doorbell check
157
- herdr plugin action invoke cabra.amq.doorbell-check
158
-
159
- # Launch the AGmail webmail dashboard
160
- herdr plugin action invoke cabra.amq.open-dashboard
161
-
162
- # Migrate legacy message attachments into immutable CAS blobs or pinned Git commits
163
- herdr plugin action invoke cabra.amq.migrate
164
- ```
165
-
166
- ### Herdr Terminal Panes
167
-
168
- Open modal terminal panes inside Herdr:
169
-
170
- ```bash
171
- # Fast terminal inbox peek popup
172
- herdr plugin pane open --plugin cabra.amq --entrypoint inbox-popup
173
-
174
- # Dashboard server in dedicated pane
175
- herdr plugin pane open --plugin cabra.amq --entrypoint dashboard
176
- ```
177
-
178
- ---
179
-
180
- ## CLI Reference (`herdr-amq`)
181
-
182
- The plugin ships an executable CLI dispatcher (`bin/herdr-amq.mjs`) used by both agents and operators:
183
-
184
- ```bash
185
- # Start AGmail webmail dashboard (default: http://127.0.0.1:8505)
37
+ herdr-amq bootstrap --kind opencode
186
38
  herdr-amq dashboard
187
-
188
- # Start the continuous bridge daemon
189
- herdr-amq bridge-daemon
190
-
191
- # Messaging
192
- herdr-amq send --to spotter --subject "Check ADS alignment" --body @/tmp/prompt.txt
193
- herdr-amq reply --id 20260922-120000-001@swarm --body "Approved. Commit with explicit pathspec."
194
- herdr-amq drain --me coordinator
195
-
196
- # Decentralized Kanban Task Bus
197
- herdr-amq task list
198
- herdr-amq task claim TSK-402 --me worker-alpha
199
- herdr-amq task done TSK-402 --proof "Proof of Sabotage: INV-29 passed with non-zero exit on mutation"
200
- herdr-amq task block TSK-402 --reason "Waiting on asset import lock"
201
-
202
- # Attachment Migration (historical CAS blob / Git pinning)
203
- herdr-amq migrate [--dry-run] [--verbose]
204
-
205
- # Fleet Discovery & Cold Start (unions .opencode, .agents, .pi, AGENTS.md)
206
- herdr-amq fleet status
207
- herdr-amq fleet prepopulate
208
- herdr-amq fleet up [--kind agy|opencode|pi] [--agents a,b,c] [--dry-run]
209
-
210
- # Instant One-Shot Swarm Cold-Start (prepopulate + launch + daemon + doorbell)
211
- herdr-amq bootstrap [--kind agy]
212
-
213
- # Print or install the agentic skill
214
- herdr-amq --skill
215
- herdr-amq --skill --install .opencode/skills/herdr-amq
216
39
  ```
217
40
 
218
- ---
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).
219
42
 
220
- ## Onboarding & Swarm Cold Start
43
+ ## AGmail preview
221
44
 
222
- When onboarding a new repository or recovering after all Herdr panes were lost (e.g. machine reboot or closed panes):
45
+ ![AGmail agent activity sheet](docs/images/agmail-agent-activity.webp)
223
46
 
224
- ### 1. Instant Automated Bootstrap
225
- 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.
226
48
 
227
- ```bash
228
- herdr-amq bootstrap [--kind agy|opencode|pi]
229
- ```
230
-
231
- Under the hood, this pipeline automatically:
232
- 1. **Unifies Personas**: Scans `.opencode/agents/`, `.agents/`, `.pi/agents/`, `.claude/agents/`, rule declarations in `AGENTS.md` (e.g. `Handles: coordinator, ...`), and established `.worktrees/`.
233
- 2. **Prepopulates Storage & Worktrees**: Generates clean Maildir queues (`.agent-mail/agents/<handle>/`) and dedicated Git worktrees (`.worktrees/<handle>`) on `agent/<handle>`.
234
- 3. **Pre-authorizes Workspace Trust**: Injects worktree paths into `trustedWorkspaces` in `~/.gemini/antigravity-cli/settings.json` so `agy` bypasses interactive TUI trust confirmation dialogs.
235
- 4. **Environment Sanitation**: Seeds child PTYs with robust PATH resolution (`~/.local/bin`, Nix profiles) so agent CLIs and local binaries are found unconditionally.
236
- 5. **Supervised Lifecycle**: Launches Herdr terminal tabs with shell-boot backoff, starts the Doorbell Bridge daemon, and executes an initial doorbell pass.
237
-
238
- ### 2. Context Resilience (Do agents lose context on cold start?)
239
- **No.** Context is completely decoupled from the terminal scrollback:
240
- * **Persistent Transmissions**: All messages, decisions, reviews, and CAS/Git attachments live as RFC 5322 markdown files in `.agent-mail/`.
241
- * **Decentralized Task Bus**: Tasks live in `.opencode/bus/{backlog,doing,blocked,done}/`.
242
- * **Code Branch Isolation**: Staged and uncommitted edits remain intact in `.worktrees/<handle>` on the agent's branch.
243
- * **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.
244
-
245
- ---
49
+ ![AGmail task dossier](docs/images/agmail-task-drawer.webp)
246
50
 
247
- ## Agentic Skill Integration
248
-
249
- AI coding agents (Antigravity, Claude Code, OpenCode, Aider) can consume the skill definition directly to learn the protocol without human instruction:
250
-
251
- ```bash
252
- # Output full YAML-frontmattered SKILL.md
253
- herdr-amq --skill
254
-
255
- # Auto-install directly into your workspace
256
- herdr-amq --skill --install .opencode/skills/herdr-amq/SKILL.md
257
- ```
51
+ The compact mobile task form keeps its owner warning and action row visible at narrow widths.
258
52
 
259
- ---
53
+ ![Compact AGmail New Task form](docs/images/agmail-mobile-new-task.webp)
260
54
 
261
- ## Security & Threat Model (Strictly Local-Only)
262
-
263
- > [!CAUTION]
264
- > **The AGmail dashboard and AMQ bridge are strictly local development tools.**
265
- > 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.**
266
-
267
- By design, `herdr-plugin-amq` implements strict defense-in-depth protections verified by continuous red-team exploit tests:
268
-
269
- * **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).
270
- * **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`.
271
- * **Null-Byte Injection Neutralization**: Any request containing `%00` or `\0` is blocked with `403 Forbidden`.
272
- * **Mandatory Security Headers**: Injected on all HTTP responses:
273
- - `X-Content-Type-Options: nosniff` (prevents MIME-type confusion attacks)
274
- - `X-Frame-Options: DENY` (anti-clickjacking)
275
- - `Referrer-Policy: no-referrer` (prevents URL leakage)
276
- - `Content-Security-Policy: frame-ancestors 'none';`
277
- * **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`.
278
-
279
- ---
55
+ ## Requirements
280
56
 
281
- ## Testing & Quality Assurance
57
+ - Node.js >= 18
58
+ - Herdr >= 0.7.0
59
+ - Chrome/Chromium for browser journeys only
60
+ - Zero npm runtime dependencies
282
61
 
283
- Our test suite adheres to high-rigor standards with zero external test runners:
62
+ ## Verification
284
63
 
285
64
  ```bash
286
- # Run 95 automated unit, integration, simulation & security tests
287
65
  npm test
288
-
289
- # Run red-team security penetration audit suite
290
- npm run test:security
291
-
292
- # Run tests with experimental coverage reporting (80%+ lines and functions)
293
- npm run test:coverage
294
-
295
- # Validate JavaScript module syntax across all files
66
+ npm run test:e2e
296
67
  npm run check
68
+ npm audit --audit-level=high
297
69
  ```
298
70
 
299
- Automated GitHub Actions CI validates compatibility across **Node 18.x, 20.x, and 22.x** on both **Ubuntu** and **macOS**, alongside a dedicated **Security Compliance & Red-Team Audit** workflow.
300
-
301
- ---
71
+ The browser suite uses an isolated Maildir, board, and fake Herdr socket, so screenshots and tests never touch the live swarm.
302
72
 
303
73
  ## License
304
74
 
package/bin/herdr-amq.mjs CHANGED
@@ -53,6 +53,12 @@ switch (cmd) {
53
53
  case "board":
54
54
  handleTaskCommand(process.argv[3], process.argv.slice(4));
55
55
  break;
56
+ case "next":
57
+ handleTaskCommand("next", process.argv.slice(3));
58
+ break;
59
+ case "task-drain":
60
+ handleTaskCommand("drain", process.argv.slice(3));
61
+ break;
56
62
  case "mail":
57
63
  handleMailCommand(process.argv[3], process.argv.slice(4));
58
64
  break;
@@ -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.
@@ -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
+ ![AGmail agent activity sheet showing live task, pane, and harness model](images/agmail-agent-activity.webp)
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
+ ![AGmail task dossier with linked transmissions and dispatch controls](images/agmail-task-drawer.webp)
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
+ ![Compact mobile New Task form with visible Cancel and Create Task actions](images/agmail-mobile-new-task.webp)
package/herdr-plugin.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  id = "cabra.amq"
2
2
  name = "Herdr AMQ"
3
- version = "0.1.7"
3
+ version = "0.1.8"
4
4
  min_herdr_version = "0.7.0"
5
5
  description = "Agent Message Queue (AMQ) bridge daemon, mailbox monitor, and dashboard for Herdr"
6
6
  platforms = ["linux", "macos"]
@@ -62,6 +62,12 @@ title = "Open AGmail Webmail Dashboard"
62
62
  contexts = ["workspace"]
63
63
  command = ["node", "bin/herdr-amq.mjs", "dashboard"]
64
64
 
65
+ [[actions]]
66
+ id = "task-drain"
67
+ title = "Drain Assigned Backlog Tasks"
68
+ contexts = ["workspace", "pane"]
69
+ command = ["node", "bin/herdr-amq.mjs", "task", "drain"]
70
+
65
71
  [[panes]]
66
72
  id = "dashboard"
67
73
  title = "AGmail Dashboard"