swarm-mail 0.1.3 → 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.
Files changed (59) hide show
  1. package/README.md +4 -0
  2. package/bin/daemon-cli.ts +304 -0
  3. package/dist/beads/adapter.d.ts +38 -0
  4. package/dist/beads/adapter.d.ts.map +1 -0
  5. package/dist/beads/blocked-cache.d.ts +21 -0
  6. package/dist/beads/blocked-cache.d.ts.map +1 -0
  7. package/dist/beads/comments.d.ts +21 -0
  8. package/dist/beads/comments.d.ts.map +1 -0
  9. package/dist/beads/dependencies.d.ts +58 -0
  10. package/dist/beads/dependencies.d.ts.map +1 -0
  11. package/dist/beads/events.d.ts +163 -0
  12. package/dist/beads/events.d.ts.map +1 -0
  13. package/dist/beads/flush-manager.d.ts +71 -0
  14. package/dist/beads/flush-manager.d.ts.map +1 -0
  15. package/dist/beads/index.d.ts +25 -0
  16. package/dist/beads/index.d.ts.map +1 -0
  17. package/dist/beads/jsonl.d.ts +103 -0
  18. package/dist/beads/jsonl.d.ts.map +1 -0
  19. package/dist/beads/labels.d.ts +21 -0
  20. package/dist/beads/labels.d.ts.map +1 -0
  21. package/dist/beads/merge.d.ts +99 -0
  22. package/dist/beads/merge.d.ts.map +1 -0
  23. package/dist/beads/migrations.d.ts +41 -0
  24. package/dist/beads/migrations.d.ts.map +1 -0
  25. package/dist/beads/operations.d.ts +56 -0
  26. package/dist/beads/operations.d.ts.map +1 -0
  27. package/dist/beads/projections.d.ts +103 -0
  28. package/dist/beads/projections.d.ts.map +1 -0
  29. package/dist/beads/queries.d.ts +77 -0
  30. package/dist/beads/queries.d.ts.map +1 -0
  31. package/dist/beads/store.d.ts +98 -0
  32. package/dist/beads/store.d.ts.map +1 -0
  33. package/dist/beads/validation.d.ts +75 -0
  34. package/dist/beads/validation.d.ts.map +1 -0
  35. package/dist/daemon.d.ts +139 -0
  36. package/dist/daemon.d.ts.map +1 -0
  37. package/dist/index.d.ts +6 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +8314 -4513
  40. package/dist/pglite.d.ts +78 -5
  41. package/dist/pglite.d.ts.map +1 -1
  42. package/dist/socket-adapter.d.ts +78 -0
  43. package/dist/socket-adapter.d.ts.map +1 -0
  44. package/dist/streams/debug.d.ts.map +1 -1
  45. package/dist/streams/effect/ask.integration-test.d.ts +8 -0
  46. package/dist/streams/effect/ask.integration-test.d.ts.map +1 -0
  47. package/dist/streams/effect/cursor.integration-test.d.ts +2 -0
  48. package/dist/streams/effect/cursor.integration-test.d.ts.map +1 -0
  49. package/dist/streams/index.d.ts.map +1 -1
  50. package/dist/streams/leader-election.d.ts +44 -0
  51. package/dist/streams/leader-election.d.ts.map +1 -0
  52. package/dist/streams/migrations.d.ts +1 -1
  53. package/dist/streams/migrations.d.ts.map +1 -1
  54. package/dist/streams/store.d.ts.map +1 -1
  55. package/dist/streams/store.integration-test.d.ts +2 -0
  56. package/dist/streams/store.integration-test.d.ts.map +1 -0
  57. package/dist/types/beads-adapter.d.ts +397 -0
  58. package/dist/types/beads-adapter.d.ts.map +1 -0
  59. package/package.json +15 -5
package/README.md CHANGED
@@ -30,6 +30,8 @@
30
30
 
31
31
  Event sourcing primitives for multi-agent coordination. Local-first, no external servers.
32
32
 
33
+ **[🌐 swarmtools.ai](https://swarmtools.ai)** | **[📖 Full Documentation](https://swarmtools.ai/docs)**
34
+
33
35
  ```
34
36
  ┌─────────────────────────────────────────────────────────────┐
35
37
  │ SWARM MAIL STACK │
@@ -190,6 +192,8 @@ Materialized views derived from events:
190
192
 
191
193
  ## API Reference
192
194
 
195
+ For complete API documentation, see [swarmtools.ai/docs](https://swarmtools.ai/docs).
196
+
193
197
  ### SwarmMailAdapter
194
198
 
195
199
  ```typescript
@@ -0,0 +1,304 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * swarm-mail-daemon CLI
4
+ *
5
+ * Command-line interface for managing the swarm-mail pglite-server daemon.
6
+ *
7
+ * Commands:
8
+ * start [options] - Start the daemon
9
+ * stop - Stop the daemon
10
+ * status - Show daemon status
11
+ *
12
+ * @example
13
+ * ```bash
14
+ * # Start daemon on default port
15
+ * swarm-mail-daemon start
16
+ *
17
+ * # Start with custom port
18
+ * swarm-mail-daemon start --port 5555
19
+ *
20
+ * # Start with Unix socket
21
+ * swarm-mail-daemon start --path /tmp/swarm-mail.sock
22
+ *
23
+ * # Check status
24
+ * swarm-mail-daemon status
25
+ *
26
+ * # Stop daemon
27
+ * swarm-mail-daemon stop
28
+ * ```
29
+ */
30
+
31
+ import { existsSync } from "node:fs";
32
+ import { readFile } from "node:fs/promises";
33
+ import { parseArgs } from "node:util";
34
+ import {
35
+ type DaemonOptions,
36
+ getPidFilePath,
37
+ healthCheck,
38
+ isDaemonRunning,
39
+ startDaemon,
40
+ stopDaemon,
41
+ } from "../src/daemon";
42
+
43
+ // Colors for terminal output
44
+ const colors = {
45
+ reset: "\x1b[0m",
46
+ red: "\x1b[31m",
47
+ green: "\x1b[32m",
48
+ yellow: "\x1b[33m",
49
+ blue: "\x1b[34m",
50
+ dim: "\x1b[2m",
51
+ bold: "\x1b[1m",
52
+ };
53
+
54
+ function success(msg: string) {
55
+ console.log(`${colors.green}✓${colors.reset} ${msg}`);
56
+ }
57
+
58
+ function error(msg: string) {
59
+ console.error(`${colors.red}✗${colors.reset} ${msg}`);
60
+ }
61
+
62
+ function info(msg: string) {
63
+ console.log(`${colors.blue}ℹ${colors.reset} ${msg}`);
64
+ }
65
+
66
+ function showHelp() {
67
+ console.log(`
68
+ ${colors.bold}swarm-mail-daemon${colors.reset} - Manage pglite-server daemon for swarm-mail
69
+
70
+ ${colors.bold}USAGE${colors.reset}
71
+ swarm-mail-daemon <command> [options]
72
+
73
+ ${colors.bold}COMMANDS${colors.reset}
74
+ start [options] Start the daemon
75
+ stop Stop the daemon
76
+ status Show daemon status
77
+
78
+ ${colors.bold}START OPTIONS${colors.reset}
79
+ --port <number> TCP port to bind (default: 5433)
80
+ --host <string> Host to bind (default: 127.0.0.1)
81
+ --path <string> Unix socket path (alternative to port/host)
82
+ --db <string> Database path (default: .opencode/streams or ~/.opencode/streams)
83
+ --project <string> Project path for PID file location
84
+
85
+ ${colors.bold}EXAMPLES${colors.reset}
86
+ # Start daemon on default port
87
+ swarm-mail-daemon start
88
+
89
+ # Start with custom port
90
+ swarm-mail-daemon start --port 5555
91
+
92
+ # Start with Unix socket
93
+ swarm-mail-daemon start --path /tmp/swarm-mail.sock
94
+
95
+ # Start with custom database path
96
+ swarm-mail-daemon start --db /custom/db/path
97
+
98
+ # Check status
99
+ swarm-mail-daemon status
100
+
101
+ # Stop daemon
102
+ swarm-mail-daemon stop
103
+ `);
104
+ }
105
+
106
+ /**
107
+ * Read PID from PID file
108
+ */
109
+ async function readPid(projectPath?: string): Promise<number | null> {
110
+ const pidFilePath = getPidFilePath(projectPath);
111
+ if (!existsSync(pidFilePath)) {
112
+ return null;
113
+ }
114
+ try {
115
+ const content = await readFile(pidFilePath, "utf-8");
116
+ const pid = Number.parseInt(content.trim(), 10);
117
+ if (Number.isNaN(pid) || pid <= 0) {
118
+ return null;
119
+ }
120
+ return pid;
121
+ } catch {
122
+ return null;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Start command handler
128
+ */
129
+ async function startCommand(args: string[]): Promise<void> {
130
+ const { values } = parseArgs({
131
+ args,
132
+ options: {
133
+ port: { type: "string", short: "p" },
134
+ host: { type: "string", short: "h" },
135
+ path: { type: "string" },
136
+ db: { type: "string" },
137
+ project: { type: "string" },
138
+ help: { type: "boolean" },
139
+ },
140
+ });
141
+
142
+ if (values.help) {
143
+ showHelp();
144
+ return;
145
+ }
146
+
147
+ const options: DaemonOptions = {
148
+ port: values.port ? Number.parseInt(values.port, 10) : undefined,
149
+ host: values.host,
150
+ path: values.path,
151
+ dbPath: values.db,
152
+ projectPath: values.project,
153
+ };
154
+
155
+ try {
156
+ // Check if already running
157
+ if (await isDaemonRunning(options.projectPath)) {
158
+ const pid = await readPid(options.projectPath);
159
+ const connInfo = options.path
160
+ ? `socket=${options.path}`
161
+ : `port=${options.port || 5433}`;
162
+ info(`Daemon already running (PID: ${pid}, ${connInfo})`);
163
+ return;
164
+ }
165
+
166
+ info("Starting daemon...");
167
+ const daemonInfo = await startDaemon(options);
168
+
169
+ const connInfo = daemonInfo.socketPath
170
+ ? `socket=${daemonInfo.socketPath}`
171
+ : `port=${daemonInfo.port}`;
172
+ success(`Daemon started (PID: ${daemonInfo.pid}, ${connInfo})`);
173
+ } catch (err) {
174
+ error(
175
+ `Failed to start daemon: ${err instanceof Error ? err.message : String(err)}`,
176
+ );
177
+ process.exit(1);
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Stop command handler
183
+ */
184
+ async function stopCommand(args: string[]): Promise<void> {
185
+ const { values } = parseArgs({
186
+ args,
187
+ options: {
188
+ project: { type: "string" },
189
+ help: { type: "boolean" },
190
+ },
191
+ });
192
+
193
+ if (values.help) {
194
+ showHelp();
195
+ return;
196
+ }
197
+
198
+ try {
199
+ const pid = await readPid(values.project);
200
+
201
+ if (!pid || !(await isDaemonRunning(values.project))) {
202
+ info("Daemon is not running");
203
+ return;
204
+ }
205
+
206
+ info(`Stopping daemon (PID: ${pid})...`);
207
+ await stopDaemon(values.project);
208
+ success("Daemon stopped");
209
+ } catch (err) {
210
+ error(
211
+ `Failed to stop daemon: ${err instanceof Error ? err.message : String(err)}`,
212
+ );
213
+ process.exit(1);
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Status command handler
219
+ */
220
+ async function statusCommand(args: string[]): Promise<void> {
221
+ const { values } = parseArgs({
222
+ args,
223
+ options: {
224
+ port: { type: "string", short: "p" },
225
+ host: { type: "string", short: "h" },
226
+ path: { type: "string" },
227
+ project: { type: "string" },
228
+ help: { type: "boolean" },
229
+ },
230
+ });
231
+
232
+ if (values.help) {
233
+ showHelp();
234
+ return;
235
+ }
236
+
237
+ const projectPath = values.project;
238
+ const pid = await readPid(projectPath);
239
+ const running = await isDaemonRunning(projectPath);
240
+
241
+ if (!running) {
242
+ console.log(`${colors.bold}Status:${colors.reset} ${colors.red}Stopped${colors.reset}`);
243
+ console.log(`${colors.bold}PID File:${colors.reset} ${getPidFilePath(projectPath)}`);
244
+ return;
245
+ }
246
+
247
+ // Daemon is running - check health
248
+ const port = values.port ? Number.parseInt(values.port, 10) : 5433;
249
+ const host = values.host || "127.0.0.1";
250
+ const path = values.path;
251
+
252
+ const healthOptions = path ? { path } : { port, host };
253
+ const healthy = await healthCheck(healthOptions);
254
+
255
+ console.log(
256
+ `${colors.bold}Status:${colors.reset} ${colors.green}Running${colors.reset}`,
257
+ );
258
+ console.log(`${colors.bold}PID:${colors.reset} ${pid}`);
259
+ console.log(`${colors.bold}PID File:${colors.reset} ${getPidFilePath(projectPath)}`);
260
+
261
+ if (path) {
262
+ console.log(`${colors.bold}Socket:${colors.reset} ${path}`);
263
+ } else {
264
+ console.log(`${colors.bold}Host:${colors.reset} ${host}`);
265
+ console.log(`${colors.bold}Port:${colors.reset} ${port}`);
266
+ }
267
+
268
+ console.log(
269
+ `${colors.bold}Health:${colors.reset} ${healthy ? `${colors.green}OK${colors.reset}` : `${colors.red}Failed${colors.reset}`}`,
270
+ );
271
+ }
272
+
273
+ /**
274
+ * Main CLI entrypoint
275
+ */
276
+ async function main() {
277
+ const [command, ...args] = process.argv.slice(2);
278
+
279
+ if (!command || command === "help" || command === "--help" || command === "-h") {
280
+ showHelp();
281
+ process.exit(0);
282
+ }
283
+
284
+ switch (command) {
285
+ case "start":
286
+ await startCommand(args);
287
+ break;
288
+ case "stop":
289
+ await stopCommand(args);
290
+ break;
291
+ case "status":
292
+ await statusCommand(args);
293
+ break;
294
+ default:
295
+ error(`Unknown command: ${command}`);
296
+ showHelp();
297
+ process.exit(1);
298
+ }
299
+ }
300
+
301
+ main().catch((err) => {
302
+ error(`Unexpected error: ${err instanceof Error ? err.message : String(err)}`);
303
+ process.exit(1);
304
+ });
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Beads Adapter - Factory for creating BeadsAdapter instances
3
+ *
4
+ * This file implements the adapter pattern for beads event sourcing,
5
+ * enabling dependency injection of the database.
6
+ *
7
+ * ## Design Pattern
8
+ * - Accept DatabaseAdapter via factory parameter
9
+ * - Return BeadsAdapter interface
10
+ * - Delegate to store.ts for event operations
11
+ * - Delegate to projections.ts for queries
12
+ * - No direct database access (all via adapter)
13
+ *
14
+ * ## Usage
15
+ * ```typescript
16
+ * import { wrapPGlite } from '@opencode/swarm-mail/pglite';
17
+ * import { createBeadsAdapter } from '@opencode/swarm-mail/beads';
18
+ *
19
+ * const pglite = new PGlite('./streams.db');
20
+ * const db = wrapPGlite(pglite);
21
+ * const beads = createBeadsAdapter(db, '/path/to/project');
22
+ *
23
+ * // Use the adapter
24
+ * await beads.createBead(projectKey, { title: "Task", type: "task", priority: 2 });
25
+ * const bead = await beads.getBead(projectKey, "bd-123");
26
+ * ```
27
+ */
28
+ import type { DatabaseAdapter } from "../types/database.js";
29
+ import type { BeadsAdapter } from "../types/beads-adapter.js";
30
+ /**
31
+ * Create a BeadsAdapter instance
32
+ *
33
+ * @param db - DatabaseAdapter instance (PGLite, SQLite, PostgreSQL, etc.)
34
+ * @param projectKey - Project identifier (typically the project path)
35
+ * @returns BeadsAdapter interface
36
+ */
37
+ export declare function createBeadsAdapter(db: DatabaseAdapter, projectKey: string): BeadsAdapter;
38
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/beads/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AA6B9D;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,eAAe,EACnB,UAAU,EAAE,MAAM,GACjB,YAAY,CAkiBd"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Blocked Beads Cache Management
3
+ *
4
+ * Convenience re-exports for blocked cache operations.
5
+ * The actual implementation is in dependencies.ts to avoid circular dependencies.
6
+ *
7
+ * ## Cache Strategy
8
+ * - blocked_beads_cache table stores bead_id → blocker_ids[]
9
+ * - Rebuilt when dependencies change or bead status changes
10
+ * - Enables fast "ready work" queries without recursive CTEs
11
+ *
12
+ * ## Performance
13
+ * - Cache rebuild: <50ms for typical projects
14
+ * - Ready work query: 25x faster with cache (752ms → 29ms on 10K beads)
15
+ *
16
+ * Reference: steveyegge/beads/internal/storage/sqlite/blocked_cache.go
17
+ *
18
+ * @module beads/blocked-cache
19
+ */
20
+ export { rebuildBeadBlockedCache, rebuildAllBlockedCaches, invalidateBlockedCache, } from "./dependencies.js";
21
+ //# sourceMappingURL=blocked-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocked-cache.d.ts","sourceRoot":"","sources":["../../src/beads/blocked-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Comment Operations
3
+ *
4
+ * Comment management with threading support.
5
+ * Comments can have parent_id for nested discussions.
6
+ *
7
+ * Reference: steveyegge/beads/internal/storage/sqlite/comments.go
8
+ *
9
+ * @module beads/comments
10
+ */
11
+ import type { DatabaseAdapter } from "../types/database.js";
12
+ import type { BeadComment } from "../types/beads-adapter.js";
13
+ /**
14
+ * Get a specific comment by ID
15
+ */
16
+ export declare function getCommentById(db: DatabaseAdapter, commentId: number): Promise<BeadComment | null>;
17
+ /**
18
+ * Get comment thread (comment + all replies)
19
+ */
20
+ export declare function getCommentThread(db: DatabaseAdapter, rootCommentId: number): Promise<BeadComment[]>;
21
+ //# sourceMappingURL=comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/beads/comments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D;;GAEG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,eAAe,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAM7B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,eAAe,EACnB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,WAAW,EAAE,CAAC,CAgBxB"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Dependency Graph Operations
3
+ *
4
+ * Provides dependency management with cycle detection and blocked bead tracking.
5
+ *
6
+ * ## Dependency Types
7
+ * - **blocks**: Hard dependency - target must be closed before source can start
8
+ * - **blocked-by**: Inverse of blocks (computed, not stored)
9
+ * - **related**: Soft relationship - doesn't affect ready state
10
+ * - **discovered-from**: Tracking relationship - found while working on another bead
11
+ *
12
+ * ## Cycle Prevention
13
+ * All dependency types are checked for cycles to maintain a DAG (Directed Acyclic Graph).
14
+ * This ensures:
15
+ * - Ready work calculation works correctly
16
+ * - Dependency traversal doesn't loop
17
+ * - Semantic clarity (no circular dependencies)
18
+ *
19
+ * Reference: steveyegge/beads/internal/storage/sqlite/dependencies.go
20
+ *
21
+ * @module beads/dependencies
22
+ */
23
+ import type { DatabaseAdapter } from "../types/database.js";
24
+ /**
25
+ * Check if adding a dependency would create a cycle
26
+ *
27
+ * Uses recursive CTE to traverse from dependsOnId to see if we can reach beadId.
28
+ * If yes, adding "beadId depends on dependsOnId" would complete a cycle.
29
+ */
30
+ export declare function wouldCreateCycle(db: DatabaseAdapter, beadId: string, dependsOnId: string): Promise<boolean>;
31
+ /**
32
+ * Get all open blockers for a bead (including transitive)
33
+ *
34
+ * Returns bead IDs of all beads blocking this one that aren't closed.
35
+ * Only considers "blocks" relationship type.
36
+ */
37
+ export declare function getOpenBlockers(db: DatabaseAdapter, projectKey: string, beadId: string): Promise<string[]>;
38
+ /**
39
+ * Rebuild blocked cache for a specific bead
40
+ *
41
+ * Finds all open blockers and updates the cache.
42
+ * If no open blockers, removes from cache (bead is unblocked).
43
+ */
44
+ export declare function rebuildBeadBlockedCache(db: DatabaseAdapter, projectKey: string, beadId: string): Promise<void>;
45
+ /**
46
+ * Rebuild blocked cache for all beads in a project
47
+ *
48
+ * Used after bulk operations or status changes that affect blocking.
49
+ */
50
+ export declare function rebuildAllBlockedCaches(db: DatabaseAdapter, projectKey: string): Promise<void>;
51
+ /**
52
+ * Invalidate blocked cache when dependencies change
53
+ *
54
+ * Marks beads as needing cache rebuild.
55
+ * In this simple implementation, we just rebuild immediately.
56
+ */
57
+ export declare function invalidateBlockedCache(db: DatabaseAdapter, projectKey: string, beadId: string): Promise<void>;
58
+ //# sourceMappingURL=dependencies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../src/beads/dependencies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI5D;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CA6BlB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,eAAe,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC,CAwBnB;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,eAAe,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,eAAe,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,eAAe,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAYf"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Bead Event Types - Minimal type definitions for swarm-mail
3
+ *
4
+ * These are simplified type definitions that match the bead-events from
5
+ * opencode-swarm-plugin but avoid cross-package TypeScript imports.
6
+ *
7
+ * The actual event schemas with Zod validation live in:
8
+ * packages/opencode-swarm-plugin/src/schemas/bead-events.ts
9
+ *
10
+ * This file provides just enough type information for the store to work.
11
+ */
12
+ /**
13
+ * Base bead event (all events extend this)
14
+ */
15
+ export interface BaseBeadEvent {
16
+ id?: number;
17
+ type: string;
18
+ project_key: string;
19
+ bead_id: string;
20
+ timestamp: number;
21
+ sequence?: number;
22
+ }
23
+ /**
24
+ * Union of all bead event types
25
+ *
26
+ * This matches the discriminated union in bead-events.ts but as pure TypeScript
27
+ */
28
+ export type BeadEvent = BeadCreatedEvent | BeadUpdatedEvent | BeadStatusChangedEvent | BeadClosedEvent | BeadReopenedEvent | BeadDeletedEvent | BeadDependencyAddedEvent | BeadDependencyRemovedEvent | BeadLabelAddedEvent | BeadLabelRemovedEvent | BeadCommentAddedEvent | BeadCommentUpdatedEvent | BeadCommentDeletedEvent | BeadEpicChildAddedEvent | BeadEpicChildRemovedEvent | BeadEpicClosureEligibleEvent | BeadAssignedEvent | BeadWorkStartedEvent | BeadCompactedEvent;
29
+ export interface BeadCreatedEvent extends BaseBeadEvent {
30
+ type: "bead_created";
31
+ title: string;
32
+ description?: string;
33
+ issue_type: "bug" | "feature" | "task" | "epic" | "chore";
34
+ priority: number;
35
+ parent_id?: string;
36
+ created_by?: string;
37
+ metadata?: Record<string, unknown>;
38
+ }
39
+ export interface BeadUpdatedEvent extends BaseBeadEvent {
40
+ type: "bead_updated";
41
+ updated_by?: string;
42
+ changes: {
43
+ title?: {
44
+ old: string;
45
+ new: string;
46
+ };
47
+ description?: {
48
+ old: string;
49
+ new: string;
50
+ };
51
+ priority?: {
52
+ old: number;
53
+ new: number;
54
+ };
55
+ };
56
+ }
57
+ export interface BeadStatusChangedEvent extends BaseBeadEvent {
58
+ type: "bead_status_changed";
59
+ from_status: "open" | "in_progress" | "blocked" | "closed" | "tombstone";
60
+ to_status: "open" | "in_progress" | "blocked" | "closed" | "tombstone";
61
+ changed_by?: string;
62
+ reason?: string;
63
+ }
64
+ export interface BeadClosedEvent extends BaseBeadEvent {
65
+ type: "bead_closed";
66
+ reason: string;
67
+ closed_by?: string;
68
+ files_touched?: string[];
69
+ duration_ms?: number;
70
+ }
71
+ export interface BeadReopenedEvent extends BaseBeadEvent {
72
+ type: "bead_reopened";
73
+ reason?: string;
74
+ reopened_by?: string;
75
+ }
76
+ export interface BeadDeletedEvent extends BaseBeadEvent {
77
+ type: "bead_deleted";
78
+ reason?: string;
79
+ deleted_by?: string;
80
+ }
81
+ export interface BeadDependencyAddedEvent extends BaseBeadEvent {
82
+ type: "bead_dependency_added";
83
+ dependency: {
84
+ target: string;
85
+ type: "blocks" | "blocked-by" | "related" | "discovered-from";
86
+ };
87
+ added_by?: string;
88
+ reason?: string;
89
+ }
90
+ export interface BeadDependencyRemovedEvent extends BaseBeadEvent {
91
+ type: "bead_dependency_removed";
92
+ dependency: {
93
+ target: string;
94
+ type: "blocks" | "blocked-by" | "related" | "discovered-from";
95
+ };
96
+ removed_by?: string;
97
+ reason?: string;
98
+ }
99
+ export interface BeadLabelAddedEvent extends BaseBeadEvent {
100
+ type: "bead_label_added";
101
+ label: string;
102
+ added_by?: string;
103
+ }
104
+ export interface BeadLabelRemovedEvent extends BaseBeadEvent {
105
+ type: "bead_label_removed";
106
+ label: string;
107
+ removed_by?: string;
108
+ }
109
+ export interface BeadCommentAddedEvent extends BaseBeadEvent {
110
+ type: "bead_comment_added";
111
+ comment_id?: number;
112
+ author: string;
113
+ body: string;
114
+ parent_comment_id?: number;
115
+ metadata?: Record<string, unknown>;
116
+ }
117
+ export interface BeadCommentUpdatedEvent extends BaseBeadEvent {
118
+ type: "bead_comment_updated";
119
+ comment_id: number;
120
+ old_body: string;
121
+ new_body: string;
122
+ updated_by: string;
123
+ }
124
+ export interface BeadCommentDeletedEvent extends BaseBeadEvent {
125
+ type: "bead_comment_deleted";
126
+ comment_id: number;
127
+ deleted_by: string;
128
+ reason?: string;
129
+ }
130
+ export interface BeadEpicChildAddedEvent extends BaseBeadEvent {
131
+ type: "bead_epic_child_added";
132
+ child_id: string;
133
+ child_index?: number;
134
+ added_by?: string;
135
+ }
136
+ export interface BeadEpicChildRemovedEvent extends BaseBeadEvent {
137
+ type: "bead_epic_child_removed";
138
+ child_id: string;
139
+ removed_by?: string;
140
+ reason?: string;
141
+ }
142
+ export interface BeadEpicClosureEligibleEvent extends BaseBeadEvent {
143
+ type: "bead_epic_closure_eligible";
144
+ child_ids: string[];
145
+ total_duration_ms?: number;
146
+ all_files_touched?: string[];
147
+ }
148
+ export interface BeadAssignedEvent extends BaseBeadEvent {
149
+ type: "bead_assigned";
150
+ agent_name: string;
151
+ task_description?: string;
152
+ }
153
+ export interface BeadWorkStartedEvent extends BaseBeadEvent {
154
+ type: "bead_work_started";
155
+ agent_name: string;
156
+ reserved_files?: string[];
157
+ }
158
+ export interface BeadCompactedEvent extends BaseBeadEvent {
159
+ type: "bead_compacted";
160
+ events_archived: number;
161
+ new_start_sequence: number;
162
+ }
163
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/beads/events.ts"],"names":[],"mappings":"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"}