@renseiai/agentfactory 0.8.6 → 0.8.8

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 (175) hide show
  1. package/README.md +2 -2
  2. package/dist/src/config/repository-config.d.ts +14 -0
  3. package/dist/src/config/repository-config.d.ts.map +1 -1
  4. package/dist/src/config/repository-config.js +20 -0
  5. package/dist/src/governor/decision-engine.d.ts +7 -0
  6. package/dist/src/governor/decision-engine.d.ts.map +1 -1
  7. package/dist/src/governor/decision-engine.js +59 -1
  8. package/dist/src/governor/event-types.d.ts +18 -1
  9. package/dist/src/governor/event-types.d.ts.map +1 -1
  10. package/dist/src/governor/event-types.js +4 -0
  11. package/dist/src/governor/governor.d.ts +5 -1
  12. package/dist/src/governor/governor.d.ts.map +1 -1
  13. package/dist/src/governor/governor.js +6 -1
  14. package/dist/src/index.d.ts +1 -0
  15. package/dist/src/index.d.ts.map +1 -1
  16. package/dist/src/index.js +1 -0
  17. package/dist/src/merge-queue/adapters/github-native.d.ts +22 -0
  18. package/dist/src/merge-queue/adapters/github-native.d.ts.map +1 -0
  19. package/dist/src/merge-queue/adapters/github-native.js +243 -0
  20. package/dist/src/merge-queue/adapters/github-native.test.d.ts +2 -0
  21. package/dist/src/merge-queue/adapters/github-native.test.d.ts.map +1 -0
  22. package/dist/src/merge-queue/adapters/github-native.test.js +384 -0
  23. package/dist/src/merge-queue/index.d.ts +18 -0
  24. package/dist/src/merge-queue/index.d.ts.map +1 -0
  25. package/dist/src/merge-queue/index.js +28 -0
  26. package/dist/src/merge-queue/merge-queue.integration.test.d.ts +2 -0
  27. package/dist/src/merge-queue/merge-queue.integration.test.d.ts.map +1 -0
  28. package/dist/src/merge-queue/merge-queue.integration.test.js +128 -0
  29. package/dist/src/merge-queue/types.d.ts +48 -0
  30. package/dist/src/merge-queue/types.d.ts.map +1 -0
  31. package/dist/src/merge-queue/types.js +8 -0
  32. package/dist/src/orchestrator/activity-emitter.d.ts +3 -3
  33. package/dist/src/orchestrator/activity-emitter.d.ts.map +1 -1
  34. package/dist/src/orchestrator/activity-emitter.js +1 -1
  35. package/dist/src/orchestrator/artifact-tracker.d.ts +93 -0
  36. package/dist/src/orchestrator/artifact-tracker.d.ts.map +1 -0
  37. package/dist/src/orchestrator/artifact-tracker.js +235 -0
  38. package/dist/src/orchestrator/artifact-tracker.test.d.ts +2 -0
  39. package/dist/src/orchestrator/artifact-tracker.test.d.ts.map +1 -0
  40. package/dist/src/orchestrator/artifact-tracker.test.js +189 -0
  41. package/dist/src/orchestrator/context-manager.d.ts +72 -0
  42. package/dist/src/orchestrator/context-manager.d.ts.map +1 -0
  43. package/dist/src/orchestrator/context-manager.js +120 -0
  44. package/dist/src/orchestrator/context-manager.test.d.ts +2 -0
  45. package/dist/src/orchestrator/context-manager.test.d.ts.map +1 -0
  46. package/dist/src/orchestrator/context-manager.test.js +137 -0
  47. package/dist/src/orchestrator/detect-work-type.test.js +25 -16
  48. package/dist/src/orchestrator/index.d.ts +12 -2
  49. package/dist/src/orchestrator/index.d.ts.map +1 -1
  50. package/dist/src/orchestrator/index.js +9 -1
  51. package/dist/src/orchestrator/issue-tracker-client.d.ts +103 -0
  52. package/dist/src/orchestrator/issue-tracker-client.d.ts.map +1 -0
  53. package/dist/src/orchestrator/issue-tracker-client.js +8 -0
  54. package/dist/src/orchestrator/log-analyzer.d.ts +19 -4
  55. package/dist/src/orchestrator/log-analyzer.d.ts.map +1 -1
  56. package/dist/src/orchestrator/log-analyzer.js +26 -50
  57. package/dist/src/orchestrator/orchestrator-utils.test.js +3 -0
  58. package/dist/src/orchestrator/orchestrator.d.ts +16 -2
  59. package/dist/src/orchestrator/orchestrator.d.ts.map +1 -1
  60. package/dist/src/orchestrator/orchestrator.js +449 -115
  61. package/dist/src/orchestrator/parse-work-result.d.ts +1 -1
  62. package/dist/src/orchestrator/parse-work-result.d.ts.map +1 -1
  63. package/dist/src/orchestrator/parse-work-result.js +1 -1
  64. package/dist/src/orchestrator/session-logger.d.ts +1 -1
  65. package/dist/src/orchestrator/session-logger.d.ts.map +1 -1
  66. package/dist/src/orchestrator/state-recovery.d.ts +22 -3
  67. package/dist/src/orchestrator/state-recovery.d.ts.map +1 -1
  68. package/dist/src/orchestrator/state-recovery.js +55 -2
  69. package/dist/src/orchestrator/state-recovery.test.js +106 -2
  70. package/dist/src/orchestrator/state-types.d.ts +63 -1
  71. package/dist/src/orchestrator/state-types.d.ts.map +1 -1
  72. package/dist/src/orchestrator/state-types.js +5 -1
  73. package/dist/src/orchestrator/summary-builder.d.ts +47 -0
  74. package/dist/src/orchestrator/summary-builder.d.ts.map +1 -0
  75. package/dist/src/orchestrator/summary-builder.js +240 -0
  76. package/dist/src/orchestrator/summary-builder.test.d.ts +2 -0
  77. package/dist/src/orchestrator/summary-builder.test.d.ts.map +1 -0
  78. package/dist/src/orchestrator/summary-builder.test.js +236 -0
  79. package/dist/src/orchestrator/types.d.ts +24 -2
  80. package/dist/src/orchestrator/types.d.ts.map +1 -1
  81. package/dist/src/orchestrator/work-types.d.ts +50 -0
  82. package/dist/src/orchestrator/work-types.d.ts.map +1 -0
  83. package/dist/src/orchestrator/work-types.js +20 -0
  84. package/dist/src/templates/registry.d.ts +1 -1
  85. package/dist/src/templates/registry.test.js +2 -2
  86. package/dist/src/templates/renderer.d.ts +1 -1
  87. package/dist/src/templates/types.d.ts +6 -2
  88. package/dist/src/templates/types.d.ts.map +1 -1
  89. package/dist/src/templates/types.js +2 -0
  90. package/dist/src/templates/types.test.js +4 -3
  91. package/dist/src/tools/index.d.ts +0 -3
  92. package/dist/src/tools/index.d.ts.map +1 -1
  93. package/dist/src/tools/index.js +0 -2
  94. package/dist/src/workflow/branching-router.d.ts +38 -0
  95. package/dist/src/workflow/branching-router.d.ts.map +1 -0
  96. package/dist/src/workflow/branching-router.js +52 -0
  97. package/dist/src/workflow/branching-router.test.d.ts +2 -0
  98. package/dist/src/workflow/branching-router.test.d.ts.map +1 -0
  99. package/dist/src/workflow/branching-router.test.js +209 -0
  100. package/dist/src/workflow/duration.d.ts +28 -0
  101. package/dist/src/workflow/duration.d.ts.map +1 -0
  102. package/dist/src/workflow/duration.js +57 -0
  103. package/dist/src/workflow/duration.test.d.ts +2 -0
  104. package/dist/src/workflow/duration.test.d.ts.map +1 -0
  105. package/dist/src/workflow/duration.test.js +74 -0
  106. package/dist/src/workflow/expression/ast.d.ts +53 -0
  107. package/dist/src/workflow/expression/ast.d.ts.map +1 -0
  108. package/dist/src/workflow/expression/ast.js +8 -0
  109. package/dist/src/workflow/expression/context.d.ts +40 -0
  110. package/dist/src/workflow/expression/context.d.ts.map +1 -0
  111. package/dist/src/workflow/expression/context.js +37 -0
  112. package/dist/src/workflow/expression/evaluator.d.ts +28 -0
  113. package/dist/src/workflow/expression/evaluator.d.ts.map +1 -0
  114. package/dist/src/workflow/expression/evaluator.js +165 -0
  115. package/dist/src/workflow/expression/evaluator.test.d.ts +2 -0
  116. package/dist/src/workflow/expression/evaluator.test.d.ts.map +1 -0
  117. package/dist/src/workflow/expression/evaluator.test.js +792 -0
  118. package/dist/src/workflow/expression/expression.test.d.ts +2 -0
  119. package/dist/src/workflow/expression/expression.test.d.ts.map +1 -0
  120. package/dist/src/workflow/expression/expression.test.js +516 -0
  121. package/dist/src/workflow/expression/helpers.d.ts +21 -0
  122. package/dist/src/workflow/expression/helpers.d.ts.map +1 -0
  123. package/dist/src/workflow/expression/helpers.js +56 -0
  124. package/dist/src/workflow/expression/index.d.ts +55 -0
  125. package/dist/src/workflow/expression/index.d.ts.map +1 -0
  126. package/dist/src/workflow/expression/index.js +71 -0
  127. package/dist/src/workflow/expression/lexer.d.ts +37 -0
  128. package/dist/src/workflow/expression/lexer.d.ts.map +1 -0
  129. package/dist/src/workflow/expression/lexer.js +166 -0
  130. package/dist/src/workflow/expression/parser.d.ts +23 -0
  131. package/dist/src/workflow/expression/parser.d.ts.map +1 -0
  132. package/dist/src/workflow/expression/parser.js +181 -0
  133. package/dist/src/workflow/index.d.ts +21 -0
  134. package/dist/src/workflow/index.d.ts.map +1 -0
  135. package/dist/src/workflow/index.js +15 -0
  136. package/dist/src/workflow/retry-resolver.d.ts +51 -0
  137. package/dist/src/workflow/retry-resolver.d.ts.map +1 -0
  138. package/dist/src/workflow/retry-resolver.js +70 -0
  139. package/dist/src/workflow/retry-resolver.test.d.ts +2 -0
  140. package/dist/src/workflow/retry-resolver.test.d.ts.map +1 -0
  141. package/dist/src/workflow/retry-resolver.test.js +149 -0
  142. package/dist/src/workflow/transition-engine.d.ts +46 -0
  143. package/dist/src/workflow/transition-engine.d.ts.map +1 -0
  144. package/dist/src/workflow/transition-engine.js +113 -0
  145. package/dist/src/workflow/transition-engine.test.d.ts +2 -0
  146. package/dist/src/workflow/transition-engine.test.d.ts.map +1 -0
  147. package/dist/src/workflow/transition-engine.test.js +425 -0
  148. package/dist/src/workflow/workflow-loader.d.ts +21 -0
  149. package/dist/src/workflow/workflow-loader.d.ts.map +1 -0
  150. package/dist/src/workflow/workflow-loader.js +40 -0
  151. package/dist/src/workflow/workflow-loader.test.d.ts +2 -0
  152. package/dist/src/workflow/workflow-loader.test.d.ts.map +1 -0
  153. package/dist/src/workflow/workflow-loader.test.js +134 -0
  154. package/dist/src/workflow/workflow-registry.d.ts +97 -0
  155. package/dist/src/workflow/workflow-registry.d.ts.map +1 -0
  156. package/dist/src/workflow/workflow-registry.js +173 -0
  157. package/dist/src/workflow/workflow-registry.test.d.ts +2 -0
  158. package/dist/src/workflow/workflow-registry.test.d.ts.map +1 -0
  159. package/dist/src/workflow/workflow-registry.test.js +201 -0
  160. package/dist/src/workflow/workflow-types.d.ts +442 -0
  161. package/dist/src/workflow/workflow-types.d.ts.map +1 -0
  162. package/dist/src/workflow/workflow-types.js +113 -0
  163. package/dist/src/workflow/workflow-types.test.d.ts +2 -0
  164. package/dist/src/workflow/workflow-types.test.d.ts.map +1 -0
  165. package/dist/src/workflow/workflow-types.test.js +440 -0
  166. package/package.json +3 -4
  167. package/dist/src/linear-cli.d.ts +0 -38
  168. package/dist/src/linear-cli.d.ts.map +0 -1
  169. package/dist/src/linear-cli.js +0 -674
  170. package/dist/src/tools/linear-runner.d.ts +0 -34
  171. package/dist/src/tools/linear-runner.d.ts.map +0 -1
  172. package/dist/src/tools/linear-runner.js +0 -700
  173. package/dist/src/tools/plugins/linear.d.ts +0 -9
  174. package/dist/src/tools/plugins/linear.d.ts.map +0 -1
  175. package/dist/src/tools/plugins/linear.js +0 -138
@@ -0,0 +1,384 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ vi.mock('child_process', () => ({
3
+ exec: vi.fn(),
4
+ }));
5
+ import { exec } from 'child_process';
6
+ import { GitHubNativeMergeQueueAdapter } from './github-native.js';
7
+ const mockExec = vi.mocked(exec);
8
+ function mockGraphQLResponse(data) {
9
+ mockExec.mockImplementation((_cmd, _opts, callback) => {
10
+ // exec with options has callback as 3rd arg
11
+ const cb = typeof _opts === 'function' ? _opts : callback;
12
+ cb?.(null, { stdout: JSON.stringify({ data }) });
13
+ return {};
14
+ });
15
+ }
16
+ function mockGraphQLError(message) {
17
+ mockExec.mockImplementation((_cmd, _opts, callback) => {
18
+ const cb = typeof _opts === 'function' ? _opts : callback;
19
+ cb?.(new Error(message), { stdout: '' });
20
+ return {};
21
+ });
22
+ }
23
+ function mockGraphQLErrorResponse(errors) {
24
+ mockExec.mockImplementation((_cmd, _opts, callback) => {
25
+ const cb = typeof _opts === 'function' ? _opts : callback;
26
+ cb?.(null, { stdout: JSON.stringify({ errors }) });
27
+ return {};
28
+ });
29
+ }
30
+ describe('GitHubNativeMergeQueueAdapter', () => {
31
+ let adapter;
32
+ beforeEach(() => {
33
+ vi.clearAllMocks();
34
+ adapter = new GitHubNativeMergeQueueAdapter();
35
+ });
36
+ it('has name "github-native"', () => {
37
+ expect(adapter.name).toBe('github-native');
38
+ });
39
+ describe('canEnqueue', () => {
40
+ it('returns true when PR is mergeable and approved', async () => {
41
+ mockGraphQLResponse({
42
+ repository: {
43
+ pullRequest: {
44
+ mergeable: 'MERGEABLE',
45
+ reviewDecision: 'APPROVED',
46
+ mergeQueueEntry: null,
47
+ baseRef: {
48
+ branchProtectionRule: { requiresStatusChecks: true },
49
+ },
50
+ },
51
+ },
52
+ });
53
+ const result = await adapter.canEnqueue('owner', 'repo', 1);
54
+ expect(result).toBe(true);
55
+ });
56
+ it('returns false when PR is already in queue', async () => {
57
+ mockGraphQLResponse({
58
+ repository: {
59
+ pullRequest: {
60
+ mergeable: 'MERGEABLE',
61
+ reviewDecision: 'APPROVED',
62
+ mergeQueueEntry: { state: 'QUEUED' },
63
+ baseRef: {
64
+ branchProtectionRule: { requiresStatusChecks: true },
65
+ },
66
+ },
67
+ },
68
+ });
69
+ const result = await adapter.canEnqueue('owner', 'repo', 1);
70
+ expect(result).toBe(false);
71
+ });
72
+ it('returns false when PR is not mergeable', async () => {
73
+ mockGraphQLResponse({
74
+ repository: {
75
+ pullRequest: {
76
+ mergeable: 'CONFLICTING',
77
+ reviewDecision: 'APPROVED',
78
+ mergeQueueEntry: null,
79
+ baseRef: {
80
+ branchProtectionRule: { requiresStatusChecks: true },
81
+ },
82
+ },
83
+ },
84
+ });
85
+ const result = await adapter.canEnqueue('owner', 'repo', 1);
86
+ expect(result).toBe(false);
87
+ });
88
+ it('returns false when PR is not approved', async () => {
89
+ mockGraphQLResponse({
90
+ repository: {
91
+ pullRequest: {
92
+ mergeable: 'MERGEABLE',
93
+ reviewDecision: 'CHANGES_REQUESTED',
94
+ mergeQueueEntry: null,
95
+ baseRef: {
96
+ branchProtectionRule: { requiresStatusChecks: true },
97
+ },
98
+ },
99
+ },
100
+ });
101
+ const result = await adapter.canEnqueue('owner', 'repo', 1);
102
+ expect(result).toBe(false);
103
+ });
104
+ it('returns true when reviewDecision is null (no reviews required)', async () => {
105
+ mockGraphQLResponse({
106
+ repository: {
107
+ pullRequest: {
108
+ mergeable: 'MERGEABLE',
109
+ reviewDecision: null,
110
+ mergeQueueEntry: null,
111
+ baseRef: {
112
+ branchProtectionRule: null,
113
+ },
114
+ },
115
+ },
116
+ });
117
+ const result = await adapter.canEnqueue('owner', 'repo', 1);
118
+ expect(result).toBe(true);
119
+ });
120
+ it('returns false on API error', async () => {
121
+ mockGraphQLError('API rate limit exceeded');
122
+ const result = await adapter.canEnqueue('owner', 'repo', 1);
123
+ expect(result).toBe(false);
124
+ });
125
+ });
126
+ describe('enqueue', () => {
127
+ it('enqueues a PR and returns status', async () => {
128
+ // First graphql call: getPRNodeId, Second: enqueue mutation
129
+ function mockExecOnce(data) {
130
+ mockExec.mockImplementationOnce((_cmd, _opts, callback) => {
131
+ const cb = typeof _opts === 'function' ? _opts : callback;
132
+ cb?.(null, { stdout: JSON.stringify({ data }) });
133
+ return {};
134
+ });
135
+ }
136
+ mockExecOnce({ repository: { pullRequest: { id: 'PR_node_123' } } });
137
+ mockExecOnce({
138
+ enqueuePullRequest: {
139
+ mergeQueueEntry: {
140
+ state: 'QUEUED',
141
+ position: 1,
142
+ headCommit: { oid: 'abc123' },
143
+ enqueuedAt: '2026-03-24T00:00:00Z',
144
+ },
145
+ },
146
+ });
147
+ const result = await adapter.enqueue('owner', 'repo', 1);
148
+ expect(result.state).toBe('queued');
149
+ expect(result.position).toBe(1);
150
+ });
151
+ it('returns failed status when enqueue mutation throws', async () => {
152
+ // getPRNodeId succeeds
153
+ mockExec.mockImplementationOnce((_cmd, _opts, callback) => {
154
+ const cb = typeof _opts === 'function' ? _opts : callback;
155
+ cb?.(null, {
156
+ stdout: JSON.stringify({
157
+ data: { repository: { pullRequest: { id: 'PR_node_123' } } },
158
+ }),
159
+ });
160
+ return {};
161
+ });
162
+ // enqueue mutation fails (all retries)
163
+ mockExec.mockImplementation((_cmd, _opts, callback) => {
164
+ const cb = typeof _opts === 'function' ? _opts : callback;
165
+ cb?.(new Error('Permission denied'), { stdout: '' });
166
+ return {};
167
+ });
168
+ const result = await adapter.enqueue('owner', 'repo', 1);
169
+ expect(result.state).toBe('failed');
170
+ expect(result.failureReason).toContain('Permission denied');
171
+ });
172
+ });
173
+ describe('getStatus', () => {
174
+ it('returns queued status with check info', async () => {
175
+ mockGraphQLResponse({
176
+ repository: {
177
+ pullRequest: {
178
+ mergeQueueEntry: {
179
+ state: 'QUEUED',
180
+ position: 2,
181
+ headCommit: { oid: 'abc123' },
182
+ enqueuedAt: '2026-03-24T00:00:00Z',
183
+ },
184
+ commits: {
185
+ nodes: [
186
+ {
187
+ commit: {
188
+ statusCheckRollup: {
189
+ contexts: {
190
+ nodes: [
191
+ { name: 'CI', conclusion: 'SUCCESS', status: 'COMPLETED' },
192
+ { name: 'lint', conclusion: null, status: 'IN_PROGRESS' },
193
+ ],
194
+ },
195
+ },
196
+ },
197
+ },
198
+ ],
199
+ },
200
+ },
201
+ },
202
+ });
203
+ const result = await adapter.getStatus('owner', 'repo', 1);
204
+ expect(result.state).toBe('queued');
205
+ expect(result.position).toBe(2);
206
+ expect(result.checksStatus).toHaveLength(2);
207
+ expect(result.checksStatus[0]).toEqual({ name: 'CI', status: 'pass' });
208
+ expect(result.checksStatus[1]).toEqual({ name: 'lint', status: 'pending' });
209
+ });
210
+ it('returns not-queued when no merge queue entry', async () => {
211
+ mockGraphQLResponse({
212
+ repository: {
213
+ pullRequest: {
214
+ mergeQueueEntry: null,
215
+ commits: { nodes: [] },
216
+ },
217
+ },
218
+ });
219
+ const result = await adapter.getStatus('owner', 'repo', 1);
220
+ expect(result.state).toBe('not-queued');
221
+ });
222
+ it('maps MERGEABLE state to merging', async () => {
223
+ mockGraphQLResponse({
224
+ repository: {
225
+ pullRequest: {
226
+ mergeQueueEntry: {
227
+ state: 'MERGEABLE',
228
+ position: 1,
229
+ headCommit: { oid: 'abc123' },
230
+ enqueuedAt: '2026-03-24T00:00:00Z',
231
+ },
232
+ commits: { nodes: [] },
233
+ },
234
+ },
235
+ });
236
+ const result = await adapter.getStatus('owner', 'repo', 1);
237
+ expect(result.state).toBe('merging');
238
+ });
239
+ it('maps StatusContext nodes correctly', async () => {
240
+ mockGraphQLResponse({
241
+ repository: {
242
+ pullRequest: {
243
+ mergeQueueEntry: {
244
+ state: 'QUEUED',
245
+ position: 1,
246
+ headCommit: { oid: 'abc123' },
247
+ enqueuedAt: '2026-03-24T00:00:00Z',
248
+ },
249
+ commits: {
250
+ nodes: [
251
+ {
252
+ commit: {
253
+ statusCheckRollup: {
254
+ contexts: {
255
+ nodes: [
256
+ { context: 'deploy', state: 'SUCCESS' },
257
+ { context: 'build', state: 'PENDING' },
258
+ { context: 'test', state: 'FAILURE' },
259
+ ],
260
+ },
261
+ },
262
+ },
263
+ },
264
+ ],
265
+ },
266
+ },
267
+ },
268
+ });
269
+ const result = await adapter.getStatus('owner', 'repo', 1);
270
+ expect(result.checksStatus).toEqual([
271
+ { name: 'deploy', status: 'pass' },
272
+ { name: 'build', status: 'pending' },
273
+ { name: 'test', status: 'fail' },
274
+ ]);
275
+ });
276
+ });
277
+ describe('dequeue', () => {
278
+ it('dequeues a PR successfully', async () => {
279
+ // First call: getPRNodeId
280
+ mockExec.mockImplementationOnce((_cmd, _opts, callback) => {
281
+ const cb = typeof _opts === 'function' ? _opts : callback;
282
+ cb?.(null, {
283
+ stdout: JSON.stringify({
284
+ data: { repository: { pullRequest: { id: 'PR_node_123' } } },
285
+ }),
286
+ });
287
+ return {};
288
+ });
289
+ // Second call: dequeue mutation
290
+ mockExec.mockImplementationOnce((_cmd, _opts, callback) => {
291
+ const cb = typeof _opts === 'function' ? _opts : callback;
292
+ cb?.(null, {
293
+ stdout: JSON.stringify({
294
+ data: { dequeuePullRequest: { mergeQueueEntry: { state: 'QUEUED' } } },
295
+ }),
296
+ });
297
+ return {};
298
+ });
299
+ await expect(adapter.dequeue('owner', 'repo', 1)).resolves.toBeUndefined();
300
+ });
301
+ });
302
+ describe('isEnabled', () => {
303
+ it('returns true when merge queue is required', async () => {
304
+ mockGraphQLResponse({
305
+ repository: {
306
+ defaultBranchRef: {
307
+ branchProtectionRule: { requiresMergeQueue: true },
308
+ },
309
+ },
310
+ });
311
+ const result = await adapter.isEnabled('owner', 'repo');
312
+ expect(result).toBe(true);
313
+ });
314
+ it('returns false when merge queue is not required', async () => {
315
+ mockGraphQLResponse({
316
+ repository: {
317
+ defaultBranchRef: {
318
+ branchProtectionRule: { requiresMergeQueue: false },
319
+ },
320
+ },
321
+ });
322
+ const result = await adapter.isEnabled('owner', 'repo');
323
+ expect(result).toBe(false);
324
+ });
325
+ it('returns false when no branch protection', async () => {
326
+ mockGraphQLResponse({
327
+ repository: {
328
+ defaultBranchRef: {
329
+ branchProtectionRule: null,
330
+ },
331
+ },
332
+ });
333
+ const result = await adapter.isEnabled('owner', 'repo');
334
+ expect(result).toBe(false);
335
+ });
336
+ it('returns false on API error', async () => {
337
+ mockGraphQLError('Not found');
338
+ const result = await adapter.isEnabled('owner', 'repo');
339
+ expect(result).toBe(false);
340
+ });
341
+ });
342
+ describe('graphql retry logic', () => {
343
+ it('retries on transient failure then succeeds', async () => {
344
+ let callCount = 0;
345
+ mockExec.mockImplementation((_cmd, _opts, callback) => {
346
+ const cb = typeof _opts === 'function' ? _opts : callback;
347
+ callCount++;
348
+ if (callCount === 1) {
349
+ cb?.(new Error('ETIMEDOUT'), { stdout: '' });
350
+ }
351
+ else {
352
+ cb?.(null, {
353
+ stdout: JSON.stringify({
354
+ data: {
355
+ repository: {
356
+ defaultBranchRef: {
357
+ branchProtectionRule: { requiresMergeQueue: true },
358
+ },
359
+ },
360
+ },
361
+ }),
362
+ });
363
+ }
364
+ return {};
365
+ });
366
+ const result = await adapter.isEnabled('owner', 'repo');
367
+ expect(result).toBe(true);
368
+ expect(callCount).toBe(2);
369
+ });
370
+ it('throws after exhausting retries', async () => {
371
+ mockGraphQLError('Server error');
372
+ // canEnqueue catches and returns false, but we can test via isEnabled which also catches
373
+ // Let's test directly by triggering a method that propagates errors
374
+ // getStatus does NOT catch errors — it will throw
375
+ await expect(adapter.getStatus('owner', 'repo', 1)).rejects.toThrow('Server error');
376
+ // 1 initial + 2 retries = 3 calls
377
+ expect(mockExec).toHaveBeenCalledTimes(3);
378
+ });
379
+ it('handles GraphQL error responses', async () => {
380
+ mockGraphQLErrorResponse([{ message: 'Resource not found' }]);
381
+ await expect(adapter.getStatus('owner', 'repo', 1)).rejects.toThrow('Resource not found');
382
+ });
383
+ });
384
+ });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Merge Queue Module
3
+ *
4
+ * Factory and exports for merge queue adapters.
5
+ */
6
+ export type { MergeQueueAdapter, MergeQueueStatus, MergeQueueProviderName } from './types.js';
7
+ /**
8
+ * Create a merge queue adapter by provider name.
9
+ *
10
+ * Currently only 'github-native' is implemented.
11
+ * 'mergify' and 'trunk' will throw until implemented.
12
+ *
13
+ * @param name - Provider name
14
+ * @returns MergeQueueAdapter instance
15
+ * @throws Error if provider is not yet implemented
16
+ */
17
+ export declare function createMergeQueueAdapter(name: import('./types.js').MergeQueueProviderName): import('./types.js').MergeQueueAdapter;
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/merge-queue/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAE7F;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,YAAY,EAAE,sBAAsB,GAAG,OAAO,YAAY,EAAE,iBAAiB,CAiBjI"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Merge Queue Module
3
+ *
4
+ * Factory and exports for merge queue adapters.
5
+ */
6
+ import { GitHubNativeMergeQueueAdapter } from './adapters/github-native.js';
7
+ /**
8
+ * Create a merge queue adapter by provider name.
9
+ *
10
+ * Currently only 'github-native' is implemented.
11
+ * 'mergify' and 'trunk' will throw until implemented.
12
+ *
13
+ * @param name - Provider name
14
+ * @returns MergeQueueAdapter instance
15
+ * @throws Error if provider is not yet implemented
16
+ */
17
+ export function createMergeQueueAdapter(name) {
18
+ switch (name) {
19
+ case 'github-native':
20
+ return new GitHubNativeMergeQueueAdapter();
21
+ case 'mergify':
22
+ throw new Error('Mergify merge queue adapter not yet implemented. Contributions welcome.');
23
+ case 'trunk':
24
+ throw new Error('Trunk merge queue adapter not yet implemented. Contributions welcome.');
25
+ default:
26
+ throw new Error(`Unknown merge queue provider: ${name}. Supported: github-native, mergify, trunk.`);
27
+ }
28
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=merge-queue.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-queue.integration.test.d.ts","sourceRoot":"","sources":["../../../src/merge-queue/merge-queue.integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,128 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { createMergeQueueAdapter } from './index.js';
3
+ import { GitHubNativeMergeQueueAdapter } from './adapters/github-native.js';
4
+ describe('merge queue integration', () => {
5
+ describe('createMergeQueueAdapter factory', () => {
6
+ it('creates GitHub native adapter', () => {
7
+ const adapter = createMergeQueueAdapter('github-native');
8
+ expect(adapter).toBeInstanceOf(GitHubNativeMergeQueueAdapter);
9
+ expect(adapter.name).toBe('github-native');
10
+ });
11
+ it('throws for mergify (not yet implemented)', () => {
12
+ expect(() => createMergeQueueAdapter('mergify')).toThrow('not yet implemented');
13
+ });
14
+ it('throws for trunk (not yet implemented)', () => {
15
+ expect(() => createMergeQueueAdapter('trunk')).toThrow('not yet implemented');
16
+ });
17
+ it('throws for unknown provider', () => {
18
+ expect(() => createMergeQueueAdapter('unknown')).toThrow('Unknown merge queue provider');
19
+ });
20
+ });
21
+ describe('adapter interface compliance', () => {
22
+ it('GitHubNativeMergeQueueAdapter implements all MergeQueueAdapter methods', () => {
23
+ const adapter = new GitHubNativeMergeQueueAdapter();
24
+ expect(typeof adapter.canEnqueue).toBe('function');
25
+ expect(typeof adapter.enqueue).toBe('function');
26
+ expect(typeof adapter.getStatus).toBe('function');
27
+ expect(typeof adapter.dequeue).toBe('function');
28
+ expect(typeof adapter.isEnabled).toBe('function');
29
+ expect(adapter.name).toBe('github-native');
30
+ });
31
+ });
32
+ describe('orchestrator merge queue wiring', () => {
33
+ it('mock adapter can be injected and used in lifecycle', async () => {
34
+ const mockStatus = {
35
+ state: 'queued',
36
+ position: 1,
37
+ checksStatus: [{ name: 'CI', status: 'pass' }],
38
+ };
39
+ const mockAdapter = {
40
+ name: 'github-native',
41
+ canEnqueue: vi.fn().mockResolvedValue(true),
42
+ enqueue: vi.fn().mockResolvedValue(mockStatus),
43
+ getStatus: vi.fn().mockResolvedValue(mockStatus),
44
+ dequeue: vi.fn().mockResolvedValue(undefined),
45
+ isEnabled: vi.fn().mockResolvedValue(true),
46
+ };
47
+ // Verify adapter works as expected when called
48
+ expect(await mockAdapter.canEnqueue('owner', 'repo', 1)).toBe(true);
49
+ expect(await mockAdapter.enqueue('owner', 'repo', 1)).toEqual(mockStatus);
50
+ expect(await mockAdapter.getStatus('owner', 'repo', 1)).toEqual(mockStatus);
51
+ await mockAdapter.dequeue('owner', 'repo', 1);
52
+ expect(await mockAdapter.isEnabled('owner', 'repo')).toBe(true);
53
+ expect(mockAdapter.canEnqueue).toHaveBeenCalledWith('owner', 'repo', 1);
54
+ expect(mockAdapter.enqueue).toHaveBeenCalledWith('owner', 'repo', 1);
55
+ expect(mockAdapter.dequeue).toHaveBeenCalledWith('owner', 'repo', 1);
56
+ });
57
+ it('mock adapter handles PR URL parsing for enqueue', async () => {
58
+ const mockAdapter = {
59
+ name: 'github-native',
60
+ canEnqueue: vi.fn().mockResolvedValue(true),
61
+ enqueue: vi.fn().mockResolvedValue({ state: 'queued', checksStatus: [] }),
62
+ getStatus: vi.fn(),
63
+ dequeue: vi.fn(),
64
+ isEnabled: vi.fn(),
65
+ };
66
+ // Simulate the PR URL parsing logic from the orchestrator
67
+ const pullRequestUrl = 'https://github.com/RenseiAI/agentfactory/pull/31';
68
+ const prMatch = pullRequestUrl.match(/\/([^/]+)\/([^/]+)\/pull\/(\d+)/);
69
+ expect(prMatch).not.toBeNull();
70
+ if (prMatch) {
71
+ const [, owner, repo, prNum] = prMatch;
72
+ expect(owner).toBe('RenseiAI');
73
+ expect(repo).toBe('agentfactory');
74
+ expect(prNum).toBe('31');
75
+ const canEnqueue = await mockAdapter.canEnqueue(owner, repo, parseInt(prNum, 10));
76
+ expect(canEnqueue).toBe(true);
77
+ if (canEnqueue) {
78
+ const status = await mockAdapter.enqueue(owner, repo, parseInt(prNum, 10));
79
+ expect(status.state).toBe('queued');
80
+ }
81
+ }
82
+ });
83
+ it('mock adapter handles dequeue on failure', async () => {
84
+ const mockAdapter = {
85
+ name: 'github-native',
86
+ canEnqueue: vi.fn(),
87
+ enqueue: vi.fn(),
88
+ getStatus: vi.fn(),
89
+ dequeue: vi.fn().mockResolvedValue(undefined),
90
+ isEnabled: vi.fn(),
91
+ };
92
+ // Simulate the failure dequeue logic from the orchestrator
93
+ const pullRequestUrl = 'https://github.com/RenseiAI/agentfactory/pull/31';
94
+ const prMatch = pullRequestUrl.match(/\/([^/]+)\/([^/]+)\/pull\/(\d+)/);
95
+ if (prMatch) {
96
+ const [, owner, repo, prNum] = prMatch;
97
+ await mockAdapter.dequeue(owner, repo, parseInt(prNum, 10));
98
+ expect(mockAdapter.dequeue).toHaveBeenCalledWith('RenseiAI', 'agentfactory', 31);
99
+ }
100
+ });
101
+ it('handles dequeue errors gracefully', async () => {
102
+ const mockAdapter = {
103
+ name: 'github-native',
104
+ canEnqueue: vi.fn(),
105
+ enqueue: vi.fn(),
106
+ getStatus: vi.fn(),
107
+ dequeue: vi.fn().mockRejectedValue(new Error('API rate limit')),
108
+ isEnabled: vi.fn(),
109
+ };
110
+ // The orchestrator wraps dequeue in try/catch — verify the error is thrown
111
+ await expect(mockAdapter.dequeue('owner', 'repo', 1)).rejects.toThrow('API rate limit');
112
+ });
113
+ it('skips enqueue when canEnqueue returns false', async () => {
114
+ const mockAdapter = {
115
+ name: 'github-native',
116
+ canEnqueue: vi.fn().mockResolvedValue(false),
117
+ enqueue: vi.fn(),
118
+ getStatus: vi.fn(),
119
+ dequeue: vi.fn(),
120
+ isEnabled: vi.fn(),
121
+ };
122
+ const canEnqueue = await mockAdapter.canEnqueue('owner', 'repo', 1);
123
+ expect(canEnqueue).toBe(false);
124
+ // enqueue should NOT be called
125
+ expect(mockAdapter.enqueue).not.toHaveBeenCalled();
126
+ });
127
+ });
128
+ });
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Merge Queue Adapter Interface
3
+ *
4
+ * Provider-agnostic abstraction for merge queue operations.
5
+ * Supports GitHub native merge queue, Mergify, and Trunk.
6
+ * Concrete implementations live in adapters/ subdirectory.
7
+ */
8
+ /** Supported merge queue provider names */
9
+ export type MergeQueueProviderName = 'github-native' | 'mergify' | 'trunk';
10
+ /** Status of a PR in the merge queue */
11
+ export interface MergeQueueStatus {
12
+ /** Current state in the merge queue */
13
+ state: 'queued' | 'merging' | 'merged' | 'failed' | 'blocked' | 'not-queued';
14
+ /** Position in queue (1-based), undefined if not queued */
15
+ position?: number;
16
+ /** Estimated time until merge, if available */
17
+ estimatedMergeTime?: Date;
18
+ /** Reason for failure, if state is 'failed' or 'blocked' */
19
+ failureReason?: string;
20
+ /** Status of required checks */
21
+ checksStatus: {
22
+ name: string;
23
+ status: 'pass' | 'fail' | 'pending';
24
+ }[];
25
+ }
26
+ /**
27
+ * Provider-agnostic merge queue adapter.
28
+ *
29
+ * Each implementation wraps a specific merge queue provider's API
30
+ * (GitHub native, Mergify, Trunk) behind this common interface.
31
+ * The adapter handles only queue management — conflict resolution
32
+ * is handled at the git level by mergiraf.
33
+ */
34
+ export interface MergeQueueAdapter {
35
+ /** Provider name identifier */
36
+ readonly name: MergeQueueProviderName;
37
+ /** Check if a PR is eligible for merge queue entry */
38
+ canEnqueue(owner: string, repo: string, prNumber: number): Promise<boolean>;
39
+ /** Add a PR to the merge queue */
40
+ enqueue(owner: string, repo: string, prNumber: number): Promise<MergeQueueStatus>;
41
+ /** Get current queue status for a PR */
42
+ getStatus(owner: string, repo: string, prNumber: number): Promise<MergeQueueStatus>;
43
+ /** Remove a PR from the merge queue */
44
+ dequeue(owner: string, repo: string, prNumber: number): Promise<void>;
45
+ /** Check if a repository has merge queue enabled */
46
+ isEnabled(owner: string, repo: string): Promise<boolean>;
47
+ }
48
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/merge-queue/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,2CAA2C;AAC3C,MAAM,MAAM,sBAAsB,GAAG,eAAe,GAAG,SAAS,GAAG,OAAO,CAAA;AAE1E,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAA;IAC5E,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,+CAA+C;IAC/C,kBAAkB,CAAC,EAAE,IAAI,CAAA;IACzB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,gCAAgC;IAChC,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,EAAE,CAAA;CACtE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAA;IAErC,sDAAsD;IACtD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAE3E,kCAAkC;IAClC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAEjF,wCAAwC;IACxC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAEnF,uCAAuC;IACvC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAErE,oDAAoD;IACpD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACzD"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Merge Queue Adapter Interface
3
+ *
4
+ * Provider-agnostic abstraction for merge queue operations.
5
+ * Supports GitHub native merge queue, Mergify, and Trunk.
6
+ * Concrete implementations live in adapters/ subdirectory.
7
+ */
8
+ export {};
@@ -12,11 +12,11 @@
12
12
  * - result → response (persisted)
13
13
  * - error → error (persisted)
14
14
  */
15
- import type { AgentSession } from '@renseiai/agentfactory-linear';
15
+ import type { IssueTrackerSession } from './issue-tracker-client.js';
16
16
  /** Configuration for the activity emitter */
17
17
  export interface ActivityEmitterConfig {
18
- /** AgentSession to emit activities to */
19
- session: AgentSession;
18
+ /** Issue tracker session to emit activities to */
19
+ session: IssueTrackerSession;
20
20
  /** Minimum interval between activities in ms (default: 500ms) */
21
21
  minInterval?: number;
22
22
  /** Maximum length for tool outputs before truncation (default: 2000) */
@@ -1 +1 @@
1
- {"version":3,"file":"activity-emitter.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/activity-emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAGjE,6CAA6C;AAC7C,MAAM,WAAW,qBAAqB;IACpC,yCAAyC;IACzC,OAAO,EAAE,YAAY,CAAA;IACrB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,oDAAoD;IACpD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3D,sDAAsD;IACtD,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9D;AAcD;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAyC;IAC5E,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAyC;IAE9E,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,UAAU,CAA6C;IAC/D,OAAO,CAAC,YAAY,CAAQ;IAE5B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAyB;gBAEhD,MAAM,EAAE,qBAAqB;IASzC;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpE;;OAEG;IACG,WAAW,CACf,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,UAAO,GACf,OAAO,CAAC,IAAI,CAAC;IAWhB;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlD;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASrD;;;;;;;;OAQG;IACG,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;QACR,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAC5C,GACA,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IA2BlE;;OAEG;YACW,aAAa;IAe3B;;OAEG;YACW,YAAY;IA+B1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAiD7B;;OAEG;YACW,YAAY;IA6C1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoC1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAQtB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,qBAAqB,GAC5B,eAAe,CAEjB"}
1
+ {"version":3,"file":"activity-emitter.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/activity-emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAGpE,6CAA6C;AAC7C,MAAM,WAAW,qBAAqB;IACpC,kDAAkD;IAClD,OAAO,EAAE,mBAAmB,CAAA;IAC5B,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,oDAAoD;IACpD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3D,sDAAsD;IACtD,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9D;AAcD;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAyC;IAC5E,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAyC;IAE9E,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,UAAU,CAA6C;IAC/D,OAAO,CAAC,YAAY,CAAQ;IAE5B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAyB;gBAEhD,MAAM,EAAE,qBAAqB;IASzC;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpE;;OAEG;IACG,WAAW,CACf,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,UAAO,GACf,OAAO,CAAC,IAAI,CAAC;IAWhB;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlD;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASrD;;;;;;;;OAQG;IACG,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;QACR,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAC5C,GACA,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IA2BlE;;OAEG;YACW,aAAa;IAe3B;;OAEG;YACW,YAAY;IA+B1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAiD7B;;OAEG;YACW,YAAY;IA6C1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoC1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAQtB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,qBAAqB,GAC5B,eAAe,CAEjB"}