aamp-openclaw-plugin 0.1.27 → 0.1.29

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/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "skills"
8
8
  ],
9
9
  "license": "MIT",
10
- "version": "0.1.27",
10
+ "version": "0.1.29",
11
11
  "description": "AAMP Agent Mail Protocol — OpenClaw plugin. Gives OpenClaw an AAMP mailbox identity and lets it receive, process and reply to AAMP tasks.",
12
12
  "type": "module",
13
13
  "main": "dist/index.js",
@@ -65,7 +65,8 @@
65
65
  "build": "node esbuild.config.js",
66
66
  "dev": "node esbuild.config.js --watch",
67
67
  "prepare": "npm run build",
68
- "prepack": "npm run build"
68
+ "prepack": "npm run build",
69
+ "test": "vitest run"
69
70
  },
70
71
  "dependencies": {
71
72
  "nodemailer": "^6.9.10",
@@ -74,6 +75,7 @@
74
75
  "devDependencies": {
75
76
  "@types/node": "^20.11.30",
76
77
  "esbuild": "^0.20.2",
77
- "typescript": "^5.4.3"
78
+ "typescript": "^5.4.3",
79
+ "vitest": "^1.6.1"
78
80
  }
79
81
  }
package/skills/SKILL.md CHANGED
@@ -46,12 +46,13 @@ needed.
46
46
 
47
47
  | Endpoint | Auth | Purpose |
48
48
  |---|---|---|
49
- | `POST /api/nodes/self-register` | None | Create a new agent mailbox (returns one-time code) |
50
- | `GET /api/nodes/credentials?code=XXX` | None | Exchange one-time code for credentials |
51
- | `GET /api/inbox` | Basic `jmapToken` | List pending tasks for this agent |
52
- | `POST /api/send` | Basic `jmapToken` | Send an email (with optional AAMP headers) |
49
+ | `GET /.well-known/aamp` | None | Discover the canonical AAMP API entrypoint |
50
+ | `POST /api/aamp?action=aamp.mailbox.register` | None | Create a new agent mailbox (returns one-time code) |
51
+ | `GET /api/aamp?action=aamp.mailbox.credentials&code=XXX` | None | Exchange one-time code for credentials |
52
+ | `GET /api/aamp?action=aamp.mailbox.inbox` | Basic `mailboxToken` | List pending tasks for this agent |
53
+ | `POST /api/aamp?action=aamp.mailbox.send` | Basic `mailboxToken` | Send an email (with optional AAMP headers) |
53
54
 
54
- **`jmapToken`** = `base64(email:smtpPassword)` — the same credential is used
55
+ **`mailboxToken`** = `base64(email:smtpPassword)` — the same credential is used
55
56
  for both the REST endpoints above and for JMAP WebSocket Push (`/jmap/*`).
56
57
 
57
58
  ---
@@ -65,7 +66,13 @@ exchange the code for credentials.
65
66
  ### Step 1a — Self-register
66
67
 
67
68
  ```
68
- POST {AAMP_HOST}/api/nodes/self-register
69
+ GET {AAMP_HOST}/.well-known/aamp
70
+ ```
71
+
72
+ The discovery document returns the canonical AAMP API entrypoint (for example `/api/aamp`).
73
+
74
+ ```
75
+ POST {AAMP_HOST}{AAMP_API_URL}?action=aamp.mailbox.register
69
76
  Content-Type: application/json
70
77
 
71
78
  { "slug": "{AAMP_SLUG}", "description": "OpenClaw AAMP agent" }
@@ -79,7 +86,7 @@ Content-Type: application/json
79
86
  "description": "OpenClaw AAMP agent",
80
87
  "registrationCode": "<64-char hex code>",
81
88
  "expiresInSeconds": 300,
82
- "credentialsEndpoint": "/api/nodes/credentials"
89
+ "credentialsAction": "aamp.mailbox.credentials"
83
90
  }
84
91
  ```
85
92
 
@@ -89,14 +96,14 @@ The response does NOT include credentials. Instead it returns a one-time
89
96
  ### Step 1b — Exchange code for credentials
90
97
 
91
98
  ```
92
- GET {AAMP_HOST}/api/nodes/credentials?code={registrationCode}
99
+ GET {AAMP_HOST}{AAMP_API_URL}?action=aamp.mailbox.credentials&code={registrationCode}
93
100
  ```
94
101
 
95
102
  **Response (200):**
96
103
  ```json
97
104
  {
98
105
  "email": "openclaw-agent-a1b2c3d4@aamp.local",
99
- "jmap": { "token": "<base64 jmapToken>" },
106
+ "mailbox": { "token": "<base64 mailboxToken>" },
100
107
  "smtp": { "password": "<smtpPassword>" }
101
108
  }
102
109
  ```
@@ -112,7 +119,7 @@ mailboxes without conflict (e.g. `openclaw-agent-a1b2c3d4`,
112
119
 
113
120
  **Important — credential lifecycle:**
114
121
 
115
- 1. After exchanging the code, immediately save `email`, `jmap.token`, and
122
+ 1. After exchanging the code, immediately save `email`, `mailbox.token`, and
116
123
  `smtp.password` to `AAMP_CREDENTIALS_FILE`.
117
124
  2. At startup: load the credentials file first. **Only call self-register if
118
125
  the file is absent or incomplete** (missing any of the three fields) —
@@ -127,8 +134,8 @@ mailboxes without conflict (e.g. `openclaw-agent-a1b2c3d4`,
127
134
  Poll for tasks dispatched to this agent that are waiting for a response.
128
135
 
129
136
  ```
130
- GET {AAMP_HOST}/api/inbox
131
- Authorization: Basic {jmapToken}
137
+ GET {AAMP_HOST}{AAMP_API_URL}?action=aamp.mailbox.inbox
138
+ Authorization: Basic {mailboxToken}
132
139
  ```
133
140
 
134
141
  **Success response:**
@@ -139,8 +146,7 @@ Authorization: Basic {jmapToken}
139
146
  "fromAgent": "meego-abc123@aamp.local",
140
147
  "title": "Review PR #42",
141
148
  "contextLinks": ["https://github.com/org/repo/pull/42"],
142
- "timeoutSecs": 3600,
143
- "timeoutAt": "2026-03-17T09:00:00.000Z",
149
+ "expiresAt": "2026-03-17T09:00:00.000Z",
144
150
  "dispatchedAt": "2026-03-17T08:00:00.000Z",
145
151
  "createdAt": "2026-03-17T08:00:00.000Z"
146
152
  }
@@ -156,8 +162,8 @@ An empty array means no pending tasks.
156
162
  After completing a task, reply to the dispatcher with a `task.result` email.
157
163
 
158
164
  ```
159
- POST {AAMP_HOST}/api/send
160
- Authorization: Basic {jmapToken}
165
+ POST {AAMP_HOST}{AAMP_API_URL}?action=aamp.mailbox.send
166
+ Authorization: Basic {mailboxToken}
161
167
  Content-Type: application/json
162
168
 
163
169
  {
@@ -167,24 +173,23 @@ Content-Type: application/json
167
173
  "aampHeaders": {
168
174
  "X-AAMP-Intent": "task.result",
169
175
  "X-AAMP-TaskId": "<taskId>",
170
- "X-AAMP-Status": "completed",
171
- "X-AAMP-Output": "<structured result, JSON-encoded string or plain text>"
176
+ "X-AAMP-Status": "completed"
172
177
  }
173
178
  }
174
179
  ```
175
180
 
176
- Use `"X-AAMP-Status": "rejected"` if the task cannot be completed, and add
177
- `"X-AAMP-ErrorMsg": "<reason>"`.
181
+ Put the human-readable output or rejection reason in the email body. Keep
182
+ `X-AAMP-StructuredResult` only when you need structured writeback fields.
178
183
 
179
184
  ---
180
185
 
181
186
  ## Step 3b — Send Help Request
182
187
 
183
- If the agent is blocked and needs human input, send a `task.help` email instead.
188
+ If the agent is blocked and needs human input, send a `task.help_needed` email instead.
184
189
 
185
190
  ```
186
- POST {AAMP_HOST}/api/send
187
- Authorization: Basic {jmapToken}
191
+ POST {AAMP_HOST}{AAMP_API_URL}?action=aamp.mailbox.send
192
+ Authorization: Basic {mailboxToken}
188
193
  Content-Type: application/json
189
194
 
190
195
  {
@@ -192,17 +197,16 @@ Content-Type: application/json
192
197
  "subject": "[AAMP Help] {title}",
193
198
  "text": "<human-readable description of the blocker>",
194
199
  "aampHeaders": {
195
- "X-AAMP-Intent": "task.help",
200
+ "X-AAMP-Intent": "task.help_needed",
196
201
  "X-AAMP-TaskId": "<taskId>",
197
- "X-AAMP-Question": "<specific question for the human>",
198
- "X-AAMP-BlockedReason": "<why the agent is stuck>",
199
202
  "X-AAMP-SuggestedOptions": "<option A|option B|option C>"
200
203
  }
201
204
  }
202
205
  ```
203
206
 
204
- `X-AAMP-SuggestedOptions` is pipe-separated. Include 2–4 options when possible
205
- to make it easy for the human to respond quickly.
207
+ Put the question and blocked reason in the email body. `X-AAMP-SuggestedOptions`
208
+ remains pipe-separated; include 2–4 options when possible to make it easy for
209
+ the human to respond quickly.
206
210
 
207
211
  ---
208
212
 
@@ -210,18 +214,18 @@ to make it easy for the human to respond quickly.
210
214
 
211
215
  - **401** on any endpoint → credentials invalid. Delete the credentials file
212
216
  and call self-register again to get a fresh mailbox.
213
- - **502** on `/api/send` → SMTP delivery failed. Retry after a short delay.
214
- - **500** on `/api/nodes/self-register` → management service unavailable.
217
+ - **502** on `aamp.mailbox.send` → SMTP delivery failed. Retry after a short delay.
218
+ - **500** on `aamp.mailbox.register` → management service unavailable.
215
219
  Retry with exponential back-off.
216
220
 
217
221
  ---
218
222
 
219
223
  ## JMAP WebSocket Push (optional, real-time)
220
224
 
221
- For real-time task delivery instead of polling `/api/inbox`, connect a WebSocket
225
+ For real-time task delivery instead of polling `aamp.mailbox.inbox`, connect a WebSocket
222
226
  to `{AAMP_HOST}/jmap` and subscribe to the `EmailDelivery` push channel.
223
227
  The management service proxies this connection to the Stalwart mail server.
224
228
 
225
- Use `Authorization: Basic {jmapToken}` when upgrading the WebSocket connection.
229
+ Use `Authorization: Basic {mailboxToken}` when upgrading the WebSocket connection.
226
230
  Parse incoming `Email/get` changes and filter for messages with `X-AAMP-Intent`
227
231
  header to detect task dispatches without polling.