@blogic-cz/agent-tools 1.16.1 → 1.16.2

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 (42) hide show
  1. package/README.md +19 -0
  2. package/dist/gh-tool/issue/triage.d.ts +1 -1
  3. package/dist/gh-tool/issue/triage.d.ts.map +1 -1
  4. package/dist/gh-tool/main.d.ts.map +1 -1
  5. package/dist/gh-tool/pr/commands.d.ts +7 -7
  6. package/dist/gh-tool/pr/commands.d.ts.map +1 -1
  7. package/dist/gh-tool/pr/core.d.ts +9 -9
  8. package/dist/gh-tool/pr/review.d.ts +3 -3
  9. package/dist/gh-tool/pr/review.d.ts.map +1 -1
  10. package/dist/gh-tool/read/graphql-fallback.d.ts +21 -0
  11. package/dist/gh-tool/read/graphql-fallback.d.ts.map +1 -0
  12. package/dist/gh-tool/read/pulls.d.ts +13 -12
  13. package/dist/gh-tool/read/pulls.d.ts.map +1 -1
  14. package/dist/gh-tool/read/reads.d.ts +6 -5
  15. package/dist/gh-tool/read/reads.d.ts.map +1 -1
  16. package/dist/gh-tool/read/rest-porcelain.d.ts +131 -0
  17. package/dist/gh-tool/read/rest-porcelain.d.ts.map +1 -0
  18. package/dist/gh-tool/read/review-guards.d.ts +1 -1
  19. package/dist/gh-tool/read/review-guards.d.ts.map +1 -1
  20. package/dist/gh-tool/read/review-model.d.ts +1 -1
  21. package/dist/gh-tool/read/review-model.d.ts.map +1 -1
  22. package/dist/gh-tool/read/reviews.d.ts.map +1 -1
  23. package/dist/gh-tool/read/telemetry.d.ts +1 -1
  24. package/dist/gh-tool/read/telemetry.d.ts.map +1 -1
  25. package/dist/gh-tool/read/transport.d.ts.map +1 -1
  26. package/dist/gh-tool/types.d.ts +2 -2
  27. package/dist/gh-tool/types.d.ts.map +1 -1
  28. package/package.json +1 -1
  29. package/src/gh-tool/issue/triage.ts +1 -1
  30. package/src/gh-tool/main.ts +2 -1
  31. package/src/gh-tool/pr/commands.ts +15 -6
  32. package/src/gh-tool/pr/review.ts +27 -7
  33. package/src/gh-tool/read/graphql-fallback.ts +366 -0
  34. package/src/gh-tool/read/pulls.ts +60 -10
  35. package/src/gh-tool/read/reads.ts +2 -0
  36. package/src/gh-tool/read/rest-porcelain.ts +571 -0
  37. package/src/gh-tool/read/review-guards.ts +8 -2
  38. package/src/gh-tool/read/review-model.ts +1 -1
  39. package/src/gh-tool/read/reviews.ts +19 -3
  40. package/src/gh-tool/read/telemetry.ts +6 -3
  41. package/src/gh-tool/read/transport.ts +314 -7
  42. package/src/gh-tool/types.ts +2 -2
@@ -8,13 +8,14 @@ import { gatedRead } from "./gated";
8
8
  import { restSnapshot, snapshotDigest } from "./rest";
9
9
  import { OPS } from "./classes";
10
10
  import { repoSlug } from "./keys";
11
+ import { isFallbackResult } from "./graphql-fallback";
11
12
  import type { RepoRef } from "./keys";
12
13
  import { parsePreserving } from "./porcelain";
13
14
 
14
15
  export const PR_VIEW_FIELDS =
15
- "number,url,title,headRefName,baseRefName,headRefOid,state,isDraft,mergeable,body,author,reviewDecision,reviewRequests,createdAt,headRepositoryOwner,mergeCommit";
16
+ "number,url,title,headRefName,baseRefName,headRefOid,state,isDraft,mergeable,body,author,reviewRequests,createdAt,headRepositoryOwner,mergeCommit,reviewDecision";
16
17
  export const PR_LIST_FIELDS =
17
- "number,url,title,headRefName,baseRefName,state,isDraft,mergeable,author,createdAt,reviewDecision,headRepositoryOwner";
18
+ "number,url,title,headRefName,baseRefName,state,isDraft,mergeable,author,createdAt,headRepositoryOwner,reviewDecision";
18
19
  export type PrListFilter = {
19
20
  state: string;
20
21
  limit: number;
@@ -38,7 +39,7 @@ const Pull = Schema.Struct({
38
39
  ),
39
40
  createdAt: Schema.optional(Schema.String),
40
41
  reviewDecision: Schema.optional(Schema.String),
41
- headRepositoryOwner: Schema.optional(Schema.Struct({ login: Schema.String })),
42
+ headRepositoryOwner: Schema.optional(Schema.NullOr(Schema.Struct({ login: Schema.String }))),
42
43
  });
43
44
 
44
45
  const PullView = Schema.Struct({
@@ -48,7 +49,13 @@ const PullView = Schema.Struct({
48
49
  baseSha: Schema.optional(Schema.NullOr(Schema.String)),
49
50
  body: Schema.String,
50
51
  author: Schema.Struct({ login: Schema.String, is_bot: Schema.Boolean }),
51
- reviewDecision: Schema.Literals(["APPROVED", "CHANGES_REQUESTED", "REVIEW_REQUIRED", ""]),
52
+ reviewDecision: Schema.Literals([
53
+ "APPROVED",
54
+ "CHANGES_REQUESTED",
55
+ "REVIEW_REQUIRED",
56
+ "UNKNOWN",
57
+ "",
58
+ ]),
52
59
  reviewRequests: Schema.mutable(
53
60
  Schema.Array(
54
61
  Schema.Union([
@@ -159,7 +166,7 @@ export const prView = Effect.fn("reads.prView")(function* (
159
166
  if (selector.by === "currentBranch" || repo === null) {
160
167
  const fence = yield* readFence;
161
168
  const data = (yield* fetch()).value;
162
- if (repo !== null && consistency !== "origin" && fence !== null) {
169
+ if (repo !== null && consistency !== "origin" && fence !== null && !("fallback" in data)) {
163
170
  const head = yield* prHead(repo, data.number).pipe(Effect.orElseSucceed(() => null));
164
171
  if (head !== null && head.headSha === data.headRefOid)
165
172
  yield* seedRead(
@@ -177,6 +184,7 @@ export const prView = Effect.fn("reads.prView")(function* (
177
184
  fetch: Effect.suspend(() => gh.runGhJson<PrView>(args)),
178
185
  signal: prHead(repo, selector.number).pipe(Effect.map((head) => head.signature)),
179
186
  maxAgeMs: () => OPS.prView.maxAgeMs,
187
+ cacheableWhen: (value) => !("fallback" in value),
180
188
  });
181
189
  });
182
190
 
@@ -214,6 +222,8 @@ export const prList = Effect.fn("reads.prList")(function* (
214
222
  gh
215
223
  .runGhJson<PrListItem[]>(args)
216
224
  .pipe(Effect.map((value) => ({ kind: "fresh" as const, value }))),
225
+ cacheableWhen: (value) =>
226
+ !isFallbackResult(value) && value.every((item) => !("fallback" in item)),
217
227
  });
218
228
  });
219
229
 
@@ -353,7 +363,7 @@ type PrReviewTriageSummaryPage = {
353
363
  };
354
364
  readonly reviewThreads: {
355
365
  readonly nodes: ReadonlyArray<{
356
- readonly isResolved: boolean;
366
+ readonly isResolved: boolean | null;
357
367
  readonly comments: {
358
368
  readonly nodes: ReadonlyArray<{ readonly replyTo: { readonly id: string } | null }>;
359
369
  };
@@ -376,7 +386,7 @@ export type PrReviewTriageSummary = {
376
386
  readonly reviewRequests: ReadonlyArray<{ readonly login: string }>;
377
387
  };
378
388
  readonly summary: {
379
- readonly unresolvedReviewThreadsCount: number;
389
+ readonly unresolvedReviewThreadsCount: number | null;
380
390
  readonly unrepliedReviewThreadsCount: number;
381
391
  };
382
392
  readonly checks: ReadonlyArray<{ readonly name: string; readonly bucket: string }>;
@@ -392,14 +402,16 @@ export const prReviewTriageSummary = Effect.fn("reads.prReviewTriageSummary")(fu
392
402
  PR_REVIEW_TRIAGE_SUMMARY_QUERY,
393
403
  variables,
394
404
  )) as PrReviewTriageSummaryPage;
395
- const firstPage = first.repository.pullRequest;
405
+ let firstPage = first.repository.pullRequest;
396
406
  let unresolvedReviewThreadsCount = 0;
407
+ let resolutionUnknown = false;
397
408
  let unrepliedReviewThreadsCount = 0;
398
409
  const countThreads = (
399
410
  threads: PrReviewTriageSummaryPage["repository"]["pullRequest"]["reviewThreads"]["nodes"],
400
411
  ) => {
401
412
  for (const thread of threads) {
402
- if (!thread.isResolved) unresolvedReviewThreadsCount++;
413
+ if (thread.isResolved === null) resolutionUnknown = true;
414
+ if (thread.isResolved === false) unresolvedReviewThreadsCount++;
403
415
  if (!thread.comments.nodes.some((comment) => comment.replyTo !== null))
404
416
  unrepliedReviewThreadsCount++;
405
417
  }
@@ -413,6 +425,12 @@ export const prReviewTriageSummary = Effect.fn("reads.prReviewTriageSummary")(fu
413
425
  after: pageInfo.endCursor,
414
426
  })) as PrReviewTriageSummaryPage;
415
427
  const pullRequest = response.repository.pullRequest;
428
+ if ("fallback" in response) {
429
+ unresolvedReviewThreadsCount = 0;
430
+ unrepliedReviewThreadsCount = 0;
431
+ resolutionUnknown = false;
432
+ firstPage = pullRequest;
433
+ }
416
434
  countThreads(pullRequest.reviewThreads.nodes);
417
435
  pageInfo = pullRequest.reviewThreads.pageInfo;
418
436
  }
@@ -451,7 +469,10 @@ export const prReviewTriageSummary = Effect.fn("reads.prReviewTriageSummary")(fu
451
469
  mergeable: firstPage.mergeable,
452
470
  reviewRequests,
453
471
  },
454
- summary: { unresolvedReviewThreadsCount, unrepliedReviewThreadsCount },
472
+ summary: {
473
+ unresolvedReviewThreadsCount: resolutionUnknown ? null : unresolvedReviewThreadsCount,
474
+ unrepliedReviewThreadsCount,
475
+ },
455
476
  checks,
456
477
  };
457
478
  });
@@ -464,3 +485,32 @@ const movedHead = (pr: number) =>
464
485
  stderr: "PR head changed while collecting checks",
465
486
  retryable: true,
466
487
  });
488
+
489
+ export const prReviewDecision = Effect.fn("reads.prReviewDecision")(function* (
490
+ repo: RepoRef,
491
+ pr: number,
492
+ ) {
493
+ const gh = yield* GitHubService;
494
+ const result = yield* gh.runGhJson<unknown>([
495
+ "pr",
496
+ "view",
497
+ String(pr),
498
+ "--repo",
499
+ repoSlug(repo),
500
+ "--json",
501
+ "reviewDecision",
502
+ ]);
503
+ return yield* Effect.try({
504
+ try: () =>
505
+ Schema.decodeUnknownSync(Schema.Struct({ reviewDecision: PullView.fields.reviewDecision }))(
506
+ result,
507
+ ).reviewDecision,
508
+ catch: (cause) =>
509
+ new GitHubCommandError({
510
+ command: "pr view",
511
+ exitCode: 1,
512
+ message: "Invalid review decision",
513
+ stderr: String(cause),
514
+ }),
515
+ });
516
+ });
@@ -14,6 +14,7 @@ import {
14
14
  prBody,
15
15
  checkSignal,
16
16
  prReviewTriageSummary,
17
+ prReviewDecision,
17
18
  } from "./pulls";
18
19
  import { prComments, prReviews, reviewThreads, lastHumanReviewer } from "./reviews";
19
20
  import { reviewGuards } from "./review-guards";
@@ -384,6 +385,7 @@ export const reads = {
384
385
  prList,
385
386
  prChecks,
386
387
  prReviewTriageSummary,
388
+ prReviewDecision,
387
389
  prHead,
388
390
  prBody,
389
391
  checkSignal,