@diff-review-system/drs 3.3.0 → 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.
- package/.pi/agents/task/agents-md-updater.md +24 -0
- package/.pi/agents/task/changelog-updater.md +29 -0
- package/.pi/agents/task/review-issue-fixer.md +25 -0
- package/.pi/workflows/github-pr-describe-post.yaml +24 -0
- package/.pi/workflows/github-pr-describe.yaml +23 -0
- package/.pi/workflows/github-pr-post-comment.yaml +19 -0
- package/.pi/workflows/github-pr-review-post.yaml +32 -0
- package/.pi/workflows/github-pr-review.yaml +23 -0
- package/.pi/workflows/github-pr-show-changes.yaml +25 -0
- package/.pi/workflows/gitlab-mr-describe-post.yaml +22 -0
- package/.pi/workflows/gitlab-mr-describe.yaml +21 -0
- package/.pi/workflows/gitlab-mr-post-comment.yaml +17 -0
- package/.pi/workflows/gitlab-mr-review-code-quality.yaml +31 -0
- package/.pi/workflows/gitlab-mr-review-post-code-quality.yaml +40 -0
- package/.pi/workflows/gitlab-mr-review-post.yaml +30 -0
- package/.pi/workflows/gitlab-mr-review.yaml +21 -0
- package/.pi/workflows/gitlab-mr-show-changes.yaml +23 -0
- package/.pi/workflows/local-changelog-update.yaml +23 -0
- package/.pi/workflows/local-fix-review-issues.yaml +42 -0
- package/.pi/workflows/local-review.yaml +17 -0
- package/.pi/workflows/local-staged-review.yaml +17 -0
- package/.pi/workflows/local-update-agents-md.yaml +24 -0
- package/.pi/workflows/tag-changelog-update.yaml +26 -0
- package/README.md +215 -106
- package/dist/ci/runner.d.ts.map +1 -1
- package/dist/ci/runner.js +7 -8
- package/dist/ci/runner.js.map +1 -1
- package/dist/cli/index.js +69 -341
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +25 -23
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/run-agent.d.ts +24 -0
- package/dist/cli/run-agent.d.ts.map +1 -0
- package/dist/cli/run-agent.js +139 -0
- package/dist/cli/run-agent.js.map +1 -0
- package/dist/cli/run-agent.test.d.ts +2 -0
- package/dist/cli/run-agent.test.d.ts.map +1 -0
- package/dist/cli/run-agent.test.js +204 -0
- package/dist/cli/run-agent.test.js.map +1 -0
- package/dist/cli/workflow.d.ts +51 -0
- package/dist/cli/workflow.d.ts.map +1 -0
- package/dist/cli/workflow.js +1229 -0
- package/dist/cli/workflow.js.map +1 -0
- package/dist/cli/workflow.test.d.ts +2 -0
- package/dist/cli/workflow.test.d.ts.map +1 -0
- package/dist/cli/workflow.test.js +1410 -0
- package/dist/cli/workflow.test.js.map +1 -0
- package/dist/lib/agent-id.d.ts +9 -0
- package/dist/lib/agent-id.d.ts.map +1 -0
- package/dist/lib/agent-id.js +32 -0
- package/dist/lib/agent-id.js.map +1 -0
- package/dist/lib/comment-formatter.d.ts +7 -1
- package/dist/lib/comment-formatter.d.ts.map +1 -1
- package/dist/lib/comment-formatter.js +42 -1
- package/dist/lib/comment-formatter.js.map +1 -1
- package/dist/lib/comment-formatter.test.js +33 -0
- package/dist/lib/comment-formatter.test.js.map +1 -1
- package/dist/lib/comment-manager.d.ts +4 -0
- package/dist/lib/comment-manager.d.ts.map +1 -1
- package/dist/lib/comment-manager.js +7 -1
- package/dist/lib/comment-manager.js.map +1 -1
- package/dist/lib/comment-poster.d.ts +2 -2
- package/dist/lib/comment-poster.d.ts.map +1 -1
- package/dist/lib/comment-poster.js +3 -3
- package/dist/lib/comment-poster.js.map +1 -1
- package/dist/lib/comment-poster.test.js +13 -3
- package/dist/lib/comment-poster.test.js.map +1 -1
- package/dist/lib/config-model-overrides.test.d.ts +0 -10
- package/dist/lib/config-model-overrides.test.d.ts.map +1 -1
- package/dist/lib/config-model-overrides.test.js +174 -210
- package/dist/lib/config-model-overrides.test.js.map +1 -1
- package/dist/lib/config.d.ts +111 -34
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +322 -83
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.js +282 -2
- package/dist/lib/config.test.js.map +1 -1
- package/dist/lib/context-loader.d.ts +4 -4
- package/dist/lib/context-loader.d.ts.map +1 -1
- package/dist/lib/context-loader.js +10 -7
- package/dist/lib/context-loader.js.map +1 -1
- package/dist/lib/context-loader.test.js +31 -26
- package/dist/lib/context-loader.test.js.map +1 -1
- package/dist/lib/description-executor.js +1 -1
- package/dist/lib/description-executor.js.map +1 -1
- package/dist/lib/description-executor.test.js +10 -3
- package/dist/lib/description-executor.test.js.map +1 -1
- package/dist/lib/diff-lines.d.ts +9 -0
- package/dist/lib/diff-lines.d.ts.map +1 -0
- package/dist/lib/diff-lines.js +32 -0
- package/dist/lib/diff-lines.js.map +1 -0
- package/dist/lib/diff-lines.test.d.ts +2 -0
- package/dist/lib/diff-lines.test.d.ts.map +1 -0
- package/dist/lib/diff-lines.test.js +13 -0
- package/dist/lib/diff-lines.test.js.map +1 -0
- package/dist/lib/logger.d.ts +1 -1
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/review-core.d.ts.map +1 -1
- package/dist/lib/review-core.js +22 -27
- package/dist/lib/review-core.js.map +1 -1
- package/dist/lib/review-core.test.js +37 -23
- package/dist/lib/review-core.test.js.map +1 -1
- package/dist/lib/review-orchestrator.d.ts.map +1 -1
- package/dist/lib/review-orchestrator.js +11 -8
- package/dist/lib/review-orchestrator.js.map +1 -1
- package/dist/lib/review-orchestrator.test.js +27 -6
- package/dist/lib/review-orchestrator.test.js.map +1 -1
- package/dist/lib/unified-review-executor.d.ts +0 -2
- package/dist/lib/unified-review-executor.d.ts.map +1 -1
- package/dist/lib/unified-review-executor.js +7 -13
- package/dist/lib/unified-review-executor.js.map +1 -1
- package/dist/lib/unified-review-executor.test.js +2 -2
- package/dist/lib/unified-review-executor.test.js.map +1 -1
- package/dist/pi/sdk.d.ts.map +1 -1
- package/dist/pi/sdk.js +37 -12
- package/dist/pi/sdk.js.map +1 -1
- package/dist/pi/sdk.test.js +83 -10
- package/dist/pi/sdk.test.js.map +1 -1
- package/dist/runtime/agent-loader.d.ts +10 -6
- package/dist/runtime/agent-loader.d.ts.map +1 -1
- package/dist/runtime/agent-loader.js +53 -27
- package/dist/runtime/agent-loader.js.map +1 -1
- package/dist/runtime/agent-loader.test.js +116 -119
- package/dist/runtime/agent-loader.test.js.map +1 -1
- package/dist/runtime/built-in-paths.d.ts +1 -0
- package/dist/runtime/built-in-paths.d.ts.map +1 -1
- package/dist/runtime/built-in-paths.js +7 -0
- package/dist/runtime/built-in-paths.js.map +1 -1
- package/dist/runtime/client.d.ts +12 -0
- package/dist/runtime/client.d.ts.map +1 -1
- package/dist/runtime/client.js +83 -58
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/client.test.js +264 -15
- package/dist/runtime/client.test.js.map +1 -1
- package/dist/runtime/path-config.d.ts +2 -2
- package/dist/runtime/path-config.d.ts.map +1 -1
- package/dist/runtime/path-config.js +8 -8
- package/dist/runtime/path-config.js.map +1 -1
- package/dist/runtime/path-config.test.js +14 -14
- package/dist/runtime/path-config.test.js.map +1 -1
- package/package.json +3 -4
- package/.pi/agents/review/documentation.md +0 -56
- package/.pi/agents/review/performance.md +0 -53
- package/.pi/agents/review/quality.md +0 -59
- package/.pi/agents/review/security.md +0 -53
- package/.pi/agents/review/style.md +0 -132
- package/dist/cli/describe-mr.d.ts +0 -11
- package/dist/cli/describe-mr.d.ts.map +0 -1
- package/dist/cli/describe-mr.js +0 -134
- package/dist/cli/describe-mr.js.map +0 -1
- package/dist/cli/describe-pr.d.ts +0 -12
- package/dist/cli/describe-pr.d.ts.map +0 -1
- package/dist/cli/describe-pr.js +0 -135
- package/dist/cli/describe-pr.js.map +0 -1
- package/dist/cli/post-comments.d.ts +0 -20
- package/dist/cli/post-comments.d.ts.map +0 -1
- package/dist/cli/post-comments.js +0 -225
- package/dist/cli/post-comments.js.map +0 -1
- package/dist/cli/review-local.d.ts +0 -13
- package/dist/cli/review-local.d.ts.map +0 -1
- package/dist/cli/review-local.integration.test.d.ts +0 -2
- package/dist/cli/review-local.integration.test.d.ts.map +0 -1
- package/dist/cli/review-local.integration.test.js +0 -343
- package/dist/cli/review-local.integration.test.js.map +0 -1
- package/dist/cli/review-local.js +0 -90
- package/dist/cli/review-local.js.map +0 -1
- package/dist/cli/review-local.live.e2e.test.d.ts +0 -2
- package/dist/cli/review-local.live.e2e.test.d.ts.map +0 -1
- package/dist/cli/review-local.live.e2e.test.js +0 -153
- package/dist/cli/review-local.live.e2e.test.js.map +0 -1
- package/dist/cli/review-local.test.d.ts +0 -2
- package/dist/cli/review-local.test.d.ts.map +0 -1
- package/dist/cli/review-local.test.js +0 -164
- package/dist/cli/review-local.test.js.map +0 -1
- package/dist/cli/review-mr.d.ts +0 -22
- package/dist/cli/review-mr.d.ts.map +0 -1
- package/dist/cli/review-mr.js +0 -181
- package/dist/cli/review-mr.js.map +0 -1
- package/dist/cli/review-mr.test.d.ts +0 -2
- package/dist/cli/review-mr.test.d.ts.map +0 -1
- package/dist/cli/review-mr.test.js +0 -142
- package/dist/cli/review-mr.test.js.map +0 -1
- package/dist/cli/review-pr.d.ts +0 -22
- package/dist/cli/review-pr.d.ts.map +0 -1
- package/dist/cli/review-pr.js +0 -181
- package/dist/cli/review-pr.js.map +0 -1
- package/dist/cli/review-pr.test.d.ts +0 -2
- package/dist/cli/review-pr.test.d.ts.map +0 -1
- package/dist/cli/review-pr.test.js +0 -137
- package/dist/cli/review-pr.test.js.map +0 -1
- package/dist/cli/review-url.d.ts +0 -35
- package/dist/cli/review-url.d.ts.map +0 -1
- package/dist/cli/review-url.js +0 -110
- package/dist/cli/review-url.js.map +0 -1
- package/dist/cli/review-url.test.d.ts +0 -2
- package/dist/cli/review-url.test.d.ts.map +0 -1
- package/dist/cli/review-url.test.js +0 -132
- package/dist/cli/review-url.test.js.map +0 -1
- package/dist/cli/show-changes.d.ts +0 -15
- package/dist/cli/show-changes.d.ts.map +0 -1
- package/dist/cli/show-changes.js +0 -184
- package/dist/cli/show-changes.js.map +0 -1
package/dist/lib/config.test.js
CHANGED
|
@@ -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":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;YACvC,MAAM,EAAE;gBACN,MAAM,EAAE,SAAS;aAClB;SACK,CAAC,CAAC;QAEV,2DAA2D;QAC3D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;YACvC,MAAM,EAAE;gBACN,MAAM,EAAE,CAAC,UAAU,CAAC;aACd;SACT,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAEzC,2EAA2E;QAC3E,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAEvD,4EAA4E;QAC5E,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACrC,MAAM,OAAO,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC;YAC5F,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;YACvC,MAAM,EAAE;gBACN,aAAa,EAAE,IAAI;aACb;SACT,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;YACvC,MAAM,EAAE;gBACN,eAAe,EAAE,IAAI;aACf;SACT,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAEzC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,aAAa,EAAE,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,aAAa,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;YACvC,OAAO,EAAE;gBACP,MAAM,EAAE;oBACN,qBAAqB,EAAE;wBACrB,KAAK,EAAE,CAAC;wBACR,MAAM,EAAE,CAAC;qBACV;iBACF;aACF;SACK,CAAC,CAAC;QAEV,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9D,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;SACV,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
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(
|
|
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(
|
|
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;
|
|
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 {
|
|
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(
|
|
18
|
-
const {
|
|
19
|
-
const
|
|
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(
|
|
46
|
+
export function buildReviewPrompt(agentId, basePrompt, reviewLabel, changedFiles, projectRoot = process.cwd(), config, describeSummary) {
|
|
45
47
|
const globalContext = loadGlobalContext(projectRoot);
|
|
46
|
-
const agentContext = loadAgentContext(
|
|
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
|
-
|
|
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":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,
|
|
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') ||
|
|
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
|
});
|