@jphutchins/code-review 0.1.0-alpha.63 → 0.1.0-alpha.64
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/dist/index.js +57 -82
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -494,7 +494,7 @@ var incompleteFindings = (summary) => ({
|
|
|
494
494
|
var isIncompleteFindings = (findings) => findings.verdict === "error" && findings.findings.length === 0;
|
|
495
495
|
|
|
496
496
|
// src/released.ts
|
|
497
|
-
var RELEASED = "2026-
|
|
497
|
+
var RELEASED = "2026-10-02";
|
|
498
498
|
|
|
499
499
|
// src/cost.ts
|
|
500
500
|
var defaultWarn = (message) => {
|
|
@@ -3546,6 +3546,18 @@ ${dropNote}` : ""}`,
|
|
|
3546
3546
|
const template = readFileSync(input.templatePath, "utf-8");
|
|
3547
3547
|
const inlineRequested = input.inline === true;
|
|
3548
3548
|
const envelope = loadEnvelope(input.envelopePath);
|
|
3549
|
+
const effectiveRoute = input.route ?? envelope?.route;
|
|
3550
|
+
const runRenderInput = {
|
|
3551
|
+
prices: decodedPrices.right,
|
|
3552
|
+
pricesProvided: input.pricesProvided,
|
|
3553
|
+
template,
|
|
3554
|
+
route: effectiveRoute,
|
|
3555
|
+
reviewedSha: input.headSha,
|
|
3556
|
+
effort: input.effort,
|
|
3557
|
+
runUrl: input.runUrl,
|
|
3558
|
+
jsonUrl: input.jsonUrl,
|
|
3559
|
+
postedAt: input.postedAt
|
|
3560
|
+
};
|
|
3549
3561
|
const reachable = existingSticky !== null ? discussionRows(commentRows, existingSticky.id, input.botLogin) : [];
|
|
3550
3562
|
const priorIsMechanic = existingSticky !== null && (parseReviewedRoute(existingSticky.body) === "mechanic" || parseMechanicAncestor(existingSticky.body));
|
|
3551
3563
|
const noticeDiscussion = async () => {
|
|
@@ -3569,7 +3581,7 @@ ${dropNote}` : ""}`,
|
|
|
3569
3581
|
};
|
|
3570
3582
|
};
|
|
3571
3583
|
const renderNotice = (message, discussion) => {
|
|
3572
|
-
const noticeConvergence =
|
|
3584
|
+
const noticeConvergence = effectiveRoute === "mechanic" ? mechanicConvergence(
|
|
3573
3585
|
priorConv,
|
|
3574
3586
|
input.convergenceThreshold ?? DEFAULT_CONVERGENCE_THRESHOLD
|
|
3575
3587
|
) : priorConv;
|
|
@@ -3582,22 +3594,14 @@ ${dropNote}` : ""}`,
|
|
|
3582
3594
|
};
|
|
3583
3595
|
return formatMarkdown(
|
|
3584
3596
|
render({
|
|
3597
|
+
...runRenderInput,
|
|
3585
3598
|
findings: findings2,
|
|
3586
3599
|
envelope: null,
|
|
3587
3600
|
incomplete: true,
|
|
3588
|
-
prices: decodedPrices.right,
|
|
3589
|
-
pricesProvided: input.pricesProvided,
|
|
3590
|
-
template,
|
|
3591
|
-
route: input.route,
|
|
3592
|
-
reviewedSha: input.headSha,
|
|
3593
|
-
effort: input.effort,
|
|
3594
3601
|
sameRootNotes: {},
|
|
3595
3602
|
roundCount: priorRoundCount,
|
|
3596
3603
|
convergenceRound: false,
|
|
3597
|
-
runUrl: input.runUrl,
|
|
3598
|
-
jsonUrl: input.jsonUrl,
|
|
3599
3604
|
findingsPointer: noticeFindingsPointer(findings2),
|
|
3600
|
-
postedAt: input.postedAt,
|
|
3601
3605
|
orphanedDiscussion: discussion.orphanedDiscussion,
|
|
3602
3606
|
orphanedTotal: discussion.orphanedTotal,
|
|
3603
3607
|
orphanedTruncated: discussion.orphanedTruncated,
|
|
@@ -3694,7 +3698,6 @@ ${dropNote}` : ""}`,
|
|
|
3694
3698
|
const orphanedTruncated = stickyDiscussion.orphanedTruncated;
|
|
3695
3699
|
const testReport = input.testReportPath ? loadTestReport(input.testReportPath) : void 0;
|
|
3696
3700
|
const clocDiff = input.clocDiffPath ? loadClocDiff(input.clocDiffPath) : void 0;
|
|
3697
|
-
const effectiveRoute = input.route ?? envelope?.route;
|
|
3698
3701
|
const shedPriority = (f) => SEVERITIES.length - 1 - SEVERITIES.indexOf(f.severity);
|
|
3699
3702
|
const shedOrderOf = (list) => list.map((f, index) => ({ f, index })).sort((a, b) => shedPriority(a.f) - shedPriority(b.f) || a.index - b.index).map((entry) => entry.f);
|
|
3700
3703
|
const sizeSticky = (renderAt, total, reserve = SHED_RESERVE) => {
|
|
@@ -3763,6 +3766,33 @@ ${findingsPointer2}`
|
|
|
3763
3766
|
${note}
|
|
3764
3767
|
`;
|
|
3765
3768
|
};
|
|
3769
|
+
const sharedRenderInput = {
|
|
3770
|
+
...runRenderInput,
|
|
3771
|
+
repo: input.headRepo || input.repo,
|
|
3772
|
+
testReport,
|
|
3773
|
+
clocDiff,
|
|
3774
|
+
// The answered-state honesty rules apply on EVERY surface that renders the filtered
|
|
3775
|
+
// findings — the lost-envelope branch lists every VISIBLE finding (no inline review exists to
|
|
3776
|
+
// carry them) so the kept re-raises' annotations actually render, and names the drops
|
|
3777
|
+
// exactly like the main path (issues #151 review r1 + r2). The nit visibility floor applies
|
|
3778
|
+
// here too (issue #164): below-floor nits are hidden from the human list and shown only in the
|
|
3779
|
+
// collapsed aside — the floor is a human-visibility policy, not an inline-comment policy, so it
|
|
3780
|
+
// must hold on the surface that lists findings without an inline review.
|
|
3781
|
+
suppressedNits,
|
|
3782
|
+
nitVisibilityFloor: input.nitVisibilityFloor,
|
|
3783
|
+
answeredNotes: reRaisedNotes,
|
|
3784
|
+
answeredReRaiseNote: answeredDropNote,
|
|
3785
|
+
discussionByFinding,
|
|
3786
|
+
orphanedDiscussion,
|
|
3787
|
+
orphanedTotal,
|
|
3788
|
+
discussionTruncated,
|
|
3789
|
+
orphanedTruncated,
|
|
3790
|
+
orphanedUnresolvable: orphanResolveFailed,
|
|
3791
|
+
convergenceThreshold: input.convergenceThreshold,
|
|
3792
|
+
unverifiedNoLogs: input.unverifiedNoLogs,
|
|
3793
|
+
pricedAt: input.pricedAt,
|
|
3794
|
+
summaryAvailable
|
|
3795
|
+
};
|
|
3766
3796
|
if (envelope === null) {
|
|
3767
3797
|
const envelopelessIncomplete = isIncompleteFindings(findings);
|
|
3768
3798
|
if (wouldBuryCompleted(envelopelessIncomplete)) {
|
|
@@ -3779,44 +3809,14 @@ ${note}
|
|
|
3779
3809
|
) : priorConv
|
|
3780
3810
|
);
|
|
3781
3811
|
const lostInput = {
|
|
3812
|
+
...sharedRenderInput,
|
|
3782
3813
|
findings: stampedFindings2,
|
|
3783
3814
|
envelope: null,
|
|
3784
3815
|
incomplete: envelopelessIncomplete,
|
|
3785
|
-
prices: decodedPrices.right,
|
|
3786
|
-
pricesProvided: input.pricesProvided,
|
|
3787
|
-
template,
|
|
3788
|
-
route: effectiveRoute,
|
|
3789
|
-
reviewedSha: input.headSha,
|
|
3790
|
-
repo: input.headRepo || input.repo,
|
|
3791
|
-
effort: input.effort,
|
|
3792
3816
|
sameRootNotes: {},
|
|
3793
|
-
// The answered-state honesty rules apply on EVERY surface that renders the filtered
|
|
3794
|
-
// findings — the lost-envelope branch lists every VISIBLE finding (no inline review exists to
|
|
3795
|
-
// carry them) so the kept re-raises' annotations actually render, and names the drops
|
|
3796
|
-
// exactly like the main path (issues #151 review r1 + r2). The nit visibility floor applies
|
|
3797
|
-
// here too (issue #164): below-floor nits are hidden from the human list and shown only in the
|
|
3798
|
-
// collapsed aside — the floor is a human-visibility policy, not an inline-comment policy, so it
|
|
3799
|
-
// must hold on the surface that lists findings without an inline review.
|
|
3800
|
-
suppressedNits,
|
|
3801
|
-
nitVisibilityFloor: input.nitVisibilityFloor,
|
|
3802
|
-
answeredNotes: reRaisedNotes,
|
|
3803
|
-
answeredReRaiseNote: answeredDropNote,
|
|
3804
3817
|
roundCount: priorRoundCount,
|
|
3805
3818
|
convergenceRound: false,
|
|
3806
|
-
|
|
3807
|
-
clocDiff,
|
|
3808
|
-
runUrl: input.runUrl,
|
|
3809
|
-
unverifiedNoLogs: input.unverifiedNoLogs,
|
|
3810
|
-
jsonUrl: input.jsonUrl,
|
|
3811
|
-
findingsPointer: findingsBlob(stampedFindings2),
|
|
3812
|
-
postedAt: input.postedAt,
|
|
3813
|
-
summaryAvailable,
|
|
3814
|
-
discussionByFinding,
|
|
3815
|
-
orphanedDiscussion,
|
|
3816
|
-
orphanedTotal,
|
|
3817
|
-
discussionTruncated,
|
|
3818
|
-
orphanedTruncated,
|
|
3819
|
-
orphanedUnresolvable: orphanResolveFailed
|
|
3819
|
+
findingsPointer: findingsBlob(stampedFindings2)
|
|
3820
3820
|
};
|
|
3821
3821
|
const lostRender = (opts) => formatMarkdown(
|
|
3822
3822
|
render({
|
|
@@ -3894,7 +3894,6 @@ ${note}
|
|
|
3894
3894
|
}
|
|
3895
3895
|
const botReviews = await fetchBotReviews(input.repo, prNumber, input.botLogin, ghApi);
|
|
3896
3896
|
const initialDisposition = !inlineRequested ? { kind: "disabled" } : comments.length === 0 && strays.length > 0 ? { kind: "none-in-diff" } : void 0;
|
|
3897
|
-
const currentCounts = computeSeverityCounts(findings.findings);
|
|
3898
3897
|
const currentCodes = computeIdCounts(findings.findings, findings.systemic_problems ?? []);
|
|
3899
3898
|
const roundNumber = priorRoundCount + 1;
|
|
3900
3899
|
const convergence = isRound ? buildConvergence(
|
|
@@ -3914,41 +3913,15 @@ ${note}
|
|
|
3914
3913
|
const currentRoundCount = isRound ? roundNumber : priorRoundCount;
|
|
3915
3914
|
const findingsMarker = findingsBlob(stampedFindings);
|
|
3916
3915
|
const commonRenderInput = {
|
|
3916
|
+
...sharedRenderInput,
|
|
3917
3917
|
findings: stampedFindings,
|
|
3918
3918
|
envelope,
|
|
3919
3919
|
incomplete: thisIncomplete,
|
|
3920
|
-
prices: decodedPrices.right,
|
|
3921
|
-
pricesProvided: input.pricesProvided,
|
|
3922
|
-
template,
|
|
3923
|
-
route: effectiveRoute,
|
|
3924
|
-
reviewedSha: input.headSha,
|
|
3925
|
-
repo: input.headRepo || input.repo,
|
|
3926
|
-
effort: input.effort,
|
|
3927
|
-
testReport,
|
|
3928
|
-
clocDiff,
|
|
3929
|
-
severityCounts: currentCounts,
|
|
3930
3920
|
sameRootNotes,
|
|
3931
|
-
answeredNotes: reRaisedNotes,
|
|
3932
|
-
answeredReRaiseNote: answeredDropNote,
|
|
3933
|
-
discussionByFinding,
|
|
3934
|
-
orphanedDiscussion,
|
|
3935
|
-
orphanedTotal,
|
|
3936
|
-
discussionTruncated,
|
|
3937
|
-
orphanedTruncated,
|
|
3938
|
-
orphanedUnresolvable: orphanResolveFailed,
|
|
3939
3921
|
roundCount: currentRoundCount,
|
|
3940
|
-
convergenceThreshold: input.convergenceThreshold,
|
|
3941
|
-
nitVisibilityFloor: input.nitVisibilityFloor,
|
|
3942
3922
|
convergenceRound: isRound,
|
|
3943
3923
|
strays,
|
|
3944
|
-
|
|
3945
|
-
runUrl: input.runUrl,
|
|
3946
|
-
unverifiedNoLogs: input.unverifiedNoLogs,
|
|
3947
|
-
jsonUrl: input.jsonUrl,
|
|
3948
|
-
findingsPointer: findingsMarker,
|
|
3949
|
-
postedAt: input.postedAt,
|
|
3950
|
-
pricedAt: input.pricedAt,
|
|
3951
|
-
summaryAvailable
|
|
3924
|
+
findingsPointer: findingsMarker
|
|
3952
3925
|
};
|
|
3953
3926
|
const longFilesNote = longFiles.length > 0 ? `
|
|
3954
3927
|
|
|
@@ -4526,6 +4499,13 @@ failing_jobs=${String(result.failingJobs)}
|
|
|
4526
4499
|
`;
|
|
4527
4500
|
}
|
|
4528
4501
|
};
|
|
4502
|
+
var FETCH_WITHOUT_DETACHED_CHILDREN = [
|
|
4503
|
+
"-c",
|
|
4504
|
+
"maintenance.auto=false",
|
|
4505
|
+
"-c",
|
|
4506
|
+
"gc.auto=0",
|
|
4507
|
+
"fetch"
|
|
4508
|
+
];
|
|
4529
4509
|
var runGit = (args) => execFileWithTimeout({
|
|
4530
4510
|
command: "git",
|
|
4531
4511
|
args,
|
|
@@ -4593,7 +4573,7 @@ var fetchFullDiff = async (repo, defaultBranch, headSha, ghApi, gitRun) => {
|
|
|
4593
4573
|
process.stderr.write(`compare diff fetch failed (${errMsg(err)}) \u2014 falling back to git diff
|
|
4594
4574
|
`);
|
|
4595
4575
|
}
|
|
4596
|
-
await gitRun([
|
|
4576
|
+
await gitRun([...FETCH_WITHOUT_DETACHED_CHILDREN, "origin", headSha]);
|
|
4597
4577
|
const base = (await gitRun(["rev-parse", "HEAD"])).trim();
|
|
4598
4578
|
return gitRun(["diff", `${base}...${headSha}`]);
|
|
4599
4579
|
};
|
|
@@ -4785,7 +4765,7 @@ var gather = async (input, ghApi = runGhApi, gitRun = runGit, readArtifact = ghA
|
|
|
4785
4765
|
`PR diff fetch failed or was empty for ${String(meta.changed_files)} changed files \u2014 falling back to git diff
|
|
4786
4766
|
`
|
|
4787
4767
|
);
|
|
4788
|
-
await gitRun([
|
|
4768
|
+
await gitRun([...FETCH_WITHOUT_DETACHED_CHILDREN, "origin", input.headSha]);
|
|
4789
4769
|
return gitRun(["diff", meta.base_sha, input.headSha]);
|
|
4790
4770
|
})();
|
|
4791
4771
|
const fullDiff = stacked ? await fetchFullDiff(input.repo, input.defaultBranch, input.headSha, ghApi, gitRun) : prDiff;
|
|
@@ -5153,7 +5133,6 @@ var composeReviewSettings = (opts) => {
|
|
|
5153
5133
|
};
|
|
5154
5134
|
|
|
5155
5135
|
// src/sandbox.ts
|
|
5156
|
-
var GITHUB_HOSTS = ["api.github.com", "github.com"];
|
|
5157
5136
|
var deriveModelHost = (apiBaseUrl) => {
|
|
5158
5137
|
const host = URL.canParse(apiBaseUrl) ? new URL(apiBaseUrl).hostname : "";
|
|
5159
5138
|
if (host === "") {
|
|
@@ -5173,11 +5152,7 @@ var parseExtraEndpoints = (extra) => extra.split(/\s+/).map((token) => token.rep
|
|
|
5173
5152
|
var buildSandboxConfig = (opts) => ({
|
|
5174
5153
|
network: {
|
|
5175
5154
|
allowedDomains: [
|
|
5176
|
-
.../* @__PURE__ */ new Set([
|
|
5177
|
-
deriveModelHost(opts.apiBaseUrl),
|
|
5178
|
-
...GITHUB_HOSTS,
|
|
5179
|
-
...parseExtraEndpoints(opts.extra ?? "")
|
|
5180
|
-
])
|
|
5155
|
+
.../* @__PURE__ */ new Set([deriveModelHost(opts.apiBaseUrl), ...parseExtraEndpoints(opts.extra ?? "")])
|
|
5181
5156
|
],
|
|
5182
5157
|
deniedDomains: []
|
|
5183
5158
|
},
|
|
@@ -6969,7 +6944,7 @@ var checkScopeCmd = defineCommand({
|
|
|
6969
6944
|
var sandboxConfigCmd = defineCommand({
|
|
6970
6945
|
meta: {
|
|
6971
6946
|
name: "sandbox-config",
|
|
6972
|
-
description: "Emit the sandbox-runtime (srt) settings that jail the untrusted review agent's egress: allow the model host (derived from api_base_url)
|
|
6947
|
+
description: "Emit the sandbox-runtime (srt) settings that jail the untrusted review agent's egress: allow the model host (derived from api_base_url) and the consumer's extra_endpoints; deny all else; filesystem isolation off"
|
|
6973
6948
|
},
|
|
6974
6949
|
args: {
|
|
6975
6950
|
"api-base-url": {
|