@krotovm/gitlab-ai-review 1.0.3 → 1.0.5

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/README.md CHANGED
@@ -8,28 +8,16 @@ Gitlab AI Code Review is a CLI tool that leverages OpenAI models to automaticall
8
8
  - Provides feedback on code clarity, simplicity, bugs, and security issues
9
9
  - Generates Markdown-formatted responses for easy readability in GitLab
10
10
 
11
- ## GitLab CI usage (recommended)
11
+ ## Usage
12
12
 
13
- This repo now includes a CLI you can run in a dedicated GitLab CI job. It is designed to run in **Merge Request pipelines** and will post a **new comment** on the MR with the AI review.
13
+ ### GitLab CI/CD
14
14
 
15
- ### Required CI variables
15
+ Run the tool in Merge Request pipelines to post a new AI review comment to the MR.
16
16
 
17
- - `OPENAI_API_KEY`
18
- - `AI_MODEL` (optional, default: `gpt-4o-mini`; examples: `gpt-4o`)
19
- - `PROJECT_ACCESS_TOKEN` (recommended for private projects; Project or Personal Access Token with `api` scope)
20
-
21
- GitLab provides these automatically in CI:
22
-
23
- - `CI_API_V4_URL`
24
- - `CI_PROJECT_ID`
25
- - `CI_MERGE_REQUEST_IID`
26
- - `CI_JOB_TOKEN` (used only when `PROJECT_ACCESS_TOKEN` is not set)
27
-
28
- ### Example `.gitlab-ci.yml`
17
+ Minimal MR review job:
29
18
 
30
19
  ```yaml
31
- stages:
32
- - review
20
+ stages: [review]
33
21
 
34
22
  ai_review:
35
23
  stage: review
@@ -37,31 +25,47 @@ ai_review:
37
25
  rules:
38
26
  - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
39
27
  script:
40
- - corepack enable
41
- - pnpm install --frozen-lockfile
42
- - pnpm build:ts
43
- - node dist/cli.js
28
+ - npx -y @krotovm/gitlab-ai-review --ci
44
29
  ```
45
30
 
46
- ## Local usage
31
+ ### Local CLI
47
32
 
48
- You can also run the CLI locally to review diffs and print the review to the console.
49
-
50
- ### Review uncommitted changes (staged + unstaged)
33
+ Run locally to review diffs and print the review to stdout.
51
34
 
52
35
  ```bash
53
- OPENAI_API_KEY=... AI_MODEL=gpt-4o node dist/cli.js --worktree
36
+ # review local uncommitted changes
37
+ OPENAI_API_KEY=... npx -y @krotovm/gitlab-ai-review --worktree
38
+
39
+ # review last commit and ignore docs/lock changes by extension
40
+ OPENAI_API_KEY=... npx -y @krotovm/gitlab-ai-review --last-commit --ignore-ext=md,lock
54
41
  ```
55
42
 
56
- ### Review last commit (HEAD)
43
+ ## Env variables
57
44
 
58
- ```bash
59
- OPENAI_API_KEY=... AI_MODEL=gpt-4o node dist/cli.js --last-commit
60
- ```
45
+ Set these in your project/group CI settings (or locally in your shell):
61
46
 
62
- ## Installation
47
+ - `OPENAI_API_KEY` (required)
48
+ - `OPENAI_BASE_URL` (optional, for OpenAI-compatible providers/proxies)
49
+ - `AI_MODEL` (optional, default: `gpt-4o-mini`; example: `gpt-4o`)
50
+ - `PROJECT_ACCESS_TOKEN` (optional but recommended for private projects; token with `api` scope)
63
51
 
64
- ```bash
65
- pnpm install
66
- pnpm build:ts
67
- ```
52
+ GitLab provides these automatically in Merge Request pipelines:
53
+
54
+ - `CI_API_V4_URL`
55
+ - `CI_PROJECT_ID`
56
+ - `CI_MERGE_REQUEST_IID`
57
+ - `CI_JOB_TOKEN` (used only when `PROJECT_ACCESS_TOKEN` is not provided)
58
+
59
+ ## Flags
60
+
61
+ - `--ci` - Run in GitLab MR pipeline mode and post a new MR note.
62
+ - `--worktree` - Review local uncommitted changes (staged + unstaged).
63
+ - `--last-commit` - Review the last commit (`HEAD`).
64
+ - `--ignore-ext=md,lock` - Exclude file extensions from review (comma-separated only).
65
+ - `--max-old-files=30` - Max number of pre-change files included in the prompt.
66
+ - `--max-old-file-chars=12000` - Max chars per pre-change file content.
67
+ - `--max-diffs=50` - Max number of diffs included in the prompt.
68
+ - `--max-diff-chars=16000` - Max chars per diff chunk.
69
+ - `--max-total-prompt-chars=220000` - Final hard cap for prompt size.
70
+ - `--debug` - Print full error details (stack and API error fields).
71
+ - `--help` - Show help output.
package/dist/cli.js CHANGED
@@ -1,120 +1,222 @@
1
1
  #!/usr/bin/env node
2
- import OpenAI from 'openai';
3
- import { buildAnswer, buildPrompt } from './prompt/index.js';
4
- import { fetchMergeRequestChanges, fetchPreEditFiles, generateAICompletion, postMergeRequestNote } from './gitlab/services.js';
2
+ /** @format */
3
+ import OpenAI from "openai";
4
+ import { buildAnswer, buildPrompt, DEFAULT_PROMPT_LIMITS, } from "./prompt/index.js";
5
+ import { fetchMergeRequestChanges, fetchPreEditFiles, generateAICompletion, postMergeRequestNote, } from "./gitlab/services.js";
5
6
  function printHelp() {
6
7
  process.stdout.write([
7
- 'gitlab-ai-review',
8
- '',
9
- 'Usage:',
10
- ' gitlab-ai-review --ci',
11
- ' gitlab-ai-review --worktree',
12
- ' gitlab-ai-review --last-commit',
13
- ' gitlab-ai-review --help',
14
- ' gitlab-ai-review --debug',
15
- '',
16
- 'Modes (choose one):',
17
- ' --ci Run in GitLab MR pipeline: fetch MR changes and post a new MR note.',
18
- ' --worktree Review local uncommitted changes (staged + unstaged) and print to stdout.',
19
- ' --last-commit Review last commit (HEAD) and print to stdout.',
20
- '',
21
- 'Debug:',
22
- ' --debug Print full error details (stack, API error fields).',
23
- '',
24
- 'Env vars:',
25
- ' OPENAI_API_KEY (required) OpenAI API key.',
26
- ' AI_MODEL (optional) OpenAI chat model, e.g. gpt-4o. Default: gpt-4o-mini.',
27
- ' PROJECT_ACCESS_TOKEN (optional) GitLab Project/Personal Access Token for API calls (recommended for private projects).',
28
- '',
29
- 'CI-only env vars (provided by GitLab):',
30
- ' CI_API_V4_URL, CI_PROJECT_ID, CI_MERGE_REQUEST_IID, CI_JOB_TOKEN (only if PROJECT_ACCESS_TOKEN is not set)',
31
- '',
32
- 'Notes:',
33
- ' - If no mode is specified, it defaults to --ci when CI_MERGE_REQUEST_IID is set, otherwise --worktree.',
34
- ''
35
- ].join('\n'));
8
+ "gitlab-ai-review",
9
+ "",
10
+ "Usage:",
11
+ " gitlab-ai-review --ci",
12
+ " gitlab-ai-review --worktree",
13
+ " gitlab-ai-review --last-commit",
14
+ " gitlab-ai-review --help",
15
+ " gitlab-ai-review --debug",
16
+ " gitlab-ai-review --ci --ignore-ext=md,lock",
17
+ "",
18
+ "Modes (choose one):",
19
+ " --ci Run in GitLab MR pipeline: fetch MR changes and post a new MR note.",
20
+ " --worktree Review local uncommitted changes (staged + unstaged) and print to stdout.",
21
+ " --last-commit Review last commit (HEAD) and print to stdout.",
22
+ "",
23
+ "Debug:",
24
+ " --debug Print full error details (stack, API error fields).",
25
+ " --ignore-ext Ignore file extensions (comma-separated only). Example: --ignore-ext=md,lock",
26
+ " --max-old-files=30",
27
+ " --max-old-file-chars=12000",
28
+ " --max-diffs=50",
29
+ " --max-diff-chars=16000",
30
+ " --max-total-prompt-chars=220000",
31
+ "",
32
+ "Env vars:",
33
+ " OPENAI_API_KEY (required) OpenAI API key.",
34
+ " OPENAI_BASE_URL (optional) Custom OpenAI-compatible API base URL.",
35
+ " AI_MODEL (optional) OpenAI chat model, e.g. gpt-4o. Default: gpt-4o-mini.",
36
+ " PROJECT_ACCESS_TOKEN (optional) GitLab Project/Personal Access Token for API calls (recommended for private projects).",
37
+ "",
38
+ "CI-only env vars (provided by GitLab):",
39
+ " CI_API_V4_URL, CI_PROJECT_ID, CI_MERGE_REQUEST_IID, CI_JOB_TOKEN (only if PROJECT_ACCESS_TOKEN is not set)",
40
+ "",
41
+ "Notes:",
42
+ " - If no mode is specified, it defaults to --ci when CI_MERGE_REQUEST_IID is set, otherwise --worktree.",
43
+ "",
44
+ ].join("\n"));
36
45
  }
37
46
  function requiredEnv(name) {
38
47
  const value = process.env[name];
39
- if (value == null || value.trim() === '') {
48
+ if (value == null || value.trim() === "") {
40
49
  throw new Error(`Missing required env var: ${name}`);
41
50
  }
42
51
  return value;
43
52
  }
53
+ function requireEnvs(names) {
54
+ const missing = names.filter((name) => {
55
+ const value = process.env[name];
56
+ return value == null || value.trim() === "";
57
+ });
58
+ if (missing.length > 0) {
59
+ throw new Error(`Missing required env vars: ${missing.join(", ")}`);
60
+ }
61
+ const result = {};
62
+ for (const name of names) {
63
+ result[name] = process.env[name].trim();
64
+ }
65
+ return result;
66
+ }
44
67
  function envOrDefault(name, defaultValue) {
45
68
  const value = process.env[name];
46
69
  if (value == null)
47
70
  return defaultValue;
48
71
  const trimmed = value.trim();
49
- return trimmed === '' ? defaultValue : trimmed;
72
+ return trimmed === "" ? defaultValue : trimmed;
50
73
  }
51
74
  function envOrUndefined(name) {
52
75
  const value = process.env[name];
53
76
  if (value == null)
54
77
  return undefined;
55
78
  const trimmed = value.trim();
56
- return trimmed === '' ? undefined : trimmed;
79
+ return trimmed === "" ? undefined : trimmed;
57
80
  }
58
81
  function hasDebugFlag(argv) {
59
82
  const args = new Set(argv.slice(2));
60
- return args.has('--debug');
83
+ return args.has("--debug");
84
+ }
85
+ function parseIgnoreExtensions(argv) {
86
+ const parsed = [];
87
+ const args = argv.slice(2);
88
+ for (const current of args) {
89
+ if (current === "--ignore-ext") {
90
+ throw new Error("Use comma-separated format: --ignore-ext=md,lock");
91
+ }
92
+ if (!current.startsWith("--ignore-ext="))
93
+ continue;
94
+ const value = current.slice("--ignore-ext=".length);
95
+ if (value.trim() === "")
96
+ continue;
97
+ const pieces = value
98
+ .split(",")
99
+ .map((part) => part.trim().toLowerCase())
100
+ .filter(Boolean);
101
+ for (const piece of pieces) {
102
+ parsed.push(piece.startsWith(".") ? piece : `.${piece}`);
103
+ }
104
+ }
105
+ return Array.from(new Set(parsed));
106
+ }
107
+ function parseNumberFlag(argv, flagName, defaultValue, minValue) {
108
+ const prefix = `--${flagName}=`;
109
+ let value = defaultValue;
110
+ for (const arg of argv.slice(2)) {
111
+ if (!arg.startsWith(prefix))
112
+ continue;
113
+ const raw = arg.slice(prefix.length).trim();
114
+ if (raw === "") {
115
+ throw new Error(`Missing value for --${flagName}. Expected integer.`);
116
+ }
117
+ const parsed = Number(raw);
118
+ if (!Number.isInteger(parsed) || parsed < minValue) {
119
+ throw new Error(`Invalid value for --${flagName}: "${raw}". Expected integer >= ${minValue}.`);
120
+ }
121
+ value = parsed;
122
+ }
123
+ return value;
124
+ }
125
+ function parsePromptLimits(argv) {
126
+ return {
127
+ maxOldFiles: parseNumberFlag(argv, "max-old-files", DEFAULT_PROMPT_LIMITS.maxOldFiles, 0),
128
+ maxOldFileChars: parseNumberFlag(argv, "max-old-file-chars", DEFAULT_PROMPT_LIMITS.maxOldFileChars, 1),
129
+ maxDiffs: parseNumberFlag(argv, "max-diffs", DEFAULT_PROMPT_LIMITS.maxDiffs, 0),
130
+ maxDiffChars: parseNumberFlag(argv, "max-diff-chars", DEFAULT_PROMPT_LIMITS.maxDiffChars, 1),
131
+ maxTotalPromptChars: parseNumberFlag(argv, "max-total-prompt-chars", DEFAULT_PROMPT_LIMITS.maxTotalPromptChars, 1),
132
+ };
133
+ }
134
+ function hasIgnoredExtension(filePath, ignoredExtensions) {
135
+ const lowerPath = filePath.toLowerCase();
136
+ return ignoredExtensions.some((ext) => lowerPath.endsWith(ext));
137
+ }
138
+ function buildGitExcludePathspecs(ignoredExtensions) {
139
+ return ignoredExtensions.map((ext) => `:(exclude,glob)**/*${ext}`);
61
140
  }
62
141
  function parseMode(argv) {
63
142
  const args = new Set(argv.slice(2));
64
- if (args.has('--help') || args.has('-h')) {
143
+ if (args.has("--help") || args.has("-h")) {
65
144
  printHelp();
66
145
  process.exit(0);
67
146
  }
68
- const hasCi = args.has('--ci');
69
- const hasWorktree = args.has('--worktree');
70
- const hasLastCommit = args.has('--last-commit');
147
+ const hasCi = args.has("--ci");
148
+ const hasWorktree = args.has("--worktree");
149
+ const hasLastCommit = args.has("--last-commit");
71
150
  const count = Number(hasCi) + Number(hasWorktree) + Number(hasLastCommit);
72
151
  if (count > 1) {
73
- throw new Error('Choose only one mode: --ci, --worktree, or --last-commit');
152
+ throw new Error("Choose only one mode: --ci, --worktree, or --last-commit");
74
153
  }
75
154
  if (hasCi)
76
- return 'ci';
155
+ return "ci";
77
156
  if (hasWorktree)
78
- return 'worktree';
157
+ return "worktree";
79
158
  if (hasLastCommit)
80
- return 'last-commit';
81
- if (process.env.CI_MERGE_REQUEST_IID != null)
82
- return 'ci';
83
- return 'worktree';
159
+ return "last-commit";
160
+ const mergeRequestIid = process.env.CI_MERGE_REQUEST_IID;
161
+ if (mergeRequestIid != null && mergeRequestIid.trim() !== "")
162
+ return "ci";
163
+ return "worktree";
164
+ }
165
+ function logStep(message) {
166
+ process.stdout.write(`${message}\n`);
84
167
  }
85
168
  async function runGit(args) {
86
- const { spawn } = await import('node:child_process');
169
+ const { spawn } = await import("node:child_process");
87
170
  return await new Promise((resolve, reject) => {
88
- const child = spawn('git', args, { stdio: ['ignore', 'pipe', 'pipe'] });
89
- let stdout = '';
90
- let stderr = '';
91
- child.stdout.on('data', (d) => { stdout += String(d); });
92
- child.stderr.on('data', (d) => { stderr += String(d); });
93
- child.on('error', reject);
94
- child.on('close', (code) => {
171
+ const child = spawn("git", args, { stdio: ["ignore", "pipe", "pipe"] });
172
+ let stdout = "";
173
+ let stderr = "";
174
+ child.stdout.on("data", (d) => {
175
+ stdout += String(d);
176
+ });
177
+ child.stderr.on("data", (d) => {
178
+ stderr += String(d);
179
+ });
180
+ child.on("error", reject);
181
+ child.on("close", (code) => {
95
182
  if (code === 0)
96
183
  return resolve(stdout);
97
- reject(new Error(stderr.trim() || `git ${args.join(' ')} failed with exit code ${code}`));
184
+ reject(new Error(stderr.trim() ||
185
+ `git ${args.join(" ")} failed with exit code ${code}`));
98
186
  });
99
187
  });
100
188
  }
101
189
  async function localDiffWorktree() {
102
- const unstaged = await runGit(['diff']);
103
- const staged = await runGit(['diff', '--staged']);
104
- const combined = [staged.trim(), unstaged.trim()].filter(Boolean).join('\n\n');
190
+ const ignoreExtensions = parseIgnoreExtensions(process.argv);
191
+ const pathspecs = buildGitExcludePathspecs(ignoreExtensions);
192
+ const unstagedArgs = pathspecs.length > 0 ? ["diff", "--", ...pathspecs] : ["diff"];
193
+ const stagedArgs = pathspecs.length > 0
194
+ ? ["diff", "--staged", "--", ...pathspecs]
195
+ : ["diff", "--staged"];
196
+ const unstaged = await runGit(unstagedArgs);
197
+ const staged = await runGit(stagedArgs);
198
+ const combined = [staged.trim(), unstaged.trim()]
199
+ .filter(Boolean)
200
+ .join("\n\n");
105
201
  return combined;
106
202
  }
107
203
  async function localDiffLastCommit() {
204
+ const ignoreExtensions = parseIgnoreExtensions(process.argv);
205
+ const pathspecs = buildGitExcludePathspecs(ignoreExtensions);
108
206
  // show patch for HEAD, but avoid commit message metadata
109
- return await runGit(['show', '--format=', 'HEAD']);
207
+ const args = pathspecs.length > 0
208
+ ? ["show", "--format=", "HEAD", "--", ...pathspecs]
209
+ : ["show", "--format=", "HEAD"];
210
+ return await runGit(args);
110
211
  }
111
- async function reviewDiffToConsole(diff, openaiApiKey, aiModel) {
112
- if (diff.trim() === '') {
113
- process.stdout.write('No diff found. Skipping review.\n');
212
+ async function reviewDiffToConsole(diff, openaiApiKey, aiModel, promptLimits) {
213
+ if (diff.trim() === "") {
214
+ process.stdout.write("No diff found. Skipping review.\n");
114
215
  return;
115
216
  }
116
217
  const messageParams = buildPrompt({
117
- changes: [{ diff }]
218
+ changes: [{ diff }],
219
+ limits: promptLimits,
118
220
  });
119
221
  const openaiInstance = new OpenAI({ apiKey: openaiApiKey });
120
222
  const completion = await generateAICompletion(messageParams, openaiInstance, aiModel);
@@ -123,78 +225,111 @@ async function reviewDiffToConsole(diff, openaiApiKey, aiModel) {
123
225
  }
124
226
  async function main() {
125
227
  const mode = parseMode(process.argv);
126
- const openaiApiKey = requiredEnv('OPENAI_API_KEY');
127
- const aiModel = envOrDefault('AI_MODEL', 'gpt-4o-mini');
128
- if (mode === 'worktree') {
228
+ const ignoredExtensions = parseIgnoreExtensions(process.argv);
229
+ const promptLimits = parsePromptLimits(process.argv);
230
+ const aiModel = envOrDefault("AI_MODEL", "gpt-4o-mini");
231
+ if (mode === "worktree") {
232
+ logStep("Collecting local changes");
233
+ const openaiEnvs = requireEnvs(["OPENAI_API_KEY"]);
234
+ const openaiApiKey = openaiEnvs["OPENAI_API_KEY"];
129
235
  const diff = await localDiffWorktree();
130
- await reviewDiffToConsole(diff, openaiApiKey, aiModel);
236
+ logStep(`Requesting AI completion with model: ${aiModel}`);
237
+ await reviewDiffToConsole(diff, openaiApiKey, aiModel, promptLimits);
131
238
  return;
132
239
  }
133
- if (mode === 'last-commit') {
240
+ if (mode === "last-commit") {
241
+ logStep("Collecting HEAD diff");
242
+ const openaiEnvs = requireEnvs(["OPENAI_API_KEY"]);
243
+ const openaiApiKey = openaiEnvs["OPENAI_API_KEY"];
134
244
  const diff = await localDiffLastCommit();
135
- await reviewDiffToConsole(diff, openaiApiKey, aiModel);
245
+ logStep(`Requesting AI completion with model: ${aiModel}`);
246
+ await reviewDiffToConsole(diff, openaiApiKey, aiModel, promptLimits);
136
247
  return;
137
248
  }
138
- const ciApiV4Url = requiredEnv('CI_API_V4_URL');
139
- const projectId = requiredEnv('CI_PROJECT_ID');
140
- const mergeRequestIid = requiredEnv('CI_MERGE_REQUEST_IID');
249
+ const projectAccessToken = envOrUndefined("PROJECT_ACCESS_TOKEN") ?? envOrUndefined("GITLAB_TOKEN");
250
+ const gitlabRequired = [
251
+ "OPENAI_API_KEY",
252
+ "CI_API_V4_URL",
253
+ "CI_PROJECT_ID",
254
+ "CI_MERGE_REQUEST_IID",
255
+ ];
256
+ if (projectAccessToken == null) {
257
+ gitlabRequired.push("CI_JOB_TOKEN");
258
+ }
259
+ const gitlabEnvs = requireEnvs(gitlabRequired);
260
+ const openaiApiKey = gitlabEnvs["OPENAI_API_KEY"];
261
+ const ciApiV4Url = gitlabEnvs["CI_API_V4_URL"];
262
+ const projectId = gitlabEnvs["CI_PROJECT_ID"];
263
+ const mergeRequestIid = gitlabEnvs["CI_MERGE_REQUEST_IID"];
141
264
  const gitLabBaseUrl = new URL(ciApiV4Url);
142
- const projectAccessToken = envOrUndefined('PROJECT_ACCESS_TOKEN') ?? envOrUndefined('GITLAB_TOKEN');
143
265
  const headers = {};
144
266
  if (projectAccessToken != null) {
145
- headers['PRIVATE-TOKEN'] = projectAccessToken;
267
+ headers["PRIVATE-TOKEN"] = projectAccessToken;
146
268
  }
147
269
  else {
148
- headers['JOB-TOKEN'] = requiredEnv('CI_JOB_TOKEN');
270
+ headers["JOB-TOKEN"] = gitlabEnvs["CI_JOB_TOKEN"];
149
271
  }
272
+ logStep("Fetching merge request changes");
150
273
  const mrChanges = await fetchMergeRequestChanges({
151
274
  gitLabBaseUrl,
152
275
  headers,
153
276
  projectId,
154
- mergeRequestIid
277
+ mergeRequestIid,
155
278
  });
156
279
  if (mrChanges instanceof Error)
157
280
  throw mrChanges;
158
281
  const changes = mrChanges.changes ?? [];
159
- if (changes.length === 0) {
160
- process.stdout.write('No changes found in merge request. Skipping review.\n');
282
+ const filteredChanges = ignoredExtensions.length === 0
283
+ ? changes
284
+ : changes.filter((change) => !hasIgnoredExtension(change.new_path, ignoredExtensions) &&
285
+ !hasIgnoredExtension(change.old_path, ignoredExtensions));
286
+ if (filteredChanges.length === 0) {
287
+ process.stdout.write("No changes found in merge request. Skipping review.\n");
161
288
  return;
162
289
  }
163
290
  const baseSha = mrChanges.diff_refs?.base_sha;
164
- const ref = baseSha ?? 'HEAD';
165
- const changesOldPaths = changes.map(c => c.old_path);
291
+ const ref = baseSha ?? "HEAD";
292
+ const changesOldPaths = filteredChanges.map((c) => c.old_path);
293
+ logStep("Fetching pre-edit file versions");
166
294
  const oldFiles = await fetchPreEditFiles({
167
295
  gitLabBaseUrl: new URL(`${ciApiV4Url}/projects/${projectId}`),
168
296
  headers,
169
297
  changesOldPaths,
170
- ref
298
+ ref,
171
299
  });
172
300
  if (oldFiles instanceof Error)
173
301
  throw oldFiles;
302
+ logStep("Building prompt");
174
303
  const messageParams = buildPrompt({
175
304
  oldFiles,
176
- changes: changes.map(c => ({ diff: c.diff }))
305
+ changes: filteredChanges.map((c) => ({ diff: c.diff })),
306
+ limits: promptLimits,
177
307
  });
308
+ logStep(`Requesting AI completion with model: ${aiModel}`);
178
309
  const openaiInstance = new OpenAI({ apiKey: openaiApiKey });
179
310
  const completion = await generateAICompletion(messageParams, openaiInstance, aiModel);
180
311
  const answer = buildAnswer(completion);
312
+ logStep("Posting AI review note to merge request");
181
313
  const noteRes = await postMergeRequestNote({
182
314
  gitLabBaseUrl: new URL(`${ciApiV4Url}/projects/${projectId}`),
183
315
  headers,
184
- mergeRequestIid
316
+ mergeRequestIid,
185
317
  }, { body: answer });
186
318
  if (noteRes instanceof Error)
187
319
  throw noteRes;
188
- process.stdout.write('Posted AI review comment to merge request.\n');
320
+ process.stdout.write("Posted AI review comment to merge request.\n");
189
321
  }
190
322
  main().catch((err) => {
191
323
  const message = err instanceof Error ? err.message : String(err);
192
324
  process.stderr.write(`${message}\n`);
325
+ const anyErr = err;
326
+ if (anyErr?.name === "FAILED_TO_POST_COMMENT" && anyErr?.cause != null) {
327
+ process.stderr.write(`Cause: ${JSON.stringify(anyErr.cause)}\n`);
328
+ }
193
329
  if (hasDebugFlag(process.argv)) {
194
330
  if (err instanceof Error && err.stack != null) {
195
331
  process.stderr.write(`\nStack:\n${err.stack}\n`);
196
332
  }
197
- const anyErr = err;
198
333
  const debugInfo = {
199
334
  name: anyErr?.name,
200
335
  message: anyErr?.message,
@@ -204,7 +339,13 @@ main().catch((err) => {
204
339
  request_id: anyErr?.request_id,
205
340
  headers: anyErr?.headers,
206
341
  error: anyErr?.error,
207
- cause: anyErr?.cause instanceof Error ? { name: anyErr.cause.name, message: anyErr.cause.message, stack: anyErr.cause.stack } : anyErr?.cause
342
+ cause: anyErr?.cause instanceof Error
343
+ ? {
344
+ name: anyErr.cause.name,
345
+ message: anyErr.cause.message,
346
+ stack: anyErr.cause.stack,
347
+ }
348
+ : anyErr?.cause,
208
349
  };
209
350
  process.stderr.write(`\nDebug:\n${JSON.stringify(debugInfo, null, 2)}\n`);
210
351
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -11,8 +11,12 @@ export const fetchPreEditFiles = async ({ gitLabBaseUrl, headers, changesOldPath
11
11
  let oldFiles;
12
12
  try {
13
13
  oldFiles = await Promise.allSettled(oldFilesRequestUrls.map(async (url) => {
14
- const file = await (await fetch(url, { headers: { ...headers } })).text();
15
- return file;
14
+ const res = await fetch(url, { headers: { ...headers } });
15
+ if (!res.ok) {
16
+ const bodyText = await res.text().catch(() => "");
17
+ throw new Error(`Failed to fetch old file: ${url.toString()} (status ${res.status} ${res.statusText}, body: ${bodyText.slice(0, 500)})`);
18
+ }
19
+ return await res.text();
16
20
  }));
17
21
  }
18
22
  catch (error) {
@@ -22,6 +26,10 @@ export const fetchPreEditFiles = async ({ gitLabBaseUrl, headers, changesOldPath
22
26
  return new GitLabError({
23
27
  name: "MISSING_OLD_FILES",
24
28
  message: "Failed to fetch old files",
29
+ cause: {
30
+ message: oldFiles.message,
31
+ stack: oldFiles.stack,
32
+ },
25
33
  });
26
34
  }
27
35
  return oldFiles.reduce((acc, file, index) => {
@@ -73,9 +81,30 @@ export const postMergeRequestNote = async ({ gitLabBaseUrl, headers, mergeReques
73
81
  aiComment = error;
74
82
  }
75
83
  if (aiComment instanceof Error || !aiComment.ok) {
84
+ const responseDetails = await (async () => {
85
+ if (aiComment instanceof Error) {
86
+ return {
87
+ url: commentUrl.toString(),
88
+ error: {
89
+ name: aiComment.name,
90
+ message: aiComment.message,
91
+ stack: aiComment.stack,
92
+ },
93
+ };
94
+ }
95
+ const bodyText = await aiComment.text().catch(() => "");
96
+ return {
97
+ url: commentUrl.toString(),
98
+ status: aiComment.status,
99
+ statusText: aiComment.statusText,
100
+ body: bodyText.slice(0, 4000),
101
+ };
102
+ })();
76
103
  return new GitLabError({
77
104
  name: "FAILED_TO_POST_COMMENT",
78
105
  message: "Failed to post AI comment",
106
+ statusCode: aiComment instanceof Error ? 502 : aiComment.status,
107
+ cause: responseDetails,
79
108
  });
80
109
  }
81
110
  };
@@ -1 +1 @@
1
- {"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/gitlab/services.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/gitlab/services.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,16 @@
1
+ export const DEFAULT_PROMPT_LIMITS = {
2
+ maxOldFiles: 30,
3
+ maxOldFileChars: 12000,
4
+ maxDiffs: 50,
5
+ maxDiffChars: 16000,
6
+ maxTotalPromptChars: 220000
7
+ };
8
+ function truncateWithMarker(value, maxChars, markerLabel) {
9
+ if (value.length <= maxChars)
10
+ return value;
11
+ const omitted = value.length - maxChars;
12
+ return `${value.slice(0, maxChars)}\n\n[... ${markerLabel} truncated, omitted ${omitted} chars ...]`;
13
+ }
1
14
  const QUESTIONS = `\n\nQuestions:\n
2
15
  1. Can you summarize the changes in a succinct bullet point list\n
3
16
  2. In the diff, are the added or changed code written in a clear and easy to understand way?\n
@@ -7,28 +20,41 @@ const QUESTIONS = `\n\nQuestions:\n
7
20
  6. Do you see any code that could induce security issues?\n\n`;
8
21
  const MESSAGES = [{
9
22
  role: 'system',
10
- content: 'You are a senior developer reviewing code changes.'
11
- },
12
- {
13
- role: 'assistant',
14
- content: 'Format the response so it renders nicely in GitLab, with nice and organized markdown (use code blocks if needed), and send just the response no comments on the request, when answering include a short version of the question, so we know what it is.'
23
+ content: 'You are a senior developer reviewing code changes. Format the response so it renders nicely in GitLab, with organized markdown (use code blocks if needed), and send only the review content. Include short question labels so each answer section is easy to identify.'
15
24
  }];
16
25
  export const AI_MODEL_TEMPERATURE = 0.2;
17
- export const buildPrompt = ({ changes, oldFiles }) => {
18
- const hasOldFiles = oldFiles != null && oldFiles.length > 0;
26
+ export const buildPrompt = ({ changes, oldFiles, limits }) => {
27
+ const effectiveLimits = {
28
+ ...DEFAULT_PROMPT_LIMITS,
29
+ ...(limits ?? {})
30
+ };
31
+ const oldFilesTrimmed = (oldFiles ?? [])
32
+ .slice(0, effectiveLimits.maxOldFiles)
33
+ .map((oldFile) => ({
34
+ fileName: oldFile.fileName,
35
+ fileContent: truncateWithMarker(oldFile.fileContent, effectiveLimits.maxOldFileChars, `old file "${oldFile.fileName}"`)
36
+ }));
37
+ const diffsTrimmed = changes
38
+ .slice(0, effectiveLimits.maxDiffs)
39
+ .map((change, index) => truncateWithMarker(change.diff, effectiveLimits.maxDiffChars, `diff #${index + 1}`));
40
+ const hasOldFiles = oldFilesTrimmed.length > 0;
41
+ const oldFilesText = hasOldFiles ? oldFilesTrimmed.map(oldFile => JSON.stringify(oldFile)).join('\n\n') : '(not provided)';
42
+ const changesText = diffsTrimmed.join('\n\n');
19
43
  const content = `
20
44
  As a senior developer, review the following code changes and answer code review questions about them. The code changes are provided as git diff strings.
21
45
  ${hasOldFiles ? 'The entire file before the change is provided for context. Make sure to keep it as a reference when reviewing the changes.' : 'No full pre-change file context is available; review based on the diff only.'}
46
+ Input safety constraints were applied to keep payload size bounded. If you see truncation markers, call out potential blind spots in your review.
22
47
 
23
48
  Files before changes:
24
- ${hasOldFiles ? oldFiles.map(oldFile => JSON.stringify(oldFile)).join('\n\n') : '(not provided)'}
49
+ ${oldFilesText}
25
50
 
26
51
  Changes:
27
- ${changes.map(change => change.diff).join('\n\n')}
52
+ ${changesText}
28
53
 
29
54
  ${QUESTIONS}
30
55
  `;
31
- return [...MESSAGES, { role: 'user', content }];
56
+ const boundedContent = truncateWithMarker(content, effectiveLimits.maxTotalPromptChars, 'prompt payload');
57
+ return [...MESSAGES, { role: 'user', content: boundedContent }];
32
58
  };
33
59
  const ERROR_ANSWER = 'I\'m sorry, I\'m not feeling well today. Please ask a human to review this code change.';
34
60
  const DISCLAIMER = 'This comment was generated by an artificial intelligence duck.';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompt/index.ts"],"names":[],"mappings":"AAGA,MAAM,SAAS,GAAG;;;;;;8DAM4C,CAAA;AAE9D,MAAM,QAAQ,GAAiC,CAAC;QAC9C,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,oDAAoD;KAC9D;IACD;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,yPAAyP;KACnQ,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAA;AAOvC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAyB,EAAgC,EAAE;IACxG,MAAM,WAAW,GAAG,QAAQ,IAAI,IAAI,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;IAC3D,MAAM,OAAO,GAAG;;MAEZ,WAAW,CAAC,CAAC,CAAC,4HAA4H,CAAC,CAAC,CAAC,8EAA8E;;;MAG3N,WAAW,CAAC,CAAC,CAAC,QAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,gBAAgB;;;MAG/F,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;;MAE/C,SAAS;KACV,CAAA;IAEH,OAAO,CAAC,GAAG,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;AACjD,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,yFAAyF,CAAA;AAE9G,MAAM,UAAU,GAAG,gEAAgE,CAAA;AAEnF,SAAS,sBAAsB,CAAE,KAAa;IAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;IACtD,+GAA+G;IAC/G,MAAM,UAAU,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAA;IAC1D,MAAM,eAAe,GAAG,UAAU,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,UAAU,CAAC,CAAC,CAAC,UAAU,CAAA;IACnF,OAAO,eAAe,CAAA;AACxB,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,UAA8C,EAAU,EAAE;IACpF,IAAI,UAAU,YAAY,KAAK,EAAE,CAAC;QAChC,MAAM,UAAU,GAAI,UAAkB,CAAC,KAAK,CAAA;QAC5C,MAAM,YAAY,GAAG,UAAU,YAAY,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;QACjF,OAAO,GAAG,YAAY,cAAc,UAAU,CAAC,OAAO,GAAG,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;IACnH,CAAC;IACD,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAC9D,OAAO,GAAG,YAAY,OAAO,UAAU,EAAE,CAAA;IAC3C,CAAC;IACD,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAA;IAC5D,MAAM,IAAI,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAA;IAC5C,OAAO,GAAG,IAAI,aAAa,UAAU,GAAG,CAAA;AAC1C,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompt/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@krotovm/gitlab-ai-review",
4
- "version": "1.0.3",
4
+ "version": "1.0.5",
5
5
  "description": "CLI tool to generate AI code reviews for GitLab merge requests and local diffs.",
6
6
  "main": "dist/cli.js",
7
7
  "bin": {