@diff-review-system/drs 3.3.1 → 4.0.0-rc.4

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 (203) hide show
  1. package/.pi/agents/task/agents-md-updater.md +24 -0
  2. package/.pi/agents/task/changelog-updater.md +29 -0
  3. package/.pi/agents/task/review-issue-fixer.md +25 -0
  4. package/.pi/workflows/github-pr-describe-post.yaml +24 -0
  5. package/.pi/workflows/github-pr-describe.yaml +23 -0
  6. package/.pi/workflows/github-pr-post-comment.yaml +19 -0
  7. package/.pi/workflows/github-pr-review-post.yaml +32 -0
  8. package/.pi/workflows/github-pr-review.yaml +23 -0
  9. package/.pi/workflows/github-pr-show-changes.yaml +25 -0
  10. package/.pi/workflows/gitlab-mr-describe-post.yaml +22 -0
  11. package/.pi/workflows/gitlab-mr-describe.yaml +21 -0
  12. package/.pi/workflows/gitlab-mr-post-comment.yaml +17 -0
  13. package/.pi/workflows/gitlab-mr-review-code-quality.yaml +31 -0
  14. package/.pi/workflows/gitlab-mr-review-post-code-quality.yaml +40 -0
  15. package/.pi/workflows/gitlab-mr-review-post.yaml +30 -0
  16. package/.pi/workflows/gitlab-mr-review.yaml +21 -0
  17. package/.pi/workflows/gitlab-mr-show-changes.yaml +23 -0
  18. package/.pi/workflows/local-changelog-update.yaml +23 -0
  19. package/.pi/workflows/local-fix-review-issues.yaml +42 -0
  20. package/.pi/workflows/local-review.yaml +17 -0
  21. package/.pi/workflows/local-staged-review.yaml +17 -0
  22. package/.pi/workflows/local-update-agents-md.yaml +24 -0
  23. package/.pi/workflows/tag-changelog-update.yaml +26 -0
  24. package/README.md +214 -101
  25. package/dist/ci/runner.d.ts.map +1 -1
  26. package/dist/ci/runner.js +7 -8
  27. package/dist/ci/runner.js.map +1 -1
  28. package/dist/cli/index.js +69 -341
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/cli/init.d.ts.map +1 -1
  31. package/dist/cli/init.js +25 -23
  32. package/dist/cli/init.js.map +1 -1
  33. package/dist/cli/run-agent.d.ts +24 -0
  34. package/dist/cli/run-agent.d.ts.map +1 -0
  35. package/dist/cli/run-agent.js +139 -0
  36. package/dist/cli/run-agent.js.map +1 -0
  37. package/dist/cli/run-agent.test.d.ts +2 -0
  38. package/dist/cli/run-agent.test.d.ts.map +1 -0
  39. package/dist/cli/run-agent.test.js +204 -0
  40. package/dist/cli/run-agent.test.js.map +1 -0
  41. package/dist/cli/workflow.d.ts +51 -0
  42. package/dist/cli/workflow.d.ts.map +1 -0
  43. package/dist/cli/workflow.js +1229 -0
  44. package/dist/cli/workflow.js.map +1 -0
  45. package/dist/cli/workflow.test.d.ts +2 -0
  46. package/dist/cli/workflow.test.d.ts.map +1 -0
  47. package/dist/cli/workflow.test.js +1410 -0
  48. package/dist/cli/workflow.test.js.map +1 -0
  49. package/dist/lib/agent-id.d.ts +9 -0
  50. package/dist/lib/agent-id.d.ts.map +1 -0
  51. package/dist/lib/agent-id.js +32 -0
  52. package/dist/lib/agent-id.js.map +1 -0
  53. package/dist/lib/comment-formatter.d.ts +7 -1
  54. package/dist/lib/comment-formatter.d.ts.map +1 -1
  55. package/dist/lib/comment-formatter.js +42 -1
  56. package/dist/lib/comment-formatter.js.map +1 -1
  57. package/dist/lib/comment-formatter.test.js +33 -0
  58. package/dist/lib/comment-formatter.test.js.map +1 -1
  59. package/dist/lib/comment-manager.d.ts +4 -0
  60. package/dist/lib/comment-manager.d.ts.map +1 -1
  61. package/dist/lib/comment-manager.js +7 -1
  62. package/dist/lib/comment-manager.js.map +1 -1
  63. package/dist/lib/comment-poster.d.ts +2 -2
  64. package/dist/lib/comment-poster.d.ts.map +1 -1
  65. package/dist/lib/comment-poster.js +3 -3
  66. package/dist/lib/comment-poster.js.map +1 -1
  67. package/dist/lib/comment-poster.test.js +13 -3
  68. package/dist/lib/comment-poster.test.js.map +1 -1
  69. package/dist/lib/config-model-overrides.test.d.ts +0 -10
  70. package/dist/lib/config-model-overrides.test.d.ts.map +1 -1
  71. package/dist/lib/config-model-overrides.test.js +174 -210
  72. package/dist/lib/config-model-overrides.test.js.map +1 -1
  73. package/dist/lib/config.d.ts +111 -34
  74. package/dist/lib/config.d.ts.map +1 -1
  75. package/dist/lib/config.js +322 -83
  76. package/dist/lib/config.js.map +1 -1
  77. package/dist/lib/config.test.js +282 -2
  78. package/dist/lib/config.test.js.map +1 -1
  79. package/dist/lib/context-loader.d.ts +4 -4
  80. package/dist/lib/context-loader.d.ts.map +1 -1
  81. package/dist/lib/context-loader.js +10 -7
  82. package/dist/lib/context-loader.js.map +1 -1
  83. package/dist/lib/context-loader.test.js +31 -26
  84. package/dist/lib/context-loader.test.js.map +1 -1
  85. package/dist/lib/description-executor.js +1 -1
  86. package/dist/lib/description-executor.js.map +1 -1
  87. package/dist/lib/description-executor.test.js +10 -3
  88. package/dist/lib/description-executor.test.js.map +1 -1
  89. package/dist/lib/diff-lines.d.ts +9 -0
  90. package/dist/lib/diff-lines.d.ts.map +1 -0
  91. package/dist/lib/diff-lines.js +32 -0
  92. package/dist/lib/diff-lines.js.map +1 -0
  93. package/dist/lib/diff-lines.test.d.ts +2 -0
  94. package/dist/lib/diff-lines.test.d.ts.map +1 -0
  95. package/dist/lib/diff-lines.test.js +13 -0
  96. package/dist/lib/diff-lines.test.js.map +1 -0
  97. package/dist/lib/logger.d.ts +1 -1
  98. package/dist/lib/logger.d.ts.map +1 -1
  99. package/dist/lib/review-core.d.ts.map +1 -1
  100. package/dist/lib/review-core.js +22 -27
  101. package/dist/lib/review-core.js.map +1 -1
  102. package/dist/lib/review-core.test.js +37 -23
  103. package/dist/lib/review-core.test.js.map +1 -1
  104. package/dist/lib/review-orchestrator.d.ts.map +1 -1
  105. package/dist/lib/review-orchestrator.js +11 -8
  106. package/dist/lib/review-orchestrator.js.map +1 -1
  107. package/dist/lib/review-orchestrator.test.js +27 -6
  108. package/dist/lib/review-orchestrator.test.js.map +1 -1
  109. package/dist/lib/unified-review-executor.d.ts +0 -2
  110. package/dist/lib/unified-review-executor.d.ts.map +1 -1
  111. package/dist/lib/unified-review-executor.js +7 -13
  112. package/dist/lib/unified-review-executor.js.map +1 -1
  113. package/dist/lib/unified-review-executor.test.js +2 -2
  114. package/dist/lib/unified-review-executor.test.js.map +1 -1
  115. package/dist/pi/sdk.d.ts.map +1 -1
  116. package/dist/pi/sdk.js +36 -11
  117. package/dist/pi/sdk.js.map +1 -1
  118. package/dist/pi/sdk.test.js +48 -9
  119. package/dist/pi/sdk.test.js.map +1 -1
  120. package/dist/runtime/agent-loader.d.ts +10 -6
  121. package/dist/runtime/agent-loader.d.ts.map +1 -1
  122. package/dist/runtime/agent-loader.js +53 -27
  123. package/dist/runtime/agent-loader.js.map +1 -1
  124. package/dist/runtime/agent-loader.test.js +116 -119
  125. package/dist/runtime/agent-loader.test.js.map +1 -1
  126. package/dist/runtime/built-in-paths.d.ts +1 -0
  127. package/dist/runtime/built-in-paths.d.ts.map +1 -1
  128. package/dist/runtime/built-in-paths.js +7 -0
  129. package/dist/runtime/built-in-paths.js.map +1 -1
  130. package/dist/runtime/client.d.ts +12 -0
  131. package/dist/runtime/client.d.ts.map +1 -1
  132. package/dist/runtime/client.js +83 -58
  133. package/dist/runtime/client.js.map +1 -1
  134. package/dist/runtime/client.test.js +264 -15
  135. package/dist/runtime/client.test.js.map +1 -1
  136. package/dist/runtime/path-config.d.ts +2 -2
  137. package/dist/runtime/path-config.d.ts.map +1 -1
  138. package/dist/runtime/path-config.js +8 -8
  139. package/dist/runtime/path-config.js.map +1 -1
  140. package/dist/runtime/path-config.test.js +14 -14
  141. package/dist/runtime/path-config.test.js.map +1 -1
  142. package/package.json +3 -3
  143. package/.pi/agents/review/documentation.md +0 -56
  144. package/.pi/agents/review/performance.md +0 -53
  145. package/.pi/agents/review/quality.md +0 -59
  146. package/.pi/agents/review/security.md +0 -53
  147. package/.pi/agents/review/style.md +0 -132
  148. package/dist/cli/describe-mr.d.ts +0 -11
  149. package/dist/cli/describe-mr.d.ts.map +0 -1
  150. package/dist/cli/describe-mr.js +0 -134
  151. package/dist/cli/describe-mr.js.map +0 -1
  152. package/dist/cli/describe-pr.d.ts +0 -12
  153. package/dist/cli/describe-pr.d.ts.map +0 -1
  154. package/dist/cli/describe-pr.js +0 -135
  155. package/dist/cli/describe-pr.js.map +0 -1
  156. package/dist/cli/post-comments.d.ts +0 -20
  157. package/dist/cli/post-comments.d.ts.map +0 -1
  158. package/dist/cli/post-comments.js +0 -225
  159. package/dist/cli/post-comments.js.map +0 -1
  160. package/dist/cli/review-local.d.ts +0 -13
  161. package/dist/cli/review-local.d.ts.map +0 -1
  162. package/dist/cli/review-local.integration.test.d.ts +0 -2
  163. package/dist/cli/review-local.integration.test.d.ts.map +0 -1
  164. package/dist/cli/review-local.integration.test.js +0 -343
  165. package/dist/cli/review-local.integration.test.js.map +0 -1
  166. package/dist/cli/review-local.js +0 -90
  167. package/dist/cli/review-local.js.map +0 -1
  168. package/dist/cli/review-local.live.e2e.test.d.ts +0 -2
  169. package/dist/cli/review-local.live.e2e.test.d.ts.map +0 -1
  170. package/dist/cli/review-local.live.e2e.test.js +0 -153
  171. package/dist/cli/review-local.live.e2e.test.js.map +0 -1
  172. package/dist/cli/review-local.test.d.ts +0 -2
  173. package/dist/cli/review-local.test.d.ts.map +0 -1
  174. package/dist/cli/review-local.test.js +0 -164
  175. package/dist/cli/review-local.test.js.map +0 -1
  176. package/dist/cli/review-mr.d.ts +0 -22
  177. package/dist/cli/review-mr.d.ts.map +0 -1
  178. package/dist/cli/review-mr.js +0 -181
  179. package/dist/cli/review-mr.js.map +0 -1
  180. package/dist/cli/review-mr.test.d.ts +0 -2
  181. package/dist/cli/review-mr.test.d.ts.map +0 -1
  182. package/dist/cli/review-mr.test.js +0 -142
  183. package/dist/cli/review-mr.test.js.map +0 -1
  184. package/dist/cli/review-pr.d.ts +0 -22
  185. package/dist/cli/review-pr.d.ts.map +0 -1
  186. package/dist/cli/review-pr.js +0 -181
  187. package/dist/cli/review-pr.js.map +0 -1
  188. package/dist/cli/review-pr.test.d.ts +0 -2
  189. package/dist/cli/review-pr.test.d.ts.map +0 -1
  190. package/dist/cli/review-pr.test.js +0 -137
  191. package/dist/cli/review-pr.test.js.map +0 -1
  192. package/dist/cli/review-url.d.ts +0 -35
  193. package/dist/cli/review-url.d.ts.map +0 -1
  194. package/dist/cli/review-url.js +0 -110
  195. package/dist/cli/review-url.js.map +0 -1
  196. package/dist/cli/review-url.test.d.ts +0 -2
  197. package/dist/cli/review-url.test.d.ts.map +0 -1
  198. package/dist/cli/review-url.test.js +0 -132
  199. package/dist/cli/review-url.test.js.map +0 -1
  200. package/dist/cli/show-changes.d.ts +0 -15
  201. package/dist/cli/show-changes.d.ts.map +0 -1
  202. package/dist/cli/show-changes.js +0 -184
  203. package/dist/cli/show-changes.js.map +0 -1
@@ -1,3 +1,6 @@
1
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'fs';
2
+ import { tmpdir } from 'os';
3
+ import { join } from 'path';
1
4
  import { describe, it, expect } from 'vitest';
2
5
  import { loadConfig } from './config.js';
3
6
  describe('Config', () => {
@@ -15,10 +18,10 @@ describe('Config', () => {
15
18
  it('should override agents when explicitly provided', () => {
16
19
  const config = loadConfig(process.cwd(), {
17
20
  review: {
18
- agents: ['security'],
21
+ agents: ['review/security'],
19
22
  },
20
23
  });
21
- expect(config.review.agents).toEqual(['security']);
24
+ expect(config.review.agents).toEqual(['review/security']);
22
25
  });
23
26
  it('should load agents from config file when no override provided', () => {
24
27
  const config = loadConfig(process.cwd());
@@ -69,5 +72,282 @@ describe('Config', () => {
69
72
  output: 2,
70
73
  });
71
74
  });
75
+ it('loads built-in workflow files', () => {
76
+ const projectRoot = mkdtempSync(join(tmpdir(), 'drs-workflow-builtins-'));
77
+ try {
78
+ const config = loadConfig(projectRoot);
79
+ expect(config.workflows?.['local-review']).toMatchObject({
80
+ description: 'Review local unstaged git diff',
81
+ nodes: {
82
+ change: {
83
+ action: 'change-source',
84
+ },
85
+ review: {
86
+ action: 'review',
87
+ },
88
+ },
89
+ });
90
+ expect(config.workflows?.['gitlab-mr-review']?.inputs).toEqual({
91
+ project: '',
92
+ mr: '',
93
+ });
94
+ expect(config.workflows?.['github-pr-describe-post']).toMatchObject({
95
+ description: 'Generate and post a GitHub pull request description',
96
+ nodes: {
97
+ describe: {
98
+ action: 'describe',
99
+ with: {
100
+ post: true,
101
+ },
102
+ },
103
+ },
104
+ });
105
+ expect(config.workflows?.['gitlab-mr-describe']?.inputs).toEqual({
106
+ project: '',
107
+ mr: '',
108
+ });
109
+ expect(config.workflows?.['github-pr-post-comment']).toMatchObject({
110
+ description: 'Post or update a GitHub pull request comment',
111
+ nodes: {
112
+ comment: {
113
+ action: 'post-comment',
114
+ },
115
+ },
116
+ });
117
+ expect(config.workflows?.['local-changelog-update']).toMatchObject({
118
+ description: 'Update CHANGELOG.md from local unstaged changes',
119
+ nodes: {
120
+ 'update-changelog': {
121
+ agent: 'task/changelog-updater',
122
+ },
123
+ },
124
+ });
125
+ expect(config.workflows?.['local-fix-review-issues']).toMatchObject({
126
+ description: 'Fix actionable issues from a saved DRS review result',
127
+ inputs: {
128
+ review: '',
129
+ },
130
+ nodes: {
131
+ 'fix-issues': {
132
+ agent: 'task/review-issue-fixer',
133
+ },
134
+ review: {
135
+ action: 'review',
136
+ },
137
+ },
138
+ });
139
+ expect(config.workflows?.['local-update-agents-md']).toMatchObject({
140
+ description: 'Update repository agent guidance from local changes',
141
+ nodes: {
142
+ 'update-guidance': {
143
+ agent: 'task/agents-md-updater',
144
+ },
145
+ },
146
+ });
147
+ expect(config.workflows?.['tag-changelog-update']).toMatchObject({
148
+ description: 'Update CHANGELOG.md from changes between two git refs or tags',
149
+ inputs: {
150
+ from: '',
151
+ to: '',
152
+ },
153
+ nodes: {
154
+ 'release-change': {
155
+ action: 'change-source',
156
+ with: {
157
+ type: 'git-range',
158
+ },
159
+ },
160
+ 'update-changelog': {
161
+ agent: 'task/changelog-updater',
162
+ },
163
+ },
164
+ });
165
+ }
166
+ finally {
167
+ rmSync(projectRoot, { recursive: true, force: true });
168
+ }
169
+ });
170
+ it('loads project workflow files from .drs/workflows', () => {
171
+ const projectRoot = mkdtempSync(join(tmpdir(), 'drs-project-workflow-'));
172
+ try {
173
+ mkdirSync(join(projectRoot, '.drs', 'workflows'), { recursive: true });
174
+ writeFileSync(join(projectRoot, '.drs', 'workflows', 'release-notes.yaml'), [
175
+ 'description: Draft release notes',
176
+ 'nodes:',
177
+ ' write:',
178
+ ' action: write',
179
+ ' input: hello',
180
+ ' writes: RELEASE_NOTES.md',
181
+ '',
182
+ ].join('\n'));
183
+ const config = loadConfig(projectRoot);
184
+ expect(config.workflows?.['release-notes']).toMatchObject({
185
+ description: 'Draft release notes',
186
+ nodes: {
187
+ write: {
188
+ action: 'write',
189
+ writes: 'RELEASE_NOTES.md',
190
+ },
191
+ },
192
+ });
193
+ }
194
+ finally {
195
+ rmSync(projectRoot, { recursive: true, force: true });
196
+ }
197
+ });
198
+ it('lets project workflow files override built-in workflow files', () => {
199
+ const projectRoot = mkdtempSync(join(tmpdir(), 'drs-workflow-override-'));
200
+ try {
201
+ mkdirSync(join(projectRoot, '.drs', 'workflows'), { recursive: true });
202
+ writeFileSync(join(projectRoot, '.drs', 'workflows', 'local-review.yaml'), [
203
+ 'description: Project local review override',
204
+ 'nodes:',
205
+ ' write:',
206
+ ' action: write',
207
+ ' input: project',
208
+ ' writes: project.txt',
209
+ '',
210
+ ].join('\n'));
211
+ const config = loadConfig(projectRoot);
212
+ expect(config.workflows?.['local-review']).toMatchObject({
213
+ description: 'Project local review override',
214
+ nodes: {
215
+ write: {
216
+ action: 'write',
217
+ },
218
+ },
219
+ });
220
+ }
221
+ finally {
222
+ rmSync(projectRoot, { recursive: true, force: true });
223
+ }
224
+ });
225
+ it('rejects top-level workflows in drs.config.yaml', () => {
226
+ const projectRoot = mkdtempSync(join(tmpdir(), 'drs-workflow-config-'));
227
+ try {
228
+ mkdirSync(join(projectRoot, '.drs'), { recursive: true });
229
+ writeFileSync(join(projectRoot, '.drs', 'drs.config.yaml'), [
230
+ 'workflows:',
231
+ ' custom:',
232
+ ' description: Inline workflow',
233
+ ' nodes:',
234
+ ' write:',
235
+ ' action: write',
236
+ '',
237
+ ].join('\n'));
238
+ expect(() => loadConfig(projectRoot)).toThrow('cannot define top-level workflows');
239
+ }
240
+ finally {
241
+ rmSync(projectRoot, { recursive: true, force: true });
242
+ }
243
+ });
244
+ it('rejects workflow files that contain a workflows map', () => {
245
+ const projectRoot = mkdtempSync(join(tmpdir(), 'drs-workflow-map-'));
246
+ try {
247
+ mkdirSync(join(projectRoot, '.drs', 'workflows'), { recursive: true });
248
+ writeFileSync(join(projectRoot, '.drs', 'workflows', 'custom.yaml'), ['workflows:', ' custom:', ' nodes:', ' write:', ' action: write', ''].join('\n'));
249
+ expect(() => loadConfig(projectRoot)).toThrow('must define one workflow directly');
250
+ }
251
+ finally {
252
+ rmSync(projectRoot, { recursive: true, force: true });
253
+ }
254
+ });
255
+ it('loads workflow run defaults from drs.config.yaml', () => {
256
+ const projectRoot = mkdtempSync(join(tmpdir(), 'drs-workflow-default-'));
257
+ try {
258
+ mkdirSync(join(projectRoot, '.drs'), { recursive: true });
259
+ writeFileSync(join(projectRoot, '.drs', 'drs.config.yaml'), ['workflow:', ' default: local-changelog-review', ''].join('\n'));
260
+ const config = loadConfig(projectRoot);
261
+ expect(config.workflow?.default).toBe('local-changelog-review');
262
+ }
263
+ finally {
264
+ rmSync(projectRoot, { recursive: true, force: true });
265
+ }
266
+ });
267
+ it('uses DRS_DEFAULT_MODEL as the generic default model environment alias', () => {
268
+ const previous = process.env.DRS_DEFAULT_MODEL;
269
+ process.env.DRS_DEFAULT_MODEL = 'provider/env-default-model';
270
+ try {
271
+ const config = loadConfig(process.cwd());
272
+ expect(config.agents.default?.model).toBe('provider/env-default-model');
273
+ }
274
+ finally {
275
+ if (previous === undefined) {
276
+ delete process.env.DRS_DEFAULT_MODEL;
277
+ }
278
+ else {
279
+ process.env.DRS_DEFAULT_MODEL = previous;
280
+ }
281
+ }
282
+ });
283
+ it('merges pi runtime timeout and provider retry settings', () => {
284
+ const config = loadConfig(process.cwd(), {
285
+ pi: {
286
+ runtime: {
287
+ operationTimeoutMs: 111000,
288
+ streamTimeoutMs: 222000,
289
+ streamPollIntervalMs: 1500,
290
+ },
291
+ retry: {
292
+ provider: {
293
+ timeoutMs: 45000,
294
+ maxRetries: 2,
295
+ maxRetryDelayMs: 15000,
296
+ },
297
+ },
298
+ },
299
+ });
300
+ expect(config.pi.runtime).toEqual({
301
+ operationTimeoutMs: 111000,
302
+ streamTimeoutMs: 222000,
303
+ streamPollIntervalMs: 1500,
304
+ });
305
+ expect(config.pi.retry?.provider).toEqual({
306
+ timeoutMs: 45000,
307
+ maxRetries: 2,
308
+ maxRetryDelayMs: 15000,
309
+ });
310
+ });
311
+ it('rejects legacy review.default config with migration guidance', () => {
312
+ const projectRoot = mkdtempSync(join(tmpdir(), 'drs-legacy-config-'));
313
+ try {
314
+ mkdirSync(join(projectRoot, '.drs'), { recursive: true });
315
+ writeFileSync(join(projectRoot, '.drs', 'drs.config.yaml'), ['review:', ' default:', ' model: provider/legacy-model', ''].join('\n'));
316
+ expect(() => loadConfig(projectRoot)).toThrow('review.default -> agents.default');
317
+ }
318
+ finally {
319
+ rmSync(projectRoot, { recursive: true, force: true });
320
+ }
321
+ });
322
+ it('rejects legacy review.paths config with migration guidance', () => {
323
+ const projectRoot = mkdtempSync(join(tmpdir(), 'drs-legacy-paths-'));
324
+ try {
325
+ mkdirSync(join(projectRoot, '.drs'), { recursive: true });
326
+ writeFileSync(join(projectRoot, '.drs', 'drs.config.yaml'), ['review:', ' paths:', ' agents: custom/agents', ''].join('\n'));
327
+ expect(() => loadConfig(projectRoot)).toThrow('review.paths -> agents.paths');
328
+ }
329
+ finally {
330
+ rmSync(projectRoot, { recursive: true, force: true });
331
+ }
332
+ });
333
+ it('rejects removed implicit review posting config keys', () => {
334
+ const projectRoot = mkdtempSync(join(tmpdir(), 'drs-removed-posting-config-'));
335
+ try {
336
+ mkdirSync(join(projectRoot, '.drs'), { recursive: true });
337
+ writeFileSync(join(projectRoot, '.drs', 'drs.config.yaml'), [
338
+ 'review:',
339
+ ' postErrorComment: true',
340
+ ' describe:',
341
+ ' enabled: true',
342
+ ' postDescription: true',
343
+ '',
344
+ ].join('\n'));
345
+ expect(() => loadConfig(projectRoot)).toThrow('review.postErrorComment');
346
+ expect(() => loadConfig(projectRoot)).toThrow('review.describe.postDescription');
347
+ }
348
+ finally {
349
+ rmSync(projectRoot, { recursive: true, force: true });
350
+ }
351
+ });
72
352
  });
73
353
  //# sourceMappingURL=config.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/lib/config.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/lib/config.test.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,12 @@ import type { DRSConfig } from './config.js';
2
2
  export interface AgentContext {
3
3
  /**
4
4
  * Source of the agent definition
5
- * - 'override': Using .drs/agents/{name}/agent.md (full replacement)
5
+ * - 'override': Using .drs/agents/{namespace}/{name}/agent.md (full replacement)
6
6
  * - 'default': Using built-in agent
7
7
  */
8
8
  source: 'override' | 'default';
9
9
  /**
10
- * Agent-specific context from .drs/agents/{name}/context.md
10
+ * Agent-specific context from .drs/agents/{namespace}/{name}/context.md
11
11
  */
12
12
  agentContext?: string;
13
13
  /**
@@ -22,9 +22,9 @@ export declare function loadGlobalContext(projectRoot?: string): string | null;
22
22
  /**
23
23
  * Load agent-specific context and check for overrides
24
24
  */
25
- export declare function loadAgentContext(agentName: string, projectRoot?: string, config?: DRSConfig): AgentContext;
25
+ export declare function loadAgentContext(agentId: string, projectRoot?: string, config?: DRSConfig): AgentContext;
26
26
  /**
27
27
  * Build review prompt with global and agent-specific context
28
28
  */
29
- export declare function buildReviewPrompt(agentName: string, basePrompt: string, reviewLabel: string, changedFiles: string[], projectRoot?: string, config?: DRSConfig, describeSummary?: string): string;
29
+ export declare function buildReviewPrompt(agentId: string, basePrompt: string, reviewLabel: string, changedFiles: string[], projectRoot?: string, config?: DRSConfig, describeSummary?: string): string;
30
30
  //# sourceMappingURL=context-loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-loader.d.ts","sourceRoot":"","sources":["../../src/lib/context-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,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,EACnC,MAAM,CAAC,EAAE,SAAS,GACjB,YAAY,CA0Bd;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,EACnC,MAAM,CAAC,EAAE,SAAS,EAClB,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,CA6CR"}
1
+ {"version":3,"file":"context-loader.d.ts","sourceRoot":"","sources":["../../src/lib/context-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,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,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,MAAsB,EACnC,MAAM,CAAC,EAAE,SAAS,GACjB,YAAY,CA2Bd;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EAAE,EACtB,WAAW,GAAE,MAAsB,EACnC,MAAM,CAAC,EAAE,SAAS,EAClB,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,CA8CR"}
@@ -1,6 +1,7 @@
1
1
  import { existsSync, readFileSync } from 'fs';
2
2
  import { join } from 'path';
3
- import { resolveReviewPaths } from '../runtime/path-config.js';
3
+ import { requireAgentId } from './agent-id.js';
4
+ import { resolveAgentPaths } from '../runtime/path-config.js';
4
5
  /**
5
6
  * Load global project context from .drs/context.md
6
7
  */
@@ -14,9 +15,10 @@ export function loadGlobalContext(projectRoot = process.cwd()) {
14
15
  /**
15
16
  * Load agent-specific context and check for overrides
16
17
  */
17
- export function loadAgentContext(agentName, projectRoot = process.cwd(), config) {
18
- const { agentsPath } = resolveReviewPaths(projectRoot, config);
19
- const agentDir = join(agentsPath, agentName);
18
+ export function loadAgentContext(agentId, projectRoot = process.cwd(), config) {
19
+ const { namespace, name } = requireAgentId(agentId);
20
+ const { agentsPath } = resolveAgentPaths(projectRoot, config);
21
+ const agentDir = join(agentsPath, namespace, name);
20
22
  // Check for full agent override
21
23
  const agentDefPath = join(agentDir, 'agent.md');
22
24
  if (existsSync(agentDefPath)) {
@@ -41,9 +43,9 @@ export function loadAgentContext(agentName, projectRoot = process.cwd(), config)
41
43
  /**
42
44
  * Build review prompt with global and agent-specific context
43
45
  */
44
- export function buildReviewPrompt(agentName, basePrompt, reviewLabel, changedFiles, projectRoot = process.cwd(), config, describeSummary) {
46
+ export function buildReviewPrompt(agentId, basePrompt, reviewLabel, changedFiles, projectRoot = process.cwd(), config, describeSummary) {
45
47
  const globalContext = loadGlobalContext(projectRoot);
46
- const agentContext = loadAgentContext(agentName, projectRoot, config);
48
+ const agentContext = loadAgentContext(agentId, projectRoot, config);
47
49
  let prompt = '';
48
50
  // If agent is fully overridden, use that instead of base prompt
49
51
  if (agentContext.source === 'override' && agentContext.agentDefinition) {
@@ -71,7 +73,8 @@ export function buildReviewPrompt(agentName, basePrompt, reviewLabel, changedFil
71
73
  }
72
74
  // 2. Agent-specific context (if available)
73
75
  if (agentContext.agentContext) {
74
- prompt += `# ${agentName.charAt(0).toUpperCase() + agentName.slice(1)} Agent Context\n\n`;
76
+ const agentLabel = agentId.split('/').pop() ?? agentId;
77
+ prompt += `# ${agentLabel.charAt(0).toUpperCase() + agentLabel.slice(1)} Agent Context\n\n`;
75
78
  prompt += `${agentContext.agentContext}\n\n`;
76
79
  }
77
80
  // 3. Base agent instructions
@@ -1 +1 @@
1
- {"version":3,"file":"context-loader.js","sourceRoot":"","sources":["../../src/lib/context-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context-loader.js","sourceRoot":"","sources":["../../src/lib/context-loader.ts"],"names":[],"mappings":"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"}
@@ -40,12 +40,12 @@ describe('context-loader', () => {
40
40
  return path.toString().includes('agent.md');
41
41
  });
42
42
  vi.mocked(readFileSync).mockReturnValue('# Custom Agent\n\nCustom agent definition');
43
- const result = loadAgentContext('security', '/test/project');
43
+ const result = loadAgentContext('review/security', '/test/project');
44
44
  expect(result).toEqual({
45
45
  source: 'override',
46
46
  agentDefinition: '# Custom Agent\n\nCustom agent definition',
47
47
  });
48
- expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/security/agent.md');
48
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/review/security/agent.md');
49
49
  });
50
50
  it('should load agent context when context.md exists but not agent.md', () => {
51
51
  // Mock only context.md exists
@@ -53,28 +53,32 @@ describe('context-loader', () => {
53
53
  return path.toString().includes('context.md') && !path.toString().includes('agent.md');
54
54
  });
55
55
  vi.mocked(readFileSync).mockReturnValue('Agent-specific context');
56
- const result = loadAgentContext('quality', '/test/project');
56
+ const result = loadAgentContext('review/quality', '/test/project');
57
57
  expect(result).toEqual({
58
58
  source: 'default',
59
59
  agentContext: 'Agent-specific context',
60
60
  });
61
- expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/quality/agent.md');
62
- expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/quality/context.md');
61
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/review/quality/agent.md');
62
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/review/quality/context.md');
63
63
  });
64
64
  it('should return default when no customization exists', () => {
65
65
  vi.mocked(existsSync).mockReturnValue(false);
66
- const result = loadAgentContext('style', '/test/project');
66
+ const result = loadAgentContext('review/style', '/test/project');
67
67
  expect(result).toEqual({
68
68
  source: 'default',
69
69
  });
70
- expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/style/agent.md');
71
- expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/style/context.md');
70
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/review/style/agent.md');
71
+ expect(existsSync).toHaveBeenCalledWith('/test/project/.drs/agents/review/style/context.md');
72
72
  });
73
73
  it('should use process.cwd() as default project root', () => {
74
74
  vi.mocked(existsSync).mockReturnValue(false);
75
75
  const originalCwd = process.cwd();
76
- loadAgentContext('security');
77
- expect(existsSync).toHaveBeenCalledWith(`${originalCwd}/.drs/agents/security/agent.md`);
76
+ loadAgentContext('review/security');
77
+ expect(existsSync).toHaveBeenCalledWith(`${originalCwd}/.drs/agents/review/security/agent.md`);
78
+ });
79
+ it('rejects unsafe agent ids before building filesystem paths', () => {
80
+ expect(() => loadAgentContext('review/..', '/test/project')).toThrow('path components');
81
+ expect(existsSync).not.toHaveBeenCalled();
78
82
  });
79
83
  });
80
84
  describe('buildReviewPrompt', () => {
@@ -84,7 +88,7 @@ describe('context-loader', () => {
84
88
  return path.toString().includes('agent.md');
85
89
  });
86
90
  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');
91
+ const result = buildReviewPrompt('review/security', 'Default base prompt', 'PR #123', ['src/app.ts', 'src/utils.ts'], '/test/project');
88
92
  expect(result).toContain('# Custom Security Agent');
89
93
  expect(result).toContain('Custom instructions');
90
94
  expect(result).toContain('Review the following files from PR #123');
@@ -104,7 +108,7 @@ describe('context-loader', () => {
104
108
  }
105
109
  return '';
106
110
  });
107
- const result = buildReviewPrompt('quality', 'Review code quality', 'MR !456', ['lib/index.ts'], '/test/project');
111
+ const result = buildReviewPrompt('review/quality', 'Review code quality', 'MR !456', ['lib/index.ts'], '/test/project');
108
112
  expect(result).toContain('# Project Context');
109
113
  expect(result).toContain('This is our project');
110
114
  expect(result).toContain('Review code quality');
@@ -114,7 +118,7 @@ describe('context-loader', () => {
114
118
  return path.toString().includes('.drs/context.md');
115
119
  });
116
120
  vi.mocked(readFileSync).mockReturnValue('Just some context without header');
117
- const result = buildReviewPrompt('security', 'Base instructions', 'PR #1', ['file.ts'], '/test/project');
121
+ const result = buildReviewPrompt('review/security', 'Base instructions', 'PR #1', ['file.ts'], '/test/project');
118
122
  expect(result).toContain('# Project Context\n\nJust some context without header');
119
123
  });
120
124
  it('should not duplicate Project Context header when already present', () => {
@@ -122,7 +126,7 @@ describe('context-loader', () => {
122
126
  return path.toString().includes('.drs/context.md');
123
127
  });
124
128
  vi.mocked(readFileSync).mockReturnValue('# Project Context\n\nAlready has header');
125
- const result = buildReviewPrompt('security', 'Base instructions', 'PR #1', ['file.ts'], '/test/project');
129
+ const result = buildReviewPrompt('review/security', 'Base instructions', 'PR #1', ['file.ts'], '/test/project');
126
130
  // Should not have double "# Project Context"
127
131
  const matches = result.match(/# Project Context/g);
128
132
  expect(matches).toHaveLength(1);
@@ -131,38 +135,39 @@ describe('context-loader', () => {
131
135
  // Mock agent context exists
132
136
  vi.mocked(existsSync).mockImplementation((path) => {
133
137
  const pathStr = path.toString();
134
- return pathStr.includes('agents/security/context.md');
138
+ return pathStr.includes('agents/review/security/context.md');
135
139
  });
136
140
  vi.mocked(readFileSync).mockReturnValue('Focus on authentication and authorization');
137
- const result = buildReviewPrompt('security', 'Base security review', 'PR #2', ['auth.ts'], '/test/project');
141
+ const result = buildReviewPrompt('review/security', 'Base security review', 'PR #2', ['auth.ts'], '/test/project');
138
142
  expect(result).toContain('# Security Agent Context');
139
143
  expect(result).toContain('Focus on authentication and authorization');
140
144
  expect(result).toContain('Base security review');
141
145
  });
142
146
  it('should capitalize agent name in agent context header', () => {
143
147
  vi.mocked(existsSync).mockImplementation((path) => {
144
- return path.toString().includes('agents/quality/context.md');
148
+ return path.toString().includes('agents/review/quality/context.md');
145
149
  });
146
150
  vi.mocked(readFileSync).mockReturnValue('Quality context');
147
- const result = buildReviewPrompt('quality', 'Base prompt', 'PR #3', ['file.ts'], '/test/project');
151
+ const result = buildReviewPrompt('review/quality', 'Base prompt', 'PR #3', ['file.ts'], '/test/project');
148
152
  expect(result).toContain('# Quality Agent Context');
149
153
  });
150
154
  it('should build prompt with all contexts (global + agent + base)', () => {
151
155
  // Mock both global and agent context
152
156
  vi.mocked(existsSync).mockImplementation((path) => {
153
157
  const pathStr = path.toString();
154
- return (pathStr.includes('.drs/context.md') || pathStr.includes('agents/security/context.md'));
158
+ return (pathStr.includes('.drs/context.md') ||
159
+ pathStr.includes('agents/review/security/context.md'));
155
160
  });
156
161
  vi.mocked(readFileSync).mockImplementation((path) => {
157
162
  if (path.toString().includes('.drs/context.md')) {
158
163
  return 'Global project context';
159
164
  }
160
- if (path.toString().includes('agents/security/context.md')) {
165
+ if (path.toString().includes('agents/review/security/context.md')) {
161
166
  return 'Security-specific context';
162
167
  }
163
168
  return '';
164
169
  });
165
- const result = buildReviewPrompt('security', 'Base security instructions', 'PR #4', ['auth.ts'], '/test/project');
170
+ const result = buildReviewPrompt('review/security', 'Base security instructions', 'PR #4', ['auth.ts'], '/test/project');
166
171
  expect(result).toContain('Global project context');
167
172
  expect(result).toContain('Security-specific context');
168
173
  expect(result).toContain('Base security instructions');
@@ -172,23 +177,23 @@ describe('context-loader', () => {
172
177
  return path.toString().includes('agent.md');
173
178
  });
174
179
  vi.mocked(readFileSync).mockReturnValue('Custom agent');
175
- const result = buildReviewPrompt('security', 'Base prompt', 'PR #5', [], '/test/project');
180
+ const result = buildReviewPrompt('review/security', 'Base prompt', 'PR #5', [], '/test/project');
176
181
  expect(result).toContain('Review the following files from PR #5');
177
182
  // Should still work with no files listed
178
183
  });
179
184
  it('should use process.cwd() as default project root', () => {
180
185
  vi.mocked(existsSync).mockReturnValue(false);
181
186
  const originalCwd = process.cwd();
182
- buildReviewPrompt('security', 'Base prompt', 'PR #1', ['file.ts']);
187
+ buildReviewPrompt('review/security', 'Base prompt', 'PR #1', ['file.ts']);
183
188
  expect(existsSync).toHaveBeenCalledWith(`${originalCwd}/.drs/context.md`);
184
- expect(existsSync).toHaveBeenCalledWith(`${originalCwd}/.drs/agents/security/agent.md`);
189
+ expect(existsSync).toHaveBeenCalledWith(`${originalCwd}/.drs/agents/review/security/agent.md`);
185
190
  });
186
191
  it('should handle whitespace-only global context', () => {
187
192
  vi.mocked(existsSync).mockImplementation((path) => {
188
193
  return path.toString().includes('.drs/context.md');
189
194
  });
190
195
  vi.mocked(readFileSync).mockReturnValue(' \n\n ');
191
- const result = buildReviewPrompt('security', 'Base prompt', 'PR #1', ['file.ts'], '/test/project');
196
+ const result = buildReviewPrompt('review/security', 'Base prompt', 'PR #1', ['file.ts'], '/test/project');
192
197
  // Whitespace is preserved and wrapped with header
193
198
  expect(result).toContain('# Project Context');
194
199
  expect(result).toContain('Base prompt');
@@ -198,7 +203,7 @@ describe('context-loader', () => {
198
203
  return path.toString().includes('.drs/context.md');
199
204
  });
200
205
  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');
206
+ const result = buildReviewPrompt('review/security', 'Base prompt', 'PR #1', ['file.ts'], '/test/project');
202
207
  expect(result).toContain('# Project Context\n\nContent here');
203
208
  expect(result).not.toMatch(/^\n+/); // Should not start with newlines
204
209
  });