@blogic-cz/agent-tools 0.14.32 → 0.14.34
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/package.json +1 -1
- package/src/gh-tool/index.ts +2 -0
- package/src/gh-tool/pr/commands.ts +71 -12
- package/src/gh-tool/pr/index.ts +1 -0
package/package.json
CHANGED
package/src/gh-tool/index.ts
CHANGED
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
prChecksFailedCommand,
|
|
37
37
|
prRerunChecksCommand,
|
|
38
38
|
prReplyAndResolveCommand,
|
|
39
|
+
prReviewTriageBatchCommand,
|
|
39
40
|
prReviewTriageCommand,
|
|
40
41
|
} from "./pr/index";
|
|
41
42
|
import { branchRenameCommand } from "./branch";
|
|
@@ -84,6 +85,7 @@ const prCommand = Command.make("pr", {}).pipe(
|
|
|
84
85
|
prRerunChecksCommand,
|
|
85
86
|
prReplyAndResolveCommand,
|
|
86
87
|
prReviewTriageCommand,
|
|
88
|
+
prReviewTriageBatchCommand,
|
|
87
89
|
]),
|
|
88
90
|
);
|
|
89
91
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command, Flag } from "effect/unstable/cli";
|
|
2
2
|
import { Effect, Option } from "effect";
|
|
3
3
|
|
|
4
|
-
import type { PRStatusResult } from "#gh/types";
|
|
4
|
+
import type { CheckResult, PRStatusResult } from "#gh/types";
|
|
5
5
|
|
|
6
6
|
import { formatOption, logFormatted } from "#shared";
|
|
7
7
|
import { GitHubService } from "#gh/service";
|
|
@@ -56,6 +56,50 @@ const withRepo = <A, E, R>(repo: Option.Option<string>, effect: Effect.Effect<A,
|
|
|
56
56
|
return yield* gh.withRepoTarget(Option.getOrNull(repo), effect);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
+
type ReviewTriageSummary = {
|
|
60
|
+
readonly visibleOpenReviewThreadsCount: number;
|
|
61
|
+
readonly unrepliedReviewThreadsCount: number;
|
|
62
|
+
readonly unresolvedReviewThreadsCount: number;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
type ReviewTriageClassification = {
|
|
66
|
+
readonly status: "clear" | "needs_investigation";
|
|
67
|
+
readonly reasons: readonly string[];
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const classifyReviewTriage = (
|
|
71
|
+
summary: ReviewTriageSummary,
|
|
72
|
+
checks: readonly CheckResult[],
|
|
73
|
+
): ReviewTriageClassification => {
|
|
74
|
+
const reasons = [
|
|
75
|
+
...(checks.some((check) => check.bucket === "fail") ? ["failed_checks"] : []),
|
|
76
|
+
...(summary.visibleOpenReviewThreadsCount > 0 ? ["visible_open_review_threads"] : []),
|
|
77
|
+
...(summary.unrepliedReviewThreadsCount > 0 ? ["unreplied_review_threads"] : []),
|
|
78
|
+
...(summary.unresolvedReviewThreadsCount > 0 ? ["unresolved_review_threads"] : []),
|
|
79
|
+
];
|
|
80
|
+
return { status: reasons.length > 0 ? "needs_investigation" : "clear", reasons };
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const parsePrNumbers = (input: string): readonly number[] =>
|
|
84
|
+
input
|
|
85
|
+
.split(",")
|
|
86
|
+
.map((part) => Number.parseInt(part.trim(), 10))
|
|
87
|
+
.filter((number) => Number.isInteger(number) && number > 0);
|
|
88
|
+
|
|
89
|
+
export const fetchReviewTriage = Effect.fn("pr.fetchReviewTriage")(function* (
|
|
90
|
+
prNumber: number | null,
|
|
91
|
+
) {
|
|
92
|
+
const [info, unresolvedThreads, visibleOpenThreads, summary, checks] = yield* Effect.all([
|
|
93
|
+
viewPR(prNumber),
|
|
94
|
+
fetchThreads(prNumber, true),
|
|
95
|
+
fetchThreads(prNumber, false, true),
|
|
96
|
+
fetchDiscussionSummary(prNumber),
|
|
97
|
+
fetchChecks(prNumber, false, false, 0),
|
|
98
|
+
]);
|
|
99
|
+
const classification = classifyReviewTriage(summary, checks);
|
|
100
|
+
return { classification, info, unresolvedThreads, visibleOpenThreads, summary, checks };
|
|
101
|
+
});
|
|
102
|
+
|
|
59
103
|
export const prViewCommand = Command.make(
|
|
60
104
|
"view",
|
|
61
105
|
{
|
|
@@ -663,17 +707,8 @@ export const prReviewTriageCommand = Command.make(
|
|
|
663
707
|
repo,
|
|
664
708
|
Effect.gen(function* () {
|
|
665
709
|
const prNumber = Option.getOrNull(pr);
|
|
666
|
-
const
|
|
667
|
-
|
|
668
|
-
fetchThreads(prNumber, true),
|
|
669
|
-
fetchThreads(prNumber, false, true),
|
|
670
|
-
fetchDiscussionSummary(prNumber),
|
|
671
|
-
fetchChecks(prNumber, false, false, 0),
|
|
672
|
-
]);
|
|
673
|
-
yield* logFormatted(
|
|
674
|
-
{ info, unresolvedThreads, visibleOpenThreads, summary, checks },
|
|
675
|
-
format,
|
|
676
|
-
);
|
|
710
|
+
const result = yield* fetchReviewTriage(prNumber);
|
|
711
|
+
yield* logFormatted(result, format);
|
|
677
712
|
}),
|
|
678
713
|
),
|
|
679
714
|
).pipe(
|
|
@@ -682,6 +717,30 @@ export const prReviewTriageCommand = Command.make(
|
|
|
682
717
|
),
|
|
683
718
|
);
|
|
684
719
|
|
|
720
|
+
export const prReviewTriageBatchCommand = Command.make(
|
|
721
|
+
"review-triage-batch",
|
|
722
|
+
{
|
|
723
|
+
format: formatOption,
|
|
724
|
+
prs: Flag.string("prs").pipe(Flag.withDescription("Comma-separated PR numbers")),
|
|
725
|
+
repo: repoOption,
|
|
726
|
+
},
|
|
727
|
+
({ format, prs, repo }) =>
|
|
728
|
+
withRepo(
|
|
729
|
+
repo,
|
|
730
|
+
Effect.gen(function* () {
|
|
731
|
+
const results = yield* Effect.all(
|
|
732
|
+
parsePrNumbers(prs).map((prNumber) => fetchReviewTriage(prNumber)),
|
|
733
|
+
{ concurrency: "unbounded" },
|
|
734
|
+
);
|
|
735
|
+
yield* logFormatted(results, format);
|
|
736
|
+
}),
|
|
737
|
+
),
|
|
738
|
+
).pipe(
|
|
739
|
+
Command.withDescription(
|
|
740
|
+
"Composite: fetch review-triage output for multiple PRs in one gh-tool invocation",
|
|
741
|
+
),
|
|
742
|
+
);
|
|
743
|
+
|
|
685
744
|
export const prReplyAndResolveCommand = Command.make(
|
|
686
745
|
"reply-and-resolve",
|
|
687
746
|
{
|