@diff-review-system/drs 1.0.0 → 2.0.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 (287) 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 -130
  4. package/.opencode/agent/review/quality.md +36 -104
  5. package/.opencode/agent/review/security.md +32 -94
  6. package/.opencode/agent/review/style.md +26 -10
  7. package/.opencode/agent/review/unified-reviewer.md +74 -0
  8. package/.opencode/opencode.jsonc +4 -41
  9. package/.opencode/tool/write_json_output.ts +24 -0
  10. package/README.md +215 -82
  11. package/dist/ci/runner.d.ts.map +1 -1
  12. package/dist/ci/runner.js +4 -4
  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 +234 -20
  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 +337 -120
  27. package/dist/cli/init.js.map +1 -1
  28. package/dist/cli/post-comments.d.ts +15 -0
  29. package/dist/cli/post-comments.d.ts.map +1 -0
  30. package/dist/cli/post-comments.js +216 -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 +46 -63
  35. package/dist/cli/review-local.js.map +1 -1
  36. package/dist/cli/review-mr.d.ts +7 -0
  37. package/dist/cli/review-mr.d.ts.map +1 -1
  38. package/dist/cli/review-mr.js +88 -117
  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 +81 -114
  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/client.d.ts +199 -4
  49. package/dist/github/client.d.ts.map +1 -1
  50. package/dist/github/client.js +37 -2
  51. package/dist/github/client.js.map +1 -1
  52. package/dist/github/client.test.d.ts +2 -0
  53. package/dist/github/client.test.d.ts.map +1 -0
  54. package/dist/github/client.test.js +206 -0
  55. package/dist/github/client.test.js.map +1 -0
  56. package/dist/github/platform-adapter.d.ts +31 -0
  57. package/dist/github/platform-adapter.d.ts.map +1 -0
  58. package/dist/github/platform-adapter.js +129 -0
  59. package/dist/github/platform-adapter.js.map +1 -0
  60. package/dist/github/platform-adapter.test.d.ts +2 -0
  61. package/dist/github/platform-adapter.test.d.ts.map +1 -0
  62. package/dist/github/platform-adapter.test.js +40 -0
  63. package/dist/github/platform-adapter.test.js.map +1 -0
  64. package/dist/gitlab/client.d.ts +12 -0
  65. package/dist/gitlab/client.d.ts.map +1 -1
  66. package/dist/gitlab/client.js +19 -1
  67. package/dist/gitlab/client.js.map +1 -1
  68. package/dist/gitlab/diff-parser.test.d.ts +2 -0
  69. package/dist/gitlab/diff-parser.test.d.ts.map +1 -0
  70. package/dist/gitlab/diff-parser.test.js +315 -0
  71. package/dist/gitlab/diff-parser.test.js.map +1 -0
  72. package/dist/gitlab/platform-adapter.d.ts +27 -0
  73. package/dist/gitlab/platform-adapter.d.ts.map +1 -0
  74. package/dist/gitlab/platform-adapter.js +121 -0
  75. package/dist/gitlab/platform-adapter.js.map +1 -0
  76. package/dist/gitlab/platform-adapter.test.d.ts +2 -0
  77. package/dist/gitlab/platform-adapter.test.d.ts.map +1 -0
  78. package/dist/gitlab/platform-adapter.test.js +21 -0
  79. package/dist/gitlab/platform-adapter.test.js.map +1 -0
  80. package/dist/index.test.d.ts +2 -0
  81. package/dist/index.test.d.ts.map +1 -0
  82. package/dist/index.test.js +7 -0
  83. package/dist/index.test.js.map +1 -0
  84. package/dist/lib/change-summary.d.ts +8 -0
  85. package/dist/lib/change-summary.d.ts.map +1 -0
  86. package/dist/lib/change-summary.js +2 -0
  87. package/dist/lib/change-summary.js.map +1 -0
  88. package/dist/lib/code-quality-report.d.ts +44 -0
  89. package/dist/lib/code-quality-report.d.ts.map +1 -0
  90. package/dist/lib/code-quality-report.js +62 -0
  91. package/dist/lib/code-quality-report.js.map +1 -0
  92. package/dist/lib/code-quality-report.test.d.ts +2 -0
  93. package/dist/lib/code-quality-report.test.d.ts.map +1 -0
  94. package/dist/lib/code-quality-report.test.js +327 -0
  95. package/dist/lib/code-quality-report.test.js.map +1 -0
  96. package/dist/{gitlab → lib}/comment-formatter.d.ts +6 -3
  97. package/dist/lib/comment-formatter.d.ts.map +1 -0
  98. package/dist/{gitlab → lib}/comment-formatter.js +63 -16
  99. package/dist/lib/comment-formatter.js.map +1 -0
  100. package/dist/lib/comment-formatter.test.d.ts +2 -0
  101. package/dist/lib/comment-formatter.test.d.ts.map +1 -0
  102. package/dist/lib/comment-formatter.test.js +607 -0
  103. package/dist/lib/comment-formatter.test.js.map +1 -0
  104. package/dist/lib/comment-manager.d.ts +61 -0
  105. package/dist/lib/comment-manager.d.ts.map +1 -0
  106. package/dist/lib/comment-manager.js +91 -0
  107. package/dist/lib/comment-manager.js.map +1 -0
  108. package/dist/lib/comment-manager.test.d.ts +2 -0
  109. package/dist/lib/comment-manager.test.d.ts.map +1 -0
  110. package/dist/lib/comment-manager.test.js +618 -0
  111. package/dist/lib/comment-manager.test.js.map +1 -0
  112. package/dist/lib/comment-poster.d.ts +21 -0
  113. package/dist/lib/comment-poster.d.ts.map +1 -0
  114. package/dist/lib/comment-poster.js +96 -0
  115. package/dist/lib/comment-poster.js.map +1 -0
  116. package/dist/lib/comment-poster.test.d.ts +5 -0
  117. package/dist/lib/comment-poster.test.d.ts.map +1 -0
  118. package/dist/lib/comment-poster.test.js +215 -0
  119. package/dist/lib/comment-poster.test.js.map +1 -0
  120. package/dist/lib/config-model-overrides.test.d.ts +12 -0
  121. package/dist/lib/config-model-overrides.test.d.ts.map +1 -0
  122. package/dist/lib/config-model-overrides.test.js +254 -0
  123. package/dist/lib/config-model-overrides.test.js.map +1 -0
  124. package/dist/lib/config.d.ts +93 -8
  125. package/dist/lib/config.d.ts.map +1 -1
  126. package/dist/lib/config.js +178 -25
  127. package/dist/lib/config.js.map +1 -1
  128. package/dist/lib/config.test.d.ts +2 -0
  129. package/dist/lib/config.test.d.ts.map +1 -0
  130. package/dist/lib/config.test.js +36 -0
  131. package/dist/lib/config.test.js.map +1 -0
  132. package/dist/lib/context-compression.d.ts +19 -0
  133. package/dist/lib/context-compression.d.ts.map +1 -0
  134. package/dist/lib/context-compression.js +170 -0
  135. package/dist/lib/context-compression.js.map +1 -0
  136. package/dist/lib/context-compression.test.d.ts +2 -0
  137. package/dist/lib/context-compression.test.d.ts.map +1 -0
  138. package/dist/lib/context-compression.test.js +33 -0
  139. package/dist/lib/context-compression.test.js.map +1 -0
  140. package/dist/lib/context-loader.d.ts +29 -0
  141. package/dist/lib/context-loader.d.ts.map +1 -0
  142. package/dist/lib/context-loader.js +75 -0
  143. package/dist/lib/context-loader.js.map +1 -0
  144. package/dist/lib/context-loader.test.d.ts +2 -0
  145. package/dist/lib/context-loader.test.d.ts.map +1 -0
  146. package/dist/lib/context-loader.test.js +207 -0
  147. package/dist/lib/context-loader.test.js.map +1 -0
  148. package/dist/lib/describe-core.d.ts +9 -0
  149. package/dist/lib/describe-core.d.ts.map +1 -0
  150. package/dist/lib/describe-core.js +71 -0
  151. package/dist/lib/describe-core.js.map +1 -0
  152. package/dist/lib/describe-core.test.d.ts +2 -0
  153. package/dist/lib/describe-core.test.d.ts.map +1 -0
  154. package/dist/lib/describe-core.test.js +208 -0
  155. package/dist/lib/describe-core.test.js.map +1 -0
  156. package/dist/lib/describe-output-path.test.d.ts +2 -0
  157. package/dist/lib/describe-output-path.test.d.ts.map +1 -0
  158. package/dist/lib/describe-output-path.test.js +51 -0
  159. package/dist/lib/describe-output-path.test.js.map +1 -0
  160. package/dist/lib/describe-parser.d.ts +3 -0
  161. package/dist/lib/describe-parser.d.ts.map +1 -0
  162. package/dist/lib/describe-parser.js +163 -0
  163. package/dist/lib/describe-parser.js.map +1 -0
  164. package/dist/lib/describe-parser.test.d.ts +2 -0
  165. package/dist/lib/describe-parser.test.d.ts.map +1 -0
  166. package/dist/lib/describe-parser.test.js +282 -0
  167. package/dist/lib/describe-parser.test.js.map +1 -0
  168. package/dist/lib/description-executor.d.ts +22 -0
  169. package/dist/lib/description-executor.d.ts.map +1 -0
  170. package/dist/lib/description-executor.js +72 -0
  171. package/dist/lib/description-executor.js.map +1 -0
  172. package/dist/lib/description-formatter.d.ts +37 -0
  173. package/dist/lib/description-formatter.d.ts.map +1 -0
  174. package/dist/lib/description-formatter.js +219 -0
  175. package/dist/lib/description-formatter.js.map +1 -0
  176. package/dist/{gitlab → lib}/diff-parser.d.ts +11 -0
  177. package/dist/lib/diff-parser.d.ts.map +1 -0
  178. package/dist/{gitlab → lib}/diff-parser.js +40 -3
  179. package/dist/lib/diff-parser.js.map +1 -0
  180. package/dist/lib/issue-parser.d.ts +29 -0
  181. package/dist/lib/issue-parser.d.ts.map +1 -0
  182. package/dist/lib/issue-parser.js +153 -0
  183. package/dist/lib/issue-parser.js.map +1 -0
  184. package/dist/lib/issue-parser.test.d.ts +2 -0
  185. package/dist/lib/issue-parser.test.d.ts.map +1 -0
  186. package/dist/lib/issue-parser.test.js +281 -0
  187. package/dist/lib/issue-parser.test.js.map +1 -0
  188. package/dist/lib/json-output-schema.d.ts +207 -0
  189. package/dist/lib/json-output-schema.d.ts.map +1 -0
  190. package/dist/lib/json-output-schema.js +124 -0
  191. package/dist/lib/json-output-schema.js.map +1 -0
  192. package/dist/lib/json-output-schema.test.d.ts +2 -0
  193. package/dist/lib/json-output-schema.test.d.ts.map +1 -0
  194. package/dist/lib/json-output-schema.test.js +92 -0
  195. package/dist/lib/json-output-schema.test.js.map +1 -0
  196. package/dist/lib/json-output.d.ts +43 -0
  197. package/dist/lib/json-output.d.ts.map +1 -0
  198. package/dist/lib/json-output.js +34 -0
  199. package/dist/lib/json-output.js.map +1 -0
  200. package/dist/lib/output-paths.d.ts +6 -0
  201. package/dist/lib/output-paths.d.ts.map +1 -0
  202. package/dist/lib/output-paths.js +5 -0
  203. package/dist/lib/output-paths.js.map +1 -0
  204. package/dist/lib/platform-client.d.ts +130 -0
  205. package/dist/lib/platform-client.d.ts.map +1 -0
  206. package/dist/lib/platform-client.js +8 -0
  207. package/dist/lib/platform-client.js.map +1 -0
  208. package/dist/lib/position-validator.d.ts +36 -0
  209. package/dist/lib/position-validator.d.ts.map +1 -0
  210. package/dist/lib/position-validator.js +43 -0
  211. package/dist/lib/position-validator.js.map +1 -0
  212. package/dist/lib/repository-validator.d.ts +52 -0
  213. package/dist/lib/repository-validator.d.ts.map +1 -0
  214. package/dist/lib/repository-validator.js +219 -0
  215. package/dist/lib/repository-validator.js.map +1 -0
  216. package/dist/lib/repository-validator.test.d.ts +5 -0
  217. package/dist/lib/repository-validator.test.d.ts.map +1 -0
  218. package/dist/lib/repository-validator.test.js +341 -0
  219. package/dist/lib/repository-validator.test.js.map +1 -0
  220. package/dist/lib/review-core.d.ts +66 -0
  221. package/dist/lib/review-core.d.ts.map +1 -0
  222. package/dist/lib/review-core.js +449 -0
  223. package/dist/lib/review-core.js.map +1 -0
  224. package/dist/lib/review-core.test.d.ts +2 -0
  225. package/dist/lib/review-core.test.d.ts.map +1 -0
  226. package/dist/lib/review-core.test.js +552 -0
  227. package/dist/lib/review-core.test.js.map +1 -0
  228. package/dist/lib/review-orchestrator.d.ts +77 -0
  229. package/dist/lib/review-orchestrator.d.ts.map +1 -0
  230. package/dist/lib/review-orchestrator.js +124 -0
  231. package/dist/lib/review-orchestrator.js.map +1 -0
  232. package/dist/lib/review-orchestrator.test.d.ts +2 -0
  233. package/dist/lib/review-orchestrator.test.d.ts.map +1 -0
  234. package/dist/lib/review-orchestrator.test.js +413 -0
  235. package/dist/lib/review-orchestrator.test.js.map +1 -0
  236. package/dist/lib/review-output-path.test.d.ts +2 -0
  237. package/dist/lib/review-output-path.test.d.ts.map +1 -0
  238. package/dist/lib/review-output-path.test.js +83 -0
  239. package/dist/lib/review-output-path.test.js.map +1 -0
  240. package/dist/lib/review-parser.d.ts +2 -0
  241. package/dist/lib/review-parser.d.ts.map +1 -0
  242. package/dist/lib/review-parser.js +100 -0
  243. package/dist/lib/review-parser.js.map +1 -0
  244. package/dist/lib/unified-review-executor.d.ts +49 -0
  245. package/dist/lib/unified-review-executor.d.ts.map +1 -0
  246. package/dist/lib/unified-review-executor.js +158 -0
  247. package/dist/lib/unified-review-executor.js.map +1 -0
  248. package/dist/lib/unified-review-executor.test.d.ts +5 -0
  249. package/dist/lib/unified-review-executor.test.d.ts.map +1 -0
  250. package/dist/lib/unified-review-executor.test.js +344 -0
  251. package/dist/lib/unified-review-executor.test.js.map +1 -0
  252. package/dist/lib/write-json-output.d.ts +13 -0
  253. package/dist/lib/write-json-output.d.ts.map +1 -0
  254. package/dist/lib/write-json-output.js +37 -0
  255. package/dist/lib/write-json-output.js.map +1 -0
  256. package/dist/opencode/agent-loader.d.ts +3 -4
  257. package/dist/opencode/agent-loader.d.ts.map +1 -1
  258. package/dist/opencode/agent-loader.js +51 -42
  259. package/dist/opencode/agent-loader.js.map +1 -1
  260. package/dist/opencode/agent-skill-overlay.d.ts +11 -0
  261. package/dist/opencode/agent-skill-overlay.d.ts.map +1 -0
  262. package/dist/opencode/agent-skill-overlay.js +164 -0
  263. package/dist/opencode/agent-skill-overlay.js.map +1 -0
  264. package/dist/opencode/client.d.ts +14 -5
  265. package/dist/opencode/client.d.ts.map +1 -1
  266. package/dist/opencode/client.js +311 -32
  267. package/dist/opencode/client.js.map +1 -1
  268. package/dist/opencode/client.test.d.ts +2 -0
  269. package/dist/opencode/client.test.d.ts.map +1 -0
  270. package/dist/opencode/client.test.js +317 -0
  271. package/dist/opencode/client.test.js.map +1 -0
  272. package/dist/opencode/opencode-paths.d.ts +2 -0
  273. package/dist/opencode/opencode-paths.d.ts.map +1 -0
  274. package/dist/opencode/opencode-paths.js +7 -0
  275. package/dist/opencode/opencode-paths.js.map +1 -0
  276. package/dist/opencode/skill-loader.d.ts +6 -0
  277. package/dist/opencode/skill-loader.d.ts.map +1 -0
  278. package/dist/opencode/skill-loader.js +36 -0
  279. package/dist/opencode/skill-loader.js.map +1 -0
  280. package/package.json +29 -20
  281. package/.opencode/agent/github-reviewer.md +0 -62
  282. package/.opencode/agent/gitlab-reviewer.md +0 -62
  283. package/.opencode/agent/local-reviewer.md +0 -71
  284. package/dist/gitlab/comment-formatter.d.ts.map +0 -1
  285. package/dist/gitlab/comment-formatter.js.map +0 -1
  286. package/dist/gitlab/diff-parser.d.ts.map +0 -1
  287. package/dist/gitlab/diff-parser.js.map +0 -1
@@ -0,0 +1,170 @@
1
+ const DEFAULT_COMPRESSION_OPTIONS = {
2
+ enabled: true,
3
+ maxTokens: 8000,
4
+ softBufferTokens: 1500,
5
+ hardBufferTokens: 1000,
6
+ tokenEstimateDivisor: 4,
7
+ };
8
+ function normalizeOptions(options) {
9
+ return {
10
+ ...DEFAULT_COMPRESSION_OPTIONS,
11
+ ...options,
12
+ };
13
+ }
14
+ function estimateTokens(text, divisor) {
15
+ const normalizedDivisor = divisor > 0 ? divisor : DEFAULT_COMPRESSION_OPTIONS.tokenEstimateDivisor;
16
+ return Math.ceil(text.length / normalizedDivisor);
17
+ }
18
+ function buildDiffEntry(file) {
19
+ return `### ${file.filename}\n\n\`\`\`diff\n${file.patch}\n\`\`\``;
20
+ }
21
+ export function stripDeletionOnlyHunks(patch) {
22
+ const lines = patch.split('\n');
23
+ const preserved = [];
24
+ const prefix = [];
25
+ let currentHunk = [];
26
+ let sawHunk = false;
27
+ let hunkHasAddition = false;
28
+ const flushHunk = () => {
29
+ if (currentHunk.length > 0) {
30
+ if (hunkHasAddition) {
31
+ preserved.push(...currentHunk);
32
+ }
33
+ currentHunk = [];
34
+ hunkHasAddition = false;
35
+ }
36
+ };
37
+ for (const line of lines) {
38
+ if (line.startsWith('@@')) {
39
+ sawHunk = true;
40
+ flushHunk();
41
+ currentHunk.push(line);
42
+ continue;
43
+ }
44
+ if (!sawHunk) {
45
+ prefix.push(line);
46
+ continue;
47
+ }
48
+ currentHunk.push(line);
49
+ if (line.startsWith('+') && !line.startsWith('+++')) {
50
+ hunkHasAddition = true;
51
+ }
52
+ }
53
+ flushHunk();
54
+ if (!sawHunk) {
55
+ return patch.trim();
56
+ }
57
+ if (preserved.length === 0) {
58
+ return '';
59
+ }
60
+ return [...prefix, ...preserved].join('\n').trim();
61
+ }
62
+ export function compressFilesWithDiffs(files, options) {
63
+ const resolvedOptions = normalizeOptions(options);
64
+ if (!resolvedOptions.enabled) {
65
+ return {
66
+ files,
67
+ omitted: {
68
+ deletionsOnly: [],
69
+ dueToBudget: [],
70
+ },
71
+ };
72
+ }
73
+ const deletionsOnly = [];
74
+ const budgetOmitted = [];
75
+ const filesWithDiffs = [];
76
+ for (const file of files) {
77
+ if (!file.patch)
78
+ continue;
79
+ const trimmedPatch = stripDeletionOnlyHunks(file.patch ?? '');
80
+ if (!trimmedPatch.trim()) {
81
+ deletionsOnly.push(file.filename);
82
+ continue;
83
+ }
84
+ filesWithDiffs.push({
85
+ filename: file.filename,
86
+ patch: trimmedPatch,
87
+ });
88
+ }
89
+ if (filesWithDiffs.length === 0) {
90
+ return {
91
+ files,
92
+ omitted: {
93
+ deletionsOnly,
94
+ dueToBudget: [],
95
+ },
96
+ };
97
+ }
98
+ const entries = filesWithDiffs.map((file) => {
99
+ const entryText = buildDiffEntry(file);
100
+ return {
101
+ file,
102
+ entryText,
103
+ tokens: estimateTokens(entryText, resolvedOptions.tokenEstimateDivisor),
104
+ };
105
+ });
106
+ const totalTokens = entries.reduce((sum, entry) => sum + entry.tokens, 0);
107
+ const softLimit = resolvedOptions.maxTokens - resolvedOptions.softBufferTokens;
108
+ const hardLimit = resolvedOptions.maxTokens - resolvedOptions.hardBufferTokens;
109
+ if (totalTokens <= softLimit) {
110
+ const patchLookup = new Map(filesWithDiffs.map((file) => [file.filename, file.patch]));
111
+ return {
112
+ files: files.map((file) => file.patch ? { filename: file.filename, patch: patchLookup.get(file.filename) } : file),
113
+ omitted: {
114
+ deletionsOnly,
115
+ dueToBudget: [],
116
+ },
117
+ };
118
+ }
119
+ const sorted = [...entries].sort((a, b) => {
120
+ if (b.tokens !== a.tokens)
121
+ return b.tokens - a.tokens;
122
+ return a.file.filename.localeCompare(b.file.filename);
123
+ });
124
+ const kept = [];
125
+ let currentTokens = 0;
126
+ for (const entry of sorted) {
127
+ if (currentTokens > hardLimit) {
128
+ budgetOmitted.push(entry.file.filename);
129
+ continue;
130
+ }
131
+ if (currentTokens + entry.tokens > softLimit) {
132
+ budgetOmitted.push(entry.file.filename);
133
+ continue;
134
+ }
135
+ kept.push(entry.file);
136
+ currentTokens += entry.tokens;
137
+ }
138
+ const keptLookup = new Map(kept.map((entry) => [entry.filename, entry.patch]));
139
+ const keptFiles = files.map((file) => {
140
+ if (!file.patch)
141
+ return file;
142
+ const keptPatch = keptLookup.get(file.filename);
143
+ return keptPatch ? { filename: file.filename, patch: keptPatch } : { filename: file.filename };
144
+ });
145
+ return {
146
+ files: keptFiles,
147
+ omitted: {
148
+ deletionsOnly,
149
+ dueToBudget: budgetOmitted,
150
+ },
151
+ };
152
+ }
153
+ export function formatCompressionSummary(result) {
154
+ const sections = [];
155
+ if (result.omitted.deletionsOnly.length > 0) {
156
+ sections.push(`- Deletions-only changes (omitted from diff content):\n${result.omitted.deletionsOnly
157
+ .map((name) => ` - ${name}`)
158
+ .join('\n')}`);
159
+ }
160
+ if (result.omitted.dueToBudget.length > 0) {
161
+ sections.push(`- Omitted due to token budget:\n${result.omitted.dueToBudget
162
+ .map((name) => ` - ${name}`)
163
+ .join('\n')}`);
164
+ }
165
+ if (sections.length === 0) {
166
+ return '';
167
+ }
168
+ return `## Omitted Files\n\n${sections.join('\n\n')}`;
169
+ }
170
+ //# sourceMappingURL=context-compression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-compression.js","sourceRoot":"","sources":["../../src/lib/context-compression.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=context-compression.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-compression.test.d.ts","sourceRoot":"","sources":["../../src/lib/context-compression.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { compressFilesWithDiffs, formatCompressionSummary, stripDeletionOnlyHunks, } from './context-compression.js';
3
+ describe('context compression', () => {
4
+ it('removes deletion-only hunks', () => {
5
+ const patch = ['@@ -1,3 +1,0 @@', '-const remove = true;', '-const gone = false;'].join('\n');
6
+ expect(stripDeletionOnlyHunks(patch)).toBe('');
7
+ });
8
+ it('keeps hunks with additions', () => {
9
+ const patch = [
10
+ '@@ -1,3 +1,4 @@',
11
+ ' const keep = true;',
12
+ '+const added = true;',
13
+ '-const removed = false;',
14
+ ].join('\n');
15
+ expect(stripDeletionOnlyHunks(patch)).toContain('+const added = true;');
16
+ });
17
+ it('omits patches that exceed token budget', () => {
18
+ const files = [
19
+ { filename: 'src/large.ts', patch: '@@ -1,1 +1,3 @@\n+foo\n+bar\n+baz' },
20
+ { filename: 'src/small.ts', patch: '@@ -1,1 +1,2 @@\n+ok' },
21
+ ];
22
+ const result = compressFilesWithDiffs(files, {
23
+ maxTokens: 10,
24
+ softBufferTokens: 2,
25
+ hardBufferTokens: 1,
26
+ tokenEstimateDivisor: 1,
27
+ });
28
+ const summary = formatCompressionSummary(result);
29
+ expect(summary).toContain('Omitted due to token budget');
30
+ expect(result.files.find((file) => file.filename === 'src/large.ts')?.patch).toBeUndefined();
31
+ });
32
+ });
33
+ //# sourceMappingURL=context-compression.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-compression.test.js","sourceRoot":"","sources":["../../src/lib/context-compression.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAElC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,KAAK,GAAG,CAAC,iBAAiB,EAAE,uBAAuB,EAAE,sBAAsB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9F,MAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,KAAK,GAAG;YACZ,iBAAiB;YACjB,qBAAqB;YACrB,sBAAsB;YACtB,yBAAyB;SAC1B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,KAAK,GAAG;YACZ,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,mCAAmC,EAAE;YACxE,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,sBAAsB,EAAE;SAC5D,CAAC;QAEF,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,EAAE;YAC3C,SAAS,EAAE,EAAE;YACb,gBAAgB,EAAE,CAAC;YACnB,gBAAgB,EAAE,CAAC;YACnB,oBAAoB,EAAE,CAAC;SACxB,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;IAC/F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface AgentContext {
2
+ /**
3
+ * Source of the agent definition
4
+ * - 'override': Using .drs/agents/{name}/agent.md (full replacement)
5
+ * - 'default': Using built-in agent
6
+ */
7
+ source: 'override' | 'default';
8
+ /**
9
+ * Agent-specific context from .drs/agents/{name}/context.md
10
+ */
11
+ agentContext?: string;
12
+ /**
13
+ * Full agent definition (only for overrides)
14
+ */
15
+ agentDefinition?: string;
16
+ }
17
+ /**
18
+ * Load global project context from .drs/context.md
19
+ */
20
+ export declare function loadGlobalContext(projectRoot?: string): string | null;
21
+ /**
22
+ * Load agent-specific context and check for overrides
23
+ */
24
+ export declare function loadAgentContext(agentName: string, projectRoot?: string): AgentContext;
25
+ /**
26
+ * Build review prompt with global and agent-specific context
27
+ */
28
+ export declare function buildReviewPrompt(agentName: string, basePrompt: string, reviewLabel: string, changedFiles: string[], projectRoot?: string): string;
29
+ //# sourceMappingURL=context-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-loader.d.ts","sourceRoot":"","sources":["../../src/lib/context-loader.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAE/B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAQpF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,WAAW,GAAE,MAAsB,GAClC,YAAY,CAyBd;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EAAE,EACtB,WAAW,GAAE,MAAsB,GAClC,MAAM,CAwCR"}
@@ -0,0 +1,75 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ /**
4
+ * Load global project context from .drs/context.md
5
+ */
6
+ export function loadGlobalContext(projectRoot = process.cwd()) {
7
+ const contextPath = join(projectRoot, '.drs', 'context.md');
8
+ if (existsSync(contextPath)) {
9
+ return readFileSync(contextPath, 'utf-8');
10
+ }
11
+ return null;
12
+ }
13
+ /**
14
+ * Load agent-specific context and check for overrides
15
+ */
16
+ export function loadAgentContext(agentName, projectRoot = process.cwd()) {
17
+ const agentDir = join(projectRoot, '.drs', 'agents', agentName);
18
+ // Check for full agent override
19
+ const agentDefPath = join(agentDir, 'agent.md');
20
+ if (existsSync(agentDefPath)) {
21
+ return {
22
+ source: 'override',
23
+ agentDefinition: readFileSync(agentDefPath, 'utf-8'),
24
+ };
25
+ }
26
+ // Check for agent-specific context (additive to default agent)
27
+ const contextPath = join(agentDir, 'context.md');
28
+ if (existsSync(contextPath)) {
29
+ return {
30
+ source: 'default',
31
+ agentContext: readFileSync(contextPath, 'utf-8'),
32
+ };
33
+ }
34
+ // No customization, use default
35
+ return {
36
+ source: 'default',
37
+ };
38
+ }
39
+ /**
40
+ * Build review prompt with global and agent-specific context
41
+ */
42
+ export function buildReviewPrompt(agentName, basePrompt, reviewLabel, changedFiles, projectRoot = process.cwd()) {
43
+ const globalContext = loadGlobalContext(projectRoot);
44
+ const agentContext = loadAgentContext(agentName, projectRoot);
45
+ let prompt = '';
46
+ // If agent is fully overridden, use that instead of base prompt
47
+ if (agentContext.source === 'override' && agentContext.agentDefinition) {
48
+ prompt = agentContext.agentDefinition;
49
+ // Add task details
50
+ prompt += `\n\nReview the following files from ${reviewLabel}:\n\n`;
51
+ prompt += changedFiles.map((f) => `- ${f}`).join('\n');
52
+ return prompt;
53
+ }
54
+ // Otherwise, build prompt with contexts + base prompt
55
+ // 1. Global project context (if available)
56
+ if (globalContext) {
57
+ const trimmedContext = globalContext.trim();
58
+ const firstLine = trimmedContext.split('\n').find((line) => line.trim().length > 0) || '';
59
+ if (/^#\s*project context/i.test(firstLine)) {
60
+ prompt += `${trimmedContext}\n\n`;
61
+ }
62
+ else {
63
+ prompt += `# Project Context\n\n${trimmedContext}\n\n`;
64
+ }
65
+ }
66
+ // 2. Agent-specific context (if available)
67
+ if (agentContext.agentContext) {
68
+ prompt += `# ${agentName.charAt(0).toUpperCase() + agentName.slice(1)} Agent Context\n\n`;
69
+ prompt += `${agentContext.agentContext}\n\n`;
70
+ }
71
+ // 3. Base agent instructions
72
+ prompt += basePrompt;
73
+ return prompt;
74
+ }
75
+ //# sourceMappingURL=context-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-loader.js","sourceRoot":"","sources":["../../src/lib/context-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=context-loader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-loader.test.d.ts","sourceRoot":"","sources":["../../src/lib/context-loader.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,207 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { loadGlobalContext, loadAgentContext, buildReviewPrompt } from './context-loader.js';
3
+ import { existsSync, readFileSync } from 'fs';
4
+ // Mock fs module
5
+ vi.mock('fs', () => ({
6
+ existsSync: vi.fn(),
7
+ readFileSync: vi.fn(),
8
+ }));
9
+ describe('context-loader', () => {
10
+ beforeEach(() => {
11
+ vi.clearAllMocks();
12
+ });
13
+ describe('loadGlobalContext', () => {
14
+ it('should load global context when file exists', () => {
15
+ vi.mocked(existsSync).mockReturnValue(true);
16
+ vi.mocked(readFileSync).mockReturnValue('# Project Context\n\nThis is project context');
17
+ const result = loadGlobalContext('/test/project');
18
+ expect(result).toBe('# Project Context\n\nThis is project context');
19
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/context.md');
20
+ expect(readFileSync).toHaveBeenCalledWith('/test/project/.drs/context.md', 'utf-8');
21
+ });
22
+ it('should return null when file does not exist', () => {
23
+ vi.mocked(existsSync).mockReturnValue(false);
24
+ const result = loadGlobalContext('/test/project');
25
+ expect(result).toBeNull();
26
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/context.md');
27
+ expect(readFileSync).not.toHaveBeenCalled();
28
+ });
29
+ it('should use process.cwd() as default project root', () => {
30
+ vi.mocked(existsSync).mockReturnValue(false);
31
+ const originalCwd = process.cwd();
32
+ loadGlobalContext();
33
+ expect(existsSync).toHaveBeenCalledWith(`${originalCwd}/.drs/context.md`);
34
+ });
35
+ });
36
+ describe('loadAgentContext', () => {
37
+ it('should load full agent override when agent.md exists', () => {
38
+ // Mock agent.md exists
39
+ vi.mocked(existsSync).mockImplementation((path) => {
40
+ return path.toString().includes('agent.md');
41
+ });
42
+ vi.mocked(readFileSync).mockReturnValue('# Custom Agent\n\nCustom agent definition');
43
+ const result = loadAgentContext('security', '/test/project');
44
+ expect(result).toEqual({
45
+ source: 'override',
46
+ agentDefinition: '# Custom Agent\n\nCustom agent definition',
47
+ });
48
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/security/agent.md');
49
+ });
50
+ it('should load agent context when context.md exists but not agent.md', () => {
51
+ // Mock only context.md exists
52
+ vi.mocked(existsSync).mockImplementation((path) => {
53
+ return path.toString().includes('context.md') && !path.toString().includes('agent.md');
54
+ });
55
+ vi.mocked(readFileSync).mockReturnValue('Agent-specific context');
56
+ const result = loadAgentContext('quality', '/test/project');
57
+ expect(result).toEqual({
58
+ source: 'default',
59
+ agentContext: 'Agent-specific context',
60
+ });
61
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/quality/agent.md');
62
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/quality/context.md');
63
+ });
64
+ it('should return default when no customization exists', () => {
65
+ vi.mocked(existsSync).mockReturnValue(false);
66
+ const result = loadAgentContext('style', '/test/project');
67
+ expect(result).toEqual({
68
+ source: 'default',
69
+ });
70
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/style/agent.md');
71
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/style/context.md');
72
+ });
73
+ it('should use process.cwd() as default project root', () => {
74
+ vi.mocked(existsSync).mockReturnValue(false);
75
+ const originalCwd = process.cwd();
76
+ loadAgentContext('security');
77
+ expect(existsSync).toHaveBeenCalledWith(`${originalCwd}/.drs/agents/security/agent.md`);
78
+ });
79
+ });
80
+ describe('buildReviewPrompt', () => {
81
+ it('should use full agent override when available', () => {
82
+ // Mock agent override
83
+ vi.mocked(existsSync).mockImplementation((path) => {
84
+ return path.toString().includes('agent.md');
85
+ });
86
+ vi.mocked(readFileSync).mockReturnValue('# Custom Security Agent\n\nCustom instructions');
87
+ const result = buildReviewPrompt('security', 'Default base prompt', 'PR #123', ['src/app.ts', 'src/utils.ts'], '/test/project');
88
+ expect(result).toContain('# Custom Security Agent');
89
+ expect(result).toContain('Custom instructions');
90
+ expect(result).toContain('Review the following files from PR #123');
91
+ expect(result).toContain('- src/app.ts');
92
+ expect(result).toContain('- src/utils.ts');
93
+ expect(result).not.toContain('Default base prompt');
94
+ });
95
+ it('should build prompt with global context and base prompt', () => {
96
+ // Mock global context exists, no agent override
97
+ vi.mocked(existsSync).mockImplementation((path) => {
98
+ const pathStr = path.toString();
99
+ return pathStr.includes('.drs/context.md');
100
+ });
101
+ vi.mocked(readFileSync).mockImplementation((path) => {
102
+ if (path.toString().includes('.drs/context.md')) {
103
+ return '# Project Context\n\nThis is our project';
104
+ }
105
+ return '';
106
+ });
107
+ const result = buildReviewPrompt('quality', 'Review code quality', 'MR !456', ['lib/index.ts'], '/test/project');
108
+ expect(result).toContain('# Project Context');
109
+ expect(result).toContain('This is our project');
110
+ expect(result).toContain('Review code quality');
111
+ });
112
+ it('should add Project Context header when not present in global context', () => {
113
+ vi.mocked(existsSync).mockImplementation((path) => {
114
+ return path.toString().includes('.drs/context.md');
115
+ });
116
+ vi.mocked(readFileSync).mockReturnValue('Just some context without header');
117
+ const result = buildReviewPrompt('security', 'Base instructions', 'PR #1', ['file.ts'], '/test/project');
118
+ expect(result).toContain('# Project Context\n\nJust some context without header');
119
+ });
120
+ it('should not duplicate Project Context header when already present', () => {
121
+ vi.mocked(existsSync).mockImplementation((path) => {
122
+ return path.toString().includes('.drs/context.md');
123
+ });
124
+ vi.mocked(readFileSync).mockReturnValue('# Project Context\n\nAlready has header');
125
+ const result = buildReviewPrompt('security', 'Base instructions', 'PR #1', ['file.ts'], '/test/project');
126
+ // Should not have double "# Project Context"
127
+ const matches = result.match(/# Project Context/g);
128
+ expect(matches).toHaveLength(1);
129
+ });
130
+ it('should build prompt with agent-specific context', () => {
131
+ // Mock agent context exists
132
+ vi.mocked(existsSync).mockImplementation((path) => {
133
+ const pathStr = path.toString();
134
+ return pathStr.includes('agents/security/context.md');
135
+ });
136
+ vi.mocked(readFileSync).mockReturnValue('Focus on authentication and authorization');
137
+ const result = buildReviewPrompt('security', 'Base security review', 'PR #2', ['auth.ts'], '/test/project');
138
+ expect(result).toContain('# Security Agent Context');
139
+ expect(result).toContain('Focus on authentication and authorization');
140
+ expect(result).toContain('Base security review');
141
+ });
142
+ it('should capitalize agent name in agent context header', () => {
143
+ vi.mocked(existsSync).mockImplementation((path) => {
144
+ return path.toString().includes('agents/quality/context.md');
145
+ });
146
+ vi.mocked(readFileSync).mockReturnValue('Quality context');
147
+ const result = buildReviewPrompt('quality', 'Base prompt', 'PR #3', ['file.ts'], '/test/project');
148
+ expect(result).toContain('# Quality Agent Context');
149
+ });
150
+ it('should build prompt with all contexts (global + agent + base)', () => {
151
+ // Mock both global and agent context
152
+ vi.mocked(existsSync).mockImplementation((path) => {
153
+ const pathStr = path.toString();
154
+ return (pathStr.includes('.drs/context.md') || pathStr.includes('agents/security/context.md'));
155
+ });
156
+ vi.mocked(readFileSync).mockImplementation((path) => {
157
+ if (path.toString().includes('.drs/context.md')) {
158
+ return 'Global project context';
159
+ }
160
+ if (path.toString().includes('agents/security/context.md')) {
161
+ return 'Security-specific context';
162
+ }
163
+ return '';
164
+ });
165
+ const result = buildReviewPrompt('security', 'Base security instructions', 'PR #4', ['auth.ts'], '/test/project');
166
+ expect(result).toContain('Global project context');
167
+ expect(result).toContain('Security-specific context');
168
+ expect(result).toContain('Base security instructions');
169
+ });
170
+ it('should handle empty file list', () => {
171
+ vi.mocked(existsSync).mockImplementation((path) => {
172
+ return path.toString().includes('agent.md');
173
+ });
174
+ vi.mocked(readFileSync).mockReturnValue('Custom agent');
175
+ const result = buildReviewPrompt('security', 'Base prompt', 'PR #5', [], '/test/project');
176
+ expect(result).toContain('Review the following files from PR #5');
177
+ // Should still work with no files listed
178
+ });
179
+ it('should use process.cwd() as default project root', () => {
180
+ vi.mocked(existsSync).mockReturnValue(false);
181
+ const originalCwd = process.cwd();
182
+ buildReviewPrompt('security', 'Base prompt', 'PR #1', ['file.ts']);
183
+ expect(existsSync).toHaveBeenCalledWith(`${originalCwd}/.drs/context.md`);
184
+ expect(existsSync).toHaveBeenCalledWith(`${originalCwd}/.drs/agents/security/agent.md`);
185
+ });
186
+ it('should handle whitespace-only global context', () => {
187
+ vi.mocked(existsSync).mockImplementation((path) => {
188
+ return path.toString().includes('.drs/context.md');
189
+ });
190
+ vi.mocked(readFileSync).mockReturnValue(' \n\n ');
191
+ const result = buildReviewPrompt('security', 'Base prompt', 'PR #1', ['file.ts'], '/test/project');
192
+ // Whitespace is preserved and wrapped with header
193
+ expect(result).toContain('# Project Context');
194
+ expect(result).toContain('Base prompt');
195
+ });
196
+ it('should handle context with multiple empty lines before content', () => {
197
+ vi.mocked(existsSync).mockImplementation((path) => {
198
+ return path.toString().includes('.drs/context.md');
199
+ });
200
+ vi.mocked(readFileSync).mockReturnValue('\n\n\n# Project Context\n\nContent here');
201
+ const result = buildReviewPrompt('security', 'Base prompt', 'PR #1', ['file.ts'], '/test/project');
202
+ expect(result).toContain('# Project Context\n\nContent here');
203
+ expect(result).not.toMatch(/^\n+/); // Should not start with newlines
204
+ });
205
+ });
206
+ });
207
+ //# sourceMappingURL=context-loader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-loader.test.js","sourceRoot":"","sources":["../../src/lib/context-loader.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { FileWithDiff } from './review-core.js';
2
+ /**
3
+ * Build base instructions for the describe agent.
4
+ *
5
+ * @param label - Human-readable label for the description (e.g., "PR #123", "MR !456")
6
+ * @param files - List of files with optional diff content
7
+ */
8
+ export declare function buildDescribeInstructions(label: string, files: FileWithDiff[], compressionSummary?: string, projectContext?: string): string;
9
+ //# sourceMappingURL=describe-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe-core.d.ts","sourceRoot":"","sources":["../../src/lib/describe-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,YAAY,EAAE,EACrB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAkER"}