@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,317 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { OpencodeClient, createOpencodeClient, createOpencodeClientInstance } from './client.js';
3
+ // Mock the OpenCode SDK
4
+ vi.mock('@opencode-ai/sdk', () => ({
5
+ createOpencode: vi.fn(async () => ({
6
+ server: {
7
+ url: 'http://localhost:3000',
8
+ close: vi.fn(),
9
+ },
10
+ client: {
11
+ session: {
12
+ create: vi.fn(async () => ({ data: { id: 'session-123' } })),
13
+ prompt: vi.fn(async () => { }),
14
+ messages: vi.fn(async () => ({ data: [] })),
15
+ delete: vi.fn(async () => { }),
16
+ },
17
+ },
18
+ })),
19
+ createOpencodeClient: vi.fn((_config) => ({
20
+ session: {
21
+ create: vi.fn(async () => ({ data: { id: 'session-456' } })),
22
+ prompt: vi.fn(async () => { }),
23
+ messages: vi.fn(async () => ({ data: [] })),
24
+ delete: vi.fn(async () => { }),
25
+ },
26
+ })),
27
+ }));
28
+ describe('OpencodeClient', () => {
29
+ beforeEach(() => {
30
+ vi.spyOn(console, 'log').mockImplementation(() => { });
31
+ vi.spyOn(console, 'warn').mockImplementation(() => { });
32
+ vi.clearAllMocks();
33
+ });
34
+ describe('constructor', () => {
35
+ it('should create an instance with baseUrl', () => {
36
+ const client = new OpencodeClient({
37
+ baseUrl: 'http://localhost:3000',
38
+ directory: '/test/dir',
39
+ });
40
+ expect(client).toBeInstanceOf(OpencodeClient);
41
+ });
42
+ it('should create an instance without baseUrl for in-process server', () => {
43
+ const client = new OpencodeClient({
44
+ directory: '/test/dir',
45
+ });
46
+ expect(client).toBeInstanceOf(OpencodeClient);
47
+ });
48
+ it('should handle model overrides in config', () => {
49
+ const client = new OpencodeClient({
50
+ modelOverrides: {
51
+ 'review/security': 'claude-opus-4',
52
+ },
53
+ });
54
+ expect(client).toBeInstanceOf(OpencodeClient);
55
+ });
56
+ it('should handle custom provider in config', () => {
57
+ const client = new OpencodeClient({
58
+ provider: {
59
+ 'custom-provider': {
60
+ npm: '@custom/provider',
61
+ name: 'custom-provider',
62
+ models: { 'custom-model': { name: 'custom-model' } },
63
+ options: {
64
+ baseURL: 'https://api.custom.com',
65
+ apiKey: '{env:CUSTOM_API_KEY}',
66
+ },
67
+ },
68
+ },
69
+ });
70
+ expect(client).toBeInstanceOf(OpencodeClient);
71
+ });
72
+ });
73
+ describe('createSession', () => {
74
+ it('should throw error if not initialized', async () => {
75
+ const client = new OpencodeClient({});
76
+ await expect(client.createSession({
77
+ agent: 'review/security',
78
+ message: 'Review this code',
79
+ })).rejects.toThrow('OpenCode client not initialized');
80
+ });
81
+ });
82
+ describe('streamMessages', () => {
83
+ it('should throw error if not initialized', async () => {
84
+ const client = new OpencodeClient({});
85
+ const generator = client.streamMessages('session-123');
86
+ await expect(generator.next()).rejects.toThrow('OpenCode client not initialized');
87
+ });
88
+ });
89
+ describe('closeSession', () => {
90
+ it('should throw error if not initialized', async () => {
91
+ const client = new OpencodeClient({});
92
+ await expect(client.closeSession('session-123')).rejects.toThrow('OpenCode client not initialized');
93
+ });
94
+ });
95
+ describe('getServerUrl', () => {
96
+ it('should throw error if server not initialized', () => {
97
+ const client = new OpencodeClient({});
98
+ expect(() => client.getServerUrl()).toThrow('Server not initialized');
99
+ });
100
+ });
101
+ describe('shutdown', () => {
102
+ it('should not throw error when no server is running', async () => {
103
+ const client = new OpencodeClient({});
104
+ await expect(client.shutdown()).resolves.toBeUndefined();
105
+ });
106
+ });
107
+ describe('environment variable resolution', () => {
108
+ it('should resolve environment variables in provider config', () => {
109
+ // Set up test environment variable
110
+ const originalEnv = process.env.TEST_API_KEY;
111
+ process.env.TEST_API_KEY = 'test-key-123';
112
+ const client = new OpencodeClient({
113
+ provider: {
114
+ 'test-provider': {
115
+ npm: '@test/provider',
116
+ name: 'test-provider',
117
+ models: { 'test-model': { name: 'test-model' } },
118
+ options: {
119
+ baseURL: 'https://api.test.com',
120
+ apiKey: '{env:TEST_API_KEY}',
121
+ },
122
+ },
123
+ },
124
+ });
125
+ // The client should be created successfully
126
+ expect(client).toBeInstanceOf(OpencodeClient);
127
+ // Restore original env
128
+ if (originalEnv === undefined) {
129
+ delete process.env.TEST_API_KEY;
130
+ }
131
+ else {
132
+ process.env.TEST_API_KEY = originalEnv;
133
+ }
134
+ });
135
+ it('should warn when environment variable is not set', () => {
136
+ const consoleSpy = vi.spyOn(console, 'warn');
137
+ // Make sure the env var doesn't exist
138
+ const originalEnv = process.env.NONEXISTENT_VAR;
139
+ delete process.env.NONEXISTENT_VAR;
140
+ const client = new OpencodeClient({
141
+ provider: {
142
+ 'test-provider': {
143
+ npm: '@test/provider',
144
+ name: 'test-provider',
145
+ models: { 'test-model': { name: 'test-model' } },
146
+ options: {
147
+ baseURL: 'https://api.test.com',
148
+ apiKey: '{env:NONEXISTENT_VAR}',
149
+ },
150
+ },
151
+ },
152
+ });
153
+ expect(client).toBeInstanceOf(OpencodeClient);
154
+ // Restore original env
155
+ if (originalEnv !== undefined) {
156
+ process.env.NONEXISTENT_VAR = originalEnv;
157
+ }
158
+ consoleSpy.mockRestore();
159
+ });
160
+ it('should handle non-env string values', () => {
161
+ const client = new OpencodeClient({
162
+ provider: {
163
+ 'test-provider': {
164
+ npm: '@test/provider',
165
+ name: 'test-provider',
166
+ models: { 'test-model': { name: 'test-model' } },
167
+ options: {
168
+ baseURL: 'https://api.test.com',
169
+ apiKey: 'hardcoded-key',
170
+ },
171
+ },
172
+ },
173
+ });
174
+ expect(client).toBeInstanceOf(OpencodeClient);
175
+ });
176
+ it('should handle nested objects with env vars', () => {
177
+ const originalEnv = process.env.TEST_NESTED_KEY;
178
+ process.env.TEST_NESTED_KEY = 'nested-value';
179
+ const client = new OpencodeClient({
180
+ provider: {
181
+ 'test-provider': {
182
+ npm: '@test/provider',
183
+ name: 'test-provider',
184
+ models: { 'test-model': { name: 'test-model' } },
185
+ options: {
186
+ baseURL: 'https://api.test.com',
187
+ apiKey: 'test-key',
188
+ nested: {
189
+ deepKey: '{env:TEST_NESTED_KEY}',
190
+ },
191
+ },
192
+ },
193
+ },
194
+ });
195
+ expect(client).toBeInstanceOf(OpencodeClient);
196
+ // Restore original env
197
+ if (originalEnv === undefined) {
198
+ delete process.env.TEST_NESTED_KEY;
199
+ }
200
+ else {
201
+ process.env.TEST_NESTED_KEY = originalEnv;
202
+ }
203
+ });
204
+ it('should handle arrays with env vars', () => {
205
+ const originalEnv = process.env.TEST_ARRAY_KEY;
206
+ process.env.TEST_ARRAY_KEY = 'array-value';
207
+ const client = new OpencodeClient({
208
+ provider: {
209
+ 'test-provider': {
210
+ models: { 'test-model': { name: 'test-model' } },
211
+ options: {
212
+ baseURL: 'https://api.test.com',
213
+ apiKey: 'test-key',
214
+ keys: ['{env:TEST_ARRAY_KEY}', 'static-value'],
215
+ },
216
+ },
217
+ },
218
+ });
219
+ expect(client).toBeInstanceOf(OpencodeClient);
220
+ // Restore original env
221
+ if (originalEnv === undefined) {
222
+ delete process.env.TEST_ARRAY_KEY;
223
+ }
224
+ else {
225
+ process.env.TEST_ARRAY_KEY = originalEnv;
226
+ }
227
+ });
228
+ it('should handle primitive values', () => {
229
+ const client = new OpencodeClient({
230
+ provider: {
231
+ 'test-provider': {
232
+ models: { 'test-model': { name: 'test-model' } },
233
+ options: {
234
+ baseURL: 'https://api.test.com',
235
+ apiKey: 'test-key',
236
+ timeout: 5000,
237
+ enabled: true,
238
+ ratio: 0.5,
239
+ nullValue: null,
240
+ },
241
+ },
242
+ },
243
+ });
244
+ expect(client).toBeInstanceOf(OpencodeClient);
245
+ });
246
+ });
247
+ describe('factory functions', () => {
248
+ it('should create client with createOpencodeClient (deprecated)', () => {
249
+ const client = createOpencodeClient({
250
+ baseUrl: 'http://localhost:3000',
251
+ });
252
+ expect(client).toBeInstanceOf(OpencodeClient);
253
+ });
254
+ it('should create and initialize client with createOpencodeClientInstance', async () => {
255
+ const { createOpencodeClient: createSDKClient } = await import('@opencode-ai/sdk');
256
+ // Mock for remote server
257
+ vi.mocked(createSDKClient).mockReturnValueOnce({
258
+ session: {
259
+ create: vi.fn(async () => ({ data: { id: 'session-789' } })),
260
+ prompt: vi.fn(async () => { }),
261
+ messages: vi.fn(async () => ({ data: [] })),
262
+ delete: vi.fn(async () => { }),
263
+ },
264
+ });
265
+ const client = await createOpencodeClientInstance({
266
+ baseUrl: 'http://localhost:3000',
267
+ });
268
+ expect(client).toBeInstanceOf(OpencodeClient);
269
+ expect(createSDKClient).toHaveBeenCalledWith({
270
+ baseUrl: 'http://localhost:3000',
271
+ });
272
+ });
273
+ });
274
+ describe('debug mode', () => {
275
+ it('should log debug information when debug is enabled', () => {
276
+ const consoleSpy = vi.spyOn(console, 'log');
277
+ const client = new OpencodeClient({
278
+ debug: true,
279
+ modelOverrides: {
280
+ 'review/security': 'claude-opus-4',
281
+ },
282
+ });
283
+ expect(client).toBeInstanceOf(OpencodeClient);
284
+ consoleSpy.mockRestore();
285
+ });
286
+ });
287
+ describe('configuration', () => {
288
+ it('should handle complex configuration with all options', () => {
289
+ const client = new OpencodeClient({
290
+ baseUrl: 'http://localhost:3000',
291
+ directory: '/test/project',
292
+ modelOverrides: {
293
+ 'review/security': 'claude-opus-4',
294
+ 'review/quality': 'claude-sonnet-4',
295
+ },
296
+ provider: {
297
+ 'custom-provider': {
298
+ npm: '@custom/provider',
299
+ name: 'custom-provider',
300
+ models: { 'custom-model': { name: 'custom-model' } },
301
+ options: {
302
+ baseURL: 'https://api.custom.com',
303
+ apiKey: '{env:CUSTOM_KEY}',
304
+ },
305
+ },
306
+ },
307
+ debug: false,
308
+ });
309
+ expect(client).toBeInstanceOf(OpencodeClient);
310
+ });
311
+ it('should handle minimal configuration', () => {
312
+ const client = new OpencodeClient({});
313
+ expect(client).toBeInstanceOf(OpencodeClient);
314
+ });
315
+ });
316
+ });
317
+ //# sourceMappingURL=client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../src/opencode/client.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const builtInAgentPath: string;
2
+ //# sourceMappingURL=opencode-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-paths.d.ts","sourceRoot":"","sources":["../../src/opencode/opencode-paths.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,gBAAgB,QAA0C,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { dirname, join } from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ const __filename = fileURLToPath(import.meta.url);
4
+ const __dirname = dirname(__filename);
5
+ const packageRoot = join(__dirname, '..', '..');
6
+ export const builtInAgentPath = join(packageRoot, '.opencode', 'agent');
7
+ //# sourceMappingURL=opencode-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-paths.js","sourceRoot":"","sources":["../../src/opencode/opencode-paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAEhD,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface SkillDefinition {
2
+ name: string;
3
+ path: string;
4
+ }
5
+ export declare function loadProjectSkills(projectPath: string): SkillDefinition[];
6
+ //# sourceMappingURL=skill-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-loader.d.ts","sourceRoot":"","sources":["../../src/opencode/skill-loader.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAsCD,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,EAAE,CAQxE"}
@@ -0,0 +1,36 @@
1
+ import { existsSync, readdirSync, statSync } from 'fs';
2
+ import { join, relative } from 'path';
3
+ const skillFileNames = new Set(['SKILL.md', 'skill.md']);
4
+ function traverseDirectory(basePath, currentPath, fileFilter) {
5
+ const files = [];
6
+ if (!existsSync(currentPath)) {
7
+ return files;
8
+ }
9
+ const entries = readdirSync(currentPath);
10
+ for (const entry of entries) {
11
+ const fullPath = join(currentPath, entry);
12
+ const stat = statSync(fullPath);
13
+ if (stat.isDirectory()) {
14
+ files.push(...traverseDirectory(basePath, fullPath, fileFilter));
15
+ }
16
+ else if (stat.isFile() && fileFilter(entry, fullPath)) {
17
+ files.push(fullPath);
18
+ }
19
+ }
20
+ return files;
21
+ }
22
+ function resolveSkillName(skillsRoot, filePath) {
23
+ const relativePath = relative(skillsRoot, filePath).replace(/\\/g, '/');
24
+ const parentDir = relativePath.replace(/\/(SKILL|skill)\.md$/, '');
25
+ const segments = parentDir.split('/').filter(Boolean);
26
+ return segments[segments.length - 1] ?? parentDir;
27
+ }
28
+ export function loadProjectSkills(projectPath) {
29
+ const skillsRoot = join(projectPath, '.drs', 'skills');
30
+ const files = traverseDirectory(skillsRoot, skillsRoot, (entry) => skillFileNames.has(entry));
31
+ return files.map((filePath) => ({
32
+ name: resolveSkillName(skillsRoot, filePath),
33
+ path: filePath,
34
+ }));
35
+ }
36
+ //# sourceMappingURL=skill-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-loader.js","sourceRoot":"","sources":["../../src/opencode/skill-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAOtC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;AAEzD,SAAS,iBAAiB,CACxB,QAAgB,EAChB,WAAmB,EACnB,UAAwD;IAExD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;IAEzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEhC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;YACxD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,gBAAgB,CAAC,UAAkB,EAAE,QAAgB;IAC5D,MAAM,YAAY,GAAG,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;IACnE,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACtD,OAAO,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,iBAAiB,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IAE9F,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC9B,IAAI,EAAE,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC;QAC5C,IAAI,EAAE,QAAQ;KACf,CAAC,CAAC,CAAC;AACN,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diff-review-system/drs",
3
- "version": "1.1.2",
3
+ "version": "2.1.0",
4
4
  "description": "Intelligent code review platform for GitLab and GitHub - Enterprise-grade automated analysis",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -9,6 +9,7 @@
9
9
  },
10
10
  "scripts": {
11
11
  "build": "tsc",
12
+ "build:watch": "tsc --watch",
12
13
  "dev": "tsx watch src/cli/index.ts",
13
14
  "start": "node dist/cli/index.js",
14
15
  "test": "vitest run",
@@ -16,6 +17,7 @@
16
17
  "lint:fix": "eslint 'src/**/*.ts' --fix",
17
18
  "format": "prettier --write 'src/**/*.{ts,json}'",
18
19
  "format:check": "prettier --check 'src/**/*.{ts,json}'",
20
+ "check:all": "npm run format && npm run lint:fix && npm run build && npm test && npm run format:check && npm run lint",
19
21
  "type-check": "tsc --noEmit",
20
22
  "prepublishOnly": "npm run build"
21
23
  },
@@ -50,19 +52,17 @@
50
52
  "@anthropic-ai/sdk": "^0.32.0",
51
53
  "@gitbeaker/node": "^35.8.1",
52
54
  "@octokit/rest": "^21.0.0",
55
+ "@opencode-ai/plugin": "^1.1.23",
53
56
  "@opencode-ai/sdk": "^1.1.7",
54
- "bullmq": "^5.0.0",
57
+ "ajv": "^8.17.1",
55
58
  "chalk": "^5.3.0",
56
59
  "commander": "^12.0.0",
57
60
  "dotenv": "^16.0.0",
58
- "hono": "^4.0.0",
59
- "redis": "^4.6.0",
60
61
  "simple-git": "^3.22.0",
61
- "yaml": "^2.3.0",
62
- "zod": "^3.22.0"
62
+ "yaml": "^2.3.0"
63
63
  },
64
64
  "devDependencies": {
65
- "@types/node": "^22.19.5",
65
+ "@types/node": "^22.19.7",
66
66
  "@typescript-eslint/eslint-plugin": "^6.19.0",
67
67
  "@typescript-eslint/parser": "^6.19.0",
68
68
  "eslint": "^8.56.0",
@@ -1,77 +0,0 @@
1
- ---
2
- description: Main GitHub PR review orchestrator
3
- color: "#24292e"
4
- tools:
5
- Read: true
6
- Glob: true
7
- Grep: true
8
- Task: true
9
- github-api: true
10
- ---
11
-
12
- You are an expert code reviewer analyzing GitHub pull requests.
13
-
14
- Your task is to coordinate specialized review agents to provide comprehensive feedback on code changes.
15
-
16
- ## Review Process
17
-
18
- 1. **Fetch PR Context**: Get changed files and diffs from GitHub
19
- 2. **Invoke Specialized Agents**: Use Task tool to run specialized review agents in parallel
20
- 3. **Consolidate Findings**: Merge results from all agents
21
- 4. **Post Review**: Format and post comments to GitHub PR
22
-
23
- ## Specialized Agents Available
24
-
25
- Use the Task tool to invoke these specialized review agents:
26
-
27
- - **review/security** - OWASP vulnerabilities, injection attacks, auth issues
28
- - **review/quality** - Code patterns, complexity, maintainability
29
- - **review/style** - Formatting, naming, documentation
30
- - **review/performance** - Optimization opportunities, algorithmic improvements
31
-
32
- ## Review Workflow
33
-
34
- 1. Use the github-api tool to fetch PR details and changed files
35
- 2. Analyze which files need which type of review
36
- 3. Invoke specialized agents in parallel using the Task tool
37
- 4. Collect findings from each agent
38
- 5. Deduplicate and prioritize issues by severity
39
- 6. Use github-api tool to post findings as GitHub PR review comments
40
-
41
- ## Output Format
42
-
43
- **IMPORTANT**: Specialized agents will output JSON-formatted findings. You MUST preserve and pass through their JSON output exactly as received.
44
-
45
- The specialized agents output findings in this JSON format:
46
- ```json
47
- {
48
- "issues": [
49
- {
50
- "category": "SECURITY" | "QUALITY" | "STYLE" | "PERFORMANCE",
51
- "severity": "CRITICAL" | "HIGH" | "MEDIUM" | "LOW",
52
- "title": "Issue title",
53
- "file": "path/to/file.ts",
54
- "line": 42,
55
- "problem": "Description",
56
- "solution": "Fix description",
57
- "references": ["https://..."],
58
- "agent": "security"
59
- }
60
- ]
61
- }
62
- ```
63
-
64
- When you receive JSON output from specialized agents, include it in your response so it can be parsed for posting inline comments on GitHub PR.
65
-
66
- ## Example Agent Invocation
67
-
68
- To run specialized reviews in parallel:
69
-
70
- ```
71
- Use the Task tool to invoke:
72
- 1. Subagent: review/security - Review files: src/api/*.ts
73
- 2. Subagent: review/quality - Review files: src/services/*.ts
74
- 3. Subagent: review/style - Review files: src/**/*.ts
75
- ```
76
-
77
- Be thorough but concise. Focus on high-impact issues that improve code security, quality, and maintainability.
@@ -1,77 +0,0 @@
1
- ---
2
- description: Main GitLab MR review orchestrator
3
- color: "#FC6D26"
4
- tools:
5
- Read: true
6
- Glob: true
7
- Grep: true
8
- Task: true
9
- gitlab-api: true
10
- ---
11
-
12
- You are an expert code reviewer analyzing GitLab merge requests.
13
-
14
- Your task is to coordinate specialized review agents to provide comprehensive feedback on code changes.
15
-
16
- ## Review Process
17
-
18
- 1. **Fetch MR Context**: Get changed files and diffs from GitLab
19
- 2. **Invoke Specialized Agents**: Use Task tool to run specialized review agents in parallel
20
- 3. **Consolidate Findings**: Merge results from all agents
21
- 4. **Post Review**: Format and post comments to GitLab MR
22
-
23
- ## Specialized Agents Available
24
-
25
- Use the Task tool to invoke these specialized review agents:
26
-
27
- - **review/security** - OWASP vulnerabilities, injection attacks, auth issues
28
- - **review/quality** - Code patterns, complexity, maintainability
29
- - **review/style** - Formatting, naming, documentation
30
- - **review/performance** - Optimization opportunities, algorithmic improvements
31
-
32
- ## Review Workflow
33
-
34
- 1. Use the gitlab-api tool to fetch MR details and changed files
35
- 2. Analyze which files need which type of review
36
- 3. Invoke specialized agents in parallel using the Task tool
37
- 4. Collect findings from each agent
38
- 5. Deduplicate and prioritize issues by severity
39
- 6. Use gitlab-api tool to post findings as GitLab MR discussion threads
40
-
41
- ## Output Format
42
-
43
- **IMPORTANT**: Specialized agents will output JSON-formatted findings. You MUST preserve and pass through their JSON output exactly as received.
44
-
45
- The specialized agents output findings in this JSON format:
46
- ```json
47
- {
48
- "issues": [
49
- {
50
- "category": "SECURITY" | "QUALITY" | "STYLE" | "PERFORMANCE",
51
- "severity": "CRITICAL" | "HIGH" | "MEDIUM" | "LOW",
52
- "title": "Issue title",
53
- "file": "path/to/file.ts",
54
- "line": 42,
55
- "problem": "Description",
56
- "solution": "Fix description",
57
- "references": ["https://..."],
58
- "agent": "security"
59
- }
60
- ]
61
- }
62
- ```
63
-
64
- When you receive JSON output from specialized agents, include it in your response so it can be parsed for posting inline comments on GitLab MR discussion threads.
65
-
66
- ## Example Agent Invocation
67
-
68
- To run specialized reviews in parallel:
69
-
70
- ```
71
- Use the Task tool to invoke:
72
- 1. Subagent: review/security - Review files: src/api/*.ts
73
- 2. Subagent: review/quality - Review files: src/services/*.ts
74
- 3. Subagent: review/style - Review files: src/**/*.ts
75
- ```
76
-
77
- Be thorough but concise. Focus on high-impact issues that improve code security, quality, and maintainability.