@vibe-validate/cli 0.17.6-rc.2 → 0.18.0-rc.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 (89) hide show
  1. package/dist/bin/vibe-validate +4 -0
  2. package/dist/bin/vibe-validate.js +4 -0
  3. package/dist/bin/vibe-validate.js.map +1 -1
  4. package/dist/bin/vv +4 -0
  5. package/dist/commands/cleanup.d.ts.map +1 -1
  6. package/dist/commands/cleanup.js +5 -2
  7. package/dist/commands/cleanup.js.map +1 -1
  8. package/dist/commands/config.d.ts.map +1 -1
  9. package/dist/commands/config.js +3 -1
  10. package/dist/commands/config.js.map +1 -1
  11. package/dist/commands/create-extractor.d.ts.map +1 -1
  12. package/dist/commands/create-extractor.js +3 -1
  13. package/dist/commands/create-extractor.js.map +1 -1
  14. package/dist/commands/doctor.d.ts.map +1 -1
  15. package/dist/commands/doctor.js +11 -5
  16. package/dist/commands/doctor.js.map +1 -1
  17. package/dist/commands/generate-workflow.d.ts.map +1 -1
  18. package/dist/commands/generate-workflow.js +6 -2
  19. package/dist/commands/generate-workflow.js.map +1 -1
  20. package/dist/commands/history.d.ts.map +1 -1
  21. package/dist/commands/history.js +23 -13
  22. package/dist/commands/history.js.map +1 -1
  23. package/dist/commands/init.d.ts.map +1 -1
  24. package/dist/commands/init.js +3 -1
  25. package/dist/commands/init.js.map +1 -1
  26. package/dist/commands/pre-commit.d.ts.map +1 -1
  27. package/dist/commands/pre-commit.js +5 -2
  28. package/dist/commands/pre-commit.js.map +1 -1
  29. package/dist/commands/run.d.ts.map +1 -1
  30. package/dist/commands/run.js +12 -10
  31. package/dist/commands/run.js.map +1 -1
  32. package/dist/commands/state.d.ts.map +1 -1
  33. package/dist/commands/state.js +15 -10
  34. package/dist/commands/state.js.map +1 -1
  35. package/dist/commands/sync-check.js +5 -5
  36. package/dist/commands/sync-check.js.map +1 -1
  37. package/dist/commands/watch-pr.d.ts +16 -0
  38. package/dist/commands/watch-pr.d.ts.map +1 -1
  39. package/dist/commands/watch-pr.js +572 -318
  40. package/dist/commands/watch-pr.js.map +1 -1
  41. package/dist/schemas/watch-pr-result.schema.d.ts +2010 -0
  42. package/dist/schemas/watch-pr-result.schema.d.ts.map +1 -0
  43. package/dist/schemas/watch-pr-result.schema.js +335 -0
  44. package/dist/schemas/watch-pr-result.schema.js.map +1 -0
  45. package/dist/schemas/watch-pr-schema.d.ts +6 -6
  46. package/dist/services/cache-manager.d.ts +113 -0
  47. package/dist/services/cache-manager.d.ts.map +1 -0
  48. package/dist/services/cache-manager.js +211 -0
  49. package/dist/services/cache-manager.js.map +1 -0
  50. package/dist/services/ci-providers/github-actions.d.ts.map +1 -1
  51. package/dist/services/ci-providers/github-actions.js +10 -16
  52. package/dist/services/ci-providers/github-actions.js.map +1 -1
  53. package/dist/services/external-check-extractor.d.ts +66 -0
  54. package/dist/services/external-check-extractor.d.ts.map +1 -0
  55. package/dist/services/external-check-extractor.js +114 -0
  56. package/dist/services/external-check-extractor.js.map +1 -0
  57. package/dist/services/extraction-mode-detector.d.ts +85 -0
  58. package/dist/services/extraction-mode-detector.d.ts.map +1 -0
  59. package/dist/services/extraction-mode-detector.js +200 -0
  60. package/dist/services/extraction-mode-detector.js.map +1 -0
  61. package/dist/services/github-fetcher.d.ts +210 -0
  62. package/dist/services/github-fetcher.d.ts.map +1 -0
  63. package/dist/services/github-fetcher.js +412 -0
  64. package/dist/services/github-fetcher.js.map +1 -0
  65. package/dist/services/history-summary-builder.d.ts +74 -0
  66. package/dist/services/history-summary-builder.d.ts.map +1 -0
  67. package/dist/services/history-summary-builder.js +199 -0
  68. package/dist/services/history-summary-builder.js.map +1 -0
  69. package/dist/services/watch-pr-orchestrator.d.ts +119 -0
  70. package/dist/services/watch-pr-orchestrator.d.ts.map +1 -0
  71. package/dist/services/watch-pr-orchestrator.js +420 -0
  72. package/dist/services/watch-pr-orchestrator.js.map +1 -0
  73. package/dist/utils/command-name.d.ts +21 -0
  74. package/dist/utils/command-name.d.ts.map +1 -0
  75. package/dist/utils/command-name.js +45 -0
  76. package/dist/utils/command-name.js.map +1 -0
  77. package/dist/utils/pid-lock.d.ts.map +1 -1
  78. package/dist/utils/pid-lock.js +3 -3
  79. package/dist/utils/pid-lock.js.map +1 -1
  80. package/dist/utils/secret-scanning.d.ts +1 -1
  81. package/dist/utils/secret-scanning.d.ts.map +1 -1
  82. package/dist/utils/secret-scanning.js +32 -4
  83. package/dist/utils/secret-scanning.js.map +1 -1
  84. package/dist/utils/temp-files.d.ts.map +1 -1
  85. package/dist/utils/temp-files.js +2 -2
  86. package/dist/utils/temp-files.js.map +1 -1
  87. package/dist/utils/validate-workflow.js +7 -7
  88. package/dist/utils/validate-workflow.js.map +1 -1
  89. package/package.json +7 -7
@@ -0,0 +1,412 @@
1
+ /**
2
+ * GitHubFetcher - Fetch PR metadata and check results from GitHub API
3
+ *
4
+ * Uses `gh` CLI to fetch:
5
+ * - Complete PR metadata (title, author, labels, linked issues, etc.)
6
+ * - Check results (GitHub Actions + external status checks)
7
+ * - Run logs from GitHub Actions
8
+ * - File changes from git diff
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ import { fetchPRDetails as ghFetchPRDetails, fetchPRChecks, fetchRunLogs as ghFetchRunLogs, fetchRunDetails as ghFetchRunDetails, getDiffStats, getCommitCount, listWorkflowRuns, } from '@vibe-validate/git';
13
+ /**
14
+ * GitHubFetcher - Fetch PR data from GitHub API via gh CLI
15
+ */
16
+ export class GitHubFetcher {
17
+ owner;
18
+ repo;
19
+ /**
20
+ * Create GitHubFetcher
21
+ *
22
+ * @param owner - Repository owner (optional, defaults to current repo)
23
+ * @param repo - Repository name (optional, defaults to current repo)
24
+ */
25
+ constructor(owner, repo) {
26
+ this.owner = owner;
27
+ this.repo = repo;
28
+ }
29
+ /**
30
+ * Fetch complete PR metadata
31
+ *
32
+ * @param prNumber - PR number
33
+ * @returns PR metadata
34
+ */
35
+ async fetchPRDetails(prNumber) {
36
+ const fields = [
37
+ 'number',
38
+ 'title',
39
+ 'url',
40
+ 'headRefName',
41
+ 'baseRefName',
42
+ 'author',
43
+ 'isDraft',
44
+ 'mergeable',
45
+ 'mergeStateStatus',
46
+ 'labels',
47
+ 'closingIssuesReferences',
48
+ ];
49
+ const data = ghFetchPRDetails(prNumber, this.owner, this.repo, fields);
50
+ // Map GitHub API response to PRMetadata schema
51
+ return {
52
+ number: data.number,
53
+ title: data.title,
54
+ url: data.url,
55
+ branch: data.headRefName,
56
+ base_branch: data.baseRefName,
57
+ author: data.author.login,
58
+ draft: data.isDraft ?? false,
59
+ mergeable: data.mergeable === 'MERGEABLE',
60
+ merge_state_status: this.normalizeMergeStateStatus(data.mergeStateStatus ?? 'UNKNOWN'),
61
+ labels: data.labels?.map((label) => label.name) ?? [],
62
+ linked_issues: this.extractLinkedIssues(data.closingIssuesReferences),
63
+ };
64
+ }
65
+ /**
66
+ * Fetch check results (GitHub Actions + external)
67
+ *
68
+ * @param prNumber - PR number
69
+ * @returns Check results
70
+ */
71
+ async fetchChecks(prNumber) {
72
+ const data = fetchPRChecks(prNumber, this.owner, this.repo);
73
+ const checks = [];
74
+ for (const check of data.statusCheckRollup ?? []) {
75
+ const type = this.classifyCheck(check);
76
+ if (type === 'CheckRun') {
77
+ checks.push(this.mapCheckRun(check));
78
+ }
79
+ else {
80
+ checks.push(this.mapStatusContext(check));
81
+ }
82
+ }
83
+ return checks;
84
+ }
85
+ /**
86
+ * Fetch run logs for a GitHub Actions run
87
+ *
88
+ * @param runId - GitHub run ID
89
+ * @returns Raw log output
90
+ */
91
+ async fetchRunLogs(runId) {
92
+ return ghFetchRunLogs(runId, this.owner, this.repo);
93
+ }
94
+ /**
95
+ * Fetch details for a specific GitHub Actions run
96
+ *
97
+ * Useful for watching specific failed runs to test extraction.
98
+ *
99
+ * @param runId - GitHub run ID
100
+ * @returns Run details
101
+ */
102
+ async fetchRunDetails(runId) {
103
+ const fields = ['name', 'status', 'conclusion', 'workflowName', 'createdAt', 'updatedAt', 'url'];
104
+ const data = ghFetchRunDetails(runId, this.owner, this.repo, fields);
105
+ // Map GitHub API response to RunDetails
106
+ return {
107
+ run_id: runId,
108
+ name: data.name,
109
+ workflow: data.workflowName,
110
+ status: this.normalizeStatus(data.status),
111
+ conclusion: data.conclusion ? this.normalizeConclusion(data.conclusion) : undefined,
112
+ started_at: data.createdAt,
113
+ duration: this.calculateDuration(data.createdAt, data.updatedAt),
114
+ url: data.url,
115
+ };
116
+ }
117
+ /**
118
+ * Fetch all workflow runs for a PR
119
+ *
120
+ * @param prNumber - PR number
121
+ * @returns List of workflow runs
122
+ */
123
+ async fetchRunsForPR(prNumber) {
124
+ // First get the PR branch name
125
+ const prData = ghFetchPRDetails(prNumber, this.owner, this.repo, ['headRefName']);
126
+ const branchName = prData.headRefName;
127
+ // Fetch workflow runs for the branch
128
+ const runs = listWorkflowRuns(branchName, this.owner, this.repo, 20, ['databaseId', 'workflowName', 'status', 'conclusion', 'createdAt', 'updatedAt']);
129
+ // Transform to expected format
130
+ return runs.map((run) => ({
131
+ run_id: run.databaseId,
132
+ workflow_name: run.workflowName,
133
+ status: run.status,
134
+ conclusion: run.conclusion,
135
+ started_at: run.createdAt,
136
+ duration: this.calculateDuration(run.createdAt, run.updatedAt),
137
+ }));
138
+ }
139
+ /**
140
+ * Fetch file changes for a PR
141
+ *
142
+ * Uses git diff --numstat to get file change statistics.
143
+ *
144
+ * @param _prNumber - PR number (unused - we use git diff from current branch)
145
+ * @returns File change context
146
+ */
147
+ async fetchFileChanges(_prNumber) {
148
+ // Get diff stats using getDiffStats from @vibe-validate/git (architectural compliance)
149
+ const diffOutput = getDiffStats('origin/main', 'HEAD');
150
+ // Get commit count using getCommitCount from @vibe-validate/git (architectural compliance)
151
+ const commitCount = getCommitCount('origin/main', 'HEAD');
152
+ // Parse diff output
153
+ const lines = diffOutput.trim().split('\n').filter((line) => line.length > 0);
154
+ let totalInsertions = 0;
155
+ let totalDeletions = 0;
156
+ const files = [];
157
+ for (let i = 0; i < lines.length; i++) {
158
+ const line = lines[i];
159
+ const parts = line.split('\t');
160
+ if (parts.length !== 3)
161
+ continue;
162
+ // Skip binary file markers (0\t0\t-)
163
+ if (parts[0] === '0' && parts[1] === '0' && parts[2] === '-') {
164
+ continue;
165
+ }
166
+ const insertions = parts[0] === '-' ? 0 : Number.parseInt(parts[0], 10);
167
+ const deletions = parts[1] === '-' ? 0 : Number.parseInt(parts[1], 10);
168
+ const file = parts[2];
169
+ // Detect new files - next line is 0\t0\t- marker
170
+ const nextLine = i + 1 < lines.length ? lines[i + 1] : '';
171
+ const nextParts = nextLine.split('\t');
172
+ const isNewFile = nextParts.length === 3 && nextParts[0] === '0' && nextParts[1] === '0' && nextParts[2] === '-';
173
+ totalInsertions += insertions;
174
+ totalDeletions += deletions;
175
+ files.push({
176
+ file,
177
+ insertions,
178
+ deletions,
179
+ new_file: isNewFile,
180
+ });
181
+ }
182
+ // Sort by total changes (insertions + deletions) and limit to top 10
183
+ // Using toSorted to avoid mutation (sonarjs requirement)
184
+ const topFiles = [...files]
185
+ .sort((a, b) => b.insertions + b.deletions - (a.insertions + a.deletions))
186
+ .slice(0, 10);
187
+ return {
188
+ files_changed: files.length,
189
+ insertions: totalInsertions,
190
+ deletions: totalDeletions,
191
+ commits: Number.parseInt(commitCount.trim(), 10),
192
+ top_files: topFiles,
193
+ };
194
+ }
195
+ /**
196
+ * Classify check type
197
+ *
198
+ * @param check - Check object from GitHub API
199
+ * @returns 'CheckRun' or 'StatusContext'
200
+ */
201
+ classifyCheck(check) {
202
+ return check.__typename === 'CheckRun' ? 'CheckRun' : 'StatusContext';
203
+ }
204
+ /**
205
+ * Map CheckRun to internal CheckResult
206
+ *
207
+ * @param check - CheckRun from GitHub API
208
+ * @returns CheckResult
209
+ */
210
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
211
+ mapCheckRun(check) {
212
+ const runId = this.extractRunId(check.detailsUrl);
213
+ const workflow = this.extractWorkflowName(check.name);
214
+ return {
215
+ type: 'github_action',
216
+ name: check.name,
217
+ status: this.normalizeStatus(check.status),
218
+ conclusion: check.conclusion ? this.normalizeConclusion(check.conclusion) : undefined,
219
+ run_id: runId ?? undefined,
220
+ workflow,
221
+ started_at: check.startedAt,
222
+ duration: this.calculateDuration(check.startedAt, check.completedAt),
223
+ };
224
+ }
225
+ /**
226
+ * Map StatusContext to internal CheckResult
227
+ *
228
+ * @param check - StatusContext from GitHub API
229
+ * @returns CheckResult
230
+ */
231
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
232
+ mapStatusContext(check) {
233
+ return {
234
+ type: 'external',
235
+ name: check.context,
236
+ status: 'completed',
237
+ conclusion: this.normalizeStatusContextState(check.state),
238
+ url: check.targetUrl,
239
+ provider: this.detectProvider(check.context),
240
+ };
241
+ }
242
+ /**
243
+ * Extract run ID from GitHub Actions URL
244
+ *
245
+ * @param url - GitHub Actions URL
246
+ * @returns Run ID or null
247
+ */
248
+ extractRunId(url) {
249
+ const regex = /\/runs\/(\d+)/;
250
+ const match = regex.exec(url);
251
+ return match ? Number.parseInt(match[1], 10) : null;
252
+ }
253
+ /**
254
+ * Extract workflow name from check name
255
+ *
256
+ * @param checkName - Check name (e.g., "CI / Build")
257
+ * @returns Workflow name
258
+ */
259
+ extractWorkflowName(checkName) {
260
+ // Extract workflow name before first /
261
+ const parts = checkName.split('/');
262
+ return parts[0].trim();
263
+ }
264
+ /**
265
+ * Calculate duration between two timestamps
266
+ *
267
+ * @param start - Start time (ISO 8601)
268
+ * @param end - End time (ISO 8601, optional - defaults to now)
269
+ * @returns Human-readable duration (e.g., "2m30s")
270
+ */
271
+ calculateDuration(start, end) {
272
+ if (!start)
273
+ return '0s';
274
+ const startTime = new Date(start).getTime();
275
+ // Handle invalid start time
276
+ if (Number.isNaN(startTime))
277
+ return '0s';
278
+ const endTime = end ? new Date(end).getTime() : Date.now();
279
+ // Handle invalid end time (fall back to now)
280
+ const effectiveEndTime = Number.isNaN(endTime) ? Date.now() : endTime;
281
+ const durationMs = effectiveEndTime - startTime;
282
+ // Handle negative duration (clock skew or invalid data)
283
+ if (durationMs < 0 || Number.isNaN(durationMs))
284
+ return '0s';
285
+ const seconds = Math.floor(durationMs / 1000);
286
+ const minutes = Math.floor(seconds / 60);
287
+ const hours = Math.floor(minutes / 60);
288
+ if (hours > 0) {
289
+ return `${hours}h${minutes % 60}m${seconds % 60}s`;
290
+ }
291
+ else if (minutes > 0) {
292
+ return `${minutes}m${seconds % 60}s`;
293
+ }
294
+ else {
295
+ return `${seconds}s`;
296
+ }
297
+ }
298
+ /**
299
+ * Normalize GitHub status to CheckStatus
300
+ *
301
+ * @param status - GitHub status
302
+ * @returns CheckStatus
303
+ */
304
+ normalizeStatus(status) {
305
+ const normalized = status.toLowerCase();
306
+ if (normalized === 'completed')
307
+ return 'completed';
308
+ if (normalized === 'in_progress')
309
+ return 'in_progress';
310
+ return 'queued';
311
+ }
312
+ /**
313
+ * Normalize GitHub conclusion to CheckConclusion
314
+ *
315
+ * @param conclusion - GitHub conclusion
316
+ * @returns CheckConclusion
317
+ */
318
+ normalizeConclusion(conclusion) {
319
+ const normalized = conclusion.toLowerCase();
320
+ if (normalized === 'success')
321
+ return 'success';
322
+ if (normalized === 'failure')
323
+ return 'failure';
324
+ if (normalized === 'neutral')
325
+ return 'neutral';
326
+ if (normalized === 'cancelled')
327
+ return 'cancelled';
328
+ if (normalized === 'skipped')
329
+ return 'skipped';
330
+ if (normalized === 'timed_out')
331
+ return 'timed_out';
332
+ return 'action_required';
333
+ }
334
+ /**
335
+ * Normalize StatusContext state to CheckConclusion
336
+ *
337
+ * @param state - StatusContext state
338
+ * @returns CheckConclusion
339
+ */
340
+ normalizeStatusContextState(state) {
341
+ const normalized = state.toLowerCase();
342
+ if (normalized === 'success')
343
+ return 'success';
344
+ if (normalized === 'failure' || normalized === 'error')
345
+ return 'failure';
346
+ if (normalized === 'pending')
347
+ return 'action_required';
348
+ return 'neutral';
349
+ }
350
+ /**
351
+ * Normalize merge state status
352
+ *
353
+ * @param status - GitHub merge state status
354
+ * @returns MergeStateStatus
355
+ */
356
+ normalizeMergeStateStatus(status) {
357
+ const normalized = status.toUpperCase();
358
+ if (normalized === 'BEHIND')
359
+ return 'BEHIND';
360
+ if (normalized === 'BLOCKED')
361
+ return 'BLOCKED';
362
+ if (normalized === 'CLEAN')
363
+ return 'CLEAN';
364
+ if (normalized === 'DIRTY')
365
+ return 'DIRTY';
366
+ if (normalized === 'DRAFT')
367
+ return 'DRAFT';
368
+ if (normalized === 'HAS_HOOKS')
369
+ return 'HAS_HOOKS';
370
+ if (normalized === 'UNSTABLE')
371
+ return 'UNSTABLE';
372
+ return 'UNKNOWN';
373
+ }
374
+ /**
375
+ * Extract linked issues from closing issues references
376
+ *
377
+ * @param closingIssuesReferences - Closing issues references from GitHub API
378
+ * @returns Linked issues
379
+ */
380
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
381
+ extractLinkedIssues(closingIssuesReferences) {
382
+ if (!closingIssuesReferences?.nodes)
383
+ return [];
384
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
385
+ return closingIssuesReferences.nodes.map((issue) => ({
386
+ number: issue.number,
387
+ title: issue.title,
388
+ url: issue.url,
389
+ }));
390
+ }
391
+ /**
392
+ * Detect provider from check name
393
+ *
394
+ * @param checkName - Check name
395
+ * @returns Provider name
396
+ */
397
+ detectProvider(checkName) {
398
+ const lower = checkName.toLowerCase();
399
+ if (lower.includes('codecov'))
400
+ return 'codecov';
401
+ if (lower.includes('sonar'))
402
+ return 'sonarcloud';
403
+ if (lower.includes('circleci'))
404
+ return 'circleci';
405
+ if (lower.includes('travis'))
406
+ return 'travis';
407
+ if (lower.includes('jenkins'))
408
+ return 'jenkins';
409
+ return 'unknown';
410
+ }
411
+ }
412
+ //# sourceMappingURL=github-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-fetcher.js","sourceRoot":"","sources":["../../src/services/github-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,cAAc,IAAI,gBAAgB,EAClC,aAAa,EACb,YAAY,IAAI,cAAc,EAC9B,eAAe,IAAI,iBAAiB,EACpC,YAAY,EACZ,cAAc,EACd,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AA4E5B;;GAEG;AACH,MAAM,OAAO,aAAa;IACP,KAAK,CAAU;IACf,IAAI,CAAU;IAE/B;;;;;OAKG;IACH,YAAY,KAAc,EAAE,IAAa;QACvC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,MAAM,MAAM,GAAG;YACb,QAAQ;YACR,OAAO;YACP,KAAK;YACL,aAAa;YACb,aAAa;YACb,QAAQ;YACR,SAAS;YACT,WAAW;YACX,kBAAkB;YAClB,QAAQ;YACR,yBAAyB;SAC1B,CAAC;QAEF,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAEvE,+CAA+C;QAC/C,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,MAAM,EAAE,IAAI,CAAC,WAAW;YACxB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YACzB,KAAK,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;YAC5B,SAAS,EAAE,IAAI,CAAC,SAAS,KAAK,WAAW;YACzC,kBAAkB,EAAE,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,gBAAgB,IAAI,SAAS,CAAC;YACtF,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAuB,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;YACvE,aAAa,EAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,uBAAuB,CAAC;SACtE,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CAAC,QAAgB;QAChC,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAkB,EAAE,CAAC;QAEjC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,iBAAiB,IAAI,EAAE,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAEvC,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBACxB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,YAAY,CAAC,KAAa;QAC9B,OAAO,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,eAAe,CAAC,KAAa;QACjC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QAEjG,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAErE,wCAAwC;QACxC,OAAO;YACL,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,YAAY;YAC3B,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC;YACzC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;YACnF,UAAU,EAAE,IAAI,CAAC,SAAS;YAC1B,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC;YAChE,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,QAAgB;QAOnC,+BAA+B;QAC/B,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;QAClF,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;QAEtC,qCAAqC;QACrC,MAAM,IAAI,GAAG,gBAAgB,CAC3B,UAAU,EACV,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,IAAI,EACT,EAAE,EACF,CAAC,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC,CACjF,CAAC;QAEF,+BAA+B;QAC/B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACxB,MAAM,EAAE,GAAG,CAAC,UAAU;YACtB,aAAa,EAAE,GAAG,CAAC,YAAY;YAC/B,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,UAAU,EAAE,GAAG,CAAC,SAAS;YACzB,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC;SAC/D,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,gBAAgB,CAAC,SAAiB;QACtC,uFAAuF;QACvF,MAAM,UAAU,GAAG,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAEvD,2FAA2F;QAC3F,MAAM,WAAW,GAAG,cAAc,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAE1D,oBAAoB;QACpB,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAE9E,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,MAAM,KAAK,GAAiB,EAAE,CAAC;QAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAEjC,qCAAqC;YACrC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC7D,SAAS;YACX,CAAC;YAED,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxE,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvE,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAEtB,iDAAiD;YACjD,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;YAEjH,eAAe,IAAI,UAAU,CAAC;YAC9B,cAAc,IAAI,SAAS,CAAC;YAE5B,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI;gBACJ,UAAU;gBACV,SAAS;gBACT,QAAQ,EAAE,SAAS;aACpB,CAAC,CAAC;QACL,CAAC;QAED,qEAAqE;QACrE,yDAAyD;QACzD,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC;aACxB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;aACzE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEhB,OAAO;YACL,aAAa,EAAE,KAAK,CAAC,MAAM;YAC3B,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;YAChD,SAAS,EAAE,QAAQ;SACpB,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACK,aAAa,CAAC,KAA8B;QAClD,OAAO,KAAK,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,8DAA8D;IACtD,WAAW,CAAC,KAAU;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAEtD,OAAO;YACL,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC;YAC1C,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;YACrF,MAAM,EAAE,KAAK,IAAI,SAAS;YAC1B,QAAQ;YACR,UAAU,EAAE,KAAK,CAAC,SAAS;YAC3B,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC;SACrE,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,8DAA8D;IACtD,gBAAgB,CAAC,KAAU;QACjC,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,KAAK,CAAC,OAAO;YACnB,MAAM,EAAE,WAAW;YACnB,UAAU,EAAE,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC,KAAK,CAAC;YACzD,GAAG,EAAE,KAAK,CAAC,SAAS;YACpB,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC;SAC7C,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACK,YAAY,CAAC,GAAW;QAC9B,MAAM,KAAK,GAAG,eAAe,CAAC;QAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtD,CAAC;IAED;;;;;OAKG;IACK,mBAAmB,CAAC,SAAiB;QAC3C,uCAAuC;QACvC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACK,iBAAiB,CAAC,KAAc,EAAE,GAAY;QACpD,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;QAC5C,4BAA4B;QAC5B,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QAEzC,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3D,6CAA6C;QAC7C,MAAM,gBAAgB,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAEtE,MAAM,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAAC;QAEhD,wDAAwD;QACxD,IAAI,UAAU,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;QAE5D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QAEvC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO,GAAG,KAAK,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,GAAG,EAAE,GAAG,CAAC;QACrD,CAAC;aAAM,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,GAAG,OAAO,IAAI,OAAO,GAAG,EAAE,GAAG,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,OAAO,GAAG,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,eAAe,CAAC,MAAc;QACpC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACxC,IAAI,UAAU,KAAK,WAAW;YAAE,OAAO,WAAW,CAAC;QACnD,IAAI,UAAU,KAAK,aAAa;YAAE,OAAO,aAAa,CAAC;QACvD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;;OAKG;IACK,mBAAmB,CAAC,UAAkB;QAC5C,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QAC5C,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC/C,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC/C,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC/C,IAAI,UAAU,KAAK,WAAW;YAAE,OAAO,WAAW,CAAC;QACnD,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC/C,IAAI,UAAU,KAAK,WAAW;YAAE,OAAO,WAAW,CAAC;QACnD,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACK,2BAA2B,CAAC,KAAa;QAC/C,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACvC,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC/C,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,OAAO;YAAE,OAAO,SAAS,CAAC;QACzE,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,iBAAiB,CAAC;QACvD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACK,yBAAyB,CAAC,MAAc;QAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACxC,IAAI,UAAU,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC7C,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC/C,IAAI,UAAU,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC;QAC3C,IAAI,UAAU,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC;QAC3C,IAAI,UAAU,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC;QAC3C,IAAI,UAAU,KAAK,WAAW;YAAE,OAAO,WAAW,CAAC;QACnD,IAAI,UAAU,KAAK,UAAU;YAAE,OAAO,UAAU,CAAC;QACjD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACH,8DAA8D;IACtD,mBAAmB,CAAC,uBAA4B;QACtD,IAAI,CAAC,uBAAuB,EAAE,KAAK;YAAE,OAAO,EAAE,CAAC;QAE/C,8DAA8D;QAC9D,OAAO,uBAAuB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,CAAC;YACxD,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,GAAG,EAAE,KAAK,CAAC,GAAG;SACf,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;;;;OAKG;IACK,cAAc,CAAC,SAAiB;QACtC,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAChD,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,YAAY,CAAC;QACjD,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,OAAO,UAAU,CAAC;QAClD,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,OAAO,QAAQ,CAAC;QAC9C,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAChD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * History Summary Builder
3
+ *
4
+ * Fetches workflow runs for a PR branch and calculates:
5
+ * - Total number of runs
6
+ * - Recent pattern (passed/failed/flaky)
7
+ * - Success rate
8
+ *
9
+ * Provides context for pattern recognition without full history details.
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+ import type { CheckHistorySummary } from '../schemas/watch-pr-result.schema.js';
14
+ /**
15
+ * HistorySummaryBuilder
16
+ *
17
+ * Builds a condensed history summary for pattern recognition.
18
+ */
19
+ export declare class HistorySummaryBuilder {
20
+ private readonly _owner;
21
+ private readonly _repo;
22
+ constructor(_owner: string, _repo: string);
23
+ /**
24
+ * Build history summary for a PR branch
25
+ *
26
+ * @param branch - Branch name
27
+ * @returns History summary with total runs, pattern, and success rate
28
+ */
29
+ buildSummary(branch: string): Promise<CheckHistorySummary>;
30
+ /**
31
+ * Fetch workflow runs for a branch via gh CLI
32
+ *
33
+ * @param branch - Branch name
34
+ * @returns Array of workflow runs (sorted by created_at DESC)
35
+ */
36
+ private fetchWorkflowRuns;
37
+ /**
38
+ * Detect pattern from recent runs
39
+ *
40
+ * Patterns:
41
+ * - "Passed last N runs" - All recent runs passed
42
+ * - "Failed last N runs" - All recent runs failed
43
+ * - "Flaky (alternating)" - Alternating pass/fail
44
+ * - "Recently fixed (was failing)" - Recent passes after failures
45
+ * - Generic pattern otherwise
46
+ *
47
+ * @param runs - All runs (sorted DESC)
48
+ * @returns Pattern description
49
+ */
50
+ private detectPattern;
51
+ /**
52
+ * Count consecutive runs with the same conclusion (starting from most recent)
53
+ *
54
+ * @param runs - Workflow runs
55
+ * @param conclusion - Conclusion to check
56
+ * @returns Count of consecutive runs
57
+ */
58
+ private countConsecutive;
59
+ /**
60
+ * Check if runs are alternating between success and failure
61
+ *
62
+ * @param runs - Workflow runs (at least 4 required)
63
+ * @returns True if alternating pattern detected
64
+ */
65
+ private isAlternating;
66
+ /**
67
+ * Calculate success rate from recent runs
68
+ *
69
+ * @param runs - Recent workflow runs (up to 10)
70
+ * @returns Success rate as percentage string (e.g., "75%")
71
+ */
72
+ private calculateSuccessRate;
73
+ }
74
+ //# sourceMappingURL=history-summary-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-summary-builder.d.ts","sourceRoot":"","sources":["../../src/services/history-summary-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAUhF;;;;GAIG;AACH,qBAAa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM;IAGhC;;;;;OAKG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA+BhE;;;;;OAKG;YACW,iBAAiB;IA+B/B;;;;;;;;;;;;OAYG;IAEH,OAAO,CAAC,aAAa;IAsDrB;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAmBrB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;CAU7B"}