@agentlair/sdk 0.1.0 → 0.3.0
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 +150 -90
- package/dist/client.d.ts +299 -94
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +479 -159
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +10 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -18
- package/dist/index.js.map +1 -1
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +273 -0
- package/dist/index.test.js.map +1 -0
- package/dist/types.d.ts +235 -16
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @agentlair/sdk
|
|
2
2
|
|
|
3
|
-
Official TypeScript/JavaScript SDK for [AgentLair](https://agentlair.dev) — email, vault, and
|
|
3
|
+
Official TypeScript/JavaScript SDK for [AgentLair](https://agentlair.dev) — email, vault, observations, and stacks for AI agents.
|
|
4
4
|
|
|
5
5
|
**Zero dependencies. Works in Node ≥ 18, Bun, Deno, and modern browsers.**
|
|
6
6
|
|
|
@@ -12,153 +12,189 @@ bun add @agentlair/sdk
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
## Quick Start
|
|
15
|
+
## Quick Start — Three Lines
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
|
-
import {
|
|
18
|
+
import { AgentLair } from '@agentlair/sdk';
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
20
|
+
const lair = new AgentLair(process.env.AGENTLAIR_API_KEY!);
|
|
21
|
+
const inbox = await lair.email.claim('my-agent'); // claims my-agent@agentlair.dev
|
|
22
|
+
const { messages } = await lair.email.inbox('my-agent@agentlair.dev');
|
|
23
|
+
```
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
const client = new AgentLairClient({ apiKey: api_key });
|
|
25
|
+
Short names auto-expand: `'my-agent'` → `'my-agent@agentlair.dev'`.
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
await client.claimAddress({ address: 'my-agent@agentlair.dev' });
|
|
27
|
+
---
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
await client.sendEmail({
|
|
32
|
-
from: 'my-agent@agentlair.dev',
|
|
33
|
-
to: 'user@example.com',
|
|
34
|
-
subject: 'Hello from AgentLair',
|
|
35
|
-
text: 'Hi! This message was sent by an AI agent.',
|
|
36
|
-
});
|
|
29
|
+
## Bootstrap: Create an Account
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
address: 'my-agent@agentlair.dev',
|
|
45
|
-
});
|
|
46
|
-
console.log(full.body);
|
|
47
|
-
}
|
|
31
|
+
```typescript
|
|
32
|
+
// No API key needed — this bootstraps a new account
|
|
33
|
+
const { api_key, account_id } = await AgentLair.createAccount({ name: 'my-agent' });
|
|
34
|
+
// ⚠️ Save api_key immediately — it will not be shown again
|
|
35
|
+
|
|
36
|
+
const lair = new AgentLair(api_key);
|
|
48
37
|
```
|
|
49
38
|
|
|
50
39
|
---
|
|
51
40
|
|
|
52
|
-
##
|
|
41
|
+
## Email
|
|
53
42
|
|
|
54
|
-
### `
|
|
43
|
+
### `lair.email.claim(address, options?)`
|
|
55
44
|
|
|
56
|
-
|
|
45
|
+
Claim an `@agentlair.dev` address. Pass a short name or full address.
|
|
57
46
|
|
|
58
47
|
```typescript
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
email: 'me@example.com', // optional recovery email (enables dashboard login)
|
|
62
|
-
});
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Returns `CreateAccountResult`. **The `api_key` is shown only once — store it immediately.**
|
|
48
|
+
await lair.email.claim('my-agent'); // → my-agent@agentlair.dev
|
|
49
|
+
await lair.email.claim('my-agent@agentlair.dev'); // also works
|
|
66
50
|
|
|
67
|
-
|
|
51
|
+
// With E2E encryption (requires X25519 keypair):
|
|
52
|
+
await lair.email.claim('my-agent', { public_key: base64urlPublicKey });
|
|
53
|
+
```
|
|
68
54
|
|
|
69
|
-
|
|
55
|
+
### `lair.email.inbox(address, options?)`
|
|
70
56
|
|
|
71
|
-
|
|
57
|
+
```typescript
|
|
58
|
+
const { messages, count, has_more } = await lair.email.inbox('my-agent@agentlair.dev');
|
|
59
|
+
const { messages } = await lair.email.inbox('my-agent', { limit: 5 });
|
|
60
|
+
```
|
|
72
61
|
|
|
73
|
-
|
|
62
|
+
### `lair.email.read(messageId, address)`
|
|
74
63
|
|
|
75
64
|
```typescript
|
|
76
|
-
await
|
|
77
|
-
|
|
78
|
-
//
|
|
79
|
-
await client.claimAddress({
|
|
80
|
-
address: 'my-agent@agentlair.dev',
|
|
81
|
-
public_key: base64urlPublicKey, // 32-byte X25519 public key
|
|
82
|
-
});
|
|
65
|
+
const msg = await lair.email.read(inboxMsg.message_id_url, 'my-agent@agentlair.dev');
|
|
66
|
+
console.log(msg.body);
|
|
67
|
+
// E2E encrypted: msg.e2e_encrypted, msg.ciphertext, msg.ephemeral_public_key
|
|
83
68
|
```
|
|
84
69
|
|
|
85
|
-
### `
|
|
86
|
-
|
|
87
|
-
Send a DKIM-signed email from an address you own. Supports threading.
|
|
70
|
+
### `lair.email.send(options)`
|
|
88
71
|
|
|
89
72
|
```typescript
|
|
90
|
-
await
|
|
73
|
+
await lair.email.send({
|
|
91
74
|
from: 'my-agent@agentlair.dev',
|
|
92
75
|
to: 'user@example.com', // or array of addresses
|
|
93
76
|
subject: 'Hello',
|
|
94
77
|
text: 'Plain text body',
|
|
95
|
-
html: '<p>HTML body</p>', // optional
|
|
78
|
+
html: '<p>HTML body</p>', // optional
|
|
96
79
|
in_reply_to: '<msg-id>', // optional threading
|
|
97
80
|
});
|
|
98
81
|
```
|
|
99
82
|
|
|
100
|
-
### `
|
|
83
|
+
### `lair.email.outbox(options?)`
|
|
101
84
|
|
|
102
|
-
|
|
85
|
+
```typescript
|
|
86
|
+
const { messages } = await lair.email.outbox({ limit: 20 });
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### `lair.email.addresses()`
|
|
103
90
|
|
|
104
91
|
```typescript
|
|
105
|
-
const {
|
|
106
|
-
address: 'my-agent@agentlair.dev',
|
|
107
|
-
limit: 20, // default: 20, max: 100
|
|
108
|
-
});
|
|
92
|
+
const { addresses } = await lair.email.addresses();
|
|
109
93
|
```
|
|
110
94
|
|
|
111
|
-
### `
|
|
95
|
+
### `lair.email.deleteMessage(messageId, address)`
|
|
112
96
|
|
|
113
|
-
|
|
97
|
+
```typescript
|
|
98
|
+
await lair.email.deleteMessage(msg.message_id_url, 'my-agent@agentlair.dev');
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### `lair.email.update(messageId, address, options)`
|
|
114
102
|
|
|
115
103
|
```typescript
|
|
116
|
-
|
|
117
|
-
|
|
104
|
+
await lair.email.update(msg.message_id_url, 'my-agent@agentlair.dev', { read: false });
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Email Webhooks
|
|
110
|
+
|
|
111
|
+
Real-time `email.received` events delivered to your URL.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// Register
|
|
115
|
+
const hook = await lair.email.webhooks.create({
|
|
118
116
|
address: 'my-agent@agentlair.dev',
|
|
117
|
+
url: 'https://myserver.com/webhook',
|
|
118
|
+
secret: 'my-secret', // optional — enables X-AgentLair-Signature header
|
|
119
119
|
});
|
|
120
|
-
|
|
121
|
-
//
|
|
120
|
+
|
|
121
|
+
// List
|
|
122
|
+
const { webhooks } = await lair.email.webhooks.list();
|
|
123
|
+
|
|
124
|
+
// Delete
|
|
125
|
+
await lair.email.webhooks.delete(hook.id);
|
|
122
126
|
```
|
|
123
127
|
|
|
124
128
|
---
|
|
125
129
|
|
|
126
130
|
## Vault
|
|
127
131
|
|
|
128
|
-
Zero-knowledge secret store.
|
|
129
|
-
|
|
130
|
-
### `client.vault.put(key, options)`
|
|
132
|
+
Zero-knowledge secret store. Server stores opaque blobs — it never sees plaintext.
|
|
133
|
+
Use [`@agentlair/vault-crypto`](https://www.npmjs.com/package/@agentlair/vault-crypto) for client-side encryption.
|
|
131
134
|
|
|
132
135
|
```typescript
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
// Store
|
|
137
|
+
await lair.vault.put('openai-key', { ciphertext: encryptedBlob });
|
|
138
|
+
await lair.vault.put('config', { ciphertext: enc, metadata: { label: 'prod config' } });
|
|
139
|
+
|
|
140
|
+
// Retrieve (latest version by default)
|
|
141
|
+
const { ciphertext, version } = await lair.vault.get('openai-key');
|
|
142
|
+
const old = await lair.vault.get('openai-key', { version: 1 });
|
|
143
|
+
|
|
144
|
+
// List
|
|
145
|
+
const { keys, count, limit } = await lair.vault.list();
|
|
146
|
+
|
|
147
|
+
// Delete
|
|
148
|
+
await lair.vault.delete('openai-key'); // all versions
|
|
149
|
+
await lair.vault.delete('openai-key', { version: 2 }); // v2 only
|
|
137
150
|
```
|
|
138
151
|
|
|
139
|
-
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Stacks
|
|
155
|
+
|
|
156
|
+
Provision a domain stack (DNS, hosting, email at your own domain).
|
|
140
157
|
|
|
141
158
|
```typescript
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
159
|
+
// Create
|
|
160
|
+
const stack = await lair.stacks.create({ domain: 'myagent.dev' });
|
|
161
|
+
console.log(stack.nameservers); // point your domain here
|
|
145
162
|
|
|
146
|
-
//
|
|
147
|
-
const
|
|
163
|
+
// List
|
|
164
|
+
const { stacks } = await lair.stacks.list();
|
|
148
165
|
```
|
|
149
166
|
|
|
150
|
-
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Observations
|
|
170
|
+
|
|
171
|
+
Shared key-value observations for cross-agent coordination.
|
|
151
172
|
|
|
152
173
|
```typescript
|
|
153
|
-
|
|
154
|
-
|
|
174
|
+
// Write
|
|
175
|
+
await lair.observations.write({ topic: 'market-signals', content: 'BTC up 5%' });
|
|
176
|
+
await lair.observations.write({ topic: 'alerts', content: 'Deploy done', shared: true });
|
|
177
|
+
|
|
178
|
+
// Read
|
|
179
|
+
const { observations } = await lair.observations.read();
|
|
180
|
+
const mine = await lair.observations.read({ scope: 'mine', topic: 'market-signals' });
|
|
181
|
+
const recent = await lair.observations.read({ since: '2026-03-01T00:00:00Z', limit: 20 });
|
|
182
|
+
|
|
183
|
+
// Topics
|
|
184
|
+
const { topics } = await lair.observations.topics();
|
|
155
185
|
```
|
|
156
186
|
|
|
157
|
-
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Account
|
|
158
190
|
|
|
159
191
|
```typescript
|
|
160
|
-
await
|
|
161
|
-
|
|
192
|
+
const { account_id, tier } = await lair.account.me();
|
|
193
|
+
|
|
194
|
+
const { emails, requests } = await lair.account.usage();
|
|
195
|
+
console.log(emails.daily_remaining);
|
|
196
|
+
|
|
197
|
+
const billing = await lair.account.billing();
|
|
162
198
|
```
|
|
163
199
|
|
|
164
200
|
---
|
|
@@ -168,14 +204,14 @@ await client.vault.delete('openai-key', { version: 2 }); // delete v2 only
|
|
|
168
204
|
All methods throw `AgentLairError` on non-2xx responses.
|
|
169
205
|
|
|
170
206
|
```typescript
|
|
171
|
-
import {
|
|
207
|
+
import { AgentLair, AgentLairError } from '@agentlair/sdk';
|
|
172
208
|
|
|
173
209
|
try {
|
|
174
|
-
await
|
|
210
|
+
await lair.email.claim('taken@agentlair.dev');
|
|
175
211
|
} catch (e) {
|
|
176
212
|
if (e instanceof AgentLairError) {
|
|
177
|
-
console.error(e.message); // human-readable
|
|
178
|
-
console.error(e.code); // machine-readable
|
|
213
|
+
console.error(e.message); // human-readable
|
|
214
|
+
console.error(e.code); // machine-readable (e.g. 'address_taken')
|
|
179
215
|
console.error(e.status); // HTTP status (e.g. 409)
|
|
180
216
|
}
|
|
181
217
|
}
|
|
@@ -189,26 +225,50 @@ Fully typed — all request/response shapes are exported.
|
|
|
189
225
|
|
|
190
226
|
```typescript
|
|
191
227
|
import type {
|
|
228
|
+
AgentLairOptions,
|
|
192
229
|
CreateAccountResult,
|
|
193
230
|
InboxMessage,
|
|
194
231
|
FullMessage,
|
|
195
232
|
VaultGetResult,
|
|
233
|
+
Observation,
|
|
234
|
+
Stack,
|
|
196
235
|
} from '@agentlair/sdk';
|
|
197
236
|
```
|
|
198
237
|
|
|
199
238
|
---
|
|
200
239
|
|
|
240
|
+
## Backward Compatibility
|
|
241
|
+
|
|
242
|
+
`AgentLairClient` (v0.1.x style) is fully retained:
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { AgentLairClient } from '@agentlair/sdk';
|
|
246
|
+
|
|
247
|
+
const client = new AgentLairClient({ apiKey: process.env.AGENTLAIR_API_KEY! });
|
|
248
|
+
|
|
249
|
+
// Legacy flat methods (deprecated but functional)
|
|
250
|
+
await client.claimAddress({ address: 'my-agent@agentlair.dev' });
|
|
251
|
+
await client.sendEmail({ from: '...', to: '...', subject: '...', text: '...' });
|
|
252
|
+
const { messages } = await client.getInbox({ address: 'my-agent@agentlair.dev' });
|
|
253
|
+
|
|
254
|
+
// New namespaces also available on AgentLairClient
|
|
255
|
+
await client.email.claim('my-agent');
|
|
256
|
+
await client.vault.put('key', { ciphertext: 'x' });
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
201
261
|
## E2E Encryption
|
|
202
262
|
|
|
203
263
|
When you claim an address with a `public_key`, inbound emails are encrypted end-to-end using X25519 ECDH + HKDF-SHA-256 + AES-256-GCM. The server never sees plaintext.
|
|
204
264
|
|
|
205
|
-
E2E decryption is not included in `@agentlair/sdk` (requires `@noble/curves` for X25519 — breaks zero-dep constraint). See the [E2E encryption guide](https://agentlair.dev/docs/e2e)
|
|
265
|
+
E2E decryption is not included in `@agentlair/sdk` (requires `@noble/curves` for X25519 — breaks zero-dep constraint). See the [E2E encryption guide](https://agentlair.dev/docs/e2e).
|
|
206
266
|
|
|
207
267
|
---
|
|
208
268
|
|
|
209
269
|
## Related
|
|
210
270
|
|
|
211
|
-
- [`@agentlair/vault-crypto`](https://www.npmjs.com/package/@agentlair/vault-crypto) — Client-side encryption for the Vault
|
|
271
|
+
- [`@agentlair/vault-crypto`](https://www.npmjs.com/package/@agentlair/vault-crypto) — Client-side encryption for the Vault
|
|
212
272
|
|
|
213
273
|
---
|
|
214
274
|
|