@agentlair/sdk 0.1.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 ADDED
@@ -0,0 +1,217 @@
1
+ # @agentlair/sdk
2
+
3
+ Official TypeScript/JavaScript SDK for [AgentLair](https://agentlair.dev) — email, vault, and account management for AI agents.
4
+
5
+ **Zero dependencies. Works in Node ≥ 18, Bun, Deno, and modern browsers.**
6
+
7
+ ```bash
8
+ npm install @agentlair/sdk
9
+ # or
10
+ bun add @agentlair/sdk
11
+ ```
12
+
13
+ ---
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { AgentLairClient } from '@agentlair/sdk';
19
+
20
+ // 1. Create an account (no existing key needed)
21
+ const { api_key, account_id } = await AgentLairClient.createAccount({ name: 'my-agent' });
22
+ // ⚠️ Save api_key immediately — it will not be shown again
23
+
24
+ // 2. Instantiate the client
25
+ const client = new AgentLairClient({ apiKey: api_key });
26
+
27
+ // 3. Claim an email address
28
+ await client.claimAddress({ address: 'my-agent@agentlair.dev' });
29
+
30
+ // 4. Send email
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
+ });
37
+
38
+ // 5. Read inbox
39
+ const { messages } = await client.getInbox({ address: 'my-agent@agentlair.dev' });
40
+ for (const msg of messages) {
41
+ console.log(msg.from, msg.subject, msg.snippet);
42
+ const full = await client.readMessage({
43
+ messageId: msg.message_id_url,
44
+ address: 'my-agent@agentlair.dev',
45
+ });
46
+ console.log(full.body);
47
+ }
48
+ ```
49
+
50
+ ---
51
+
52
+ ## Account
53
+
54
+ ### `AgentLairClient.createAccount(options?)` — static
55
+
56
+ Create a new account and get an API key. No existing account needed.
57
+
58
+ ```typescript
59
+ const { api_key, account_id, tier, limits } = await AgentLairClient.createAccount({
60
+ name: 'my-agent', // optional display name
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.**
66
+
67
+ ---
68
+
69
+ ## Email
70
+
71
+ ### `client.claimAddress(options)`
72
+
73
+ Claim an `@agentlair.dev` address. First-touch ownership — first to claim it owns it.
74
+
75
+ ```typescript
76
+ await client.claimAddress({ address: 'my-agent@agentlair.dev' });
77
+
78
+ // With E2E encryption (optional — requires X25519 keypair):
79
+ await client.claimAddress({
80
+ address: 'my-agent@agentlair.dev',
81
+ public_key: base64urlPublicKey, // 32-byte X25519 public key
82
+ });
83
+ ```
84
+
85
+ ### `client.sendEmail(options)`
86
+
87
+ Send a DKIM-signed email from an address you own. Supports threading.
88
+
89
+ ```typescript
90
+ await client.sendEmail({
91
+ from: 'my-agent@agentlair.dev',
92
+ to: 'user@example.com', // or array of addresses
93
+ subject: 'Hello',
94
+ text: 'Plain text body',
95
+ html: '<p>HTML body</p>', // optional; send text or html or both
96
+ in_reply_to: '<msg-id>', // optional threading
97
+ });
98
+ ```
99
+
100
+ ### `client.getInbox(options)`
101
+
102
+ Get inbox messages (preview only — no full body).
103
+
104
+ ```typescript
105
+ const { messages, count, has_more } = await client.getInbox({
106
+ address: 'my-agent@agentlair.dev',
107
+ limit: 20, // default: 20, max: 100
108
+ });
109
+ ```
110
+
111
+ ### `client.readMessage(options)`
112
+
113
+ Read the full body of a message. Marks as read.
114
+
115
+ ```typescript
116
+ const msg = await client.readMessage({
117
+ messageId: inboxMsg.message_id_url, // URL-encoded — safe to use directly
118
+ address: 'my-agent@agentlair.dev',
119
+ });
120
+ console.log(msg.body); // platform-decrypted body
121
+ // For E2E messages: msg.e2e_encrypted, msg.ciphertext, msg.ephemeral_public_key
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Vault
127
+
128
+ Zero-knowledge secret store. The server stores opaque blobs — it never sees plaintext. Use [`@agentlair/vault-crypto`](https://www.npmjs.com/package/@agentlair/vault-crypto) for client-side encryption helpers.
129
+
130
+ ### `client.vault.put(key, options)`
131
+
132
+ ```typescript
133
+ await client.vault.put('openai-key', {
134
+ ciphertext: encryptedBlob, // encrypt before storing
135
+ metadata: { label: 'OpenAI API Key' }, // optional plaintext metadata
136
+ });
137
+ ```
138
+
139
+ ### `client.vault.get(key, options?)`
140
+
141
+ ```typescript
142
+ const { ciphertext, version, latest_version } = await client.vault.get('openai-key');
143
+ // With @agentlair/vault-crypto:
144
+ const plaintext = await vc.decrypt(ciphertext, 'openai-key');
145
+
146
+ // Specific version:
147
+ const old = await client.vault.get('openai-key', { version: 1 });
148
+ ```
149
+
150
+ ### `client.vault.list()`
151
+
152
+ ```typescript
153
+ const { keys, count, limit } = await client.vault.list();
154
+ // keys: [{ key, version, metadata, created_at, updated_at }]
155
+ ```
156
+
157
+ ### `client.vault.delete(key, options?)`
158
+
159
+ ```typescript
160
+ await client.vault.delete('openai-key'); // delete all versions
161
+ await client.vault.delete('openai-key', { version: 2 }); // delete v2 only
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Error Handling
167
+
168
+ All methods throw `AgentLairError` on non-2xx responses.
169
+
170
+ ```typescript
171
+ import { AgentLairClient, AgentLairError } from '@agentlair/sdk';
172
+
173
+ try {
174
+ await client.claimAddress({ address: 'taken@agentlair.dev' });
175
+ } catch (e) {
176
+ if (e instanceof AgentLairError) {
177
+ console.error(e.message); // human-readable message
178
+ console.error(e.code); // machine-readable code (e.g. 'address_taken')
179
+ console.error(e.status); // HTTP status (e.g. 409)
180
+ }
181
+ }
182
+ ```
183
+
184
+ ---
185
+
186
+ ## TypeScript
187
+
188
+ Fully typed — all request/response shapes are exported.
189
+
190
+ ```typescript
191
+ import type {
192
+ CreateAccountResult,
193
+ InboxMessage,
194
+ FullMessage,
195
+ VaultGetResult,
196
+ } from '@agentlair/sdk';
197
+ ```
198
+
199
+ ---
200
+
201
+ ## E2E Encryption
202
+
203
+ 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
+
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) for the decryption recipe.
206
+
207
+ ---
208
+
209
+ ## Related
210
+
211
+ - [`@agentlair/vault-crypto`](https://www.npmjs.com/package/@agentlair/vault-crypto) — Client-side encryption for the Vault (zero-knowledge AES-256-GCM + HKDF)
212
+
213
+ ---
214
+
215
+ ## License
216
+
217
+ MIT © [AgentLair](https://agentlair.dev)
@@ -0,0 +1,157 @@
1
+ /**
2
+ * @agentlair/sdk — AgentLairClient
3
+ *
4
+ * Official TypeScript/JavaScript SDK for AgentLair.
5
+ * Zero dependencies. Works in Node ≥ 18, Bun, Deno, and modern browsers.
6
+ *
7
+ * @example
8
+ * // Create a new account (no API key needed)
9
+ * const { api_key, account_id } = await AgentLairClient.createAccount({ name: 'my-agent' });
10
+ *
11
+ * @example
12
+ * // Use an existing key
13
+ * const client = new AgentLairClient({ apiKey: process.env.AGENTLAIR_API_KEY! });
14
+ * await client.claimAddress({ address: 'my-agent@agentlair.dev' });
15
+ * await client.sendEmail({ from: 'my-agent@agentlair.dev', to: 'user@example.com', subject: 'Hello', text: 'Hi!' });
16
+ * const inbox = await client.getInbox({ address: 'my-agent@agentlair.dev' });
17
+ */
18
+ import type { AgentLairClientOptions, ClaimAddressOptions, ClaimAddressResult, CreateAccountOptions, CreateAccountResult, FullMessage, GetInboxOptions, GetInboxResult, ReadMessageOptions, SendEmailOptions, SendEmailResult, VaultDeleteOptions, VaultDeleteResult, VaultGetOptions, VaultGetResult, VaultListResult, VaultPutOptions, VaultPutResult } from './types.js';
19
+ /**
20
+ * vault.put / vault.get / vault.list / vault.delete
21
+ *
22
+ * The AgentLair Vault is a zero-knowledge secret store.
23
+ * The server stores opaque encrypted blobs — plaintext never leaves your client.
24
+ * Use @agentlair/vault-crypto for client-side encryption helpers.
25
+ */
26
+ declare class VaultNamespace {
27
+ private readonly _request;
28
+ constructor(_request: <T>(method: string, path: string, opts?: {
29
+ body?: unknown;
30
+ query?: Record<string, string>;
31
+ }) => Promise<T>);
32
+ /**
33
+ * Store an encrypted blob in the Vault.
34
+ *
35
+ * Each PUT creates a new version (append-only, versioned).
36
+ * Free tier: up to 50 keys, 3 versions each.
37
+ *
38
+ * @example
39
+ * // With @agentlair/vault-crypto:
40
+ * const vc = VaultCrypto.fromSeed(seed);
41
+ * const ciphertext = await vc.encrypt('sk-openai-...', 'openai-key');
42
+ * await client.vault.put('openai-key', { ciphertext });
43
+ */
44
+ put(key: string, options: VaultPutOptions): Promise<VaultPutResult>;
45
+ /**
46
+ * Retrieve an encrypted blob from the Vault.
47
+ *
48
+ * Returns the latest version by default. Pass `version` for a specific one.
49
+ *
50
+ * @example
51
+ * const { ciphertext } = await client.vault.get('openai-key');
52
+ * // With @agentlair/vault-crypto:
53
+ * const plaintext = await vc.decrypt(ciphertext, 'openai-key');
54
+ */
55
+ get(key: string, options?: VaultGetOptions): Promise<VaultGetResult>;
56
+ /**
57
+ * List all Vault keys for this account (metadata only — no ciphertext).
58
+ *
59
+ * @example
60
+ * const { keys, count, limit } = await client.vault.list();
61
+ */
62
+ list(): Promise<VaultListResult>;
63
+ /**
64
+ * Delete a Vault key (all versions) or a specific version.
65
+ *
66
+ * Pass `version` to delete only that version. Omit to delete all versions.
67
+ *
68
+ * @example
69
+ * await client.vault.delete('openai-key'); // delete all versions
70
+ * await client.vault.delete('openai-key', { version: 2 }); // delete v2 only
71
+ */
72
+ delete(key: string, options?: VaultDeleteOptions): Promise<VaultDeleteResult>;
73
+ }
74
+ export declare class AgentLairClient {
75
+ private readonly _apiKey;
76
+ private readonly _baseUrl;
77
+ /**
78
+ * Namespaced Vault operations: vault.put / vault.get / vault.list / vault.delete
79
+ */
80
+ readonly vault: VaultNamespace;
81
+ constructor(options: AgentLairClientOptions);
82
+ private _request;
83
+ /**
84
+ * Create a new AgentLair account and get an API key.
85
+ *
86
+ * No existing account or API key needed — this is the bootstrapping method.
87
+ * **Save the returned `api_key` immediately** — it will not be shown again.
88
+ *
89
+ * @param options Optional name and recovery email
90
+ * @param baseUrl Override API base URL (default: https://agentlair.dev)
91
+ *
92
+ * @example
93
+ * const { api_key, account_id } = await AgentLairClient.createAccount({ name: 'my-agent' });
94
+ * // Store api_key securely — never log it
95
+ * const client = new AgentLairClient({ apiKey: api_key });
96
+ */
97
+ static createAccount(options?: CreateAccountOptions, baseUrl?: string): Promise<CreateAccountResult>;
98
+ /**
99
+ * Claim an @agentlair.dev email address for this account.
100
+ *
101
+ * First-touch ownership model — the first agent to claim an address owns it.
102
+ * DKIM, SPF, and DMARC are pre-configured. Ready to send in under 5 seconds.
103
+ *
104
+ * Optionally provide a `public_key` (base64url X25519, 32 bytes) to enable
105
+ * end-to-end encryption for inbound messages.
106
+ *
107
+ * @example
108
+ * await client.claimAddress({ address: 'my-agent@agentlair.dev' });
109
+ */
110
+ claimAddress(options: ClaimAddressOptions): Promise<ClaimAddressResult>;
111
+ /**
112
+ * Send a DKIM-signed email from an @agentlair.dev address you own.
113
+ *
114
+ * Supports plain text, HTML, or both. Supports threading via `in_reply_to`.
115
+ * Free tier: 10 emails/day per address.
116
+ *
117
+ * @example
118
+ * await client.sendEmail({
119
+ * from: 'my-agent@agentlair.dev',
120
+ * to: 'user@example.com',
121
+ * subject: 'Hello from AgentLair',
122
+ * text: 'Hi! This email was sent by an AI agent.',
123
+ * });
124
+ */
125
+ sendEmail(options: SendEmailOptions): Promise<SendEmailResult>;
126
+ /**
127
+ * Get the inbox for an @agentlair.dev address you own.
128
+ *
129
+ * Returns message previews (no full body). Use `readMessage()` for the full body.
130
+ *
131
+ * @example
132
+ * const { messages, count } = await client.getInbox({ address: 'my-agent@agentlair.dev' });
133
+ * for (const msg of messages) {
134
+ * console.log(msg.from, msg.subject, msg.snippet);
135
+ * }
136
+ */
137
+ getInbox(options: GetInboxOptions): Promise<GetInboxResult>;
138
+ /**
139
+ * Read the full body of a specific message.
140
+ *
141
+ * Marks the message as read. For E2E-encrypted messages, returns
142
+ * `ciphertext` and `ephemeral_public_key` for client-side decryption.
143
+ *
144
+ * @param messageId Use `message_id_url` from inbox (URL-encoded) or raw `message_id`
145
+ * @param address The @agentlair.dev address that received the message
146
+ *
147
+ * @example
148
+ * const msg = await client.readMessage({
149
+ * messageId: inboxMsg.message_id_url,
150
+ * address: 'my-agent@agentlair.dev',
151
+ * });
152
+ * console.log(msg.body);
153
+ */
154
+ readMessage(options: ReadMessageOptions): Promise<FullMessage>;
155
+ }
156
+ export {};
157
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,eAAe,EACf,eAAe,EACf,cAAc,EACf,MAAM,YAAY,CAAC;AAMpB;;;;;;GAMG;AACH,cAAM,cAAc;IAEhB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,CAAC,CAAC,EAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,KACtD,OAAO,CAAC,CAAC,CAAC;IAGjB;;;;;;;;;;;OAWG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAMzE;;;;;;;;;OASG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAM9E;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,eAAe,CAAC;IAItC;;;;;;;;OAQG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAOxF;AAID,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAElC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;gBAEnB,OAAO,EAAE,sBAAsB;YAQ7B,QAAQ;IAiDtB;;;;;;;;;;;;;OAaG;WACU,aAAa,CACxB,OAAO,GAAE,oBAAyB,EAClC,OAAO,SAAmB,GACzB,OAAO,CAAC,mBAAmB,CAAC;IAoB/B;;;;;;;;;;;OAWG;IACG,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAM7E;;;;;;;;;;;;;OAaG;IACG,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAMpE;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAQjE;;;;;;;;;;;;;;;OAeG;IACG,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC;CAOrE"}
package/dist/client.js ADDED
@@ -0,0 +1,241 @@
1
+ /**
2
+ * @agentlair/sdk — AgentLairClient
3
+ *
4
+ * Official TypeScript/JavaScript SDK for AgentLair.
5
+ * Zero dependencies. Works in Node ≥ 18, Bun, Deno, and modern browsers.
6
+ *
7
+ * @example
8
+ * // Create a new account (no API key needed)
9
+ * const { api_key, account_id } = await AgentLairClient.createAccount({ name: 'my-agent' });
10
+ *
11
+ * @example
12
+ * // Use an existing key
13
+ * const client = new AgentLairClient({ apiKey: process.env.AGENTLAIR_API_KEY! });
14
+ * await client.claimAddress({ address: 'my-agent@agentlair.dev' });
15
+ * await client.sendEmail({ from: 'my-agent@agentlair.dev', to: 'user@example.com', subject: 'Hello', text: 'Hi!' });
16
+ * const inbox = await client.getInbox({ address: 'my-agent@agentlair.dev' });
17
+ */
18
+ import { AgentLairError } from './errors.js';
19
+ const DEFAULT_BASE_URL = 'https://agentlair.dev';
20
+ // ─── VaultNamespace ───────────────────────────────────────────────────────────
21
+ /**
22
+ * vault.put / vault.get / vault.list / vault.delete
23
+ *
24
+ * The AgentLair Vault is a zero-knowledge secret store.
25
+ * The server stores opaque encrypted blobs — plaintext never leaves your client.
26
+ * Use @agentlair/vault-crypto for client-side encryption helpers.
27
+ */
28
+ class VaultNamespace {
29
+ _request;
30
+ constructor(_request) {
31
+ this._request = _request;
32
+ }
33
+ /**
34
+ * Store an encrypted blob in the Vault.
35
+ *
36
+ * Each PUT creates a new version (append-only, versioned).
37
+ * Free tier: up to 50 keys, 3 versions each.
38
+ *
39
+ * @example
40
+ * // With @agentlair/vault-crypto:
41
+ * const vc = VaultCrypto.fromSeed(seed);
42
+ * const ciphertext = await vc.encrypt('sk-openai-...', 'openai-key');
43
+ * await client.vault.put('openai-key', { ciphertext });
44
+ */
45
+ async put(key, options) {
46
+ return this._request('PUT', `/v1/vault/${encodeURIComponent(key)}`, {
47
+ body: options,
48
+ });
49
+ }
50
+ /**
51
+ * Retrieve an encrypted blob from the Vault.
52
+ *
53
+ * Returns the latest version by default. Pass `version` for a specific one.
54
+ *
55
+ * @example
56
+ * const { ciphertext } = await client.vault.get('openai-key');
57
+ * // With @agentlair/vault-crypto:
58
+ * const plaintext = await vc.decrypt(ciphertext, 'openai-key');
59
+ */
60
+ async get(key, options = {}) {
61
+ const query = {};
62
+ if (options.version !== undefined)
63
+ query.version = String(options.version);
64
+ return this._request('GET', `/v1/vault/${encodeURIComponent(key)}`, { query });
65
+ }
66
+ /**
67
+ * List all Vault keys for this account (metadata only — no ciphertext).
68
+ *
69
+ * @example
70
+ * const { keys, count, limit } = await client.vault.list();
71
+ */
72
+ async list() {
73
+ return this._request('GET', '/v1/vault/');
74
+ }
75
+ /**
76
+ * Delete a Vault key (all versions) or a specific version.
77
+ *
78
+ * Pass `version` to delete only that version. Omit to delete all versions.
79
+ *
80
+ * @example
81
+ * await client.vault.delete('openai-key'); // delete all versions
82
+ * await client.vault.delete('openai-key', { version: 2 }); // delete v2 only
83
+ */
84
+ async delete(key, options = {}) {
85
+ const query = {};
86
+ if (options.version !== undefined)
87
+ query.version = String(options.version);
88
+ return this._request('DELETE', `/v1/vault/${encodeURIComponent(key)}`, {
89
+ query,
90
+ });
91
+ }
92
+ }
93
+ // ─── AgentLairClient ──────────────────────────────────────────────────────────
94
+ export class AgentLairClient {
95
+ _apiKey;
96
+ _baseUrl;
97
+ /**
98
+ * Namespaced Vault operations: vault.put / vault.get / vault.list / vault.delete
99
+ */
100
+ vault;
101
+ constructor(options) {
102
+ this._apiKey = options.apiKey;
103
+ this._baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, '');
104
+ this.vault = new VaultNamespace(this._request.bind(this));
105
+ }
106
+ // ─── Internal request helper ─────────────────────────────────────────────
107
+ async _request(method, path, opts = {}) {
108
+ const url = new URL(this._baseUrl + path);
109
+ if (opts.query) {
110
+ for (const [k, v] of Object.entries(opts.query)) {
111
+ url.searchParams.set(k, v);
112
+ }
113
+ }
114
+ const headers = {
115
+ 'Content-Type': 'application/json',
116
+ };
117
+ // auth defaults to Bearer <apiKey>; pass null to skip auth
118
+ if (opts.auth !== null) {
119
+ headers['Authorization'] = `Bearer ${opts.auth ?? this._apiKey}`;
120
+ }
121
+ const response = await fetch(url.toString(), {
122
+ method,
123
+ headers,
124
+ body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,
125
+ });
126
+ let data;
127
+ const contentType = response.headers.get('content-type') ?? '';
128
+ if (contentType.includes('application/json')) {
129
+ data = await response.json();
130
+ }
131
+ else {
132
+ data = await response.text();
133
+ }
134
+ if (!response.ok) {
135
+ const body = data;
136
+ throw new AgentLairError(body?.message ?? `HTTP ${response.status}`, response.status, body?.error ?? 'error');
137
+ }
138
+ return data;
139
+ }
140
+ // ─── Static: createAccount ───────────────────────────────────────────────
141
+ /**
142
+ * Create a new AgentLair account and get an API key.
143
+ *
144
+ * No existing account or API key needed — this is the bootstrapping method.
145
+ * **Save the returned `api_key` immediately** — it will not be shown again.
146
+ *
147
+ * @param options Optional name and recovery email
148
+ * @param baseUrl Override API base URL (default: https://agentlair.dev)
149
+ *
150
+ * @example
151
+ * const { api_key, account_id } = await AgentLairClient.createAccount({ name: 'my-agent' });
152
+ * // Store api_key securely — never log it
153
+ * const client = new AgentLairClient({ apiKey: api_key });
154
+ */
155
+ static async createAccount(options = {}, baseUrl = DEFAULT_BASE_URL) {
156
+ const url = baseUrl.replace(/\/$/, '') + '/v1/auth/keys';
157
+ const response = await fetch(url, {
158
+ method: 'POST',
159
+ headers: { 'Content-Type': 'application/json' },
160
+ body: JSON.stringify(options),
161
+ });
162
+ const data = await response.json();
163
+ if (!response.ok) {
164
+ throw new AgentLairError(data.message ?? `HTTP ${response.status}`, response.status, data.error ?? 'error');
165
+ }
166
+ return data;
167
+ }
168
+ // ─── Email: claimAddress ─────────────────────────────────────────────────
169
+ /**
170
+ * Claim an @agentlair.dev email address for this account.
171
+ *
172
+ * First-touch ownership model — the first agent to claim an address owns it.
173
+ * DKIM, SPF, and DMARC are pre-configured. Ready to send in under 5 seconds.
174
+ *
175
+ * Optionally provide a `public_key` (base64url X25519, 32 bytes) to enable
176
+ * end-to-end encryption for inbound messages.
177
+ *
178
+ * @example
179
+ * await client.claimAddress({ address: 'my-agent@agentlair.dev' });
180
+ */
181
+ async claimAddress(options) {
182
+ return this._request('POST', '/v1/email/claim', { body: options });
183
+ }
184
+ // ─── Email: sendEmail ────────────────────────────────────────────────────
185
+ /**
186
+ * Send a DKIM-signed email from an @agentlair.dev address you own.
187
+ *
188
+ * Supports plain text, HTML, or both. Supports threading via `in_reply_to`.
189
+ * Free tier: 10 emails/day per address.
190
+ *
191
+ * @example
192
+ * await client.sendEmail({
193
+ * from: 'my-agent@agentlair.dev',
194
+ * to: 'user@example.com',
195
+ * subject: 'Hello from AgentLair',
196
+ * text: 'Hi! This email was sent by an AI agent.',
197
+ * });
198
+ */
199
+ async sendEmail(options) {
200
+ return this._request('POST', '/v1/email/send', { body: options });
201
+ }
202
+ // ─── Email: getInbox ─────────────────────────────────────────────────────
203
+ /**
204
+ * Get the inbox for an @agentlair.dev address you own.
205
+ *
206
+ * Returns message previews (no full body). Use `readMessage()` for the full body.
207
+ *
208
+ * @example
209
+ * const { messages, count } = await client.getInbox({ address: 'my-agent@agentlair.dev' });
210
+ * for (const msg of messages) {
211
+ * console.log(msg.from, msg.subject, msg.snippet);
212
+ * }
213
+ */
214
+ async getInbox(options) {
215
+ const query = { address: options.address };
216
+ if (options.limit !== undefined)
217
+ query.limit = String(options.limit);
218
+ return this._request('GET', '/v1/email/inbox', { query });
219
+ }
220
+ // ─── Email: readMessage ──────────────────────────────────────────────────
221
+ /**
222
+ * Read the full body of a specific message.
223
+ *
224
+ * Marks the message as read. For E2E-encrypted messages, returns
225
+ * `ciphertext` and `ephemeral_public_key` for client-side decryption.
226
+ *
227
+ * @param messageId Use `message_id_url` from inbox (URL-encoded) or raw `message_id`
228
+ * @param address The @agentlair.dev address that received the message
229
+ *
230
+ * @example
231
+ * const msg = await client.readMessage({
232
+ * messageId: inboxMsg.message_id_url,
233
+ * address: 'my-agent@agentlair.dev',
234
+ * });
235
+ * console.log(msg.body);
236
+ */
237
+ async readMessage(options) {
238
+ return this._request('GET', `/v1/email/messages/${options.messageId}`, { query: { address: options.address } });
239
+ }
240
+ }
241
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAsB7C,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAEjD,iFAAiF;AAEjF;;;;;;GAMG;AACH,MAAM,cAAc;IAEC;IADnB,YACmB,QAIF;QAJE,aAAQ,GAAR,QAAQ,CAIV;IACd,CAAC;IAEJ;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,OAAwB;QAC7C,OAAO,IAAI,CAAC,QAAQ,CAAiB,KAAK,EAAE,aAAa,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE;YAClF,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,UAA2B,EAAE;QAClD,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;YAAE,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC,QAAQ,CAAiB,KAAK,EAAE,aAAa,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACjG,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,QAAQ,CAAkB,KAAK,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,MAAM,CAAC,GAAW,EAAE,UAA8B,EAAE;QACxD,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;YAAE,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC,QAAQ,CAAoB,QAAQ,EAAE,aAAa,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE;YACxF,KAAK;SACN,CAAC,CAAC;IACL,CAAC;CACF;AAED,iFAAiF;AAEjF,MAAM,OAAO,eAAe;IACT,OAAO,CAAS;IAChB,QAAQ,CAAS;IAElC;;OAEG;IACM,KAAK,CAAiB;IAE/B,YAAY,OAA+B;QACzC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,KAAK,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,4EAA4E;IAEpE,KAAK,CAAC,QAAQ,CACpB,MAAc,EACd,IAAY,EACZ,OAAiF,EAAE;QAEnF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;QAC1C,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,2DAA2D;QAC3D,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACvB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACnE,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;YAC3C,MAAM;YACN,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SACtE,CAAC,CAAC;QAEH,IAAI,IAAa,CAAC;QAClB,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/D,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC7C,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,IAA4C,CAAC;YAC1D,MAAM,IAAI,cAAc,CACtB,IAAI,EAAE,OAAO,IAAI,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAC1C,QAAQ,CAAC,MAAM,EACf,IAAI,EAAE,KAAK,IAAI,OAAO,CACvB,CAAC;QACJ,CAAC;QAED,OAAO,IAAS,CAAC;IACnB,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,KAAK,CAAC,aAAa,CACxB,UAAgC,EAAE,EAClC,OAAO,GAAG,gBAAgB;QAE1B,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,eAAe,CAAC;QACzD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAgE,CAAC;QACjG,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,cAAc,CACtB,IAAI,CAAC,OAAO,IAAI,QAAQ,QAAQ,CAAC,MAAM,EAAE,EACzC,QAAQ,CAAC,MAAM,EACf,IAAI,CAAC,KAAK,IAAI,OAAO,CACtB,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,YAAY,CAAC,OAA4B;QAC7C,OAAO,IAAI,CAAC,QAAQ,CAAqB,MAAM,EAAE,iBAAiB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,SAAS,CAAC,OAAyB;QACvC,OAAO,IAAI,CAAC,QAAQ,CAAkB,MAAM,EAAE,gBAAgB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;;;OAUG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAwB;QACrC,MAAM,KAAK,GAA2B,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;QACnE,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC,QAAQ,CAAiB,KAAK,EAAE,iBAAiB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,WAAW,CAAC,OAA2B;QAC3C,OAAO,IAAI,CAAC,QAAQ,CAClB,KAAK,EACL,sBAAsB,OAAO,CAAC,SAAS,EAAE,EACzC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,CACxC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * AgentLairError — thrown when the API returns a non-2xx response.
3
+ */
4
+ export declare class AgentLairError extends Error {
5
+ /** HTTP status code */
6
+ readonly status: number;
7
+ /** Machine-readable error code from the API */
8
+ readonly code: string;
9
+ constructor(message: string, status: number, code: string);
10
+ }
11
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,uBAAuB;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAM1D"}
package/dist/errors.js ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * AgentLairError — thrown when the API returns a non-2xx response.
3
+ */
4
+ export class AgentLairError extends Error {
5
+ /** HTTP status code */
6
+ status;
7
+ /** Machine-readable error code from the API */
8
+ code;
9
+ constructor(message, status, code) {
10
+ super(message);
11
+ this.name = 'AgentLairError';
12
+ this.status = status;
13
+ this.code = code;
14
+ }
15
+ }
16
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,uBAAuB;IACd,MAAM,CAAS;IACxB,+CAA+C;IACtC,IAAI,CAAS;IAEtB,YAAY,OAAe,EAAE,MAAc,EAAE,IAAY;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @agentlair/sdk
3
+ *
4
+ * Official TypeScript/JavaScript SDK for AgentLair.
5
+ * Zero dependencies. Works in Node ≥ 18, Bun, Deno, and modern browsers.
6
+ *
7
+ * @example
8
+ * import { AgentLairClient } from '@agentlair/sdk';
9
+ *
10
+ * // Bootstrap: create an account
11
+ * const { api_key } = await AgentLairClient.createAccount({ name: 'my-agent' });
12
+ *
13
+ * // Use the client
14
+ * const client = new AgentLairClient({ apiKey: api_key });
15
+ * await client.claimAddress({ address: 'my-agent@agentlair.dev' });
16
+ * await client.sendEmail({
17
+ * from: 'my-agent@agentlair.dev',
18
+ * to: 'user@example.com',
19
+ * subject: 'Hello',
20
+ * text: 'Hi from an AI agent!',
21
+ * });
22
+ *
23
+ * // Vault: store secrets (encrypt first with @agentlair/vault-crypto)
24
+ * await client.vault.put('openai-key', { ciphertext: encryptedBlob });
25
+ * const { ciphertext } = await client.vault.get('openai-key');
26
+ *
27
+ * @see https://agentlair.dev/docs
28
+ */
29
+ export { AgentLairClient } from './client.js';
30
+ export { AgentLairError } from './errors.js';
31
+ export type { AgentLairClientOptions, CreateAccountOptions, CreateAccountResult, ClaimAddressOptions, ClaimAddressResult, SendEmailOptions, SendEmailResult, GetInboxOptions, GetInboxResult, InboxMessage, FullMessage, ReadMessageOptions, VaultPutOptions, VaultPutResult, VaultGetOptions, VaultGetResult, VaultListResult, VaultKeyInfo, VaultDeleteOptions, VaultDeleteResult, AgentLairErrorBody, } from './types.js';
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,YAAY,EAEV,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EAEnB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,EACd,YAAY,EACZ,WAAW,EACX,kBAAkB,EAElB,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EAEjB,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @agentlair/sdk
3
+ *
4
+ * Official TypeScript/JavaScript SDK for AgentLair.
5
+ * Zero dependencies. Works in Node ≥ 18, Bun, Deno, and modern browsers.
6
+ *
7
+ * @example
8
+ * import { AgentLairClient } from '@agentlair/sdk';
9
+ *
10
+ * // Bootstrap: create an account
11
+ * const { api_key } = await AgentLairClient.createAccount({ name: 'my-agent' });
12
+ *
13
+ * // Use the client
14
+ * const client = new AgentLairClient({ apiKey: api_key });
15
+ * await client.claimAddress({ address: 'my-agent@agentlair.dev' });
16
+ * await client.sendEmail({
17
+ * from: 'my-agent@agentlair.dev',
18
+ * to: 'user@example.com',
19
+ * subject: 'Hello',
20
+ * text: 'Hi from an AI agent!',
21
+ * });
22
+ *
23
+ * // Vault: store secrets (encrypt first with @agentlair/vault-crypto)
24
+ * await client.vault.put('openai-key', { ciphertext: encryptedBlob });
25
+ * const { ciphertext } = await client.vault.get('openai-key');
26
+ *
27
+ * @see https://agentlair.dev/docs
28
+ */
29
+ export { AgentLairClient } from './client.js';
30
+ export { AgentLairError } from './errors.js';
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * @agentlair/sdk — Type definitions
3
+ */
4
+ export interface CreateAccountOptions {
5
+ /** Optional display name for this account/agent */
6
+ name?: string;
7
+ /** Optional recovery email — enables dashboard login */
8
+ email?: string;
9
+ }
10
+ export interface CreateAccountResult {
11
+ /** API key — save this immediately, it will not be shown again */
12
+ api_key: string;
13
+ /** Short prefix of the API key (safe to log) */
14
+ key_prefix: string;
15
+ /** Unique account identifier */
16
+ account_id: string;
17
+ /** Account tier */
18
+ tier: 'free' | 'paid';
19
+ /** ISO timestamp of creation */
20
+ created_at: string;
21
+ /** Human-readable warning */
22
+ warning: string;
23
+ /** Rate/usage limits for this tier */
24
+ limits: {
25
+ stacks: number;
26
+ addresses: number;
27
+ dns_records: number;
28
+ emails_per_day: number;
29
+ requests_per_day: number;
30
+ };
31
+ }
32
+ export interface ClaimAddressOptions {
33
+ /** Full address to claim, e.g. "my-agent@agentlair.dev" */
34
+ address: string;
35
+ /**
36
+ * Optional base64url-encoded X25519 public key (32 bytes).
37
+ * When provided, enables end-to-end encryption for inbound messages.
38
+ * Inbound emails will have `e2e_encrypted: true` and a `ciphertext` field.
39
+ */
40
+ public_key?: string;
41
+ }
42
+ export interface ClaimAddressResult {
43
+ address: string;
44
+ claimed: boolean;
45
+ already_owned: boolean;
46
+ account_id: string;
47
+ /** Whether E2E encryption is enabled for this address */
48
+ e2e_enabled: boolean;
49
+ }
50
+ export interface SendEmailOptions {
51
+ /** Sender address — must be a claimed @agentlair.dev address you own */
52
+ from: string;
53
+ /** Recipient address or array of addresses */
54
+ to: string | string[];
55
+ /** Email subject */
56
+ subject: string;
57
+ /** Plain text body (required if html not provided) */
58
+ text?: string;
59
+ /** HTML body (required if text not provided) */
60
+ html?: string;
61
+ /** Message-ID of the email being replied to (for threading) */
62
+ in_reply_to?: string;
63
+ }
64
+ export interface SendEmailResult {
65
+ /** Internal message ID */
66
+ id: string;
67
+ /** Delivery status */
68
+ status: 'sent' | 'queued';
69
+ /** Provider message ID (if delivered) */
70
+ provider_id?: string;
71
+ /** Delivery timestamp */
72
+ sent_at?: string;
73
+ /** Warning if provider not configured */
74
+ warning?: string;
75
+ }
76
+ export interface InboxMessage {
77
+ /** Full Message-ID header (may contain angle brackets) */
78
+ message_id: string;
79
+ /** URL-encoded message_id (use this in readMessage calls) */
80
+ message_id_url: string;
81
+ /** Sender address */
82
+ from: string;
83
+ /** Recipient address */
84
+ to: string;
85
+ /** Email subject */
86
+ subject: string;
87
+ /** Up to 120-char preview of the body */
88
+ snippet: string;
89
+ /** ISO timestamp when received */
90
+ received_at: string;
91
+ /** Whether the message has been read */
92
+ read: boolean;
93
+ /** True if inbound E2E encryption is enabled for this address */
94
+ e2e_encrypted?: boolean;
95
+ }
96
+ export interface GetInboxOptions {
97
+ /** The @agentlair.dev address to read */
98
+ address: string;
99
+ /** Max messages to return (default: 20, max: 100) */
100
+ limit?: number;
101
+ }
102
+ export interface GetInboxResult {
103
+ messages: InboxMessage[];
104
+ has_more: boolean;
105
+ count: number;
106
+ address: string;
107
+ }
108
+ export interface ReadMessageOptions {
109
+ /** Message ID — use message_id_url from inbox for safety, or raw message_id */
110
+ messageId: string;
111
+ /** The @agentlair.dev address that received the message */
112
+ address: string;
113
+ }
114
+ export interface FullMessage extends InboxMessage {
115
+ /** Full message body (platform-decrypted). For E2E messages, see `ciphertext`. */
116
+ body?: string;
117
+ /**
118
+ * Raw E2E ciphertext (base64url). Only present when `e2e_encrypted: true`.
119
+ * Decrypt client-side using X25519 ECDH + HKDF-SHA-256 + AES-256-GCM
120
+ * with the private key corresponding to the address's registered public key.
121
+ */
122
+ ciphertext?: string;
123
+ /**
124
+ * Ephemeral sender public key for E2E decryption (base64url X25519).
125
+ * Only present when `e2e_encrypted: true`.
126
+ */
127
+ ephemeral_public_key?: string;
128
+ /** Thread/reply context */
129
+ in_reply_to?: string;
130
+ /** HTML version of the body, if available */
131
+ html?: string;
132
+ }
133
+ export interface VaultPutOptions {
134
+ /**
135
+ * Encrypted blob to store (typically base64url-encoded ciphertext).
136
+ * The server stores this opaque blob — it never sees plaintext.
137
+ * Use @agentlair/vault-crypto for client-side encryption.
138
+ */
139
+ ciphertext: string;
140
+ /** Optional metadata object (max 4KB) — stored in plaintext, visible in index */
141
+ metadata?: Record<string, unknown>;
142
+ }
143
+ export interface VaultPutResult {
144
+ key: string;
145
+ stored: boolean;
146
+ /** New version number (increments on each PUT) */
147
+ version: number;
148
+ created_at: string;
149
+ updated_at: string;
150
+ }
151
+ export interface VaultGetOptions {
152
+ /** Specific version to retrieve (default: latest) */
153
+ version?: number;
154
+ }
155
+ export interface VaultGetResult {
156
+ key: string;
157
+ /** The encrypted blob as stored */
158
+ ciphertext: string;
159
+ /** Same as ciphertext — v1 compatibility alias */
160
+ value: string;
161
+ metadata: Record<string, unknown> | null;
162
+ version: number;
163
+ latest_version: number;
164
+ created_at: string;
165
+ updated_at: string;
166
+ }
167
+ export interface VaultKeyInfo {
168
+ key: string;
169
+ version: number;
170
+ metadata: Record<string, unknown> | null;
171
+ created_at: string;
172
+ updated_at: string;
173
+ }
174
+ export interface VaultListResult {
175
+ keys: VaultKeyInfo[];
176
+ count: number;
177
+ /** Maximum keys allowed on this tier */
178
+ limit: number;
179
+ tier: string;
180
+ }
181
+ export interface VaultDeleteOptions {
182
+ /**
183
+ * Specific version to delete. If omitted, all versions are deleted.
184
+ */
185
+ version?: number;
186
+ }
187
+ export interface VaultDeleteResult {
188
+ key: string;
189
+ deleted: boolean;
190
+ /** Number of versions removed (when deleting all) */
191
+ versions_removed?: number;
192
+ /** Version removed (when deleting a single version) */
193
+ version_removed?: number;
194
+ }
195
+ export interface AgentLairClientOptions {
196
+ /**
197
+ * AgentLair API key (al_live_...).
198
+ * Not required for `createAccount()` which is called statically.
199
+ */
200
+ apiKey: string;
201
+ /**
202
+ * Base URL for the AgentLair API.
203
+ * @default "https://agentlair.dev"
204
+ */
205
+ baseUrl?: string;
206
+ }
207
+ export interface AgentLairErrorBody {
208
+ error: string;
209
+ message: string;
210
+ }
211
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB;IACnB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAID,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC/C,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAID,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @agentlair/sdk — Type definitions
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@agentlair/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Official TypeScript/JavaScript SDK for AgentLair — email, vault, and account management for AI agents. Zero dependencies. Works in Node, Bun, Deno, and browsers.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "test": "bun test",
22
+ "prepublishOnly": "bun run build"
23
+ },
24
+ "keywords": [
25
+ "agentlair",
26
+ "ai-agent",
27
+ "email",
28
+ "vault",
29
+ "sdk",
30
+ "typescript",
31
+ "zero-deps",
32
+ "agent-email",
33
+ "agent-secrets",
34
+ "web-crypto"
35
+ ],
36
+ "author": "AgentLair",
37
+ "license": "MIT",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/piiiico/agentlair-sdk"
41
+ },
42
+ "homepage": "https://agentlair.dev",
43
+ "bugs": {
44
+ "url": "https://github.com/piiiico/agentlair-sdk/issues"
45
+ },
46
+ "engines": {
47
+ "node": ">=18.0.0"
48
+ },
49
+ "devDependencies": {
50
+ "typescript": "^5.9.3"
51
+ }
52
+ }