@diff-review-system/drs 1.0.0 → 1.1.2
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/github-reviewer.md +22 -7
- package/.opencode/agent/gitlab-reviewer.md +22 -7
- package/.opencode/agent/local-reviewer.md +21 -29
- package/.opencode/agent/review/performance.md +22 -13
- package/.opencode/agent/review/quality.md +22 -13
- package/.opencode/agent/review/security.md +22 -19
- package/.opencode/agent/review/style.md +22 -10
- package/.opencode/opencode.jsonc +7 -19
- package/README.md +175 -69
- package/dist/ci/runner.d.ts.map +1 -1
- package/dist/ci/runner.js +2 -4
- package/dist/ci/runner.js.map +1 -1
- package/dist/cli/index.js +14 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +112 -23
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/review-local.d.ts.map +1 -1
- package/dist/cli/review-local.js +27 -70
- package/dist/cli/review-local.js.map +1 -1
- package/dist/cli/review-mr.d.ts +1 -0
- package/dist/cli/review-mr.d.ts.map +1 -1
- package/dist/cli/review-mr.js +34 -119
- package/dist/cli/review-mr.js.map +1 -1
- package/dist/cli/review-pr.d.ts.map +1 -1
- package/dist/cli/review-pr.js +74 -114
- package/dist/cli/review-pr.js.map +1 -1
- package/dist/github/client.d.ts +199 -4
- package/dist/github/client.d.ts.map +1 -1
- package/dist/github/client.js +37 -2
- package/dist/github/client.js.map +1 -1
- package/dist/github/client.test.d.ts +2 -0
- package/dist/github/client.test.d.ts.map +1 -0
- package/dist/github/client.test.js +206 -0
- package/dist/github/client.test.js.map +1 -0
- package/dist/github/platform-adapter.d.ts +31 -0
- package/dist/github/platform-adapter.d.ts.map +1 -0
- package/dist/github/platform-adapter.js +127 -0
- package/dist/github/platform-adapter.js.map +1 -0
- package/dist/github/platform-adapter.test.d.ts +2 -0
- package/dist/github/platform-adapter.test.d.ts.map +1 -0
- package/dist/github/platform-adapter.test.js +40 -0
- package/dist/github/platform-adapter.test.js.map +1 -0
- package/dist/gitlab/client.d.ts +12 -0
- package/dist/gitlab/client.d.ts.map +1 -1
- package/dist/gitlab/client.js +18 -0
- package/dist/gitlab/client.js.map +1 -1
- package/dist/gitlab/diff-parser.test.d.ts +2 -0
- package/dist/gitlab/diff-parser.test.d.ts.map +1 -0
- package/dist/gitlab/diff-parser.test.js +315 -0
- package/dist/gitlab/diff-parser.test.js.map +1 -0
- package/dist/gitlab/platform-adapter.d.ts +27 -0
- package/dist/gitlab/platform-adapter.d.ts.map +1 -0
- package/dist/gitlab/platform-adapter.js +120 -0
- package/dist/gitlab/platform-adapter.js.map +1 -0
- package/dist/gitlab/platform-adapter.test.d.ts +2 -0
- package/dist/gitlab/platform-adapter.test.d.ts.map +1 -0
- package/dist/gitlab/platform-adapter.test.js +21 -0
- package/dist/gitlab/platform-adapter.test.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +7 -0
- package/dist/index.test.js.map +1 -0
- package/dist/lib/code-quality-report.d.ts +44 -0
- package/dist/lib/code-quality-report.d.ts.map +1 -0
- package/dist/lib/code-quality-report.js +62 -0
- package/dist/lib/code-quality-report.js.map +1 -0
- package/dist/lib/code-quality-report.test.d.ts +2 -0
- package/dist/lib/code-quality-report.test.d.ts.map +1 -0
- package/dist/lib/code-quality-report.test.js +327 -0
- package/dist/lib/code-quality-report.test.js.map +1 -0
- package/dist/{gitlab → lib}/comment-formatter.d.ts +4 -2
- package/dist/lib/comment-formatter.d.ts.map +1 -0
- package/dist/{gitlab → lib}/comment-formatter.js +48 -15
- package/dist/lib/comment-formatter.js.map +1 -0
- package/dist/lib/comment-manager.d.ts +61 -0
- package/dist/lib/comment-manager.d.ts.map +1 -0
- package/dist/lib/comment-manager.js +91 -0
- package/dist/lib/comment-manager.js.map +1 -0
- package/dist/lib/config-model-overrides.test.d.ts +12 -0
- package/dist/lib/config-model-overrides.test.d.ts.map +1 -0
- package/dist/lib/config-model-overrides.test.js +224 -0
- package/dist/lib/config-model-overrides.test.js.map +1 -0
- package/dist/lib/config.d.ts +30 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +70 -11
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.d.ts +2 -0
- package/dist/lib/config.test.d.ts.map +1 -0
- package/dist/lib/config.test.js +28 -0
- package/dist/lib/config.test.js.map +1 -0
- package/dist/lib/context-loader.d.ts +29 -0
- package/dist/lib/context-loader.d.ts.map +1 -0
- package/dist/lib/context-loader.js +68 -0
- package/dist/lib/context-loader.js.map +1 -0
- package/dist/lib/diff-parser.d.ts.map +1 -0
- package/dist/{gitlab → lib}/diff-parser.js +3 -3
- package/dist/lib/diff-parser.js.map +1 -0
- package/dist/lib/issue-parser.d.ts +29 -0
- package/dist/lib/issue-parser.d.ts.map +1 -0
- package/dist/lib/issue-parser.js +151 -0
- package/dist/lib/issue-parser.js.map +1 -0
- package/dist/lib/issue-parser.test.d.ts +2 -0
- package/dist/lib/issue-parser.test.d.ts.map +1 -0
- package/dist/lib/issue-parser.test.js +281 -0
- package/dist/lib/issue-parser.test.js.map +1 -0
- package/dist/lib/platform-client.d.ts +130 -0
- package/dist/lib/platform-client.d.ts.map +1 -0
- package/dist/lib/platform-client.js +8 -0
- package/dist/lib/platform-client.js.map +1 -0
- package/dist/lib/position-validator.d.ts +36 -0
- package/dist/lib/position-validator.d.ts.map +1 -0
- package/dist/lib/position-validator.js +43 -0
- package/dist/lib/position-validator.js.map +1 -0
- package/dist/lib/review-orchestrator.d.ts +60 -0
- package/dist/lib/review-orchestrator.d.ts.map +1 -0
- package/dist/lib/review-orchestrator.js +183 -0
- package/dist/lib/review-orchestrator.js.map +1 -0
- package/dist/lib/unified-review-executor.d.ts +32 -0
- package/dist/lib/unified-review-executor.d.ts.map +1 -0
- package/dist/lib/unified-review-executor.js +228 -0
- package/dist/lib/unified-review-executor.js.map +1 -0
- package/dist/opencode/agent-loader.d.ts.map +1 -1
- package/dist/opencode/agent-loader.js +5 -10
- package/dist/opencode/agent-loader.js.map +1 -1
- package/dist/opencode/client.d.ts +3 -2
- package/dist/opencode/client.d.ts.map +1 -1
- package/dist/opencode/client.js +141 -28
- package/dist/opencode/client.js.map +1 -1
- package/package.json +28 -19
- package/dist/gitlab/comment-formatter.d.ts.map +0 -1
- package/dist/gitlab/comment-formatter.js.map +0 -1
- package/dist/gitlab/diff-parser.d.ts.map +0 -1
- package/dist/gitlab/diff-parser.js.map +0 -1
- /package/dist/{gitlab → lib}/diff-parser.d.ts +0 -0
package/dist/cli/init.js
CHANGED
|
@@ -5,14 +5,14 @@ const DEFAULT_DRS_CONFIG = `# DRS Configuration
|
|
|
5
5
|
# Documentation: https://github.com/your-org/drs
|
|
6
6
|
|
|
7
7
|
review:
|
|
8
|
-
# Review agents to use
|
|
8
|
+
# Review agents to use (mix of built-in and custom)
|
|
9
9
|
agents:
|
|
10
10
|
- security
|
|
11
11
|
- quality
|
|
12
12
|
- style
|
|
13
13
|
- performance
|
|
14
14
|
|
|
15
|
-
# Automatically review new MRs
|
|
15
|
+
# Automatically review new PRs/MRs
|
|
16
16
|
autoReview: true
|
|
17
17
|
|
|
18
18
|
# Review when bot is mentioned
|
|
@@ -38,6 +38,36 @@ output:
|
|
|
38
38
|
format: terminal
|
|
39
39
|
verbosity: normal
|
|
40
40
|
`;
|
|
41
|
+
const DEFAULT_GLOBAL_CONTEXT = `# Project Context
|
|
42
|
+
|
|
43
|
+
## Architecture
|
|
44
|
+
<!-- Describe your system architecture -->
|
|
45
|
+
|
|
46
|
+
## Technology Stack
|
|
47
|
+
<!-- List your main technologies, frameworks, and tools -->
|
|
48
|
+
|
|
49
|
+
## Trust Boundaries
|
|
50
|
+
<!-- Explain what inputs are trusted vs untrusted -->
|
|
51
|
+
|
|
52
|
+
## Review Guidelines
|
|
53
|
+
<!-- Any project-specific guidelines for reviewers -->
|
|
54
|
+
`;
|
|
55
|
+
const EXAMPLE_AGENT_CONTEXT = `# Security Agent Context
|
|
56
|
+
|
|
57
|
+
## Project-Specific Security Rules
|
|
58
|
+
|
|
59
|
+
### What NOT to Flag
|
|
60
|
+
<!-- List patterns that are valid for your project -->
|
|
61
|
+
|
|
62
|
+
### What TO Flag
|
|
63
|
+
<!-- List security concerns specific to your project -->
|
|
64
|
+
|
|
65
|
+
## Severity Calibration
|
|
66
|
+
- **CRITICAL**: Actively exploitable vulnerabilities with high impact
|
|
67
|
+
- **HIGH**: Real security issues requiring immediate attention
|
|
68
|
+
- **MEDIUM**: Potential edge cases or hardening opportunities
|
|
69
|
+
- **LOW**: Best practice improvements
|
|
70
|
+
`;
|
|
41
71
|
const EXAMPLE_GITLAB_CI = `# Example GitLab CI configuration for DRS
|
|
42
72
|
# Add this to your .gitlab-ci.yml file
|
|
43
73
|
|
|
@@ -76,7 +106,7 @@ REVIEW_AGENTS=security,quality,style,performance
|
|
|
76
106
|
* Initialize DRS configuration in a project
|
|
77
107
|
*/
|
|
78
108
|
export async function initProject(projectPath) {
|
|
79
|
-
console.log(chalk.bold.cyan('\n
|
|
109
|
+
console.log(chalk.bold.cyan('\n📋 DRS | Configuration Setup\n'));
|
|
80
110
|
// Create .drs directory
|
|
81
111
|
const drsDir = join(projectPath, '.drs');
|
|
82
112
|
if (!existsSync(drsDir)) {
|
|
@@ -86,12 +116,33 @@ export async function initProject(projectPath) {
|
|
|
86
116
|
else {
|
|
87
117
|
console.log(chalk.yellow('⚠'), chalk.cyan('.drs/'), 'directory already exists');
|
|
88
118
|
}
|
|
119
|
+
// Create global context file
|
|
120
|
+
const contextPath = join(drsDir, 'context.md');
|
|
121
|
+
if (!existsSync(contextPath)) {
|
|
122
|
+
writeFileSync(contextPath, DEFAULT_GLOBAL_CONTEXT, 'utf-8');
|
|
123
|
+
console.log(chalk.green('✓'), 'Created', chalk.cyan('.drs/context.md'));
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
console.log(chalk.yellow('⚠'), chalk.cyan('.drs/context.md'), 'already exists');
|
|
127
|
+
}
|
|
89
128
|
// Create .drs/agents directory
|
|
90
129
|
const agentsDir = join(drsDir, 'agents');
|
|
91
130
|
if (!existsSync(agentsDir)) {
|
|
92
131
|
mkdirSync(agentsDir, { recursive: true });
|
|
93
132
|
console.log(chalk.green('✓'), 'Created', chalk.cyan('.drs/agents/'), 'directory');
|
|
94
133
|
}
|
|
134
|
+
// Create example agent folders
|
|
135
|
+
const exampleAgents = ['security', 'quality', 'style', 'performance'];
|
|
136
|
+
for (const agentName of exampleAgents) {
|
|
137
|
+
const agentDir = join(agentsDir, agentName);
|
|
138
|
+
if (!existsSync(agentDir)) {
|
|
139
|
+
mkdirSync(agentDir, { recursive: true });
|
|
140
|
+
// Create context.md template
|
|
141
|
+
const agentContextPath = join(agentDir, 'context.md');
|
|
142
|
+
writeFileSync(agentContextPath, EXAMPLE_AGENT_CONTEXT.replace('Security', agentName.charAt(0).toUpperCase() + agentName.slice(1)), 'utf-8');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
console.log(chalk.green('✓'), 'Created agent context templates in', chalk.cyan('.drs/agents/'));
|
|
95
146
|
// Create drs.config.yaml
|
|
96
147
|
const configPath = join(drsDir, 'drs.config.yaml');
|
|
97
148
|
if (!existsSync(configPath)) {
|
|
@@ -112,38 +163,74 @@ export async function initProject(projectPath) {
|
|
|
112
163
|
console.log(chalk.green('✓'), 'Created example configurations in', chalk.cyan('.drs/examples/'));
|
|
113
164
|
}
|
|
114
165
|
// Create custom agents info
|
|
115
|
-
const customAgentReadme = `#
|
|
166
|
+
const customAgentReadme = `# DRS Agent Customization
|
|
167
|
+
|
|
168
|
+
DRS supports three levels of agent customization:
|
|
169
|
+
|
|
170
|
+
## 1. Global Context (.drs/context.md)
|
|
116
171
|
|
|
117
|
-
|
|
172
|
+
Project-wide context applied to ALL agents. Use this for:
|
|
173
|
+
- Architecture overview
|
|
174
|
+
- Technology stack
|
|
175
|
+
- Trust boundaries
|
|
176
|
+
- General review guidelines
|
|
118
177
|
|
|
119
|
-
##
|
|
178
|
+
## 2. Agent-Specific Context (.drs/agents/{name}/context.md)
|
|
120
179
|
|
|
121
|
-
|
|
180
|
+
**Additive** - Enhances the default agent with project-specific rules.
|
|
122
181
|
|
|
182
|
+
Example: \`.drs/agents/security/context.md\`
|
|
183
|
+
\`\`\`markdown
|
|
184
|
+
# Security Agent Context
|
|
185
|
+
|
|
186
|
+
## What NOT to Flag
|
|
187
|
+
- process.env for configuration (standard practice)
|
|
188
|
+
- Data from trusted APIs
|
|
189
|
+
|
|
190
|
+
## What TO Flag
|
|
191
|
+
- SQL injection vulnerabilities
|
|
192
|
+
- XSS in user-facing endpoints
|
|
193
|
+
\`\`\`
|
|
194
|
+
|
|
195
|
+
## 3. Full Agent Override (.drs/agents/{name}/agent.md)
|
|
196
|
+
|
|
197
|
+
**Replacement** - Completely replaces the default agent.
|
|
198
|
+
|
|
199
|
+
Example: \`.drs/agents/security/agent.md\`
|
|
123
200
|
\`\`\`markdown
|
|
124
201
|
---
|
|
125
|
-
description: Custom security reviewer
|
|
126
|
-
|
|
127
|
-
model: opencode/claude-sonnet-4-5
|
|
202
|
+
description: Custom security reviewer
|
|
203
|
+
model: claude-sonnet-4-5
|
|
128
204
|
tools:
|
|
129
205
|
Read: true
|
|
130
|
-
Glob: true
|
|
131
206
|
Grep: true
|
|
132
207
|
---
|
|
133
208
|
|
|
134
|
-
You are a security expert
|
|
209
|
+
You are a security expert specialized in [your domain].
|
|
135
210
|
|
|
136
|
-
|
|
211
|
+
[Complete custom instructions here]
|
|
212
|
+
\`\`\`
|
|
213
|
+
|
|
214
|
+
## Custom Agents
|
|
137
215
|
|
|
138
|
-
|
|
216
|
+
Create a new folder for custom agents:
|
|
217
|
+
\`.drs/agents/rails-reviewer/agent.md\`
|
|
218
|
+
|
|
219
|
+
Then add to \`.drs/drs.config.yaml\`:
|
|
220
|
+
\`\`\`yaml
|
|
221
|
+
review:
|
|
222
|
+
agents:
|
|
223
|
+
- security
|
|
224
|
+
- quality
|
|
225
|
+
- rails-reviewer # Your custom agent
|
|
139
226
|
\`\`\`
|
|
140
227
|
|
|
141
|
-
##
|
|
228
|
+
## Future: Skills (Coming Soon)
|
|
229
|
+
|
|
230
|
+
\`.drs/agents/security/skills/python.md\`
|
|
231
|
+
\`.drs/agents/security/skills/nodejs.md\`
|
|
142
232
|
|
|
143
|
-
|
|
144
|
-
1. \`.drs/agents/\` (highest priority - project-specific)
|
|
145
|
-
2. \`.opencode/agent/\` (standard OpenCode location)
|
|
146
|
-
3. Built-in DRS agents (fallback)
|
|
233
|
+
Skills will be auto-loaded based on detected languages.
|
|
147
234
|
|
|
148
235
|
## Learn More
|
|
149
236
|
|
|
@@ -158,9 +245,11 @@ DRS loads agents in this order:
|
|
|
158
245
|
// Summary
|
|
159
246
|
console.log(chalk.bold.green('\n✓ DRS initialization complete!\n'));
|
|
160
247
|
console.log(chalk.bold('Next steps:\n'));
|
|
161
|
-
console.log(' 1. Edit', chalk.cyan('.drs/
|
|
162
|
-
console.log(' 2.
|
|
163
|
-
console.log(' 3.
|
|
164
|
-
console.log(' 4.
|
|
248
|
+
console.log(' 1. Edit', chalk.cyan('.drs/context.md'), 'with your project context');
|
|
249
|
+
console.log(' 2. Customize agent behavior in', chalk.cyan('.drs/agents/{name}/context.md'));
|
|
250
|
+
console.log(' 3. Configure review settings in', chalk.cyan('.drs/drs.config.yaml'));
|
|
251
|
+
console.log(' 4. Set environment variables (see', chalk.cyan('.drs/examples/.env.example') + ')');
|
|
252
|
+
console.log(' 5. Run', chalk.cyan('drs review-pr'), 'to test on a PR\n');
|
|
253
|
+
console.log(chalk.gray('See', chalk.cyan('.drs/agents/README.md'), 'for customization guide\n'));
|
|
165
254
|
}
|
|
166
255
|
//# sourceMappingURL=init.js.map
|
package/dist/cli/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoC1B,CAAC;AAEF,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBzB,CAAC;AAEF,MAAM,WAAW,GAAG;;;;;;;;;;;CAWnB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,WAAmB;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-local.d.ts","sourceRoot":"","sources":["../../src/cli/review-local.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"review-local.d.ts","sourceRoot":"","sources":["../../src/cli/review-local.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAUlD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgE/F"}
|
package/dist/cli/review-local.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import simpleGit from 'simple-git';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { parseDiff, getChangedFiles } from '../lib/diff-parser.js';
|
|
4
|
+
import { formatTerminalIssue } from '../lib/comment-formatter.js';
|
|
5
|
+
import { executeReview, displayReviewSummary, hasBlockingIssues, } from '../lib/review-orchestrator.js';
|
|
6
6
|
/**
|
|
7
7
|
* Review local git diff before pushing
|
|
8
8
|
*/
|
|
9
9
|
export async function reviewLocal(config, options) {
|
|
10
|
-
console.log(chalk.bold.cyan('\n
|
|
10
|
+
console.log(chalk.bold.cyan('\n📋 DRS | Local Diff Analysis\n'));
|
|
11
11
|
const git = simpleGit();
|
|
12
12
|
const cwd = process.cwd();
|
|
13
13
|
// Check if we're in a git repository
|
|
@@ -15,91 +15,48 @@ export async function reviewLocal(config, options) {
|
|
|
15
15
|
if (!isRepo) {
|
|
16
16
|
throw new Error('Not a git repository. Run this command from within a git repository.');
|
|
17
17
|
}
|
|
18
|
-
// Get diff
|
|
18
|
+
// Get diff (platform-specific: local git)
|
|
19
19
|
console.log(chalk.gray(`Getting ${options.staged ? 'staged' : 'unstaged'} changes...\n`));
|
|
20
|
-
const diffText = options.staged
|
|
21
|
-
? await git.diff(['--cached'])
|
|
22
|
-
: await git.diff();
|
|
20
|
+
const diffText = options.staged ? await git.diff(['--cached']) : await git.diff();
|
|
23
21
|
if (!diffText || diffText.trim().length === 0) {
|
|
24
22
|
console.log(chalk.yellow('✓ No changes to review\n'));
|
|
25
23
|
return;
|
|
26
24
|
}
|
|
27
|
-
// Parse diff
|
|
25
|
+
// Parse diff to get changed files
|
|
28
26
|
const diffs = parseDiff(diffText);
|
|
29
27
|
const changedFiles = getChangedFiles(diffs);
|
|
30
28
|
if (changedFiles.length === 0) {
|
|
31
29
|
console.log(chalk.yellow('✓ No files to review\n'));
|
|
32
30
|
return;
|
|
33
31
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
baseUrl: config.opencode.serverUrl || undefined,
|
|
39
|
-
directory: cwd,
|
|
40
|
-
});
|
|
41
|
-
// Create review session
|
|
42
|
-
console.log(chalk.gray('Starting AI review...\n'));
|
|
43
|
-
const agentsList = config.review.agents.join(',');
|
|
44
|
-
const session = await opencode.createSession({
|
|
45
|
-
agent: 'local-reviewer',
|
|
46
|
-
message: `Review local diff with agents: ${agentsList}. Files: ${changedFiles.join(', ')}`,
|
|
32
|
+
// Execute review using common orchestrator
|
|
33
|
+
const source = {
|
|
34
|
+
name: `Local ${options.staged ? 'staged' : 'unstaged'} diff`,
|
|
35
|
+
files: changedFiles,
|
|
47
36
|
context: {
|
|
48
|
-
files: changedFiles,
|
|
49
|
-
agents: config.review.agents,
|
|
50
37
|
staged: options.staged,
|
|
51
38
|
},
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// For now, we'll display raw output
|
|
62
|
-
// In production, parse structured JSON responses from agents
|
|
63
|
-
}
|
|
39
|
+
workingDir: cwd,
|
|
40
|
+
};
|
|
41
|
+
const result = await executeReview(config, source);
|
|
42
|
+
// Display results (platform-specific: terminal output)
|
|
43
|
+
if (result.issues.length > 0) {
|
|
44
|
+
displayReviewSummary(result);
|
|
45
|
+
// Display issues in terminal
|
|
46
|
+
for (const issue of result.issues) {
|
|
47
|
+
console.log(formatTerminalIssue(issue));
|
|
64
48
|
}
|
|
65
|
-
//
|
|
66
|
-
if (
|
|
67
|
-
console.log(chalk.bold('\n
|
|
68
|
-
|
|
69
|
-
console.log(chalk.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
|
|
70
|
-
const summary = calculateSummary(changedFiles.length, issues);
|
|
71
|
-
console.log(` Files reviewed: ${chalk.cyan(summary.filesReviewed)}`);
|
|
72
|
-
console.log(` Issues found: ${chalk.yellow(summary.issuesFound)}`);
|
|
73
|
-
if (summary.issuesFound > 0) {
|
|
74
|
-
console.log(` 🔴 Critical: ${chalk.red(summary.bySeverity.CRITICAL)}`);
|
|
75
|
-
console.log(` 🟡 High: ${chalk.yellow(summary.bySeverity.HIGH)}`);
|
|
76
|
-
console.log(` 🟠 Medium: ${chalk.hex('#FFA500')(summary.bySeverity.MEDIUM)}`);
|
|
77
|
-
console.log(` ⚪ Low: ${chalk.gray(summary.bySeverity.LOW)}`);
|
|
78
|
-
}
|
|
79
|
-
console.log('');
|
|
80
|
-
// Display issues
|
|
81
|
-
for (const issue of issues) {
|
|
82
|
-
console.log(formatTerminalIssue(issue));
|
|
83
|
-
}
|
|
84
|
-
// Recommendation
|
|
85
|
-
const hasCritical = summary.bySeverity.CRITICAL > 0;
|
|
86
|
-
const hasHigh = summary.bySeverity.HIGH > 0;
|
|
87
|
-
if (hasCritical || hasHigh) {
|
|
88
|
-
console.log(chalk.red.bold('\n⚠️ Recommendation: Fix critical/high issues before pushing\n'));
|
|
89
|
-
process.exit(1);
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
console.log(chalk.green('\n✓ No critical issues found. Safe to push.\n'));
|
|
93
|
-
}
|
|
49
|
+
// Recommendation
|
|
50
|
+
if (hasBlockingIssues(result)) {
|
|
51
|
+
console.log(chalk.red.bold('\n⚠️ Recommendation: Fix critical/high issues before pushing\n'));
|
|
52
|
+
process.exit(1);
|
|
94
53
|
}
|
|
95
54
|
else {
|
|
96
|
-
console.log(chalk.green('\n✓ No issues found
|
|
55
|
+
console.log(chalk.green('\n✓ No critical issues found. Safe to push.\n'));
|
|
97
56
|
}
|
|
98
57
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
await opencode.closeSession(session.id);
|
|
102
|
-
await opencode.shutdown();
|
|
58
|
+
else {
|
|
59
|
+
console.log(chalk.green('\n✓ No issues found! Code looks good.\n'));
|
|
103
60
|
}
|
|
104
61
|
}
|
|
105
62
|
//# sourceMappingURL=review-local.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-local.js","sourceRoot":"","sources":["../../src/cli/review-local.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"review-local.js","sourceRoot":"","sources":["../../src/cli/review-local.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/review-mr.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-mr.d.ts","sourceRoot":"","sources":["../../src/cli/review-mr.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"review-mr.d.ts","sourceRoot":"","sources":["../../src/cli/review-mr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAOlD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCzF"}
|
package/dist/cli/review-mr.js
CHANGED
|
@@ -1,128 +1,43 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
1
|
import { createGitLabClient } from '../gitlab/client.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { formatSummaryComment, formatIssueComment, calculateSummary, } from '../gitlab/comment-formatter.js';
|
|
2
|
+
import { GitLabPlatformAdapter } from '../gitlab/platform-adapter.js';
|
|
3
|
+
import { executeUnifiedReview } from '../lib/unified-review-executor.js';
|
|
6
4
|
/**
|
|
7
5
|
* Review a GitLab merge request
|
|
8
6
|
*/
|
|
9
7
|
export async function reviewMR(config, options) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
// Fetch MR details
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (changes.length === 0) {
|
|
22
|
-
console.log(chalk.yellow('✓ No changes to review\n'));
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
// Parse diffs
|
|
26
|
-
const diffs = changes.map(change => parseDiff(change.diff)).flat();
|
|
27
|
-
const changedFiles = getChangedFiles(diffs);
|
|
28
|
-
// Connect to OpenCode (or start in-process if serverUrl is empty)
|
|
29
|
-
console.log(chalk.gray('Connecting to OpenCode server...\n'));
|
|
30
|
-
const opencode = await createOpencodeClientInstance({
|
|
31
|
-
baseUrl: config.opencode.serverUrl || undefined,
|
|
32
|
-
});
|
|
33
|
-
// Create review session
|
|
34
|
-
console.log(chalk.gray('Starting AI review...\n'));
|
|
35
|
-
const agentsList = config.review.agents.join(',');
|
|
36
|
-
const session = await opencode.createSession({
|
|
37
|
-
agent: 'gitlab-reviewer',
|
|
38
|
-
message: `Review MR !${options.mrIid} in project ${options.projectId}. Agents: ${agentsList}. Files: ${changedFiles.join(', ')}`,
|
|
39
|
-
context: {
|
|
40
|
-
projectId: options.projectId,
|
|
41
|
-
mrIid: options.mrIid,
|
|
42
|
-
files: changedFiles,
|
|
43
|
-
agents: config.review.agents,
|
|
44
|
-
mr: {
|
|
45
|
-
title: mr.title,
|
|
46
|
-
description: mr.description,
|
|
47
|
-
author: mr.author?.name,
|
|
48
|
-
sourceBranch: mr.source_branch,
|
|
49
|
-
targetBranch: mr.target_branch,
|
|
50
|
-
},
|
|
8
|
+
// Create GitLab client and adapter
|
|
9
|
+
const gitlabClient = createGitLabClient();
|
|
10
|
+
const platformClient = new GitLabPlatformAdapter(gitlabClient);
|
|
11
|
+
// Fetch MR details to get diff refs
|
|
12
|
+
const mr = await gitlabClient.getMergeRequest(options.projectId, options.mrIid);
|
|
13
|
+
// Create line validator
|
|
14
|
+
// For GitLab, we can post on any line with valid diff_refs
|
|
15
|
+
const diffRefs = mr.diff_refs;
|
|
16
|
+
const lineValidator = {
|
|
17
|
+
isValidLine(file, line) {
|
|
18
|
+
return line !== undefined && diffRefs?.base_sha && diffRefs.head_sha && diffRefs.start_sha;
|
|
51
19
|
},
|
|
20
|
+
};
|
|
21
|
+
// Create inline position builder
|
|
22
|
+
const createInlinePosition = (issue, platformData) => {
|
|
23
|
+
const refs = platformData.diff_refs;
|
|
24
|
+
return {
|
|
25
|
+
path: issue.file,
|
|
26
|
+
line: issue.line,
|
|
27
|
+
baseSha: refs.base_sha,
|
|
28
|
+
headSha: refs.head_sha,
|
|
29
|
+
startSha: refs.start_sha,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
// Execute unified review
|
|
33
|
+
await executeUnifiedReview(config, {
|
|
34
|
+
platformClient,
|
|
35
|
+
projectId: options.projectId,
|
|
36
|
+
prNumber: options.mrIid,
|
|
37
|
+
postComments: options.postComments,
|
|
38
|
+
codeQualityReport: options.codeQualityReport,
|
|
39
|
+
lineValidator,
|
|
40
|
+
createInlinePosition,
|
|
52
41
|
});
|
|
53
|
-
// Stream and collect results
|
|
54
|
-
const issues = [];
|
|
55
|
-
try {
|
|
56
|
-
for await (const message of opencode.streamMessages(session.id)) {
|
|
57
|
-
if (message.role === 'assistant') {
|
|
58
|
-
// Parse issues from assistant messages
|
|
59
|
-
// TODO: Implement structured output parsing once OpenCode SDK supports it
|
|
60
|
-
console.log(message.content);
|
|
61
|
-
// For now, we'll display raw output
|
|
62
|
-
// In production, parse structured JSON responses from agents
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
// Display and post summary
|
|
66
|
-
const summary = calculateSummary(changedFiles.length, issues);
|
|
67
|
-
console.log(chalk.bold('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
68
|
-
console.log(chalk.bold('📊 Review Summary'));
|
|
69
|
-
console.log(chalk.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
|
|
70
|
-
console.log(` Files reviewed: ${chalk.cyan(summary.filesReviewed)}`);
|
|
71
|
-
console.log(` Issues found: ${chalk.yellow(summary.issuesFound)}`);
|
|
72
|
-
if (summary.issuesFound > 0) {
|
|
73
|
-
console.log(` 🔴 Critical: ${chalk.red(summary.bySeverity.CRITICAL)}`);
|
|
74
|
-
console.log(` 🟡 High: ${chalk.yellow(summary.bySeverity.HIGH)}`);
|
|
75
|
-
console.log(` 🟠 Medium: ${chalk.hex('#FFA500')(summary.bySeverity.MEDIUM)}`);
|
|
76
|
-
console.log(` ⚪ Low: ${chalk.gray(summary.bySeverity.LOW)}`);
|
|
77
|
-
}
|
|
78
|
-
console.log('');
|
|
79
|
-
// Post comments to GitLab if requested
|
|
80
|
-
if (options.postComments) {
|
|
81
|
-
console.log(chalk.gray('Posting review comments to GitLab...\n'));
|
|
82
|
-
// Post summary comment
|
|
83
|
-
const summaryComment = formatSummaryComment(summary, issues);
|
|
84
|
-
await gitlab.createMRComment(options.projectId, options.mrIid, summaryComment);
|
|
85
|
-
// Post individual issue comments as discussion threads
|
|
86
|
-
for (const issue of issues) {
|
|
87
|
-
const diffRefs = mr.diff_refs;
|
|
88
|
-
if (issue.line && diffRefs && diffRefs.base_sha && diffRefs.head_sha && diffRefs.start_sha) {
|
|
89
|
-
try {
|
|
90
|
-
await gitlab.createMRDiscussionThread(options.projectId, options.mrIid, formatIssueComment(issue), {
|
|
91
|
-
baseSha: diffRefs.base_sha,
|
|
92
|
-
headSha: diffRefs.head_sha,
|
|
93
|
-
startSha: diffRefs.start_sha,
|
|
94
|
-
newPath: issue.file,
|
|
95
|
-
newLine: issue.line,
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
catch (error) {
|
|
99
|
-
// If line-specific comment fails, post as general comment
|
|
100
|
-
console.warn(chalk.yellow(`Warning: Could not post line comment for ${issue.file}:${issue.line}`));
|
|
101
|
-
await gitlab.createMRComment(options.projectId, options.mrIid, formatIssueComment(issue));
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
// Post as general comment if no line number
|
|
106
|
-
await gitlab.createMRComment(options.projectId, options.mrIid, formatIssueComment(issue));
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
// Add ai-reviewed label
|
|
110
|
-
await gitlab.addLabel(options.projectId, options.mrIid, ['ai-reviewed']);
|
|
111
|
-
console.log(chalk.green('✓ Review posted to GitLab MR\n'));
|
|
112
|
-
}
|
|
113
|
-
// Exit with error code if critical issues found
|
|
114
|
-
if (summary.bySeverity.CRITICAL > 0) {
|
|
115
|
-
console.log(chalk.red.bold('⚠️ Critical issues found!\n'));
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
118
|
-
else if (summary.issuesFound === 0) {
|
|
119
|
-
console.log(chalk.green('✓ No issues found! MR looks good.\n'));
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
finally {
|
|
123
|
-
// Clean up session and shutdown in-process server if applicable
|
|
124
|
-
await opencode.closeSession(session.id);
|
|
125
|
-
await opencode.shutdown();
|
|
126
|
-
}
|
|
127
42
|
}
|
|
128
43
|
//# sourceMappingURL=review-mr.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-mr.js","sourceRoot":"","sources":["../../src/cli/review-mr.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"review-mr.js","sourceRoot":"","sources":["../../src/cli/review-mr.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAWzE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAiB,EAAE,OAAwB;IACxE,mCAAmC;IACnC,MAAM,YAAY,GAAG,kBAAkB,EAAE,CAAC;IAC1C,MAAM,cAAc,GAAG,IAAI,qBAAqB,CAAC,YAAY,CAAC,CAAC;IAE/D,oCAAoC;IACpC,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAEhF,wBAAwB;IACxB,2DAA2D;IAC3D,MAAM,QAAQ,GAAQ,EAAE,CAAC,SAAS,CAAC;IACnC,MAAM,aAAa,GAAkB;QACnC,WAAW,CAAC,IAAY,EAAE,IAAY;YACpC,OAAO,IAAI,KAAK,SAAS,IAAI,QAAQ,EAAE,QAAQ,IAAI,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,SAAS,CAAC;QAC7F,CAAC;KACF,CAAC;IAEF,iCAAiC;IACjC,MAAM,oBAAoB,GAAG,CAAC,KAAkB,EAAE,YAAiB,EAAyB,EAAE;QAC5F,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC;QACpC,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAK;YACjB,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,QAAQ,EAAE,IAAI,CAAC,SAAS;SACzB,CAAC;IACJ,CAAC,CAAC;IAEF,yBAAyB;IACzB,MAAM,oBAAoB,CAAC,MAAM,EAAE;QACjC,cAAc;QACd,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,QAAQ,EAAE,OAAO,CAAC,KAAK;QACvB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,aAAa;QACb,oBAAoB;KACrB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-pr.d.ts","sourceRoot":"","sources":["../../src/cli/review-pr.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"review-pr.d.ts","sourceRoot":"","sources":["../../src/cli/review-pr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAOlD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;CACvB;AAwCD;;GAEG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CzF"}
|