@diff-review-system/drs 1.1.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/agent/describe/pr-describer.md +221 -0
- package/.opencode/agent/review/documentation.md +56 -0
- package/.opencode/agent/review/performance.md +32 -139
- package/.opencode/agent/review/quality.md +36 -113
- package/.opencode/agent/review/security.md +32 -97
- package/.opencode/agent/review/style.md +4 -0
- package/.opencode/agent/review/unified-reviewer.md +74 -0
- package/.opencode/opencode.jsonc +4 -29
- package/.opencode/tool/write_json_output.ts +24 -0
- package/README.md +48 -21
- package/dist/ci/runner.d.ts.map +1 -1
- package/dist/ci/runner.js +2 -0
- package/dist/ci/runner.js.map +1 -1
- package/dist/cli/describe-mr.d.ts +11 -0
- package/dist/cli/describe-mr.d.ts.map +1 -0
- package/dist/cli/describe-mr.js +104 -0
- package/dist/cli/describe-mr.js.map +1 -0
- package/dist/cli/describe-pr.d.ts +12 -0
- package/dist/cli/describe-pr.d.ts.map +1 -0
- package/dist/cli/describe-pr.js +105 -0
- package/dist/cli/describe-pr.js.map +1 -0
- package/dist/cli/index.js +220 -16
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +273 -145
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/post-comments.d.ts +15 -0
- package/dist/cli/post-comments.d.ts.map +1 -0
- package/dist/cli/post-comments.js +216 -0
- package/dist/cli/post-comments.js.map +1 -0
- package/dist/cli/review-local.d.ts +3 -0
- package/dist/cli/review-local.d.ts.map +1 -1
- package/dist/cli/review-local.js +44 -18
- package/dist/cli/review-local.js.map +1 -1
- package/dist/cli/review-mr.d.ts +6 -0
- package/dist/cli/review-mr.d.ts.map +1 -1
- package/dist/cli/review-mr.js +63 -7
- package/dist/cli/review-mr.js.map +1 -1
- package/dist/cli/review-pr.d.ts +6 -0
- package/dist/cli/review-pr.d.ts.map +1 -1
- package/dist/cli/review-pr.js +8 -1
- package/dist/cli/review-pr.js.map +1 -1
- package/dist/cli/show-changes.d.ts +15 -0
- package/dist/cli/show-changes.d.ts.map +1 -0
- package/dist/cli/show-changes.js +184 -0
- package/dist/cli/show-changes.js.map +1 -0
- package/dist/github/platform-adapter.d.ts.map +1 -1
- package/dist/github/platform-adapter.js +4 -2
- package/dist/github/platform-adapter.js.map +1 -1
- package/dist/gitlab/client.d.ts.map +1 -1
- package/dist/gitlab/client.js +1 -1
- package/dist/gitlab/client.js.map +1 -1
- package/dist/gitlab/platform-adapter.d.ts.map +1 -1
- package/dist/gitlab/platform-adapter.js +6 -5
- package/dist/gitlab/platform-adapter.js.map +1 -1
- package/dist/lib/change-summary.d.ts +8 -0
- package/dist/lib/change-summary.d.ts.map +1 -0
- package/dist/lib/change-summary.js +2 -0
- package/dist/lib/change-summary.js.map +1 -0
- package/dist/lib/comment-formatter.d.ts +3 -2
- package/dist/lib/comment-formatter.d.ts.map +1 -1
- package/dist/lib/comment-formatter.js +16 -2
- package/dist/lib/comment-formatter.js.map +1 -1
- package/dist/lib/comment-formatter.test.d.ts +2 -0
- package/dist/lib/comment-formatter.test.d.ts.map +1 -0
- package/dist/lib/comment-formatter.test.js +607 -0
- package/dist/lib/comment-formatter.test.js.map +1 -0
- package/dist/lib/comment-manager.test.d.ts +2 -0
- package/dist/lib/comment-manager.test.d.ts.map +1 -0
- package/dist/lib/comment-manager.test.js +618 -0
- package/dist/lib/comment-manager.test.js.map +1 -0
- package/dist/lib/comment-poster.d.ts +21 -0
- package/dist/lib/comment-poster.d.ts.map +1 -0
- package/dist/lib/comment-poster.js +96 -0
- package/dist/lib/comment-poster.js.map +1 -0
- package/dist/lib/comment-poster.test.d.ts +5 -0
- package/dist/lib/comment-poster.test.d.ts.map +1 -0
- package/dist/lib/comment-poster.test.js +215 -0
- package/dist/lib/comment-poster.test.js.map +1 -0
- package/dist/lib/config-model-overrides.test.js +71 -41
- package/dist/lib/config-model-overrides.test.js.map +1 -1
- package/dist/lib/config.d.ts +63 -7
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +116 -22
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.js +10 -2
- package/dist/lib/config.test.js.map +1 -1
- package/dist/lib/context-compression.d.ts +19 -0
- package/dist/lib/context-compression.d.ts.map +1 -0
- package/dist/lib/context-compression.js +170 -0
- package/dist/lib/context-compression.js.map +1 -0
- package/dist/lib/context-compression.test.d.ts +2 -0
- package/dist/lib/context-compression.test.d.ts.map +1 -0
- package/dist/lib/context-compression.test.js +33 -0
- package/dist/lib/context-compression.test.js.map +1 -0
- package/dist/lib/context-loader.d.ts.map +1 -1
- package/dist/lib/context-loader.js +8 -1
- package/dist/lib/context-loader.js.map +1 -1
- package/dist/lib/context-loader.test.d.ts +2 -0
- package/dist/lib/context-loader.test.d.ts.map +1 -0
- package/dist/lib/context-loader.test.js +207 -0
- package/dist/lib/context-loader.test.js.map +1 -0
- package/dist/lib/describe-core.d.ts +9 -0
- package/dist/lib/describe-core.d.ts.map +1 -0
- package/dist/lib/describe-core.js +71 -0
- package/dist/lib/describe-core.js.map +1 -0
- package/dist/lib/describe-core.test.d.ts +2 -0
- package/dist/lib/describe-core.test.d.ts.map +1 -0
- package/dist/lib/describe-core.test.js +208 -0
- package/dist/lib/describe-core.test.js.map +1 -0
- package/dist/lib/describe-output-path.test.d.ts +2 -0
- package/dist/lib/describe-output-path.test.d.ts.map +1 -0
- package/dist/lib/describe-output-path.test.js +51 -0
- package/dist/lib/describe-output-path.test.js.map +1 -0
- package/dist/lib/describe-parser.d.ts +3 -0
- package/dist/lib/describe-parser.d.ts.map +1 -0
- package/dist/lib/describe-parser.js +163 -0
- package/dist/lib/describe-parser.js.map +1 -0
- package/dist/lib/describe-parser.test.d.ts +2 -0
- package/dist/lib/describe-parser.test.d.ts.map +1 -0
- package/dist/lib/describe-parser.test.js +282 -0
- package/dist/lib/describe-parser.test.js.map +1 -0
- package/dist/lib/description-executor.d.ts +22 -0
- package/dist/lib/description-executor.d.ts.map +1 -0
- package/dist/lib/description-executor.js +72 -0
- package/dist/lib/description-executor.js.map +1 -0
- package/dist/lib/description-formatter.d.ts +37 -0
- package/dist/lib/description-formatter.d.ts.map +1 -0
- package/dist/lib/description-formatter.js +219 -0
- package/dist/lib/description-formatter.js.map +1 -0
- package/dist/lib/diff-parser.d.ts +11 -0
- package/dist/lib/diff-parser.d.ts.map +1 -1
- package/dist/lib/diff-parser.js +37 -0
- package/dist/lib/diff-parser.js.map +1 -1
- package/dist/lib/issue-parser.d.ts +1 -1
- package/dist/lib/issue-parser.d.ts.map +1 -1
- package/dist/lib/issue-parser.js +16 -14
- package/dist/lib/issue-parser.js.map +1 -1
- package/dist/lib/json-output-schema.d.ts +207 -0
- package/dist/lib/json-output-schema.d.ts.map +1 -0
- package/dist/lib/json-output-schema.js +124 -0
- package/dist/lib/json-output-schema.js.map +1 -0
- package/dist/lib/json-output-schema.test.d.ts +2 -0
- package/dist/lib/json-output-schema.test.d.ts.map +1 -0
- package/dist/lib/json-output-schema.test.js +92 -0
- package/dist/lib/json-output-schema.test.js.map +1 -0
- package/dist/lib/json-output.d.ts +43 -0
- package/dist/lib/json-output.d.ts.map +1 -0
- package/dist/lib/json-output.js +34 -0
- package/dist/lib/json-output.js.map +1 -0
- package/dist/lib/output-paths.d.ts +6 -0
- package/dist/lib/output-paths.d.ts.map +1 -0
- package/dist/lib/output-paths.js +5 -0
- package/dist/lib/output-paths.js.map +1 -0
- package/dist/lib/platform-client.d.ts +1 -1
- package/dist/lib/platform-client.d.ts.map +1 -1
- package/dist/lib/repository-validator.d.ts +52 -0
- package/dist/lib/repository-validator.d.ts.map +1 -0
- package/dist/lib/repository-validator.js +219 -0
- package/dist/lib/repository-validator.js.map +1 -0
- package/dist/lib/repository-validator.test.d.ts +5 -0
- package/dist/lib/repository-validator.test.d.ts.map +1 -0
- package/dist/lib/repository-validator.test.js +341 -0
- package/dist/lib/repository-validator.test.js.map +1 -0
- package/dist/lib/review-core.d.ts +66 -0
- package/dist/lib/review-core.d.ts.map +1 -0
- package/dist/lib/review-core.js +449 -0
- package/dist/lib/review-core.js.map +1 -0
- package/dist/lib/review-core.test.d.ts +2 -0
- package/dist/lib/review-core.test.d.ts.map +1 -0
- package/dist/lib/review-core.test.js +552 -0
- package/dist/lib/review-core.test.js.map +1 -0
- package/dist/lib/review-orchestrator.d.ts +27 -10
- package/dist/lib/review-orchestrator.d.ts.map +1 -1
- package/dist/lib/review-orchestrator.js +51 -110
- package/dist/lib/review-orchestrator.js.map +1 -1
- package/dist/lib/review-orchestrator.test.d.ts +2 -0
- package/dist/lib/review-orchestrator.test.d.ts.map +1 -0
- package/dist/lib/review-orchestrator.test.js +413 -0
- package/dist/lib/review-orchestrator.test.js.map +1 -0
- package/dist/lib/review-output-path.test.d.ts +2 -0
- package/dist/lib/review-output-path.test.d.ts.map +1 -0
- package/dist/lib/review-output-path.test.js +83 -0
- package/dist/lib/review-output-path.test.js.map +1 -0
- package/dist/lib/review-parser.d.ts +2 -0
- package/dist/lib/review-parser.d.ts.map +1 -0
- package/dist/lib/review-parser.js +100 -0
- package/dist/lib/review-parser.js.map +1 -0
- package/dist/lib/unified-review-executor.d.ts +21 -4
- package/dist/lib/unified-review-executor.d.ts.map +1 -1
- package/dist/lib/unified-review-executor.js +81 -151
- package/dist/lib/unified-review-executor.js.map +1 -1
- package/dist/lib/unified-review-executor.test.d.ts +5 -0
- package/dist/lib/unified-review-executor.test.d.ts.map +1 -0
- package/dist/lib/unified-review-executor.test.js +344 -0
- package/dist/lib/unified-review-executor.test.js.map +1 -0
- package/dist/lib/write-json-output.d.ts +13 -0
- package/dist/lib/write-json-output.d.ts.map +1 -0
- package/dist/lib/write-json-output.js +37 -0
- package/dist/lib/write-json-output.js.map +1 -0
- package/dist/opencode/agent-loader.d.ts +3 -4
- package/dist/opencode/agent-loader.d.ts.map +1 -1
- package/dist/opencode/agent-loader.js +48 -34
- package/dist/opencode/agent-loader.js.map +1 -1
- package/dist/opencode/agent-skill-overlay.d.ts +11 -0
- package/dist/opencode/agent-skill-overlay.d.ts.map +1 -0
- package/dist/opencode/agent-skill-overlay.js +164 -0
- package/dist/opencode/agent-skill-overlay.js.map +1 -0
- package/dist/opencode/client.d.ts +11 -3
- package/dist/opencode/client.d.ts.map +1 -1
- package/dist/opencode/client.js +237 -71
- package/dist/opencode/client.js.map +1 -1
- package/dist/opencode/client.test.d.ts +2 -0
- package/dist/opencode/client.test.d.ts.map +1 -0
- package/dist/opencode/client.test.js +317 -0
- package/dist/opencode/client.test.js.map +1 -0
- package/dist/opencode/opencode-paths.d.ts +2 -0
- package/dist/opencode/opencode-paths.d.ts.map +1 -0
- package/dist/opencode/opencode-paths.js +7 -0
- package/dist/opencode/opencode-paths.js.map +1 -0
- package/dist/opencode/skill-loader.d.ts +6 -0
- package/dist/opencode/skill-loader.d.ts.map +1 -0
- package/dist/opencode/skill-loader.js +36 -0
- package/dist/opencode/skill-loader.js.map +1 -0
- package/package.json +7 -7
- package/.opencode/agent/github-reviewer.md +0 -77
- package/.opencode/agent/gitlab-reviewer.md +0 -77
- 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 @@
|
|
|
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 @@
|
|
|
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": "
|
|
3
|
+
"version": "2.0.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
|
-
"
|
|
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.
|
|
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.
|