swarm-mail 0.1.0 → 0.1.2
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 +28 -0
- package/dist/adapter.d.ts +36 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23131 -0
- package/{src/pglite.ts → dist/pglite.d.ts} +7 -93
- package/dist/pglite.d.ts.map +1 -0
- package/dist/streams/agent-mail.d.ts +139 -0
- package/dist/streams/agent-mail.d.ts.map +1 -0
- package/dist/streams/debug.d.ts +173 -0
- package/dist/streams/debug.d.ts.map +1 -0
- package/dist/streams/effect/ask.d.ts +124 -0
- package/dist/streams/effect/ask.d.ts.map +1 -0
- package/dist/streams/effect/cursor.d.ts +87 -0
- package/dist/streams/effect/cursor.d.ts.map +1 -0
- package/dist/streams/effect/deferred.d.ts +108 -0
- package/dist/streams/effect/deferred.d.ts.map +1 -0
- package/{src/streams/effect/index.ts → dist/streams/effect/index.d.ts} +1 -0
- package/dist/streams/effect/index.d.ts.map +1 -0
- package/{src/streams/effect/layers.ts → dist/streams/effect/layers.d.ts} +8 -33
- package/dist/streams/effect/layers.d.ts.map +1 -0
- package/dist/streams/effect/lock.d.ts +137 -0
- package/dist/streams/effect/lock.d.ts.map +1 -0
- package/dist/streams/effect/mailbox.d.ts +98 -0
- package/dist/streams/effect/mailbox.d.ts.map +1 -0
- package/dist/streams/events.d.ts +487 -0
- package/dist/streams/events.d.ts.map +1 -0
- package/dist/streams/index.d.ts +106 -0
- package/dist/streams/index.d.ts.map +1 -0
- package/dist/streams/migrations.d.ts +102 -0
- package/dist/streams/migrations.d.ts.map +1 -0
- package/dist/streams/projections.d.ts +173 -0
- package/dist/streams/projections.d.ts.map +1 -0
- package/dist/streams/store.d.ts +171 -0
- package/dist/streams/store.d.ts.map +1 -0
- package/dist/streams/swarm-mail.d.ts +153 -0
- package/dist/streams/swarm-mail.d.ts.map +1 -0
- package/dist/types/adapter.d.ts +267 -0
- package/dist/types/adapter.d.ts.map +1 -0
- package/dist/types/database.d.ts +117 -0
- package/dist/types/database.d.ts.map +1 -0
- package/{src/types/index.ts → dist/types/index.d.ts} +2 -15
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +20 -4
- package/src/adapter.ts +0 -306
- package/src/index.ts +0 -57
- package/src/streams/agent-mail.test.ts +0 -777
- package/src/streams/agent-mail.ts +0 -535
- package/src/streams/debug.test.ts +0 -500
- package/src/streams/debug.ts +0 -727
- package/src/streams/effect/ask.integration.test.ts +0 -314
- package/src/streams/effect/ask.ts +0 -202
- package/src/streams/effect/cursor.integration.test.ts +0 -418
- package/src/streams/effect/cursor.ts +0 -288
- package/src/streams/effect/deferred.test.ts +0 -357
- package/src/streams/effect/deferred.ts +0 -445
- package/src/streams/effect/lock.test.ts +0 -385
- package/src/streams/effect/lock.ts +0 -399
- package/src/streams/effect/mailbox.test.ts +0 -260
- package/src/streams/effect/mailbox.ts +0 -318
- package/src/streams/events.test.ts +0 -924
- package/src/streams/events.ts +0 -329
- package/src/streams/index.test.ts +0 -229
- package/src/streams/index.ts +0 -578
- package/src/streams/migrations.test.ts +0 -359
- package/src/streams/migrations.ts +0 -362
- package/src/streams/projections.test.ts +0 -611
- package/src/streams/projections.ts +0 -564
- package/src/streams/store.integration.test.ts +0 -658
- package/src/streams/store.ts +0 -1129
- package/src/streams/swarm-mail.ts +0 -552
- package/src/types/adapter.ts +0 -392
- package/src/types/database.ts +0 -127
- package/tsconfig.json +0 -22
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SwarmMailAdapter - High-level interface for swarm-mail operations
|
|
3
|
+
*
|
|
4
|
+
* This interface abstracts all swarm-mail operations (events, messaging,
|
|
5
|
+
* reservations, locks) to enable different storage backends.
|
|
6
|
+
*
|
|
7
|
+
* ## Design Goals
|
|
8
|
+
* - Database-agnostic (works with PGLite, SQLite, PostgreSQL, etc.)
|
|
9
|
+
* - Matches existing swarm-mail API surface
|
|
10
|
+
* - No implementation details leak through interface
|
|
11
|
+
*
|
|
12
|
+
* ## Layering
|
|
13
|
+
* - DatabaseAdapter: Low-level SQL execution
|
|
14
|
+
* - SwarmMailAdapter: High-level swarm-mail operations (uses DatabaseAdapter internally)
|
|
15
|
+
* - Plugin tools: Type-safe Zod-validated wrappers (use SwarmMailAdapter)
|
|
16
|
+
*/
|
|
17
|
+
import type { AgentEvent, AgentRegisteredEvent, FileReservedEvent, MessageSentEvent } from "../streams/events";
|
|
18
|
+
import type { DatabaseAdapter } from "./database";
|
|
19
|
+
export interface ReadEventsOptions {
|
|
20
|
+
projectKey?: string;
|
|
21
|
+
types?: AgentEvent["type"][];
|
|
22
|
+
since?: number;
|
|
23
|
+
until?: number;
|
|
24
|
+
afterSequence?: number;
|
|
25
|
+
limit?: number;
|
|
26
|
+
offset?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface EventStoreAdapter {
|
|
29
|
+
/**
|
|
30
|
+
* Append a single event to the log
|
|
31
|
+
*
|
|
32
|
+
* Updates materialized views automatically.
|
|
33
|
+
*/
|
|
34
|
+
appendEvent(event: AgentEvent, projectPath?: string): Promise<AgentEvent & {
|
|
35
|
+
id: number;
|
|
36
|
+
sequence: number;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Append multiple events in a transaction
|
|
40
|
+
*
|
|
41
|
+
* Atomic - all events succeed or all fail.
|
|
42
|
+
*/
|
|
43
|
+
appendEvents(events: AgentEvent[], projectPath?: string): Promise<Array<AgentEvent & {
|
|
44
|
+
id: number;
|
|
45
|
+
sequence: number;
|
|
46
|
+
}>>;
|
|
47
|
+
/**
|
|
48
|
+
* Read events with filters
|
|
49
|
+
*/
|
|
50
|
+
readEvents(options?: ReadEventsOptions, projectPath?: string): Promise<Array<AgentEvent & {
|
|
51
|
+
id: number;
|
|
52
|
+
sequence: number;
|
|
53
|
+
}>>;
|
|
54
|
+
/**
|
|
55
|
+
* Get the latest sequence number for a project
|
|
56
|
+
*/
|
|
57
|
+
getLatestSequence(projectKey?: string, projectPath?: string): Promise<number>;
|
|
58
|
+
/**
|
|
59
|
+
* Replay events to rebuild materialized views
|
|
60
|
+
*/
|
|
61
|
+
replayEvents(options?: {
|
|
62
|
+
projectKey?: string;
|
|
63
|
+
fromSequence?: number;
|
|
64
|
+
clearViews?: boolean;
|
|
65
|
+
}, projectPath?: string): Promise<{
|
|
66
|
+
eventsReplayed: number;
|
|
67
|
+
duration: number;
|
|
68
|
+
}>;
|
|
69
|
+
}
|
|
70
|
+
export interface AgentAdapter {
|
|
71
|
+
/**
|
|
72
|
+
* Register an agent for a project
|
|
73
|
+
*/
|
|
74
|
+
registerAgent(projectKey: string, agentName: string, options?: {
|
|
75
|
+
program?: string;
|
|
76
|
+
model?: string;
|
|
77
|
+
taskDescription?: string;
|
|
78
|
+
}, projectPath?: string): Promise<AgentRegisteredEvent & {
|
|
79
|
+
id: number;
|
|
80
|
+
sequence: number;
|
|
81
|
+
}>;
|
|
82
|
+
/**
|
|
83
|
+
* Get all agents for a project
|
|
84
|
+
*/
|
|
85
|
+
getAgents(projectKey: string, projectPath?: string): Promise<Array<{
|
|
86
|
+
id: number;
|
|
87
|
+
name: string;
|
|
88
|
+
program: string;
|
|
89
|
+
model: string;
|
|
90
|
+
task_description: string | null;
|
|
91
|
+
registered_at: number;
|
|
92
|
+
last_active_at: number;
|
|
93
|
+
}>>;
|
|
94
|
+
/**
|
|
95
|
+
* Get a specific agent by name
|
|
96
|
+
*/
|
|
97
|
+
getAgent(projectKey: string, agentName: string, projectPath?: string): Promise<{
|
|
98
|
+
id: number;
|
|
99
|
+
name: string;
|
|
100
|
+
program: string;
|
|
101
|
+
model: string;
|
|
102
|
+
task_description: string | null;
|
|
103
|
+
registered_at: number;
|
|
104
|
+
last_active_at: number;
|
|
105
|
+
} | null>;
|
|
106
|
+
}
|
|
107
|
+
export interface InboxOptions {
|
|
108
|
+
limit?: number;
|
|
109
|
+
urgentOnly?: boolean;
|
|
110
|
+
unreadOnly?: boolean;
|
|
111
|
+
includeBodies?: boolean;
|
|
112
|
+
sinceTs?: string;
|
|
113
|
+
}
|
|
114
|
+
export interface Message {
|
|
115
|
+
id: number;
|
|
116
|
+
from_agent: string;
|
|
117
|
+
subject: string;
|
|
118
|
+
body?: string;
|
|
119
|
+
thread_id: string | null;
|
|
120
|
+
importance: string;
|
|
121
|
+
ack_required: boolean;
|
|
122
|
+
created_at: number;
|
|
123
|
+
read_at?: number | null;
|
|
124
|
+
acked_at?: number | null;
|
|
125
|
+
}
|
|
126
|
+
export interface MessagingAdapter {
|
|
127
|
+
/**
|
|
128
|
+
* Send a message to other agents
|
|
129
|
+
*/
|
|
130
|
+
sendMessage(projectKey: string, fromAgent: string, toAgents: string[], subject: string, body: string, options?: {
|
|
131
|
+
threadId?: string;
|
|
132
|
+
importance?: "low" | "normal" | "high" | "urgent";
|
|
133
|
+
ackRequired?: boolean;
|
|
134
|
+
}, projectPath?: string): Promise<MessageSentEvent & {
|
|
135
|
+
id: number;
|
|
136
|
+
sequence: number;
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Get inbox messages for an agent
|
|
140
|
+
*/
|
|
141
|
+
getInbox(projectKey: string, agentName: string, options?: InboxOptions, projectPath?: string): Promise<Message[]>;
|
|
142
|
+
/**
|
|
143
|
+
* Get a single message by ID
|
|
144
|
+
*/
|
|
145
|
+
getMessage(projectKey: string, messageId: number, projectPath?: string): Promise<Message | null>;
|
|
146
|
+
/**
|
|
147
|
+
* Get all messages in a thread
|
|
148
|
+
*/
|
|
149
|
+
getThreadMessages(projectKey: string, threadId: string, projectPath?: string): Promise<Message[]>;
|
|
150
|
+
/**
|
|
151
|
+
* Mark a message as read
|
|
152
|
+
*/
|
|
153
|
+
markMessageAsRead(projectKey: string, messageId: number, agentName: string, projectPath?: string): Promise<void>;
|
|
154
|
+
/**
|
|
155
|
+
* Acknowledge a message
|
|
156
|
+
*/
|
|
157
|
+
acknowledgeMessage(projectKey: string, messageId: number, agentName: string, projectPath?: string): Promise<void>;
|
|
158
|
+
}
|
|
159
|
+
export interface Reservation {
|
|
160
|
+
id: number;
|
|
161
|
+
agent_name: string;
|
|
162
|
+
path_pattern: string;
|
|
163
|
+
exclusive: boolean;
|
|
164
|
+
reason: string | null;
|
|
165
|
+
created_at: number;
|
|
166
|
+
expires_at: number;
|
|
167
|
+
}
|
|
168
|
+
export interface Conflict {
|
|
169
|
+
path: string;
|
|
170
|
+
holder: string;
|
|
171
|
+
pattern: string;
|
|
172
|
+
exclusive: boolean;
|
|
173
|
+
}
|
|
174
|
+
export interface ReservationAdapter {
|
|
175
|
+
/**
|
|
176
|
+
* Reserve files for exclusive editing
|
|
177
|
+
*/
|
|
178
|
+
reserveFiles(projectKey: string, agentName: string, paths: string[], options?: {
|
|
179
|
+
reason?: string;
|
|
180
|
+
exclusive?: boolean;
|
|
181
|
+
ttlSeconds?: number;
|
|
182
|
+
}, projectPath?: string): Promise<FileReservedEvent & {
|
|
183
|
+
id: number;
|
|
184
|
+
sequence: number;
|
|
185
|
+
}>;
|
|
186
|
+
/**
|
|
187
|
+
* Release file reservations
|
|
188
|
+
*/
|
|
189
|
+
releaseFiles(projectKey: string, agentName: string, options?: {
|
|
190
|
+
paths?: string[];
|
|
191
|
+
reservationIds?: number[];
|
|
192
|
+
}, projectPath?: string): Promise<void>;
|
|
193
|
+
/**
|
|
194
|
+
* Get active reservations for a project
|
|
195
|
+
*/
|
|
196
|
+
getActiveReservations(projectKey: string, projectPath?: string, agentName?: string): Promise<Reservation[]>;
|
|
197
|
+
/**
|
|
198
|
+
* Check for conflicts with existing reservations
|
|
199
|
+
*/
|
|
200
|
+
checkConflicts(projectKey: string, agentName: string, paths: string[], projectPath?: string): Promise<Conflict[]>;
|
|
201
|
+
}
|
|
202
|
+
export interface SchemaAdapter {
|
|
203
|
+
/**
|
|
204
|
+
* Run database migrations
|
|
205
|
+
*
|
|
206
|
+
* Initializes tables, indexes, and constraints.
|
|
207
|
+
*/
|
|
208
|
+
runMigrations(projectPath?: string): Promise<void>;
|
|
209
|
+
/**
|
|
210
|
+
* Check if database is healthy
|
|
211
|
+
*/
|
|
212
|
+
healthCheck(projectPath?: string): Promise<boolean>;
|
|
213
|
+
/**
|
|
214
|
+
* Get database statistics
|
|
215
|
+
*/
|
|
216
|
+
getDatabaseStats(projectPath?: string): Promise<{
|
|
217
|
+
events: number;
|
|
218
|
+
agents: number;
|
|
219
|
+
messages: number;
|
|
220
|
+
reservations: number;
|
|
221
|
+
}>;
|
|
222
|
+
/**
|
|
223
|
+
* Reset database for testing
|
|
224
|
+
*
|
|
225
|
+
* Clears all data but keeps schema.
|
|
226
|
+
*/
|
|
227
|
+
resetDatabase(projectPath?: string): Promise<void>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* SwarmMailAdapter - Complete interface for swarm-mail operations
|
|
231
|
+
*
|
|
232
|
+
* Combines all sub-adapters into a single interface.
|
|
233
|
+
* Implementations provide a DatabaseAdapter and implement all operations.
|
|
234
|
+
*/
|
|
235
|
+
export interface SwarmMailAdapter extends EventStoreAdapter, AgentAdapter, MessagingAdapter, ReservationAdapter, SchemaAdapter {
|
|
236
|
+
/**
|
|
237
|
+
* Get the underlying database adapter
|
|
238
|
+
*/
|
|
239
|
+
getDatabase(projectPath?: string): Promise<DatabaseAdapter>;
|
|
240
|
+
/**
|
|
241
|
+
* Close the database connection
|
|
242
|
+
*/
|
|
243
|
+
close(projectPath?: string): Promise<void>;
|
|
244
|
+
/**
|
|
245
|
+
* Close all database connections
|
|
246
|
+
*/
|
|
247
|
+
closeAll(): Promise<void>;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* SwarmMailAdapterFactory - Function that creates a SwarmMailAdapter instance
|
|
251
|
+
*
|
|
252
|
+
* Adapters export a factory function with this signature.
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```typescript
|
|
256
|
+
* import { createPGLiteAdapter } from '@opencode/swarm-mail/adapters/pglite';
|
|
257
|
+
* import { createSQLiteAdapter } from '@opencode/swarm-mail/adapters/sqlite';
|
|
258
|
+
*
|
|
259
|
+
* const adapter = createPGLiteAdapter({ path: './streams.db' });
|
|
260
|
+
* const adapter2 = createSQLiteAdapter({ path: './streams.db' });
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
export type SwarmMailAdapterFactory = (config: {
|
|
264
|
+
path?: string;
|
|
265
|
+
timeout?: number;
|
|
266
|
+
}) => SwarmMailAdapter;
|
|
267
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/types/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DatabaseAdapter - Database-agnostic interface for swarm-mail
|
|
3
|
+
*
|
|
4
|
+
* Abstracts PGLite-specific operations to support multiple database backends.
|
|
5
|
+
* Based on coursebuilder's adapter-drizzle pattern.
|
|
6
|
+
*
|
|
7
|
+
* ## Design Goals
|
|
8
|
+
* - Zero PGLite types in this interface
|
|
9
|
+
* - Support for PGLite, better-sqlite3, libsql, PostgreSQL
|
|
10
|
+
* - Transaction support optional (some adapters may not support it)
|
|
11
|
+
*
|
|
12
|
+
* ## Implementation Strategy
|
|
13
|
+
* - Accept database instance via dependency injection
|
|
14
|
+
* - Adapters implement this interface for their specific database
|
|
15
|
+
* - Query results use plain objects (no driver-specific types)
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Query result with rows array
|
|
19
|
+
*
|
|
20
|
+
* All database adapters return results in this shape.
|
|
21
|
+
*/
|
|
22
|
+
export interface QueryResult<T = unknown> {
|
|
23
|
+
/** Array of result rows */
|
|
24
|
+
rows: T[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* DatabaseAdapter interface
|
|
28
|
+
*
|
|
29
|
+
* Minimal interface for executing SQL queries and managing transactions.
|
|
30
|
+
* Adapters implement this for PGLite, SQLite, PostgreSQL, etc.
|
|
31
|
+
*/
|
|
32
|
+
export interface DatabaseAdapter {
|
|
33
|
+
/**
|
|
34
|
+
* Execute a query and return results
|
|
35
|
+
*
|
|
36
|
+
* @param sql - SQL query string (parameterized)
|
|
37
|
+
* @param params - Query parameters ($1, $2, etc.)
|
|
38
|
+
* @returns Query result with rows array
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const result = await db.query<{ id: number }>(
|
|
43
|
+
* "SELECT id FROM agents WHERE name = $1",
|
|
44
|
+
* ["BlueLake"]
|
|
45
|
+
* );
|
|
46
|
+
* const id = result.rows[0]?.id;
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
query<T = unknown>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
|
|
50
|
+
/**
|
|
51
|
+
* Execute a SQL statement without returning results
|
|
52
|
+
*
|
|
53
|
+
* Used for DDL (CREATE TABLE, etc.), DML (INSERT/UPDATE/DELETE), and transactions.
|
|
54
|
+
*
|
|
55
|
+
* @param sql - SQL statement(s) to execute
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* await db.exec("BEGIN");
|
|
60
|
+
* await db.exec("COMMIT");
|
|
61
|
+
* await db.exec("CREATE TABLE users (id SERIAL PRIMARY KEY)");
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
exec(sql: string): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Execute a function within a transaction (optional)
|
|
67
|
+
*
|
|
68
|
+
* If the adapter doesn't support transactions, it can omit this method
|
|
69
|
+
* or throw an error. The swarm-mail layer will handle transaction
|
|
70
|
+
* fallback (using manual BEGIN/COMMIT/ROLLBACK).
|
|
71
|
+
*
|
|
72
|
+
* @param fn - Function to execute within transaction context
|
|
73
|
+
* @returns Result of the function
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* const result = await db.transaction?.(async (tx) => {
|
|
78
|
+
* await tx.query("INSERT INTO events ...", [...]);
|
|
79
|
+
* await tx.query("UPDATE agents ...", [...]);
|
|
80
|
+
* return { success: true };
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
transaction?<T>(fn: (tx: DatabaseAdapter) => Promise<T>): Promise<T>;
|
|
85
|
+
/**
|
|
86
|
+
* Close the database connection (optional)
|
|
87
|
+
*
|
|
88
|
+
* Some adapters (like PGLite) need explicit cleanup.
|
|
89
|
+
* If not provided, swarm-mail assumes connection is managed externally.
|
|
90
|
+
*/
|
|
91
|
+
close?(): Promise<void>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Database configuration options
|
|
95
|
+
*
|
|
96
|
+
* Passed to adapter factory functions to create DatabaseAdapter instances.
|
|
97
|
+
*/
|
|
98
|
+
export interface DatabaseConfig {
|
|
99
|
+
/** Path to database file or connection string */
|
|
100
|
+
path: string;
|
|
101
|
+
/** Optional timeout in milliseconds for queries */
|
|
102
|
+
timeout?: number;
|
|
103
|
+
/** Optional flags for database initialization */
|
|
104
|
+
flags?: {
|
|
105
|
+
/** Create database if it doesn't exist */
|
|
106
|
+
create?: boolean;
|
|
107
|
+
/** Enable foreign key constraints */
|
|
108
|
+
foreignKeys?: boolean;
|
|
109
|
+
/** Enable WAL mode (SQLite) */
|
|
110
|
+
wal?: boolean;
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Type guard to check if adapter supports transactions
|
|
115
|
+
*/
|
|
116
|
+
export declare function supportsTransactions(adapter: DatabaseAdapter): adapter is Required<Pick<DatabaseAdapter, "transaction">> & DatabaseAdapter;
|
|
117
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/types/database.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;GAIG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACvC,2BAA2B;IAC3B,IAAI,EAAE,CAAC,EAAE,CAAC;CACV;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC/B;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7E;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjC;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAErE;;;;;OAKG;IACH,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,KAAK,CAAC,EAAE;QACP,0CAA0C;QAC1C,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,qCAAqC;QACrC,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,+BAA+B;QAC/B,GAAG,CAAC,EAAE,OAAO,CAAC;KACd,CAAC;CACF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,eAAe,GACtB,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC,GAAG,eAAe,CAE7E"}
|
|
@@ -7,20 +7,7 @@
|
|
|
7
7
|
* import type { DatabaseAdapter, SwarmMailAdapter } from '@opencode/swarm-mail/types';
|
|
8
8
|
* ```
|
|
9
9
|
*/
|
|
10
|
-
|
|
11
|
-
export type {
|
|
12
|
-
AgentAdapter,
|
|
13
|
-
Conflict,
|
|
14
|
-
EventStoreAdapter,
|
|
15
|
-
InboxOptions,
|
|
16
|
-
Message,
|
|
17
|
-
MessagingAdapter,
|
|
18
|
-
ReadEventsOptions,
|
|
19
|
-
Reservation,
|
|
20
|
-
ReservationAdapter,
|
|
21
|
-
SchemaAdapter,
|
|
22
|
-
SwarmMailAdapter,
|
|
23
|
-
SwarmMailAdapterFactory,
|
|
24
|
-
} from "./adapter";
|
|
10
|
+
export type { AgentAdapter, Conflict, EventStoreAdapter, InboxOptions, Message, MessagingAdapter, ReadEventsOptions, Reservation, ReservationAdapter, SchemaAdapter, SwarmMailAdapter, SwarmMailAdapterFactory, } from "./adapter";
|
|
25
11
|
export type { DatabaseAdapter, DatabaseConfig, QueryResult } from "./database";
|
|
26
12
|
export { supportsTransactions } from "./database";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY,EACX,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,23 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swarm-mail",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Event sourcing primitives for multi-agent coordination. Local-first, no external servers.",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"main": "./dist/index.js",
|
|
6
7
|
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
7
12
|
"exports": {
|
|
8
13
|
".": {
|
|
9
14
|
"import": "./dist/index.js",
|
|
10
15
|
"types": "./dist/index.d.ts"
|
|
11
16
|
}
|
|
12
17
|
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/joelhooks/opencode-swarm-plugin"
|
|
21
|
+
},
|
|
22
|
+
"author": "Joel Hooks",
|
|
23
|
+
"license": "MIT",
|
|
13
24
|
"scripts": {
|
|
14
25
|
"build": "bun build ./src/index.ts --outdir ./dist --target node && tsc",
|
|
15
|
-
"test": "vitest run",
|
|
16
|
-
"
|
|
26
|
+
"test": "vitest run --exclude '**/*.integration.test.ts'",
|
|
27
|
+
"test:integration": "vitest run --include '**/*.integration.test.ts' --testTimeout 60000",
|
|
28
|
+
"test:all": "vitest run --testTimeout 60000",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"publish:pkg": "npm publish --access public --provenance"
|
|
17
31
|
},
|
|
18
32
|
"dependencies": {
|
|
19
|
-
"effect": "^3.19.12",
|
|
20
33
|
"@electric-sql/pglite": "0.3.14",
|
|
34
|
+
"effect": "^3.19.12",
|
|
35
|
+
"minimatch": "^10.1.1",
|
|
36
|
+
"nanoid": "^5.1.6",
|
|
21
37
|
"zod": "4.1.8"
|
|
22
38
|
},
|
|
23
39
|
"devDependencies": {
|