hungry-ghost-hive 0.30.0 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/cluster/adapters.d.ts +5 -0
  2. package/dist/cluster/adapters.d.ts.map +1 -0
  3. package/dist/cluster/adapters.js +401 -0
  4. package/dist/cluster/adapters.js.map +1 -0
  5. package/dist/cluster/events.d.ts +14 -0
  6. package/dist/cluster/events.d.ts.map +1 -0
  7. package/dist/cluster/events.js +151 -0
  8. package/dist/cluster/events.js.map +1 -0
  9. package/dist/cluster/replication.d.ts +4 -25
  10. package/dist/cluster/replication.d.ts.map +1 -1
  11. package/dist/cluster/replication.js +6 -943
  12. package/dist/cluster/replication.js.map +1 -1
  13. package/dist/cluster/story-merge.d.ts +3 -0
  14. package/dist/cluster/story-merge.d.ts.map +1 -0
  15. package/dist/cluster/story-merge.js +185 -0
  16. package/dist/cluster/story-merge.js.map +1 -0
  17. package/dist/cluster/sync.d.ts +5 -0
  18. package/dist/cluster/sync.d.ts.map +1 -0
  19. package/dist/cluster/sync.js +121 -0
  20. package/dist/cluster/sync.js.map +1 -0
  21. package/dist/cluster/types.d.ts +66 -0
  22. package/dist/cluster/types.d.ts.map +1 -0
  23. package/dist/cluster/types.js +3 -0
  24. package/dist/cluster/types.js.map +1 -0
  25. package/dist/cluster/utils.d.ts +16 -0
  26. package/dist/cluster/utils.d.ts.map +1 -0
  27. package/dist/cluster/utils.js +106 -0
  28. package/dist/cluster/utils.js.map +1 -0
  29. package/dist/integrations/jira/sprints.d.ts +7 -4
  30. package/dist/integrations/jira/sprints.d.ts.map +1 -1
  31. package/dist/integrations/jira/sprints.js +49 -16
  32. package/dist/integrations/jira/sprints.js.map +1 -1
  33. package/dist/integrations/jira/sprints.test.js +55 -3
  34. package/dist/integrations/jira/sprints.test.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/cluster/adapters.ts +459 -0
  37. package/src/cluster/events.ts +234 -0
  38. package/src/cluster/replication.ts +22 -1279
  39. package/src/cluster/story-merge.ts +235 -0
  40. package/src/cluster/sync.ts +170 -0
  41. package/src/cluster/types.ts +96 -0
  42. package/src/cluster/utils.ts +139 -0
  43. package/src/integrations/jira/sprints.test.ts +61 -3
  44. package/src/integrations/jira/sprints.ts +51 -16
@@ -0,0 +1,5 @@
1
+ import type { ReplicatedTable, StoryRecord, TableAdapter } from './types.js';
2
+ export declare const STORY_STATUS_ORDER: Array<StoryRecord['status']>;
3
+ export declare const REPLICATED_TABLES: TableAdapter[];
4
+ export declare const ADAPTERS_BY_TABLE: Map<ReplicatedTable, TableAdapter>;
5
+ //# sourceMappingURL=adapters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../src/cluster/adapters.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAW7E,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAU3D,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,YAAY,EA4a3C,CAAC;AAEF,eAAO,MAAM,iBAAiB,oCAE7B,CAAC"}
@@ -0,0 +1,401 @@
1
+ // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
+ import { run } from '../db/client.js';
3
+ import { asNullableNumber, asNullableString, asString, deleteAgentLogByRowId, hashPayload, splitDependencyRowId, toAgentLogPayload, } from './utils.js';
4
+ export const STORY_STATUS_ORDER = [
5
+ 'draft',
6
+ 'estimated',
7
+ 'planned',
8
+ 'in_progress',
9
+ 'review',
10
+ 'qa',
11
+ 'qa_failed',
12
+ 'pr_submitted',
13
+ 'merged',
14
+ ];
15
+ export const REPLICATED_TABLES = [
16
+ {
17
+ table: 'teams',
18
+ selectSql: 'SELECT id, repo_url, repo_path, name, created_at FROM teams ORDER BY id',
19
+ rowId: row => asString(row.id),
20
+ payload: row => ({
21
+ id: asString(row.id),
22
+ repo_url: asString(row.repo_url),
23
+ repo_path: asString(row.repo_path),
24
+ name: asString(row.name),
25
+ created_at: asString(row.created_at),
26
+ }),
27
+ upsert: (db, payload) => {
28
+ run(db, `
29
+ INSERT INTO teams (id, repo_url, repo_path, name, created_at)
30
+ VALUES (?, ?, ?, ?, ?)
31
+ ON CONFLICT(id) DO UPDATE SET
32
+ repo_url = excluded.repo_url,
33
+ repo_path = excluded.repo_path,
34
+ name = excluded.name,
35
+ created_at = excluded.created_at
36
+ `, [
37
+ asString(payload.id),
38
+ asString(payload.repo_url),
39
+ asString(payload.repo_path),
40
+ asString(payload.name),
41
+ asString(payload.created_at),
42
+ ]);
43
+ },
44
+ delete: (db, rowId) => {
45
+ run(db, 'DELETE FROM teams WHERE id = ?', [rowId]);
46
+ },
47
+ },
48
+ {
49
+ table: 'agents',
50
+ selectSql: 'SELECT id, type, team_id, tmux_session, model, status, current_story_id, memory_state, created_at, updated_at, last_seen, worktree_path FROM agents ORDER BY id',
51
+ rowId: row => asString(row.id),
52
+ payload: row => ({
53
+ id: asString(row.id),
54
+ type: asString(row.type),
55
+ team_id: asNullableString(row.team_id),
56
+ tmux_session: asNullableString(row.tmux_session),
57
+ model: asNullableString(row.model),
58
+ status: asString(row.status),
59
+ current_story_id: asNullableString(row.current_story_id),
60
+ memory_state: asNullableString(row.memory_state),
61
+ created_at: asString(row.created_at),
62
+ updated_at: asString(row.updated_at),
63
+ last_seen: asNullableString(row.last_seen),
64
+ worktree_path: asNullableString(row.worktree_path),
65
+ }),
66
+ upsert: (db, payload) => {
67
+ run(db, `
68
+ INSERT INTO agents (id, type, team_id, tmux_session, model, status, current_story_id, memory_state, created_at, updated_at, last_seen, worktree_path)
69
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
70
+ ON CONFLICT(id) DO UPDATE SET
71
+ type = excluded.type,
72
+ team_id = excluded.team_id,
73
+ tmux_session = excluded.tmux_session,
74
+ model = excluded.model,
75
+ status = excluded.status,
76
+ current_story_id = excluded.current_story_id,
77
+ memory_state = excluded.memory_state,
78
+ created_at = excluded.created_at,
79
+ updated_at = excluded.updated_at,
80
+ last_seen = excluded.last_seen,
81
+ worktree_path = excluded.worktree_path
82
+ `, [
83
+ asString(payload.id),
84
+ asString(payload.type),
85
+ asNullableString(payload.team_id),
86
+ asNullableString(payload.tmux_session),
87
+ asNullableString(payload.model),
88
+ asString(payload.status),
89
+ asNullableString(payload.current_story_id),
90
+ asNullableString(payload.memory_state),
91
+ asString(payload.created_at),
92
+ asString(payload.updated_at),
93
+ asNullableString(payload.last_seen),
94
+ asNullableString(payload.worktree_path),
95
+ ]);
96
+ },
97
+ delete: (db, rowId) => {
98
+ run(db, 'DELETE FROM agents WHERE id = ?', [rowId]);
99
+ },
100
+ },
101
+ {
102
+ table: 'requirements',
103
+ selectSql: 'SELECT id, title, description, submitted_by, status, godmode, created_at FROM requirements ORDER BY id',
104
+ rowId: row => asString(row.id),
105
+ payload: row => ({
106
+ id: asString(row.id),
107
+ title: asString(row.title),
108
+ description: asString(row.description),
109
+ submitted_by: asString(row.submitted_by),
110
+ status: asString(row.status),
111
+ godmode: asNullableNumber(row.godmode),
112
+ created_at: asString(row.created_at),
113
+ }),
114
+ upsert: (db, payload) => {
115
+ run(db, `
116
+ INSERT INTO requirements (id, title, description, submitted_by, status, godmode, created_at)
117
+ VALUES (?, ?, ?, ?, ?, COALESCE(?, 0), ?)
118
+ ON CONFLICT(id) DO UPDATE SET
119
+ title = excluded.title,
120
+ description = excluded.description,
121
+ submitted_by = excluded.submitted_by,
122
+ status = excluded.status,
123
+ godmode = CASE
124
+ WHEN ? IS NULL THEN requirements.godmode
125
+ ELSE ?
126
+ END,
127
+ created_at = excluded.created_at
128
+ `, [
129
+ asString(payload.id),
130
+ asString(payload.title),
131
+ asString(payload.description),
132
+ asString(payload.submitted_by),
133
+ asString(payload.status),
134
+ asNullableNumber(payload.godmode),
135
+ asNullableNumber(payload.godmode),
136
+ asNullableNumber(payload.godmode),
137
+ asString(payload.created_at),
138
+ ]);
139
+ },
140
+ delete: (db, rowId) => {
141
+ run(db, 'DELETE FROM requirements WHERE id = ?', [rowId]);
142
+ },
143
+ },
144
+ {
145
+ table: 'stories',
146
+ selectSql: 'SELECT id, requirement_id, team_id, title, description, acceptance_criteria, complexity_score, story_points, status, assigned_agent_id, branch_name, pr_url, created_at, updated_at FROM stories ORDER BY id',
147
+ rowId: row => asString(row.id),
148
+ payload: row => ({
149
+ id: asString(row.id),
150
+ requirement_id: asNullableString(row.requirement_id),
151
+ team_id: asNullableString(row.team_id),
152
+ title: asString(row.title),
153
+ description: asString(row.description),
154
+ acceptance_criteria: asNullableString(row.acceptance_criteria),
155
+ complexity_score: asNullableNumber(row.complexity_score),
156
+ story_points: asNullableNumber(row.story_points),
157
+ status: asString(row.status),
158
+ assigned_agent_id: asNullableString(row.assigned_agent_id),
159
+ branch_name: asNullableString(row.branch_name),
160
+ pr_url: asNullableString(row.pr_url),
161
+ created_at: asString(row.created_at),
162
+ updated_at: asString(row.updated_at),
163
+ }),
164
+ upsert: (db, payload) => {
165
+ run(db, `
166
+ INSERT INTO stories (id, requirement_id, team_id, title, description, acceptance_criteria, complexity_score, story_points, status, assigned_agent_id, branch_name, pr_url, created_at, updated_at)
167
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
168
+ ON CONFLICT(id) DO UPDATE SET
169
+ requirement_id = excluded.requirement_id,
170
+ team_id = excluded.team_id,
171
+ title = excluded.title,
172
+ description = excluded.description,
173
+ acceptance_criteria = excluded.acceptance_criteria,
174
+ complexity_score = excluded.complexity_score,
175
+ story_points = excluded.story_points,
176
+ status = excluded.status,
177
+ assigned_agent_id = excluded.assigned_agent_id,
178
+ branch_name = excluded.branch_name,
179
+ pr_url = excluded.pr_url,
180
+ created_at = excluded.created_at,
181
+ updated_at = excluded.updated_at
182
+ `, [
183
+ asString(payload.id),
184
+ asNullableString(payload.requirement_id),
185
+ asNullableString(payload.team_id),
186
+ asString(payload.title),
187
+ asString(payload.description),
188
+ asNullableString(payload.acceptance_criteria),
189
+ asNullableNumber(payload.complexity_score),
190
+ asNullableNumber(payload.story_points),
191
+ asString(payload.status),
192
+ asNullableString(payload.assigned_agent_id),
193
+ asNullableString(payload.branch_name),
194
+ asNullableString(payload.pr_url),
195
+ asString(payload.created_at),
196
+ asString(payload.updated_at),
197
+ ]);
198
+ },
199
+ delete: (db, rowId) => {
200
+ run(db, 'DELETE FROM story_dependencies WHERE story_id = ? OR depends_on_story_id = ?', [
201
+ rowId,
202
+ rowId,
203
+ ]);
204
+ run(db, 'DELETE FROM stories WHERE id = ?', [rowId]);
205
+ },
206
+ },
207
+ {
208
+ table: 'story_dependencies',
209
+ selectSql: 'SELECT story_id, depends_on_story_id FROM story_dependencies ORDER BY story_id, depends_on_story_id',
210
+ rowId: row => `${asString(row.story_id)}::${asString(row.depends_on_story_id)}`,
211
+ payload: row => ({
212
+ story_id: asString(row.story_id),
213
+ depends_on_story_id: asString(row.depends_on_story_id),
214
+ }),
215
+ upsert: (db, payload) => {
216
+ run(db, `
217
+ INSERT OR IGNORE INTO story_dependencies (story_id, depends_on_story_id)
218
+ VALUES (?, ?)
219
+ `, [asString(payload.story_id), asString(payload.depends_on_story_id)]);
220
+ },
221
+ delete: (db, rowId) => {
222
+ const [storyId, dependsOnId] = splitDependencyRowId(rowId);
223
+ run(db, 'DELETE FROM story_dependencies WHERE story_id = ? AND depends_on_story_id = ?', [
224
+ storyId,
225
+ dependsOnId,
226
+ ]);
227
+ },
228
+ },
229
+ {
230
+ table: 'agent_logs',
231
+ selectSql: 'SELECT id, agent_id, story_id, event_type, status, message, metadata, timestamp FROM agent_logs ORDER BY timestamp, id',
232
+ rowId: row => {
233
+ const payload = toAgentLogPayload(row);
234
+ return hashPayload(payload);
235
+ },
236
+ payload: row => toAgentLogPayload(row),
237
+ upsert: (db, payload) => {
238
+ run(db, `
239
+ INSERT INTO agent_logs (agent_id, story_id, event_type, status, message, metadata, timestamp)
240
+ VALUES (?, ?, ?, ?, ?, ?, ?)
241
+ `, [
242
+ asString(payload.agent_id),
243
+ asNullableString(payload.story_id),
244
+ asString(payload.event_type),
245
+ asNullableString(payload.status),
246
+ asNullableString(payload.message),
247
+ asNullableString(payload.metadata),
248
+ asString(payload.timestamp),
249
+ ]);
250
+ },
251
+ delete: (db, rowId) => {
252
+ deleteAgentLogByRowId(db, rowId);
253
+ },
254
+ },
255
+ {
256
+ table: 'escalations',
257
+ selectSql: 'SELECT id, story_id, from_agent_id, to_agent_id, reason, status, resolution, created_at, resolved_at FROM escalations ORDER BY id',
258
+ rowId: row => asString(row.id),
259
+ payload: row => ({
260
+ id: asString(row.id),
261
+ story_id: asNullableString(row.story_id),
262
+ from_agent_id: asNullableString(row.from_agent_id),
263
+ to_agent_id: asNullableString(row.to_agent_id),
264
+ reason: asString(row.reason),
265
+ status: asString(row.status),
266
+ resolution: asNullableString(row.resolution),
267
+ created_at: asString(row.created_at),
268
+ resolved_at: asNullableString(row.resolved_at),
269
+ }),
270
+ upsert: (db, payload) => {
271
+ run(db, `
272
+ INSERT INTO escalations (id, story_id, from_agent_id, to_agent_id, reason, status, resolution, created_at, resolved_at)
273
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
274
+ ON CONFLICT(id) DO UPDATE SET
275
+ story_id = excluded.story_id,
276
+ from_agent_id = excluded.from_agent_id,
277
+ to_agent_id = excluded.to_agent_id,
278
+ reason = excluded.reason,
279
+ status = excluded.status,
280
+ resolution = excluded.resolution,
281
+ created_at = excluded.created_at,
282
+ resolved_at = excluded.resolved_at
283
+ `, [
284
+ asString(payload.id),
285
+ asNullableString(payload.story_id),
286
+ asNullableString(payload.from_agent_id),
287
+ asNullableString(payload.to_agent_id),
288
+ asString(payload.reason),
289
+ asString(payload.status),
290
+ asNullableString(payload.resolution),
291
+ asString(payload.created_at),
292
+ asNullableString(payload.resolved_at),
293
+ ]);
294
+ },
295
+ delete: (db, rowId) => {
296
+ run(db, 'DELETE FROM escalations WHERE id = ?', [rowId]);
297
+ },
298
+ },
299
+ {
300
+ table: 'pull_requests',
301
+ selectSql: 'SELECT id, story_id, team_id, branch_name, github_pr_number, github_pr_url, submitted_by, reviewed_by, status, review_notes, created_at, updated_at, reviewed_at FROM pull_requests ORDER BY id',
302
+ rowId: row => asString(row.id),
303
+ payload: row => ({
304
+ id: asString(row.id),
305
+ story_id: asNullableString(row.story_id),
306
+ team_id: asNullableString(row.team_id),
307
+ branch_name: asString(row.branch_name),
308
+ github_pr_number: asNullableNumber(row.github_pr_number),
309
+ github_pr_url: asNullableString(row.github_pr_url),
310
+ submitted_by: asNullableString(row.submitted_by),
311
+ reviewed_by: asNullableString(row.reviewed_by),
312
+ status: asString(row.status),
313
+ review_notes: asNullableString(row.review_notes),
314
+ created_at: asString(row.created_at),
315
+ updated_at: asString(row.updated_at),
316
+ reviewed_at: asNullableString(row.reviewed_at),
317
+ }),
318
+ upsert: (db, payload) => {
319
+ run(db, `
320
+ INSERT INTO pull_requests (id, story_id, team_id, branch_name, github_pr_number, github_pr_url, submitted_by, reviewed_by, status, review_notes, created_at, updated_at, reviewed_at)
321
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
322
+ ON CONFLICT(id) DO UPDATE SET
323
+ story_id = excluded.story_id,
324
+ team_id = excluded.team_id,
325
+ branch_name = excluded.branch_name,
326
+ github_pr_number = excluded.github_pr_number,
327
+ github_pr_url = excluded.github_pr_url,
328
+ submitted_by = excluded.submitted_by,
329
+ reviewed_by = excluded.reviewed_by,
330
+ status = excluded.status,
331
+ review_notes = excluded.review_notes,
332
+ created_at = excluded.created_at,
333
+ updated_at = excluded.updated_at,
334
+ reviewed_at = excluded.reviewed_at
335
+ `, [
336
+ asString(payload.id),
337
+ asNullableString(payload.story_id),
338
+ asNullableString(payload.team_id),
339
+ asString(payload.branch_name),
340
+ asNullableNumber(payload.github_pr_number),
341
+ asNullableString(payload.github_pr_url),
342
+ asNullableString(payload.submitted_by),
343
+ asNullableString(payload.reviewed_by),
344
+ asString(payload.status),
345
+ asNullableString(payload.review_notes),
346
+ asString(payload.created_at),
347
+ asString(payload.updated_at),
348
+ asNullableString(payload.reviewed_at),
349
+ ]);
350
+ },
351
+ delete: (db, rowId) => {
352
+ run(db, 'DELETE FROM pull_requests WHERE id = ?', [rowId]);
353
+ },
354
+ },
355
+ {
356
+ table: 'messages',
357
+ selectSql: 'SELECT id, from_session, to_session, subject, body, reply, status, created_at, replied_at FROM messages ORDER BY id',
358
+ rowId: row => asString(row.id),
359
+ payload: row => ({
360
+ id: asString(row.id),
361
+ from_session: asString(row.from_session),
362
+ to_session: asString(row.to_session),
363
+ subject: asNullableString(row.subject),
364
+ body: asString(row.body),
365
+ reply: asNullableString(row.reply),
366
+ status: asString(row.status),
367
+ created_at: asString(row.created_at),
368
+ replied_at: asNullableString(row.replied_at),
369
+ }),
370
+ upsert: (db, payload) => {
371
+ run(db, `
372
+ INSERT INTO messages (id, from_session, to_session, subject, body, reply, status, created_at, replied_at)
373
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
374
+ ON CONFLICT(id) DO UPDATE SET
375
+ from_session = excluded.from_session,
376
+ to_session = excluded.to_session,
377
+ subject = excluded.subject,
378
+ body = excluded.body,
379
+ reply = excluded.reply,
380
+ status = excluded.status,
381
+ created_at = excluded.created_at,
382
+ replied_at = excluded.replied_at
383
+ `, [
384
+ asString(payload.id),
385
+ asString(payload.from_session),
386
+ asString(payload.to_session),
387
+ asNullableString(payload.subject),
388
+ asString(payload.body),
389
+ asNullableString(payload.reply),
390
+ asString(payload.status),
391
+ asString(payload.created_at),
392
+ asNullableString(payload.replied_at),
393
+ ]);
394
+ },
395
+ delete: (db, rowId) => {
396
+ run(db, 'DELETE FROM messages WHERE id = ?', [rowId]);
397
+ },
398
+ },
399
+ ];
400
+ export const ADAPTERS_BY_TABLE = new Map(REPLICATED_TABLES.map(adapter => [adapter.table, adapter]));
401
+ //# sourceMappingURL=adapters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.js","sourceRoot":"","sources":["../../src/cluster/adapters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Database } from 'sql.js';
2
+ import type { ClusterEvent, ReplicatedTable, ReplicationOp, TableAdapter, TableRowSnapshot, VersionVector } from './types.js';
3
+ export declare function ensureClusterTables(db: Database, nodeId: string): void;
4
+ export declare function getVersionVector(db: Database): VersionVector;
5
+ export declare function getAllClusterEvents(db: Database): ClusterEvent[];
6
+ export declare function getDeltaEvents(db: Database, remoteVersionVector: VersionVector, limit?: number): ClusterEvent[];
7
+ export declare function emitLocalEvent(db: Database, nodeId: string, input: {
8
+ table_name: ReplicatedTable;
9
+ row_id: string;
10
+ op: ReplicationOp;
11
+ payload: Record<string, unknown> | null;
12
+ }): void;
13
+ export declare function fetchTableSnapshots(db: Database, adapter: TableAdapter): TableRowSnapshot[];
14
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/cluster/events.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,KAAK,EACV,YAAY,EAEZ,eAAe,EACf,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA+FtE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,GAAG,aAAa,CAgB5D;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,GAAG,YAAY,EAAE,CAWhE;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,QAAQ,EACZ,mBAAmB,EAAE,aAAa,EAClC,KAAK,SAAO,GACX,YAAY,EAAE,CAQhB;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,UAAU,EAAE,eAAe,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,aAAa,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACzC,GACA,IAAI,CAsCN;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAW3F"}
@@ -0,0 +1,151 @@
1
+ // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
+ import { queryAll, queryOne, run } from '../db/client.js';
3
+ import { hashPayload, incrementAndGetCounter, stableStringify, toObject } from './utils.js';
4
+ export function ensureClusterTables(db, nodeId) {
5
+ run(db, `
6
+ CREATE TABLE IF NOT EXISTS cluster_state (
7
+ id INTEGER PRIMARY KEY CHECK(id = 1),
8
+ node_id TEXT NOT NULL,
9
+ event_counter INTEGER NOT NULL DEFAULT 0,
10
+ updated_at TEXT NOT NULL
11
+ )
12
+ `);
13
+ run(db, `
14
+ CREATE TABLE IF NOT EXISTS cluster_events (
15
+ event_id TEXT PRIMARY KEY,
16
+ actor_id TEXT NOT NULL,
17
+ actor_counter INTEGER NOT NULL,
18
+ logical_ts INTEGER NOT NULL,
19
+ table_name TEXT NOT NULL,
20
+ row_id TEXT NOT NULL,
21
+ op TEXT NOT NULL CHECK(op IN ('upsert', 'delete')),
22
+ payload TEXT,
23
+ created_at TEXT NOT NULL
24
+ )
25
+ `);
26
+ run(db, `
27
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_cluster_events_actor_counter
28
+ ON cluster_events(actor_id, actor_counter)
29
+ `);
30
+ run(db, `
31
+ CREATE INDEX IF NOT EXISTS idx_cluster_events_logical_ts
32
+ ON cluster_events(logical_ts)
33
+ `);
34
+ run(db, `
35
+ CREATE TABLE IF NOT EXISTS cluster_row_versions (
36
+ table_name TEXT NOT NULL,
37
+ row_id TEXT NOT NULL,
38
+ actor_id TEXT NOT NULL,
39
+ actor_counter INTEGER NOT NULL,
40
+ logical_ts INTEGER NOT NULL,
41
+ PRIMARY KEY (table_name, row_id)
42
+ )
43
+ `);
44
+ run(db, `
45
+ CREATE TABLE IF NOT EXISTS cluster_row_hashes (
46
+ table_name TEXT NOT NULL,
47
+ row_id TEXT NOT NULL,
48
+ row_hash TEXT NOT NULL,
49
+ PRIMARY KEY (table_name, row_id)
50
+ )
51
+ `);
52
+ run(db, `
53
+ CREATE TABLE IF NOT EXISTS cluster_story_merges (
54
+ duplicate_story_id TEXT PRIMARY KEY,
55
+ canonical_story_id TEXT NOT NULL,
56
+ merged_at TEXT NOT NULL
57
+ )
58
+ `);
59
+ const state = queryOne(db, 'SELECT id FROM cluster_state WHERE id = 1');
60
+ const now = new Date().toISOString();
61
+ if (!state) {
62
+ run(db, 'INSERT INTO cluster_state (id, node_id, event_counter, updated_at) VALUES (1, ?, 0, ?)', [nodeId, now]);
63
+ }
64
+ else {
65
+ run(db, 'UPDATE cluster_state SET node_id = ?, updated_at = ? WHERE id = 1', [nodeId, now]);
66
+ }
67
+ }
68
+ export function getVersionVector(db) {
69
+ const rows = queryAll(db, `
70
+ SELECT actor_id, MAX(actor_counter) as max_counter
71
+ FROM cluster_events
72
+ GROUP BY actor_id
73
+ `);
74
+ const vector = {};
75
+ for (const row of rows) {
76
+ vector[row.actor_id] = Number(row.max_counter) || 0;
77
+ }
78
+ return vector;
79
+ }
80
+ export function getAllClusterEvents(db) {
81
+ const rows = queryAll(db, `
82
+ SELECT event_id, actor_id, actor_counter, logical_ts, table_name, row_id, op, payload, created_at
83
+ FROM cluster_events
84
+ ORDER BY logical_ts ASC, actor_id ASC, actor_counter ASC
85
+ `);
86
+ return rows.map(mapEventRow);
87
+ }
88
+ export function getDeltaEvents(db, remoteVersionVector, limit = 2000) {
89
+ const events = getAllClusterEvents(db);
90
+ const missing = events.filter(event => {
91
+ const known = remoteVersionVector[event.version.actor_id] || 0;
92
+ return event.version.actor_counter > known;
93
+ });
94
+ return missing.slice(0, limit);
95
+ }
96
+ export function emitLocalEvent(db, nodeId, input) {
97
+ const nextCounter = incrementAndGetCounter(db);
98
+ const logicalTs = Date.now();
99
+ const createdAt = new Date(logicalTs).toISOString();
100
+ const eventId = `${nodeId}:${nextCounter}`;
101
+ run(db, `
102
+ INSERT OR REPLACE INTO cluster_events
103
+ (event_id, actor_id, actor_counter, logical_ts, table_name, row_id, op, payload, created_at)
104
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
105
+ `, [
106
+ eventId,
107
+ nodeId,
108
+ nextCounter,
109
+ logicalTs,
110
+ input.table_name,
111
+ input.row_id,
112
+ input.op,
113
+ input.payload ? stableStringify(input.payload) : null,
114
+ createdAt,
115
+ ]);
116
+ run(db, `
117
+ INSERT INTO cluster_row_versions (table_name, row_id, actor_id, actor_counter, logical_ts)
118
+ VALUES (?, ?, ?, ?, ?)
119
+ ON CONFLICT(table_name, row_id) DO UPDATE SET
120
+ actor_id = excluded.actor_id,
121
+ actor_counter = excluded.actor_counter,
122
+ logical_ts = excluded.logical_ts
123
+ `, [input.table_name, input.row_id, nodeId, nextCounter, logicalTs]);
124
+ }
125
+ export function fetchTableSnapshots(db, adapter) {
126
+ const rows = queryAll(db, adapter.selectSql);
127
+ return rows.map(row => {
128
+ const payload = adapter.payload(row);
129
+ return {
130
+ rowId: adapter.rowId(row),
131
+ rowHash: hashPayload(payload),
132
+ payload,
133
+ };
134
+ });
135
+ }
136
+ function mapEventRow(row) {
137
+ return {
138
+ event_id: row.event_id,
139
+ table_name: row.table_name,
140
+ row_id: row.row_id,
141
+ op: row.op,
142
+ payload: row.payload ? toObject(JSON.parse(row.payload)) : null,
143
+ version: {
144
+ actor_id: row.actor_id,
145
+ actor_counter: Number(row.actor_counter),
146
+ logical_ts: Number(row.logical_ts),
147
+ },
148
+ created_at: row.created_at,
149
+ };
150
+ }
151
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/cluster/events.ts"],"names":[],"mappings":"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"}
@@ -1,26 +1,5 @@
1
- import type { Database } from 'sql.js';
2
- export type ReplicatedTable = 'teams' | 'agents' | 'requirements' | 'stories' | 'story_dependencies' | 'agent_logs' | 'escalations' | 'pull_requests' | 'messages';
3
- export type ReplicationOp = 'upsert' | 'delete';
4
- export interface ClusterEventVersion {
5
- actor_id: string;
6
- actor_counter: number;
7
- logical_ts: number;
8
- }
9
- export interface ClusterEvent {
10
- event_id: string;
11
- table_name: ReplicatedTable;
12
- row_id: string;
13
- op: ReplicationOp;
14
- payload: Record<string, unknown> | null;
15
- version: ClusterEventVersion;
16
- created_at: string;
17
- }
18
- export type VersionVector = Record<string, number>;
19
- export declare function ensureClusterTables(db: Database, nodeId: string): void;
20
- export declare function getVersionVector(db: Database): VersionVector;
21
- export declare function getAllClusterEvents(db: Database): ClusterEvent[];
22
- export declare function getDeltaEvents(db: Database, remoteVersionVector: VersionVector, limit?: number): ClusterEvent[];
23
- export declare function scanLocalChanges(db: Database, nodeId: string): number;
24
- export declare function applyRemoteEvents(db: Database, nodeId: string, events: ClusterEvent[]): number;
25
- export declare function mergeSimilarStories(db: Database, similarityThreshold: number): number;
1
+ export type { ClusterEvent, ClusterEventVersion, ReplicatedTable, ReplicationOp, VersionVector, } from './types.js';
2
+ export { ensureClusterTables, getAllClusterEvents, getDeltaEvents, getVersionVector, } from './events.js';
3
+ export { applyRemoteEvents, scanLocalChanges } from './sync.js';
4
+ export { mergeSimilarStories } from './story-merge.js';
26
5
  //# sourceMappingURL=replication.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"replication.d.ts","sourceRoot":"","sources":["../../src/cluster/replication.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAGvC,MAAM,MAAM,eAAe,GACvB,OAAO,GACP,QAAQ,GACR,cAAc,GACd,SAAS,GACT,oBAAoB,GACpB,YAAY,GACZ,aAAa,GACb,eAAe,GACf,UAAU,CAAC;AAEf,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,eAAe,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,aAAa,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AA6fnD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA+FtE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,GAAG,aAAa,CAgB5D;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,GAAG,YAAY,EAAE,CAWhE;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,QAAQ,EACZ,mBAAmB,EAAE,aAAa,EAClC,KAAK,SAAO,GACX,YAAY,EAAE,CAQhB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA6DrE;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CA2E9F;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAqFrF"}
1
+ {"version":3,"file":"replication.d.ts","sourceRoot":"","sources":["../../src/cluster/replication.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}