@effect-agent/pr-review 0.1.0-beta.8 → 0.1.0-beta.9

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.
@@ -1,4 +1,4 @@
1
- import { Context, Effect, Encoding, Layer, Option, Redacted, Result, Schema } from "effect";
1
+ import { Context, DateTime, Effect, Encoding, Layer, Option, Redacted, Result, Schema } from "effect";
2
2
  import { Agent, AgentPolicy, Subagent, SubagentPolicy, SubagentRuntime, ToolExecutionClass } from "effect-agent";
3
3
  import { Tool, Toolkit } from "effect/unstable/ai";
4
4
  import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http";
@@ -1094,11 +1094,202 @@ const buildProfileMission = (metadata, files) => ReviewMission.make({
1094
1094
  changedFileCount: files.length
1095
1095
  });
1096
1096
  //#endregion
1097
+ //#region src/internal/retirement.ts
1098
+ const PositiveLine = Schema.Int.check(Schema.isGreaterThan(0));
1099
+ /** One previously posted review as observed through the retirement host. */
1100
+ var RetirableReview = class extends Schema.Class("@effect-agent/pr-review/RetirableReview")({
1101
+ reviewId: Schema.Int.check(Schema.isGreaterThan(0)),
1102
+ body: Schema.String.check(Schema.isMaxLength(6e4)),
1103
+ commitSha: Schema.NonEmptyString.check(Schema.isMaxLength(64)),
1104
+ authorNodeId: Schema.NullOr(Schema.NonEmptyString.check(Schema.isMaxLength(200))),
1105
+ submittedAt: Schema.NullOr(Schema.DateTimeUtc)
1106
+ }) {};
1107
+ /** One inline comment attached to a previously posted review. */
1108
+ var RetirableReviewComment = class extends Schema.Class("@effect-agent/pr-review/RetirableReviewComment")({
1109
+ nodeId: Schema.NonEmptyString.check(Schema.isMaxLength(200)),
1110
+ path: Schema.NonEmptyString.check(Schema.isMaxLength(500)),
1111
+ startLine: Schema.NullOr(PositiveLine),
1112
+ endLine: Schema.NullOr(PositiveLine),
1113
+ body: Schema.String.check(Schema.isMaxLength(65536))
1114
+ }) {};
1115
+ /** A GitHub retirement read or mutation failed. */
1116
+ var ReviewRetirementFailure = class extends Schema.TaggedError()("ReviewRetirementFailure", {
1117
+ operation: Schema.String,
1118
+ reason: Schema.String
1119
+ }) {
1120
+ get message() {
1121
+ return `Review retirement operation '${this.operation}' failed: ${this.reason}`;
1122
+ }
1123
+ };
1124
+ /**
1125
+ * Host-side GitHub operations used by retirement. Domain code never reaches
1126
+ * into REST or GraphQL directly, and deterministic tests substitute this port.
1127
+ */
1128
+ var ReviewRetirementHost = class extends Context.Service()("@effect-agent/pr-review/ReviewRetirementHost") {};
1129
+ /** Observable cosmetic work completed by one fail-open retirement pass. */
1130
+ var ReviewRetirementReport = class extends Schema.Class("@effect-agent/pr-review/ReviewRetirementReport")({
1131
+ reviewsRetired: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
1132
+ findingsResolved: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
1133
+ commentsMinimized: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
1134
+ failures: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))
1135
+ }) {};
1136
+ const findingIdentity = (finding) => `${finding.path}\u0000${finding.startLine}\u0000${finding.endLine}\u0000${finding.title}`;
1137
+ const REVIEW_METADATA_PATTERN = /<!-- effect-agent-pr-review metadata\n[\s\S]*?\n-->/g;
1138
+ const FINGERPRINT_PATTERN = /<!-- effect-agent-pr-review fingerprint=sha256:[0-9a-f]{64} -->/g;
1139
+ const STATE_PATTERN = /<!-- effect-agent-pr-review state-v1:[A-Za-z0-9+/]+={0,2}\.[0-9a-f]{64} -->/g;
1140
+ const RETIRED_ORIGINAL_PATTERN = /<!-- effect-agent-pr-review retired-original:start -->\n([\s\S]*?)\n<!-- effect-agent-pr-review retired-original:end -->/;
1141
+ const MACHINE_COMMENT_PATTERN = new RegExp(`${REVIEW_METADATA_PATTERN.source}|${FINGERPRINT_PATTERN.source}|${STATE_PATTERN.source}`, "g");
1142
+ const VERDICT_CALLOUT_PATTERN = /^(?:> \[!(?:CAUTION|IMPORTANT)\]\n> [^\n]*(?:\n> [^\n]*)*|> (?:ℹ️|✅)[^\n]*)\n*/;
1143
+ const INLINE_FINDING_TITLE_PATTERN = /^\*\*\[(?:🛑 blocking|⚠️ important|💅 nit)\] ([^\n]+)\*\*$/;
1144
+ const MAX_REVIEW_BODY_CHARS = 6e4;
1145
+ /** The host-authored metadata marker is the authority gate for any edit. */
1146
+ const hasReviewMetadataMarker = (body) => /<!-- effect-agent-pr-review metadata\n/.test(body);
1147
+ const machineComments = (body) => Array.from(body.matchAll(MACHINE_COMMENT_PATTERN), (match) => match[0]);
1148
+ const originalVisibleBody = (body) => {
1149
+ const retired = RETIRED_ORIGINAL_PATTERN.exec(body)?.[1];
1150
+ if (retired !== void 0) return retired;
1151
+ return body.replace(MACHINE_COMMENT_PATTERN, "").trim().replace(VERDICT_CALLOUT_PATTERN, "");
1152
+ };
1153
+ const findingLocation = (finding) => `${finding.path}:${finding.startLine}${finding.endLine === finding.startLine ? "" : `-${finding.endLine}`}`;
1154
+ const renderRetiredBody = (input) => {
1155
+ const shortSha = input.currentState.reviewedHeadSha.slice(0, 7);
1156
+ const comments = machineComments(input.priorBody);
1157
+ const original = originalVisibleBody(input.priorBody);
1158
+ const resolved = input.resolvedFindings.length === 0 ? [] : [
1159
+ "### Findings resolved by later review",
1160
+ "",
1161
+ ...input.resolvedFindings.map((finding) => `- \`${findingLocation(finding)}\` ~~${finding.title}~~ · resolved at \`${shortSha}\``),
1162
+ ""
1163
+ ];
1164
+ const prefix = [
1165
+ `> ℹ️ Superseded — ${input.resolvedFindings.length} of ${input.priorState.unresolvedFindings.length} findings resolved at \`${shortSha}\`; see [the latest review](${input.currentReviewUrl}).`,
1166
+ "",
1167
+ "<details>",
1168
+ "<summary>Previous review details</summary>",
1169
+ "",
1170
+ ...resolved,
1171
+ "<!-- effect-agent-pr-review retired-original:start -->"
1172
+ ];
1173
+ const suffix = [
1174
+ "<!-- effect-agent-pr-review retired-original:end -->",
1175
+ "",
1176
+ "</details>",
1177
+ ...comments.length === 0 ? [] : ["", ...comments]
1178
+ ];
1179
+ const render = (visible) => [
1180
+ ...prefix,
1181
+ visible,
1182
+ ...suffix
1183
+ ].join("\n");
1184
+ if (render(original).length <= MAX_REVIEW_BODY_CHARS) return render(original);
1185
+ const truncationNotice = "\n\n_Original review content truncated during retirement._";
1186
+ const budget = Math.max(0, MAX_REVIEW_BODY_CHARS - render(truncationNotice).length);
1187
+ return render(`${original.slice(0, budget)}${truncationNotice}`);
1188
+ };
1189
+ /** Compute one prior review's resolved subset and deterministic retired body. */
1190
+ const decideReviewRetirement = (input) => {
1191
+ const current = new Set(input.currentState.unresolvedFindings.map(findingIdentity));
1192
+ const resolvedFindings = input.priorState.unresolvedFindings.filter((finding) => !current.has(findingIdentity(finding)));
1193
+ return {
1194
+ body: renderRetiredBody({
1195
+ ...input,
1196
+ resolvedFindings
1197
+ }),
1198
+ resolvedFindings,
1199
+ priorFindingCount: input.priorState.unresolvedFindings.length
1200
+ };
1201
+ };
1202
+ const inlineCommentIdentity = (comment) => {
1203
+ if (comment.startLine === null || comment.endLine === null) return void 0;
1204
+ const firstLine = comment.body.split("\n", 1)[0] ?? "";
1205
+ const title = INLINE_FINDING_TITLE_PATTERN.exec(firstLine)?.[1];
1206
+ return title === void 0 ? void 0 : findingIdentity({
1207
+ path: comment.path,
1208
+ startLine: comment.startLine,
1209
+ endLine: comment.endLine,
1210
+ title
1211
+ });
1212
+ };
1213
+ const failOpen = (effect, fallback, message) => effect.pipe(Effect.catch((error) => Effect.logWarning(`${message}: ${String(error)}`).pipe(Effect.as(fallback))));
1214
+ const isStrictlyOlderReview = (review, input) => {
1215
+ if (review.submittedAt === null) return false;
1216
+ const submittedAt = DateTime.toEpochMillis(review.submittedAt);
1217
+ const currentSubmittedAt = DateTime.toEpochMillis(input.currentSubmittedAt);
1218
+ return submittedAt < currentSubmittedAt || submittedAt === currentSubmittedAt && review.reviewId < input.currentReviewId;
1219
+ };
1220
+ /**
1221
+ * Retire every marker-bearing prior review against the newest posted state.
1222
+ * Every lookup, edit, and minimization is isolated: retirement is cosmetic
1223
+ * and can never change the run or check outcome.
1224
+ */
1225
+ const retireStaleReviews = Effect.fn("retireStaleReviews")(function* (input) {
1226
+ const host = yield* ReviewRetirementHost;
1227
+ const authenticator = yield* ReviewStateAuthenticator;
1228
+ if (authenticator.status !== "available") {
1229
+ yield* Effect.logWarning("Skipping stale-review retirement because authenticated review state is unavailable.");
1230
+ return ReviewRetirementReport.make({
1231
+ reviewsRetired: 0,
1232
+ findingsResolved: 0,
1233
+ commentsMinimized: 0,
1234
+ failures: 0
1235
+ });
1236
+ }
1237
+ let failures = 0;
1238
+ let reviewsRetired = 0;
1239
+ let findingsResolved = 0;
1240
+ let commentsMinimized = 0;
1241
+ const reviews = yield* failOpen(host.listReviews, void 0, "Could not list prior reviews");
1242
+ if (reviews === void 0) return ReviewRetirementReport.make({
1243
+ reviewsRetired,
1244
+ findingsResolved,
1245
+ commentsMinimized,
1246
+ failures: 1
1247
+ });
1248
+ for (const review of reviews) {
1249
+ if (review.authorNodeId !== input.currentAuthorNodeId || !isStrictlyOlderReview(review, input) || !hasReviewMetadataMarker(review.body)) continue;
1250
+ const priorState = yield* failOpen(authenticator.extract(review.body), Option.none(), `Could not authenticate prior review ${review.reviewId}`);
1251
+ if (Option.isNone(priorState)) continue;
1252
+ const decision = decideReviewRetirement({
1253
+ priorBody: review.body,
1254
+ priorState: priorState.value,
1255
+ currentState: input.currentState,
1256
+ currentReviewUrl: input.currentReviewUrl
1257
+ });
1258
+ if (yield* failOpen(host.updateBody(review.reviewId, decision.body).pipe(Effect.as(true)), false, `Could not retire prior review ${review.reviewId}`)) {
1259
+ reviewsRetired += 1;
1260
+ findingsResolved += decision.resolvedFindings.length;
1261
+ } else failures += 1;
1262
+ if (decision.resolvedFindings.length === 0) continue;
1263
+ const comments = yield* failOpen(host.listComments(review.reviewId), void 0, `Could not list inline comments for prior review ${review.reviewId}`);
1264
+ if (comments === void 0) {
1265
+ failures += 1;
1266
+ continue;
1267
+ }
1268
+ const resolved = new Set(decision.resolvedFindings.map(findingIdentity));
1269
+ for (const comment of comments) {
1270
+ const identity = inlineCommentIdentity(comment);
1271
+ if (identity === void 0 || !resolved.has(identity)) continue;
1272
+ if (yield* failOpen(host.minimizeComment(comment.nodeId).pipe(Effect.as(true)), false, `Could not minimize resolved inline comment ${comment.nodeId}`)) commentsMinimized += 1;
1273
+ else failures += 1;
1274
+ }
1275
+ }
1276
+ return ReviewRetirementReport.make({
1277
+ reviewsRetired,
1278
+ findingsResolved,
1279
+ commentsMinimized,
1280
+ failures
1281
+ });
1282
+ });
1283
+ //#endregion
1097
1284
  //#region src/internal/github.ts
1285
+ const defaultGraphqlUrl = (apiUrl) => apiUrl === "https://api.github.com" ? "https://api.github.com/graphql" : apiUrl.replace(/\/api\/v3$/, "/api/graphql");
1098
1286
  /** Which pull request to review and how to reach the API. */
1099
1287
  var GitHubReviewTarget = class GitHubReviewTarget extends Context.Service()("@effect-agent/pr-review/GitHubReviewTarget") {
1100
1288
  static layer(config) {
1101
- return Layer.succeed(this, GitHubReviewTarget.of(config));
1289
+ return Layer.succeed(this, GitHubReviewTarget.of({
1290
+ ...config,
1291
+ graphqlUrl: config.graphqlUrl ?? defaultGraphqlUrl(config.apiUrl)
1292
+ }));
1102
1293
  }
1103
1294
  };
1104
1295
  /** A GitHub API call failed: transport, status, or payload decode. */
@@ -1133,16 +1324,46 @@ const GitHubFileWire = Schema.Struct({
1133
1324
  previous_filename: Schema.optionalKey(Schema.String)
1134
1325
  });
1135
1326
  const GitHubFilesPageWire = Schema.Array(GitHubFileWire);
1327
+ const GitHubActorWire = Schema.Struct({ node_id: Schema.String });
1136
1328
  const GitHubReviewWire = Schema.Struct({
1137
1329
  id: Schema.Int,
1138
- html_url: Schema.String
1330
+ html_url: Schema.String,
1331
+ user: Schema.NullOr(GitHubActorWire),
1332
+ submitted_at: Schema.NullOr(Schema.String)
1333
+ });
1334
+ const GitHubRetirableReviewWire = Schema.Struct({
1335
+ id: Schema.Int,
1336
+ body: Schema.NullOr(Schema.String),
1337
+ commit_id: Schema.String,
1338
+ user: Schema.NullOr(GitHubActorWire),
1339
+ submitted_at: Schema.NullOr(Schema.String)
1139
1340
  });
1341
+ const GitHubRetirableReviewsPageWire = Schema.Array(GitHubRetirableReviewWire);
1342
+ const GitHubReviewCommentWire = Schema.Struct({
1343
+ node_id: Schema.String,
1344
+ path: Schema.String,
1345
+ body: Schema.String,
1346
+ line: Schema.NullOr(Schema.Int),
1347
+ original_line: Schema.NullOr(Schema.Int),
1348
+ start_line: Schema.optionalKey(Schema.NullOr(Schema.Int)),
1349
+ original_start_line: Schema.optionalKey(Schema.NullOr(Schema.Int))
1350
+ });
1351
+ const GitHubReviewCommentsPageWire = Schema.Array(GitHubReviewCommentWire);
1352
+ const GitHubMinimizeCommentWire = Schema.Struct({
1353
+ data: Schema.optionalKey(Schema.NullOr(Schema.Struct({ minimizeComment: Schema.NullOr(Schema.Struct({ minimizedComment: Schema.NullOr(Schema.Struct({ isMinimized: Schema.Boolean })) })) }))),
1354
+ errors: Schema.optionalKey(Schema.Array(Schema.Struct({ message: Schema.String })))
1355
+ });
1356
+ /** Decode GitHub's external timestamp before it participates in mutation ordering. */
1357
+ const parseGitHubSubmittedAt = (value) => value === null ? null : Option.getOrNull(DateTime.make(value));
1140
1358
  /** The publication receipt callers report back to the operator. */
1141
1359
  var PublishedReview = class extends Schema.Class("@effect-agent/pr-review/PublishedReview")({
1142
1360
  reviewId: Schema.Int,
1143
1361
  url: Schema.String,
1144
1362
  event: Schema.String,
1145
- inlineComments: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))
1363
+ inlineComments: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
1364
+ /** Actor and ordering boundary returned by the create-review response. */
1365
+ authorNodeId: Schema.NullOr(Schema.NonEmptyString.check(Schema.isMaxLength(200))),
1366
+ submittedAt: Schema.NullOr(Schema.DateTimeUtc)
1146
1367
  }) {};
1147
1368
  /** Posts one planned review; the ONLY mutating operation in this package. */
1148
1369
  var ReviewPublisher = class extends Context.Service()("@effect-agent/pr-review/ReviewPublisher") {};
@@ -1266,10 +1487,90 @@ const gitHubReviewPublisherLayer = Layer.effect(ReviewPublisher)(Effect.gen(func
1266
1487
  reviewId: wire.id,
1267
1488
  url: wire.html_url,
1268
1489
  event: plan.event,
1269
- inlineComments: plan.comments.length
1490
+ inlineComments: plan.comments.length,
1491
+ authorNodeId: wire.user?.node_id ?? null,
1492
+ submittedAt: parseGitHubSubmittedAt(wire.submitted_at)
1270
1493
  });
1271
1494
  }) });
1272
1495
  }));
1496
+ const MAX_RETIREMENT_PAGES = 5;
1497
+ const MINIMIZE_REVIEW_COMMENT_MUTATION = `mutation MinimizeReviewComment($subjectId: ID!) {
1498
+ minimizeComment(input: { subjectId: $subjectId, classifier: OUTDATED }) {
1499
+ minimizedComment { isMinimized }
1500
+ }
1501
+ }`;
1502
+ /** GitHub-backed host operations for cosmetic retirement after publication. */
1503
+ const gitHubReviewRetirementHostLayer = Layer.effect(ReviewRetirementHost)(Effect.gen(function* () {
1504
+ const target = yield* GitHubReviewTarget;
1505
+ const client = yield* HttpClient.HttpClient;
1506
+ const prefix = `${target.apiUrl}/repos/${target.repository}/pulls/${target.number}`;
1507
+ const asRetirementFailure = (operation) => (error) => ReviewRetirementFailure.make({
1508
+ operation,
1509
+ reason: `${error._tag}: ${error.message ?? "request failed"}`.slice(0, 2048)
1510
+ });
1511
+ const executeRetirement = (operation, request) => HttpClient.execute(request).pipe(Effect.flatMap(HttpClientResponse.filterStatusOk), Effect.mapError(asRetirementFailure(operation)), Effect.provideService(HttpClient.HttpClient, client));
1512
+ const decodeRetirement = (schema, operation) => {
1513
+ const decode = Schema.decodeUnknownEffect(schema);
1514
+ return (response) => response.json.pipe(Effect.mapError(asRetirementFailure(operation)), Effect.flatMap((body) => decode(body).pipe(Effect.mapError(asRetirementFailure(operation)))));
1515
+ };
1516
+ const listPaged = (input) => Effect.gen(function* () {
1517
+ const values = [];
1518
+ const perPage = 100;
1519
+ for (let page = 1; page <= MAX_RETIREMENT_PAGES; page += 1) {
1520
+ const response = yield* executeRetirement(input.operation, withCommonHeaders(HttpClientRequest.get(input.url).pipe(HttpClientRequest.acceptJson, HttpClientRequest.setUrlParams({
1521
+ per_page: String(perPage),
1522
+ page: String(page)
1523
+ })), target.token));
1524
+ const pageValues = yield* input.decode(response);
1525
+ values.push(...pageValues);
1526
+ if (pageValues.length < perPage) return values;
1527
+ }
1528
+ return yield* ReviewRetirementFailure.make({
1529
+ operation: input.operation,
1530
+ reason: `history exceeds the bounded ${MAX_RETIREMENT_PAGES * 100}-item lookup`
1531
+ });
1532
+ });
1533
+ return ReviewRetirementHost.of({
1534
+ listReviews: listPaged({
1535
+ operation: "listReviewsForRetirement",
1536
+ url: `${prefix}/reviews`,
1537
+ decode: decodeRetirement(GitHubRetirableReviewsPageWire, "listReviewsForRetirement")
1538
+ }).pipe(Effect.map((reviews) => reviews.map((review) => RetirableReview.make({
1539
+ reviewId: review.id,
1540
+ body: review.body ?? "",
1541
+ commitSha: review.commit_id,
1542
+ authorNodeId: review.user?.node_id ?? null,
1543
+ submittedAt: parseGitHubSubmittedAt(review.submitted_at)
1544
+ })))),
1545
+ listComments: (reviewId) => listPaged({
1546
+ operation: "listReviewCommentsForRetirement",
1547
+ url: `${prefix}/reviews/${reviewId}/comments`,
1548
+ decode: decodeRetirement(GitHubReviewCommentsPageWire, "listReviewCommentsForRetirement")
1549
+ }).pipe(Effect.map((comments) => comments.map((comment) => {
1550
+ const endLine = comment.line ?? comment.original_line;
1551
+ const startLine = comment.start_line ?? comment.original_start_line ?? endLine;
1552
+ return RetirableReviewComment.make({
1553
+ nodeId: comment.node_id,
1554
+ path: comment.path,
1555
+ startLine,
1556
+ endLine,
1557
+ body: comment.body
1558
+ });
1559
+ }))),
1560
+ updateBody: (reviewId, body) => executeRetirement("updateReview", withCommonHeaders(HttpClientRequest.put(`${prefix}/reviews/${reviewId}`).pipe(HttpClientRequest.acceptJson, HttpClientRequest.bodyJsonUnsafe({ body })), target.token)).pipe(Effect.asVoid),
1561
+ minimizeComment: (nodeId) => Effect.gen(function* () {
1562
+ const response = yield* executeRetirement("minimizeComment", withCommonHeaders(HttpClientRequest.post(target.graphqlUrl).pipe(HttpClientRequest.acceptJson, HttpClientRequest.bodyJsonUnsafe({
1563
+ query: MINIMIZE_REVIEW_COMMENT_MUTATION,
1564
+ variables: { subjectId: nodeId }
1565
+ })), target.token));
1566
+ const wire = yield* decodeRetirement(GitHubMinimizeCommentWire, "minimizeComment")(response);
1567
+ if ((wire.errors?.length ?? 0) > 0 || wire.data?.minimizeComment?.minimizedComment?.isMinimized !== true) return yield* ReviewRetirementFailure.make({
1568
+ operation: "minimizeComment",
1569
+ reason: wire.errors?.map((error) => error.message).join("; ").slice(0, 2048) ?? "GitHub did not confirm comment minimization"
1570
+ });
1571
+ })
1572
+ });
1573
+ }));
1273
1574
  /** Reading the pull request's previously posted reviews failed. */
1274
1575
  var PriorReviewLookupFailure = class extends Schema.TaggedError()("PriorReviewLookupFailure", { reason: Schema.String }) {
1275
1576
  get message() {
@@ -1367,6 +1668,6 @@ const fingerprintUnchanged = (current) => Effect.gen(function* () {
1367
1668
  return Option.isSome(latest) && latest.value === current;
1368
1669
  });
1369
1670
  //#endregion
1370
- export { ListReviewUnits as $, reviewInstructions as $t, toStoredConcern as A, FileSlice as At, FanOutCoordinatorToolkit as B, ReviewConcern as Bt, StoredReviewFinding as C, planReviewUnits as Ct, fromStoredFinding as D, CodeReview as Dt, fromStoredConcern as E, ChangedFilesView as Et, FINGERPRINT_MARKER_LENGTH as F, MAX_CONCERNS as Ft, FileReviewDelegationFailure as G, ReviewVerdict as Gt, FanOutReviewToolkit as H, ReviewMission as Ht, computeChangesetFingerprint as I, MAX_FINDINGS as It, FileReviewToolkit as J, listChangedFilesHandler as Jt, FileReviewReport as K, clampMaxFindings as Kt, extractFingerprint as L, PullRequestReviewer as Lt, unavailableReviewStateAuthenticatorLayer as M, FindingSeverity as Mt, validateReviewState as N, ListChangedFiles as Nt, selectReviewRange as O, FileDiffQuery as Ot, webCryptoReviewStateAuthenticatorLayer as P, ListChangedFilesQuery as Pt, FileReviewer as Q, resolveGuidance as Qt, renderFingerprintMarker as R, ReadFile as Rt, StoredReviewConcern as S, UNIT_CHANGED_LINE_BUDGET as St, computeProfileFingerprint as T, ChangedFileSummary as Tt, FanOutReviewer as U, ReviewToolkit as Ut, FanOutCoordinatorToolkitLayer as V, ReviewFinding as Vt, FileReviewBrief as W, ReviewToolkitLayer as Wt, FileReviewUnitFailed as X, readFileDiffHandler as Xt, FileReviewToolkitLayer as Y, makeReviewInstructions as Yt, FileReviewUnitResult as Z, readFileHandler as Zt, ReviewState as _, MAX_REVIEW_UNITS as _t, PublishedReview as a, ReviewInputViolation as an, defaultFileReviewerPolicy as at, ReviewStateMarker as b, ReviewUnitId as bt, gitHubPriorReviewsLayer as c, ChangedFileStatus as cn, fanOutReviewInstructions as ct, GitCommitSha as d, commentableLines as dn, fileReviewerInstructions as dt, MAX_CHANGED_FILES as en, ListReviewUnitsQuery as et, MAX_REVIEW_STATE_MARKER_CHARS as f, parsePatch as fn, makeFanOutReviewInstructions as ft, ReviewScopeMode as g, MAX_MERGED_FINDINGS as gt, ReviewMode as h, mapFileReviewChildFailure as ht, PriorReviews as i, PullRequestSourceFailure as in, defaultFanOutPolicy as it, toStoredFinding as j, FileSliceQuery as jt, selectedPullRequestSourceLayer as k, FileDiffView as kt, gitHubPullRequestSourceLayer as l, ChangedPath as ln, fileReviewDelegation as lt, ReviewHeadComparison as m, makeFileReviewerInstructions as mt, GitHubReviewTarget as n, PullRequestMetadata as nn, MAX_CHILD_FINDINGS as nt, ReviewPublisher as o, normalizeRepoRelativePath as on, fanOutHandlersLayer as ot, ReviewExecutionContext as p, makeFanOutReviewSuite as pt, FileReviewRequest as q, defaultReviewPolicy as qt, PriorReviewLookupFailure as r, PullRequestSource as rn, MAX_FILE_REVIEW_TOOL_CALLS as rt, fingerprintUnchanged as s, ChangedFile as sn, fanOutHandlersLayerFor as st, GitHubApiFailure as t, MAX_FILE_CHARS as tn, MAX_CHILD_CONCERNS as tt, gitHubReviewPublisherLayer as u, annotatePatch as un, fileReviewPolicy as ut, ReviewStateAuthenticationFailure as v, MAX_UNIT_FILES as vt, buildProfileMission as w, rankAndDedupeFindings as wt, ReviewStateMarkerTooLarge as x, ReviewUnitPlan as xt, ReviewStateAuthenticator as y, ReviewUnit as yt, DelegateFileReview as z, ReadFileDiff as zt };
1671
+ export { FanOutReviewer as $, ReviewToolkit as $t, ReviewStateMarker as A, ReviewUnitId as At, toStoredConcern as B, FileSlice as Bt, ReviewExecutionContext as C, makeFanOutReviewSuite as Ct, ReviewState as D, MAX_REVIEW_UNITS as Dt, ReviewScopeMode as E, MAX_MERGED_FINDINGS as Et, computeProfileFingerprint as F, ChangedFileSummary as Ft, FINGERPRINT_MARKER_LENGTH as G, MAX_CONCERNS as Gt, unavailableReviewStateAuthenticatorLayer as H, FindingSeverity as Ht, fromStoredConcern as I, ChangedFilesView as It, renderFingerprintMarker as J, ReadFile as Jt, computeChangesetFingerprint as K, MAX_FINDINGS as Kt, fromStoredFinding as L, CodeReview as Lt, StoredReviewConcern as M, UNIT_CHANGED_LINE_BUDGET as Mt, StoredReviewFinding as N, planReviewUnits as Nt, ReviewStateAuthenticationFailure as O, MAX_UNIT_FILES as Ot, buildProfileMission as P, rankAndDedupeFindings as Pt, FanOutReviewToolkit as Q, ReviewMission as Qt, selectReviewRange as R, FileDiffQuery as Rt, MAX_REVIEW_STATE_MARKER_CHARS as S, parsePatch as Sn, makeFanOutReviewInstructions as St, ReviewMode as T, mapFileReviewChildFailure as Tt, validateReviewState as U, ListChangedFiles as Ut, toStoredFinding as V, FileSliceQuery as Vt, webCryptoReviewStateAuthenticatorLayer as W, ListChangedFilesQuery as Wt, FanOutCoordinatorToolkit as X, ReviewConcern as Xt, DelegateFileReview as Y, ReadFileDiff as Yt, FanOutCoordinatorToolkitLayer as Z, ReviewFinding as Zt, ReviewRetirementReport as _, ChangedFile as _n, fanOutHandlersLayerFor as _t, PublishedReview as a, makeReviewInstructions as an, FileReviewToolkitLayer as at, retireStaleReviews as b, annotatePatch as bn, fileReviewPolicy as bt, gitHubPriorReviewsLayer as c, resolveGuidance as cn, FileReviewer as ct, gitHubReviewRetirementHostLayer as d, MAX_FILE_CHARS as dn, MAX_CHILD_CONCERNS as dt, ReviewToolkitLayer as en, FileReviewBrief as et, parseGitHubSubmittedAt as f, PullRequestMetadata as fn, MAX_CHILD_FINDINGS as ft, ReviewRetirementHost as g, normalizeRepoRelativePath as gn, fanOutHandlersLayer as gt, ReviewRetirementFailure as h, ReviewInputViolation as hn, defaultFileReviewerPolicy as ht, PriorReviews as i, listChangedFilesHandler as in, FileReviewToolkit as it, ReviewStateMarkerTooLarge as j, ReviewUnitPlan as jt, ReviewStateAuthenticator as k, ReviewUnit as kt, gitHubPullRequestSourceLayer as l, reviewInstructions as ln, ListReviewUnits as lt, RetirableReviewComment as m, PullRequestSourceFailure as mn, defaultFanOutPolicy as mt, GitHubReviewTarget as n, clampMaxFindings as nn, FileReviewReport as nt, ReviewPublisher as o, readFileDiffHandler as on, FileReviewUnitFailed as ot, RetirableReview as p, PullRequestSource as pn, MAX_FILE_REVIEW_TOOL_CALLS as pt, extractFingerprint as q, PullRequestReviewer as qt, PriorReviewLookupFailure as r, defaultReviewPolicy as rn, FileReviewRequest as rt, fingerprintUnchanged as s, readFileHandler as sn, FileReviewUnitResult as st, GitHubApiFailure as t, ReviewVerdict as tn, FileReviewDelegationFailure as tt, gitHubReviewPublisherLayer as u, MAX_CHANGED_FILES as un, ListReviewUnitsQuery as ut, decideReviewRetirement as v, ChangedFileStatus as vn, fanOutReviewInstructions as vt, ReviewHeadComparison as w, makeFileReviewerInstructions as wt, GitCommitSha as x, commentableLines as xn, fileReviewerInstructions as xt, hasReviewMetadataMarker as y, ChangedPath as yn, fileReviewDelegation as yt, selectedPullRequestSourceLayer as z, FileDiffView as zt };
1371
1672
 
1372
- //# sourceMappingURL=github-BZNzmxao.mjs.map
1673
+ //# sourceMappingURL=github-Lfa_ox-u.mjs.map