@jinke5245/code-reviewer 0.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.
Files changed (161) hide show
  1. package/.schemas/code-reviewer.schema.json +224 -0
  2. package/LICENSE.md +24 -0
  3. package/README.md +182 -0
  4. package/dist/cli.js +59352 -0
  5. package/dist/src/cli.d.ts +21 -0
  6. package/dist/src/cli.d.ts.map +1 -0
  7. package/dist/src/cli.js +646 -0
  8. package/dist/src/cli.js.map +1 -0
  9. package/dist/src/config/load-config.d.ts +12 -0
  10. package/dist/src/config/load-config.d.ts.map +1 -0
  11. package/dist/src/config/load-config.js +201 -0
  12. package/dist/src/config/load-config.js.map +1 -0
  13. package/dist/src/config/schema.d.ts +84 -0
  14. package/dist/src/config/schema.d.ts.map +1 -0
  15. package/dist/src/config/schema.js +148 -0
  16. package/dist/src/config/schema.js.map +1 -0
  17. package/dist/src/env.d.ts +5 -0
  18. package/dist/src/env.d.ts.map +1 -0
  19. package/dist/src/env.js +9 -0
  20. package/dist/src/env.js.map +1 -0
  21. package/dist/src/gitlab/client.d.ts +63 -0
  22. package/dist/src/gitlab/client.d.ts.map +1 -0
  23. package/dist/src/gitlab/client.js +47 -0
  24. package/dist/src/gitlab/client.js.map +1 -0
  25. package/dist/src/gitlab/diff-lines.d.ts +31 -0
  26. package/dist/src/gitlab/diff-lines.d.ts.map +1 -0
  27. package/dist/src/gitlab/diff-lines.js +110 -0
  28. package/dist/src/gitlab/diff-lines.js.map +1 -0
  29. package/dist/src/gitlab/inline-discussions.d.ts +68 -0
  30. package/dist/src/gitlab/inline-discussions.d.ts.map +1 -0
  31. package/dist/src/gitlab/inline-discussions.js +255 -0
  32. package/dist/src/gitlab/inline-discussions.js.map +1 -0
  33. package/dist/src/gitlab/mr-context.d.ts +69 -0
  34. package/dist/src/gitlab/mr-context.d.ts.map +1 -0
  35. package/dist/src/gitlab/mr-context.js +116 -0
  36. package/dist/src/gitlab/mr-context.js.map +1 -0
  37. package/dist/src/gitlab/reference-context.d.ts +58 -0
  38. package/dist/src/gitlab/reference-context.d.ts.map +1 -0
  39. package/dist/src/gitlab/reference-context.js +148 -0
  40. package/dist/src/gitlab/reference-context.js.map +1 -0
  41. package/dist/src/gitlab/response-utils.d.ts +21 -0
  42. package/dist/src/gitlab/response-utils.d.ts.map +1 -0
  43. package/dist/src/gitlab/response-utils.js +84 -0
  44. package/dist/src/gitlab/response-utils.js.map +1 -0
  45. package/dist/src/gitlab/review-formatting.d.ts +3 -0
  46. package/dist/src/gitlab/review-formatting.d.ts.map +1 -0
  47. package/dist/src/gitlab/review-formatting.js +9 -0
  48. package/dist/src/gitlab/review-formatting.js.map +1 -0
  49. package/dist/src/gitlab/review-publication-plan.d.ts +68 -0
  50. package/dist/src/gitlab/review-publication-plan.d.ts.map +1 -0
  51. package/dist/src/gitlab/review-publication-plan.js +180 -0
  52. package/dist/src/gitlab/review-publication-plan.js.map +1 -0
  53. package/dist/src/gitlab/review-template-rendering.d.ts +9 -0
  54. package/dist/src/gitlab/review-template-rendering.d.ts.map +1 -0
  55. package/dist/src/gitlab/review-template-rendering.js +61 -0
  56. package/dist/src/gitlab/review-template-rendering.js.map +1 -0
  57. package/dist/src/gitlab/review-templates.d.ts +14 -0
  58. package/dist/src/gitlab/review-templates.d.ts.map +1 -0
  59. package/dist/src/gitlab/review-templates.js +78 -0
  60. package/dist/src/gitlab/review-templates.js.map +1 -0
  61. package/dist/src/gitlab/summary-note.d.ts +49 -0
  62. package/dist/src/gitlab/summary-note.d.ts.map +1 -0
  63. package/dist/src/gitlab/summary-note.js +197 -0
  64. package/dist/src/gitlab/summary-note.js.map +1 -0
  65. package/dist/src/gitlab/token-env.d.ts +13 -0
  66. package/dist/src/gitlab/token-env.d.ts.map +1 -0
  67. package/dist/src/gitlab/token-env.js +29 -0
  68. package/dist/src/gitlab/token-env.js.map +1 -0
  69. package/dist/src/index.d.ts +39 -0
  70. package/dist/src/index.d.ts.map +1 -0
  71. package/dist/src/index.js +22 -0
  72. package/dist/src/index.js.map +1 -0
  73. package/dist/src/log-value.d.ts +3 -0
  74. package/dist/src/log-value.d.ts.map +1 -0
  75. package/dist/src/log-value.js +13 -0
  76. package/dist/src/log-value.js.map +1 -0
  77. package/dist/src/logger.d.ts +8 -0
  78. package/dist/src/logger.d.ts.map +1 -0
  79. package/dist/src/logger.js +77 -0
  80. package/dist/src/logger.js.map +1 -0
  81. package/dist/src/model/openai-compatible.d.ts +26 -0
  82. package/dist/src/model/openai-compatible.d.ts.map +1 -0
  83. package/dist/src/model/openai-compatible.js +568 -0
  84. package/dist/src/model/openai-compatible.js.map +1 -0
  85. package/dist/src/package-info.d.ts +8 -0
  86. package/dist/src/package-info.d.ts.map +1 -0
  87. package/dist/src/package-info.js +43 -0
  88. package/dist/src/package-info.js.map +1 -0
  89. package/dist/src/prompt/review-prompts.d.ts +34 -0
  90. package/dist/src/prompt/review-prompts.d.ts.map +1 -0
  91. package/dist/src/prompt/review-prompts.js +139 -0
  92. package/dist/src/prompt/review-prompts.js.map +1 -0
  93. package/dist/src/review/finding-evidence-contract.d.ts +3 -0
  94. package/dist/src/review/finding-evidence-contract.d.ts.map +1 -0
  95. package/dist/src/review/finding-evidence-contract.js +13 -0
  96. package/dist/src/review/finding-evidence-contract.js.map +1 -0
  97. package/dist/src/review/loop.d.ts +78 -0
  98. package/dist/src/review/loop.d.ts.map +1 -0
  99. package/dist/src/review/loop.js +332 -0
  100. package/dist/src/review/loop.js.map +1 -0
  101. package/dist/src/review/report.d.ts +42 -0
  102. package/dist/src/review/report.d.ts.map +1 -0
  103. package/dist/src/review/report.js +203 -0
  104. package/dist/src/review/report.js.map +1 -0
  105. package/dist/src/tools/builtin/gitlab-utils.d.ts +12 -0
  106. package/dist/src/tools/builtin/gitlab-utils.d.ts.map +1 -0
  107. package/dist/src/tools/builtin/gitlab-utils.js +22 -0
  108. package/dist/src/tools/builtin/gitlab-utils.js.map +1 -0
  109. package/dist/src/tools/builtin/index.d.ts +3 -0
  110. package/dist/src/tools/builtin/index.d.ts.map +1 -0
  111. package/dist/src/tools/builtin/index.js +19 -0
  112. package/dist/src/tools/builtin/index.js.map +1 -0
  113. package/dist/src/tools/builtin/list-gitlab-issues.d.ts +3 -0
  114. package/dist/src/tools/builtin/list-gitlab-issues.d.ts.map +1 -0
  115. package/dist/src/tools/builtin/list-gitlab-issues.js +33 -0
  116. package/dist/src/tools/builtin/list-gitlab-issues.js.map +1 -0
  117. package/dist/src/tools/builtin/list-gitlab-mrs.d.ts +3 -0
  118. package/dist/src/tools/builtin/list-gitlab-mrs.d.ts.map +1 -0
  119. package/dist/src/tools/builtin/list-gitlab-mrs.js +33 -0
  120. package/dist/src/tools/builtin/list-gitlab-mrs.js.map +1 -0
  121. package/dist/src/tools/builtin/read-diff.d.ts +3 -0
  122. package/dist/src/tools/builtin/read-diff.d.ts.map +1 -0
  123. package/dist/src/tools/builtin/read-diff.js +25 -0
  124. package/dist/src/tools/builtin/read-diff.js.map +1 -0
  125. package/dist/src/tools/builtin/read-file.d.ts +3 -0
  126. package/dist/src/tools/builtin/read-file.d.ts.map +1 -0
  127. package/dist/src/tools/builtin/read-file.js +52 -0
  128. package/dist/src/tools/builtin/read-file.js.map +1 -0
  129. package/dist/src/tools/builtin/read-gitlab-issue.d.ts +3 -0
  130. package/dist/src/tools/builtin/read-gitlab-issue.d.ts.map +1 -0
  131. package/dist/src/tools/builtin/read-gitlab-issue.js +45 -0
  132. package/dist/src/tools/builtin/read-gitlab-issue.js.map +1 -0
  133. package/dist/src/tools/builtin/read-gitlab-mr-discussions.d.ts +3 -0
  134. package/dist/src/tools/builtin/read-gitlab-mr-discussions.d.ts.map +1 -0
  135. package/dist/src/tools/builtin/read-gitlab-mr-discussions.js +85 -0
  136. package/dist/src/tools/builtin/read-gitlab-mr-discussions.js.map +1 -0
  137. package/dist/src/tools/builtin/read-gitlab-mr.d.ts +3 -0
  138. package/dist/src/tools/builtin/read-gitlab-mr.d.ts.map +1 -0
  139. package/dist/src/tools/builtin/read-gitlab-mr.js +61 -0
  140. package/dist/src/tools/builtin/read-gitlab-mr.js.map +1 -0
  141. package/dist/src/tools/builtin/repo-search.d.ts +14 -0
  142. package/dist/src/tools/builtin/repo-search.d.ts.map +1 -0
  143. package/dist/src/tools/builtin/repo-search.js +121 -0
  144. package/dist/src/tools/builtin/repo-search.js.map +1 -0
  145. package/dist/src/tools/format-error.d.ts +2 -0
  146. package/dist/src/tools/format-error.d.ts.map +1 -0
  147. package/dist/src/tools/format-error.js +4 -0
  148. package/dist/src/tools/format-error.js.map +1 -0
  149. package/dist/src/tools/repository-path.d.ts +4 -0
  150. package/dist/src/tools/repository-path.d.ts.map +1 -0
  151. package/dist/src/tools/repository-path.js +40 -0
  152. package/dist/src/tools/repository-path.js.map +1 -0
  153. package/dist/src/tools/runner.d.ts +17 -0
  154. package/dist/src/tools/runner.d.ts.map +1 -0
  155. package/dist/src/tools/runner.js +118 -0
  156. package/dist/src/tools/runner.js.map +1 -0
  157. package/dist/src/tools/types.d.ts +44 -0
  158. package/dist/src/tools/types.d.ts.map +1 -0
  159. package/dist/src/tools/types.js +2 -0
  160. package/dist/src/tools/types.js.map +1 -0
  161. package/package.json +161 -0
@@ -0,0 +1,224 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://github.com/jinke5245/code-reviewer/schemas/code-reviewer.schema.json",
4
+ "title": "Code Reviewer configuration",
5
+ "description": "Configuration accepted by .codereviewer.yml, .codereviewer.yaml, .codereviewer.json, .codereviewer.jsonc, package.json#codereviewer, pyproject.toml#[tool.codereviewer], and Cargo.toml#[package.metadata.codereviewer].",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "review": {
10
+ "type": "object",
11
+ "additionalProperties": false,
12
+ "properties": {
13
+ "maxRounds": {
14
+ "type": "integer",
15
+ "minimum": 1,
16
+ "default": 12,
17
+ "description": "Maximum model/tool review loop rounds before returning the final report."
18
+ }
19
+ }
20
+ },
21
+ "model": {
22
+ "type": "object",
23
+ "additionalProperties": false,
24
+ "properties": {
25
+ "provider": {
26
+ "const": "openai-compatible",
27
+ "default": "openai-compatible",
28
+ "description": "Model provider implementation. Only OpenAI-compatible chat completions are supported today."
29
+ },
30
+ "baseUrl": {
31
+ "type": "string",
32
+ "minLength": 1,
33
+ "pattern": "^[A-Za-z][A-Za-z0-9+.-]*://[^\\s]+$",
34
+ "description": "OpenAI-compatible base URL. Defaults to OPENAI_BASE_URL, then the public OpenAI API base URL."
35
+ },
36
+ "apiKeyEnv": {
37
+ "type": "string",
38
+ "minLength": 1,
39
+ "default": "OPENAI_API_KEY",
40
+ "description": "Environment variable that contains the model API key."
41
+ },
42
+ "model": {
43
+ "type": "string",
44
+ "minLength": 1,
45
+ "description": "Model name. Defaults to OPENAI_MODEL."
46
+ },
47
+ "temperature": {
48
+ "type": "number",
49
+ "minimum": 0,
50
+ "maximum": 2
51
+ },
52
+ "maxOutputTokens": {
53
+ "type": "integer",
54
+ "minimum": 1
55
+ },
56
+ "timeoutMs": {
57
+ "type": "integer",
58
+ "minimum": 1,
59
+ "default": 300000,
60
+ "description": "Per-request model timeout in milliseconds."
61
+ },
62
+ "responseFormat": {
63
+ "type": "string",
64
+ "enum": ["auto", "json_schema", "json_object", "off"],
65
+ "default": "auto",
66
+ "description": "OpenAI-compatible response_format mode for final review JSON. Auto tries json_schema, falls back to json_object, then omits response_format when the provider rejects both structured response formats. Use off to always rely on prompt-only JSON output."
67
+ }
68
+ }
69
+ },
70
+ "gitlab": {
71
+ "type": "object",
72
+ "additionalProperties": false,
73
+ "properties": {
74
+ "tokenEnv": {
75
+ "type": "string",
76
+ "minLength": 1,
77
+ "default": "GITLAB_TOKEN",
78
+ "description": "Environment variable that contains the GitLab token. The default GITLAB_TOKEN falls back to GL_TOKEN when unset or blank."
79
+ },
80
+ "publish": {
81
+ "type": "string",
82
+ "enum": ["dry-run", "summary", "inline"],
83
+ "default": "dry-run",
84
+ "description": "How review findings are published."
85
+ },
86
+ "failOnSeverity": {
87
+ "type": "string",
88
+ "enum": ["none", "low", "medium", "high"],
89
+ "default": "none",
90
+ "description": "Minimum finding severity that should fail the review job."
91
+ }
92
+ }
93
+ },
94
+ "prompts": {
95
+ "type": "object",
96
+ "additionalProperties": false,
97
+ "properties": {
98
+ "system": {
99
+ "type": "string",
100
+ "minLength": 1,
101
+ "description": "Repository-relative path to an additional system prompt file."
102
+ },
103
+ "review": {
104
+ "type": "string",
105
+ "minLength": 1,
106
+ "description": "Repository-relative path to an additional review prompt file."
107
+ },
108
+ "extraRules": {
109
+ "type": "array",
110
+ "default": [],
111
+ "items": {
112
+ "type": "string",
113
+ "minLength": 1
114
+ }
115
+ }
116
+ }
117
+ },
118
+ "templates": {
119
+ "type": "object",
120
+ "additionalProperties": false,
121
+ "properties": {
122
+ "summary": {
123
+ "type": "string",
124
+ "minLength": 1,
125
+ "description": "Repository-relative path to a Markdown template used for GitLab summary review notes."
126
+ },
127
+ "inline": {
128
+ "type": "string",
129
+ "minLength": 1,
130
+ "description": "Repository-relative path to a Markdown template used for inline GitLab discussion comments."
131
+ }
132
+ }
133
+ },
134
+ "tools": {
135
+ "type": "object",
136
+ "additionalProperties": false,
137
+ "properties": {
138
+ "enabled": {
139
+ "type": "array",
140
+ "default": [
141
+ "read_diff",
142
+ "read_file",
143
+ "repo_search",
144
+ "read_gitlab_mr",
145
+ "read_gitlab_issue",
146
+ "list_gitlab_issues",
147
+ "list_gitlab_mrs",
148
+ "read_gitlab_mr_discussions"
149
+ ],
150
+ "items": {
151
+ "$ref": "#/definitions/toolName"
152
+ }
153
+ },
154
+ "limits": {
155
+ "type": "object",
156
+ "additionalProperties": false,
157
+ "properties": {
158
+ "maxToolCalls": {
159
+ "type": "integer",
160
+ "minimum": 1,
161
+ "default": 120
162
+ },
163
+ "maxBytesPerToolResult": {
164
+ "type": "integer",
165
+ "minimum": 1,
166
+ "default": 1000000
167
+ },
168
+ "maxTotalContextBytes": {
169
+ "type": "integer",
170
+ "minimum": 1,
171
+ "default": 8000000
172
+ },
173
+ "timeoutMs": {
174
+ "type": "integer",
175
+ "minimum": 1,
176
+ "default": 60000
177
+ }
178
+ }
179
+ },
180
+ "permissions": {
181
+ "type": "object",
182
+ "additionalProperties": false,
183
+ "properties": {
184
+ "readRepo": {
185
+ "type": "boolean",
186
+ "default": true
187
+ },
188
+ "readGitLab": {
189
+ "type": "boolean",
190
+ "default": true
191
+ },
192
+ "shell": {
193
+ "type": "boolean",
194
+ "default": false
195
+ },
196
+ "network": {
197
+ "type": "boolean",
198
+ "default": false
199
+ },
200
+ "write": {
201
+ "type": "boolean",
202
+ "default": false
203
+ }
204
+ }
205
+ }
206
+ }
207
+ }
208
+ },
209
+ "definitions": {
210
+ "toolName": {
211
+ "type": "string",
212
+ "enum": [
213
+ "read_diff",
214
+ "read_file",
215
+ "repo_search",
216
+ "read_gitlab_mr",
217
+ "read_gitlab_issue",
218
+ "list_gitlab_issues",
219
+ "list_gitlab_mrs",
220
+ "read_gitlab_mr_discussions"
221
+ ]
222
+ }
223
+ }
224
+ }
package/LICENSE.md ADDED
@@ -0,0 +1,24 @@
1
+ # The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Ke Jin (jinke5245)
4
+
5
+ Permission is hereby granted, free of charge, to any person
6
+ obtaining a copy of this software and associated documentation
7
+ files (the “Software”), to deal in the Software without
8
+ restriction, including without limitation the rights to use,
9
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the
11
+ Software is furnished to do so, subject to the following
12
+ conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+ OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # Code Reviewer
2
+
3
+ Code Reviewer is an early-stage AI-assisted code review CLI. It aims to provide
4
+ a review experience similar to GitHub Copilot Code Review while keeping the core
5
+ review engine portable across code hosting platforms.
6
+
7
+ The current implementation supports GitLab merge request review. GitHub support,
8
+ platform adapters, and skill-defined custom tools are planned follow-up
9
+ milestones.
10
+
11
+ ## Agent Quick Start
12
+
13
+ Copy this prompt to your coding agent when you want it to wire Code Reviewer
14
+ into a repository:
15
+
16
+ ```text
17
+ Configure Code Reviewer for this repository.
18
+ Use the setup instructions from:
19
+ https://gitlab.com/jinke5245/code-reviewer/-/blob/main/README.md
20
+ ```
21
+
22
+ Code Reviewer runs in a merge request pipeline, reads the current MR metadata and
23
+ diff, asks an OpenAI-compatible model to review the change, and publishes the
24
+ review back to the merge request.
25
+
26
+ The setup usually needs three pieces:
27
+
28
+ - `.codereviewer.yml`: Code Reviewer configuration.
29
+ - `.gitlab-ci.yml`: a review job, usually triggered manually.
30
+ - GitLab CI/CD variables: `OPENAI_API_KEY`, `OPENAI_MODEL`, and `GITLAB_TOKEN`
31
+ or `GL_TOKEN`; private model gateways also need `OPENAI_BASE_URL`.
32
+
33
+ ## Step 1: Create `.codereviewer.yml`
34
+
35
+ Create `.codereviewer.yml` at the repository root with the key fields below:
36
+
37
+ ```yaml
38
+ # yaml-language-server: $schema=https://gitlab.com/jinke5245/code-reviewer/-/raw/main/.schemas/code-reviewer.schema.json
39
+ gitlab:
40
+ publish: inline
41
+ review:
42
+ maxRounds: 12
43
+ prompts:
44
+ extraRules:
45
+ - Write review summaries, findings, and suggestions in Chinese.
46
+ - Keep comments concise and focused on actionable issues.
47
+ - >-
48
+ When a finding has a safe direct replacement anchored to the selected diff
49
+ range, populate replacementCode with the complete replacement code so
50
+ GitLab can render an applyable suggestion block.
51
+ - >-
52
+ Prefer targeted reads over broad file sweeps; stop gathering context once
53
+ findings are supported.
54
+ tools:
55
+ limits:
56
+ maxToolCalls: 120
57
+ ```
58
+
59
+ Configuration sources are checked in this order:
60
+
61
+ 1. The explicit `--config <path>` value.
62
+ 2. `.codereviewer.yml`.
63
+ 3. `.codereviewer.yaml`.
64
+ 4. `.codereviewer.json`.
65
+ 5. `.codereviewer.jsonc`.
66
+ 6. `package.json#codereviewer`.
67
+ 7. `pyproject.toml#[tool.codereviewer]`.
68
+ 8. `Cargo.toml#[package.metadata.codereviewer]`.
69
+ 9. Built-in defaults.
70
+
71
+ Prefer `.codereviewer.yml` for first-time setup. Do not store API keys, GitLab
72
+ tokens, or other secrets in configuration files.
73
+
74
+ ## Step 2: Configure GitLab CI/CD Variables
75
+
76
+ Configure these variables in the target GitLab project:
77
+
78
+ - `OPENAI_API_KEY`: API key for the OpenAI-compatible model endpoint.
79
+ - `OPENAI_MODEL`: model name used for review.
80
+ - `OPENAI_BASE_URL`: optional private model gateway URL.
81
+ - `GITLAB_TOKEN` or `GL_TOKEN`: token used to read merge request context,
82
+ diffs, discussions, and publish review notes.
83
+
84
+ Code Reviewer reads `GITLAB_TOKEN` first and falls back to `GL_TOKEN`.
85
+
86
+ ## Step 3: Add a GitLab Review Job
87
+
88
+ Add a review job to `.gitlab-ci.yml`. Manual review jobs are recommended because
89
+ AI review is often most useful on demand, not on every temporary push.
90
+
91
+ ```yaml
92
+ stages:
93
+ - review
94
+
95
+ ai-code-review:
96
+ image: node:22-bookworm-slim
97
+ stage: review
98
+ before_script:
99
+ - npm install -g @jinke5245/code-reviewer
100
+ script:
101
+ - codereviewer --version
102
+ - codereviewer review
103
+ rules:
104
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
105
+ when: manual
106
+ allow_failure: true
107
+ - when: never
108
+ ```
109
+
110
+ If the project already has `stages`, only add `review` if it is missing. Remove
111
+ `when: manual` if the team wants every merge request pipeline to run AI review
112
+ automatically.
113
+
114
+ ## Step 4: Verify the First Review
115
+
116
+ Trigger `ai-code-review` from a merge request pipeline. A successful setup should
117
+ show:
118
+
119
+ - `codereviewer --version` prints the installed version.
120
+ - The job log shows review progress and final JSON.
121
+ - With `gitlab.publish: inline`, the MR receives one summary note and inline
122
+ discussions for findings that can be mapped to exact diff lines.
123
+
124
+ For debugging, run:
125
+
126
+ ```sh
127
+ codereviewer review --dry-run --verbose
128
+ ```
129
+
130
+ Verbose logs go to stderr and include configuration, MR context, prompt byte
131
+ counts, model rounds, tool call summaries, and tool result sizes. The final
132
+ review JSON still goes to stdout so CI steps can parse it.
133
+
134
+ ## Configuration Reference
135
+
136
+ See [Configuration](docs/configuration.md) for all fields, defaults, discovery
137
+ rules, templates, tools, permissions, and model response format behavior. Start
138
+ with the minimal `.codereviewer.yml` above, then use the reference only when you
139
+ need to tune model settings, publish mode, prompts, templates, or tool limits.
140
+
141
+ ## Troubleshooting
142
+
143
+ - `codereviewer --version` prints nothing: confirm the package installed
144
+ successfully and the job uses a supported Node.js version.
145
+ - `CI_MERGE_REQUEST_IID` is missing: the job is not running in a merge request
146
+ pipeline; check the `rules`.
147
+ - GitLab token is missing: configure `GITLAB_TOKEN` or `GL_TOKEN`.
148
+ - Model name is missing: configure `OPENAI_MODEL` or set `model.model` in the
149
+ config file.
150
+ - The model gateway rejects structured response formats: keep
151
+ `model.responseFormat: auto`, which falls back from `json_schema` to
152
+ `json_object` to prompt-only JSON output.
153
+ - Inline mode succeeds but no line-level threads appear: check the MR summary
154
+ note first. Only findings anchored to exact diff lines become inline
155
+ discussions.
156
+ - The review path is unclear: run `codereviewer review --dry-run --verbose`.
157
+ Verbose logs do not include full prompts, raw model responses, or raw tool
158
+ results.
159
+
160
+ ## Development
161
+
162
+ Install dependencies with pnpm:
163
+
164
+ ```sh
165
+ pnpm install
166
+ ```
167
+
168
+ Run checks:
169
+
170
+ ```sh
171
+ pnpm check
172
+ ```
173
+
174
+ Live OpenAI-compatible integration tests are skipped by default. To run them,
175
+ provide model environment variables and opt in:
176
+
177
+ ```sh
178
+ RUN_LIVE_OPENAI_TESTS=true pnpm test tests/integration/openai-compatible-live.test.ts
179
+ ```
180
+
181
+ See [Development](docs/development.md) for local commands, tests, build, and
182
+ packaging notes.