expectbox-agents 0.1.1
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/LICENSE +21 -0
- package/README.md +101 -0
- package/js/expectbox.d.mts +106 -0
- package/js/expectbox.mjs +160 -0
- package/package.json +36 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Expectbox
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Expectbox Agents SDK
|
|
2
|
+
|
|
3
|
+
[Website](https://www.expectbox.com/) · [Expectbox Agents](https://www.expectbox.com/agents/) · [API documentation](https://www.expectbox.com/agent-sdk/README.md) · [Releases](https://github.com/simon86pl/expectbox-sdk/releases)
|
|
4
|
+
|
|
5
|
+
Official JavaScript/TypeScript and Python clients for [Expectbox Agents](https://www.expectbox.com/agents/).
|
|
6
|
+
This repository contains the clients, examples and API contract; the hosted mail service is separate.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
Node.js 22+:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npm install expectbox-agents
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Python 3.10+:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
python -m pip install https://github.com/simon86pl/expectbox-sdk/releases/download/v0.1.1/expectbox_agents-0.1.1-py3-none-any.whl
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
JavaScript and TypeScript use the [npm package](https://www.npmjs.com/package/expectbox-agents). The Python command installs a versioned GitHub release artifact; PyPI publication is not enabled yet. See [release instructions](https://github.com/simon86pl/expectbox-sdk/blob/main/RELEASING.md).
|
|
23
|
+
|
|
24
|
+
## Before connecting
|
|
25
|
+
|
|
26
|
+
1. [Create an Agents account](https://www.expectbox.com/mail?product=agents&signup=1&view=agents) using your current external email, or sign in to an existing Expectbox account.
|
|
27
|
+
2. Verify the email code, then activate a separate Agents subscription or obtain admin-granted Agents access. Personal mailbox payment does not unlock Agents.
|
|
28
|
+
3. In Agents → Project API keys, create a key with the permissions you need. **Project keys (`exp_…`) belong on your backend. Individual agents receive scoped inbox keys (`exa_…`).**
|
|
29
|
+
|
|
30
|
+
Production provisioning also requires the operator to activate agent mail and DNS/DKIM. A disabled service returns HTTP 503; creating an account or installing this SDK does not enable mail delivery.
|
|
31
|
+
|
|
32
|
+
## Provision an agent (TypeScript / JavaScript)
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
import { ExpectboxProject, ExpectboxAgent } from 'expectbox-agents';
|
|
36
|
+
|
|
37
|
+
const project = new ExpectboxProject({ apiKey: process.env.EXPECTBOX_PROJECT_API_KEY });
|
|
38
|
+
const inbox = await project.createInbox({
|
|
39
|
+
name: 'Research assistant',
|
|
40
|
+
username: 'research',
|
|
41
|
+
mode: 'drafts',
|
|
42
|
+
senderManagementMode: 'restricted',
|
|
43
|
+
senderManagementAllow: ['updates.example.com'],
|
|
44
|
+
}, 'research-inbox-v1'); // Persist this key; reuse it only for the same operation.
|
|
45
|
+
|
|
46
|
+
const credential = await project.createInboxKey(inbox.id, {
|
|
47
|
+
name: 'Research runtime',
|
|
48
|
+
scopes: ['messages:read', 'drafts:write', 'events:read', 'senders:write'],
|
|
49
|
+
days: 90,
|
|
50
|
+
});
|
|
51
|
+
// Store credential.key in your secret manager. It is returned only once.
|
|
52
|
+
const agent = new ExpectboxAgent({ apiKey: credential.key });
|
|
53
|
+
await agent.allowSender(inbox.id, {
|
|
54
|
+
matchType: 'domain', matchValue: 'updates.example.com', reason: 'Requested research updates',
|
|
55
|
+
});
|
|
56
|
+
const page = await agent.messages(inbox.id, { limit: 20 });
|
|
57
|
+
console.log(page.items.length);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
New inboxes default to read-only with no approved senders, no sending and no sender-management delegation. Setting a delegation does not itself allow incoming mail: call `allowSender` or approve it in the panel. Existing owner blocks always take priority.
|
|
61
|
+
|
|
62
|
+
## Python
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import os
|
|
66
|
+
from expectbox_agents import ExpectboxProject, ExpectboxAgent
|
|
67
|
+
|
|
68
|
+
project = ExpectboxProject(os.environ['EXPECTBOX_PROJECT_API_KEY'])
|
|
69
|
+
inbox = project.create_inbox({'name': 'Research assistant', 'username': 'research'}, 'research-inbox-v1')
|
|
70
|
+
credential = project.create_inbox_key(inbox['id'], 'Research runtime', ['messages:read', 'events:read'])
|
|
71
|
+
# Store credential['key'] in your secret manager; never print it.
|
|
72
|
+
agent = ExpectboxAgent(credential['key'])
|
|
73
|
+
page = agent.messages(inbox['id'], limit=20)
|
|
74
|
+
print(len(page['items']))
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## API and guarantees
|
|
78
|
+
|
|
79
|
+
- Base URL: `https://www.expectbox.com/api/agents/v1`. Override `baseUrl` / `base_url` with an HTTPS origin for another deployment; HTTP is accepted only on localhost for tests.
|
|
80
|
+
- Project: `project()`, `inboxes()`, `createInbox()`, `createInboxKey()`, `revokeInboxKey()`; Python uses snake_case.
|
|
81
|
+
- Inbox: `inboxes()`, `messages()`, `message()`, `thread()`, `attachment()`, `draft()`, `editDraft()` / `edit_draft()`, `send()`, `reply()`, `events()`, `senders()`, `allowSender()` / `allow_sender()`.
|
|
82
|
+
- Messages use `items` and `next`. Pass `next.before` and `next.beforeId` to get the next page. Events return `items`, `cursor` and `retentionDays`; persist the cursor after processing.
|
|
83
|
+
- Delivery is queued, not guaranteed by a successful send response. Sending needs `messages:send`, inbox mode `send`, an approved recipient and available quota. Unknown incoming senders are rejected before storage.
|
|
84
|
+
- Inbox creation, sending and replies require your persisted idempotency key. Same key and content return the same result; changed content returns 409. Inbox keys are not idempotent: do not retry key creation blindly after a timeout; inspect/revoke unused keys in the panel.
|
|
85
|
+
- No automatic retries. Retry GETs with backoff; retry idempotent writes using the original key. Errors expose `.status` in JavaScript and standard `urllib.error.HTTPError.code` in Python.
|
|
86
|
+
- Timeouts default to 30 seconds. Configure `timeoutMs` (JS) or `timeout` in seconds (Python). Redirects are rejected so credentials cannot follow them to another origin.
|
|
87
|
+
- Keys expire and can be revoked. Project/inbox limits and paid access are checked by the server, not the SDK. Revoking a project key does not revoke inbox keys it issued; revoke those separately.
|
|
88
|
+
- Never include API keys in client-side apps, source control, logs or prompts. These clients do not execute email content or send messages automatically.
|
|
89
|
+
|
|
90
|
+
See [openapi.json](https://github.com/simon86pl/expectbox-sdk/blob/main/openapi.json) for the project management contract, TypeScript declarations for return types, and [examples](https://github.com/simon86pl/expectbox-sdk/tree/main/examples) for runnable entry points. The full inbox API is documented at [Expectbox](https://www.expectbox.com/agent-sdk/README.md).
|
|
91
|
+
|
|
92
|
+
## Contributing
|
|
93
|
+
|
|
94
|
+
No API key or external mail is needed for tests:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
npm test
|
|
98
|
+
python -m unittest discover -s tests -p '*_test.py'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The two clients share the API contract and local HTTP contract tests. They are maintained explicitly, not generated. Changes to routes or payloads must update the contract, both clients and tests together.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export interface Attachment {
|
|
2
|
+
filename: string;
|
|
3
|
+
contentType?: string;
|
|
4
|
+
content: string;
|
|
5
|
+
}
|
|
6
|
+
export interface Draft {
|
|
7
|
+
to?: string[];
|
|
8
|
+
cc?: string[];
|
|
9
|
+
bcc?: string[];
|
|
10
|
+
subject?: string;
|
|
11
|
+
text?: string;
|
|
12
|
+
attachments?: Attachment[];
|
|
13
|
+
replyToId?: string;
|
|
14
|
+
version?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface Queued {
|
|
17
|
+
id: string;
|
|
18
|
+
thread_id: string;
|
|
19
|
+
status: "queued";
|
|
20
|
+
}
|
|
21
|
+
export interface Message {
|
|
22
|
+
id: string;
|
|
23
|
+
thread_id: string;
|
|
24
|
+
subject: string;
|
|
25
|
+
body_text: string;
|
|
26
|
+
from_address: string;
|
|
27
|
+
revision: number;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
export interface SenderRule {
|
|
31
|
+
id: string;
|
|
32
|
+
match_type: "email" | "domain";
|
|
33
|
+
match_value: string;
|
|
34
|
+
policy: string;
|
|
35
|
+
paused: boolean;
|
|
36
|
+
paused_until: string | null;
|
|
37
|
+
}
|
|
38
|
+
export class ExpectboxAgent {
|
|
39
|
+
constructor(options: { apiKey: string; baseUrl?: string; timeoutMs?: number });
|
|
40
|
+
inboxes(): Promise<{
|
|
41
|
+
items: { id: string; email: string; name: string; mode: string }[];
|
|
42
|
+
}>;
|
|
43
|
+
senders(inbox: string): Promise<{ items: SenderRule[] }>;
|
|
44
|
+
allowSender(
|
|
45
|
+
inbox: string,
|
|
46
|
+
body: { matchType: "email" | "domain"; matchValue: string; reason: string },
|
|
47
|
+
): Promise<{ created: boolean; rule: SenderRule }>;
|
|
48
|
+
messages(
|
|
49
|
+
inbox: string,
|
|
50
|
+
query?: {
|
|
51
|
+
before?: string;
|
|
52
|
+
beforeId?: string;
|
|
53
|
+
q?: string;
|
|
54
|
+
limit?: number;
|
|
55
|
+
folder?: string;
|
|
56
|
+
},
|
|
57
|
+
): Promise<{
|
|
58
|
+
items: Message[];
|
|
59
|
+
next: { before: string; beforeId: string } | null;
|
|
60
|
+
}>;
|
|
61
|
+
message(inbox: string, id: string): Promise<Message>;
|
|
62
|
+
thread(inbox: string, id: string): Promise<{ items: Message[] }>;
|
|
63
|
+
attachment(inbox: string, id: string): Promise<Uint8Array>;
|
|
64
|
+
draft(inbox: string, body: Draft): Promise<Message>;
|
|
65
|
+
editDraft(
|
|
66
|
+
inbox: string,
|
|
67
|
+
id: string,
|
|
68
|
+
body: Draft & { version: number },
|
|
69
|
+
): Promise<Message>;
|
|
70
|
+
send(inbox: string, body: Draft, idempotencyKey: string): Promise<Queued>;
|
|
71
|
+
reply(
|
|
72
|
+
inbox: string,
|
|
73
|
+
id: string,
|
|
74
|
+
body: Pick<Draft, "text" | "attachments">,
|
|
75
|
+
idempotencyKey: string,
|
|
76
|
+
): Promise<Queued>;
|
|
77
|
+
events(cursor?: string): Promise<{
|
|
78
|
+
items: {
|
|
79
|
+
id: string;
|
|
80
|
+
type: string;
|
|
81
|
+
inbox_id: string;
|
|
82
|
+
message_id: string | null;
|
|
83
|
+
detail: Record<string, unknown>;
|
|
84
|
+
created_at: string;
|
|
85
|
+
}[];
|
|
86
|
+
cursor: string;
|
|
87
|
+
retentionDays: number;
|
|
88
|
+
}>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export type AgentScope = 'messages:read' | 'attachments:read' | 'drafts:write' | 'messages:send' | 'events:read' | 'senders:write';
|
|
92
|
+
export interface Inbox { id: string; email: string; name: string; }
|
|
93
|
+
export interface CreateInbox {
|
|
94
|
+
name: string; username: string;
|
|
95
|
+
mode?: 'read' | 'drafts' | 'send'; sendAllow?: string[];
|
|
96
|
+
senderManagementMode?: 'none' | 'restricted' | 'any'; senderManagementAllow?: string[];
|
|
97
|
+
}
|
|
98
|
+
export interface InboxKeyOptions { name: string; scopes: AgentScope[]; days?: number; }
|
|
99
|
+
export class ExpectboxProject {
|
|
100
|
+
constructor(options: { apiKey: string; baseUrl?: string; timeoutMs?: number });
|
|
101
|
+
project(): Promise<{ id: string; limits: { inboxes: number; monthly: number; daily: number; bytes: number }; usage: { incoming: number; outgoing: number } }>;
|
|
102
|
+
inboxes(): Promise<{ inboxes: (Inbox & { mode: string; paused: boolean; retired_at: string | null; created_at: string })[] }>;
|
|
103
|
+
createInbox(body: CreateInbox, idempotencyKey: string): Promise<Inbox>;
|
|
104
|
+
createInboxKey(inbox: string, body: InboxKeyOptions): Promise<{ id: string; key: string }>;
|
|
105
|
+
revokeInboxKey(inbox: string, key: string): Promise<{ ok: true }>;
|
|
106
|
+
}
|
package/js/expectbox.mjs
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
class Client {
|
|
2
|
+
constructor(
|
|
3
|
+
{ apiKey, baseUrl = "https://www.expectbox.com", timeoutMs = 30000 } = {},
|
|
4
|
+
prefix,
|
|
5
|
+
) {
|
|
6
|
+
const url = new URL(baseUrl);
|
|
7
|
+
if (
|
|
8
|
+
(url.protocol !== "https:" &&
|
|
9
|
+
!(
|
|
10
|
+
url.protocol === "http:" &&
|
|
11
|
+
["127.0.0.1", "localhost", "[::1]"].includes(url.hostname)
|
|
12
|
+
)) ||
|
|
13
|
+
url.username ||
|
|
14
|
+
url.password ||
|
|
15
|
+
url.search ||
|
|
16
|
+
url.hash ||
|
|
17
|
+
url.pathname !== "/"
|
|
18
|
+
)
|
|
19
|
+
throw new Error("Use an HTTPS origin or local test origin.");
|
|
20
|
+
if (!new RegExp(`^${prefix}_[a-zA-Z0-9_-]{43}$`).test(apiKey || ""))
|
|
21
|
+
throw new Error("Agent API key required.");
|
|
22
|
+
this.baseUrl = url.origin;
|
|
23
|
+
Object.defineProperty(this, "apiKey", { value: apiKey });
|
|
24
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 300000)
|
|
25
|
+
throw new Error("Invalid timeoutMs.");
|
|
26
|
+
this.timeoutMs = timeoutMs;
|
|
27
|
+
}
|
|
28
|
+
id(value) {
|
|
29
|
+
if (!/^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/i.test(value || ""))
|
|
30
|
+
throw new Error("Expected resource UUID.");
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
async request(
|
|
34
|
+
path,
|
|
35
|
+
{ method = "GET", body, idempotencyKey, binary = false } = {},
|
|
36
|
+
) {
|
|
37
|
+
const res = await fetch(this.baseUrl + "/api/agents/v1" + path, {
|
|
38
|
+
method,
|
|
39
|
+
redirect: "error",
|
|
40
|
+
signal: AbortSignal.timeout(this.timeoutMs),
|
|
41
|
+
headers: {
|
|
42
|
+
Authorization: "Bearer " + this.apiKey,
|
|
43
|
+
"Content-Type": "application/json",
|
|
44
|
+
...(idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {}),
|
|
45
|
+
},
|
|
46
|
+
...(body === undefined ? {} : { body: JSON.stringify(body) }),
|
|
47
|
+
});
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
const error = new Error("Expectbox API " + res.status);
|
|
50
|
+
error.status = res.status;
|
|
51
|
+
try {
|
|
52
|
+
error.message = (await res.json()).message || error.message;
|
|
53
|
+
} catch {}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
return binary ? new Uint8Array(await res.arrayBuffer()) : res.json();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export class ExpectboxAgent extends Client {
|
|
60
|
+
constructor(options) {
|
|
61
|
+
super(options, "exa");
|
|
62
|
+
}
|
|
63
|
+
inboxes() {
|
|
64
|
+
return this.request("/inboxes");
|
|
65
|
+
}
|
|
66
|
+
messages(inbox, query = {}) {
|
|
67
|
+
return this.request(
|
|
68
|
+
`/inboxes/${this.id(inbox)}/messages?` +
|
|
69
|
+
new URLSearchParams(
|
|
70
|
+
Object.entries(query).filter(([, v]) => v !== undefined),
|
|
71
|
+
),
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
message(inbox, id) {
|
|
75
|
+
return this.request(`/inboxes/${this.id(inbox)}/messages/${this.id(id)}`);
|
|
76
|
+
}
|
|
77
|
+
thread(inbox, id) {
|
|
78
|
+
return this.request(`/inboxes/${this.id(inbox)}/threads/${this.id(id)}`);
|
|
79
|
+
}
|
|
80
|
+
attachment(inbox, id) {
|
|
81
|
+
return this.request(
|
|
82
|
+
`/inboxes/${this.id(inbox)}/attachments/${this.id(id)}`,
|
|
83
|
+
{ binary: true },
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
draft(inbox, body) {
|
|
87
|
+
return this.request(`/inboxes/${this.id(inbox)}/drafts`, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
body,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
editDraft(inbox, id, body) {
|
|
93
|
+
return this.request(`/inboxes/${this.id(inbox)}/drafts/${this.id(id)}`, {
|
|
94
|
+
method: "PUT",
|
|
95
|
+
body,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
send(inbox, body, idempotencyKey) {
|
|
99
|
+
if (!idempotencyKey)
|
|
100
|
+
throw new Error("Persist an idempotency key before sending.");
|
|
101
|
+
return this.request(`/inboxes/${this.id(inbox)}/send`, {
|
|
102
|
+
method: "POST",
|
|
103
|
+
body,
|
|
104
|
+
idempotencyKey,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
reply(inbox, id, body, idempotencyKey) {
|
|
108
|
+
if (!idempotencyKey)
|
|
109
|
+
throw new Error("Persist an idempotency key before replying.");
|
|
110
|
+
return this.request(
|
|
111
|
+
`/inboxes/${this.id(inbox)}/messages/${this.id(id)}/reply`,
|
|
112
|
+
{ method: "POST", body, idempotencyKey },
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
events(cursor = "0") {
|
|
116
|
+
return this.request("/events?" + new URLSearchParams({ cursor }));
|
|
117
|
+
}
|
|
118
|
+
senders(inbox) {
|
|
119
|
+
return this.request(`/inboxes/${this.id(inbox)}/senders`);
|
|
120
|
+
}
|
|
121
|
+
allowSender(inbox, body) {
|
|
122
|
+
return this.request(`/inboxes/${this.id(inbox)}/senders`, {
|
|
123
|
+
method: "POST",
|
|
124
|
+
body,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export class ExpectboxProject extends Client {
|
|
130
|
+
constructor(options) {
|
|
131
|
+
super(options, "exp");
|
|
132
|
+
}
|
|
133
|
+
project() {
|
|
134
|
+
return this.request("/project");
|
|
135
|
+
}
|
|
136
|
+
inboxes() {
|
|
137
|
+
return this.request("/project/inboxes");
|
|
138
|
+
}
|
|
139
|
+
createInbox(body, idempotencyKey) {
|
|
140
|
+
if (!idempotencyKey)
|
|
141
|
+
throw new Error("Persist an idempotency key before creating an inbox.");
|
|
142
|
+
return this.request("/project/inboxes", {
|
|
143
|
+
method: "POST",
|
|
144
|
+
body,
|
|
145
|
+
idempotencyKey,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
createInboxKey(inbox, body) {
|
|
149
|
+
return this.request(`/project/inboxes/${this.id(inbox)}/keys`, {
|
|
150
|
+
method: "POST",
|
|
151
|
+
body,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
revokeInboxKey(inbox, key) {
|
|
155
|
+
return this.request(
|
|
156
|
+
`/project/inboxes/${this.id(inbox)}/keys/${this.id(key)}`,
|
|
157
|
+
{ method: "DELETE" },
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "expectbox-agents",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Scoped email inboxes for agents: Expectbox TypeScript and JavaScript SDK",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./js/expectbox.mjs",
|
|
7
|
+
"types": "./js/expectbox.d.mts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./js/expectbox.d.mts",
|
|
11
|
+
"import": "./js/expectbox.mjs",
|
|
12
|
+
"default": "./js/expectbox.mjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"js/",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=22"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"test": "node --test tests/*.test.mjs"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/simon86pl/expectbox-sdk.git"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://www.expectbox.com/",
|
|
32
|
+
"bugs": "https://github.com/simon86pl/expectbox-sdk/issues",
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
}
|
|
36
|
+
}
|