secondpair 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.
Files changed (62) hide show
  1. package/README.md +119 -0
  2. package/dist/bitbucket/comments.d.ts +49 -0
  3. package/dist/bitbucket/comments.js +198 -0
  4. package/dist/bitbucket/comments.js.map +1 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.js +208 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/config.d.ts +33 -0
  9. package/dist/config.js +87 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/diff/github.d.ts +14 -0
  12. package/dist/diff/github.js +27 -0
  13. package/dist/diff/github.js.map +1 -0
  14. package/dist/diff/local.d.ts +10 -0
  15. package/dist/diff/local.js +39 -0
  16. package/dist/diff/local.js.map +1 -0
  17. package/dist/diff/parse.d.ts +9 -0
  18. package/dist/diff/parse.js +141 -0
  19. package/dist/diff/parse.js.map +1 -0
  20. package/dist/finding-id.d.ts +28 -0
  21. package/dist/finding-id.js +96 -0
  22. package/dist/finding-id.js.map +1 -0
  23. package/dist/github/comments.d.ts +25 -0
  24. package/dist/github/comments.js +193 -0
  25. package/dist/github/comments.js.map +1 -0
  26. package/dist/gitlab/comments.d.ts +46 -0
  27. package/dist/gitlab/comments.js +213 -0
  28. package/dist/gitlab/comments.js.map +1 -0
  29. package/dist/index.d.ts +10 -0
  30. package/dist/index.js +11 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/llm/prompt.d.ts +23 -0
  33. package/dist/llm/prompt.js +53 -0
  34. package/dist/llm/prompt.js.map +1 -0
  35. package/dist/llm/schema.d.ts +61 -0
  36. package/dist/llm/schema.js +73 -0
  37. package/dist/llm/schema.js.map +1 -0
  38. package/dist/reconcile.d.ts +20 -0
  39. package/dist/reconcile.js +70 -0
  40. package/dist/reconcile.js.map +1 -0
  41. package/dist/redact.d.ts +3 -0
  42. package/dist/redact.js +25 -0
  43. package/dist/redact.js.map +1 -0
  44. package/dist/report/cli.d.ts +5 -0
  45. package/dist/report/cli.js +63 -0
  46. package/dist/report/cli.js.map +1 -0
  47. package/dist/report/json.d.ts +27 -0
  48. package/dist/report/json.js +53 -0
  49. package/dist/report/json.js.map +1 -0
  50. package/dist/review.d.ts +41 -0
  51. package/dist/review.js +274 -0
  52. package/dist/review.js.map +1 -0
  53. package/dist/suppress-signals.d.ts +7 -0
  54. package/dist/suppress-signals.js +19 -0
  55. package/dist/suppress-signals.js.map +1 -0
  56. package/dist/suppressions.d.ts +6 -0
  57. package/dist/suppressions.js +48 -0
  58. package/dist/suppressions.js.map +1 -0
  59. package/dist/types.d.ts +92 -0
  60. package/dist/types.js +14 -0
  61. package/dist/types.js.map +1 -0
  62. package/package.json +49 -0
package/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # secondpair — the second pair of eyes
2
+
3
+ LLM-powered PR reviewer with whole-repo context. Reviews a diff (local,
4
+ staged, or a GitHub/GitLab/Bitbucket PR), posts inline comments, gates CI
5
+ on severity. Uses sibling package [`codengram`](../codengram/README.md) as
6
+ its repo memory so review isn't diff-blind — it sees callers, related
7
+ files, and project context, not just the patch.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install --save-dev secondpair
13
+ ```
14
+
15
+ Needs an LLM API key (same resolution as `codengram` — set one):
16
+
17
+ ```bash
18
+ export ANTHROPIC_API_KEY=sk-ant-... # default, recommended
19
+ # or: OPENAI_API_KEY / OPENROUTER_API_KEY / CODENGRAM_API_KEY+CODENGRAM_BASE_URL+CODENGRAM_MODEL
20
+ ```
21
+
22
+ ## Quick start
23
+
24
+ ```bash
25
+ cd your-repo
26
+ npx codengram init # one-time: builds repo memory, installs git hooks
27
+ npx secondpair review --staged # review staged changes, print report
28
+ npx secondpair review --base main # review branch vs main
29
+ ```
30
+
31
+ Nothing to configure to get useful output — defaults are sane
32
+ (`fail_on: high`, `min_confidence: 0.5`). Add `.pr-review.yml` only when you
33
+ want to change them (see [Config](#config)).
34
+
35
+ ## Reviewing a real PR (posting comments + CI gate)
36
+
37
+ Pick your platform, set its token, run with `--post`:
38
+
39
+ **GitHub** (GitHub Actions: `GITHUB_TOKEN` is provided automatically)
40
+ ```bash
41
+ export GITHUB_TOKEN=ghp_...
42
+ npx secondpair review --pr 123 --repo owner/name --post --fail-on high
43
+ ```
44
+
45
+ **GitLab** (in GitLab CI, `CI_SERVER_URL`/`CI_PROJECT_ID`/`CI_MERGE_REQUEST_IID`
46
+ are auto-detected; set a token as `GITLAB_TOKEN` or `GL_TOKEN`)
47
+ ```bash
48
+ export GITLAB_TOKEN=glpat-...
49
+ npx secondpair review --post --fail-on high # host auto-detected via GITLAB_CI env
50
+ ```
51
+
52
+ **Bitbucket** (`BITBUCKET_WORKSPACE`/`BITBUCKET_PR_ID` auto-detected in
53
+ Bitbucket Pipelines; auth via token or app password)
54
+ ```bash
55
+ export BITBUCKET_TOKEN=... # or BITBUCKET_USERNAME + BITBUCKET_APP_PASSWORD
56
+ npx secondpair review --post --fail-on high
57
+ ```
58
+
59
+ `--host` overrides auto-detection if you're running somewhere the CI env
60
+ vars aren't set. Exit code is 1 when any active finding is at/above
61
+ `fail_on` — wire that into your pipeline as the merge gate.
62
+
63
+ ### Example: GitHub Actions
64
+
65
+ ```yaml
66
+ - run: npx secondpair review --pr ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --post
67
+ env:
68
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
69
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
70
+ ```
71
+
72
+ Re-running on the same PR (new commit, or CI re-triggered) never
73
+ double-posts — each platform re-checks live existing comment ids right
74
+ before posting, on top of run-to-run fingerprint reconciliation.
75
+
76
+ ## Config (`.pr-review.yml`, optional)
77
+
78
+ ```yaml
79
+ fail_on: high # critical|high|medium|low|info — CI exit-1 threshold
80
+ min_confidence: 0.5
81
+ ignore: ["**/*.generated.ts", "vendor/**"]
82
+ context_token_budget: 8000 # codengram context injected per chunk
83
+ context_snippets: 3
84
+ categories: # turn any off
85
+ bug: true
86
+ security: true
87
+ missing-tests: true
88
+ naming: true
89
+ complexity: true
90
+ custom: true
91
+ limits:
92
+ max_findings_per_file: 5
93
+ max_total: 30
94
+ self_critique: false # extra LLM pass that only drops findings, never adds
95
+ redact_secrets: true # strip secrets from diff/context before they reach the LLM
96
+ redact_patterns: [] # extra regexes, on top of built-in AWS/GitHub-token/PEM/etc
97
+ write_suppressions: false # persist "won't fix" replies to .pr-review-suppressions.yml
98
+ custom_instructions: ""
99
+ ```
100
+
101
+ Suppress a finding permanently: reply "won't fix" (or react 👎) on its PR
102
+ comment, or hand-edit `.pr-review-suppressions.yml` with the finding id
103
+ from the report.
104
+
105
+ ## `secondpair index`
106
+
107
+ Alias for `codengram index` — kept so a repo can adopt `secondpair` without
108
+ also depending on `codengram` directly for this one command. Same
109
+ incremental behavior; see [codengram's README](../codengram/README.md#staying-in-sync-after-code-changes)
110
+ for exactly when/how re-indexing happens and why it's cheap on repeated
111
+ runs — short version: git-hook-triggered, hash-incremental, never a full
112
+ rebuild unless you pass `--full`.
113
+
114
+ ## More detail
115
+
116
+ - Agent-oriented internals reference (pipeline, invariants to preserve when
117
+ editing): [`AGENTS.md`](./AGENTS.md)
118
+ - Architecture review, requirements scorecard, known gaps:
119
+ [`docs/architecture-review.md`](./docs/architecture-review.md)
@@ -0,0 +1,49 @@
1
+ import type { Finding, ReviewResult } from "../types.js";
2
+ export interface BbRef {
3
+ workspace: string;
4
+ repoSlug: string;
5
+ prId: number;
6
+ }
7
+ /**
8
+ * Resolve Bitbucket Cloud auth from the environment:
9
+ * BITBUCKET_TOKEN / BITBUCKET_ACCESS_TOKEN -> Bearer (repository access token)
10
+ * BITBUCKET_USERNAME + BITBUCKET_APP_PASSWORD -> Basic (app password)
11
+ */
12
+ export declare function resolveBbAuthHeader(): string;
13
+ /** Resolve workspace/repo/PR id from flags or Bitbucket Pipelines env vars. */
14
+ export declare function resolveBbRef(repoSlug: string | undefined, pr: number | undefined): BbRef;
15
+ /** Fetch the unified diff of a Bitbucket Cloud pull request. */
16
+ export declare function getBbPrDiff(ref: BbRef): Promise<string>;
17
+ interface BbComment {
18
+ id?: number;
19
+ content?: {
20
+ raw?: string;
21
+ };
22
+ inline?: {
23
+ path?: string;
24
+ to?: number;
25
+ };
26
+ parent?: {
27
+ id?: number;
28
+ };
29
+ }
30
+ export declare function listBbComments(ref: BbRef): Promise<BbComment[]>;
31
+ export declare function listBbFindingIds(ref: BbRef): Promise<Set<string>>;
32
+ export declare function listBbWontFixFindingIds(ref: BbRef): Promise<Set<string>>;
33
+ /** Bitbucket Cloud exposes no API for resolving pull-request comment threads. */
34
+ export declare function resolveBbCommentsForIds(_ref: BbRef, _ids: Iterable<string>, log?: (msg: string) => void): Promise<number>;
35
+ /** Bitbucket markdown has no GitHub suggestion blocks — render fixes as code fences. */
36
+ export declare function formatBbCommentBody(f: Finding): string;
37
+ export declare function formatBbSummaryBody(result: ReviewResult, failed: boolean): string;
38
+ export interface PostBbReviewOptions {
39
+ ref: BbRef;
40
+ result: ReviewResult;
41
+ failed: boolean;
42
+ log?: (msg: string) => void;
43
+ }
44
+ /**
45
+ * Post findings to a Bitbucket Cloud PR: one summary comment plus one inline
46
+ * comment per *new* finding. Persistent findings (same pr-review-id) are skipped.
47
+ */
48
+ export declare function postBbReview(opts: PostBbReviewOptions): Promise<void>;
49
+ export {};
@@ -0,0 +1,198 @@
1
+ import { collectIdsFromBodies, embedFindingId, parseFindingId } from "../finding-id.js";
2
+ import { AGENT_MARKER, SEVERITY_EMOJI } from "../github/comments.js";
3
+ import { collectWontFixIds } from "../suppress-signals.js";
4
+ const API = "https://api.bitbucket.org/2.0";
5
+ /**
6
+ * Resolve Bitbucket Cloud auth from the environment:
7
+ * BITBUCKET_TOKEN / BITBUCKET_ACCESS_TOKEN -> Bearer (repository access token)
8
+ * BITBUCKET_USERNAME + BITBUCKET_APP_PASSWORD -> Basic (app password)
9
+ */
10
+ export function resolveBbAuthHeader() {
11
+ const env = process.env;
12
+ const token = env.BITBUCKET_TOKEN || env.BITBUCKET_ACCESS_TOKEN;
13
+ if (token)
14
+ return `Bearer ${token}`;
15
+ if (env.BITBUCKET_USERNAME && env.BITBUCKET_APP_PASSWORD) {
16
+ const basic = Buffer.from(`${env.BITBUCKET_USERNAME}:${env.BITBUCKET_APP_PASSWORD}`).toString("base64");
17
+ return `Basic ${basic}`;
18
+ }
19
+ throw new Error("Bitbucket auth required: set BITBUCKET_TOKEN (repository access token with pullrequest:write) " +
20
+ "or BITBUCKET_USERNAME + BITBUCKET_APP_PASSWORD.");
21
+ }
22
+ /** Resolve workspace/repo/PR id from flags or Bitbucket Pipelines env vars. */
23
+ export function resolveBbRef(repoSlug, pr) {
24
+ const env = process.env;
25
+ let workspace;
26
+ let slug;
27
+ if (repoSlug) {
28
+ [workspace, slug] = repoSlug.split("/");
29
+ }
30
+ else {
31
+ workspace = env.BITBUCKET_WORKSPACE;
32
+ slug = env.BITBUCKET_REPO_SLUG;
33
+ }
34
+ const prId = pr ?? (env.BITBUCKET_PR_ID ? parseInt(env.BITBUCKET_PR_ID, 10) : undefined);
35
+ if (!workspace || !slug || prId == null || Number.isNaN(prId)) {
36
+ throw new Error("Bitbucket PR not identified. Pass --repo workspace/repo_slug and --pr <id>, " +
37
+ "or run inside Bitbucket Pipelines (BITBUCKET_WORKSPACE / BITBUCKET_REPO_SLUG / BITBUCKET_PR_ID).");
38
+ }
39
+ return { workspace, repoSlug: slug, prId };
40
+ }
41
+ async function bbFetch(url, init = {}) {
42
+ const res = await fetch(url, {
43
+ ...init,
44
+ headers: {
45
+ authorization: resolveBbAuthHeader(),
46
+ accept: "application/json",
47
+ ...(init.body ? { "content-type": "application/json" } : {}),
48
+ ...(init.headers ?? {}),
49
+ },
50
+ });
51
+ if (!res.ok) {
52
+ const text = await res.text();
53
+ throw new Error(`Bitbucket API ${init.method ?? "GET"} ${url} failed (${res.status}): ${text.slice(0, 400)}`);
54
+ }
55
+ return res;
56
+ }
57
+ /** Fetch the unified diff of a Bitbucket Cloud pull request. */
58
+ export async function getBbPrDiff(ref) {
59
+ const res = await bbFetch(`${API}/repositories/${ref.workspace}/${ref.repoSlug}/pullrequests/${ref.prId}/diff`, { headers: { accept: "text/plain" } });
60
+ return res.text();
61
+ }
62
+ export async function listBbComments(ref) {
63
+ const comments = [];
64
+ let url = `${API}/repositories/${ref.workspace}/${ref.repoSlug}/pullrequests/${ref.prId}/comments?pagelen=100`;
65
+ while (url) {
66
+ const res = await bbFetch(url);
67
+ const page = (await res.json());
68
+ comments.push(...(page.values ?? []));
69
+ url = page.next ?? null;
70
+ }
71
+ return comments;
72
+ }
73
+ export async function listBbFindingIds(ref) {
74
+ const existing = await listBbComments(ref);
75
+ return collectIdsFromBodies(existing.filter((c) => c.content?.raw?.includes(AGENT_MARKER)).map((c) => c.content?.raw ?? ""));
76
+ }
77
+ export async function listBbWontFixFindingIds(ref) {
78
+ const comments = await listBbComments(ref);
79
+ const byId = new Map(comments.flatMap((comment) => (comment.id == null ? [] : [[comment.id, comment]])));
80
+ return collectWontFixIds(comments.map((comment) => {
81
+ let parent = comment.parent?.id == null ? undefined : byId.get(comment.parent.id);
82
+ while (parent) {
83
+ const body = parent.content?.raw ?? "";
84
+ if (body.includes(AGENT_MARKER)) {
85
+ return { body: comment.content?.raw ?? "", parentAgentId: parseFindingId(body) };
86
+ }
87
+ parent = parent.parent?.id == null ? undefined : byId.get(parent.parent.id);
88
+ }
89
+ const body = comment.content?.raw ?? "";
90
+ return { body, isAgent: body.includes(AGENT_MARKER), parentAgentId: null };
91
+ }));
92
+ }
93
+ /** Bitbucket Cloud exposes no API for resolving pull-request comment threads. */
94
+ export async function resolveBbCommentsForIds(_ref, _ids, log = () => { }) {
95
+ log("Bitbucket: soft-resolve not supported; skipping");
96
+ return 0;
97
+ }
98
+ /** Bitbucket markdown has no GitHub suggestion blocks — render fixes as code fences. */
99
+ export function formatBbCommentBody(f) {
100
+ const parts = [
101
+ `${SEVERITY_EMOJI[f.severity]} **${f.severity.toUpperCase()}** · \`${f.category}\` · confidence ${Math.round(f.confidence * 100)}%`,
102
+ "",
103
+ `**${f.title}**`,
104
+ "",
105
+ f.body.trim(),
106
+ ];
107
+ if (f.suggestion) {
108
+ parts.push("", "Suggested fix:", "```", f.suggestion.replace(/\n$/, ""), "```");
109
+ }
110
+ parts.push("", AGENT_MARKER);
111
+ let body = parts.join("\n");
112
+ if (f.id)
113
+ body = embedFindingId(body, f.id);
114
+ return body;
115
+ }
116
+ export function formatBbSummaryBody(result, failed) {
117
+ const counts = {};
118
+ for (const f of result.findings)
119
+ counts[f.severity] = (counts[f.severity] ?? 0) + 1;
120
+ const countLine = result.findings.length === 0
121
+ ? "No findings."
122
+ : Object.entries(counts)
123
+ .map(([sev, n]) => `${SEVERITY_EMOJI[sev]} ${n} ${sev}`)
124
+ .join(" · ");
125
+ const recon = result.reconciliation;
126
+ const reconLine = recon
127
+ ? `\n_Lifecycle:_ ${recon.new.length} new · ${recon.persistent.length} persistent · ${recon.resolved.length} resolved · ${recon.suppressed.length} suppressed`
128
+ : "";
129
+ return [
130
+ "## PR Review Agent",
131
+ "",
132
+ result.summary.trim(),
133
+ "",
134
+ countLine,
135
+ reconLine,
136
+ failed ? "\n❌ **Check failed**: findings at or above the configured severity threshold." : "",
137
+ AGENT_MARKER,
138
+ ].join("\n");
139
+ }
140
+ /**
141
+ * Post findings to a Bitbucket Cloud PR: one summary comment plus one inline
142
+ * comment per *new* finding. Persistent findings (same pr-review-id) are skipped.
143
+ */
144
+ export async function postBbReview(opts) {
145
+ const { ref, result, log = () => { } } = opts;
146
+ const commentsUrl = `${API}/repositories/${ref.workspace}/${ref.repoSlug}/pullrequests/${ref.prId}/comments`;
147
+ const existing = await listBbComments(ref);
148
+ const mine = existing.filter((c) => c.content?.raw?.includes(AGENT_MARKER));
149
+ const existingIds = collectIdsFromBodies(mine.map((c) => c.content?.raw ?? ""));
150
+ const alreadySummarized = mine.some((c) => c.inline == null);
151
+ if (!alreadySummarized || result.findings.length === 0) {
152
+ await bbFetch(commentsUrl, {
153
+ method: "POST",
154
+ body: JSON.stringify({ content: { raw: formatBbSummaryBody(result, opts.failed) } }),
155
+ });
156
+ }
157
+ const toPost = result.findingsToPost ?? result.findings;
158
+ let posted = 0;
159
+ let skipped = 0;
160
+ const failedInline = [];
161
+ for (const f of toPost) {
162
+ if (f.id && existingIds.has(f.id)) {
163
+ skipped++;
164
+ continue;
165
+ }
166
+ try {
167
+ await bbFetch(commentsUrl, {
168
+ method: "POST",
169
+ body: JSON.stringify({
170
+ content: { raw: formatBbCommentBody(f) },
171
+ inline: { path: f.file, to: f.end_line },
172
+ }),
173
+ });
174
+ posted++;
175
+ }
176
+ catch {
177
+ failedInline.push(f);
178
+ }
179
+ }
180
+ if (failedInline.length > 0) {
181
+ const body = [
182
+ "### Findings that could not be placed inline",
183
+ ...failedInline.map((f) => `- ${SEVERITY_EMOJI[f.severity]} **${f.severity}** \`${f.file}:${f.start_line}-${f.end_line}\` — ${f.title}\n\n ${f.body.split("\n").join("\n ")}`),
184
+ "",
185
+ AGENT_MARKER,
186
+ ].join("\n");
187
+ await bbFetch(commentsUrl, { method: "POST", body: JSON.stringify({ content: { raw: body } }) });
188
+ }
189
+ log(`Bitbucket: posted ${posted} inline comment(s)` +
190
+ (skipped ? `, skipped ${skipped} duplicate(s)` : "") +
191
+ (failedInline.length ? `, ${failedInline.length} moved to a summary comment` : "") +
192
+ ".");
193
+ const resolvedIds = result.reconciliation?.resolved ?? [];
194
+ if (resolvedIds.length > 0) {
195
+ await resolveBbCommentsForIds(ref, resolvedIds, log);
196
+ }
197
+ }
198
+ //# sourceMappingURL=comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/bitbucket/comments.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import path from "node:path";
4
+ import pc from "picocolors";
5
+ import { getModel, runIndex } from "codengram";
6
+ import { getBbPrDiff, listBbFindingIds, listBbWontFixFindingIds, postBbReview, resolveBbRef, } from "./bitbucket/comments.js";
7
+ import { getGlMrDiff, listGlFindingIds, listGlWontFixFindingIds, postGlReview, resolveGlRef, } from "./gitlab/comments.js";
8
+ import { loadConfig } from "./config.js";
9
+ import { getPrDiff, getPrHeadSha, makeOctokit, parseRepoSlug } from "./diff/github.js";
10
+ import { getLocalDiff } from "./diff/local.js";
11
+ import { listPostedFindingIds, listWontFixFindingIds, postReview } from "./github/comments.js";
12
+ import { formatReport, shouldFail } from "./report/cli.js";
13
+ import { buildJsonReport, formatRunSummaryLine, loadPreviousFindings, loadPreviousIds, writeJsonReport, } from "./report/json.js";
14
+ import { runReview } from "./review.js";
15
+ import { appendSuppressionIds, loadSuppressions } from "./suppressions.js";
16
+ import { SEVERITIES } from "./types.js";
17
+ const program = new Command();
18
+ const log = (msg) => console.error(pc.dim(msg));
19
+ program
20
+ .name("secondpair")
21
+ .description("secondpair — the second pair of eyes: LLM PR reviewer with a persistent repo memory (codengram) for whole-project context")
22
+ .version("0.1.0");
23
+ program
24
+ .command("index")
25
+ .description("Build or incrementally update the repo memory (.codengram/index.json)")
26
+ .option("--full", "re-index every file regardless of content hash", false)
27
+ .option("--no-llm", "skip LLM summaries (symbols + import graph only; no API key needed)")
28
+ .option("--dir <path>", "repository root", process.cwd())
29
+ .option("--config <path>", "path to .pr-review.yml")
30
+ .action(async (opts) => {
31
+ const cwd = path.resolve(opts.dir);
32
+ const config = await loadConfig(cwd, opts.config);
33
+ const stats = await runIndex({
34
+ cwd,
35
+ full: opts.full,
36
+ llm: opts.llm,
37
+ ignore: config.ignore,
38
+ log,
39
+ });
40
+ console.log(pc.green(`Codemap updated: ${stats.indexed} indexed, ${stats.unchanged} unchanged, ${stats.removed} removed (${stats.total} files).`));
41
+ });
42
+ program
43
+ .command("review")
44
+ .description("Review a diff (local branch, staged changes, or a GitHub/Bitbucket/GitLab PR)")
45
+ .option("--staged", "review staged changes instead of branch vs base", false)
46
+ .option("--base <ref>", "base ref for the local diff (default: auto-detected origin/main)")
47
+ .option("--pr <number>", "pull request number/id to review", (v) => parseInt(v, 10))
48
+ .option("--repo <owner/name>", "repository (GitHub owner/name, Bitbucket workspace/repo_slug, or GitLab group/project; default from CI env vars)")
49
+ .option("--host <host>", "github | bitbucket | gitlab (default: detected from CI env vars, else github)")
50
+ .option("--json <path>", "write findings JSON to this path", "pr-review-report.json")
51
+ .option("--post", "post findings as inline PR review comments", false)
52
+ .option("--fail-on <severity>", `exit 1 at/above this severity (${SEVERITIES.join("|")}); overrides config`)
53
+ .option("--no-context", "review the diff without codemap context")
54
+ .option("--dir <path>", "repository root", process.cwd())
55
+ .option("--config <path>", "path to .pr-review.yml")
56
+ .option("--suppressions <path>", "path to .pr-review-suppressions.yml")
57
+ .option("--write-suppressions", "append won’t-fix finding ids to .pr-review-suppressions.yml", false)
58
+ .action(async (opts) => {
59
+ const cwd = path.resolve(opts.dir);
60
+ const config = await loadConfig(cwd, opts.config);
61
+ if (opts.writeSuppressions)
62
+ config.write_suppressions = true;
63
+ if (opts.failOn) {
64
+ if (!SEVERITIES.includes(opts.failOn)) {
65
+ throw new Error(`--fail-on must be one of: ${SEVERITIES.join(", ")}`);
66
+ }
67
+ config.fail_on = opts.failOn;
68
+ }
69
+ const env = process.env;
70
+ const host = opts.host ??
71
+ (env.BITBUCKET_WORKSPACE || env.BITBUCKET_PR_ID
72
+ ? "bitbucket"
73
+ : env.GITLAB_CI
74
+ ? "gitlab"
75
+ : "github");
76
+ if (host !== "github" && host !== "bitbucket" && host !== "gitlab") {
77
+ throw new Error(`--host must be github, bitbucket, or gitlab, got "${opts.host}".`);
78
+ }
79
+ const bbPrAvailable = host === "bitbucket" && (opts.pr != null || env.BITBUCKET_PR_ID);
80
+ const glMrAvailable = host === "gitlab" && (opts.pr != null || env.CI_MERGE_REQUEST_IID);
81
+ let diffText;
82
+ let changeDescription;
83
+ let prRef = null;
84
+ let octokit = null;
85
+ let bbRef = null;
86
+ let glRef = null;
87
+ let glDiffRefs = null;
88
+ if (glMrAvailable) {
89
+ glRef = resolveGlRef(opts.repo, opts.pr);
90
+ log(`Fetching diff for project ${decodeURIComponent(glRef.projectId)} MR !${glRef.mrIid} (GitLab)…`);
91
+ const mr = await getGlMrDiff(glRef);
92
+ diffText = mr.diffText;
93
+ glDiffRefs = mr.diffRefs;
94
+ changeDescription = `MR !${glRef.mrIid} in ${decodeURIComponent(glRef.projectId)}`;
95
+ }
96
+ else if (bbPrAvailable) {
97
+ bbRef = resolveBbRef(opts.repo, opts.pr);
98
+ log(`Fetching diff for ${bbRef.workspace}/${bbRef.repoSlug} PR #${bbRef.prId} (Bitbucket)…`);
99
+ diffText = await getBbPrDiff(bbRef);
100
+ changeDescription = `PR #${bbRef.prId} in ${bbRef.workspace}/${bbRef.repoSlug}`;
101
+ }
102
+ else if (opts.pr != null) {
103
+ const slug = opts.repo ?? process.env.GITHUB_REPOSITORY;
104
+ if (!slug)
105
+ throw new Error("Pass --repo owner/name or set GITHUB_REPOSITORY when using --pr.");
106
+ octokit = makeOctokit(process.env.GITHUB_TOKEN);
107
+ prRef = { ...parseRepoSlug(slug), pull_number: opts.pr };
108
+ log(`Fetching diff for ${slug}#${opts.pr}…`);
109
+ diffText = await getPrDiff(octokit, prRef);
110
+ changeDescription = `PR #${opts.pr} in ${slug}`;
111
+ }
112
+ else {
113
+ diffText = await getLocalDiff({ cwd, staged: opts.staged, base: opts.base });
114
+ changeDescription = opts.staged
115
+ ? "staged changes"
116
+ : `local diff vs ${opts.base ?? "auto-detected base"}`;
117
+ }
118
+ if (diffText.trim() === "") {
119
+ console.log(pc.yellow("Nothing to review — the diff is empty."));
120
+ return;
121
+ }
122
+ const jsonPath = path.resolve(cwd, opts.json);
123
+ const previousIds = await loadPreviousIds(jsonPath);
124
+ const previousFindings = await loadPreviousFindings(jsonPath);
125
+ const suppressions = await loadSuppressions(cwd, opts.suppressions);
126
+ const ephemeral = new Set();
127
+ try {
128
+ if (glRef) {
129
+ for (const id of await listGlWontFixFindingIds(glRef))
130
+ ephemeral.add(id);
131
+ }
132
+ else if (bbRef) {
133
+ for (const id of await listBbWontFixFindingIds(bbRef))
134
+ ephemeral.add(id);
135
+ }
136
+ else if (prRef && octokit) {
137
+ for (const id of await listWontFixFindingIds(octokit, prRef))
138
+ ephemeral.add(id);
139
+ }
140
+ }
141
+ catch (e) {
142
+ log(`Warning: could not scan won’t-fix replies: ${e instanceof Error ? e.message : e}`);
143
+ }
144
+ const suppressedIds = new Set([...suppressions.ids, ...ephemeral]);
145
+ if (opts.post) {
146
+ if (glRef) {
147
+ for (const id of await listGlFindingIds(glRef))
148
+ previousIds.add(id);
149
+ }
150
+ else if (bbRef) {
151
+ for (const id of await listBbFindingIds(bbRef))
152
+ previousIds.add(id);
153
+ }
154
+ else if (prRef && octokit) {
155
+ for (const id of await listPostedFindingIds(octokit, prRef))
156
+ previousIds.add(id);
157
+ }
158
+ }
159
+ const result = await runReview({
160
+ cwd,
161
+ diffText,
162
+ config,
163
+ changeDescription,
164
+ useContext: opts.context,
165
+ previousIds,
166
+ previousFindings,
167
+ suppressedIds,
168
+ log,
169
+ });
170
+ if (config.write_suppressions && ephemeral.size) {
171
+ const n = await appendSuppressionIds(cwd, ephemeral, opts.suppressions);
172
+ if (n)
173
+ log(`Wrote ${n} new id(s) to suppressions file.`);
174
+ }
175
+ console.log("\n" + formatReport(result) + "\n");
176
+ await writeJsonReport(jsonPath, buildJsonReport(result, {
177
+ model: getModel(),
178
+ changeDescription,
179
+ usedContext: result.usedContext,
180
+ }));
181
+ log(`Wrote ${jsonPath}`);
182
+ console.error(formatRunSummaryLine(result.stats));
183
+ const failed = shouldFail(result.findings, config.fail_on);
184
+ if (opts.post) {
185
+ if (glRef && glDiffRefs) {
186
+ await postGlReview({ ref: glRef, diffRefs: glDiffRefs, result, failed, log });
187
+ }
188
+ else if (bbRef) {
189
+ await postBbReview({ ref: bbRef, result, failed, log });
190
+ }
191
+ else if (prRef && octokit) {
192
+ const headSha = await getPrHeadSha(octokit, prRef);
193
+ await postReview({ octokit, pr: prRef, headSha, result, failed, log });
194
+ }
195
+ else {
196
+ throw new Error("--post requires a PR (--pr, or Bitbucket/GitLab CI env vars).");
197
+ }
198
+ }
199
+ if (failed) {
200
+ console.error(pc.red(`✖ Failing: findings at or above "${config.fail_on}" severity.`));
201
+ process.exitCode = 1;
202
+ }
203
+ });
204
+ program.parseAsync().catch((err) => {
205
+ console.error(pc.red(`Error: ${err instanceof Error ? err.message : String(err)}`));
206
+ process.exit(2);
207
+ });
208
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ import { matchesGlob } from "codengram";
3
+ import { type ReviewConfig } from "./types.js";
4
+ export { matchesGlob };
5
+ export declare const DEFAULT_CONFIG: ReviewConfig;
6
+ declare const configSchema: z.ZodObject<{
7
+ fail_on: z.ZodOptional<z.ZodEnum<{
8
+ [x: string]: string;
9
+ }>>;
10
+ min_confidence: z.ZodOptional<z.ZodNumber>;
11
+ ignore: z.ZodOptional<z.ZodArray<z.ZodString>>;
12
+ context_token_budget: z.ZodOptional<z.ZodNumber>;
13
+ context_snippets: z.ZodOptional<z.ZodNumber>;
14
+ custom_instructions: z.ZodOptional<z.ZodString>;
15
+ categories: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
16
+ [x: string]: string;
17
+ }> & z.core.$partial, z.ZodBoolean>>;
18
+ temperature: z.ZodOptional<z.ZodNumber>;
19
+ limits: z.ZodOptional<z.ZodObject<{
20
+ max_findings_per_file: z.ZodOptional<z.ZodNumber>;
21
+ max_total: z.ZodOptional<z.ZodNumber>;
22
+ }, z.core.$strict>>;
23
+ self_critique: z.ZodOptional<z.ZodBoolean>;
24
+ redact_secrets: z.ZodOptional<z.ZodBoolean>;
25
+ redact_patterns: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ write_suppressions: z.ZodOptional<z.ZodBoolean>;
27
+ }, z.core.$strict>;
28
+ export declare const CONFIG_FILENAME = ".pr-review.yml";
29
+ /** Load .pr-review.yml from the repo root, merged over defaults. */
30
+ export declare function loadConfig(cwd: string, configPath?: string): Promise<ReviewConfig>;
31
+ export declare function mergeConfig(partial: z.infer<typeof configSchema>): ReviewConfig;
32
+ /** True when the path matches codengram's built-in ignores or this config's patterns. */
33
+ export declare function isIgnored(filePath: string, config: ReviewConfig): boolean;