agentic-notify 0.0.0-stage → 0.2.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/dist/cli.js ADDED
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ PACKAGE_NAME
4
+ } from "./chunk-3N77SYRA.js";
5
+ import {
6
+ ApiError,
7
+ createClient
8
+ } from "./chunk-FJPEUDTG.js";
9
+ import "./chunk-KJKM56FT.js";
10
+ import {
11
+ VERSION
12
+ } from "./chunk-6QCYA3X7.js";
13
+
14
+ // src/cli.ts
15
+ import { realpathSync } from "fs";
16
+ import { pathToFileURL } from "url";
17
+ function defaultIo() {
18
+ return { out: (l) => console.log(l), err: (l) => console.error(l), env: process.env };
19
+ }
20
+ var UsageError = class extends Error {
21
+ };
22
+ function helpText() {
23
+ return [
24
+ `${PACKAGE_NAME} ${VERSION}`,
25
+ "Notifications for humans and agents.",
26
+ "",
27
+ `Usage: ${PACKAGE_NAME} <command> [flags]`,
28
+ "",
29
+ "Commands:",
30
+ " list [--unread] [--limit <n>] [--cursor <c>] List your notifications.",
31
+ " get <id> Show one notification.",
32
+ " read <id> Mark one as read.",
33
+ " read-all Mark all as read.",
34
+ " unread-count Count unread.",
35
+ " digest [--since <ms>] Group unread by type.",
36
+ " prefs get Show your preferences.",
37
+ " prefs set --json <json> Replace your preferences.",
38
+ " send --to <kind:id> --type <t> --resource <kind:id> --body <text>",
39
+ " Send a notification.",
40
+ " export Print all data held about you.",
41
+ " erase --yes Delete all data held about you.",
42
+ " mcp Start the MCP server on stdio.",
43
+ "",
44
+ "Environment: NOTIFY_URL (server base url), NOTIFY_TOKEN (bearer token).",
45
+ "Flags: --help, -h; --version, -V."
46
+ ].join("\n");
47
+ }
48
+ function flags(args, known) {
49
+ const out = {};
50
+ const rest = [];
51
+ for (let i = 0; i < args.length; i++) {
52
+ const a = args[i];
53
+ if (!a.startsWith("--")) {
54
+ rest.push(a);
55
+ } else if (known.bool.includes(a.slice(2))) {
56
+ out[a.slice(2)] = true;
57
+ } else if (known.value.includes(a.slice(2)) && i + 1 < args.length) {
58
+ out[a.slice(2)] = args[++i];
59
+ } else {
60
+ throw new UsageError(`unknown or incomplete flag "${a}"`);
61
+ }
62
+ }
63
+ return { flags: out, rest };
64
+ }
65
+ function pair(text, what) {
66
+ const m = typeof text === "string" ? /^([^:]+):(.+)$/.exec(text) : null;
67
+ if (!m) throw new UsageError(`${what} must look like kind:id`);
68
+ return { kind: m[1], id: m[2] };
69
+ }
70
+ function int(text, what) {
71
+ if (text === void 0) return void 0;
72
+ const n = typeof text === "string" && /^\d+$/.test(text) ? Number(text) : Number.NaN;
73
+ if (!Number.isSafeInteger(n)) throw new UsageError(`${what} needs a whole number`);
74
+ return n;
75
+ }
76
+ async function runCli(argv, io = defaultIo()) {
77
+ const [cmd, ...args] = argv;
78
+ if (cmd === void 0 || cmd === "--help" || cmd === "-h") {
79
+ io.out(helpText());
80
+ return 0;
81
+ }
82
+ if (cmd === "--version" || cmd === "-V") {
83
+ io.out(VERSION);
84
+ return 0;
85
+ }
86
+ try {
87
+ if (cmd === "mcp") {
88
+ const { startMcp } = await import("./mcp.js");
89
+ await startMcp(io.env.NOTIFY_URL && io.env.NOTIFY_TOKEN ? client() : void 0);
90
+ return 0;
91
+ }
92
+ return await run();
93
+ } catch (error) {
94
+ if (error instanceof UsageError) {
95
+ io.err(error.message);
96
+ io.err(`Run "${PACKAGE_NAME} --help" for usage.`);
97
+ return 2;
98
+ }
99
+ if (error instanceof ApiError) {
100
+ io.err(error.message);
101
+ return 1;
102
+ }
103
+ throw error;
104
+ }
105
+ function client() {
106
+ const baseUrl = io.env.NOTIFY_URL;
107
+ const token = io.env.NOTIFY_TOKEN;
108
+ if (!baseUrl || !token) throw new UsageError("set NOTIFY_URL and NOTIFY_TOKEN");
109
+ return createClient({ baseUrl, token, fetch: io.fetch });
110
+ }
111
+ async function run() {
112
+ const print = (v) => io.out(JSON.stringify(v));
113
+ const one = (rest) => {
114
+ if (rest.length !== 1) throw new UsageError(`${cmd} needs one id`);
115
+ return rest[0];
116
+ };
117
+ const none = (a) => {
118
+ if (a.length > 0) throw new UsageError(`${cmd} takes no arguments`);
119
+ };
120
+ switch (cmd) {
121
+ case "list": {
122
+ const f = flags(args, { value: ["limit", "cursor"], bool: ["unread"] });
123
+ none(f.rest);
124
+ const c = client();
125
+ print(await c.list({
126
+ unreadOnly: f.flags.unread === true,
127
+ limit: int(f.flags.limit, "--limit"),
128
+ cursor: typeof f.flags.cursor === "string" ? f.flags.cursor : void 0
129
+ }));
130
+ return 0;
131
+ }
132
+ case "get":
133
+ print(await client().get(one(args)));
134
+ return 0;
135
+ case "read":
136
+ print(await client().markRead(one(args)));
137
+ return 0;
138
+ case "read-all":
139
+ none(args);
140
+ print(await client().markAllRead());
141
+ return 0;
142
+ case "unread-count":
143
+ none(args);
144
+ print(await client().unreadCount());
145
+ return 0;
146
+ case "digest": {
147
+ const f = flags(args, { value: ["since"], bool: [] });
148
+ none(f.rest);
149
+ print(await client().digest(int(f.flags.since, "--since")));
150
+ return 0;
151
+ }
152
+ case "prefs": {
153
+ const [sub, ...rest] = args;
154
+ if (sub === "get") {
155
+ none(rest);
156
+ print(await client().getPreferences());
157
+ return 0;
158
+ }
159
+ if (sub === "set") {
160
+ const f = flags(rest, { value: ["json"], bool: [] });
161
+ none(f.rest);
162
+ if (typeof f.flags.json !== "string") throw new UsageError("prefs set needs --json");
163
+ let parsed;
164
+ try {
165
+ parsed = JSON.parse(f.flags.json);
166
+ } catch {
167
+ throw new UsageError("--json is not valid JSON");
168
+ }
169
+ print(await client().setPreferences(parsed));
170
+ return 0;
171
+ }
172
+ throw new UsageError("prefs needs get or set");
173
+ }
174
+ case "send": {
175
+ const f = flags(args, { value: ["to", "type", "resource", "body", "url"], bool: [] });
176
+ none(f.rest);
177
+ if (typeof f.flags.type !== "string" || typeof f.flags.body !== "string") throw new UsageError("send needs --type and --body");
178
+ const to = pair(f.flags.to, "--to");
179
+ const res = pair(f.flags.resource, "--resource");
180
+ print(await client().send({
181
+ recipient: { kind: to.kind, id: to.id },
182
+ type: f.flags.type,
183
+ resource: { kind: res.kind, id: res.id, ...typeof f.flags.url === "string" ? { url: f.flags.url } : {} },
184
+ body: f.flags.body
185
+ }));
186
+ return 0;
187
+ }
188
+ case "export":
189
+ none(args);
190
+ print(await client().exportData());
191
+ return 0;
192
+ case "erase": {
193
+ const f = flags(args, { value: [], bool: ["yes"] });
194
+ none(f.rest);
195
+ if (f.flags.yes !== true) throw new UsageError("erase deletes all your data. Pass --yes to confirm");
196
+ print(await client().erase());
197
+ return 0;
198
+ }
199
+ default:
200
+ throw new UsageError(`unknown command "${cmd}"`);
201
+ }
202
+ }
203
+ }
204
+ function isMainModule() {
205
+ const invoked = process.argv[1];
206
+ if (typeof invoked !== "string") return false;
207
+ try {
208
+ return import.meta.url === pathToFileURL(realpathSync(invoked)).href;
209
+ } catch {
210
+ return false;
211
+ }
212
+ }
213
+ if (isMainModule()) {
214
+ runCli(process.argv.slice(2)).then(
215
+ (code) => {
216
+ if (code !== 0) process.exit(code);
217
+ },
218
+ (error) => {
219
+ console.error(error instanceof Error ? error.message : String(error));
220
+ process.exit(1);
221
+ }
222
+ );
223
+ }
224
+ export {
225
+ runCli
226
+ };
@@ -0,0 +1,77 @@
1
+ import { R as RecipientExport } from './gdpr-CUq5MUwo.js';
2
+ import { Store } from 'agentic-identity';
3
+ import { S as SendInput, N as Notification, C as Channel, R as Recipient, D as Digest, P as Preferences } from './types-C842YAMe.js';
4
+ import { D as DeliveryChannel, L as Logger } from './types-DONKNIOo.js';
5
+
6
+ interface NotifierOptions {
7
+ store: Store;
8
+ now?: () => number;
9
+ newId?: () => string;
10
+ /** Notifications older than this many milliseconds go on `sweep`. Unset keeps them. */
11
+ retentionMs?: number;
12
+ }
13
+ interface SendResult {
14
+ /** Null only when the recipient muted the type. */
15
+ notification: Notification | null;
16
+ /** True when the notification went to the inbox. Only then can `get` and `markRead` find its id. */
17
+ stored: boolean;
18
+ /** Channels the delivery layer must serve. Empty when muted. */
19
+ channels: Channel[];
20
+ muted: boolean;
21
+ }
22
+ interface ListOptions {
23
+ unreadOnly?: boolean;
24
+ limit?: number;
25
+ cursor?: string;
26
+ }
27
+ interface ListResult {
28
+ items: Notification[];
29
+ nextCursor: string | null;
30
+ }
31
+ declare class NotFoundError extends Error {
32
+ readonly code = "NOT_FOUND";
33
+ constructor(message?: string);
34
+ }
35
+ declare function createNotifier(options: NotifierOptions): {
36
+ send: (input: SendInput) => Promise<SendResult>;
37
+ list: (recipient: Recipient, opts?: ListOptions) => Promise<ListResult>;
38
+ get: (recipient: Recipient, id: string) => Promise<Notification>;
39
+ markRead: (recipient: Recipient, id: string) => Promise<Notification>;
40
+ markAllRead: (recipient: Recipient) => Promise<number>;
41
+ unreadCount: (recipient: Recipient) => Promise<number>;
42
+ digest: (recipient: Recipient, since?: number) => Promise<Digest>;
43
+ getPreferences: (recipient: Recipient) => Promise<Preferences>;
44
+ setPreferences: (recipient: Recipient, prefs: Preferences) => Promise<Preferences>;
45
+ parseType: (type: string) => string;
46
+ exportData: (recipient: Recipient) => Promise<RecipientExport>;
47
+ erase: (recipient: Recipient) => Promise<{
48
+ notifications: number;
49
+ }>;
50
+ sweep: () => Promise<number>;
51
+ };
52
+ type Notifier = ReturnType<typeof createNotifier>;
53
+
54
+ interface DispatchResult {
55
+ notification: Notification | null;
56
+ stored: boolean;
57
+ muted: boolean;
58
+ /** `skipped` means nothing was sent: the recipient has no target, or no channel is set up for it. */
59
+ deliveries: {
60
+ channel: Channel;
61
+ ok: boolean;
62
+ error?: string;
63
+ skipped?: "no_target" | "no_channel";
64
+ }[];
65
+ }
66
+ interface DispatcherOptions {
67
+ notifier: Notifier;
68
+ /** Channels other than the inbox. A channel with no entry is skipped. */
69
+ channels: Partial<Record<Exclude<Channel, "inbox">, DeliveryChannel>>;
70
+ logger?: Logger;
71
+ }
72
+ declare function createDispatcher(options: DispatcherOptions): {
73
+ /** Store in the inbox, then try each other channel the recipient chose. One failure never blocks the rest. */
74
+ notify(input: SendInput): Promise<DispatchResult>;
75
+ };
76
+
77
+ export { type DispatchResult as D, type ListOptions as L, NotFoundError as N, type SendResult as S, type DispatcherOptions as a, type ListResult as b, type Notifier as c, type NotifierOptions as d, createDispatcher as e, createNotifier as f };
@@ -0,0 +1,9 @@
1
+ import { R as Recipient, P as Preferences, N as Notification } from './types-C842YAMe.js';
2
+
3
+ interface RecipientExport {
4
+ recipient: Recipient;
5
+ preferences: Preferences | null;
6
+ notifications: Notification[];
7
+ }
8
+
9
+ export type { RecipientExport as R };
@@ -0,0 +1,45 @@
1
+ export { D as DispatchResult, a as DispatcherOptions, L as ListOptions, b as ListResult, N as NotFoundError, c as Notifier, d as NotifierOptions, S as SendResult, e as createDispatcher, f as createNotifier } from './dispatch-LBnkLOQg.js';
2
+ export { Doc, Page, Query, Scalar, Store, StoreOps, createMemoryStore } from 'agentic-identity';
3
+ import { R as Recipient } from './types-C842YAMe.js';
4
+ export { A as Actor, b as CHANNELS, C as Channel, c as DEFAULT_CHANNELS, D as Digest, d as DigestGroup, N as Notification, P as Preferences, a as ResourceRef, S as SendInput, e as defaultPreferences, r as recipientKey } from './types-C842YAMe.js';
5
+ import { D as DeliveryChannel } from './types-DONKNIOo.js';
6
+ export { a as DeliveryError, L as Logger } from './types-DONKNIOo.js';
7
+ export { E as EmailChannelOptions, a as EmailMessage, b as EmailPort, c as createEmailChannel } from './testing-B5slvYDV.js';
8
+ export { D1Like, D1_SCHEMA, createD1Store } from 'agentic-identity/cloudflare';
9
+ export { R as RecipientExport } from './gdpr-CUq5MUwo.js';
10
+ import 'zod';
11
+ import 'agentic-identity/testing';
12
+
13
+ declare const VERSION: string;
14
+
15
+ declare const SIGNATURE_HEADER = "x-notify-signature";
16
+ /** Header value: `t=<unix seconds>,v1=<hex hmac-sha256 of "<t>.<body>">`. */
17
+ declare function signPayload(secret: string, body: string, timestamp: number): Promise<string>;
18
+ /** Returns false for any malformed, stale, future or wrong signature. Throws only on a bad secret. */
19
+ declare function verifySignature(secret: string, body: string, header: string | null | undefined, options?: {
20
+ now?: number;
21
+ toleranceSeconds?: number;
22
+ }): Promise<boolean>;
23
+ interface WebhookTarget {
24
+ url: string;
25
+ secret: string;
26
+ }
27
+ interface WebhookOptions {
28
+ /** Find the endpoint for a recipient. Return null when none is set. */
29
+ resolve(recipient: Recipient): Promise<WebhookTarget | null> | WebhookTarget | null;
30
+ fetch?: typeof fetch;
31
+ maxAttempts?: number;
32
+ baseDelayMs?: number;
33
+ maxDelayMs?: number;
34
+ timeoutMs?: number;
35
+ /** Allow http:// targets. Off by default. */
36
+ allowInsecure?: boolean;
37
+ sleep?: (ms: number) => Promise<void>;
38
+ random?: () => number;
39
+ now?: () => number;
40
+ }
41
+ declare function createWebhookChannel(options: WebhookOptions): DeliveryChannel;
42
+
43
+ declare const PACKAGE_NAME = "agentic-notify";
44
+
45
+ export { DeliveryChannel, PACKAGE_NAME, Recipient, SIGNATURE_HEADER, VERSION, type WebhookOptions, type WebhookTarget, createWebhookChannel, signPayload, verifySignature };
package/dist/index.js ADDED
@@ -0,0 +1,44 @@
1
+ import {
2
+ D1_SCHEMA,
3
+ DeliveryError,
4
+ PACKAGE_NAME,
5
+ SIGNATURE_HEADER,
6
+ createD1Store,
7
+ createDispatcher,
8
+ createMemoryStore,
9
+ createWebhookChannel,
10
+ signPayload,
11
+ verifySignature
12
+ } from "./chunk-3N77SYRA.js";
13
+ import {
14
+ createEmailChannel
15
+ } from "./chunk-KJKM56FT.js";
16
+ import {
17
+ CHANNELS,
18
+ DEFAULT_CHANNELS,
19
+ NotFoundError,
20
+ VERSION,
21
+ createNotifier,
22
+ defaultPreferences,
23
+ recipientKey
24
+ } from "./chunk-6QCYA3X7.js";
25
+ export {
26
+ CHANNELS,
27
+ D1_SCHEMA,
28
+ DEFAULT_CHANNELS,
29
+ DeliveryError,
30
+ NotFoundError,
31
+ PACKAGE_NAME,
32
+ SIGNATURE_HEADER,
33
+ VERSION,
34
+ createD1Store,
35
+ createDispatcher,
36
+ createEmailChannel,
37
+ createMemoryStore,
38
+ createNotifier,
39
+ createWebhookChannel,
40
+ defaultPreferences,
41
+ recipientKey,
42
+ signPayload,
43
+ verifySignature
44
+ };
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ startMcp
4
+ } from "./chunk-POSHKDNY.js";
5
+ import "./chunk-3N77SYRA.js";
6
+ import {
7
+ createClient
8
+ } from "./chunk-FJPEUDTG.js";
9
+ import "./chunk-KJKM56FT.js";
10
+ import "./chunk-6QCYA3X7.js";
11
+
12
+ // src/mcp-bin.ts
13
+ var { NOTIFY_URL, NOTIFY_TOKEN } = process.env;
14
+ var client = NOTIFY_URL && NOTIFY_TOKEN ? createClient({ baseUrl: NOTIFY_URL, token: NOTIFY_TOKEN }) : void 0;
15
+ startMcp(client).catch((error) => {
16
+ console.error(error instanceof Error ? error.message : String(error));
17
+ process.exit(1);
18
+ });
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { Client } from './sdk.js';
3
+ import './types-C842YAMe.js';
4
+ import 'zod';
5
+ import './gdpr-CUq5MUwo.js';
6
+
7
+ /** Without a client, only `ping` works and the other tools report that setup is missing. */
8
+ declare function createMcpServer(client?: Client): McpServer;
9
+ declare function startMcp(client?: Client): Promise<void>;
10
+
11
+ export { createMcpServer, startMcp };
package/dist/mcp.js ADDED
@@ -0,0 +1,12 @@
1
+ import {
2
+ createMcpServer,
3
+ startMcp
4
+ } from "./chunk-POSHKDNY.js";
5
+ import "./chunk-3N77SYRA.js";
6
+ import "./chunk-FJPEUDTG.js";
7
+ import "./chunk-KJKM56FT.js";
8
+ import "./chunk-6QCYA3X7.js";
9
+ export {
10
+ createMcpServer,
11
+ startMcp
12
+ };
package/dist/sdk.d.ts ADDED
@@ -0,0 +1,110 @@
1
+ import { N as Notification, D as Digest, P as Preferences, R as Recipient, a as ResourceRef } from './types-C842YAMe.js';
2
+ import { R as RecipientExport } from './gdpr-CUq5MUwo.js';
3
+ import 'zod';
4
+
5
+ declare class ApiError extends Error {
6
+ readonly status: number;
7
+ readonly code: string;
8
+ constructor(status: number, code: string);
9
+ }
10
+ interface ClientOptions {
11
+ baseUrl: string;
12
+ token: string;
13
+ fetch?: typeof fetch;
14
+ }
15
+ interface SendRequest {
16
+ recipient: Recipient;
17
+ type: string;
18
+ resource: ResourceRef;
19
+ body: string;
20
+ }
21
+ interface SendResponse {
22
+ notification: Notification | null;
23
+ stored: boolean;
24
+ muted: boolean;
25
+ /** Channels the recipient chose. Absent when a dispatcher answers: see `deliveries`. */
26
+ channels?: string[];
27
+ /** Per channel outcome for the non-inbox channels. `skipped` means nothing was sent. */
28
+ deliveries: {
29
+ channel: string;
30
+ ok: boolean;
31
+ error?: string;
32
+ skipped?: "no_target" | "no_channel";
33
+ }[];
34
+ }
35
+ interface NotificationPage {
36
+ items: Notification[];
37
+ nextCursor: string | null;
38
+ }
39
+ declare function createClient(options: ClientOptions): {
40
+ list: (o?: {
41
+ unreadOnly?: boolean;
42
+ limit?: number;
43
+ cursor?: string;
44
+ }) => Promise<NotificationPage>;
45
+ get: (id: string) => Promise<{
46
+ type: string;
47
+ id: string;
48
+ recipient: {
49
+ id: string;
50
+ kind: "human" | "agent";
51
+ };
52
+ resource: {
53
+ id: string;
54
+ kind: string;
55
+ url?: string | undefined;
56
+ };
57
+ actor: {
58
+ id: string;
59
+ kind: "human" | "agent";
60
+ };
61
+ body: string;
62
+ createdAt: number;
63
+ readAt: number | null;
64
+ }>;
65
+ markRead: (id: string) => Promise<{
66
+ type: string;
67
+ id: string;
68
+ recipient: {
69
+ id: string;
70
+ kind: "human" | "agent";
71
+ };
72
+ resource: {
73
+ id: string;
74
+ kind: string;
75
+ url?: string | undefined;
76
+ };
77
+ actor: {
78
+ id: string;
79
+ kind: "human" | "agent";
80
+ };
81
+ body: string;
82
+ createdAt: number;
83
+ readAt: number | null;
84
+ }>;
85
+ markAllRead: () => Promise<{
86
+ marked: number;
87
+ }>;
88
+ unreadCount: () => Promise<{
89
+ count: number;
90
+ }>;
91
+ digest: (since?: number) => Promise<Digest>;
92
+ getPreferences: () => Promise<{
93
+ channels: Record<string, ("inbox" | "webhook" | "email")[]>;
94
+ muted: boolean;
95
+ mutedTypes: string[];
96
+ }>;
97
+ setPreferences: (prefs: Preferences) => Promise<{
98
+ channels: Record<string, ("inbox" | "webhook" | "email")[]>;
99
+ muted: boolean;
100
+ mutedTypes: string[];
101
+ }>;
102
+ send: (request: SendRequest) => Promise<SendResponse>;
103
+ exportData: () => Promise<RecipientExport>;
104
+ erase: () => Promise<{
105
+ notifications: number;
106
+ }>;
107
+ };
108
+ type Client = ReturnType<typeof createClient>;
109
+
110
+ export { ApiError, type Client, type ClientOptions, type NotificationPage, type SendRequest, type SendResponse, createClient };
package/dist/sdk.js ADDED
@@ -0,0 +1,8 @@
1
+ import {
2
+ ApiError,
3
+ createClient
4
+ } from "./chunk-FJPEUDTG.js";
5
+ export {
6
+ ApiError,
7
+ createClient
8
+ };
@@ -0,0 +1,27 @@
1
+ import 'agentic-identity/testing';
2
+ import { R as Recipient } from './types-C842YAMe.js';
3
+ import { D as DeliveryChannel } from './types-DONKNIOo.js';
4
+
5
+ interface EmailMessage {
6
+ to: string;
7
+ subject: string;
8
+ text: string;
9
+ }
10
+ /** Port for a mail provider. Real adapters live outside this package. */
11
+ interface EmailPort {
12
+ send(message: EmailMessage): Promise<void>;
13
+ }
14
+ /** Test adapter. Keeps sent messages in memory. */
15
+ declare class TestEmailAdapter implements EmailPort {
16
+ readonly sent: EmailMessage[];
17
+ failNext: number;
18
+ send(message: EmailMessage): Promise<void>;
19
+ }
20
+ interface EmailChannelOptions {
21
+ port: EmailPort;
22
+ /** Find the address for a recipient. Return null when none is set. */
23
+ resolveAddress(recipient: Recipient): Promise<string | null> | string | null;
24
+ }
25
+ declare function createEmailChannel(options: EmailChannelOptions): DeliveryChannel;
26
+
27
+ export { type EmailChannelOptions as E, TestEmailAdapter as T, type EmailMessage as a, type EmailPort as b, createEmailChannel as c };
@@ -0,0 +1,5 @@
1
+ export { runStoreContract } from 'agentic-identity/testing';
2
+ export { T as TestEmailAdapter } from './testing-B5slvYDV.js';
3
+ import './types-C842YAMe.js';
4
+ import 'zod';
5
+ import './types-DONKNIOo.js';
@@ -0,0 +1,10 @@
1
+ import {
2
+ TestEmailAdapter
3
+ } from "./chunk-KJKM56FT.js";
4
+
5
+ // src/testing.ts
6
+ import { runStoreContract } from "agentic-identity/testing";
7
+ export {
8
+ TestEmailAdapter,
9
+ runStoreContract
10
+ };