From 2b11979b66cbbd0a45a92730bff21a170f99a6bf Mon Sep 17 00:00:00 2001 From: ztimson Date: Sat, 27 Dec 2025 15:21:57 -0500 Subject: [PATCH] Update --- .env | 8 ++++++++ .gitignore | 1 + package-lock.json | 22 +++++++++++++++++---- package.json | 3 ++- src/review.mjs | 50 ++++++++++++++++++++++++++++++++--------------- 5 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 .env create mode 100644 .gitignore diff --git a/.env b/.env new file mode 100644 index 0000000..9fbf229 --- /dev/null +++ b/.env @@ -0,0 +1,8 @@ +GIT_HOST= +GIT_OWNER= +GIT_REPO= +GIT_TOKEN= +PULL_REQUEST= +AI_HOST= +AI_MODEL= +AI_TOKEN= diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..11ee758 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env.local diff --git a/package-lock.json b/package-lock.json index bfb1a27..454923e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,9 @@ "license": "ISC", "dependencies": { "@ztimson/ai-utils": "0.2.3", - "@ztimson/utils": "^0.28.3" + "@ztimson/node-utils": "^1.0.7", + "@ztimson/utils": "^0.28.3", + "dotenv": "^17.2.3" } }, "node_modules/@anthropic-ai/sdk": { @@ -311,9 +313,9 @@ } }, "node_modules/@ztimson/node-utils": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@ztimson/node-utils/-/node-utils-1.0.4.tgz", - "integrity": "sha512-EVI0CQYvrzRV7f9pmy13piyFfF9htYS4Kf2W/dW4HzSBEPTO//mGPZthWyQXnxvMeG6p3e5hAPlQ4hAmrRDv6A==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@ztimson/node-utils/-/node-utils-1.0.7.tgz", + "integrity": "sha512-BqrEMfW3/FKyYnTnL1uzxHUZFUeg2FaRGjL9tWAFkw8M99HcN9HoStdrPL6JfLSudvCwDbGzUJSEP6GL0E8uoQ==", "license": "MIT" }, "node_modules/@ztimson/utils": { @@ -682,6 +684,18 @@ "node": ">=8" } }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", diff --git a/package.json b/package.json index e361b29..6d4d020 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "description": "", "dependencies": { "@ztimson/ai-utils": "0.2.3", + "@ztimson/node-utils": "^1.0.7", "@ztimson/utils": "^0.28.3", - "@ztimson/node-utils": "^1.0.4" + "dotenv": "^17.2.3" } } diff --git a/src/review.mjs b/src/review.mjs index 2dfba38..7775768 100644 --- a/src/review.mjs +++ b/src/review.mjs @@ -3,6 +3,11 @@ import {$} from '@ztimson/node-utils'; import * as os from 'node:os'; import * as path from 'node:path'; import * as fs from 'node:fs'; +import * as dotenv from 'dotenv'; +import {execSync} from 'node:child_process'; + +dotenv.config(); +dotenv.config({path: '.env.local', override: true}); (async () => { const @@ -16,9 +21,13 @@ import * as fs from 'node:fs'; model = process.env['AI_MODEL'], token = process.env['AI_TOKEN']; + const comments = []; - const commit = (await $`git log -1 --pretty=format:%H`).trim(); - const gitDiff = await $`git diff HEAD^..HEAD`; + const commit = await $`cd ${root} && git log -1 --pretty=format:%H`; + const remote = await $`cd ${root} && git symbolic-ref refs/remotes/origin/HEAD`; + const gitDiff = execSync(`git diff ${remote}...HEAD`, {cwd: root, encoding: 'utf-8'}); + + console.log(`Inspecting: ${root} (${commit})`); let options = {ollama: {model, host}}; if(host === 'anthropic') options = {anthropic: {model, token}}; @@ -61,19 +70,28 @@ import * as fs from 'node:fs'; }] }); + if(!gitDiff) { + console.warn('No diff found'); + return process.exit(); + } + const summary = await ai.language.ask(gitDiff); - const res = await fetch(`${git}/api/v1/repos/${owner}/${repo}/pulls/${pr}/reviews`, { - method: 'POST', - headers: { - 'Authorization': `token ${auth}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - body: summary, - commit_id: commit, - event: 'COMMENT', - comments, - }) - }); - if(!res.ok) throw new Error(`${res.status} ${await res.text()}`); + if(git) { + const res = await fetch(`${git}/api/v1/repos/${owner}/${repo}/pulls/${pr}/reviews`, { + method: 'POST', + headers: { + 'Authorization': `token ${auth}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + body: summary, + commit_id: commit, + event: 'COMMENT', + comments, + }) + }); + if(!res.ok) throw new Error(`${res.status} ${await res.text()}`); + } else { + console.log(comments.map(c => `${c.path}:${c.new_position}\n${c.body}`).join('\n\n') + '\n\n' + summary); + } })();