@diff-review-system/drs 1.1.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/.opencode/agent/describe/pr-describer.md +221 -0
  2. package/.opencode/agent/review/documentation.md +56 -0
  3. package/.opencode/agent/review/performance.md +32 -139
  4. package/.opencode/agent/review/quality.md +36 -113
  5. package/.opencode/agent/review/security.md +32 -97
  6. package/.opencode/agent/review/style.md +4 -0
  7. package/.opencode/agent/review/unified-reviewer.md +74 -0
  8. package/.opencode/opencode.jsonc +4 -29
  9. package/.opencode/tool/write_json_output.ts +24 -0
  10. package/README.md +48 -21
  11. package/dist/ci/runner.d.ts.map +1 -1
  12. package/dist/ci/runner.js +2 -0
  13. package/dist/ci/runner.js.map +1 -1
  14. package/dist/cli/describe-mr.d.ts +11 -0
  15. package/dist/cli/describe-mr.d.ts.map +1 -0
  16. package/dist/cli/describe-mr.js +104 -0
  17. package/dist/cli/describe-mr.js.map +1 -0
  18. package/dist/cli/describe-pr.d.ts +12 -0
  19. package/dist/cli/describe-pr.d.ts.map +1 -0
  20. package/dist/cli/describe-pr.js +105 -0
  21. package/dist/cli/describe-pr.js.map +1 -0
  22. package/dist/cli/index.js +222 -16
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/cli/init.d.ts +1 -1
  25. package/dist/cli/init.d.ts.map +1 -1
  26. package/dist/cli/init.js +273 -145
  27. package/dist/cli/init.js.map +1 -1
  28. package/dist/cli/post-comments.d.ts +16 -0
  29. package/dist/cli/post-comments.d.ts.map +1 -0
  30. package/dist/cli/post-comments.js +222 -0
  31. package/dist/cli/post-comments.js.map +1 -0
  32. package/dist/cli/review-local.d.ts +3 -0
  33. package/dist/cli/review-local.d.ts.map +1 -1
  34. package/dist/cli/review-local.js +44 -18
  35. package/dist/cli/review-local.js.map +1 -1
  36. package/dist/cli/review-mr.d.ts +6 -0
  37. package/dist/cli/review-mr.d.ts.map +1 -1
  38. package/dist/cli/review-mr.js +63 -7
  39. package/dist/cli/review-mr.js.map +1 -1
  40. package/dist/cli/review-pr.d.ts +6 -0
  41. package/dist/cli/review-pr.d.ts.map +1 -1
  42. package/dist/cli/review-pr.js +8 -1
  43. package/dist/cli/review-pr.js.map +1 -1
  44. package/dist/cli/show-changes.d.ts +15 -0
  45. package/dist/cli/show-changes.d.ts.map +1 -0
  46. package/dist/cli/show-changes.js +184 -0
  47. package/dist/cli/show-changes.js.map +1 -0
  48. package/dist/github/platform-adapter.d.ts.map +1 -1
  49. package/dist/github/platform-adapter.js +4 -2
  50. package/dist/github/platform-adapter.js.map +1 -1
  51. package/dist/gitlab/client.d.ts.map +1 -1
  52. package/dist/gitlab/client.js +1 -1
  53. package/dist/gitlab/client.js.map +1 -1
  54. package/dist/gitlab/platform-adapter.d.ts.map +1 -1
  55. package/dist/gitlab/platform-adapter.js +6 -5
  56. package/dist/gitlab/platform-adapter.js.map +1 -1
  57. package/dist/lib/change-summary.d.ts +8 -0
  58. package/dist/lib/change-summary.d.ts.map +1 -0
  59. package/dist/lib/change-summary.js +2 -0
  60. package/dist/lib/change-summary.js.map +1 -0
  61. package/dist/lib/comment-formatter.d.ts +3 -2
  62. package/dist/lib/comment-formatter.d.ts.map +1 -1
  63. package/dist/lib/comment-formatter.js +16 -2
  64. package/dist/lib/comment-formatter.js.map +1 -1
  65. package/dist/lib/comment-formatter.test.d.ts +2 -0
  66. package/dist/lib/comment-formatter.test.d.ts.map +1 -0
  67. package/dist/lib/comment-formatter.test.js +607 -0
  68. package/dist/lib/comment-formatter.test.js.map +1 -0
  69. package/dist/lib/comment-manager.test.d.ts +2 -0
  70. package/dist/lib/comment-manager.test.d.ts.map +1 -0
  71. package/dist/lib/comment-manager.test.js +618 -0
  72. package/dist/lib/comment-manager.test.js.map +1 -0
  73. package/dist/lib/comment-poster.d.ts +21 -0
  74. package/dist/lib/comment-poster.d.ts.map +1 -0
  75. package/dist/lib/comment-poster.js +96 -0
  76. package/dist/lib/comment-poster.js.map +1 -0
  77. package/dist/lib/comment-poster.test.d.ts +5 -0
  78. package/dist/lib/comment-poster.test.d.ts.map +1 -0
  79. package/dist/lib/comment-poster.test.js +215 -0
  80. package/dist/lib/comment-poster.test.js.map +1 -0
  81. package/dist/lib/config-model-overrides.test.js +71 -41
  82. package/dist/lib/config-model-overrides.test.js.map +1 -1
  83. package/dist/lib/config.d.ts +65 -7
  84. package/dist/lib/config.d.ts.map +1 -1
  85. package/dist/lib/config.js +122 -22
  86. package/dist/lib/config.js.map +1 -1
  87. package/dist/lib/config.test.js +31 -2
  88. package/dist/lib/config.test.js.map +1 -1
  89. package/dist/lib/context-compression.d.ts +19 -0
  90. package/dist/lib/context-compression.d.ts.map +1 -0
  91. package/dist/lib/context-compression.js +170 -0
  92. package/dist/lib/context-compression.js.map +1 -0
  93. package/dist/lib/context-compression.test.d.ts +2 -0
  94. package/dist/lib/context-compression.test.d.ts.map +1 -0
  95. package/dist/lib/context-compression.test.js +33 -0
  96. package/dist/lib/context-compression.test.js.map +1 -0
  97. package/dist/lib/context-loader.d.ts.map +1 -1
  98. package/dist/lib/context-loader.js +8 -1
  99. package/dist/lib/context-loader.js.map +1 -1
  100. package/dist/lib/context-loader.test.d.ts +2 -0
  101. package/dist/lib/context-loader.test.d.ts.map +1 -0
  102. package/dist/lib/context-loader.test.js +207 -0
  103. package/dist/lib/context-loader.test.js.map +1 -0
  104. package/dist/lib/describe-core.d.ts +9 -0
  105. package/dist/lib/describe-core.d.ts.map +1 -0
  106. package/dist/lib/describe-core.js +71 -0
  107. package/dist/lib/describe-core.js.map +1 -0
  108. package/dist/lib/describe-core.test.d.ts +2 -0
  109. package/dist/lib/describe-core.test.d.ts.map +1 -0
  110. package/dist/lib/describe-core.test.js +208 -0
  111. package/dist/lib/describe-core.test.js.map +1 -0
  112. package/dist/lib/describe-output-path.test.d.ts +2 -0
  113. package/dist/lib/describe-output-path.test.d.ts.map +1 -0
  114. package/dist/lib/describe-output-path.test.js +51 -0
  115. package/dist/lib/describe-output-path.test.js.map +1 -0
  116. package/dist/lib/describe-parser.d.ts +3 -0
  117. package/dist/lib/describe-parser.d.ts.map +1 -0
  118. package/dist/lib/describe-parser.js +163 -0
  119. package/dist/lib/describe-parser.js.map +1 -0
  120. package/dist/lib/describe-parser.test.d.ts +2 -0
  121. package/dist/lib/describe-parser.test.d.ts.map +1 -0
  122. package/dist/lib/describe-parser.test.js +282 -0
  123. package/dist/lib/describe-parser.test.js.map +1 -0
  124. package/dist/lib/description-executor.d.ts +22 -0
  125. package/dist/lib/description-executor.d.ts.map +1 -0
  126. package/dist/lib/description-executor.js +72 -0
  127. package/dist/lib/description-executor.js.map +1 -0
  128. package/dist/lib/description-formatter.d.ts +37 -0
  129. package/dist/lib/description-formatter.d.ts.map +1 -0
  130. package/dist/lib/description-formatter.js +219 -0
  131. package/dist/lib/description-formatter.js.map +1 -0
  132. package/dist/lib/diff-parser.d.ts +11 -0
  133. package/dist/lib/diff-parser.d.ts.map +1 -1
  134. package/dist/lib/diff-parser.js +37 -0
  135. package/dist/lib/diff-parser.js.map +1 -1
  136. package/dist/lib/issue-parser.d.ts +1 -1
  137. package/dist/lib/issue-parser.d.ts.map +1 -1
  138. package/dist/lib/issue-parser.js +16 -14
  139. package/dist/lib/issue-parser.js.map +1 -1
  140. package/dist/lib/json-output-schema.d.ts +207 -0
  141. package/dist/lib/json-output-schema.d.ts.map +1 -0
  142. package/dist/lib/json-output-schema.js +124 -0
  143. package/dist/lib/json-output-schema.js.map +1 -0
  144. package/dist/lib/json-output-schema.test.d.ts +2 -0
  145. package/dist/lib/json-output-schema.test.d.ts.map +1 -0
  146. package/dist/lib/json-output-schema.test.js +92 -0
  147. package/dist/lib/json-output-schema.test.js.map +1 -0
  148. package/dist/lib/json-output.d.ts +43 -0
  149. package/dist/lib/json-output.d.ts.map +1 -0
  150. package/dist/lib/json-output.js +34 -0
  151. package/dist/lib/json-output.js.map +1 -0
  152. package/dist/lib/output-paths.d.ts +6 -0
  153. package/dist/lib/output-paths.d.ts.map +1 -0
  154. package/dist/lib/output-paths.js +5 -0
  155. package/dist/lib/output-paths.js.map +1 -0
  156. package/dist/lib/platform-client.d.ts +1 -1
  157. package/dist/lib/platform-client.d.ts.map +1 -1
  158. package/dist/lib/repository-validator.d.ts +57 -0
  159. package/dist/lib/repository-validator.d.ts.map +1 -0
  160. package/dist/lib/repository-validator.js +225 -0
  161. package/dist/lib/repository-validator.js.map +1 -0
  162. package/dist/lib/repository-validator.test.d.ts +5 -0
  163. package/dist/lib/repository-validator.test.d.ts.map +1 -0
  164. package/dist/lib/repository-validator.test.js +341 -0
  165. package/dist/lib/repository-validator.test.js.map +1 -0
  166. package/dist/lib/review-core.d.ts +66 -0
  167. package/dist/lib/review-core.d.ts.map +1 -0
  168. package/dist/lib/review-core.js +449 -0
  169. package/dist/lib/review-core.js.map +1 -0
  170. package/dist/lib/review-core.test.d.ts +2 -0
  171. package/dist/lib/review-core.test.d.ts.map +1 -0
  172. package/dist/lib/review-core.test.js +552 -0
  173. package/dist/lib/review-core.test.js.map +1 -0
  174. package/dist/lib/review-orchestrator.d.ts +27 -10
  175. package/dist/lib/review-orchestrator.d.ts.map +1 -1
  176. package/dist/lib/review-orchestrator.js +51 -110
  177. package/dist/lib/review-orchestrator.js.map +1 -1
  178. package/dist/lib/review-orchestrator.test.d.ts +2 -0
  179. package/dist/lib/review-orchestrator.test.d.ts.map +1 -0
  180. package/dist/lib/review-orchestrator.test.js +413 -0
  181. package/dist/lib/review-orchestrator.test.js.map +1 -0
  182. package/dist/lib/review-output-path.test.d.ts +2 -0
  183. package/dist/lib/review-output-path.test.d.ts.map +1 -0
  184. package/dist/lib/review-output-path.test.js +83 -0
  185. package/dist/lib/review-output-path.test.js.map +1 -0
  186. package/dist/lib/review-parser.d.ts +2 -0
  187. package/dist/lib/review-parser.d.ts.map +1 -0
  188. package/dist/lib/review-parser.js +100 -0
  189. package/dist/lib/review-parser.js.map +1 -0
  190. package/dist/lib/unified-review-executor.d.ts +21 -4
  191. package/dist/lib/unified-review-executor.d.ts.map +1 -1
  192. package/dist/lib/unified-review-executor.js +84 -151
  193. package/dist/lib/unified-review-executor.js.map +1 -1
  194. package/dist/lib/unified-review-executor.test.d.ts +5 -0
  195. package/dist/lib/unified-review-executor.test.d.ts.map +1 -0
  196. package/dist/lib/unified-review-executor.test.js +350 -0
  197. package/dist/lib/unified-review-executor.test.js.map +1 -0
  198. package/dist/lib/write-json-output.d.ts +13 -0
  199. package/dist/lib/write-json-output.d.ts.map +1 -0
  200. package/dist/lib/write-json-output.js +37 -0
  201. package/dist/lib/write-json-output.js.map +1 -0
  202. package/dist/opencode/agent-loader.d.ts +3 -4
  203. package/dist/opencode/agent-loader.d.ts.map +1 -1
  204. package/dist/opencode/agent-loader.js +48 -34
  205. package/dist/opencode/agent-loader.js.map +1 -1
  206. package/dist/opencode/agent-skill-overlay.d.ts +11 -0
  207. package/dist/opencode/agent-skill-overlay.d.ts.map +1 -0
  208. package/dist/opencode/agent-skill-overlay.js +164 -0
  209. package/dist/opencode/agent-skill-overlay.js.map +1 -0
  210. package/dist/opencode/client.d.ts +11 -3
  211. package/dist/opencode/client.d.ts.map +1 -1
  212. package/dist/opencode/client.js +237 -71
  213. package/dist/opencode/client.js.map +1 -1
  214. package/dist/opencode/client.test.d.ts +2 -0
  215. package/dist/opencode/client.test.d.ts.map +1 -0
  216. package/dist/opencode/client.test.js +317 -0
  217. package/dist/opencode/client.test.js.map +1 -0
  218. package/dist/opencode/opencode-paths.d.ts +2 -0
  219. package/dist/opencode/opencode-paths.d.ts.map +1 -0
  220. package/dist/opencode/opencode-paths.js +7 -0
  221. package/dist/opencode/opencode-paths.js.map +1 -0
  222. package/dist/opencode/skill-loader.d.ts +6 -0
  223. package/dist/opencode/skill-loader.d.ts.map +1 -0
  224. package/dist/opencode/skill-loader.js +36 -0
  225. package/dist/opencode/skill-loader.js.map +1 -0
  226. package/package.json +7 -7
  227. package/.opencode/agent/github-reviewer.md +0 -77
  228. package/.opencode/agent/gitlab-reviewer.md +0 -77
  229. package/.opencode/agent/local-reviewer.md +0 -63
@@ -0,0 +1,618 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { createIssueFingerprint, extractCommentId, extractIssueFingerprints, filterCriticalAndHigh, filterDuplicateIssues, findExistingSummaryComment, collectExistingFingerprints, prepareIssuesForPosting, BOT_COMMENT_ID, } from './comment-manager.js';
3
+ describe('comment-manager', () => {
4
+ describe('createIssueFingerprint', () => {
5
+ it('should create fingerprint with line number', () => {
6
+ const issue = {
7
+ category: 'SECURITY',
8
+ severity: 'HIGH',
9
+ title: 'SQL Injection',
10
+ file: 'src/db.ts',
11
+ line: 42,
12
+ problem: 'Unsafe query',
13
+ solution: 'Use parameterized queries',
14
+ agent: 'security',
15
+ };
16
+ const fingerprint = createIssueFingerprint(issue);
17
+ expect(fingerprint).toBe('src/db.ts:42:SECURITY:SQL Injection');
18
+ });
19
+ it('should create fingerprint without line number', () => {
20
+ const issue = {
21
+ category: 'QUALITY',
22
+ severity: 'MEDIUM',
23
+ title: 'Code smell',
24
+ file: 'src/app.ts',
25
+ problem: 'Complex function',
26
+ solution: 'Refactor',
27
+ agent: 'quality',
28
+ };
29
+ const fingerprint = createIssueFingerprint(issue);
30
+ expect(fingerprint).toBe('src/app.ts:general:QUALITY:Code smell');
31
+ });
32
+ it('should create fingerprint with line 0 (treated as general)', () => {
33
+ const issue = {
34
+ category: 'STYLE',
35
+ severity: 'LOW',
36
+ title: 'Missing import',
37
+ file: 'src/utils.ts',
38
+ line: 0,
39
+ problem: 'Missing import',
40
+ solution: 'Add import',
41
+ agent: 'style',
42
+ };
43
+ const fingerprint = createIssueFingerprint(issue);
44
+ expect(fingerprint).toBe('src/utils.ts:general:STYLE:Missing import');
45
+ });
46
+ it('should create unique fingerprints for different issues', () => {
47
+ const issue1 = {
48
+ category: 'SECURITY',
49
+ severity: 'HIGH',
50
+ title: 'Issue 1',
51
+ file: 'file1.ts',
52
+ line: 10,
53
+ problem: 'Problem',
54
+ solution: 'Solution',
55
+ agent: 'security',
56
+ };
57
+ const issue2 = {
58
+ category: 'SECURITY',
59
+ severity: 'HIGH',
60
+ title: 'Issue 2',
61
+ file: 'file1.ts',
62
+ line: 10,
63
+ problem: 'Problem',
64
+ solution: 'Solution',
65
+ agent: 'security',
66
+ };
67
+ const fp1 = createIssueFingerprint(issue1);
68
+ const fp2 = createIssueFingerprint(issue2);
69
+ expect(fp1).not.toBe(fp2);
70
+ });
71
+ });
72
+ describe('extractCommentId', () => {
73
+ it('should extract comment ID from body', () => {
74
+ const body = 'Some text\n<!-- drs-comment-id: drs-review-summary -->\nMore text';
75
+ const id = extractCommentId(body);
76
+ expect(id).toBe('drs-review-summary');
77
+ });
78
+ it('should return null if no comment ID found', () => {
79
+ const body = 'Just some regular text without markers';
80
+ const id = extractCommentId(body);
81
+ expect(id).toBeNull();
82
+ });
83
+ it('should extract custom comment ID', () => {
84
+ const body = '<!-- drs-comment-id: custom-id-123 -->';
85
+ const id = extractCommentId(body);
86
+ expect(id).toBe('custom-id-123');
87
+ });
88
+ it('should handle multiple comment IDs and return first', () => {
89
+ const body = '<!-- drs-comment-id: first-id -->\n<!-- drs-comment-id: second-id -->';
90
+ const id = extractCommentId(body);
91
+ expect(id).toBe('first-id');
92
+ });
93
+ });
94
+ describe('extractIssueFingerprints', () => {
95
+ it('should extract single fingerprint', () => {
96
+ const body = 'Issue here\n<!-- issue-fp: src/app.ts:10:SECURITY:SQL Injection -->';
97
+ const fingerprints = extractIssueFingerprints(body);
98
+ expect(fingerprints.size).toBe(1);
99
+ expect(fingerprints.has('src/app.ts:10:SECURITY:SQL Injection')).toBe(true);
100
+ });
101
+ it('should extract multiple fingerprints', () => {
102
+ const body = `
103
+ <!-- issue-fp: src/app.ts:10:SECURITY:Issue 1 -->
104
+ Some text
105
+ <!-- issue-fp: src/db.ts:20:QUALITY:Issue 2 -->
106
+ More text
107
+ <!-- issue-fp: src/utils.ts:general:STYLE:Issue 3 -->
108
+ `;
109
+ const fingerprints = extractIssueFingerprints(body);
110
+ expect(fingerprints.size).toBe(3);
111
+ expect(fingerprints.has('src/app.ts:10:SECURITY:Issue 1')).toBe(true);
112
+ expect(fingerprints.has('src/db.ts:20:QUALITY:Issue 2')).toBe(true);
113
+ expect(fingerprints.has('src/utils.ts:general:STYLE:Issue 3')).toBe(true);
114
+ });
115
+ it('should return empty set if no fingerprints found', () => {
116
+ const body = 'Just regular text with no fingerprints';
117
+ const fingerprints = extractIssueFingerprints(body);
118
+ expect(fingerprints.size).toBe(0);
119
+ });
120
+ it('should handle duplicate fingerprints in same comment', () => {
121
+ const body = `
122
+ <!-- issue-fp: src/app.ts:10:SECURITY:Issue -->
123
+ <!-- issue-fp: src/app.ts:10:SECURITY:Issue -->
124
+ `;
125
+ const fingerprints = extractIssueFingerprints(body);
126
+ expect(fingerprints.size).toBe(1);
127
+ });
128
+ });
129
+ describe('filterCriticalAndHigh', () => {
130
+ it('should filter only CRITICAL issues', () => {
131
+ const issues = [
132
+ {
133
+ category: 'SECURITY',
134
+ severity: 'CRITICAL',
135
+ title: 'Critical issue',
136
+ file: 'file.ts',
137
+ line: 1,
138
+ problem: 'Problem',
139
+ solution: 'Solution',
140
+ agent: 'security',
141
+ },
142
+ {
143
+ category: 'QUALITY',
144
+ severity: 'MEDIUM',
145
+ title: 'Medium issue',
146
+ file: 'file.ts',
147
+ line: 2,
148
+ problem: 'Problem',
149
+ solution: 'Solution',
150
+ agent: 'quality',
151
+ },
152
+ ];
153
+ const filtered = filterCriticalAndHigh(issues);
154
+ expect(filtered).toHaveLength(1);
155
+ expect(filtered[0].severity).toBe('CRITICAL');
156
+ });
157
+ it('should filter only HIGH issues', () => {
158
+ const issues = [
159
+ {
160
+ category: 'SECURITY',
161
+ severity: 'HIGH',
162
+ title: 'High issue',
163
+ file: 'file.ts',
164
+ line: 1,
165
+ problem: 'Problem',
166
+ solution: 'Solution',
167
+ agent: 'security',
168
+ },
169
+ {
170
+ category: 'QUALITY',
171
+ severity: 'LOW',
172
+ title: 'Low issue',
173
+ file: 'file.ts',
174
+ line: 2,
175
+ problem: 'Problem',
176
+ solution: 'Solution',
177
+ agent: 'quality',
178
+ },
179
+ ];
180
+ const filtered = filterCriticalAndHigh(issues);
181
+ expect(filtered).toHaveLength(1);
182
+ expect(filtered[0].severity).toBe('HIGH');
183
+ });
184
+ it('should filter both CRITICAL and HIGH issues', () => {
185
+ const issues = [
186
+ {
187
+ category: 'SECURITY',
188
+ severity: 'CRITICAL',
189
+ title: 'Critical',
190
+ file: 'file.ts',
191
+ line: 1,
192
+ problem: 'Problem',
193
+ solution: 'Solution',
194
+ agent: 'security',
195
+ },
196
+ {
197
+ category: 'SECURITY',
198
+ severity: 'HIGH',
199
+ title: 'High',
200
+ file: 'file.ts',
201
+ line: 2,
202
+ problem: 'Problem',
203
+ solution: 'Solution',
204
+ agent: 'security',
205
+ },
206
+ {
207
+ category: 'QUALITY',
208
+ severity: 'MEDIUM',
209
+ title: 'Medium',
210
+ file: 'file.ts',
211
+ line: 3,
212
+ problem: 'Problem',
213
+ solution: 'Solution',
214
+ agent: 'quality',
215
+ },
216
+ {
217
+ category: 'STYLE',
218
+ severity: 'LOW',
219
+ title: 'Low',
220
+ file: 'file.ts',
221
+ line: 4,
222
+ problem: 'Problem',
223
+ solution: 'Solution',
224
+ agent: 'style',
225
+ },
226
+ ];
227
+ const filtered = filterCriticalAndHigh(issues);
228
+ expect(filtered).toHaveLength(2);
229
+ expect(filtered.every((i) => i.severity === 'CRITICAL' || i.severity === 'HIGH')).toBe(true);
230
+ });
231
+ it('should return empty array if no critical/high issues', () => {
232
+ const issues = [
233
+ {
234
+ category: 'QUALITY',
235
+ severity: 'MEDIUM',
236
+ title: 'Medium',
237
+ file: 'file.ts',
238
+ line: 1,
239
+ problem: 'Problem',
240
+ solution: 'Solution',
241
+ agent: 'quality',
242
+ },
243
+ {
244
+ category: 'STYLE',
245
+ severity: 'LOW',
246
+ title: 'Low',
247
+ file: 'file.ts',
248
+ line: 2,
249
+ problem: 'Problem',
250
+ solution: 'Solution',
251
+ agent: 'style',
252
+ },
253
+ ];
254
+ const filtered = filterCriticalAndHigh(issues);
255
+ expect(filtered).toHaveLength(0);
256
+ });
257
+ });
258
+ describe('filterDuplicateIssues', () => {
259
+ it('should filter out duplicate issues', () => {
260
+ const issues = [
261
+ {
262
+ category: 'SECURITY',
263
+ severity: 'HIGH',
264
+ title: 'SQL Injection',
265
+ file: 'src/db.ts',
266
+ line: 42,
267
+ problem: 'Problem',
268
+ solution: 'Solution',
269
+ agent: 'security',
270
+ },
271
+ {
272
+ category: 'QUALITY',
273
+ severity: 'MEDIUM',
274
+ title: 'Code smell',
275
+ file: 'src/app.ts',
276
+ line: 10,
277
+ problem: 'Problem',
278
+ solution: 'Solution',
279
+ agent: 'quality',
280
+ },
281
+ ];
282
+ const existingFingerprints = new Set(['src/db.ts:42:SECURITY:SQL Injection']);
283
+ const filtered = filterDuplicateIssues(issues, existingFingerprints);
284
+ expect(filtered).toHaveLength(1);
285
+ expect(filtered[0].title).toBe('Code smell');
286
+ });
287
+ it('should return all issues if no duplicates', () => {
288
+ const issues = [
289
+ {
290
+ category: 'SECURITY',
291
+ severity: 'HIGH',
292
+ title: 'Issue 1',
293
+ file: 'file1.ts',
294
+ line: 1,
295
+ problem: 'Problem',
296
+ solution: 'Solution',
297
+ agent: 'security',
298
+ },
299
+ {
300
+ category: 'QUALITY',
301
+ severity: 'MEDIUM',
302
+ title: 'Issue 2',
303
+ file: 'file2.ts',
304
+ line: 2,
305
+ problem: 'Problem',
306
+ solution: 'Solution',
307
+ agent: 'quality',
308
+ },
309
+ ];
310
+ const existingFingerprints = new Set();
311
+ const filtered = filterDuplicateIssues(issues, existingFingerprints);
312
+ expect(filtered).toHaveLength(2);
313
+ });
314
+ it('should filter all issues if all are duplicates', () => {
315
+ const issues = [
316
+ {
317
+ category: 'SECURITY',
318
+ severity: 'HIGH',
319
+ title: 'Issue 1',
320
+ file: 'file1.ts',
321
+ line: 1,
322
+ problem: 'Problem',
323
+ solution: 'Solution',
324
+ agent: 'security',
325
+ },
326
+ {
327
+ category: 'QUALITY',
328
+ severity: 'MEDIUM',
329
+ title: 'Issue 2',
330
+ file: 'file2.ts',
331
+ line: 2,
332
+ problem: 'Problem',
333
+ solution: 'Solution',
334
+ agent: 'quality',
335
+ },
336
+ ];
337
+ const existingFingerprints = new Set([
338
+ 'file1.ts:1:SECURITY:Issue 1',
339
+ 'file2.ts:2:QUALITY:Issue 2',
340
+ ]);
341
+ const filtered = filterDuplicateIssues(issues, existingFingerprints);
342
+ expect(filtered).toHaveLength(0);
343
+ });
344
+ });
345
+ describe('findExistingSummaryComment', () => {
346
+ it('should find summary comment with bot marker', () => {
347
+ const comments = [
348
+ { id: 1, body: 'Regular comment' },
349
+ {
350
+ id: 2,
351
+ body: `Review Summary\n<!-- drs-comment-id: ${BOT_COMMENT_ID} -->\nSummary text`,
352
+ },
353
+ { id: 3, body: 'Another comment' },
354
+ ];
355
+ const found = findExistingSummaryComment(comments);
356
+ expect(found).not.toBeNull();
357
+ expect(found?.id).toBe(2);
358
+ });
359
+ it('should return null if no summary comment exists', () => {
360
+ const comments = [
361
+ { id: 1, body: 'Regular comment 1' },
362
+ { id: 2, body: 'Regular comment 2' },
363
+ ];
364
+ const found = findExistingSummaryComment(comments);
365
+ expect(found).toBeNull();
366
+ });
367
+ it('should return first summary comment if multiple exist', () => {
368
+ const comments = [
369
+ {
370
+ id: 1,
371
+ body: `Summary 1\n<!-- drs-comment-id: ${BOT_COMMENT_ID} -->`,
372
+ },
373
+ {
374
+ id: 2,
375
+ body: `Summary 2\n<!-- drs-comment-id: ${BOT_COMMENT_ID} -->`,
376
+ },
377
+ ];
378
+ const found = findExistingSummaryComment(comments);
379
+ expect(found?.id).toBe(1);
380
+ });
381
+ it('should handle empty comments array', () => {
382
+ const comments = [];
383
+ const found = findExistingSummaryComment(comments);
384
+ expect(found).toBeNull();
385
+ });
386
+ });
387
+ describe('collectExistingFingerprints', () => {
388
+ it('should collect fingerprints from multiple comments', () => {
389
+ const comments = [
390
+ {
391
+ id: 1,
392
+ body: `Issue 1\n<!-- issue-fp: file1.ts:10:SECURITY:Issue 1 -->`,
393
+ },
394
+ {
395
+ id: 2,
396
+ body: `Issue 2\n<!-- issue-fp: file2.ts:20:QUALITY:Issue 2 -->`,
397
+ },
398
+ ];
399
+ const fingerprints = collectExistingFingerprints(comments);
400
+ expect(fingerprints.size).toBe(2);
401
+ expect(fingerprints.has('file1.ts:10:SECURITY:Issue 1')).toBe(true);
402
+ expect(fingerprints.has('file2.ts:20:QUALITY:Issue 2')).toBe(true);
403
+ });
404
+ it('should collect multiple fingerprints from single comment', () => {
405
+ const comments = [
406
+ {
407
+ id: 1,
408
+ body: `
409
+ <!-- issue-fp: file1.ts:10:SECURITY:Issue 1 -->
410
+ <!-- issue-fp: file2.ts:20:QUALITY:Issue 2 -->
411
+ <!-- issue-fp: file3.ts:30:STYLE:Issue 3 -->
412
+ `,
413
+ },
414
+ ];
415
+ const fingerprints = collectExistingFingerprints(comments);
416
+ expect(fingerprints.size).toBe(3);
417
+ });
418
+ it('should deduplicate fingerprints across comments', () => {
419
+ const comments = [
420
+ {
421
+ id: 1,
422
+ body: `<!-- issue-fp: file1.ts:10:SECURITY:Issue -->`,
423
+ },
424
+ {
425
+ id: 2,
426
+ body: `<!-- issue-fp: file1.ts:10:SECURITY:Issue -->`,
427
+ },
428
+ ];
429
+ const fingerprints = collectExistingFingerprints(comments);
430
+ expect(fingerprints.size).toBe(1);
431
+ });
432
+ it('should return empty set for comments with no fingerprints', () => {
433
+ const comments = [
434
+ { id: 1, body: 'Regular comment 1' },
435
+ { id: 2, body: 'Regular comment 2' },
436
+ ];
437
+ const fingerprints = collectExistingFingerprints(comments);
438
+ expect(fingerprints.size).toBe(0);
439
+ });
440
+ it('should handle empty comments array', () => {
441
+ const comments = [];
442
+ const fingerprints = collectExistingFingerprints(comments);
443
+ expect(fingerprints.size).toBe(0);
444
+ });
445
+ });
446
+ describe('prepareIssuesForPosting', () => {
447
+ it('should filter and prepare issues correctly', () => {
448
+ const allIssues = [
449
+ {
450
+ category: 'SECURITY',
451
+ severity: 'CRITICAL',
452
+ title: 'New critical issue',
453
+ file: 'file1.ts',
454
+ line: 10,
455
+ problem: 'Problem',
456
+ solution: 'Solution',
457
+ agent: 'security',
458
+ },
459
+ {
460
+ category: 'SECURITY',
461
+ severity: 'HIGH',
462
+ title: 'New high issue',
463
+ file: 'file2.ts',
464
+ line: 20,
465
+ problem: 'Problem',
466
+ solution: 'Solution',
467
+ agent: 'security',
468
+ },
469
+ {
470
+ category: 'QUALITY',
471
+ severity: 'MEDIUM',
472
+ title: 'Medium issue',
473
+ file: 'file3.ts',
474
+ line: 30,
475
+ problem: 'Problem',
476
+ solution: 'Solution',
477
+ agent: 'quality',
478
+ },
479
+ {
480
+ category: 'STYLE',
481
+ severity: 'LOW',
482
+ title: 'Low issue',
483
+ file: 'file4.ts',
484
+ line: 40,
485
+ problem: 'Problem',
486
+ solution: 'Solution',
487
+ agent: 'style',
488
+ },
489
+ ];
490
+ const existingComments = [];
491
+ const result = prepareIssuesForPosting(allIssues, existingComments);
492
+ expect(result.inlineIssues).toHaveLength(2);
493
+ expect(result.deduplicatedCount).toBe(0);
494
+ expect(result.nonInlineCount).toBe(2); // MEDIUM + LOW
495
+ });
496
+ it('should deduplicate existing issues', () => {
497
+ const allIssues = [
498
+ {
499
+ category: 'SECURITY',
500
+ severity: 'CRITICAL',
501
+ title: 'Existing issue',
502
+ file: 'file1.ts',
503
+ line: 10,
504
+ problem: 'Problem',
505
+ solution: 'Solution',
506
+ agent: 'security',
507
+ },
508
+ {
509
+ category: 'SECURITY',
510
+ severity: 'HIGH',
511
+ title: 'New issue',
512
+ file: 'file2.ts',
513
+ line: 20,
514
+ problem: 'Problem',
515
+ solution: 'Solution',
516
+ agent: 'security',
517
+ },
518
+ ];
519
+ const existingComments = [
520
+ {
521
+ id: 1,
522
+ body: '<!-- issue-fp: file1.ts:10:SECURITY:Existing issue -->',
523
+ },
524
+ ];
525
+ const result = prepareIssuesForPosting(allIssues, existingComments);
526
+ expect(result.inlineIssues).toHaveLength(1);
527
+ expect(result.inlineIssues[0].title).toBe('New issue');
528
+ expect(result.deduplicatedCount).toBe(1);
529
+ });
530
+ it('should filter out issues without line numbers', () => {
531
+ const allIssues = [
532
+ {
533
+ category: 'SECURITY',
534
+ severity: 'CRITICAL',
535
+ title: 'With line',
536
+ file: 'file1.ts',
537
+ line: 10,
538
+ problem: 'Problem',
539
+ solution: 'Solution',
540
+ agent: 'security',
541
+ },
542
+ {
543
+ category: 'SECURITY',
544
+ severity: 'HIGH',
545
+ title: 'Without line',
546
+ file: 'file2.ts',
547
+ problem: 'Problem',
548
+ solution: 'Solution',
549
+ agent: 'security',
550
+ },
551
+ ];
552
+ const existingComments = [];
553
+ const result = prepareIssuesForPosting(allIssues, existingComments);
554
+ expect(result.inlineIssues).toHaveLength(1);
555
+ expect(result.inlineIssues[0].title).toBe('With line');
556
+ });
557
+ it('should apply custom valid lines checker', () => {
558
+ const allIssues = [
559
+ {
560
+ category: 'SECURITY',
561
+ severity: 'CRITICAL',
562
+ title: 'Valid line',
563
+ file: 'file1.ts',
564
+ line: 10,
565
+ problem: 'Problem',
566
+ solution: 'Solution',
567
+ agent: 'security',
568
+ },
569
+ {
570
+ category: 'SECURITY',
571
+ severity: 'HIGH',
572
+ title: 'Invalid line',
573
+ file: 'file2.ts',
574
+ line: 999,
575
+ problem: 'Problem',
576
+ solution: 'Solution',
577
+ agent: 'security',
578
+ },
579
+ ];
580
+ const existingComments = [];
581
+ // Only allow lines <= 100
582
+ const validLinesChecker = (issue) => {
583
+ return issue.line !== undefined && issue.line <= 100;
584
+ };
585
+ const result = prepareIssuesForPosting(allIssues, existingComments, validLinesChecker);
586
+ expect(result.inlineIssues).toHaveLength(1);
587
+ expect(result.inlineIssues[0].title).toBe('Valid line');
588
+ });
589
+ it('should handle all issues being filtered out', () => {
590
+ const allIssues = [
591
+ {
592
+ category: 'QUALITY',
593
+ severity: 'MEDIUM',
594
+ title: 'Medium issue',
595
+ file: 'file1.ts',
596
+ line: 10,
597
+ problem: 'Problem',
598
+ solution: 'Solution',
599
+ agent: 'quality',
600
+ },
601
+ ];
602
+ const existingComments = [];
603
+ const result = prepareIssuesForPosting(allIssues, existingComments);
604
+ expect(result.inlineIssues).toHaveLength(0);
605
+ expect(result.nonInlineCount).toBe(1);
606
+ expect(result.deduplicatedCount).toBe(0);
607
+ });
608
+ it('should handle empty issues array', () => {
609
+ const allIssues = [];
610
+ const existingComments = [];
611
+ const result = prepareIssuesForPosting(allIssues, existingComments);
612
+ expect(result.inlineIssues).toHaveLength(0);
613
+ expect(result.nonInlineCount).toBe(0);
614
+ expect(result.deduplicatedCount).toBe(0);
615
+ });
616
+ });
617
+ });
618
+ //# sourceMappingURL=comment-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment-manager.test.js","sourceRoot":"","sources":["../../src/lib/comment-manager.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,uBAAuB,EACvB,cAAc,GAEf,MAAM,sBAAsB,CAAC;AAG9B,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,KAAK,GAAgB;gBACzB,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,eAAe;gBACtB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,EAAE;gBACR,OAAO,EAAE,cAAc;gBACvB,QAAQ,EAAE,2BAA2B;gBACrC,KAAK,EAAE,UAAU;aAClB,CAAC;YAEF,MAAM,WAAW,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,KAAK,GAAgB;gBACzB,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,kBAAkB;gBAC3B,QAAQ,EAAE,UAAU;gBACpB,KAAK,EAAE,SAAS;aACjB,CAAC;YAEF,MAAM,WAAW,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,MAAM,KAAK,GAAgB;gBACzB,QAAQ,EAAE,OAAO;gBACjB,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,gBAAgB;gBACvB,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,gBAAgB;gBACzB,QAAQ,EAAE,YAAY;gBACtB,KAAK,EAAE,OAAO;aACf,CAAC;YAEF,MAAM,WAAW,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;YAChE,MAAM,MAAM,GAAgB;gBAC1B,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,EAAE;gBACR,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,UAAU;gBACpB,KAAK,EAAE,UAAU;aAClB,CAAC;YAEF,MAAM,MAAM,GAAgB;gBAC1B,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,EAAE;gBACR,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,UAAU;gBACpB,KAAK,EAAE,UAAU;aAClB,CAAC;YAEF,MAAM,GAAG,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,GAAG,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,IAAI,GAAG,mEAAmE,CAAC;YACjF,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,IAAI,GAAG,wCAAwC,CAAC;YACtD,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,IAAI,GAAG,wCAAwC,CAAC;YACtD,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,MAAM,IAAI,GAAG,uEAAuE,CAAC;YACrF,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,IAAI,GAAG,qEAAqE,CAAC;YACnF,MAAM,YAAY,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;YACpD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,IAAI,GAAG;;;;;;OAMZ,CAAC;YACF,MAAM,YAAY,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;YACpD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,IAAI,GAAG,wCAAwC,CAAC;YACtD,MAAM,YAAY,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;YACpD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC9D,MAAM,IAAI,GAAG;;;OAGZ,CAAC;YACF,MAAM,YAAY,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;YACpD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,MAAM,GAAkB;gBAC5B;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,gBAAgB;oBACvB,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,cAAc;oBACrB,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,SAAS;iBACjB;aACF,CAAC;YAEF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,MAAM,GAAkB;gBAC5B;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,YAAY;oBACnB,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,KAAK;oBACf,KAAK,EAAE,WAAW;oBAClB,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,SAAS;iBACjB;aACF,CAAC;YAEF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,MAAM,GAAkB;gBAC5B;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;oBACjB,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,MAAM;oBACb,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,QAAQ;oBACf,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,SAAS;iBACjB;gBACD;oBACE,QAAQ,EAAE,OAAO;oBACjB,QAAQ,EAAE,KAAK;oBACf,KAAK,EAAE,KAAK;oBACZ,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,OAAO;iBACf;aACF,CAAC;YAEF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/F,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC9D,MAAM,MAAM,GAAkB;gBAC5B;oBACE,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,QAAQ;oBACf,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,SAAS;iBACjB;gBACD;oBACE,QAAQ,EAAE,OAAO;oBACjB,QAAQ,EAAE,KAAK;oBACf,KAAK,EAAE,KAAK;oBACZ,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,OAAO;iBACf;aACF,CAAC;YAEF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,MAAM,GAAkB;gBAC5B;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,eAAe;oBACtB,IAAI,EAAE,WAAW;oBACjB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,YAAY;oBACnB,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,SAAS;iBACjB;aACF,CAAC;YAEF,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC;YAC9E,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAErE,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,MAAM,GAAkB;gBAC5B;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,SAAS;oBAChB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,SAAS;oBAChB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,SAAS;iBACjB;aACF,CAAC;YAEF,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAU,CAAC;YAC/C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAErE,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,MAAM,GAAkB;gBAC5B;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,SAAS;oBAChB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,SAAS;oBAChB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,SAAS;iBACjB;aACF,CAAC;YAEF,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;gBACnC,6BAA6B;gBAC7B,4BAA4B;aAC7B,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAErE,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,QAAQ,GAAsB;gBAClC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE;gBAClC;oBACE,EAAE,EAAE,CAAC;oBACL,IAAI,EAAE,wCAAwC,cAAc,oBAAoB;iBACjF;gBACD,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE;aACnC,CAAC;YAEF,MAAM,KAAK,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,QAAQ,GAAsB;gBAClC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE;gBACpC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE;aACrC,CAAC;YAEF,MAAM,KAAK,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;YAC/D,MAAM,QAAQ,GAAsB;gBAClC;oBACE,EAAE,EAAE,CAAC;oBACL,IAAI,EAAE,mCAAmC,cAAc,MAAM;iBAC9D;gBACD;oBACE,EAAE,EAAE,CAAC;oBACL,IAAI,EAAE,mCAAmC,cAAc,MAAM;iBAC9D;aACF,CAAC;YAEF,MAAM,KAAK,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,QAAQ,GAAsB,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC3C,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,QAAQ,GAAsB;gBAClC;oBACE,EAAE,EAAE,CAAC;oBACL,IAAI,EAAE,0DAA0D;iBACjE;gBACD;oBACE,EAAE,EAAE,CAAC;oBACL,IAAI,EAAE,yDAAyD;iBAChE;aACF,CAAC;YAEF,MAAM,YAAY,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YAC3D,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,MAAM,QAAQ,GAAsB;gBAClC;oBACE,EAAE,EAAE,CAAC;oBACL,IAAI,EAAE;;;;WAIL;iBACF;aACF,CAAC;YAEF,MAAM,YAAY,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YAC3D,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,QAAQ,GAAsB;gBAClC;oBACE,EAAE,EAAE,CAAC;oBACL,IAAI,EAAE,+CAA+C;iBACtD;gBACD;oBACE,EAAE,EAAE,CAAC;oBACL,IAAI,EAAE,+CAA+C;iBACtD;aACF,CAAC;YAEF,MAAM,YAAY,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YAC3D,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,MAAM,QAAQ,GAAsB;gBAClC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE;gBACpC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE;aACrC,CAAC;YAEF,MAAM,YAAY,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YAC3D,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,QAAQ,GAAsB,EAAE,CAAC;YACvC,MAAM,YAAY,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YAC3D,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,SAAS,GAAkB;gBAC/B;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,oBAAoB;oBAC3B,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,gBAAgB;oBACvB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,cAAc;oBACrB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,SAAS;iBACjB;gBACD;oBACE,QAAQ,EAAE,OAAO;oBACjB,QAAQ,EAAE,KAAK;oBACf,KAAK,EAAE,WAAW;oBAClB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,OAAO;iBACf;aACF,CAAC;YAEF,MAAM,gBAAgB,GAAsB,EAAE,CAAC;YAE/C,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe;QACxD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,SAAS,GAAkB;gBAC/B;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,gBAAgB;oBACvB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,WAAW;oBAClB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;aACF,CAAC;YAEF,MAAM,gBAAgB,GAAsB;gBAC1C;oBACE,EAAE,EAAE,CAAC;oBACL,IAAI,EAAE,wDAAwD;iBAC/D;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACvD,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,SAAS,GAAkB;gBAC/B;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,WAAW;oBAClB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,cAAc;oBACrB,IAAI,EAAE,UAAU;oBAChB,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;aACF,CAAC;YAEF,MAAM,gBAAgB,GAAsB,EAAE,CAAC;YAE/C,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,SAAS,GAAkB;gBAC/B;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,YAAY;oBACnB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;gBACD;oBACE,QAAQ,EAAE,UAAU;oBACpB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,cAAc;oBACrB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,GAAG;oBACT,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,UAAU;iBAClB;aACF,CAAC;YAEF,MAAM,gBAAgB,GAAsB,EAAE,CAAC;YAE/C,0BAA0B;YAC1B,MAAM,iBAAiB,GAAG,CAAC,KAAkB,EAAE,EAAE;gBAC/C,OAAO,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC;YACvD,CAAC,CAAC;YAEF,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,EAAE,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;YAEvF,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,SAAS,GAAkB;gBAC/B;oBACE,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,cAAc;oBACrB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,SAAS;iBACjB;aACF,CAAC;YAEF,MAAM,gBAAgB,GAAsB,EAAE,CAAC;YAE/C,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,SAAS,GAAkB,EAAE,CAAC;YACpC,MAAM,gBAAgB,GAAsB,EAAE,CAAC;YAE/C,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Comment posting utilities for PR/MR reviews
3
+ *
4
+ * This module handles posting review comments to GitHub and GitLab platforms,
5
+ * including summary comments and inline code comments.
6
+ */
7
+ import type { calculateSummary } from './comment-formatter.js';
8
+ import { type ReviewIssue } from './comment-formatter.js';
9
+ import type { ChangeSummary } from './change-summary.js';
10
+ import type { PlatformClient, LineValidator, InlineCommentPosition } from './platform-client.js';
11
+ /**
12
+ * Post review comments to a PR/MR
13
+ *
14
+ * This function:
15
+ * 1. Fetches existing comments to prevent duplicates
16
+ * 2. Posts or updates a summary comment
17
+ * 3. Posts inline comments for CRITICAL/HIGH severity issues
18
+ * 4. Adds an "ai-reviewed" label
19
+ */
20
+ export declare function postReviewComments(platformClient: PlatformClient, projectId: string, prNumber: number, summary: ReturnType<typeof calculateSummary>, issues: ReviewIssue[], changeSummary: ChangeSummary | undefined, platformData: unknown, lineValidator?: LineValidator, createInlinePosition?: (issue: ReviewIssue, platformData: unknown) => InlineCommentPosition): Promise<void>;
21
+ //# sourceMappingURL=comment-poster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment-poster.d.ts","sourceRoot":"","sources":["../../src/lib/comment-poster.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAA4C,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACpG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQzD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAEjG;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,MAAM,EAAE,WAAW,EAAE,EACrB,aAAa,EAAE,aAAa,GAAG,SAAS,EACxC,YAAY,EAAE,OAAO,EACrB,aAAa,CAAC,EAAE,aAAa,EAC7B,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,KAAK,qBAAqB,GAC1F,OAAO,CAAC,IAAI,CAAC,CAmEf"}