opencode-swarm-plugin 0.26.0 → 0.27.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/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +37 -0
- package/README.md +43 -46
- package/bin/swarm.ts +8 -8
- package/dist/compaction-hook.d.ts +57 -0
- package/dist/compaction-hook.d.ts.map +1 -0
- package/dist/hive.d.ts +741 -0
- package/dist/hive.d.ts.map +1 -0
- package/dist/index.d.ts +139 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1418 -387
- package/dist/learning.d.ts +9 -9
- package/dist/plugin.js +1240 -386
- package/dist/schemas/cell-events.d.ts +1352 -0
- package/dist/schemas/{bead-events.d.ts.map → cell-events.d.ts.map} +1 -1
- package/dist/schemas/{bead.d.ts → cell.d.ts} +173 -29
- package/dist/schemas/cell.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +11 -7
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/structured.d.ts +17 -7
- package/dist/structured.d.ts.map +1 -1
- package/dist/swarm-decompose.d.ts +5 -5
- package/dist/swarm-orchestrate.d.ts +16 -2
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/dist/swarm-prompts.d.ts +9 -9
- package/dist/swarm-prompts.d.ts.map +1 -1
- package/dist/swarm-review.d.ts +210 -0
- package/dist/swarm-review.d.ts.map +1 -0
- package/dist/swarm-worktree.d.ts +185 -0
- package/dist/swarm-worktree.d.ts.map +1 -0
- package/dist/swarm.d.ts +7 -0
- package/dist/swarm.d.ts.map +1 -1
- package/dist/tool-availability.d.ts +3 -2
- package/dist/tool-availability.d.ts.map +1 -1
- package/docs/analysis-socratic-planner-pattern.md +1 -1
- package/docs/planning/ADR-007-swarm-enhancements-worktree-review.md +168 -0
- package/docs/testing/context-recovery-test.md +2 -2
- package/evals/README.md +2 -2
- package/evals/scorers/index.ts +7 -7
- package/examples/commands/swarm.md +21 -23
- package/examples/plugin-wrapper-template.ts +310 -44
- package/examples/skills/{beads-workflow → hive-workflow}/SKILL.md +40 -40
- package/examples/skills/swarm-coordination/SKILL.md +1 -1
- package/global-skills/swarm-coordination/SKILL.md +14 -14
- package/global-skills/swarm-coordination/references/coordinator-patterns.md +3 -3
- package/package.json +2 -2
- package/src/compaction-hook.ts +161 -0
- package/src/{beads.integration.test.ts → hive.integration.test.ts} +92 -80
- package/src/hive.ts +1017 -0
- package/src/index.ts +57 -20
- package/src/learning.ts +9 -9
- package/src/output-guardrails.test.ts +4 -4
- package/src/output-guardrails.ts +9 -9
- package/src/planning-guardrails.test.ts +1 -1
- package/src/planning-guardrails.ts +1 -1
- package/src/schemas/{bead-events.test.ts → cell-events.test.ts} +83 -77
- package/src/schemas/cell-events.ts +807 -0
- package/src/schemas/{bead.ts → cell.ts} +95 -41
- package/src/schemas/evaluation.ts +1 -1
- package/src/schemas/index.ts +90 -18
- package/src/schemas/swarm-context.ts +2 -2
- package/src/structured.test.ts +15 -15
- package/src/structured.ts +18 -11
- package/src/swarm-decompose.ts +23 -23
- package/src/swarm-orchestrate.ts +135 -21
- package/src/swarm-prompts.ts +43 -43
- package/src/swarm-review.test.ts +702 -0
- package/src/swarm-review.ts +696 -0
- package/src/swarm-worktree.test.ts +501 -0
- package/src/swarm-worktree.ts +575 -0
- package/src/swarm.integration.test.ts +12 -12
- package/src/tool-availability.ts +36 -3
- package/dist/beads.d.ts +0 -383
- package/dist/beads.d.ts.map +0 -1
- package/dist/schemas/bead-events.d.ts +0 -698
- package/dist/schemas/bead.d.ts.map +0 -1
- package/src/beads.ts +0 -800
- package/src/schemas/bead-events.ts +0 -583
|
@@ -1,583 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Event Types for Beads Event Sourcing
|
|
3
|
-
*
|
|
4
|
-
* These events form an audit trail for all bead operations.
|
|
5
|
-
* Events are NOT replayed for state reconstruction (beads uses hybrid CRUD + audit trail).
|
|
6
|
-
* Events enable:
|
|
7
|
-
* - Full audit history
|
|
8
|
-
* - Debugging distributed swarm operations
|
|
9
|
-
* - Learning from bead lifecycle patterns
|
|
10
|
-
* - Integration with swarm-mail coordination
|
|
11
|
-
*
|
|
12
|
-
* Design notes:
|
|
13
|
-
* - 75% reusable infrastructure from swarm-mail
|
|
14
|
-
* - Events stay local (PGLite/SQLite), not written to JSONL
|
|
15
|
-
* - JSONL export happens from projection snapshots (proven git merge driver)
|
|
16
|
-
* - Follows same BaseEventSchema pattern as swarm-mail
|
|
17
|
-
*/
|
|
18
|
-
import { z } from "zod";
|
|
19
|
-
import {
|
|
20
|
-
BeadDependencySchema,
|
|
21
|
-
BeadStatusSchema,
|
|
22
|
-
BeadTypeSchema,
|
|
23
|
-
} from "./bead.js";
|
|
24
|
-
|
|
25
|
-
// ============================================================================
|
|
26
|
-
// Base Event Schema (mirrors swarm-mail pattern)
|
|
27
|
-
// ============================================================================
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Base fields present on all bead events
|
|
31
|
-
*/
|
|
32
|
-
export const BaseBeadEventSchema = z.object({
|
|
33
|
-
/** Auto-generated event ID */
|
|
34
|
-
id: z.number().optional(),
|
|
35
|
-
/** Event type discriminator */
|
|
36
|
-
type: z.string(),
|
|
37
|
-
/** Project key (usually absolute path) */
|
|
38
|
-
project_key: z.string(),
|
|
39
|
-
/** Timestamp when event occurred */
|
|
40
|
-
timestamp: z.number(), // Unix ms
|
|
41
|
-
/** Sequence number for ordering */
|
|
42
|
-
sequence: z.number().optional(),
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
// ============================================================================
|
|
46
|
-
// Issue Lifecycle Events
|
|
47
|
-
// ============================================================================
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Bead created
|
|
51
|
-
*
|
|
52
|
-
* Emitted when:
|
|
53
|
-
* - User calls `bd create`
|
|
54
|
-
* - Swarm epic decomposition creates subtasks
|
|
55
|
-
* - Agent spawns new beads during work
|
|
56
|
-
*/
|
|
57
|
-
export const BeadCreatedEventSchema = BaseBeadEventSchema.extend({
|
|
58
|
-
type: z.literal("bead_created"),
|
|
59
|
-
bead_id: z.string(),
|
|
60
|
-
title: z.string(),
|
|
61
|
-
description: z.string().optional(),
|
|
62
|
-
issue_type: BeadTypeSchema,
|
|
63
|
-
priority: z.number().int().min(0).max(3),
|
|
64
|
-
parent_id: z.string().optional(),
|
|
65
|
-
/** Agent/user who created the bead */
|
|
66
|
-
created_by: z.string().optional(),
|
|
67
|
-
/** Metadata for tracking (e.g., epic context, swarm strategy) */
|
|
68
|
-
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Bead updated (generic field changes)
|
|
73
|
-
*
|
|
74
|
-
* Emitted for non-status field updates: title, description, priority
|
|
75
|
-
*/
|
|
76
|
-
export const BeadUpdatedEventSchema = BaseBeadEventSchema.extend({
|
|
77
|
-
type: z.literal("bead_updated"),
|
|
78
|
-
bead_id: z.string(),
|
|
79
|
-
/** Agent/user who made the update */
|
|
80
|
-
updated_by: z.string().optional(),
|
|
81
|
-
/** Changed fields with old and new values */
|
|
82
|
-
changes: z.object({
|
|
83
|
-
title: z
|
|
84
|
-
.object({
|
|
85
|
-
old: z.string(),
|
|
86
|
-
new: z.string(),
|
|
87
|
-
})
|
|
88
|
-
.optional(),
|
|
89
|
-
description: z
|
|
90
|
-
.object({
|
|
91
|
-
old: z.string(),
|
|
92
|
-
new: z.string(),
|
|
93
|
-
})
|
|
94
|
-
.optional(),
|
|
95
|
-
priority: z
|
|
96
|
-
.object({
|
|
97
|
-
old: z.number(),
|
|
98
|
-
new: z.number(),
|
|
99
|
-
})
|
|
100
|
-
.optional(),
|
|
101
|
-
}),
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Bead status changed
|
|
106
|
-
*
|
|
107
|
-
* Separate event for status transitions to enable workflow analysis.
|
|
108
|
-
* Tracks state machine: open → in_progress → (blocked | closed)
|
|
109
|
-
*/
|
|
110
|
-
export const BeadStatusChangedEventSchema = BaseBeadEventSchema.extend({
|
|
111
|
-
type: z.literal("bead_status_changed"),
|
|
112
|
-
bead_id: z.string(),
|
|
113
|
-
from_status: BeadStatusSchema,
|
|
114
|
-
to_status: BeadStatusSchema,
|
|
115
|
-
/** Agent/user who changed status */
|
|
116
|
-
changed_by: z.string().optional(),
|
|
117
|
-
/** Optional reason (required for closed status) */
|
|
118
|
-
reason: z.string().optional(),
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Bead closed
|
|
123
|
-
*
|
|
124
|
-
* Explicit close event (subset of status_changed for convenience).
|
|
125
|
-
* Includes closure reason for audit trail.
|
|
126
|
-
*/
|
|
127
|
-
export const BeadClosedEventSchema = BaseBeadEventSchema.extend({
|
|
128
|
-
type: z.literal("bead_closed"),
|
|
129
|
-
bead_id: z.string(),
|
|
130
|
-
reason: z.string(),
|
|
131
|
-
/** Agent/user who closed */
|
|
132
|
-
closed_by: z.string().optional(),
|
|
133
|
-
/** Files touched during work (from swarm completion) */
|
|
134
|
-
files_touched: z.array(z.string()).optional(),
|
|
135
|
-
/** Duration in ms (if tracked by agent) */
|
|
136
|
-
duration_ms: z.number().optional(),
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Bead reopened
|
|
141
|
-
*
|
|
142
|
-
* Emitted when closed bead is reopened.
|
|
143
|
-
*/
|
|
144
|
-
export const BeadReopenedEventSchema = BaseBeadEventSchema.extend({
|
|
145
|
-
type: z.literal("bead_reopened"),
|
|
146
|
-
bead_id: z.string(),
|
|
147
|
-
reason: z.string().optional(),
|
|
148
|
-
/** Agent/user who reopened */
|
|
149
|
-
reopened_by: z.string().optional(),
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Bead deleted
|
|
154
|
-
*
|
|
155
|
-
* Hard delete event (rare - beads are usually closed, not deleted).
|
|
156
|
-
* Useful for cleaning up spurious/duplicate beads.
|
|
157
|
-
*/
|
|
158
|
-
export const BeadDeletedEventSchema = BaseBeadEventSchema.extend({
|
|
159
|
-
type: z.literal("bead_deleted"),
|
|
160
|
-
bead_id: z.string(),
|
|
161
|
-
reason: z.string().optional(),
|
|
162
|
-
/** Agent/user who deleted */
|
|
163
|
-
deleted_by: z.string().optional(),
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
// ============================================================================
|
|
167
|
-
// Dependency Events
|
|
168
|
-
// ============================================================================
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Dependency added between beads
|
|
172
|
-
*
|
|
173
|
-
* Supports 4 relationship types:
|
|
174
|
-
* - blocks: This bead blocks the target
|
|
175
|
-
* - blocked-by: This bead is blocked by the target
|
|
176
|
-
* - related: Informational link
|
|
177
|
-
* - discovered-from: Bead spawned from investigation of target
|
|
178
|
-
*/
|
|
179
|
-
export const BeadDependencyAddedEventSchema = BaseBeadEventSchema.extend({
|
|
180
|
-
type: z.literal("bead_dependency_added"),
|
|
181
|
-
bead_id: z.string(),
|
|
182
|
-
/** Dependency relationship */
|
|
183
|
-
dependency: BeadDependencySchema,
|
|
184
|
-
/** Agent/user who added dependency */
|
|
185
|
-
added_by: z.string().optional(),
|
|
186
|
-
/** Optional reason (e.g., "needs auth service before OAuth implementation") */
|
|
187
|
-
reason: z.string().optional(),
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Dependency removed
|
|
192
|
-
*
|
|
193
|
-
* Emitted when dependency is no longer relevant or was added in error.
|
|
194
|
-
*/
|
|
195
|
-
export const BeadDependencyRemovedEventSchema = BaseBeadEventSchema.extend({
|
|
196
|
-
type: z.literal("bead_dependency_removed"),
|
|
197
|
-
bead_id: z.string(),
|
|
198
|
-
/** Dependency being removed */
|
|
199
|
-
dependency: BeadDependencySchema,
|
|
200
|
-
/** Agent/user who removed */
|
|
201
|
-
removed_by: z.string().optional(),
|
|
202
|
-
reason: z.string().optional(),
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
// ============================================================================
|
|
206
|
-
// Label Events
|
|
207
|
-
// ============================================================================
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Label added to bead
|
|
211
|
-
*
|
|
212
|
-
* Labels are string tags for categorization/filtering.
|
|
213
|
-
* Common labels: "p0", "needs-review", "blocked-external", "tech-debt"
|
|
214
|
-
*/
|
|
215
|
-
export const BeadLabelAddedEventSchema = BaseBeadEventSchema.extend({
|
|
216
|
-
type: z.literal("bead_label_added"),
|
|
217
|
-
bead_id: z.string(),
|
|
218
|
-
label: z.string(),
|
|
219
|
-
/** Agent/user who added label */
|
|
220
|
-
added_by: z.string().optional(),
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Label removed from bead
|
|
225
|
-
*/
|
|
226
|
-
export const BeadLabelRemovedEventSchema = BaseBeadEventSchema.extend({
|
|
227
|
-
type: z.literal("bead_label_removed"),
|
|
228
|
-
bead_id: z.string(),
|
|
229
|
-
label: z.string(),
|
|
230
|
-
/** Agent/user who removed label */
|
|
231
|
-
removed_by: z.string().optional(),
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
// ============================================================================
|
|
235
|
-
// Comment Events
|
|
236
|
-
// ============================================================================
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Comment added to bead
|
|
240
|
-
*
|
|
241
|
-
* Supports agent-to-agent communication, human notes, and progress updates.
|
|
242
|
-
*/
|
|
243
|
-
export const BeadCommentAddedEventSchema = BaseBeadEventSchema.extend({
|
|
244
|
-
type: z.literal("bead_comment_added"),
|
|
245
|
-
bead_id: z.string(),
|
|
246
|
-
/** Auto-generated comment ID */
|
|
247
|
-
comment_id: z.number().optional(),
|
|
248
|
-
author: z.string(),
|
|
249
|
-
body: z.string(),
|
|
250
|
-
/** Optional parent comment ID for threading */
|
|
251
|
-
parent_comment_id: z.number().optional(),
|
|
252
|
-
/** Comment metadata (e.g., attachments, mentions) */
|
|
253
|
-
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Comment updated (edit)
|
|
258
|
-
*/
|
|
259
|
-
export const BeadCommentUpdatedEventSchema = BaseBeadEventSchema.extend({
|
|
260
|
-
type: z.literal("bead_comment_updated"),
|
|
261
|
-
bead_id: z.string(),
|
|
262
|
-
comment_id: z.number(),
|
|
263
|
-
old_body: z.string(),
|
|
264
|
-
new_body: z.string(),
|
|
265
|
-
updated_by: z.string(),
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Comment deleted
|
|
270
|
-
*/
|
|
271
|
-
export const BeadCommentDeletedEventSchema = BaseBeadEventSchema.extend({
|
|
272
|
-
type: z.literal("bead_comment_deleted"),
|
|
273
|
-
bead_id: z.string(),
|
|
274
|
-
comment_id: z.number(),
|
|
275
|
-
deleted_by: z.string(),
|
|
276
|
-
reason: z.string().optional(),
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
// ============================================================================
|
|
280
|
-
// Epic Events
|
|
281
|
-
// ============================================================================
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Child bead added to epic
|
|
285
|
-
*
|
|
286
|
-
* Emitted when:
|
|
287
|
-
* - Epic created with subtasks (batch event for each child)
|
|
288
|
-
* - User manually adds child via `bd add-child`
|
|
289
|
-
* - Agent spawns additional subtask during work
|
|
290
|
-
*/
|
|
291
|
-
export const BeadEpicChildAddedEventSchema = BaseBeadEventSchema.extend({
|
|
292
|
-
type: z.literal("bead_epic_child_added"),
|
|
293
|
-
/** Epic ID */
|
|
294
|
-
bead_id: z.string(),
|
|
295
|
-
/** Child bead ID */
|
|
296
|
-
child_id: z.string(),
|
|
297
|
-
/** Optional index for ordering */
|
|
298
|
-
child_index: z.number().optional(),
|
|
299
|
-
added_by: z.string().optional(),
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Child bead removed from epic
|
|
304
|
-
*
|
|
305
|
-
* Rare - usually happens when subtask is merged/consolidated.
|
|
306
|
-
*/
|
|
307
|
-
export const BeadEpicChildRemovedEventSchema = BaseBeadEventSchema.extend({
|
|
308
|
-
type: z.literal("bead_epic_child_removed"),
|
|
309
|
-
/** Epic ID */
|
|
310
|
-
bead_id: z.string(),
|
|
311
|
-
/** Child bead ID */
|
|
312
|
-
child_id: z.string(),
|
|
313
|
-
removed_by: z.string().optional(),
|
|
314
|
-
reason: z.string().optional(),
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* Epic eligible for closure
|
|
319
|
-
*
|
|
320
|
-
* Emitted when all child beads are closed.
|
|
321
|
-
* Triggers coordinator review for epic closure.
|
|
322
|
-
*/
|
|
323
|
-
export const BeadEpicClosureEligibleEventSchema = BaseBeadEventSchema.extend({
|
|
324
|
-
type: z.literal("bead_epic_closure_eligible"),
|
|
325
|
-
bead_id: z.string(),
|
|
326
|
-
/** Child bead IDs (all closed) */
|
|
327
|
-
child_ids: z.array(z.string()),
|
|
328
|
-
/** Total duration across all children */
|
|
329
|
-
total_duration_ms: z.number().optional(),
|
|
330
|
-
/** Aggregate file changes */
|
|
331
|
-
all_files_touched: z.array(z.string()).optional(),
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
// ============================================================================
|
|
335
|
-
// Swarm Integration Events (bridge to swarm-mail)
|
|
336
|
-
// ============================================================================
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Bead assigned to agent
|
|
340
|
-
*
|
|
341
|
-
* Links beads to swarm-mail's agent tracking.
|
|
342
|
-
* Emitted when agent calls `beads_start` or swarm spawns worker.
|
|
343
|
-
*/
|
|
344
|
-
export const BeadAssignedEventSchema = BaseBeadEventSchema.extend({
|
|
345
|
-
type: z.literal("bead_assigned"),
|
|
346
|
-
bead_id: z.string(),
|
|
347
|
-
agent_name: z.string(),
|
|
348
|
-
/** Agent's task description for context */
|
|
349
|
-
task_description: z.string().optional(),
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Bead work started
|
|
354
|
-
*
|
|
355
|
-
* Separate from status change to track actual work start time.
|
|
356
|
-
* Useful for duration/velocity metrics.
|
|
357
|
-
*/
|
|
358
|
-
export const BeadWorkStartedEventSchema = BaseBeadEventSchema.extend({
|
|
359
|
-
type: z.literal("bead_work_started"),
|
|
360
|
-
bead_id: z.string(),
|
|
361
|
-
agent_name: z.string(),
|
|
362
|
-
/** Files reserved for this work */
|
|
363
|
-
reserved_files: z.array(z.string()).optional(),
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* Bead compacted
|
|
368
|
-
*
|
|
369
|
-
* Emitted when bead's event history is compressed (rare).
|
|
370
|
-
* Follows steveyegge/beads pattern - old events archived, projection preserved.
|
|
371
|
-
*/
|
|
372
|
-
export const BeadCompactedEventSchema = BaseBeadEventSchema.extend({
|
|
373
|
-
type: z.literal("bead_compacted"),
|
|
374
|
-
bead_id: z.string(),
|
|
375
|
-
/** Number of events archived */
|
|
376
|
-
events_archived: z.number(),
|
|
377
|
-
/** New event store start sequence */
|
|
378
|
-
new_start_sequence: z.number(),
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
// ============================================================================
|
|
382
|
-
// Union Type
|
|
383
|
-
// ============================================================================
|
|
384
|
-
|
|
385
|
-
export const BeadEventSchema = z.discriminatedUnion("type", [
|
|
386
|
-
// Lifecycle
|
|
387
|
-
BeadCreatedEventSchema,
|
|
388
|
-
BeadUpdatedEventSchema,
|
|
389
|
-
BeadStatusChangedEventSchema,
|
|
390
|
-
BeadClosedEventSchema,
|
|
391
|
-
BeadReopenedEventSchema,
|
|
392
|
-
BeadDeletedEventSchema,
|
|
393
|
-
|
|
394
|
-
// Dependencies
|
|
395
|
-
BeadDependencyAddedEventSchema,
|
|
396
|
-
BeadDependencyRemovedEventSchema,
|
|
397
|
-
|
|
398
|
-
// Labels
|
|
399
|
-
BeadLabelAddedEventSchema,
|
|
400
|
-
BeadLabelRemovedEventSchema,
|
|
401
|
-
|
|
402
|
-
// Comments
|
|
403
|
-
BeadCommentAddedEventSchema,
|
|
404
|
-
BeadCommentUpdatedEventSchema,
|
|
405
|
-
BeadCommentDeletedEventSchema,
|
|
406
|
-
|
|
407
|
-
// Epic
|
|
408
|
-
BeadEpicChildAddedEventSchema,
|
|
409
|
-
BeadEpicChildRemovedEventSchema,
|
|
410
|
-
BeadEpicClosureEligibleEventSchema,
|
|
411
|
-
|
|
412
|
-
// Swarm Integration
|
|
413
|
-
BeadAssignedEventSchema,
|
|
414
|
-
BeadWorkStartedEventSchema,
|
|
415
|
-
|
|
416
|
-
// Maintenance
|
|
417
|
-
BeadCompactedEventSchema,
|
|
418
|
-
]);
|
|
419
|
-
|
|
420
|
-
export type BeadEvent = z.infer<typeof BeadEventSchema>;
|
|
421
|
-
|
|
422
|
-
// ============================================================================
|
|
423
|
-
// Individual event types for convenience
|
|
424
|
-
// ============================================================================
|
|
425
|
-
|
|
426
|
-
export type BeadCreatedEvent = z.infer<typeof BeadCreatedEventSchema>;
|
|
427
|
-
export type BeadUpdatedEvent = z.infer<typeof BeadUpdatedEventSchema>;
|
|
428
|
-
export type BeadStatusChangedEvent = z.infer<
|
|
429
|
-
typeof BeadStatusChangedEventSchema
|
|
430
|
-
>;
|
|
431
|
-
export type BeadClosedEvent = z.infer<typeof BeadClosedEventSchema>;
|
|
432
|
-
export type BeadReopenedEvent = z.infer<typeof BeadReopenedEventSchema>;
|
|
433
|
-
export type BeadDeletedEvent = z.infer<typeof BeadDeletedEventSchema>;
|
|
434
|
-
export type BeadDependencyAddedEvent = z.infer<
|
|
435
|
-
typeof BeadDependencyAddedEventSchema
|
|
436
|
-
>;
|
|
437
|
-
export type BeadDependencyRemovedEvent = z.infer<
|
|
438
|
-
typeof BeadDependencyRemovedEventSchema
|
|
439
|
-
>;
|
|
440
|
-
export type BeadLabelAddedEvent = z.infer<typeof BeadLabelAddedEventSchema>;
|
|
441
|
-
export type BeadLabelRemovedEvent = z.infer<typeof BeadLabelRemovedEventSchema>;
|
|
442
|
-
export type BeadCommentAddedEvent = z.infer<typeof BeadCommentAddedEventSchema>;
|
|
443
|
-
export type BeadCommentUpdatedEvent = z.infer<
|
|
444
|
-
typeof BeadCommentUpdatedEventSchema
|
|
445
|
-
>;
|
|
446
|
-
export type BeadCommentDeletedEvent = z.infer<
|
|
447
|
-
typeof BeadCommentDeletedEventSchema
|
|
448
|
-
>;
|
|
449
|
-
export type BeadEpicChildAddedEvent = z.infer<
|
|
450
|
-
typeof BeadEpicChildAddedEventSchema
|
|
451
|
-
>;
|
|
452
|
-
export type BeadEpicChildRemovedEvent = z.infer<
|
|
453
|
-
typeof BeadEpicChildRemovedEventSchema
|
|
454
|
-
>;
|
|
455
|
-
export type BeadEpicClosureEligibleEvent = z.infer<
|
|
456
|
-
typeof BeadEpicClosureEligibleEventSchema
|
|
457
|
-
>;
|
|
458
|
-
export type BeadAssignedEvent = z.infer<typeof BeadAssignedEventSchema>;
|
|
459
|
-
export type BeadWorkStartedEvent = z.infer<typeof BeadWorkStartedEventSchema>;
|
|
460
|
-
export type BeadCompactedEvent = z.infer<typeof BeadCompactedEventSchema>;
|
|
461
|
-
|
|
462
|
-
// ============================================================================
|
|
463
|
-
// Event Helpers
|
|
464
|
-
// ============================================================================
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* Create a bead event with timestamp and validate
|
|
468
|
-
*
|
|
469
|
-
* Usage:
|
|
470
|
-
* ```typescript
|
|
471
|
-
* const event = createBeadEvent("bead_created", {
|
|
472
|
-
* project_key: "/path/to/repo",
|
|
473
|
-
* bead_id: "bd-123",
|
|
474
|
-
* title: "Add auth",
|
|
475
|
-
* issue_type: "feature",
|
|
476
|
-
* priority: 2
|
|
477
|
-
* });
|
|
478
|
-
* ```
|
|
479
|
-
*/
|
|
480
|
-
export function createBeadEvent<T extends BeadEvent["type"]>(
|
|
481
|
-
type: T,
|
|
482
|
-
data: Omit<
|
|
483
|
-
Extract<BeadEvent, { type: T }>,
|
|
484
|
-
"type" | "timestamp" | "id" | "sequence"
|
|
485
|
-
>,
|
|
486
|
-
): Extract<BeadEvent, { type: T }> {
|
|
487
|
-
const event = {
|
|
488
|
-
type,
|
|
489
|
-
timestamp: Date.now(),
|
|
490
|
-
...data,
|
|
491
|
-
} as Extract<BeadEvent, { type: T }>;
|
|
492
|
-
|
|
493
|
-
// Validate
|
|
494
|
-
const result = BeadEventSchema.safeParse(event);
|
|
495
|
-
if (!result.success) {
|
|
496
|
-
throw new Error(`Invalid bead event: ${result.error.message}`);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
return result.data as Extract<BeadEvent, { type: T }>;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
/**
|
|
503
|
-
* Type guard for specific bead event types
|
|
504
|
-
*
|
|
505
|
-
* Usage:
|
|
506
|
-
* ```typescript
|
|
507
|
-
* if (isBeadEventType(event, "bead_closed")) {
|
|
508
|
-
* console.log(event.reason); // TypeScript knows this is BeadClosedEvent
|
|
509
|
-
* }
|
|
510
|
-
* ```
|
|
511
|
-
*/
|
|
512
|
-
export function isBeadEventType<T extends BeadEvent["type"]>(
|
|
513
|
-
event: BeadEvent,
|
|
514
|
-
type: T,
|
|
515
|
-
): event is Extract<BeadEvent, { type: T }> {
|
|
516
|
-
return event.type === type;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* Extract bead ID from event (convenience helper)
|
|
521
|
-
*
|
|
522
|
-
* All bead events have bead_id field (or it's the epic's bead_id for epic events).
|
|
523
|
-
*/
|
|
524
|
-
export function getBeadIdFromEvent(event: BeadEvent): string {
|
|
525
|
-
return event.bead_id;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
/**
|
|
529
|
-
* Check if event represents a state transition
|
|
530
|
-
*/
|
|
531
|
-
export function isStateTransitionEvent(
|
|
532
|
-
event: BeadEvent,
|
|
533
|
-
): event is BeadStatusChangedEvent | BeadClosedEvent | BeadReopenedEvent {
|
|
534
|
-
return (
|
|
535
|
-
event.type === "bead_status_changed" ||
|
|
536
|
-
event.type === "bead_closed" ||
|
|
537
|
-
event.type === "bead_reopened"
|
|
538
|
-
);
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
/**
|
|
542
|
-
* Check if event represents an epic operation
|
|
543
|
-
*/
|
|
544
|
-
export function isEpicEvent(
|
|
545
|
-
event: BeadEvent,
|
|
546
|
-
): event is
|
|
547
|
-
| BeadEpicChildAddedEvent
|
|
548
|
-
| BeadEpicChildRemovedEvent
|
|
549
|
-
| BeadEpicClosureEligibleEvent {
|
|
550
|
-
return (
|
|
551
|
-
event.type === "bead_epic_child_added" ||
|
|
552
|
-
event.type === "bead_epic_child_removed" ||
|
|
553
|
-
event.type === "bead_epic_closure_eligible"
|
|
554
|
-
);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Check if event was triggered by an agent (vs human user)
|
|
559
|
-
*/
|
|
560
|
-
export function isAgentEvent(event: BeadEvent): boolean {
|
|
561
|
-
// Agent events have agent_name field or *_by field containing agent signature
|
|
562
|
-
if ("agent_name" in event) return true;
|
|
563
|
-
|
|
564
|
-
const actorFields = [
|
|
565
|
-
"created_by",
|
|
566
|
-
"updated_by",
|
|
567
|
-
"changed_by",
|
|
568
|
-
"closed_by",
|
|
569
|
-
"deleted_by",
|
|
570
|
-
"added_by",
|
|
571
|
-
"removed_by",
|
|
572
|
-
"reopened_by",
|
|
573
|
-
] as const;
|
|
574
|
-
|
|
575
|
-
return actorFields.some((field) => {
|
|
576
|
-
if (field in event) {
|
|
577
|
-
const value = (event as Record<string, unknown>)[field];
|
|
578
|
-
// Agent names are typically lowercase or have specific patterns
|
|
579
|
-
return typeof value === "string" && /^[a-z]+$/i.test(value);
|
|
580
|
-
}
|
|
581
|
-
return false;
|
|
582
|
-
});
|
|
583
|
-
}
|