gitreviewpilot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +234 -0
- package/dist/commands/ask.d.ts +3 -0
- package/dist/commands/ask.d.ts.map +1 -0
- package/dist/commands/ask.js +32 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/changes.d.ts +3 -0
- package/dist/commands/changes.d.ts.map +1 -0
- package/dist/commands/changes.js +57 -0
- package/dist/commands/changes.js.map +1 -0
- package/dist/commands/install.d.ts +3 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +86 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/pr.d.ts +3 -0
- package/dist/commands/pr.d.ts.map +1 -0
- package/dist/commands/pr.js +53 -0
- package/dist/commands/pr.js.map +1 -0
- package/dist/commands/review.d.ts +3 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +45 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/version.d.ts +3 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +16 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/config/env.d.ts +3 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +20 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/gitreviewpilotConfig.d.ts +16 -0
- package/dist/config/gitreviewpilotConfig.d.ts.map +1 -0
- package/dist/config/gitreviewpilotConfig.js +78 -0
- package/dist/config/gitreviewpilotConfig.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/services/ai.service.d.ts +60 -0
- package/dist/services/ai.service.d.ts.map +1 -0
- package/dist/services/ai.service.js +396 -0
- package/dist/services/ai.service.js.map +1 -0
- package/dist/services/askService.d.ts +12 -0
- package/dist/services/askService.d.ts.map +1 -0
- package/dist/services/askService.js +68 -0
- package/dist/services/askService.js.map +1 -0
- package/dist/services/git.service.d.ts +12 -0
- package/dist/services/git.service.d.ts.map +1 -0
- package/dist/services/git.service.js +61 -0
- package/dist/services/git.service.js.map +1 -0
- package/dist/services/github.service.d.ts +46 -0
- package/dist/services/github.service.d.ts.map +1 -0
- package/dist/services/github.service.js +169 -0
- package/dist/services/github.service.js.map +1 -0
- package/dist/services/prReviewService.d.ts +29 -0
- package/dist/services/prReviewService.d.ts.map +1 -0
- package/dist/services/prReviewService.js +107 -0
- package/dist/services/prReviewService.js.map +1 -0
- package/dist/services/prService.d.ts +12 -0
- package/dist/services/prService.d.ts.map +1 -0
- package/dist/services/prService.js +8 -0
- package/dist/services/prService.js.map +1 -0
- package/dist/services/reviewErrors.d.ts +7 -0
- package/dist/services/reviewErrors.d.ts.map +1 -0
- package/dist/services/reviewErrors.js +13 -0
- package/dist/services/reviewErrors.js.map +1 -0
- package/dist/services/reviewService.d.ts +16 -0
- package/dist/services/reviewService.d.ts.map +1 -0
- package/dist/services/reviewService.js +109 -0
- package/dist/services/reviewService.js.map +1 -0
- package/dist/utils/cli.d.ts +16 -0
- package/dist/utils/cli.d.ts.map +1 -0
- package/dist/utils/cli.js +108 -0
- package/dist/utils/cli.js.map +1 -0
- package/dist/utils/diff.d.ts +21 -0
- package/dist/utils/diff.d.ts.map +1 -0
- package/dist/utils/diff.js +105 -0
- package/dist/utils/diff.js.map +1 -0
- package/dist/utils/formatter.d.ts +11 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +186 -0
- package/dist/utils/formatter.js.map +1 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +35 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/repoContext.d.ts +26 -0
- package/dist/utils/repoContext.d.ts.map +1 -0
- package/dist/utils/repoContext.js +136 -0
- package/dist/utils/repoContext.js.map +1 -0
- package/dist/utils/spinner.d.ts +3 -0
- package/dist/utils/spinner.d.ts.map +1 -0
- package/dist/utils/spinner.js +5 -0
- package/dist/utils/spinner.js.map +1 -0
- package/dist/utils/structuredReview.d.ts +21 -0
- package/dist/utils/structuredReview.d.ts.map +1 -0
- package/dist/utils/structuredReview.js +59 -0
- package/dist/utils/structuredReview.js.map +1 -0
- package/gitreviewpilot.config.json +3 -0
- package/package.json +37 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class ReviewError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
details;
|
|
4
|
+
constructor(code, message, details, cause) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "ReviewError";
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.details = details;
|
|
9
|
+
if (cause !== undefined)
|
|
10
|
+
this.cause = cause;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=reviewErrors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewErrors.js","sourceRoot":"","sources":["../../src/services/reviewErrors.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,CAAkB;IACtB,OAAO,CAAqB;IAErC,YAAY,IAAqB,EAAE,OAAe,EAAE,OAAgB,EAAE,KAAe;QACnF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,KAAK,KAAK,SAAS;YAAG,IAA4B,CAAC,KAAK,GAAG,KAAK,CAAC;IACvE,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ReviewFileOptions = {
|
|
2
|
+
/**
|
|
3
|
+
* Maximum characters to send to the LLM.
|
|
4
|
+
* Large files are truncated from the end.
|
|
5
|
+
*/
|
|
6
|
+
maxChars?: number;
|
|
7
|
+
};
|
|
8
|
+
export type ReviewResult = {
|
|
9
|
+
filePath: string;
|
|
10
|
+
bytesRead: number;
|
|
11
|
+
truncated: boolean;
|
|
12
|
+
maxChars: number;
|
|
13
|
+
aiRaw: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function reviewFile(filePath: string, options?: ReviewFileOptions): Promise<ReviewResult>;
|
|
16
|
+
//# sourceMappingURL=reviewService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewService.d.ts","sourceRoot":"","sources":["../../src/services/reviewService.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAsGF,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,YAAY,CAAC,CAOzG"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { createReadStream } from "node:fs";
|
|
2
|
+
import { stat } from "node:fs/promises";
|
|
3
|
+
import { analyze, buildFileReviewPrompt, LlmApiError } from "./ai.service.js";
|
|
4
|
+
import { ReviewError } from "./reviewErrors.js";
|
|
5
|
+
function errnoCode(err) {
|
|
6
|
+
return err instanceof Error && "code" in err ? err.code : undefined;
|
|
7
|
+
}
|
|
8
|
+
function normalizeMaxChars(input) {
|
|
9
|
+
const n = input ?? 12_000;
|
|
10
|
+
if (!Number.isFinite(n) || n <= 500)
|
|
11
|
+
return 12_000;
|
|
12
|
+
return Math.floor(n);
|
|
13
|
+
}
|
|
14
|
+
function truncateToChars(text, maxChars) {
|
|
15
|
+
if (text.length <= maxChars)
|
|
16
|
+
return { text, truncated: false };
|
|
17
|
+
return { text: text.slice(0, maxChars), truncated: true };
|
|
18
|
+
}
|
|
19
|
+
async function readUtf8UpToChars(filePath, maxChars) {
|
|
20
|
+
return await new Promise((resolve, reject) => {
|
|
21
|
+
const stream = createReadStream(filePath, { encoding: "utf8" });
|
|
22
|
+
let acc = "";
|
|
23
|
+
let truncated = false;
|
|
24
|
+
let done = false;
|
|
25
|
+
const finish = () => {
|
|
26
|
+
if (done)
|
|
27
|
+
return;
|
|
28
|
+
done = true;
|
|
29
|
+
resolve(truncateToChars(acc, maxChars));
|
|
30
|
+
};
|
|
31
|
+
stream.on("data", (chunk) => {
|
|
32
|
+
if (done)
|
|
33
|
+
return;
|
|
34
|
+
acc += typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
35
|
+
if (acc.length > maxChars) {
|
|
36
|
+
truncated = true;
|
|
37
|
+
acc = acc.slice(0, maxChars);
|
|
38
|
+
stream.destroy();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
stream.on("error", (err) => {
|
|
42
|
+
if (done)
|
|
43
|
+
return;
|
|
44
|
+
// If we intentionally destroyed after truncation, treat as success.
|
|
45
|
+
if (truncated)
|
|
46
|
+
return finish();
|
|
47
|
+
reject(err);
|
|
48
|
+
});
|
|
49
|
+
stream.on("end", () => finish());
|
|
50
|
+
stream.on("close", () => finish());
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async function validateFilePath(filePath) {
|
|
54
|
+
try {
|
|
55
|
+
const st = await stat(filePath);
|
|
56
|
+
if (!st.isFile())
|
|
57
|
+
throw new ReviewError("NOT_A_FILE", `Not a file: ${filePath}`);
|
|
58
|
+
return { bytes: st.size };
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const code = errnoCode(err);
|
|
62
|
+
if (code === "ENOENT")
|
|
63
|
+
throw new ReviewError("FILE_NOT_FOUND", `File not found: ${filePath}`, undefined, err);
|
|
64
|
+
if (code === "EACCES")
|
|
65
|
+
throw new ReviewError("PERMISSION_DENIED", `Permission denied reading file: ${filePath}`, undefined, err);
|
|
66
|
+
if (err instanceof ReviewError)
|
|
67
|
+
throw err;
|
|
68
|
+
throw new ReviewError("FILE_READ_FAILED", `Unable to access file: ${filePath}`, err instanceof Error ? err.message : String(err), err);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function readFileForReview(filePath, maxChars) {
|
|
72
|
+
try {
|
|
73
|
+
const r = await readUtf8UpToChars(filePath, maxChars);
|
|
74
|
+
return { content: r.text, truncated: r.truncated };
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const code = errnoCode(err);
|
|
78
|
+
if (code === "ENOENT")
|
|
79
|
+
throw new ReviewError("FILE_NOT_FOUND", `File not found: ${filePath}`, undefined, err);
|
|
80
|
+
if (code === "EACCES")
|
|
81
|
+
throw new ReviewError("PERMISSION_DENIED", `Permission denied reading file: ${filePath}`, undefined, err);
|
|
82
|
+
throw new ReviewError("FILE_READ_FAILED", `Failed to read file: ${filePath}`, err instanceof Error ? err.message : String(err), err);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function buildPrompt(content, truncated, maxChars) {
|
|
86
|
+
return buildFileReviewPrompt(truncated
|
|
87
|
+
? `${content}\n\n[Note: file was truncated to ${maxChars.toLocaleString()} characters for analysis.]`
|
|
88
|
+
: content);
|
|
89
|
+
}
|
|
90
|
+
async function analyzePrompt(prompt) {
|
|
91
|
+
try {
|
|
92
|
+
return await analyze(prompt);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (err instanceof LlmApiError) {
|
|
96
|
+
throw new ReviewError("AI_FAILED", err.message, err.details, err);
|
|
97
|
+
}
|
|
98
|
+
throw new ReviewError("AI_FAILED", err instanceof Error ? err.message : String(err), undefined, err);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export async function reviewFile(filePath, options = {}) {
|
|
102
|
+
const maxChars = normalizeMaxChars(options.maxChars);
|
|
103
|
+
const { bytes } = await validateFilePath(filePath);
|
|
104
|
+
const { content, truncated } = await readFileForReview(filePath, maxChars);
|
|
105
|
+
const prompt = buildPrompt(content, truncated, maxChars);
|
|
106
|
+
const aiRaw = await analyzePrompt(prompt);
|
|
107
|
+
return { filePath, bytesRead: bytes, truncated, maxChars, aiRaw };
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=reviewService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewService.js","sourceRoot":"","sources":["../../src/services/reviewService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type CliErrorCode = "INVALID_ARGUMENT" | "NOT_A_GIT_REPO" | "GIT_NOT_FOUND" | "GIT_FAILED" | "UPSTREAM_NOT_SET" | "HOOK_INSTALL_FAILED";
|
|
2
|
+
export declare class CliError extends Error {
|
|
3
|
+
readonly code: CliErrorCode;
|
|
4
|
+
readonly details: string | undefined;
|
|
5
|
+
constructor(code: CliErrorCode, message: string, details?: string, cause?: unknown);
|
|
6
|
+
}
|
|
7
|
+
export declare function parsePositiveIntArg(name: string, raw: string): number;
|
|
8
|
+
export declare function parsePositiveIntOption(raw: string): number;
|
|
9
|
+
export declare function parseRepoRefArg(raw: string): string;
|
|
10
|
+
export declare function formatUserFacingError(err: unknown): {
|
|
11
|
+
title: string;
|
|
12
|
+
hint?: string;
|
|
13
|
+
details?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function printUserFacingError(err: unknown): void;
|
|
16
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/utils/cli.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,YAAY,GACpB,kBAAkB,GAClB,gBAAgB,GAChB,eAAe,GACf,YAAY,GACZ,kBAAkB,GAClB,qBAAqB,CAAC;AAE1B,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;gBACzB,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAOnF;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMrE;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAuEtG;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAQvD"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { CommanderError, InvalidArgumentError } from "commander";
|
|
3
|
+
import { ReviewError } from "../services/reviewErrors.js";
|
|
4
|
+
import { PrReviewError } from "../services/prReviewService.js";
|
|
5
|
+
export class CliError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
details;
|
|
8
|
+
constructor(code, message, details, cause) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "CliError";
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.details = details;
|
|
13
|
+
if (cause !== undefined)
|
|
14
|
+
this.cause = cause;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function parsePositiveIntArg(name, raw) {
|
|
18
|
+
const n = Number(raw);
|
|
19
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
20
|
+
throw new InvalidArgumentError(`${name} must be a positive integer (got: ${raw})`);
|
|
21
|
+
}
|
|
22
|
+
return n;
|
|
23
|
+
}
|
|
24
|
+
export function parsePositiveIntOption(raw) {
|
|
25
|
+
return parsePositiveIntArg("value", raw);
|
|
26
|
+
}
|
|
27
|
+
export function parseRepoRefArg(raw) {
|
|
28
|
+
// Keep validation lightweight here; deeper validation happens in the GitHub client.
|
|
29
|
+
if (!/^[^/\s]+\/[^/\s]+$/.test(raw)) {
|
|
30
|
+
throw new InvalidArgumentError(`repo must be in "owner/repo" format (got: ${raw})`);
|
|
31
|
+
}
|
|
32
|
+
return raw;
|
|
33
|
+
}
|
|
34
|
+
export function formatUserFacingError(err) {
|
|
35
|
+
if (err instanceof CommanderError) {
|
|
36
|
+
// Examples: unknown command/option, missing required option, etc.
|
|
37
|
+
// InvalidArgumentError extends CommanderError but is handled separately below.
|
|
38
|
+
const hint = err.code === "commander.unknownCommand"
|
|
39
|
+
? "Run `gitreviewpilot --help` to see available commands."
|
|
40
|
+
: err.code === "commander.unknownOption"
|
|
41
|
+
? "Run with `--help` to see valid options."
|
|
42
|
+
: err.code === "commander.missingMandatoryOptionValue" || err.code === "commander.optionMissingArgument"
|
|
43
|
+
? "Check the option value and try again."
|
|
44
|
+
: err.code === "commander.missingRequiredArgument"
|
|
45
|
+
? "Check required arguments and try again."
|
|
46
|
+
: undefined;
|
|
47
|
+
return { title: err.message.replace(/^error:\s*/i, ""), ...(hint ? { hint } : {}) };
|
|
48
|
+
}
|
|
49
|
+
if (err instanceof InvalidArgumentError) {
|
|
50
|
+
return { title: err.message, hint: "Run with `--help` to see valid usage." };
|
|
51
|
+
}
|
|
52
|
+
if (err instanceof CliError) {
|
|
53
|
+
const hint = err.code === "UPSTREAM_NOT_SET"
|
|
54
|
+
? "Set an upstream branch first, e.g. `git branch --set-upstream-to origin/main`."
|
|
55
|
+
: err.code === "NOT_A_GIT_REPO"
|
|
56
|
+
? "Run this from inside a git repository."
|
|
57
|
+
: err.code === "GIT_NOT_FOUND"
|
|
58
|
+
? "Install git and ensure it is on your PATH."
|
|
59
|
+
: undefined;
|
|
60
|
+
return {
|
|
61
|
+
title: err.message,
|
|
62
|
+
...(hint ? { hint } : {}),
|
|
63
|
+
...(err.details ? { details: err.details } : {})
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (err instanceof PrReviewError) {
|
|
67
|
+
const hint = err.code === "GITHUB_AUTH_MISSING"
|
|
68
|
+
? "Set `GITREVIEWPILOT_GITHUB_TOKEN` (recommended) or `GITHUB_TOKEN`."
|
|
69
|
+
: err.code === "INVALID_REPO"
|
|
70
|
+
? "Example: `--repo vercel/next.js`"
|
|
71
|
+
: err.code === "INVALID_PR_NUMBER"
|
|
72
|
+
? "Example: `gitreviewpilot pr 123 --repo owner/repo`"
|
|
73
|
+
: undefined;
|
|
74
|
+
return {
|
|
75
|
+
title: err.message,
|
|
76
|
+
...(hint ? { hint } : {}),
|
|
77
|
+
...(err.details ? { details: err.details } : {})
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (err instanceof ReviewError) {
|
|
81
|
+
const hint = err.code === "FILE_NOT_FOUND"
|
|
82
|
+
? "Check the path, or run from the repo root."
|
|
83
|
+
: err.code === "PERMISSION_DENIED"
|
|
84
|
+
? "Check file permissions."
|
|
85
|
+
: err.code === "AI_FAILED"
|
|
86
|
+
? "Verify your LLM env vars (see README) and try again."
|
|
87
|
+
: undefined;
|
|
88
|
+
return {
|
|
89
|
+
title: err.message,
|
|
90
|
+
...(hint ? { hint } : {}),
|
|
91
|
+
...(err.details ? { details: err.details } : {})
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (err instanceof Error)
|
|
95
|
+
return { title: err.message };
|
|
96
|
+
return { title: String(err) };
|
|
97
|
+
}
|
|
98
|
+
export function printUserFacingError(err) {
|
|
99
|
+
const { title, hint, details } = formatUserFacingError(err);
|
|
100
|
+
// Keep output compact and friendly (similar to popular CLIs).
|
|
101
|
+
console.error(chalk.red("Error:"), title);
|
|
102
|
+
if (hint)
|
|
103
|
+
console.error(chalk.dim("Hint:"), hint);
|
|
104
|
+
if (process.env.GITREVIEWPILOT_LOG_LEVEL === "debug" && details) {
|
|
105
|
+
console.error(chalk.dim(details));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/utils/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type DiffHunk = {
|
|
2
|
+
header: string;
|
|
3
|
+
lines: string[];
|
|
4
|
+
};
|
|
5
|
+
export type DiffFile = {
|
|
6
|
+
oldPath: string | null;
|
|
7
|
+
newPath: string | null;
|
|
8
|
+
hunks: DiffHunk[];
|
|
9
|
+
isBinary: boolean;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Parses a GitHub "application/vnd.github.v3.diff" unified diff.
|
|
13
|
+
* Keeps only per-file hunks and their changed lines (+/-), dropping context to optimize tokens.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseUnifiedDiff(diffText: string): DiffFile[];
|
|
16
|
+
export declare function toMinimizedDiff(files: DiffFile[]): string;
|
|
17
|
+
export declare function truncateToChars(text: string, maxChars: number): {
|
|
18
|
+
text: string;
|
|
19
|
+
truncated: boolean;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/utils/diff.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAgBF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,EAAE,CA8D7D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAmBzD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAGpG"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
function stripPrefix(path) {
|
|
2
|
+
// paths in unified diff are often "a/foo" and "b/foo"
|
|
3
|
+
return path.replace(/^(a|b)\//, "");
|
|
4
|
+
}
|
|
5
|
+
function parseFileMarker(line) {
|
|
6
|
+
// --- a/file or +++ b/file
|
|
7
|
+
const m = line.match(/^(---|\+\+\+)\s+(\S+)\s*$/);
|
|
8
|
+
if (!m)
|
|
9
|
+
return null;
|
|
10
|
+
const p = m[2];
|
|
11
|
+
if (p === "/dev/null")
|
|
12
|
+
return null;
|
|
13
|
+
return stripPrefix(p);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parses a GitHub "application/vnd.github.v3.diff" unified diff.
|
|
17
|
+
* Keeps only per-file hunks and their changed lines (+/-), dropping context to optimize tokens.
|
|
18
|
+
*/
|
|
19
|
+
export function parseUnifiedDiff(diffText) {
|
|
20
|
+
const lines = (diffText ?? "").split(/\r?\n/);
|
|
21
|
+
const files = [];
|
|
22
|
+
let current = null;
|
|
23
|
+
let currentHunk = null;
|
|
24
|
+
const flushHunk = () => {
|
|
25
|
+
if (!current || !currentHunk)
|
|
26
|
+
return;
|
|
27
|
+
if (currentHunk.lines.length > 0)
|
|
28
|
+
current.hunks.push(currentHunk);
|
|
29
|
+
currentHunk = null;
|
|
30
|
+
};
|
|
31
|
+
const flushFile = () => {
|
|
32
|
+
if (!current)
|
|
33
|
+
return;
|
|
34
|
+
flushHunk();
|
|
35
|
+
// Keep file entries that have changes or are binary markers.
|
|
36
|
+
if (current.isBinary || current.hunks.length > 0)
|
|
37
|
+
files.push(current);
|
|
38
|
+
current = null;
|
|
39
|
+
};
|
|
40
|
+
for (const raw of lines) {
|
|
41
|
+
const line = raw ?? "";
|
|
42
|
+
if (line.startsWith("diff --git ")) {
|
|
43
|
+
flushFile();
|
|
44
|
+
current = { oldPath: null, newPath: null, hunks: [], isBinary: false };
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (!current)
|
|
48
|
+
continue;
|
|
49
|
+
if (line.startsWith("Binary files ")) {
|
|
50
|
+
current.isBinary = true;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (line.startsWith("--- ") || line.startsWith("+++ ")) {
|
|
54
|
+
const p = parseFileMarker(line);
|
|
55
|
+
if (line.startsWith("--- "))
|
|
56
|
+
current.oldPath = p;
|
|
57
|
+
else
|
|
58
|
+
current.newPath = p;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (line.startsWith("@@")) {
|
|
62
|
+
flushHunk();
|
|
63
|
+
currentHunk = { header: line.trimEnd(), lines: [] };
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
// Inside hunks: keep only changed lines, and skip file markers which also begin with +/-.
|
|
67
|
+
if (currentHunk) {
|
|
68
|
+
if (line.startsWith("+") && !line.startsWith("+++")) {
|
|
69
|
+
currentHunk.lines.push(line);
|
|
70
|
+
}
|
|
71
|
+
else if (line.startsWith("-") && !line.startsWith("---")) {
|
|
72
|
+
currentHunk.lines.push(line);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
flushFile();
|
|
77
|
+
return files;
|
|
78
|
+
}
|
|
79
|
+
export function toMinimizedDiff(files) {
|
|
80
|
+
const out = [];
|
|
81
|
+
for (const f of files) {
|
|
82
|
+
const display = f.newPath ?? f.oldPath ?? "(unknown file)";
|
|
83
|
+
out.push(`File: ${display}`);
|
|
84
|
+
if (f.isBinary) {
|
|
85
|
+
out.push("(binary change)");
|
|
86
|
+
out.push("");
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
for (const h of f.hunks) {
|
|
90
|
+
out.push(h.header);
|
|
91
|
+
out.push(...h.lines);
|
|
92
|
+
out.push("");
|
|
93
|
+
}
|
|
94
|
+
if (f.hunks.length === 0)
|
|
95
|
+
out.push("(no textual hunks)");
|
|
96
|
+
out.push("");
|
|
97
|
+
}
|
|
98
|
+
return out.join("\n").trimEnd();
|
|
99
|
+
}
|
|
100
|
+
export function truncateToChars(text, maxChars) {
|
|
101
|
+
if (text.length <= maxChars)
|
|
102
|
+
return { text, truncated: false };
|
|
103
|
+
return { text: text.slice(0, maxChars), truncated: true };
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/utils/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ReviewSectionKey = "critical" | "improvements" | "suggestions" | "summary";
|
|
2
|
+
export type ParsedReviewSections = {
|
|
3
|
+
critical: string;
|
|
4
|
+
improvements: string;
|
|
5
|
+
suggestions: string;
|
|
6
|
+
summary: string;
|
|
7
|
+
raw: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function parseAiReview(raw: string): ParsedReviewSections;
|
|
10
|
+
export declare function formatAiReview(raw: string): string;
|
|
11
|
+
//# sourceMappingURL=formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/utils/formatter.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,cAAc,GAAG,aAAa,GAAG,SAAS,CAAC;AAEvF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AA0JF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CA2C/D;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYlD"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
const SECTION_ORDER = ["critical", "improvements", "suggestions", "summary"];
|
|
3
|
+
const SECTION_META = {
|
|
4
|
+
critical: { title: "Critical Issues", label: "🔴 Critical Issues", color: (s) => chalk.red.bold(s) },
|
|
5
|
+
improvements: { title: "Improvements", label: "🟡 Improvements", color: (s) => chalk.yellow.bold(s) },
|
|
6
|
+
suggestions: { title: "Suggestions", label: "🟢 Suggestions", color: (s) => chalk.green.bold(s) },
|
|
7
|
+
summary: { title: "Summary", label: "📌 Summary", color: (s) => chalk.cyan.bold(s) }
|
|
8
|
+
};
|
|
9
|
+
function normalizeTitleForMatch(title) {
|
|
10
|
+
return (title ?? "")
|
|
11
|
+
.replace(/^\s*[\d\.\)\-–—]+/, "")
|
|
12
|
+
.replace(/^[\p{Extended_Pictographic}\uFE0F]+\s*/gu, "")
|
|
13
|
+
.replace(/[*_`#>]+/g, "")
|
|
14
|
+
.replace(/[^\p{L}\p{N}\s]+/gu, " ")
|
|
15
|
+
.trim()
|
|
16
|
+
.toLowerCase();
|
|
17
|
+
}
|
|
18
|
+
function keyFromTitle(title) {
|
|
19
|
+
const t = normalizeTitleForMatch(title);
|
|
20
|
+
if (!t)
|
|
21
|
+
return undefined;
|
|
22
|
+
// Critical Issues
|
|
23
|
+
if (t === "critical issues" ||
|
|
24
|
+
t === "critical" ||
|
|
25
|
+
t === "blockers" ||
|
|
26
|
+
t === "blocking issues" ||
|
|
27
|
+
t === "must fix" ||
|
|
28
|
+
t === "must-fix" ||
|
|
29
|
+
t === "bugs" ||
|
|
30
|
+
t === "issues") {
|
|
31
|
+
return "critical";
|
|
32
|
+
}
|
|
33
|
+
// Improvements
|
|
34
|
+
if (t === "improvements" ||
|
|
35
|
+
t === "improvement" ||
|
|
36
|
+
t === "enhancements" ||
|
|
37
|
+
t === "optimizations" ||
|
|
38
|
+
t === "performance" ||
|
|
39
|
+
t === "maintainability") {
|
|
40
|
+
return "improvements";
|
|
41
|
+
}
|
|
42
|
+
// Suggestions
|
|
43
|
+
if (t === "suggestions" ||
|
|
44
|
+
t === "suggestion" ||
|
|
45
|
+
t === "recommendations" ||
|
|
46
|
+
t === "recommendation" ||
|
|
47
|
+
t === "nits" ||
|
|
48
|
+
t === "nitpicks" ||
|
|
49
|
+
t === "nice to have" ||
|
|
50
|
+
t === "nice-to-have") {
|
|
51
|
+
return "suggestions";
|
|
52
|
+
}
|
|
53
|
+
// Summary
|
|
54
|
+
if (t === "summary" || t === "overall" || t === "overall summary" || t === "tldr" || t === "tl dr") {
|
|
55
|
+
return "summary";
|
|
56
|
+
}
|
|
57
|
+
// Soft matches for messy headings.
|
|
58
|
+
if (/\bcritical\b/.test(t) || /\bblock(ing|er)s?\b/.test(t))
|
|
59
|
+
return "critical";
|
|
60
|
+
if (/\bimprove(ment)?s?\b/.test(t) || /\benhance(ment)?s?\b/.test(t) || /\boptimi[sz]e/.test(t))
|
|
61
|
+
return "improvements";
|
|
62
|
+
if (/\bsuggest(ion)?s?\b/.test(t) || /\brecommend(ation)?s?\b/.test(t) || /\bnit(s|pick)?\b/.test(t))
|
|
63
|
+
return "suggestions";
|
|
64
|
+
if (/\bsummary\b/.test(t) || /\boverall\b/.test(t) || /\btl\s*dr\b/.test(t))
|
|
65
|
+
return "summary";
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
function normalizeBody(body) {
|
|
69
|
+
const lines = (body ?? "")
|
|
70
|
+
.replace(/\r\n/g, "\n")
|
|
71
|
+
.replace(/\r/g, "\n")
|
|
72
|
+
.split("\n");
|
|
73
|
+
const out = [];
|
|
74
|
+
for (let i = 0; i < lines.length; i++) {
|
|
75
|
+
let line = lines[i] ?? "";
|
|
76
|
+
line = line.replace(/\s+$/g, "");
|
|
77
|
+
// Normalize common bullet variants to "- ".
|
|
78
|
+
line = line.replace(/^\s*(?:•|·|●|▪|–|—|\*)\s+/, "- ");
|
|
79
|
+
// Normalize numbered lists like "1)" or "1 -" to "1. "
|
|
80
|
+
line = line.replace(/^\s*(\d+)\s*[\)\-:]\s+/, "$1. ");
|
|
81
|
+
out.push(line);
|
|
82
|
+
}
|
|
83
|
+
// Trim leading/trailing blank lines and collapse excessive whitespace.
|
|
84
|
+
while (out.length > 0 && !out[0].trim())
|
|
85
|
+
out.shift();
|
|
86
|
+
while (out.length > 0 && !out[out.length - 1].trim())
|
|
87
|
+
out.pop();
|
|
88
|
+
const collapsed = [];
|
|
89
|
+
let blankRun = 0;
|
|
90
|
+
for (const l of out) {
|
|
91
|
+
if (!l.trim()) {
|
|
92
|
+
blankRun++;
|
|
93
|
+
if (blankRun <= 1)
|
|
94
|
+
collapsed.push("");
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
blankRun = 0;
|
|
98
|
+
collapsed.push(l);
|
|
99
|
+
}
|
|
100
|
+
return collapsed.join("\n").trim();
|
|
101
|
+
}
|
|
102
|
+
function collectHeadings(text) {
|
|
103
|
+
const matches = [];
|
|
104
|
+
const add = (m, titleLine) => {
|
|
105
|
+
const key = keyFromTitle(titleLine);
|
|
106
|
+
if (!key)
|
|
107
|
+
return;
|
|
108
|
+
matches.push({ index: m.index ?? 0, titleLine, key });
|
|
109
|
+
};
|
|
110
|
+
// Numbered headings: "1. Critical Issues"
|
|
111
|
+
for (const m of text.matchAll(/^(\d+)\.\s+(.+?)\s*$/gm))
|
|
112
|
+
add(m, m[2] ?? "");
|
|
113
|
+
// Markdown bold headings: "**Critical Issues**"
|
|
114
|
+
for (const m of text.matchAll(/^\*\*(.+?)\*\*\s*$/gm))
|
|
115
|
+
add(m, m[1] ?? "");
|
|
116
|
+
// Markdown hashes: "## Critical Issues"
|
|
117
|
+
for (const m of text.matchAll(/^#{1,6}\s+(.+?)\s*$/gm))
|
|
118
|
+
add(m, m[1] ?? "");
|
|
119
|
+
// Plain headings (best-effort): "Critical Issues:" / "Summary -"
|
|
120
|
+
for (const m of text.matchAll(/^(Critical Issues|Improvements|Suggestions|Summary)\s*[:\-–—]\s*$/gim)) {
|
|
121
|
+
add(m, m[1] ?? "");
|
|
122
|
+
}
|
|
123
|
+
// De-dup by position, keep earliest instance.
|
|
124
|
+
matches.sort((a, b) => a.index - b.index);
|
|
125
|
+
const deduped = [];
|
|
126
|
+
for (const m of matches) {
|
|
127
|
+
const last = deduped[deduped.length - 1];
|
|
128
|
+
if (last && last.index === m.index)
|
|
129
|
+
continue;
|
|
130
|
+
deduped.push(m);
|
|
131
|
+
}
|
|
132
|
+
return deduped;
|
|
133
|
+
}
|
|
134
|
+
export function parseAiReview(raw) {
|
|
135
|
+
const text = (raw ?? "").trim();
|
|
136
|
+
const empty = {
|
|
137
|
+
critical: "",
|
|
138
|
+
improvements: "",
|
|
139
|
+
suggestions: "",
|
|
140
|
+
summary: "",
|
|
141
|
+
raw: text
|
|
142
|
+
};
|
|
143
|
+
if (!text)
|
|
144
|
+
return empty;
|
|
145
|
+
const headings = collectHeadings(text);
|
|
146
|
+
if (headings.length === 0) {
|
|
147
|
+
// No headings at all: keep the original as summary unless it's clearly long/sectioned.
|
|
148
|
+
const body = normalizeBody(text);
|
|
149
|
+
return { ...empty, summary: body || "" };
|
|
150
|
+
}
|
|
151
|
+
const buckets = {
|
|
152
|
+
critical: [],
|
|
153
|
+
improvements: [],
|
|
154
|
+
suggestions: [],
|
|
155
|
+
summary: []
|
|
156
|
+
};
|
|
157
|
+
for (let i = 0; i < headings.length; i++) {
|
|
158
|
+
const start = headings[i].index;
|
|
159
|
+
const end = i + 1 < headings.length ? headings[i + 1].index : text.length;
|
|
160
|
+
const chunk = text.slice(start, end).trimEnd();
|
|
161
|
+
const firstNl = chunk.indexOf("\n");
|
|
162
|
+
const body = firstNl === -1 ? "" : chunk.slice(firstNl + 1);
|
|
163
|
+
const normalized = normalizeBody(body);
|
|
164
|
+
if (normalized)
|
|
165
|
+
buckets[headings[i].key].push(normalized);
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
critical: buckets.critical.join("\n\n").trim(),
|
|
169
|
+
improvements: buckets.improvements.join("\n\n").trim(),
|
|
170
|
+
suggestions: buckets.suggestions.join("\n\n").trim(),
|
|
171
|
+
summary: buckets.summary.join("\n\n").trim(),
|
|
172
|
+
raw: text
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
export function formatAiReview(raw) {
|
|
176
|
+
const parsed = parseAiReview(raw);
|
|
177
|
+
const out = [];
|
|
178
|
+
for (const key of SECTION_ORDER) {
|
|
179
|
+
const meta = SECTION_META[key];
|
|
180
|
+
out.push(meta.color(meta.label));
|
|
181
|
+
out.push(parsed[key] ? parsed[key] : chalk.gray("(none)"));
|
|
182
|
+
out.push("");
|
|
183
|
+
}
|
|
184
|
+
return out.join("\n").trimEnd();
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/utils/formatter.ts"],"names":[],"mappings":"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"}
|